telopt_client.c 48 KB

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