telopt_client.c 54 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335
  1. /******************************************************************************
  2. * This file is part of TinTin++ *
  3. * *
  4. * Copyright 2004-2020 Igor van den Hoven *
  5. * *
  6. * TinTin++ is free software; you can redistribute it and/or modify *
  7. * it under the terms of the GNU General Public License as published by *
  8. * the Free Software Foundation; either version 3 of the License, or *
  9. * (at your option) any later version. *
  10. * *
  11. * This program is distributed in the hope that it will be useful, *
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  14. * GNU General Public License for more details. *
  15. * *
  16. * You should have received a copy of the GNU General Public License *
  17. * along with TinTin++. If not, see https://www.gnu.org/licenses. *
  18. ******************************************************************************/
  19. /******************************************************************************
  20. * T I N T I N + + *
  21. * *
  22. * coded by Igor van den Hoven 2004 *
  23. ******************************************************************************/
  24. #include "tintin.h"
  25. #include "telnet.h"
  26. extern int client_send_do_eor(struct session *ses, int cplen, unsigned char *cpsrc);
  27. extern int client_mark_prompt(struct session *ses, int cplen, unsigned char *cpsrc);
  28. extern int client_recv_do_naws(struct session *ses, int cplen, unsigned char *cpsrc);
  29. extern int client_send_sb_naws(struct session *ses, int cplen, unsigned char *cpsrc);
  30. extern int client_recv_sb_tspeed(struct session *ses, int cplen, unsigned char *cpsrc);
  31. extern int client_recv_dont_ttype(struct session *ses, int cplen, unsigned char *cpsrc);
  32. extern int client_recv_sb_ttype(struct session *ses, int cplen, unsigned char *cpsrc);
  33. extern int client_send_wont_status(struct session *ses, int cplen, unsigned char *cpsrc);
  34. extern int client_send_dont_status(struct session *ses, int cplen, unsigned char *cpsrc);
  35. extern int client_recv_do_sga(struct session *ses, int cplen, unsigned char *cpsrc);
  36. extern int client_recv_will_sga(struct session *ses, int cplen, unsigned char *cpsrc);
  37. extern int client_send_wont_oldenviron(struct session *ses, int cplen, unsigned char *cpsrc);
  38. extern int client_recv_wont_echo(struct session *ses, int cplen, unsigned char *cpsrc);
  39. extern int client_recv_will_echo(struct session *ses, int cplen, unsigned char *cpsrc);
  40. extern int client_recv_do_echo(struct session *ses, int cplen, unsigned char *cpsrc);
  41. extern int client_send_ip(struct session *ses, int cplen, unsigned char *cpsrc);
  42. extern int client_send_wont_telopt(struct session *ses, int cplen, unsigned char *cpsrc);
  43. extern int client_send_dont_telopt(struct session *ses, int cplen, unsigned char *cpsrc);
  44. extern int client_send_will_telopt(struct session *ses, int cplen, unsigned char *cpsrc);
  45. extern int client_send_do_telopt(struct session *ses, int cplen, unsigned char *cpsrc);
  46. extern int client_recv_sb_mssp(struct session *ses, int cplen, unsigned char *src);
  47. extern int client_recv_sb_msdp(struct session *ses, int cplen, unsigned char *src);
  48. extern int client_recv_sb_gmcp(struct session *ses, int cplen, unsigned char *src);
  49. extern int client_recv_sb_charset(struct session *ses, int cplen, unsigned char *src);
  50. extern int client_recv_sb_new_environ(struct session *ses, int cplen, unsigned char *src);
  51. extern int client_recv_sb_zmp(struct session *ses, int cplen, unsigned char *cpsrc);
  52. extern int client_recv_will_mssp(struct session *ses, int cplen, unsigned char *cpsrc);
  53. extern int client_recv_will_mccp2(struct session *ses, int cplen, unsigned char *cpsrc);
  54. extern int client_send_dont_mccp2(struct session *ses, int cplen, unsigned char *cpsrc);
  55. extern int client_init_mccp2(struct session *ses, int cplen, unsigned char *cpsrc);
  56. extern int client_recv_will_mccp3(struct session *ses, int cplen, unsigned char *cpsrc);
  57. extern int client_recv_dont_mccp3(struct session *ses, int cplen, unsigned char *cpsrc);
  58. extern int client_recv_wont_mccp3(struct session *ses, int cplen, unsigned char *cpsrc);
  59. extern int client_init_mccp3(struct session *ses);
  60. extern int client_skip_sb(struct session *ses, int cplen, unsigned char *cpsrc);
  61. extern int client_recv_sb(struct session *ses, int cplen, unsigned char *cpsrc);
  62. struct iac_type
  63. {
  64. int size;
  65. unsigned char * code;
  66. int (* func) (struct session *ses, int cplen, unsigned char *cpsrc);
  67. };
  68. struct iac_type iac_client_table [] =
  69. {
  70. { 3, (unsigned char []) {IAC, DO, TELOPT_SGA}, &client_recv_do_sga },
  71. { 3, (unsigned char []) {IAC, WILL, TELOPT_SGA}, &client_recv_will_sga },
  72. { 3, (unsigned char []) {IAC, DO, TELOPT_NAWS}, &client_recv_do_naws },
  73. { 3, (unsigned char []) {IAC, DO, TELOPT_ECHO}, &client_recv_do_echo },
  74. { 3, (unsigned char []) {IAC, WILL, TELOPT_ECHO}, &client_recv_will_echo },
  75. { 3, (unsigned char []) {IAC, WONT, TELOPT_ECHO}, &client_recv_wont_echo },
  76. { 3, (unsigned char []) {IAC, WILL, TELOPT_MCCP2}, &client_recv_will_mccp2 },
  77. { 3, (unsigned char []) {IAC, WILL, TELOPT_MCCP3}, &client_recv_will_mccp3 },
  78. { 3, (unsigned char []) {IAC, DONT, TELOPT_MCCP3}, &client_recv_dont_mccp3 },
  79. { 3, (unsigned char []) {IAC, WONT, TELOPT_MCCP3}, &client_recv_wont_mccp3 },
  80. { 3, (unsigned char []) {IAC, WILL, TELOPT_MSSP}, &client_recv_will_mssp },
  81. { 3, (unsigned char []) {IAC, SB, TELOPT_MSSP}, &client_recv_sb_mssp },
  82. { 3, (unsigned char []) {IAC, SB, TELOPT_MSDP}, &client_recv_sb_msdp },
  83. { 3, (unsigned char []) {IAC, SB, TELOPT_GMCP}, &client_recv_sb_gmcp },
  84. { 3, (unsigned char []) {IAC, SB, TELOPT_CHARSET}, &client_recv_sb_charset },
  85. { 3, (unsigned char []) {IAC, SB, TELOPT_NEW_ENVIRON}, &client_recv_sb_new_environ },
  86. { 6, (unsigned char []) {IAC, SB, TELOPT_TSPEED, ENV_SEND, IAC, SE}, &client_recv_sb_tspeed },
  87. { 3, (unsigned char []) {IAC, DONT, TELOPT_TTYPE}, &client_recv_dont_ttype },
  88. { 6, (unsigned char []) {IAC, SB, TELOPT_TTYPE, ENV_SEND, IAC, SE}, &client_recv_sb_ttype },
  89. { 3, (unsigned char []) {IAC, SB, TELOPT_ZMP}, &client_recv_sb_zmp },
  90. { 5, (unsigned char []) {IAC, SB, TELOPT_MCCP1, IAC, SE}, &client_init_mccp2 },
  91. { 5, (unsigned char []) {IAC, SB, TELOPT_MCCP2, IAC, SE}, &client_init_mccp2 },
  92. { 2, (unsigned char []) {IAC, EOR}, &client_mark_prompt },
  93. { 2, (unsigned char []) {IAC, GA}, &client_mark_prompt },
  94. { 0, NULL, NULL }
  95. };
  96. void client_telopt_debug(struct session *ses, char *format, ...)
  97. {
  98. char buf[BUFFER_SIZE];
  99. va_list args;
  100. if (HAS_BIT(ses->telopts, TELOPT_FLAG_DEBUG))
  101. {
  102. va_start(args, format);
  103. vsprintf(buf, format, args);
  104. va_end(args);
  105. tintin_puts(ses, buf);
  106. }
  107. }
  108. int client_translate_telopts(struct session *ses, unsigned char *src, int cplen)
  109. {
  110. int skip, cnt, retval;
  111. unsigned char *cpdst, *cpsrc;
  112. push_call("client_translate_telopts(%p,%p,%d)",ses,src,cplen);
  113. if (cplen == 0)
  114. {
  115. gtd->mud_output_buf[gtd->mud_output_len] = 0;
  116. pop_call();
  117. return 0;
  118. }
  119. if (ses->mccp2)
  120. {
  121. ses->mccp2->next_in = src;
  122. ses->mccp2->avail_in = cplen;
  123. ses->mccp2->next_out = gtd->mccp_buf;
  124. ses->mccp2->avail_out = gtd->mccp_len;
  125. inflate:
  126. retval = inflate(ses->mccp2, Z_SYNC_FLUSH);
  127. switch (retval)
  128. {
  129. case Z_BUF_ERROR:
  130. if (ses->mccp2->avail_out == 0)
  131. {
  132. gtd->mccp_len *= 2;
  133. gtd->mccp_buf = (unsigned char *) realloc(gtd->mccp_buf, gtd->mccp_len);
  134. ses->mccp2->avail_out = gtd->mccp_len / 2;
  135. ses->mccp2->next_out = gtd->mccp_buf + gtd->mccp_len / 2;
  136. goto inflate;
  137. }
  138. else
  139. {
  140. tintin_puts2(ses, "");
  141. tintin_puts2(ses, "#COMPRESSION ERROR, Z_BUF_ERROR, DISABLING MCCP2.");
  142. client_send_dont_mccp2(ses, 0, NULL);
  143. inflateEnd(ses->mccp2);
  144. free(ses->mccp2);
  145. ses->mccp2 = NULL;
  146. cpsrc = src;
  147. cplen = 0;
  148. }
  149. break;
  150. case Z_OK:
  151. if (ses->mccp2->avail_out == 0)
  152. {
  153. gtd->mccp_len *= 2;
  154. gtd->mccp_buf = (unsigned char *) realloc(gtd->mccp_buf, gtd->mccp_len);
  155. ses->mccp2->avail_out = gtd->mccp_len / 2;
  156. ses->mccp2->next_out = gtd->mccp_buf + gtd->mccp_len / 2;
  157. goto inflate;
  158. }
  159. cplen = ses->mccp2->next_out - gtd->mccp_buf;
  160. cpsrc = gtd->mccp_buf;
  161. break;
  162. case Z_STREAM_END:
  163. client_telopt_debug(ses, "#COMPRESSION END, DISABLING MCCP2.");
  164. cnt = ses->mccp2->next_out - gtd->mccp_buf;
  165. cpsrc = src + (cplen - ses->mccp2->avail_in);
  166. cplen = ses->mccp2->avail_in;
  167. inflateEnd(ses->mccp2);
  168. free(ses->mccp2);
  169. ses->mccp2 = NULL;
  170. client_translate_telopts(ses, gtd->mccp_buf, cnt);
  171. break;
  172. default:
  173. tintin_puts2(ses, "");
  174. tintin_printf2(ses, "#COMPRESSION ERROR, DISABLING MCCP2, RETVAL %d.", retval);
  175. client_send_dont_mccp2(ses, 0, NULL);
  176. inflateEnd(ses->mccp2);
  177. free(ses->mccp2);
  178. ses->mccp2 = NULL;
  179. cpsrc = src;
  180. cplen = 0;
  181. break;
  182. }
  183. }
  184. else
  185. {
  186. cpsrc = src;
  187. }
  188. if (HAS_BIT(ses->logmode, LOG_FLAG_LOW) && ses->logfile)
  189. {
  190. fwrite(cpsrc, 1, cplen, ses->logfile);
  191. }
  192. if (ses->read_len + cplen >= ses->read_max)
  193. {
  194. ses->read_max = ses->read_len + cplen + 1000;
  195. ses->read_buf = (unsigned char *) realloc(ses->read_buf, ses->read_max);
  196. }
  197. memcpy(ses->read_buf + ses->read_len, cpsrc, cplen);
  198. cpsrc = ses->read_buf;
  199. cplen = ses->read_len + cplen;
  200. if (gtd->mud_output_len + cplen >= gtd->mud_output_max)
  201. {
  202. gtd->mud_output_max = gtd->mud_output_len + cplen + 1000;
  203. gtd->mud_output_buf = (char *) realloc(gtd->mud_output_buf, gtd->mud_output_max);
  204. }
  205. cpdst = (unsigned char *) gtd->mud_output_buf + gtd->mud_output_len;
  206. while (cplen > 0)
  207. {
  208. if (*cpsrc == IAC && HAS_BIT(ses->flags, SES_FLAG_TELNET) && !HAS_BIT(ses->flags, SES_FLAG_RUN))
  209. {
  210. skip = 2;
  211. if (HAS_BIT(ses->telopts, TELOPT_FLAG_DEBUG))
  212. {
  213. switch(cpsrc[1])
  214. {
  215. case NOP:
  216. case DM:
  217. case BREAK:
  218. case IP:
  219. case AO:
  220. case AYT:
  221. case EC:
  222. case EL:
  223. case IAC:
  224. case GA:
  225. case EOR:
  226. tintin_printf2(ses, "RCVD IAC %s", TELCMD(cpsrc[1]));
  227. break;
  228. case DO:
  229. case DONT:
  230. case WILL:
  231. case WONT:
  232. if (cplen > 2)
  233. {
  234. tintin_printf2(ses, "RCVD IAC %s %s", TELCMD(cpsrc[1]), telopt_table[cpsrc[2]].name);
  235. }
  236. else
  237. {
  238. tintin_printf2(ses, "RCVD IAC %s %d (BAD TELOPT)", TELCMD(cpsrc[1]), cpsrc[2]);
  239. }
  240. break;
  241. case SB:
  242. if (cplen > 2)
  243. {
  244. tintin_printf2(ses, "RCVD IAC SB %s", telopt_table[cpsrc[2]].name);
  245. }
  246. break;
  247. default:
  248. if (TELCMD_OK(cpsrc[1]))
  249. {
  250. tintin_printf2(ses, "RCVD IAC %s %d", TELCMD(cpsrc[1]), cpsrc[2]);
  251. }
  252. else
  253. {
  254. tintin_printf2(ses, "RCVD IAC %d %d", cpsrc[1], cpsrc[2]);
  255. }
  256. break;
  257. }
  258. }
  259. for (cnt = 0 ; iac_client_table[cnt].code ; cnt++)
  260. {
  261. if (cplen < iac_client_table[cnt].size && !memcmp(cpsrc, iac_client_table[cnt].code, cplen))
  262. {
  263. skip = iac_client_table[cnt].size; // broken packet handling
  264. break;
  265. }
  266. if (cplen >= iac_client_table[cnt].size && !memcmp(cpsrc, iac_client_table[cnt].code, iac_client_table[cnt].size))
  267. {
  268. skip = iac_client_table[cnt].func(ses, cplen, cpsrc);
  269. if (iac_client_table[cnt].func == client_init_mccp2)
  270. {
  271. pop_call();
  272. return client_translate_telopts(ses, cpsrc + skip, cplen - skip);
  273. }
  274. break;
  275. }
  276. }
  277. if (iac_client_table[cnt].code == NULL && cplen > 1)
  278. {
  279. switch (cpsrc[1])
  280. {
  281. case SE:
  282. case NOP:
  283. case DM:
  284. case BREAK:
  285. case IP:
  286. case AO:
  287. case AYT:
  288. case EC:
  289. case EL:
  290. case GA:
  291. case EOR:
  292. skip = 2;
  293. break;
  294. case WILL:
  295. if (cplen > 2)
  296. {
  297. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 1, 0, "IAC WILL %s", telopt_table[cpsrc[2]].name) && !check_all_events(ses, SUB_ARG|SUB_SEC, 1, 0, "CATCH IAC WILL %s", telopt_table[cpsrc[2]].name))
  298. {
  299. if (!HAS_BIT(ses->telopt_flag[cpsrc[2] / 32], 1 << cpsrc[2] % 32))
  300. {
  301. if (telopt_table[cpsrc[2]].want)
  302. {
  303. skip = client_send_do_telopt(ses, cplen, cpsrc);
  304. }
  305. else
  306. {
  307. skip = client_send_dont_telopt(ses, cplen, cpsrc);
  308. }
  309. SET_BIT(ses->telopt_flag[cpsrc[2] / 32], 1 << cpsrc[2] % 32);
  310. }
  311. }
  312. }
  313. skip = 3;
  314. break;
  315. case DO:
  316. if (cplen > 2)
  317. {
  318. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 1, 0, "IAC DO %s", telopt_table[cpsrc[2]].name) && !check_all_events(ses, SUB_ARG|SUB_SEC, 1, 0, "IAC DO %s", telopt_table[cpsrc[2]].name))
  319. {
  320. if (!HAS_BIT(ses->telopt_flag[cpsrc[2] / 32], 1 << cpsrc[2] % 32))
  321. {
  322. if (telopt_table[cpsrc[2]].want)
  323. {
  324. skip = client_send_will_telopt(ses, cplen, cpsrc);
  325. }
  326. else
  327. {
  328. skip = client_send_wont_telopt(ses, cplen, cpsrc);
  329. }
  330. SET_BIT(ses->telopt_flag[cpsrc[2] / 32], 1 << cpsrc[2] % 32);
  331. }
  332. }
  333. }
  334. skip = 3;
  335. break;
  336. case WONT:
  337. case DONT:
  338. if (cplen > 2)
  339. {
  340. check_all_events(ses, SUB_ARG|SUB_SEC, 2, 0, "IAC %s %s", TELCMD(cpsrc[1]), telopt_table[cpsrc[2]].name);
  341. DEL_BIT(ses->telopt_flag[cpsrc[2] / 32], 1 << cpsrc[2] % 32);
  342. }
  343. skip = 3;
  344. break;
  345. case SB:
  346. skip = client_recv_sb(ses, cplen, cpsrc);
  347. break;
  348. case IAC:
  349. gtd->mud_output_len++;
  350. *cpdst++ = 0xFF;
  351. skip = 2;
  352. break;
  353. default:
  354. tintin_printf(NULL, "RCVD IAC %d (BAD TELOPT)", cpsrc[1]);
  355. skip = 1;
  356. break;
  357. }
  358. }
  359. if (skip <= cplen)
  360. {
  361. cplen -= skip;
  362. cpsrc += skip;
  363. }
  364. else
  365. {
  366. memmove(ses->read_buf, cpsrc, cplen);
  367. gtd->mud_output_buf[gtd->mud_output_len] = 0;
  368. pop_call();
  369. return cplen;
  370. }
  371. }
  372. else
  373. {
  374. /*
  375. skip '\0' and '\r' in text input
  376. */
  377. switch (*cpsrc)
  378. {
  379. case ASCII_NUL:
  380. cpsrc++;
  381. cplen--;
  382. continue;
  383. case ASCII_ENQ:
  384. check_all_events(ses, SUB_ARG, 0, 1, "VT100 ENQ", gtd->term); // obsolete, but we'll handle it for now.
  385. cpsrc++;
  386. cplen--;
  387. continue;
  388. case ASCII_CR:
  389. if (cplen > 1 && cpsrc[1] == ASCII_LF)
  390. {
  391. cpsrc++;
  392. cplen--;
  393. continue;
  394. }
  395. break;
  396. case ASCII_LF:
  397. if (HAS_BIT(ses->telopts, TELOPT_FLAG_PROMPT))
  398. {
  399. DEL_BIT(ses->telopts, TELOPT_FLAG_PROMPT);
  400. }
  401. *cpdst++ = *cpsrc++;
  402. gtd->mud_output_len++;
  403. cplen--;
  404. while (*cpsrc == ASCII_CR)
  405. {
  406. cpsrc++;
  407. cplen--;
  408. }
  409. continue;
  410. default:
  411. if (cpsrc[0] == ASCII_ESC)
  412. {
  413. if (cplen >= 2 && cpsrc[1] == 'Z')
  414. {
  415. check_all_events(ses, SUB_ARG, 0, 0, "VT100 DECID");
  416. cpsrc += 2;
  417. cplen -= 2;
  418. continue;
  419. }
  420. if (cplen >= 3 && cpsrc[1] == '[')
  421. {
  422. if (cpsrc[2] == 'c')
  423. {
  424. check_all_events(ses, SUB_ARG, 0, 0, "VT100 DA");
  425. cpsrc += 3;
  426. cplen -= 3;
  427. continue;
  428. }
  429. if (cplen >= 4)
  430. {
  431. if (cpsrc[2] >= '5' && cpsrc[2] <= '6' && cpsrc[3] == 'n')
  432. {
  433. if (cpsrc[2] == '5')
  434. {
  435. check_all_events(ses, SUB_ARG, 0, 0, "VT100 DSR");
  436. }
  437. if (cpsrc[2] == '6')
  438. {
  439. check_all_events(ses, SUB_ARG, 0, 2, "VT100 CPR", ntos(gtd->screen->cols), ntos(gtd->screen->rows));
  440. }
  441. cpsrc += 4;
  442. cplen -= 4;
  443. continue;
  444. }
  445. if (cpsrc[2] == '0' && cpsrc[3] == 'c')
  446. {
  447. check_all_events(ses, SUB_ARG, 0, 0, "VT100 DA");
  448. cpsrc += 4;
  449. cplen -= 4;
  450. continue;
  451. }
  452. }
  453. }
  454. if (cplen >= 3 && cpsrc[1] == ']')
  455. {
  456. char osc[BUFFER_SIZE];
  457. for (skip = 2 ; cplen >= skip ; skip++)
  458. {
  459. if (cpsrc[skip] == ASCII_BEL)
  460. {
  461. break;
  462. }
  463. }
  464. sprintf(osc, "%.*s", skip - 2, cpsrc + 2);
  465. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "VT100 OSC", osc);
  466. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "CATCH VT100 OSC", osc))
  467. {
  468. cpsrc += skip;
  469. cplen -= skip;
  470. continue;
  471. }
  472. }
  473. }
  474. if (HAS_BIT(ses->telopts, TELOPT_FLAG_PROMPT))
  475. {
  476. DEL_BIT(ses->telopts, TELOPT_FLAG_PROMPT);
  477. /*
  478. Fix up non vt muds
  479. */
  480. if (HAS_BIT(ses->flags, SES_FLAG_SPLIT) || !IS_SPLIT(ses))
  481. {
  482. *cpdst++ = '\n';
  483. gtd->mud_output_len++;
  484. }
  485. }
  486. break;
  487. }
  488. *cpdst++ = *cpsrc++;
  489. gtd->mud_output_len++;
  490. cplen--;
  491. }
  492. }
  493. gtd->mud_output_buf[gtd->mud_output_len] = 0;
  494. pop_call();
  495. return 0;
  496. }
  497. /*
  498. SGA
  499. */
  500. int client_recv_will_sga(struct session *ses, int cplen, unsigned char *cpsrc)
  501. {
  502. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC WILL SGA"))
  503. {
  504. return 3;
  505. }
  506. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC WILL SGA");
  507. SET_BIT(ses->telopts, TELOPT_FLAG_SGA);
  508. if (!HAS_BIT(ses->telopt_flag[TELOPT_SGA / 32], 1 << TELOPT_SGA % 32))
  509. {
  510. SET_BIT(ses->telopt_flag[TELOPT_SGA / 32], 1 << TELOPT_SGA % 32);
  511. telnet_printf(ses, 3, "%c%c%c", IAC, DO, TELOPT_SGA);
  512. client_telopt_debug(ses, "SENT IAC DO %s", telopt_table[TELOPT_SGA].name);
  513. }
  514. return 3;
  515. }
  516. int client_recv_do_sga(struct session *ses, int cplen, unsigned char *cpsrc)
  517. {
  518. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC DO SGA"))
  519. {
  520. return 3;
  521. }
  522. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC DO SGA");
  523. SET_BIT(ses->telopts, TELOPT_FLAG_SGA);
  524. if (!HAS_BIT(ses->telopt_flag[TELOPT_SGA / 32], 1 << TELOPT_SGA % 32))
  525. {
  526. SET_BIT(ses->telopt_flag[TELOPT_SGA / 32], 1 << TELOPT_SGA % 32);
  527. telnet_printf(ses, 3, "%c%c%c", IAC, WILL, TELOPT_SGA);
  528. client_telopt_debug(ses, "SENT IAC WILL %s", telopt_table[TELOPT_SGA].name);
  529. }
  530. return 3;
  531. }
  532. int client_mark_prompt(struct session *ses, int cplen, unsigned char *cpsrc)
  533. {
  534. SET_BIT(ses->telopts, TELOPT_FLAG_PROMPT);
  535. if (cpsrc[1] == GA)
  536. {
  537. check_all_events(ses, SUB_ARG, 0, 0, "IAC GA");
  538. }
  539. else if (cpsrc[1] == EOR)
  540. {
  541. check_all_events(ses, SUB_ARG, 0, 0, "IAC EOR");
  542. }
  543. return 2;
  544. }
  545. /*
  546. TTYPE
  547. */
  548. int client_recv_dont_ttype(struct session *ses, int cplen, unsigned char *cpsrc)
  549. {
  550. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC DONT TTYPE"))
  551. {
  552. return 3;
  553. }
  554. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC DONT TTYPE");
  555. DEL_BIT(ses->telopts, TELOPT_FLAG_TTYPE);
  556. DEL_BIT(ses->telopt_flag[cpsrc[2] / 32], 1 << cpsrc[2] % 32);
  557. return 3;
  558. }
  559. int client_recv_sb_ttype(struct session *ses, int cplen, unsigned char *cpsrc)
  560. {
  561. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "CATCH IAC SB TTYPE", ntos(cpsrc[3])))
  562. {
  563. return 6;
  564. }
  565. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "IAC SB TTYPE", ntos(cpsrc[3]));
  566. if (HAS_BIT(ses->telopts, TELOPT_FLAG_MTTS))
  567. {
  568. char mtts[BUFFER_SIZE];
  569. sprintf(mtts, "MTTS %d",
  570. (ses->color > 0 ? 1 : 0) +
  571. (HAS_BIT(ses->flags, SES_FLAG_SPLIT) ? 0 : 2) +
  572. (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && !HAS_BIT(ses->charset, CHARSET_FLAG_ALL_TOUTF8) ? 4 : 0) +
  573. (ses->color > 16 ? 8 : 0) +
  574. (HAS_BIT(ses->flags, SES_FLAG_SCREENREADER) ? 64 : 0) +
  575. (ses->color > 256 ? 256 : 0));
  576. telnet_printf(ses, 6 + strlen(mtts), "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE, 0, mtts, IAC, SE);
  577. client_telopt_debug(ses, "SENT IAC SB TTYPE %s", mtts);
  578. }
  579. else if (HAS_BIT(ses->telopts, TELOPT_FLAG_TTYPE))
  580. {
  581. telnet_printf(ses, 6 + strlen(gtd->term), "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE, 0, gtd->term, IAC, SE);
  582. client_telopt_debug(ses, "SENT IAC SB TTYPE %s", gtd->term);
  583. SET_BIT(ses->telopts, TELOPT_FLAG_MTTS);
  584. }
  585. else
  586. {
  587. telnet_printf(ses, 14, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TTYPE, 0, "TINTIN++", IAC, SE);
  588. client_telopt_debug(ses, "SENT IAC SB TTYPE %s", "TINTIN++");
  589. SET_BIT(ses->telopts, TELOPT_FLAG_TTYPE);
  590. }
  591. return 6;
  592. }
  593. /*
  594. TSPEED
  595. */
  596. int client_recv_sb_tspeed(struct session *ses, int cplen, unsigned char *cpsrc)
  597. {
  598. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "CATCH IAC SB TSPEED", ntos(cpsrc[3])))
  599. {
  600. return 6;
  601. }
  602. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 1, "IAC SB TSPEED", ntos(cpsrc[3]));
  603. SET_BIT(ses->telopts, TELOPT_FLAG_TSPEED);
  604. telnet_printf(ses, 17, "%c%c%c%c%s%c%c", IAC, SB, TELOPT_TSPEED, 0, "38400,38400", IAC, SE);
  605. client_telopt_debug(ses, "SENT IAC SB 0 %s 38400,38400 IAC SB", telopt_table[TELOPT_TSPEED].name);
  606. return 6;
  607. }
  608. /*
  609. NAWS
  610. */
  611. int client_recv_do_naws(struct session *ses, int cplen, unsigned char *cpsrc)
  612. {
  613. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC DO NAWS"))
  614. {
  615. return 3;
  616. }
  617. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC DO NAWS");
  618. SET_BIT(ses->telopts, TELOPT_FLAG_NAWS);
  619. if (!HAS_BIT(ses->telopt_flag[TELOPT_NAWS / 32], 1 << TELOPT_NAWS % 32))
  620. {
  621. SET_BIT(ses->telopt_flag[TELOPT_NAWS / 32], 1 << TELOPT_NAWS % 32);
  622. telnet_printf(ses, 3, "%c%c%c", IAC, WILL, TELOPT_NAWS);
  623. client_telopt_debug(ses, "SENT IAC WILL NAWS");
  624. }
  625. return client_send_sb_naws(ses, cplen, cpsrc);
  626. }
  627. int client_send_sb_naws(struct session *ses, int cplen, unsigned char *cpsrc)
  628. {
  629. int rows;
  630. int cols;
  631. rows = HAS_BIT(ses->flags, SES_FLAG_SPLIT) ? ses->split->bot_row - ses->split->top_row + 1 : gtd->screen->rows;
  632. cols = get_scroll_cols(ses);
  633. // Properly handle row and colum size of 255
  634. if (cols % 256 == IAC && gtd->screen->rows % 256 == IAC)
  635. {
  636. telnet_printf(ses, 11, "%c%c%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_NAWS, cols / 256, IAC, cols % 256, rows / 256, IAC, rows % 256, IAC, SE);
  637. }
  638. else if (cols % 256 == IAC)
  639. {
  640. telnet_printf(ses, 10, "%c%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_NAWS, cols / 256, IAC, cols % 256, rows / 256, rows % 256, IAC, SE);
  641. }
  642. else if (gtd->screen->rows % 256 == IAC)
  643. {
  644. telnet_printf(ses, 10, "%c%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_NAWS, cols / 256, cols % 256, rows / 256, IAC, rows % 256, IAC, SE);
  645. }
  646. else
  647. {
  648. telnet_printf(ses, 9, "%c%c%c%c%c%c%c%c%c", IAC, SB, TELOPT_NAWS, cols / 256, cols % 256, rows / 256, rows % 256, IAC, SE);
  649. }
  650. client_telopt_debug(ses, "SENT IAC SB NAWS %d %d %d %d", cols / 256, cols % 256, gtd->screen->rows / 256, gtd->screen->rows % 256);
  651. return 3;
  652. }
  653. // Server requests client to enable local echo
  654. int client_recv_wont_echo(struct session *ses, int cplen, unsigned char *cpsrc)
  655. {
  656. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC WONT ECHO"))
  657. {
  658. return 3;
  659. }
  660. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC WONT ECHO");
  661. SET_BIT(ses->telopts, TELOPT_FLAG_ECHO);
  662. if (HAS_BIT(ses->telopt_flag[TELOPT_ECHO / 32], 1 << TELOPT_ECHO % 32))
  663. {
  664. DEL_BIT(ses->telopt_flag[TELOPT_ECHO / 32], 1 << TELOPT_ECHO % 32);
  665. // telnet_printf(ses, 3, "%c%c%c", IAC, DONT, TELOPT_ECHO);
  666. client_telopt_debug(ses, "SENT IAC DONT ECHO (SKIPPED)");
  667. }
  668. else
  669. {
  670. client_telopt_debug(ses, "DID NOT SEND IAC DONT ECHO, INFINITE LOOP PROTECTION.");
  671. }
  672. return 3;
  673. }
  674. // Server requests client to disable local echo
  675. int client_recv_will_echo(struct session *ses, int cplen, unsigned char *cpsrc)
  676. {
  677. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC WILL ECHO"))
  678. {
  679. return 3;
  680. }
  681. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC WILL ECHO");
  682. DEL_BIT(ses->telopts, TELOPT_FLAG_ECHO);
  683. if (!HAS_BIT(ses->telopt_flag[TELOPT_ECHO / 32], 1 << TELOPT_ECHO % 32))
  684. {
  685. SET_BIT(ses->telopt_flag[TELOPT_ECHO / 32], 1 << TELOPT_ECHO % 32);
  686. telnet_printf(ses, 3, "%c%c%c", IAC, DO, TELOPT_ECHO);
  687. client_telopt_debug(ses, "SENT IAC DO ECHO (SKIPPED)");
  688. }
  689. else
  690. {
  691. client_telopt_debug(ses, "DID NOT SEND IAC DO ECHO, INFINITE LOOP PROTECTION.");
  692. }
  693. return 3;
  694. }
  695. // Shouldn't be received, but we'll handle it as a disable local echo request
  696. int client_recv_do_echo(struct session *ses, int cplen, unsigned char *cpsrc)
  697. {
  698. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC DO ECHO"))
  699. {
  700. return 3;
  701. }
  702. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC DO ECHO");
  703. DEL_BIT(ses->telopts, TELOPT_FLAG_ECHO);
  704. if (!HAS_BIT(ses->telopt_flag[TELOPT_ECHO / 32], 1 << TELOPT_ECHO % 32))
  705. {
  706. SET_BIT(ses->telopt_flag[TELOPT_ECHO / 32], 1 << TELOPT_ECHO % 32);
  707. telnet_printf(ses, 3, "%c%c%c", IAC, WILL, TELOPT_ECHO);
  708. client_telopt_debug(ses, "SENT IAC WILL ECHO");
  709. }
  710. else
  711. {
  712. client_telopt_debug(ses, "DID NOT SEND IAC WILL ECHO, INFINITE LOOP PROTECTION.");
  713. }
  714. return 3;
  715. }
  716. /*
  717. IP
  718. */
  719. int client_send_ip(struct session *ses, int cplen, unsigned char *cpsrc)
  720. {
  721. telnet_printf(ses, 5, "%c%c%c%c%c", IAC, IP, IAC, DO, TELOPT_TIMINGMARK);
  722. client_telopt_debug(ses, "SENT IAC IP");
  723. client_telopt_debug(ses, "SENT IAC DO TIMING MARK");
  724. return 3;
  725. }
  726. /*
  727. Automatic telopt handling
  728. */
  729. int client_send_wont_telopt(struct session *ses, int cplen, unsigned char *cpsrc)
  730. {
  731. telnet_printf(ses, 3, "%c%c%c", IAC, WONT, cpsrc[2]);
  732. client_telopt_debug(ses, "SENT IAC WONT %s", telopt_table[cpsrc[2]].name);
  733. return 3;
  734. }
  735. int client_send_dont_telopt(struct session *ses, int cplen, unsigned char *cpsrc)
  736. {
  737. telnet_printf(ses, 3, "%c%c%c", IAC, DONT, cpsrc[2]);
  738. client_telopt_debug(ses, "SENT IAC DONT %s", telopt_table[cpsrc[2]].name);
  739. return 3;
  740. }
  741. int client_send_will_telopt(struct session *ses, int cplen, unsigned char *cpsrc)
  742. {
  743. telnet_printf(ses, 3, "%c%c%c", IAC, WILL, cpsrc[2]);
  744. client_telopt_debug(ses, "SENT IAC WILL %s", telopt_table[cpsrc[2]].name);
  745. return 3;
  746. }
  747. int client_send_do_telopt(struct session *ses, int cplen, unsigned char *cpsrc)
  748. {
  749. telnet_printf(ses, 3, "%c%c%c", IAC, DO, cpsrc[2]);
  750. client_telopt_debug(ses, "SENT IAC DO %s", telopt_table[cpsrc[2]].name);
  751. return 3;
  752. }
  753. /*
  754. MSSP (Mud Server Status Protocol)
  755. */
  756. int client_recv_will_mssp(struct session *ses, int cplen, unsigned char *cpsrc)
  757. {
  758. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC WILL MSSP") && !check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC WILL MSSP"))
  759. {
  760. if (HAS_BIT(ses->telopts, TELOPT_FLAG_DEBUG))
  761. {
  762. telnet_printf(ses, 3, "%c%c%c", IAC, DO, TELOPT_MSSP);
  763. client_telopt_debug(ses, "SENT IAC DO MSSP");
  764. }
  765. }
  766. return 3;
  767. }
  768. int client_recv_sb_mssp(struct session *ses, int cplen, unsigned char *src)
  769. {
  770. char var[BUFFER_SIZE], val[BUFFER_SIZE];
  771. char *pto;
  772. int i;
  773. var[0] = val[0] = i = 0;
  774. if (client_skip_sb(ses, cplen, src) > cplen)
  775. {
  776. return cplen + 1;
  777. }
  778. while (i < cplen && src[i] != SE)
  779. {
  780. switch (src[i])
  781. {
  782. case MSSP_VAR:
  783. i++;
  784. pto = var;
  785. while (i < cplen && src[i] >= 3 && src[i] != IAC)
  786. {
  787. *pto++ = src[i++];
  788. }
  789. *pto = 0;
  790. break;
  791. case MSSP_VAL:
  792. i++;
  793. pto = val;
  794. while (i < cplen && src[i] >= 3 && src[i] != IAC)
  795. {
  796. *pto++ = src[i++];
  797. }
  798. *pto = 0;
  799. client_telopt_debug(ses, "RCVD IAC SB MSSP VAR %-20s VAL %s", var, val);
  800. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 2, "IAC SB MSSP", var, val);
  801. check_all_events(ses, SUB_ARG|SUB_SEC, 1, 2, "IAC SB MSSP %s", var, var, val);
  802. break;
  803. default:
  804. i++;
  805. break;
  806. }
  807. }
  808. client_telopt_debug(ses, "RCVD IAC SB MSSP IAC SE");
  809. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC SB MSSP IAC SE");
  810. return UMIN(i + 1, cplen);
  811. }
  812. /*
  813. MSDP (Mud Server Data Protocol)
  814. */
  815. int client_recv_sb_msdp(struct session *ses, int cplen, unsigned char *src)
  816. {
  817. char var[BUFFER_SIZE], val[BUFFER_SIZE], plain[BUFFER_SIZE], *pto;
  818. int i, nest, state[100], last;
  819. var[0] = val[0] = state[0] = nest = last = 0;
  820. if (client_skip_sb(ses, cplen, src) > cplen)
  821. {
  822. return cplen + 1;
  823. }
  824. i = 3;
  825. pto = var;
  826. while (i < cplen && nest < 99)
  827. {
  828. if (src[i] == IAC && src[i+1] == SE)
  829. {
  830. break;
  831. }
  832. switch (src[i])
  833. {
  834. case MSDP_TABLE_OPEN:
  835. nest++;
  836. state[nest] = 0;
  837. last = MSDP_TABLE_OPEN;
  838. break;
  839. case MSDP_TABLE_CLOSE:
  840. if (nest)
  841. {
  842. if (last == MSDP_VAL || last == MSDP_VAR)
  843. {
  844. *pto++ = '}';
  845. }
  846. nest--;
  847. }
  848. if (nest)
  849. {
  850. *pto++ = '}';
  851. }
  852. last = MSDP_TABLE_CLOSE;
  853. break;
  854. case MSDP_ARRAY_OPEN:
  855. nest++;
  856. state[nest] = 1;
  857. last = MSDP_ARRAY_OPEN;
  858. break;
  859. case MSDP_ARRAY_CLOSE:
  860. if (nest)
  861. {
  862. if (last == MSDP_VAL)
  863. {
  864. *pto++ = '}';
  865. }
  866. nest--;
  867. }
  868. if (nest)
  869. {
  870. *pto++ = '}';
  871. }
  872. last = MSDP_ARRAY_CLOSE;
  873. break;
  874. case MSDP_VAR:
  875. if (nest)
  876. {
  877. if (last == MSDP_VAL)
  878. {
  879. *pto++ = '}';
  880. }
  881. *pto++ = '{';
  882. }
  883. else
  884. {
  885. *pto = 0;
  886. if (last)
  887. {
  888. strip_vt102_codes(val, plain);
  889. client_telopt_debug(ses, "RCVD IAC SB MSDP VAR %-20s VAL %s", var, val);
  890. check_all_events(ses, SUB_ARG, 1, 3, "IAC SB MSDP %s", var, var, val, plain);
  891. check_all_events(ses, SUB_ARG, 0, 3, "IAC SB MSDP", var, val, plain);
  892. }
  893. pto = var;
  894. }
  895. last = MSDP_VAR;
  896. break;
  897. case MSDP_VAL:
  898. if (nest)
  899. {
  900. if (last == MSDP_VAR || last == MSDP_VAL)
  901. {
  902. *pto++ = '}';
  903. }
  904. if (state[nest])
  905. {
  906. pto += sprintf(pto, "{%d}", state[nest]++);
  907. }
  908. *pto++ = '{';
  909. }
  910. else
  911. {
  912. *pto = 0;
  913. if (last != MSDP_VAR)
  914. {
  915. strip_vt102_codes(val, plain);
  916. client_telopt_debug(ses, "RCVD IAC SB MSDP VAR %-20s VAL %s", var, val);
  917. check_all_events(ses, SUB_ARG, 1, 3, "IAC SB MSDP %s", var, var, val, plain);
  918. check_all_events(ses, SUB_ARG, 0, 3, "IAC SB MSDP", var, val, plain);
  919. }
  920. pto = val;
  921. }
  922. last = MSDP_VAL;
  923. break;
  924. case '\r':
  925. break;
  926. case '\\':
  927. *pto++ = '\\';
  928. *pto++ = '\\';
  929. break;
  930. case '{':
  931. *pto++ = '\\';
  932. *pto++ = 'x';
  933. *pto++ = '7';
  934. *pto++ = 'B';
  935. break;
  936. case '}':
  937. *pto++ = '\\';
  938. *pto++ = 'x';
  939. *pto++ = '7';
  940. *pto++ = 'D';
  941. break;
  942. case COMMAND_SEPARATOR:
  943. *pto++ = '\\';
  944. *pto++ = COMMAND_SEPARATOR;
  945. break;
  946. default:
  947. *pto++ = src[i];
  948. break;
  949. }
  950. i++;
  951. }
  952. if (src[i] == IAC && nest < 99)
  953. {
  954. *pto = 0;
  955. if (last)
  956. {
  957. strip_vt102_codes(val, plain);
  958. client_telopt_debug(ses, "RCVD IAC SB MSDP VAR %-20s VAL %s", var, val);
  959. check_all_events(ses, SUB_ARG, 1, 3, "IAC SB MSDP %s", var, var, val, plain);
  960. check_all_events(ses, SUB_ARG, 0, 3, "IAC SB MSDP", var, val, plain);
  961. }
  962. i++;
  963. }
  964. var[0] = val[0] = last = 0;
  965. i = 3;
  966. pto = var;
  967. while (i < cplen && nest < 99)
  968. {
  969. if (src[i] == IAC && src[i+1] == SE)
  970. {
  971. break;
  972. }
  973. switch (src[i])
  974. {
  975. case MSDP_TABLE_OPEN:
  976. *pto++ = '{';
  977. nest++;
  978. state[nest] = 0;
  979. last = MSDP_TABLE_OPEN;
  980. break;
  981. case MSDP_TABLE_CLOSE:
  982. if (last == MSDP_VAL || last == MSDP_VAR)
  983. {
  984. *pto++ = '"';
  985. }
  986. if (nest)
  987. {
  988. nest--;
  989. }
  990. *pto++ = '}';
  991. last = MSDP_TABLE_CLOSE;
  992. break;
  993. case MSDP_ARRAY_OPEN:
  994. *pto++ = '[';
  995. nest++;
  996. state[nest] = 1;
  997. last = MSDP_ARRAY_OPEN;
  998. break;
  999. case MSDP_ARRAY_CLOSE:
  1000. if (last == MSDP_VAL || last == MSDP_VAR)
  1001. {
  1002. *pto++ = '"';
  1003. }
  1004. if (nest)
  1005. {
  1006. nest--;
  1007. }
  1008. *pto++ = ']';
  1009. last = MSDP_ARRAY_CLOSE;
  1010. break;
  1011. case MSDP_VAR:
  1012. if (nest)
  1013. {
  1014. if (last == MSDP_VAL || last == MSDP_VAR)
  1015. {
  1016. *pto++ = '"';
  1017. }
  1018. if (last == MSDP_VAL || last == MSDP_VAR || last == MSDP_TABLE_CLOSE || last == MSDP_ARRAY_CLOSE)
  1019. {
  1020. *pto++ = ',';
  1021. }
  1022. *pto++ = '"';
  1023. }
  1024. else
  1025. {
  1026. *pto = 0;
  1027. if (last)
  1028. {
  1029. strip_vt102_codes(val, plain);
  1030. check_all_events(ses, SUB_ARG, 1, 2, "IAC SB MSDP2JSON %s", var, var, plain);
  1031. check_all_events(ses, SUB_ARG, 0, 2, "IAC SB MSDP2JSON", var, plain);
  1032. }
  1033. pto = var;
  1034. }
  1035. last = MSDP_VAR;
  1036. break;
  1037. case MSDP_VAL:
  1038. if (nest)
  1039. {
  1040. if (last == MSDP_VAR)
  1041. {
  1042. *pto++ = '"';
  1043. *pto++ = ':';
  1044. }
  1045. if (last == MSDP_VAL)
  1046. {
  1047. *pto++ = '"';
  1048. *pto++ = ',';
  1049. }
  1050. if (src[i+1] != MSDP_TABLE_OPEN && src[i+1] != MSDP_ARRAY_OPEN)
  1051. {
  1052. *pto++ = '"';
  1053. }
  1054. }
  1055. else
  1056. {
  1057. *pto = 0;
  1058. if (last != MSDP_VAR)
  1059. {
  1060. strip_vt102_codes(val, plain);
  1061. check_all_events(ses, SUB_ARG, 1, 2, "IAC SB MSDP2JSON %s", var, var, plain);
  1062. check_all_events(ses, SUB_ARG, 0, 2, "IAC SB MSDP2JSON", var, plain);
  1063. }
  1064. pto = val;
  1065. }
  1066. last = MSDP_VAL;
  1067. break;
  1068. case '\\':
  1069. *pto++ = '\\';
  1070. *pto++ = '\\';
  1071. break;
  1072. case '{':
  1073. *pto++ = '\\';
  1074. *pto++ = 'x';
  1075. *pto++ = '7';
  1076. *pto++ = 'B';
  1077. break;
  1078. case '}':
  1079. *pto++ = '\\';
  1080. *pto++ = 'x';
  1081. *pto++ = '7';
  1082. *pto++ = 'D';
  1083. break;
  1084. case COMMAND_SEPARATOR:
  1085. *pto++ = '\\';
  1086. *pto++ = COMMAND_SEPARATOR;
  1087. break;
  1088. default:
  1089. *pto++ = src[i];
  1090. break;
  1091. }
  1092. i++;
  1093. }
  1094. if (src[i] == IAC && nest < 99)
  1095. {
  1096. *pto = 0;
  1097. if (last)
  1098. {
  1099. strip_vt102_codes(val, plain);
  1100. check_all_events(ses, SUB_ARG, 1, 2, "IAC SB MSDP2JSON %s", var, var, plain);
  1101. check_all_events(ses, SUB_ARG, 0, 2, "IAC SB MSDP2JSON", var, plain);
  1102. }
  1103. i++;
  1104. }
  1105. client_telopt_debug(ses, "RCVD IAC SB MSDP IAC SE");
  1106. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC SB MSDP IAC SE");
  1107. return UMIN(i + 1, cplen);
  1108. }
  1109. /*
  1110. CHARSET
  1111. */
  1112. int client_recv_sb_charset(struct session *ses, int cplen, unsigned char *src)
  1113. {
  1114. char buf[BUFFER_SIZE], var[BUFFER_SIZE];
  1115. char *pto;
  1116. int i;
  1117. if (client_skip_sb(ses, cplen, src) > cplen)
  1118. {
  1119. return cplen + 1;
  1120. }
  1121. client_telopt_debug(ses, "IAC SB CHARSET %d %d", src[3], src[4]);
  1122. i = 5;
  1123. while (i < cplen && src[i] != SE)
  1124. {
  1125. pto = buf;
  1126. while (i < cplen && src[i] != src[4] && src[i] != IAC)
  1127. {
  1128. *pto++ = src[i++];
  1129. }
  1130. *pto = 0;
  1131. substitute(ses, buf, var, SUB_SEC);
  1132. switch (src[3])
  1133. {
  1134. case CHARSET_REQUEST:
  1135. strcpy(buf, "REQUEST");
  1136. break;
  1137. case CHARSET_ACCEPTED:
  1138. strcpy(buf, "ACCEPTED");
  1139. break;
  1140. case CHARSET_REJECTED:
  1141. strcpy(buf, "REJECTED");
  1142. break;
  1143. default:
  1144. sprintf(buf, "%d", src[4]);
  1145. break;
  1146. }
  1147. client_telopt_debug(ses, "IAC SB CHARSET %s %s", buf, var);
  1148. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 2, "IAC SB CHARSET", buf, var);
  1149. check_all_events(ses, SUB_ARG|SUB_SEC, 2, 2, "IAC SB CHARSET %s %s", buf, var, buf, var);
  1150. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 2, 2, "CATCH IAC SB CHARSET %s %s", buf, var, buf, var))
  1151. {
  1152. if (!strcmp(buf, "REQUEST"))
  1153. {
  1154. if (!strcasecmp(var, "UTF-8"))
  1155. {
  1156. if (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && !HAS_BIT(ses->charset, CHARSET_FLAG_ALL_TOUTF8))
  1157. {
  1158. telnet_printf(ses, 12, "%c%c%c%c UTF-8%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_ACCEPTED, IAC, SE);
  1159. client_telopt_debug(ses, "SENT IAC SB CHARSET ACCEPTED UTF-8");
  1160. }
  1161. else
  1162. {
  1163. telnet_printf(ses, 12, "%c%c%c%c UTF-8%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_REJECTED, IAC, SE);
  1164. client_telopt_debug(ses, "SENT IAC SB CHARSET REJECTED UTF-8");
  1165. }
  1166. }
  1167. else if (!strcasecmp(var, "BIG-5"))
  1168. {
  1169. if (HAS_BIT(ses->charset, CHARSET_FLAG_BIG5) || HAS_BIT(ses->charset, CHARSET_FLAG_BIG5TOUTF8))
  1170. {
  1171. telnet_printf(ses, 11, "%c%c%c%c BIG-5%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_ACCEPTED, IAC, SE);
  1172. client_telopt_debug(ses, "SENT IAC SB CHARSET ACCEPTED BIG-5");
  1173. }
  1174. else
  1175. {
  1176. telnet_printf(ses, 11, "%c%c%c%c BIG-5%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_REJECTED, IAC, SE);
  1177. client_telopt_debug(ses, "SENT IAC SB CHARSET REJECTED BIG-5");
  1178. }
  1179. }
  1180. else if (!strcasecmp(var, "FANSI"))
  1181. {
  1182. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 2, 2, "CATCH IAC SB CHARSET %s %s", buf, var, buf, var))
  1183. {
  1184. if (HAS_BIT(ses->charset, CHARSET_FLAG_FANSITOUTF8))
  1185. {
  1186. telnet_printf(ses, 11, "%c%c%c%c FANSI%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_ACCEPTED, IAC, SE);
  1187. client_telopt_debug(ses, "SENT IAC SB CHARSET ACCEPTED FANSI");
  1188. }
  1189. else
  1190. {
  1191. telnet_printf(ses, 11, "%c%c%c%c FANSI%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_REJECTED, IAC, SE);
  1192. client_telopt_debug(ses, "SENT IAC SB CHARSET REJECTED FANSI");
  1193. }
  1194. }
  1195. }
  1196. else if (!strcasecmp(var, "ISO-8859-1") || !strcasecmp(var, "ISO-1"))
  1197. {
  1198. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 2, 2, "CATCH IAC SB CHARSET %s %s", buf, var, buf, var))
  1199. {
  1200. if (HAS_BIT(ses->charset, CHARSET_FLAG_ISO1TOUTF8))
  1201. {
  1202. telnet_printf(ses, 11, "%c%c%c%c %s%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_ACCEPTED, var, IAC, SE);
  1203. client_telopt_debug(ses, "SENT IAC SB CHARSET ACCEPTED %s", var);
  1204. }
  1205. else
  1206. {
  1207. telnet_printf(ses, 11, "%c%c%c%c %s%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_REJECTED, var, IAC, SE);
  1208. client_telopt_debug(ses, "SENT IAC SB CHARSET REJECTED %s", var);
  1209. }
  1210. }
  1211. }
  1212. else if (!strcasecmp(var, "ISO-8859-2") || !strcasecmp(var, "ISO-2"))
  1213. {
  1214. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 2, 2, "CATCH IAC SB CHARSET %s %s", buf, var, buf, var))
  1215. {
  1216. if (HAS_BIT(ses->charset, CHARSET_FLAG_ISO2TOUTF8))
  1217. {
  1218. telnet_printf(ses, 11, "%c%c%c%c %s%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_ACCEPTED, var, IAC, SE);
  1219. client_telopt_debug(ses, "SENT IAC SB CHARSET ACCEPTED %s", var);
  1220. }
  1221. else
  1222. {
  1223. telnet_printf(ses, 11, "%c%c%c%c %s%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_REJECTED, var, IAC, SE);
  1224. client_telopt_debug(ses, "SENT IAC SB CHARSET REJECTED %s", var);
  1225. }
  1226. }
  1227. }
  1228. else if (!strcasecmp(var, "GBK-1"))
  1229. {
  1230. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 2, 2, "CATCH IAC SB CHARSET %s %s", buf, var, buf, var))
  1231. {
  1232. if (HAS_BIT(ses->charset, CHARSET_FLAG_GBK1TOUTF8))
  1233. {
  1234. telnet_printf(ses, 11, "%c%c%c%c GBK-1%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_ACCEPTED, IAC, SE);
  1235. client_telopt_debug(ses, "SENT IAC SB CHARSET ACCEPTED GBK-1");
  1236. }
  1237. else
  1238. {
  1239. telnet_printf(ses, 11, "%c%c%c%c GB-18030%c%c", IAC, SB, TELOPT_CHARSET, CHARSET_REJECTED, IAC, SE);
  1240. client_telopt_debug(ses, "SENT IAC SB CHARSET REJECTED GBK-1");
  1241. }
  1242. }
  1243. }
  1244. }
  1245. }
  1246. i++;
  1247. }
  1248. client_telopt_debug(ses, "IAC SB CHARSET IAC SE");
  1249. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC SB CHARSET IAC SE");
  1250. return i + 1;
  1251. }
  1252. /*
  1253. NEW-ENVIRON
  1254. */
  1255. int get_mtts_val(struct session *ses)
  1256. {
  1257. return
  1258. (ses->color > 0 ? 1 : 0)
  1259. +
  1260. (HAS_BIT(ses->flags, SES_FLAG_SPLIT) ? 0 : 2)
  1261. +
  1262. (HAS_BIT(ses->charset, CHARSET_FLAG_UTF8) && !HAS_BIT(ses->charset, CHARSET_FLAG_ALL_TOUTF8) ? 4 : 0)
  1263. +
  1264. (ses->color > 16 ? 8 : 0)
  1265. +
  1266. (HAS_BIT(ses->flags, SES_FLAG_SCREENREADER) ? 64 : 0)
  1267. +
  1268. // proxy ? 128 : 0
  1269. // +
  1270. (ses->color > 256 ? 256 : 0)
  1271. +
  1272. 512;
  1273. }
  1274. int client_recv_sb_new_environ(struct session *ses, int cplen, unsigned char *src)
  1275. {
  1276. char buf[BUFFER_SIZE], var[BUFFER_SIZE], val[BUFFER_SIZE], sub1[NUMBER_SIZE], sub2[NUMBER_SIZE];
  1277. char *pto;
  1278. int i;
  1279. var[0] = val[0] = 0;
  1280. if (client_skip_sb(ses, cplen, src) > cplen)
  1281. {
  1282. return cplen + 1;
  1283. }
  1284. client_telopt_debug(ses, "IAC SB NEW-ENVIRON %d %d", src[3], src[4]);
  1285. switch (src[3])
  1286. {
  1287. case ENV_IS:
  1288. strcpy(sub1, "IS");
  1289. break;
  1290. case ENV_SEND:
  1291. strcpy(sub1, "SEND");
  1292. break;
  1293. case ENV_INFO:
  1294. strcpy(sub1, "INFO");
  1295. break;
  1296. default:
  1297. strcpy(sub1, "UNKNOWN");
  1298. break;
  1299. }
  1300. i = 4;
  1301. while (i < cplen && src[i] != SE)
  1302. {
  1303. switch (src[i])
  1304. {
  1305. case ENV_VAR:
  1306. strcpy(sub2, "VAR");
  1307. break;
  1308. case ENV_VAL:
  1309. strcpy(sub2, "VAL");
  1310. break;
  1311. case ENV_USR:
  1312. strcpy(sub2, "USERVAR");
  1313. break;
  1314. default:
  1315. strcpy(sub2, "UNKNOWN");
  1316. break;
  1317. }
  1318. switch (src[i])
  1319. {
  1320. case ENV_VAR:
  1321. case ENV_USR:
  1322. i++;
  1323. pto = buf;
  1324. while (i < cplen && src[i] >= 4 && src[i] != IAC)
  1325. {
  1326. *pto++ = src[i++];
  1327. }
  1328. *pto = 0;
  1329. substitute(ses, buf, var, SUB_SEC);
  1330. if (src[3] == ENV_SEND)
  1331. {
  1332. client_telopt_debug(ses, "IAC SB NEW-ENVIRON SEND %s", sub2);
  1333. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "CATCH IAC SB NEW-ENVIRON", sub1, sub2, var, ""))
  1334. {
  1335. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "IAC SB NEW-ENVIRON", sub1, sub2, var, "");
  1336. if (!check_all_events(ses, SUB_ARG|SUB_SEC, 1, 4, "CATCH IAC SB NEW-ENVIRON SEND %s", var, sub1, sub2, var, ""))
  1337. {
  1338. check_all_events(ses, SUB_ARG|SUB_SEC, 1, 4, "IAC SB NEW-ENVIRON SEND %s", var, sub1, sub2, var, "");
  1339. if (*var == 0)
  1340. {
  1341. telnet_printf(ses, -1, "%c%c%c" "%c%c%s%c%s" "%c%c%s%c%s" "%c%c%s%c%s" "%c%c%s%c%s" "%c%c%s%c%s" "%c%c",
  1342. IAC, SB, TELOPT_NEW_ENVIRON,
  1343. ENV_IS, ENV_VAR, "CHARSET", ENV_VAL, get_charset(ses),
  1344. ENV_IS, ENV_VAR, "CLIENT_NAME", ENV_VAL, CLIENT_NAME,
  1345. ENV_IS, ENV_VAR, "CLIENT_VERSION", ENV_VAL, CLIENT_VERSION,
  1346. ENV_IS, ENV_VAR, "MTTS", ENV_VAL, get_mtts_val(ses),
  1347. ENV_IS, ENV_VAR, "TERMINAL_TYPE", ENV_VAL, gtd->term,
  1348. IAC, SE);
  1349. }
  1350. else if (!strcasecmp(var, "CHARSET"))
  1351. {
  1352. telnet_printf(ses, -1, "%c%c%c%c%c%s%c%s%c%c", IAC, SB, TELOPT_NEW_ENVIRON, ENV_IS, ENV_VAR, "CHARSET", ENV_VAL, get_charset(ses), IAC, SE);
  1353. client_telopt_debug(ses, "SENT IAC SB NEW-ENVIRON IS VAR %s VAL %s", "CHARSET", get_charset(ses));
  1354. }
  1355. else if (!strcasecmp(var, "CLIENT_NAME"))
  1356. {
  1357. telnet_printf(ses, -1, "%c%c%c%c%c%s%c%s%c%c", IAC, SB, TELOPT_NEW_ENVIRON, ENV_IS, ENV_VAR, "CLIENT_NAME", ENV_VAL, CLIENT_NAME, IAC, SE);
  1358. client_telopt_debug(ses, "SENT IAC SB NEW-ENVIRON IS VAR %s VAL %s", "CLIENT_NAME", CLIENT_NAME);
  1359. }
  1360. else if (!strcasecmp(var, "CLIENT_VERSION"))
  1361. {
  1362. telnet_printf(ses, -1, "%c%c%c%c%c%s%c%s%c%c", IAC, SB, TELOPT_NEW_ENVIRON, ENV_IS, ENV_VAR, "CLIENT_VERSION", ENV_VAL, CLIENT_VERSION, IAC, SE);
  1363. client_telopt_debug(ses, "SENT IAC SB NEW-ENVIRON IS VAR %s VAL %s", "CLIENT_VERSION", CLIENT_VERSION);
  1364. }
  1365. else if (!strcasecmp(var, "MTTS") || *var == 0)
  1366. {
  1367. telnet_printf(ses, -1, "%c%c%c%c%c%s%c%d%c%c", IAC, SB, TELOPT_NEW_ENVIRON, ENV_IS, ENV_VAR, "MTTS", ENV_VAL, get_mtts_val(ses), IAC, SE);
  1368. client_telopt_debug(ses, "SENT IAC SB NEW-ENVIRON IS VAR MTTS VAL %d", get_mtts_val(ses));
  1369. }
  1370. else if (!strcasecmp(var, "TERMINAL_TYPE"))
  1371. {
  1372. telnet_printf(ses, -1, "%c%c%c%c%c%s%c%s%c%c", IAC, SB, TELOPT_NEW_ENVIRON, ENV_IS, ENV_VAR, "TERMINAL_TYPE", ENV_VAL, gtd->term, IAC, SE);
  1373. client_telopt_debug(ses, "SENT IAC SB NEW-ENVIRON IS VAR TERMINAL_TYPE VAL %s", gtd->term);
  1374. }
  1375. }
  1376. }
  1377. }
  1378. break;
  1379. case ENV_VAL:
  1380. i++;
  1381. pto = buf;
  1382. while (i < cplen && src[i] >= 4 && src[i] != IAC)
  1383. {
  1384. *pto++ = src[i++];
  1385. }
  1386. *pto = 0;
  1387. substitute(ses, buf, val, SUB_SEC);
  1388. client_telopt_debug(ses, "IAC SB NEW-ENVIRON %s %s", sub1, sub2);
  1389. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 4, "IAC SB NEW-ENVIRON", sub1, sub2, var, val);
  1390. check_all_events(ses, SUB_ARG|SUB_SEC, 2, 4, "IAC SB NEW-ENVIRON %s %s", sub1, sub2, sub1, sub2, var, val);
  1391. break;
  1392. case IAC:
  1393. client_telopt_debug(ses, "IAC SB NEW-ENVIRON (ERROR) %s %s (%s) (%s)", sub1, sub2, var, val);
  1394. i++;
  1395. break;
  1396. default:
  1397. client_telopt_debug(ses, "IAC SB NEW-ENVIRON (ERROR) %03d %c", src[i], src[i]);
  1398. i++;
  1399. break;
  1400. }
  1401. }
  1402. client_telopt_debug(ses, "IAC SB NEW-ENVIRON IAC SE");
  1403. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC SB NEW-ENVIRON IAC SE");
  1404. return i + 1;
  1405. }
  1406. int client_recv_sb_zmp(struct session *ses, int cplen, unsigned char *src)
  1407. {
  1408. char buf[BUFFER_SIZE], var[BUFFER_SIZE], val[BUFFER_SIZE];
  1409. char *pto;
  1410. int i, x;
  1411. var[0] = val[0] = x = 0;
  1412. if (client_skip_sb(ses, cplen, src) > cplen)
  1413. {
  1414. return cplen + 1;
  1415. }
  1416. i = 3;
  1417. while (i < cplen && src[i] != SE)
  1418. {
  1419. switch (src[i])
  1420. {
  1421. case IAC:
  1422. i++;
  1423. break;
  1424. default:
  1425. pto = buf;
  1426. while (i < cplen && src[i])
  1427. {
  1428. *pto++ = src[i++];
  1429. }
  1430. *pto = src[i++];
  1431. substitute(ses, buf, x ? val : var, SUB_SEC);
  1432. if (x++)
  1433. {
  1434. client_telopt_debug(ses, "IAC SB ZMP %s", var);
  1435. check_all_events(ses, SUB_ARG|SUB_SEC, 1, 1, "IAC SB ZMP %s", var, val);
  1436. }
  1437. break;
  1438. }
  1439. }
  1440. client_telopt_debug(ses, "IAC SB ZMP %s IAC SE", var);
  1441. check_all_events(ses, SUB_ARG|SUB_SEC, 1, 0, "IAC SB ZMP %s IAC SE", var);
  1442. return UMIN(i + 1, cplen);
  1443. }
  1444. int client_recv_sb_gmcp(struct session *ses, int cplen, unsigned char *src)
  1445. {
  1446. char mod[BUFFER_SIZE], val[BUFFER_SIZE], json[BUFFER_SIZE], *pto;
  1447. int i, state[100], nest, type;
  1448. push_call("client_recv_sb_gmcp(%p,%d,%p)",ses,cplen,src);
  1449. if (client_skip_sb(ses, cplen, src) > cplen)
  1450. {
  1451. pop_call();
  1452. return cplen + 1;
  1453. }
  1454. mod[0] = val[0] = state[0] = nest = type = 0;
  1455. i = 3;
  1456. pto = mod;
  1457. // space out
  1458. while (i < cplen && src[i] == ' ')
  1459. {
  1460. i++;
  1461. }
  1462. // grab module
  1463. while (i < cplen && src[i] != IAC)
  1464. {
  1465. if (src[i] == ' ' || src[i] == '{' || src[i] == '[')
  1466. {
  1467. break;
  1468. }
  1469. *pto++ = src[i++];
  1470. }
  1471. *pto = 0;
  1472. // parse JSON content
  1473. pto = val;
  1474. while (i < cplen && src[i] != IAC && nest < 99)
  1475. {
  1476. switch (src[i])
  1477. {
  1478. case ' ':
  1479. i++;
  1480. break;
  1481. case '{':
  1482. if (nest != 0)
  1483. {
  1484. *pto++ = '{';
  1485. }
  1486. i++;
  1487. state[++nest] = 0;
  1488. break;
  1489. case '}':
  1490. nest--;
  1491. i++;
  1492. if (nest != 0)
  1493. {
  1494. *pto++ = '}';
  1495. }
  1496. break;
  1497. case '[':
  1498. if (nest != 0)
  1499. {
  1500. *pto++ = '{';
  1501. }
  1502. i++;
  1503. state[++nest] = 1;
  1504. pto += sprintf(pto, "{%d}", state[nest]);
  1505. break;
  1506. case ']':
  1507. nest--;
  1508. i++;
  1509. if (nest != 0)
  1510. {
  1511. *pto++ = '}';
  1512. }
  1513. break;
  1514. case ':':
  1515. i++;
  1516. break;
  1517. case ',':
  1518. i++;
  1519. if (state[nest])
  1520. {
  1521. pto += sprintf(pto, "{%d}", ++state[nest]);
  1522. }
  1523. break;
  1524. case '"':
  1525. i++;
  1526. if (nest)
  1527. {
  1528. *pto++ = '{';
  1529. }
  1530. type = 1;
  1531. while (i < cplen && src[i] != IAC && type == 1)
  1532. {
  1533. switch (src[i])
  1534. {
  1535. case '\\':
  1536. i++;
  1537. if (i < cplen && src[i] == '"')
  1538. {
  1539. *pto++ = src[i++];
  1540. }
  1541. else
  1542. {
  1543. *pto++ = '\\';
  1544. }
  1545. break;
  1546. case '"':
  1547. i++;
  1548. type = 0;
  1549. break;
  1550. case '{':
  1551. i++;
  1552. *pto++ = '\\';
  1553. *pto++ = 'x';
  1554. *pto++ = '7';
  1555. *pto++ = 'B';
  1556. break;
  1557. case '}':
  1558. i++;
  1559. *pto++ = '\\';
  1560. *pto++ = 'x';
  1561. *pto++ = '7';
  1562. *pto++ = 'D';
  1563. break;
  1564. case COMMAND_SEPARATOR:
  1565. i++;
  1566. *pto++ = '\\';
  1567. *pto++ = COMMAND_SEPARATOR;
  1568. break;
  1569. default:
  1570. *pto++ = src[i++];
  1571. break;
  1572. }
  1573. }
  1574. if (nest)
  1575. {
  1576. *pto++ = '}';
  1577. }
  1578. break;
  1579. default:
  1580. if (nest)
  1581. {
  1582. *pto++ = '{';
  1583. }
  1584. type = 1;
  1585. while (i < cplen && src[i] != IAC && type == 1)
  1586. {
  1587. switch (src[i])
  1588. {
  1589. case '}':
  1590. case ']':
  1591. case ',':
  1592. case ':':
  1593. type = 0;
  1594. break;
  1595. case ' ':
  1596. i++;
  1597. break;
  1598. default:
  1599. *pto++ = src[i++];
  1600. break;
  1601. }
  1602. }
  1603. if (nest)
  1604. {
  1605. *pto++ = '}';
  1606. }
  1607. break;
  1608. }
  1609. }
  1610. *pto = 0;
  1611. // Raw json data for debugging purposes.
  1612. pto = json;
  1613. i = 3;
  1614. while (i < cplen && src[i] != IAC)
  1615. {
  1616. switch (src[i])
  1617. {
  1618. case '\\':
  1619. i++;
  1620. *pto++ = '\\';
  1621. *pto++ = '\\';
  1622. break;
  1623. case '{':
  1624. i++;
  1625. *pto++ = '\\';
  1626. *pto++ = 'x';
  1627. *pto++ = '7';
  1628. *pto++ = 'B';
  1629. break;
  1630. case '}':
  1631. i++;
  1632. *pto++ = '\\';
  1633. *pto++ = 'x';
  1634. *pto++ = '7';
  1635. *pto++ = 'D';
  1636. break;
  1637. case COMMAND_SEPARATOR:
  1638. i++;
  1639. *pto++ = '\\';
  1640. *pto++ = COMMAND_SEPARATOR;
  1641. break;
  1642. default:
  1643. *pto++ = src[i++];
  1644. break;
  1645. }
  1646. }
  1647. *pto = 0;
  1648. while (i < cplen && src[i] != SE)
  1649. {
  1650. i++;
  1651. }
  1652. client_telopt_debug(ses, "IAC SB GMCP %s IAC SE", mod);
  1653. check_all_events(ses, SUB_ARG, 1, 2, "IAC SB GMCP %s IAC SE", mod, val, json);
  1654. pop_call();
  1655. return UMIN(i + 1, cplen);
  1656. }
  1657. /*
  1658. MCCP2
  1659. */
  1660. int client_recv_will_mccp2(struct session *ses, int cplen, unsigned char *cpsrc)
  1661. {
  1662. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC WILL MCCP2"))
  1663. {
  1664. return 3;
  1665. }
  1666. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC WILL MCCP2");
  1667. if (HAS_BIT(ses->flags, SES_FLAG_MCCP))
  1668. {
  1669. telnet_printf(ses, 3, "%c%c%c", IAC, DO, TELOPT_MCCP2);
  1670. client_telopt_debug(ses, "SENT IAC DO MCCP2");
  1671. }
  1672. else
  1673. {
  1674. telnet_printf(ses, 3, "%c%c%c", IAC, DONT, TELOPT_MCCP2);
  1675. client_telopt_debug(ses, "SENT IAC DONT MCCP2 (#CONFIG MCCP HAS BEEN DISABLED)");
  1676. }
  1677. return 3;
  1678. }
  1679. int client_send_dont_mccp2(struct session *ses, int cplen, unsigned char *cpsrc)
  1680. {
  1681. telnet_printf(ses, 3, "%c%c%c", IAC, DONT, TELOPT_MCCP2);
  1682. client_telopt_debug(ses, "SENT DONT MCCP2");
  1683. return 3;
  1684. }
  1685. int client_init_mccp2(struct session *ses, int cplen, unsigned char *cpsrc)
  1686. {
  1687. if (ses->mccp2)
  1688. {
  1689. return 5;
  1690. }
  1691. ses->mccp2 = (z_stream *) calloc(1, sizeof(z_stream));
  1692. ses->mccp2->data_type = Z_ASCII;
  1693. ses->mccp2->zalloc = zlib_alloc;
  1694. ses->mccp2->zfree = zlib_free;
  1695. ses->mccp2->opaque = NULL;
  1696. if (inflateInit(ses->mccp2) != Z_OK)
  1697. {
  1698. tintin_puts2(ses, "MCCP2: FAILED TO INITIALIZE");
  1699. client_send_dont_mccp2(ses, 0, NULL);
  1700. free(ses->mccp2);
  1701. ses->mccp2 = NULL;
  1702. }
  1703. else
  1704. {
  1705. client_telopt_debug(ses, "MCCP2: INITIALIZED");
  1706. }
  1707. return 5;
  1708. }
  1709. void client_end_mccp2(struct session *ses)
  1710. {
  1711. if (ses->mccp2 == NULL)
  1712. {
  1713. return;
  1714. }
  1715. if (deflateEnd(ses->mccp2) != Z_OK)
  1716. {
  1717. tintin_printf2(ses, "MCCP2: FAILED TO DEFLATE_END");
  1718. }
  1719. free(ses->mccp2);
  1720. ses->mccp2 = NULL;
  1721. client_telopt_debug(ses, "MCCP2: COMPRESSION END, DISABLING MCCP2");
  1722. return;
  1723. }
  1724. // MCCP3
  1725. int client_recv_will_mccp3(struct session *ses, int cplen, unsigned char *cpsrc)
  1726. {
  1727. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC WILL MCCP3"))
  1728. {
  1729. return 3;
  1730. }
  1731. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC WILL MCCP3");
  1732. if (HAS_BIT(ses->flags, SES_FLAG_MCCP))
  1733. {
  1734. telnet_printf(ses, 3, "%c%c%c", IAC, DO, TELOPT_MCCP3);
  1735. client_telopt_debug(ses, "SENT IAC DO MCCP3");
  1736. client_init_mccp3(ses);
  1737. }
  1738. else
  1739. {
  1740. telnet_printf(ses, 3, "%c%c%c", IAC, DONT, TELOPT_MCCP3);
  1741. client_telopt_debug(ses, "SENT IAC DONT MCCP3 (#CONFIG MCCP HAS BEEN DISABLED)");
  1742. }
  1743. return 3;
  1744. }
  1745. int client_recv_dont_mccp3(struct session *ses, int cplen, unsigned char *cpsrc)
  1746. {
  1747. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC DONT MCCP3"))
  1748. {
  1749. return 3;
  1750. }
  1751. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC DONT MCCP3");
  1752. if (ses->mccp3)
  1753. {
  1754. client_end_mccp3(ses);
  1755. }
  1756. return 3;
  1757. }
  1758. int client_recv_wont_mccp3(struct session *ses, int cplen, unsigned char *cpsrc)
  1759. {
  1760. if (check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "CATCH IAC WONT MCCP3"))
  1761. {
  1762. return 3;
  1763. }
  1764. check_all_events(ses, SUB_ARG|SUB_SEC, 0, 0, "IAC WONT MCCP3");
  1765. if (ses->mccp3)
  1766. {
  1767. client_end_mccp3(ses);
  1768. }
  1769. return 3;
  1770. }
  1771. int client_init_mccp3(struct session *ses)
  1772. {
  1773. z_stream *stream;
  1774. if (ses->mccp3)
  1775. {
  1776. client_telopt_debug(ses, "MCCP3: ALREADY INITIALIZED");
  1777. return TRUE;
  1778. }
  1779. stream = calloc(1, sizeof(z_stream));
  1780. stream->next_in = NULL;
  1781. stream->avail_in = 0;
  1782. stream->next_out = gtd->mccp_buf;
  1783. stream->avail_out = gtd->mccp_len;
  1784. stream->data_type = Z_ASCII;
  1785. stream->zalloc = zlib_alloc;
  1786. stream->zfree = zlib_free;
  1787. stream->opaque = Z_NULL;
  1788. if (deflateInit(stream, Z_BEST_COMPRESSION) != Z_OK)
  1789. {
  1790. client_telopt_debug(ses, "MCCP3: FAILED TO INITIALIZE");
  1791. free(stream);
  1792. return FALSE;
  1793. }
  1794. telnet_printf(ses, 5, "%c%c%c%c%c", IAC, SB, TELOPT_MCCP3, IAC, SE);
  1795. client_telopt_debug(ses, "SENT IAC SB MCCP3 IAC SE");
  1796. client_telopt_debug(ses, "MCCP3: INITIALIZED");
  1797. ses->mccp3 = stream;
  1798. return TRUE;
  1799. }
  1800. void client_end_mccp3(struct session *ses)
  1801. {
  1802. if (ses->mccp3 == NULL)
  1803. {
  1804. return;
  1805. }
  1806. ses->mccp3->next_in = NULL;
  1807. ses->mccp3->avail_in = 0;
  1808. ses->mccp3->next_out = gtd->mccp_buf;
  1809. ses->mccp3->avail_out = gtd->mccp_len;
  1810. if (deflate(ses->mccp3, Z_FINISH) != Z_STREAM_END)
  1811. {
  1812. tintin_printf2(ses, "MCCP3: FAILED TO DEFLATE");
  1813. }
  1814. // process_compressed(d);
  1815. if (deflateEnd(ses->mccp3) != Z_OK)
  1816. {
  1817. tintin_printf2(ses, "MCCP3: FAILED TO DEFLATE_END");
  1818. }
  1819. free(ses->mccp3);
  1820. ses->mccp3 = NULL;
  1821. client_telopt_debug(ses, "MCCP3: COMPRESSION END, DISABLING MCCP3");
  1822. return;
  1823. }
  1824. int client_write_compressed(struct session *ses, char *txt, int length)
  1825. {
  1826. int result;
  1827. ses->mccp3->next_in = (unsigned char *) txt;
  1828. ses->mccp3->avail_in = length;
  1829. ses->mccp3->next_out = gtd->mccp_buf;
  1830. ses->mccp3->avail_out = gtd->mccp_len;
  1831. if (deflate(ses->mccp3, Z_SYNC_FLUSH) != Z_OK)
  1832. {
  1833. syserr_printf(ses, "client_write_compressed: deflate");
  1834. return 0;
  1835. }
  1836. #ifdef HAVE_GNUTLS_H
  1837. if (ses->ssl)
  1838. {
  1839. result = gnutls_record_send(ses->ssl, gtd->mccp_buf, gtd->mccp_len - ses->mccp3->avail_out);
  1840. while (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN)
  1841. {
  1842. result = gnutls_record_send(ses->ssl, 0, 0);
  1843. }
  1844. return result;
  1845. }
  1846. else
  1847. #endif
  1848. result = write(ses->socket, gtd->mccp_buf, gtd->mccp_len - ses->mccp3->avail_out);
  1849. if (result < 1)
  1850. {
  1851. syserr_printf(ses, "client_write_compressed: write");
  1852. return -1;
  1853. }
  1854. return result;
  1855. }
  1856. /*
  1857. Returns the length of a telnet subnegotiation
  1858. */
  1859. int client_skip_sb(struct session *ses, int cplen, unsigned char *cpsrc)
  1860. {
  1861. int i;
  1862. for (i = 1 ; i < cplen ; i++)
  1863. {
  1864. if (cpsrc[i] == SE && cpsrc[i-1] == IAC)
  1865. {
  1866. return i + 1;
  1867. }
  1868. }
  1869. client_telopt_debug(ses, "SKIP SB (%d)", cplen);
  1870. return cplen + 1;
  1871. }
  1872. int client_recv_sb(struct session *ses, int cplen, unsigned char *cpsrc)
  1873. {
  1874. char *pt1, *pt2, var1[BUFFER_SIZE], var2[BUFFER_SIZE];
  1875. int i;
  1876. if (client_skip_sb(ses, cplen, cpsrc) > cplen)
  1877. {
  1878. return cplen + 1;
  1879. }
  1880. pt1 = var1;
  1881. pt2 = var2;
  1882. for (i = 3 ; i < cplen ; i++)
  1883. {
  1884. if (cpsrc[i] == IAC && i + 1 < cplen && cpsrc[i+1] == SE)
  1885. {
  1886. break;
  1887. }
  1888. else
  1889. {
  1890. *pt1++ = cpsrc[i];
  1891. sprintf(pt2, "%03d ", cpsrc[i]);
  1892. pt2 += 4;
  1893. }
  1894. }
  1895. *pt1 = 0;
  1896. *pt2 = 0;
  1897. check_all_events(ses, SUB_ARG|SUB_SEC, 1, 2, "IAC SB %s", telopt_table[cpsrc[2]].name, var1, var2);
  1898. return i + 2;
  1899. }