dcc.c 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078
  1. /*
  2. * dcc.c -- handles:
  3. * activity on a dcc socket
  4. * disconnect on a dcc socket
  5. * ...and that's it! (but it's a LOT)
  6. *
  7. * $Id: dcc.c,v 1.55 2002/03/22 03:53:56 guppy Exp $
  8. */
  9. /*
  10. * Copyright (C) 1997 Robey Pointer
  11. * Copyright (C) 1999, 2000, 2001, 2002 Eggheads Development Team
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License
  15. * as published by the Free Software Foundation; either version 2
  16. * of the License, or (at your option) any later version.
  17. *
  18. * This program is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU General Public License
  24. * along with this program; if not, write to the Free Software
  25. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  26. */
  27. #include "main.h"
  28. #include <ctype.h>
  29. #include <errno.h>
  30. #include "modules.h"
  31. #include "tandem.h"
  32. /* Includes for botnet md5 challenge/response code <cybah> */
  33. #include "md5/md5.h"
  34. extern struct userrec *userlist;
  35. extern struct chanset_t *chanset;
  36. extern Tcl_Interp *interp;
  37. extern time_t now;
  38. extern int egg_numver, connect_timeout, conmask, backgrd,
  39. max_dcc, make_userfile, default_flags, debug_output,
  40. ignore_time, par_telnet_flood;
  41. extern char botnetnick[], ver[], origbotname[], notify_new[];
  42. struct dcc_t *dcc = NULL; /* DCC list */
  43. int dcc_total = 0; /* Total dcc's */
  44. char tempdir[121] = ""; /* Temporary directory
  45. (default: current directory) */
  46. int require_p = 0; /* Require 'p' access to get on the
  47. party line? */
  48. int allow_new_telnets = 0; /* Allow people to introduce themselves
  49. via telnet */
  50. int stealth_telnets = 0; /* Be paranoid? <cybah> */
  51. int use_telnet_banner = 0; /* Display telnet banner? */
  52. char network[41] = "unknown-net"; /* Name of the IRC network you're on */
  53. int password_timeout = 180; /* Time to wait for a password from a user */
  54. int bot_timeout = 60; /* Bot timeout value */
  55. int identtimeout = 5; /* Timeout value for ident lookups */
  56. int dupwait_timeout = 5; /* Timeout for rejecting duplicate entries */
  57. int protect_telnet = 1; /* Even bother with ident lookups :) */
  58. int flood_telnet_thr = 5; /* Number of telnet connections to be
  59. considered a flood */
  60. int flood_telnet_time = 60; /* In how many seconds? */
  61. char bannerfile[121] = "text/banner"; /* File displayed on telnet login */
  62. static void dcc_telnet_hostresolved(int);
  63. static void dcc_telnet_got_ident(int, char *);
  64. static void dcc_telnet_pass(int, int);
  65. static void strip_telnet(int sock, char *buf, int *len)
  66. {
  67. unsigned char *p = (unsigned char *) buf, *o = (unsigned char *) buf;
  68. int mark;
  69. while (*p != 0) {
  70. while ((*p != TLN_IAC) && (*p != 0))
  71. *o++ = *p++;
  72. if (*p == TLN_IAC) {
  73. p++;
  74. mark = 2;
  75. if (!*p)
  76. mark = 1; /* bogus */
  77. if ((*p >= TLN_WILL) && (*p <= TLN_DONT)) {
  78. mark = 3;
  79. if (!*(p + 1))
  80. mark = 2; /* bogus */
  81. }
  82. if (*p == TLN_WILL) {
  83. /* WILL X -> response: DONT X */
  84. /* except WILL ECHO which we just smile and ignore */
  85. if (*(p + 1) != TLN_ECHO) {
  86. write(sock, TLN_IAC_C TLN_DONT_C, 2);
  87. write(sock, p + 1, 1);
  88. }
  89. }
  90. if (*p == TLN_DO) {
  91. /* DO X -> response: WONT X */
  92. /* except DO ECHO which we just smile and ignore */
  93. if (*(p + 1) != TLN_ECHO) {
  94. write(sock, TLN_IAC_C TLN_WONT_C, 2);
  95. write(sock, p + 1, 1);
  96. }
  97. }
  98. if (*p == TLN_AYT) {
  99. /* "are you there?" */
  100. /* response is: "hell yes!" */
  101. write(sock, "\r\nHell, yes!\r\n", 14);
  102. }
  103. /* Anything else can probably be ignored */
  104. p += mark - 1;
  105. *len = *len - mark;
  106. }
  107. }
  108. *o = *p;
  109. }
  110. static void greet_new_bot(int idx)
  111. {
  112. int bfl = bot_flags(dcc[idx].user);
  113. int i;
  114. dcc[idx].timeval = now;
  115. dcc[idx].u.bot->version[0] = 0;
  116. dcc[idx].u.bot->numver = 0;
  117. if (bfl & BOT_REJECT) {
  118. putlog(LOG_BOTS, "*", DCC_REJECT, dcc[idx].nick);
  119. dprintf(idx, "bye %s\n", "rejected");
  120. killsock(dcc[idx].sock);
  121. lostdcc(idx);
  122. return;
  123. }
  124. if (bfl & BOT_LEAF)
  125. dcc[idx].status |= STAT_LEAF;
  126. dcc[idx].status |= STAT_LINKING;
  127. #ifndef NO_OLD_BOTNET
  128. dprintf(idx, "version %d %d %s <%s>\n", egg_numver, HANDLEN, ver, network);
  129. #else
  130. dprintf(idx, "v %d %d %s <%s>\n", egg_numver, HANDLEN, ver, network);
  131. #endif
  132. for (i = 0; i < dcc_total; i++)
  133. if (dcc[i].type == &DCC_FORK_BOT) {
  134. killsock(dcc[i].sock);
  135. lostdcc(i);
  136. }
  137. }
  138. static void bot_version(int idx, char *par)
  139. {
  140. char x[1024];
  141. int l;
  142. dcc[idx].timeval = now;
  143. if (in_chain(dcc[idx].nick)) {
  144. dprintf(idx, "error Sorry, already connected.\n");
  145. dprintf(idx, "bye\n");
  146. killsock(dcc[idx].sock);
  147. lostdcc(idx);
  148. return;
  149. }
  150. if ((par[0] >= '0') && (par[0] <= '9')) {
  151. char *work;
  152. work = newsplit(&par);
  153. dcc[idx].u.bot->numver = atoi(work);
  154. } else
  155. dcc[idx].u.bot->numver = 0;
  156. #ifndef NO_OLD_BOTNET
  157. if (b_numver(idx) < NEAT_BOTNET) {
  158. #if HANDLEN != 9
  159. putlog(LOG_BOTS, "*", "Non-matching handle lengths with %s, they use 9 characters.",
  160. dcc[idx].nick);
  161. dprintf(idx, "error Non-matching handle length: mine %d, yours 9\n",
  162. HANDLEN);
  163. dprintf(idx, "bye %s\n", "bad handlen");
  164. killsock(dcc[idx].sock);
  165. lostdcc(idx);
  166. return;
  167. #else
  168. dprintf(idx, "thisbot %s\n", botnetnick);
  169. #endif
  170. } else {
  171. #endif
  172. dprintf(idx, "tb %s\n", botnetnick);
  173. l = atoi(newsplit(&par));
  174. if (l != HANDLEN) {
  175. putlog(LOG_BOTS, "*", "Non-matching handle lengths with %s, they use %d characters.",
  176. dcc[idx].nick, l);
  177. dprintf(idx, "error Non-matching handle length: mine %d, yours %d\n",
  178. HANDLEN, l);
  179. dprintf(idx, "bye %s\n", "bad handlen");
  180. killsock(dcc[idx].sock);
  181. lostdcc(idx);
  182. return;
  183. }
  184. #ifndef NO_OLD_BOTNET
  185. }
  186. #endif
  187. strncpyz(dcc[idx].u.bot->version, par, 120);
  188. putlog(LOG_BOTS, "*", DCC_LINKED, dcc[idx].nick);
  189. chatout("*** Linked to %s\n", dcc[idx].nick);
  190. botnet_send_nlinked(idx, dcc[idx].nick, botnetnick, '!',
  191. dcc[idx].u.bot->numver);
  192. touch_laston(dcc[idx].user, "linked", now);
  193. dump_links(idx);
  194. dcc[idx].type = &DCC_BOT;
  195. addbot(dcc[idx].nick, dcc[idx].nick, botnetnick, '-',
  196. dcc[idx].u.bot->numver);
  197. check_tcl_link(dcc[idx].nick, botnetnick);
  198. egg_snprintf(x, sizeof x, "v %d", dcc[idx].u.bot->numver);
  199. bot_share(idx, x);
  200. dprintf(idx, "el\n");
  201. }
  202. void failed_link(int idx)
  203. {
  204. char s[81], s1[512];
  205. if (dcc[idx].port >= dcc[idx].u.bot->port + 3) {
  206. if (dcc[idx].u.bot->linker[0]) {
  207. egg_snprintf(s, sizeof s, "Couldn't link to %s.", dcc[idx].nick);
  208. strcpy(s1, dcc[idx].u.bot->linker);
  209. add_note(s1, botnetnick, s, -2, 0);
  210. }
  211. if (dcc[idx].u.bot->numver >= (-1))
  212. putlog(LOG_BOTS, "*", DCC_LINKFAIL, dcc[idx].nick);
  213. killsock(dcc[idx].sock);
  214. strcpy(s, dcc[idx].nick);
  215. lostdcc(idx);
  216. autolink_cycle(s); /* Check for more auto-connections */
  217. return;
  218. }
  219. /* Try next port */
  220. killsock(dcc[idx].sock);
  221. dcc[idx].sock = getsock(SOCK_STRONGCONN,getprotocol(dcc[idx].host));
  222. dcc[idx].port++;
  223. dcc[idx].timeval = now;
  224. if (dcc[idx].sock < 0 ||
  225. open_telnet_raw(dcc[idx].sock, dcc[idx].addr ?
  226. iptostr(htonl(dcc[idx].addr)) : dcc[idx].host,
  227. dcc[idx].port) < 0) {
  228. failed_link(idx);
  229. }
  230. }
  231. static void cont_link(int idx, char *buf, int i)
  232. {
  233. char x[1024];
  234. int atr = bot_flags(dcc[idx].user);
  235. int users, bots;
  236. if (atr & BOT_HUB) {
  237. /* Disconnect all +a bots because we just got a hub */
  238. for (i = 0; i < dcc_total; i++) {
  239. if ((i != idx) && (bot_flags(dcc[i].user) & BOT_ALT)) {
  240. if ((dcc[i].type == &DCC_FORK_BOT) ||
  241. (dcc[i].type == &DCC_BOT_NEW)) {
  242. killsock(dcc[i].sock);
  243. lostdcc(i);
  244. }
  245. }
  246. }
  247. /* Just those currently in the process of linking */
  248. if (in_chain(dcc[idx].nick)) {
  249. i = nextbot(dcc[idx].nick);
  250. if (i > 0) {
  251. bots = bots_in_subtree(findbot(dcc[idx].nick));
  252. users = users_in_subtree(findbot(dcc[idx].nick));
  253. egg_snprintf(x, sizeof x,
  254. "Unlinked %s (restructure) (lost %d bot%s and %d user%s)",
  255. dcc[i].nick, bots, (bots != 1) ? "s" : "",
  256. users, (users != 1) ? "s" : "");
  257. chatout("*** %s\n", x);
  258. botnet_send_unlinked(i, dcc[i].nick, x);
  259. dprintf(i, "bye %s\n", "restructure");
  260. killsock(dcc[i].sock);
  261. lostdcc(i);
  262. }
  263. }
  264. }
  265. dcc[idx].type = &DCC_BOT_NEW;
  266. dcc[idx].u.bot->numver = 0;
  267. /* Don't send our password here, just the username. The code later on
  268. * will determine if the password needs to be sent in cleartext or if
  269. * we can send an MD5 digest. <cybah>
  270. */
  271. dprintf(idx, "%s\n", botnetnick);
  272. return;
  273. }
  274. /* This function generates a digest by combining 'challenge' with
  275. * 'password' and then sends it to the other bot. <Cybah>
  276. */
  277. static void dcc_bot_digest(int idx, char *challenge, char *password)
  278. {
  279. MD5_CTX md5context;
  280. char digest_string[33]; /* 32 for digest in hex + null */
  281. unsigned char digest[16];
  282. int i;
  283. MD5_Init(&md5context);
  284. MD5_Update(&md5context, (unsigned char *) challenge, strlen(challenge));
  285. MD5_Update(&md5context, (unsigned char *) password, strlen(password));
  286. MD5_Final(digest, &md5context);
  287. for (i = 0; i < 16; i++)
  288. sprintf(digest_string + (i*2), "%.2x", digest[i]);
  289. dprintf(idx, "digest %s\n", digest_string);
  290. putlog(LOG_BOTS, "*", "Received challenge from %s... sending response ...",
  291. dcc[idx].nick);
  292. }
  293. static void dcc_bot_new(int idx, char *buf, int x)
  294. {
  295. struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);
  296. char *code;
  297. strip_telnet(dcc[idx].sock, buf, &x);
  298. code = newsplit(&buf);
  299. if (!egg_strcasecmp(code, "*hello!")) {
  300. greet_new_bot(idx);
  301. } else if (!egg_strcasecmp(code, "version") || !egg_strcasecmp(code, "v")) {
  302. bot_version(idx, buf);
  303. } else if (!egg_strcasecmp(code, "badpass")) {
  304. /* We entered the wrong password */
  305. putlog(LOG_BOTS, "*", DCC_BADPASS, dcc[idx].nick);
  306. } else if (!egg_strcasecmp(code, "passreq")) {
  307. char *pass = get_user(&USERENTRY_PASS, u);
  308. if (!pass || !strcmp(pass, "-")) {
  309. putlog(LOG_BOTS, "*", DCC_PASSREQ, dcc[idx].nick);
  310. dprintf(idx, "-\n");
  311. } else {
  312. /* Determine if the other end supports an MD5 digest instead of a
  313. * cleartext password. <Cybah>
  314. */
  315. if(buf && buf[0] && strchr(buf, '<') && strchr(buf+1, '>')) {
  316. dcc_bot_digest(idx, buf, pass);
  317. } else {
  318. dprintf(idx, "%s\n", pass);
  319. }
  320. }
  321. } else if (!egg_strcasecmp(code, "error")) {
  322. putlog(LOG_BOTS, "*", DCC_LINKERROR, dcc[idx].nick, buf);
  323. }
  324. /* Ignore otherwise */
  325. }
  326. static void eof_dcc_bot_new(int idx)
  327. {
  328. putlog(LOG_BOTS, "*", DCC_LOSTBOT, dcc[idx].nick, dcc[idx].port);
  329. killsock(dcc[idx].sock);
  330. lostdcc(idx);
  331. }
  332. static void timeout_dcc_bot_new(int idx)
  333. {
  334. putlog(LOG_BOTS, "*", DCC_TIMEOUT, dcc[idx].nick,
  335. dcc[idx].host, dcc[idx].port);
  336. killsock(dcc[idx].sock);
  337. lostdcc(idx);
  338. }
  339. static void display_dcc_bot_new(int idx, char *buf)
  340. {
  341. sprintf(buf, "bot* waited %lus", now - dcc[idx].timeval);
  342. }
  343. static int expmem_dcc_bot_(void *x)
  344. {
  345. return sizeof(struct bot_info);
  346. }
  347. static void free_dcc_bot_(int n, void *x)
  348. {
  349. if (dcc[n].type == &DCC_BOT) {
  350. unvia(n, findbot(dcc[n].nick));
  351. rembot(dcc[n].nick);
  352. }
  353. nfree(x);
  354. }
  355. struct dcc_table DCC_BOT_NEW =
  356. {
  357. "BOT_NEW",
  358. 0,
  359. eof_dcc_bot_new,
  360. dcc_bot_new,
  361. &bot_timeout,
  362. timeout_dcc_bot_new,
  363. display_dcc_bot_new,
  364. expmem_dcc_bot_,
  365. free_dcc_bot_,
  366. NULL
  367. };
  368. /* Hash function for tandem bot commands */
  369. extern botcmd_t C_bot[];
  370. static void dcc_bot(int idx, char *code, int i)
  371. {
  372. char *msg;
  373. int f;
  374. strip_telnet(dcc[idx].sock, code, &i);
  375. if (debug_output) {
  376. if (code[0] == 's')
  377. putlog(LOG_BOTSHARE, "*", "{%s} %s", dcc[idx].nick, code + 2);
  378. else
  379. putlog(LOG_BOTNET, "*", "[%s] %s", dcc[idx].nick, code);
  380. }
  381. msg = strchr(code, ' ');
  382. if (msg) {
  383. *msg = 0;
  384. msg++;
  385. } else
  386. msg = "";
  387. for (f = i = 0; C_bot[i].name && !f; i++) {
  388. int y = egg_strcasecmp(code, C_bot[i].name);
  389. if (!y) {
  390. /* Found a match */
  391. (C_bot[i].func)(idx, msg);
  392. f = 1;
  393. } else if (y < 0)
  394. return;
  395. }
  396. }
  397. static void eof_dcc_bot(int idx)
  398. {
  399. char x[1024];
  400. int bots, users;
  401. bots = bots_in_subtree(findbot(dcc[idx].nick));
  402. users = users_in_subtree(findbot(dcc[idx].nick));
  403. egg_snprintf(x, sizeof x,
  404. "Lost bot: %s (lost %d bot%s and %d user%s)",
  405. dcc[idx].nick, bots, (bots != 1) ? "s" : "", users,
  406. (users != 1) ? "s" : "");
  407. putlog(LOG_BOTS, "*", "%s.", x);
  408. chatout("*** %s\n", x);
  409. botnet_send_unlinked(idx, dcc[idx].nick, x);
  410. killsock(dcc[idx].sock);
  411. lostdcc(idx);
  412. }
  413. static void display_dcc_bot(int idx, char *buf)
  414. {
  415. int i = simple_sprintf(buf, "bot flags: ");
  416. buf[i++] = b_status(idx) & STAT_PINGED ? 'P' : 'p';
  417. buf[i++] = b_status(idx) & STAT_SHARE ? 'U' : 'u';
  418. buf[i++] = b_status(idx) & STAT_CALLED ? 'C' : 'c';
  419. buf[i++] = b_status(idx) & STAT_OFFERED ? 'O' : 'o';
  420. buf[i++] = b_status(idx) & STAT_SENDING ? 'S' : 's';
  421. buf[i++] = b_status(idx) & STAT_GETTING ? 'G' : 'g';
  422. buf[i++] = b_status(idx) & STAT_WARNED ? 'W' : 'w';
  423. buf[i++] = b_status(idx) & STAT_LEAF ? 'L' : 'l';
  424. buf[i++] = b_status(idx) & STAT_LINKING ? 'I' : 'i';
  425. buf[i++] = b_status(idx) & STAT_AGGRESSIVE ? 'a' : 'A';
  426. buf[i++] = 0;
  427. }
  428. static void display_dcc_fork_bot(int idx, char *buf)
  429. {
  430. sprintf(buf, "conn bot");
  431. }
  432. struct dcc_table DCC_BOT =
  433. {
  434. "BOT",
  435. DCT_BOT,
  436. eof_dcc_bot,
  437. dcc_bot,
  438. NULL,
  439. NULL,
  440. display_dcc_bot,
  441. expmem_dcc_bot_,
  442. free_dcc_bot_,
  443. NULL
  444. };
  445. struct dcc_table DCC_FORK_BOT =
  446. {
  447. "FORK_BOT",
  448. 0,
  449. failed_link,
  450. cont_link,
  451. &connect_timeout,
  452. failed_link,
  453. display_dcc_fork_bot,
  454. expmem_dcc_bot_,
  455. free_dcc_bot_,
  456. NULL
  457. };
  458. /* This function generates a digest by combining a challenge consisting
  459. * of our process id + connection time + botnetnick. The digest is then
  460. * compared to the one given by the remote bot.
  461. *
  462. * Returns 1 if the digest matches, otherwise returns 0.
  463. * <Cybah>
  464. */
  465. static int dcc_bot_check_digest(int idx, char *remote_digest)
  466. {
  467. MD5_CTX md5context;
  468. char digest_string[33]; /* 32 for digest in hex + null */
  469. unsigned char digest[16];
  470. int i;
  471. char *password = get_user(&USERENTRY_PASS, dcc[idx].user);
  472. MD5_Init(&md5context);
  473. egg_snprintf(digest_string, 33, "<%x%x@", getpid(),
  474. (unsigned int) dcc[idx].timeval);
  475. MD5_Update(&md5context, (unsigned char *) digest_string,
  476. strlen(digest_string));
  477. MD5_Update(&md5context, (unsigned char *) botnetnick, strlen(botnetnick));
  478. MD5_Update(&md5context, (unsigned char *) ">", 1);
  479. MD5_Update(&md5context, (unsigned char *) password, strlen(password));
  480. MD5_Final(digest, &md5context);
  481. for (i = 0; i < 16; i++)
  482. sprintf(digest_string + (i * 2), "%.2x", digest[i]);
  483. if (!strcmp(digest_string, remote_digest))
  484. return 1;
  485. putlog(LOG_BOTS, "*", "Response (password hash) from %s incorrect",
  486. dcc[idx].nick);
  487. return 0;
  488. }
  489. static void dcc_chat_pass(int idx, char *buf, int atr)
  490. {
  491. if (!atr)
  492. return;
  493. strip_telnet(dcc[idx].sock, buf, &atr);
  494. atr = dcc[idx].user ? dcc[idx].user->flags : 0;
  495. /* Check for MD5 digest from remote _bot_. <cybah> */
  496. if ((atr & USER_BOT) && !egg_strncasecmp(buf, "digest ", 7)) {
  497. if(dcc_bot_check_digest(idx, buf+7)) {
  498. nfree(dcc[idx].u.chat);
  499. dcc[idx].type = &DCC_BOT_NEW;
  500. dcc[idx].u.bot = get_data_ptr(sizeof(struct bot_info));
  501. dcc[idx].status = STAT_CALLED;
  502. dprintf(idx, "*hello!\n");
  503. greet_new_bot(idx);
  504. return;
  505. } else {
  506. /* Invalid password/digest */
  507. dprintf(idx, "badpass\n");
  508. putlog(LOG_MISC, "*", DCC_BADLOGIN, dcc[idx].nick, dcc[idx].host,
  509. dcc[idx].port);
  510. killsock(dcc[idx].sock);
  511. lostdcc(idx);
  512. return;
  513. }
  514. }
  515. if (u_pass_match(dcc[idx].user, buf)) {
  516. if (atr & USER_BOT) {
  517. nfree(dcc[idx].u.chat);
  518. dcc[idx].type = &DCC_BOT_NEW;
  519. dcc[idx].u.bot = get_data_ptr(sizeof(struct bot_info));
  520. dcc[idx].status = STAT_CALLED;
  521. dprintf(idx, "*hello!\n");
  522. greet_new_bot(idx);
  523. } else {
  524. /* Log entry for successful login -slennox 3/28/1999 */
  525. putlog(LOG_MISC, "*", DCC_LOGGEDIN, dcc[idx].nick,
  526. dcc[idx].host, dcc[idx].port);
  527. if (dcc[idx].u.chat->away) {
  528. nfree(dcc[idx].u.chat->away);
  529. dcc[idx].u.chat->away = NULL;
  530. }
  531. dcc[idx].type = &DCC_CHAT;
  532. dcc[idx].status &= ~STAT_CHAT;
  533. dcc[idx].u.chat->con_flags = (atr & USER_MASTER) ? conmask : 0;
  534. dcc[idx].u.chat->channel = -2;
  535. /* Turn echo back on for telnet sessions (send IAC WON'T ECHO). */
  536. if (dcc[idx].status & STAT_TELNET)
  537. dprintf(idx, TLN_IAC_C TLN_WONT_C TLN_ECHO_C "\n");
  538. dcc_chatter(idx);
  539. }
  540. } else {
  541. if (atr & USER_BOT)
  542. dprintf(idx, "badpass\n");
  543. else
  544. dprintf(idx, DCC_HOUSTON);
  545. putlog(LOG_MISC, "*", DCC_BADLOGIN, dcc[idx].nick,
  546. dcc[idx].host, dcc[idx].port);
  547. if (dcc[idx].u.chat->away) { /* su from a dumb user */
  548. /* Turn echo back on for telnet sessions (send IAC WON'T ECHO). */
  549. if (dcc[idx].status & STAT_TELNET)
  550. dprintf(idx, TLN_IAC_C TLN_WONT_C TLN_ECHO_C "\n");
  551. dcc[idx].user = get_user_by_handle(userlist, dcc[idx].u.chat->away);
  552. strcpy(dcc[idx].nick, dcc[idx].u.chat->away);
  553. nfree(dcc[idx].u.chat->away);
  554. nfree(dcc[idx].u.chat->su_nick);
  555. dcc[idx].u.chat->away = NULL;
  556. dcc[idx].u.chat->su_nick = NULL;
  557. dcc[idx].type = &DCC_CHAT;
  558. if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
  559. botnet_send_join_idx(idx, -1);
  560. chanout_but(-1, dcc[idx].u.chat->channel, DCC_JOIN, dcc[idx].nick);
  561. } else {
  562. killsock(dcc[idx].sock);
  563. lostdcc(idx);
  564. }
  565. }
  566. }
  567. static void eof_dcc_general(int idx)
  568. {
  569. putlog(LOG_MISC, "*", DCC_LOSTDCC, dcc[idx].nick,
  570. dcc[idx].host, dcc[idx].port);
  571. killsock(dcc[idx].sock);
  572. lostdcc(idx);
  573. }
  574. static void tout_dcc_chat_pass(int idx)
  575. {
  576. dprintf(idx, "Timeout.\n");
  577. putlog(LOG_MISC, "*", DCC_PWDTIMEOUT, dcc[idx].nick,
  578. dcc[idx].host);
  579. killsock(dcc[idx].sock);
  580. lostdcc(idx);
  581. }
  582. static void display_dcc_chat_pass(int idx, char *buf)
  583. {
  584. sprintf(buf, "pass waited %lus", now - dcc[idx].timeval);
  585. }
  586. static int expmem_dcc_general(void *x)
  587. {
  588. register struct chat_info *p = (struct chat_info *) x;
  589. int tot = sizeof(struct chat_info);
  590. if (p->away)
  591. tot += strlen(p->away) + 1;
  592. if (p->buffer) {
  593. struct msgq *q = p->buffer;
  594. while (q) {
  595. tot += sizeof(struct list_type);
  596. tot += q->len + 1;
  597. q = q->next;
  598. }
  599. }
  600. if (p->su_nick)
  601. tot += strlen(p->su_nick) + 1;
  602. return tot;
  603. }
  604. static void kill_dcc_general(int idx, void *x)
  605. {
  606. register struct chat_info *p = (struct chat_info *) x;
  607. if (p) {
  608. if (p->buffer) {
  609. struct msgq *r, *q;
  610. for (r = dcc[idx].u.chat->buffer; r; r = q) {
  611. q = r->next;
  612. nfree(r->msg);
  613. nfree(r);
  614. }
  615. }
  616. if (p->away) {
  617. nfree(p->away);
  618. }
  619. nfree(p);
  620. }
  621. }
  622. /* Remove the color control codes that mIRC,pIRCh etc use to make
  623. * their client seem so fecking cool! (Sorry, Khaled, you are a nice
  624. * guy, but when you added this feature you forced people to either
  625. * use your *SHAREWARE* client or face screenfulls of crap!)
  626. */
  627. static void strip_mirc_codes(int flags, char *text)
  628. {
  629. char *dd = text;
  630. while (*text) {
  631. switch (*text) {
  632. case 2: /* Bold text */
  633. if (flags & STRIP_BOLD) {
  634. text++;
  635. continue;
  636. }
  637. break;
  638. case 3: /* mIRC colors? */
  639. if (flags & STRIP_COLOR) {
  640. if (isdigit(text[1])) { /* Is the first char a number? */
  641. text += 2; /* Skip over the ^C and the first digit */
  642. if (isdigit(*text))
  643. text++; /* Is this a double digit number? */
  644. if (*text == ',') { /* Do we have a background color next? */
  645. if (isdigit(text[1]))
  646. text += 2; /* Skip over the first background digit */
  647. if (isdigit(*text))
  648. text++; /* Is it a double digit? */
  649. }
  650. } else
  651. text++;
  652. continue;
  653. }
  654. break;
  655. case 7:
  656. if (flags & STRIP_BELLS) {
  657. text++;
  658. continue;
  659. }
  660. break;
  661. case 0x16: /* Reverse video */
  662. if (flags & STRIP_REV) {
  663. text++;
  664. continue;
  665. }
  666. break;
  667. case 0x1f: /* Underlined text */
  668. if (flags & STRIP_UNDER) {
  669. text++;
  670. continue;
  671. }
  672. break;
  673. case 033:
  674. if (flags & STRIP_ANSI) {
  675. text++;
  676. if (*text == '[') {
  677. text++;
  678. while ((*text == ';') || isdigit(*text))
  679. text++;
  680. if (*text)
  681. text++; /* also kill the following char */
  682. }
  683. continue;
  684. }
  685. break;
  686. }
  687. *dd++ = *text++; /* Move on to the next char */
  688. }
  689. *dd = 0;
  690. }
  691. static void append_line(int idx, char *line)
  692. {
  693. int l = strlen(line);
  694. struct msgq *p, *q;
  695. struct chat_info *c = (dcc[idx].type == &DCC_CHAT) ? dcc[idx].u.chat :
  696. dcc[idx].u.file->chat;
  697. if (c->current_lines > 1000) {
  698. /* They're probably trying to fill up the bot nuke the sods :) */
  699. for (p = c->buffer; p; p = q) {
  700. q = p->next;
  701. nfree(p->msg);
  702. nfree(p);
  703. }
  704. c->buffer = 0;
  705. dcc[idx].status &= ~STAT_PAGE;
  706. do_boot(idx, botnetnick, "too many pages - senq full");
  707. return;
  708. }
  709. if ((c->line_count < c->max_line) && (c->buffer == NULL)) {
  710. c->line_count++;
  711. tputs(dcc[idx].sock, line, l);
  712. } else {
  713. c->current_lines++;
  714. if (c->buffer == NULL)
  715. q = NULL;
  716. else
  717. for (q = c->buffer; q->next; q = q->next);
  718. p = get_data_ptr(sizeof(struct msgq));
  719. p->len = l;
  720. p->msg = get_data_ptr(l + 1);
  721. p->next = NULL;
  722. strcpy(p->msg, line);
  723. if (q == NULL)
  724. c->buffer = p;
  725. else
  726. q->next = p;
  727. }
  728. }
  729. static void out_dcc_general(int idx, char *buf, void *x)
  730. {
  731. register struct chat_info *p = (struct chat_info *) x;
  732. char *y = buf;
  733. strip_mirc_codes(p->strip_flags, buf);
  734. if (dcc[idx].status & STAT_TELNET)
  735. y = add_cr(buf);
  736. if (dcc[idx].status & STAT_PAGE)
  737. append_line(idx, y);
  738. else
  739. tputs(dcc[idx].sock, y, strlen(y));
  740. }
  741. struct dcc_table DCC_CHAT_PASS =
  742. {
  743. "CHAT_PASS",
  744. 0,
  745. eof_dcc_general,
  746. dcc_chat_pass,
  747. &password_timeout,
  748. tout_dcc_chat_pass,
  749. display_dcc_chat_pass,
  750. expmem_dcc_general,
  751. kill_dcc_general,
  752. out_dcc_general
  753. };
  754. /* Make sure ansi code is just for color-changing
  755. */
  756. static int check_ansi(char *v)
  757. {
  758. int count = 2;
  759. if (*v++ != '\033')
  760. return 1;
  761. if (*v++ != '[')
  762. return 1;
  763. while (*v) {
  764. if (*v == 'm')
  765. return 0;
  766. if ((*v != ';') && ((*v < '0') || (*v > '9')))
  767. return count;
  768. v++;
  769. count++;
  770. }
  771. return count;
  772. }
  773. static void eof_dcc_chat(int idx)
  774. {
  775. putlog(LOG_MISC, "*", DCC_LOSTDCC, dcc[idx].nick,
  776. dcc[idx].host, dcc[idx].port);
  777. if (dcc[idx].u.chat->channel >= 0) {
  778. chanout_but(idx, dcc[idx].u.chat->channel, "*** %s lost dcc link.\n",
  779. dcc[idx].nick);
  780. if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
  781. botnet_send_part_idx(idx, "lost dcc link");
  782. check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
  783. dcc[idx].u.chat->channel);
  784. }
  785. check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
  786. killsock(dcc[idx].sock);
  787. lostdcc(idx);
  788. }
  789. static void dcc_chat(int idx, char *buf, int i)
  790. {
  791. int nathan = 0, doron = 0, fixed = 0;
  792. char *v, *d;
  793. strip_telnet(dcc[idx].sock, buf, &i);
  794. if (buf[0] && (buf[0] != '.') &&
  795. detect_dcc_flood(&dcc[idx].timeval, dcc[idx].u.chat, idx))
  796. return;
  797. dcc[idx].timeval = now;
  798. if (buf[0])
  799. strcpy(buf, check_tcl_filt(idx, buf));
  800. if (buf[0]) {
  801. /* Check for beeps and cancel annoying ones */
  802. v = buf;
  803. d = buf;
  804. while (*v)
  805. switch (*v) {
  806. case 7: /* Beep - no more than 3 */
  807. nathan++;
  808. if (nathan > 3)
  809. v++;
  810. else
  811. *d++ = *v++;
  812. break;
  813. case 8: /* Backspace - for lame telnet's :) */
  814. if (d > buf) {
  815. d--;
  816. }
  817. v++;
  818. break;
  819. case 27: /* ESC - ansi code? */
  820. doron = check_ansi(v);
  821. /* If it's valid, append a return-to-normal code at the end */
  822. if (!doron) {
  823. *d++ = *v++;
  824. fixed = 1;
  825. } else
  826. v += doron;
  827. break;
  828. case '\r': /* Weird pseudo-linefeed */
  829. v++;
  830. break;
  831. default:
  832. *d++ = *v++;
  833. }
  834. if (fixed)
  835. strcpy(d, "\033[0m");
  836. else
  837. *d = 0;
  838. if (buf[0]) { /* Nothing to say - maybe paging... */
  839. if ((buf[0] == '.') || (dcc[idx].u.chat->channel < 0)) {
  840. if (buf[0] == '.')
  841. buf++;
  842. v = newsplit(&buf);
  843. rmspace(buf);
  844. if (check_tcl_dcc(v, idx, buf)) {
  845. if (dcc[idx].u.chat->channel >= 0)
  846. check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
  847. dcc[idx].u.chat->channel);
  848. check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
  849. dprintf(idx, "*** Ja mata!\n");
  850. flush_lines(idx, dcc[idx].u.chat);
  851. putlog(LOG_MISC, "*", DCC_CLOSED, dcc[idx].nick,
  852. dcc[idx].host);
  853. if (dcc[idx].u.chat->channel >= 0) {
  854. chanout_but(-1, dcc[idx].u.chat->channel,
  855. "*** %s left the party line%s%s\n",
  856. dcc[idx].nick, buf[0] ? ": " : ".", buf);
  857. if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
  858. botnet_send_part_idx(idx, buf);
  859. }
  860. if (dcc[idx].u.chat->su_nick) {
  861. dcc[idx].user = get_user_by_handle(userlist,
  862. dcc[idx].u.chat->su_nick);
  863. strcpy(dcc[idx].nick, dcc[idx].u.chat->su_nick);
  864. dcc[idx].type = &DCC_CHAT;
  865. dprintf(idx, "Returning to real nick %s!\n",
  866. dcc[idx].u.chat->su_nick);
  867. nfree(dcc[idx].u.chat->su_nick);
  868. dcc[idx].u.chat->su_nick = NULL;
  869. dcc_chatter(idx);
  870. if (dcc[idx].u.chat->channel < GLOBAL_CHANS &&
  871. dcc[idx].u.chat->channel >= 0)
  872. botnet_send_join_idx(idx, -1);
  873. return;
  874. } else if ((dcc[idx].sock != STDOUT) || backgrd) {
  875. killsock(dcc[idx].sock);
  876. lostdcc(idx);
  877. return;
  878. } else {
  879. dprintf(DP_STDOUT, "\n### SIMULATION RESET\n\n");
  880. dcc_chatter(idx);
  881. return;
  882. }
  883. }
  884. } else if (buf[0] == ',') {
  885. int me = 0;
  886. if ((buf[1] == 'm') && (buf[2] == 'e') && buf[3] == ' ')
  887. me = 1;
  888. for (i = 0; i < dcc_total; i++) {
  889. int ok = 0;
  890. if (dcc[i].type->flags & DCT_MASTER) {
  891. if ((dcc[i].type != &DCC_CHAT) ||
  892. (dcc[i].u.chat->channel >= 0))
  893. if ((i != idx) || (dcc[idx].status & STAT_ECHO))
  894. ok = 1;
  895. }
  896. if (ok) {
  897. struct userrec *u = get_user_by_handle(userlist, dcc[i].nick);
  898. if (u && (u->flags & USER_MASTER)) {
  899. if (me)
  900. dprintf(i, "-> %s%s\n", dcc[idx].nick, buf + 3);
  901. else
  902. dprintf(i, "-%s-> %s\n", dcc[idx].nick, buf + 1);
  903. }
  904. }
  905. }
  906. } else if (buf[0] == '\'') {
  907. int me = 0;
  908. if ((buf[1] == 'm') && (buf[2] == 'e') &&
  909. ((buf[3] == ' ') || (buf[3] == '\'') || (buf[3] == ',')))
  910. me = 1;
  911. for (i = 0; i < dcc_total; i++) {
  912. if (dcc[i].type->flags & DCT_CHAT) {
  913. if (me)
  914. dprintf(i, "=> %s%s\n", dcc[idx].nick, buf + 3);
  915. else
  916. dprintf(i, "=%s=> %s\n", dcc[idx].nick, buf + 1);
  917. }
  918. }
  919. } else {
  920. if (dcc[idx].u.chat->away != NULL)
  921. not_away(idx);
  922. if (dcc[idx].status & STAT_ECHO)
  923. chanout_but(-1, dcc[idx].u.chat->channel,
  924. "<%s> %s\n", dcc[idx].nick, buf);
  925. else
  926. chanout_but(idx, dcc[idx].u.chat->channel, "<%s> %s\n",
  927. dcc[idx].nick, buf);
  928. botnet_send_chan(-1, botnetnick, dcc[idx].nick,
  929. dcc[idx].u.chat->channel, buf);
  930. check_tcl_chat(dcc[idx].nick, dcc[idx].u.chat->channel, buf);
  931. }
  932. }
  933. }
  934. if (dcc[idx].type == &DCC_CHAT) /* Could have change to files */
  935. if (dcc[idx].status & STAT_PAGE)
  936. flush_lines(idx, dcc[idx].u.chat);
  937. }
  938. static void display_dcc_chat(int idx, char *buf)
  939. {
  940. int i = simple_sprintf(buf, "chat flags: ");
  941. buf[i++] = dcc[idx].status & STAT_CHAT ? 'C' : 'c';
  942. buf[i++] = dcc[idx].status & STAT_PARTY ? 'P' : 'p';
  943. buf[i++] = dcc[idx].status & STAT_TELNET ? 'T' : 't';
  944. buf[i++] = dcc[idx].status & STAT_ECHO ? 'E' : 'e';
  945. buf[i++] = dcc[idx].status & STAT_PAGE ? 'P' : 'p';
  946. simple_sprintf(buf + i, "/%d", dcc[idx].u.chat->channel);
  947. }
  948. struct dcc_table DCC_CHAT =
  949. {
  950. "CHAT",
  951. DCT_CHAT | DCT_MASTER | DCT_SHOWWHO | DCT_VALIDIDX | DCT_SIMUL |
  952. DCT_CANBOOT | DCT_REMOTEWHO,
  953. eof_dcc_chat,
  954. dcc_chat,
  955. NULL,
  956. NULL,
  957. display_dcc_chat,
  958. expmem_dcc_general,
  959. kill_dcc_general,
  960. out_dcc_general
  961. };
  962. static int lasttelnets;
  963. static char lasttelnethost[81];
  964. static time_t lasttelnettime;
  965. /* A modified detect_flood for incoming telnet flood protection.
  966. */
  967. static int detect_telnet_flood(char *floodhost)
  968. {
  969. struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
  970. get_user_flagrec(get_user_by_host(floodhost), &fr, NULL);
  971. if (!flood_telnet_thr || (glob_friend(fr) && !par_telnet_flood))
  972. return 0; /* No flood protection */
  973. if (egg_strcasecmp(lasttelnethost, floodhost)) { /* New... */
  974. strcpy(lasttelnethost, floodhost);
  975. lasttelnettime = now;
  976. lasttelnets = 0;
  977. return 0;
  978. }
  979. if (lasttelnettime < now - flood_telnet_time) {
  980. /* Flood timer expired, reset it */
  981. lasttelnettime = now;
  982. lasttelnets = 0;
  983. return 0;
  984. }
  985. lasttelnets++;
  986. if (lasttelnets >= flood_telnet_thr) { /* FLOOD! */
  987. /* Reset counters */
  988. lasttelnets = 0;
  989. lasttelnettime = 0;
  990. lasttelnethost[0] = 0;
  991. putlog(LOG_MISC, "*", IRC_TELNETFLOOD, floodhost);
  992. addignore(floodhost, origbotname, "Telnet connection flood",
  993. now + (60 * ignore_time));
  994. return 1;
  995. }
  996. return 0;
  997. }
  998. static void dcc_telnet(int idx, char *buf, int i)
  999. {
  1000. unsigned long ip;
  1001. unsigned short port;
  1002. int j = 0, sock;
  1003. char s[UHOSTLEN + 1];
  1004. if (dcc_total + 1 > max_dcc) {
  1005. j = answer(dcc[idx].sock, s, &ip, &port, 0);
  1006. if (j != -1) {
  1007. dprintf(-j, "Sorry, too many connections already.\r\n");
  1008. killsock(j);
  1009. }
  1010. return;
  1011. }
  1012. sock = answer(dcc[idx].sock, s, &ip, &port, 0);
  1013. while ((sock == -1) && (errno == EAGAIN))
  1014. sock = answer(sock, s, &ip, &port, 0);
  1015. if (sock < 0) {
  1016. neterror(s);
  1017. putlog(LOG_MISC, "*", DCC_FAILED, s);
  1018. return;
  1019. }
  1020. /* Buffer data received on this socket. */
  1021. sockoptions(sock, EGG_OPTION_SET, SOCK_BUFFER);
  1022. if (port < 1024 || port > 65535) {
  1023. putlog(LOG_BOTS, "*", DCC_BADSRC, s, port);
  1024. killsock(sock);
  1025. return;
  1026. }
  1027. i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
  1028. dcc[i].sock = sock;
  1029. dcc[i].addr = ip;
  1030. dcc[i].port = port;
  1031. dcc[i].timeval = now;
  1032. strcpy(dcc[i].nick, "*");
  1033. dcc[i].u.dns->ip = ip;
  1034. dcc[i].u.dns->dns_success = dcc_telnet_hostresolved;
  1035. dcc[i].u.dns->dns_failure = dcc_telnet_hostresolved;
  1036. dcc[i].u.dns->dns_type = RES_HOSTBYIP;
  1037. dcc[i].u.dns->ibuf = dcc[idx].sock;
  1038. dcc[i].u.dns->type = &DCC_IDENTWAIT;
  1039. dcc_dnshostbyip(ip);
  1040. }
  1041. static void dcc_telnet_hostresolved(int i)
  1042. {
  1043. int idx;
  1044. int j = 0, sock;
  1045. char s[UHOSTLEN], s2[UHOSTLEN + 20];
  1046. strncpyz(dcc[i].host, dcc[i].u.dns->host, UHOSTLEN);
  1047. for (idx = 0; idx < dcc_total; idx++)
  1048. if ((dcc[idx].type == &DCC_TELNET) &&
  1049. (dcc[idx].sock == dcc[i].u.dns->ibuf)) {
  1050. break;
  1051. }
  1052. if (dcc_total == idx) {
  1053. putlog(LOG_BOTS, "*", "Lost listening socket while resolving %s",
  1054. dcc[i].host);
  1055. killsock(dcc[i].sock);
  1056. lostdcc(i);
  1057. return;
  1058. }
  1059. if (dcc[idx].host[0] == '@') {
  1060. /* Restrict by hostname */
  1061. if (!wild_match(dcc[idx].host + 1, dcc[i].host)) {
  1062. putlog(LOG_BOTS, "*", DCC_BADHOST, s);
  1063. killsock(dcc[i].sock);
  1064. lostdcc(i);
  1065. return;
  1066. }
  1067. }
  1068. sprintf(s2, "-telnet!telnet@%s", dcc[i].host);
  1069. if (match_ignore(s2) || detect_telnet_flood(s2)) {
  1070. killsock(dcc[i].sock);
  1071. lostdcc(i);
  1072. return;
  1073. }
  1074. changeover_dcc(i, &DCC_IDENTWAIT, 0);
  1075. dcc[i].timeval = now;
  1076. dcc[i].u.ident_sock = dcc[idx].sock;
  1077. sock = open_telnet(iptostr(htonl(dcc[i].addr)), 113);
  1078. putlog(LOG_MISC, "*", DCC_TELCONN, dcc[i].host, dcc[i].port);
  1079. s[0] = 0;
  1080. if (sock < 0) {
  1081. if (sock == -2)
  1082. strcpy(s, "DNS lookup failed for ident");
  1083. else
  1084. neterror(s);
  1085. } else {
  1086. j = new_dcc(&DCC_IDENT, 0);
  1087. if (j < 0) {
  1088. killsock(sock);
  1089. strcpy(s, "No Free DCC's");
  1090. }
  1091. }
  1092. if (s[0]) {
  1093. putlog(LOG_MISC, "*", DCC_IDENTFAIL, dcc[i].host, s);
  1094. sprintf(s, "telnet@%s", dcc[i].host);
  1095. dcc_telnet_got_ident(i, s);
  1096. return;
  1097. }
  1098. dcc[j].sock = sock;
  1099. dcc[j].port = 113;
  1100. dcc[j].addr = dcc[i].addr;
  1101. strcpy(dcc[j].host, dcc[i].host);
  1102. strcpy(dcc[j].nick, "*");
  1103. dcc[j].u.ident_sock = dcc[i].sock;
  1104. dcc[j].timeval = now;
  1105. dprintf(j, "%d, %d\n", dcc[i].port, dcc[idx].port);
  1106. }
  1107. static void eof_dcc_telnet(int idx)
  1108. {
  1109. putlog(LOG_MISC, "*", DCC_PORTDIE,
  1110. dcc[idx].port);
  1111. killsock(dcc[idx].sock);
  1112. lostdcc(idx);
  1113. }
  1114. static void display_telnet(int idx, char *buf)
  1115. {
  1116. sprintf(buf, "lstn %d%s", dcc[idx].port,
  1117. (dcc[idx].status & LSTN_PUBLIC) ? " pub" : "");
  1118. }
  1119. struct dcc_table DCC_TELNET =
  1120. {
  1121. "TELNET",
  1122. DCT_LISTEN,
  1123. eof_dcc_telnet,
  1124. dcc_telnet,
  1125. NULL,
  1126. NULL,
  1127. display_telnet,
  1128. NULL,
  1129. NULL,
  1130. NULL
  1131. };
  1132. static void eof_dcc_dupwait(int idx)
  1133. {
  1134. putlog(LOG_BOTS, "*", DCC_LOSTDUP, dcc[idx].host);
  1135. killsock(dcc[idx].sock);
  1136. lostdcc(idx);
  1137. }
  1138. static void dcc_dupwait(int idx, char *buf, int i)
  1139. {
  1140. /* We just ignore any data at this point. */
  1141. return;
  1142. }
  1143. /* We now check again. If the bot is still marked as duplicate, there is no
  1144. * botnet lag we could push it on, so we just drop the connection.
  1145. */
  1146. static void timeout_dupwait(int idx)
  1147. {
  1148. char x[100];
  1149. /* Still duplicate? */
  1150. if (in_chain(dcc[idx].nick)) {
  1151. egg_snprintf(x, sizeof x, "%s!%s", dcc[idx].nick, dcc[idx].host);
  1152. dprintf(idx, "error Already connected.\n");
  1153. putlog(LOG_BOTS, "*", DCC_DUPLICATE, x);
  1154. killsock(dcc[idx].sock);
  1155. lostdcc(idx);
  1156. } else {
  1157. /* Ha! Now it's gone and we can grant this bot access. */
  1158. dcc_telnet_pass(idx, dcc[idx].u.dupwait->atr);
  1159. }
  1160. }
  1161. static void display_dupwait(int idx, char *buf)
  1162. {
  1163. sprintf(buf, "wait duplicate?");
  1164. }
  1165. static int expmem_dupwait(void *x)
  1166. {
  1167. register struct dupwait_info *p = (struct dupwait_info *) x;
  1168. int tot = sizeof(struct dupwait_info);
  1169. if (p && p->chat && DCC_CHAT.expmem)
  1170. tot += DCC_CHAT.expmem(p->chat);
  1171. return tot;
  1172. }
  1173. static void kill_dupwait(int idx, void *x)
  1174. {
  1175. register struct dupwait_info *p = (struct dupwait_info *) x;
  1176. if (p) {
  1177. if (p->chat && DCC_CHAT.kill)
  1178. DCC_CHAT.kill(idx, p->chat);
  1179. nfree(p);
  1180. }
  1181. }
  1182. struct dcc_table DCC_DUPWAIT =
  1183. {
  1184. "DUPWAIT",
  1185. DCT_VALIDIDX,
  1186. eof_dcc_dupwait,
  1187. dcc_dupwait,
  1188. &dupwait_timeout,
  1189. timeout_dupwait,
  1190. display_dupwait,
  1191. expmem_dupwait,
  1192. kill_dupwait,
  1193. NULL
  1194. };
  1195. /* This function is called if a bot gets removed from the list. It checks
  1196. * wether we have a pending duplicate connection for that bot and continues
  1197. * with the login in that case.
  1198. */
  1199. void dupwait_notify(char *who)
  1200. {
  1201. register int idx;
  1202. Assert(who);
  1203. for (idx = 0; idx < dcc_total; idx++)
  1204. if ((dcc[idx].type == &DCC_DUPWAIT) &&
  1205. !egg_strcasecmp(dcc[idx].nick, who)) {
  1206. dcc_telnet_pass(idx, dcc[idx].u.dupwait->atr);
  1207. break;
  1208. }
  1209. }
  1210. static void dcc_telnet_id(int idx, char *buf, int atr)
  1211. {
  1212. int ok = 0;
  1213. struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
  1214. strip_telnet(dcc[idx].sock, buf, &atr);
  1215. buf[HANDLEN] = 0;
  1216. /* Toss out bad nicknames */
  1217. if ((dcc[idx].nick[0] != '@') && (!wild_match(dcc[idx].nick, buf))) {
  1218. dprintf(idx, "Sorry, that nickname format is invalid.\n");
  1219. putlog(LOG_BOTS, "*", DCC_BADNICK, dcc[idx].host);
  1220. killsock(dcc[idx].sock);
  1221. lostdcc(idx);
  1222. return;
  1223. }
  1224. dcc[idx].user = get_user_by_handle(userlist, buf);
  1225. get_user_flagrec(dcc[idx].user, &fr, NULL);
  1226. /* Make sure users-only/bots-only connects are honored */
  1227. if ((dcc[idx].status & STAT_BOTONLY) && !glob_bot(fr)) {
  1228. dprintf(idx, "This telnet port is for bots only.\n");
  1229. putlog(LOG_BOTS, "*", DCC_NONBOT, dcc[idx].host);
  1230. killsock(dcc[idx].sock);
  1231. lostdcc(idx);
  1232. return;
  1233. }
  1234. if ((dcc[idx].status & STAT_USRONLY) && glob_bot(fr)) {
  1235. dprintf(idx, "error Only users may connect at this port.\n");
  1236. putlog(LOG_BOTS, "*", DCC_NONUSER, dcc[idx].host);
  1237. killsock(dcc[idx].sock);
  1238. lostdcc(idx);
  1239. return;
  1240. }
  1241. dcc[idx].status &= ~(STAT_BOTONLY | STAT_USRONLY);
  1242. if ((!egg_strcasecmp(buf, "NEW")) &&
  1243. ((allow_new_telnets) || (make_userfile))) {
  1244. dcc[idx].type = &DCC_TELNET_NEW;
  1245. dcc[idx].timeval = now;
  1246. dprintf(idx, "\n");
  1247. dprintf(idx, IRC_TELNET, botnetnick);
  1248. dprintf(idx, IRC_TELNET1);
  1249. dprintf(idx, "\nEnter the nickname you would like to use.\n");
  1250. return;
  1251. }
  1252. if (chan_op(fr)) {
  1253. if (!require_p)
  1254. ok = 1;
  1255. }
  1256. if (!ok && (glob_party(fr) || glob_bot(fr)))
  1257. ok = 1;
  1258. if (!ok) {
  1259. dprintf(idx, "You don't have access.\n");
  1260. putlog(LOG_BOTS, "*", DCC_INVHANDLE, dcc[idx].host, buf);
  1261. killsock(dcc[idx].sock);
  1262. lostdcc(idx);
  1263. return;
  1264. }
  1265. correct_handle(buf);
  1266. strcpy(dcc[idx].nick, buf);
  1267. if (glob_bot(fr)) {
  1268. if (!egg_strcasecmp(botnetnick, dcc[idx].nick)) {
  1269. dprintf(idx, "error You cannot link using my botnetnick.\n");
  1270. putlog(LOG_BOTS, "*", DCC_MYBOTNETNICK, dcc[idx].host);
  1271. killsock(dcc[idx].sock);
  1272. lostdcc(idx);
  1273. return;
  1274. } else if (in_chain(dcc[idx].nick)) {
  1275. struct chat_info *ci;
  1276. ci = dcc[idx].u.chat;
  1277. dcc[idx].type = &DCC_DUPWAIT;
  1278. dcc[idx].u.dupwait = get_data_ptr(sizeof(struct dupwait_info));
  1279. dcc[idx].u.dupwait->chat = ci;
  1280. dcc[idx].u.dupwait->atr = atr;
  1281. return;
  1282. }
  1283. }
  1284. dcc_telnet_pass(idx, atr);
  1285. }
  1286. static void dcc_telnet_pass(int idx, int atr)
  1287. {
  1288. int ok = 0;
  1289. struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
  1290. get_user_flagrec(dcc[idx].user, &fr, NULL);
  1291. /* No password set? */
  1292. if (u_pass_match(dcc[idx].user, "-")) {
  1293. if (glob_bot(fr)) {
  1294. char ps[20];
  1295. makepass(ps);
  1296. set_user(&USERENTRY_PASS, dcc[idx].user, ps);
  1297. changeover_dcc(idx, &DCC_BOT_NEW, sizeof(struct bot_info));
  1298. dcc[idx].status = STAT_CALLED;
  1299. dprintf(idx, "*hello!\n");
  1300. greet_new_bot(idx);
  1301. #ifdef NO_OLD_BOTNET
  1302. dprintf(idx, "h %s\n", ps);
  1303. #else
  1304. dprintf(idx, "handshake %s\n", ps);
  1305. #endif
  1306. return;
  1307. }
  1308. dprintf(idx, "Can't telnet until you have a password set.\n");
  1309. putlog(LOG_MISC, "*", DCC_NOPASS, dcc[idx].nick, dcc[idx].host);
  1310. killsock(dcc[idx].sock);
  1311. lostdcc(idx);
  1312. return;
  1313. }
  1314. ok = 0;
  1315. if (dcc[idx].type == &DCC_DUPWAIT) {
  1316. struct chat_info *ci;
  1317. ci = dcc[idx].u.dupwait->chat;
  1318. nfree(dcc[idx].u.dupwait);
  1319. dcc[idx].u.chat = ci;
  1320. }
  1321. dcc[idx].type = &DCC_CHAT_PASS;
  1322. dcc[idx].timeval = now;
  1323. if (glob_botmast(fr))
  1324. ok = 1;
  1325. else if (chan_op(fr)) {
  1326. if (!require_p)
  1327. ok = 1;
  1328. else if (glob_party(fr))
  1329. ok = 1;
  1330. } else if (glob_party(fr)) {
  1331. ok = 1;
  1332. dcc[idx].status |= STAT_PARTY;
  1333. }
  1334. if (glob_bot(fr))
  1335. ok = 1;
  1336. if (!ok) {
  1337. struct chat_info *ci;
  1338. ci = dcc[idx].u.chat;
  1339. dcc[idx].u.file = get_data_ptr(sizeof(struct file_info));
  1340. dcc[idx].u.file->chat = ci;
  1341. }
  1342. if (glob_bot(fr)) {
  1343. /* Must generate a string consisting of our process ID and the current
  1344. * time. The bot will add it's password to the end and use it to generate
  1345. * an MD5 checksum (always 128bit). The checksum is sent back and this
  1346. * end does the same. The remote bot is only allowed access if the
  1347. * checksums match.
  1348. *
  1349. * Please don't fuck with 'timeval', or the digest we generate later for
  1350. * authentication will not be correct - you've been warned ;)
  1351. * <Cybah>
  1352. */
  1353. putlog(LOG_BOTS, "*", "Challenging %s...", dcc[idx].nick);
  1354. dprintf(idx, "passreq <%x%x@%s>\n", getpid(), dcc[idx].timeval, botnetnick);
  1355. } else {
  1356. /* NOTE: The MD5 digest used above to prevent cleartext passwords being
  1357. * sent across the net will _only_ work when we have the cleartext
  1358. * password. User passwords are encrypted (with blowfish usually)
  1359. * so the same thing cant be done. Botnet passwords are always
  1360. * stored in cleartext, or at least something that can be reversed.
  1361. * <Cybah>
  1362. */
  1363. /* Turn off remote telnet echo (send IAC WILL ECHO). */
  1364. dprintf(idx, "\n%s" TLN_IAC_C TLN_WILL_C TLN_ECHO_C "\n", DCC_ENTERPASS);
  1365. }
  1366. }
  1367. static void eof_dcc_telnet_id(int idx)
  1368. {
  1369. putlog(LOG_MISC, "*", DCC_LOSTCON, dcc[idx].host,
  1370. dcc[idx].port);
  1371. killsock(dcc[idx].sock);
  1372. lostdcc(idx);
  1373. }
  1374. static void timeout_dcc_telnet_id(int idx)
  1375. {
  1376. dprintf(idx, "Timeout.\n");
  1377. putlog(LOG_MISC, "*", DCC_TTIMEOUT, dcc[idx].host);
  1378. killsock(dcc[idx].sock);
  1379. lostdcc(idx);
  1380. }
  1381. static void display_dcc_telnet_id(int idx, char *buf)
  1382. {
  1383. sprintf(buf, "t-in waited %lus", now - dcc[idx].timeval);
  1384. }
  1385. struct dcc_table DCC_TELNET_ID =
  1386. {
  1387. "TELNET_ID",
  1388. 0,
  1389. eof_dcc_telnet_id,
  1390. dcc_telnet_id,
  1391. &password_timeout,
  1392. timeout_dcc_telnet_id,
  1393. display_dcc_telnet_id,
  1394. expmem_dcc_general,
  1395. kill_dcc_general,
  1396. out_dcc_general
  1397. };
  1398. static void dcc_telnet_new(int idx, char *buf, int x)
  1399. {
  1400. int ok = 1;
  1401. char work[1024], *p, *q, *r;
  1402. buf[HANDLEN] = 0;
  1403. strip_telnet(dcc[idx].sock, buf, &x);
  1404. dcc[idx].timeval = now;
  1405. for (x = 0; x < strlen(buf); x++)
  1406. if ((buf[x] <= 32) || (buf[x] >= 127))
  1407. ok = 0;
  1408. if (!ok) {
  1409. dprintf(idx, "\nYou can't use weird symbols in your nick.\n");
  1410. dprintf(idx, "Try another one please:\n");
  1411. } else if (strchr("-,+*=:!.@#;$", buf[0]) != NULL) {
  1412. dprintf(idx, "\nYou can't start your nick with the character '%c'\n",
  1413. buf[0]);
  1414. dprintf(idx, "Try another one please:\n");
  1415. } else if (get_user_by_handle(userlist, buf)) {
  1416. dprintf(idx, "\nSorry, that nickname is taken already.\n");
  1417. dprintf(idx, "Try another one please:\n");
  1418. return;
  1419. } else if (!egg_strcasecmp(buf, botnetnick)) {
  1420. dprintf(idx, "Sorry, can't use my name for a nick.\n");
  1421. } else {
  1422. strcpy(dcc[idx].nick, buf);
  1423. if (make_userfile)
  1424. userlist = adduser(userlist, buf, "-telnet!*@*", "-",
  1425. sanity_check(default_flags | USER_PARTY |
  1426. USER_MASTER | USER_OWNER));
  1427. else {
  1428. p = strchr(dcc[idx].host, '@');
  1429. if (p) {
  1430. q = p;
  1431. *q = 0;
  1432. p++;
  1433. r = strchr(p, '.');
  1434. if (!r)
  1435. simple_sprintf(work, "-telnet!%s@%s", dcc[idx].host, p);
  1436. else
  1437. simple_sprintf(work, "-telnet!%s@*%s", dcc[idx].host, r);
  1438. *q = '@';
  1439. } else
  1440. simple_sprintf(work, "-telnet!*@*%s", dcc[idx].host);
  1441. userlist = adduser(userlist, buf, work, "-",
  1442. sanity_check(USER_PARTY | default_flags));
  1443. }
  1444. reaffirm_owners();
  1445. dcc[idx].status = STAT_ECHO | STAT_TELNET;
  1446. dcc[idx].type = &DCC_CHAT; /* Just so next line will work */
  1447. dcc[idx].user = get_user_by_handle(userlist, buf);
  1448. check_dcc_attrs(dcc[idx].user, USER_PARTY | default_flags);
  1449. dcc[idx].type = &DCC_TELNET_PW;
  1450. if (make_userfile) {
  1451. dprintf(idx, "\nYOU ARE THE MASTER/OWNER ON THIS BOT NOW\n");
  1452. dprintf(idx, IRC_LIMBO);
  1453. putlog(LOG_MISC, "*", DCC_INSTCOMPL, buf);
  1454. make_userfile = 0;
  1455. write_userfile(-1);
  1456. add_note(buf, botnetnick, "Welcome to eggdrop! :)", -1, 0);
  1457. }
  1458. dprintf(idx, "\nOkay, now choose and enter a password:\n");
  1459. dprintf(idx, "(Only the first 15 letters are significant.)\n");
  1460. }
  1461. }
  1462. static void dcc_telnet_pw(int idx, char *buf, int x)
  1463. {
  1464. char *newpass;
  1465. int ok;
  1466. strip_telnet(dcc[idx].sock, buf, &x);
  1467. buf[16] = 0;
  1468. ok = 1;
  1469. if (strlen(buf) < 4) {
  1470. dprintf(idx, "\nTry to use at least 4 characters in your password.\n");
  1471. dprintf(idx, "Choose and enter a password:\n");
  1472. return;
  1473. }
  1474. for (x = 0; x < strlen(buf); x++)
  1475. if ((buf[x] <= 32) || (buf[x] == 127))
  1476. ok = 0;
  1477. if (!ok) {
  1478. dprintf(idx, "\nYou can't use weird symbols in your password.\n");
  1479. dprintf(idx, "Try another one please:\n");
  1480. return;
  1481. }
  1482. putlog(LOG_MISC, "*", DCC_NEWUSER, dcc[idx].nick, dcc[idx].host,
  1483. dcc[idx].port);
  1484. if (notify_new[0]) {
  1485. char s[121], s1[121], s2[121];
  1486. sprintf(s, "Introduced to %s, %s", dcc[idx].nick, dcc[idx].host);
  1487. strcpy(s1, notify_new);
  1488. splitc(s2, s1, ',');
  1489. while (s2[0]) {
  1490. rmspace(s2);
  1491. add_note(s2, botnetnick, s, -1, 0);
  1492. splitc(s2, s1, ',');
  1493. }
  1494. rmspace(s1);
  1495. add_note(s1, botnetnick, s, -1, 0);
  1496. }
  1497. newpass = newsplit(&buf);
  1498. set_user(&USERENTRY_PASS, dcc[idx].user, newpass);
  1499. dprintf(idx, "\nRemember that! You'll need it next time you log in.\n");
  1500. dprintf(idx, "You now have an account on %s...\n\n\n", botnetnick);
  1501. dcc[idx].type = &DCC_CHAT;
  1502. dcc[idx].u.chat->channel = -2;
  1503. dcc_chatter(idx);
  1504. }
  1505. static void eof_dcc_telnet_new(int idx)
  1506. {
  1507. putlog(LOG_MISC, "*", DCC_LOSTNEWUSER, dcc[idx].host, dcc[idx].port);
  1508. killsock(dcc[idx].sock);
  1509. lostdcc(idx);
  1510. }
  1511. static void eof_dcc_telnet_pw(int idx)
  1512. {
  1513. putlog(LOG_MISC, "*", DCC_LOSTNEWUSR2, dcc[idx].nick, dcc[idx].host,
  1514. dcc[idx].port);
  1515. deluser(dcc[idx].nick);
  1516. killsock(dcc[idx].sock);
  1517. lostdcc(idx);
  1518. }
  1519. static void tout_dcc_telnet_new(int idx)
  1520. {
  1521. dprintf(idx, "Guess you're not there. Bye.\n");
  1522. putlog(LOG_MISC, "*", DCC_TIMEOUTUSER, dcc[idx].host,
  1523. dcc[idx].port);
  1524. killsock(dcc[idx].sock);
  1525. lostdcc(idx);
  1526. }
  1527. static void tout_dcc_telnet_pw(int idx)
  1528. {
  1529. dprintf(idx, "Guess you're not there. Bye.\n");
  1530. putlog(LOG_MISC, "*", DCC_TIMEOUTUSR2, dcc[idx].nick,
  1531. dcc[idx].host, dcc[idx].port);
  1532. killsock(dcc[idx].sock);
  1533. lostdcc(idx);
  1534. }
  1535. static void display_dcc_telnet_new(int idx, char *buf)
  1536. {
  1537. sprintf(buf, "new waited %lus", now - dcc[idx].timeval);
  1538. }
  1539. static void display_dcc_telnet_pw(int idx, char *buf)
  1540. {
  1541. sprintf(buf, "newp waited %lus", now - dcc[idx].timeval);
  1542. }
  1543. struct dcc_table DCC_TELNET_NEW =
  1544. {
  1545. "TELNET_NEW",
  1546. 0,
  1547. eof_dcc_telnet_new,
  1548. dcc_telnet_new,
  1549. &password_timeout,
  1550. tout_dcc_telnet_new,
  1551. display_dcc_telnet_new,
  1552. expmem_dcc_general,
  1553. kill_dcc_general,
  1554. out_dcc_general
  1555. };
  1556. struct dcc_table DCC_TELNET_PW =
  1557. {
  1558. "TELNET_PW",
  1559. 0,
  1560. eof_dcc_telnet_pw,
  1561. dcc_telnet_pw,
  1562. &password_timeout,
  1563. tout_dcc_telnet_pw,
  1564. display_dcc_telnet_pw,
  1565. expmem_dcc_general,
  1566. kill_dcc_general,
  1567. out_dcc_general
  1568. };
  1569. static int call_tcl_func(char *name, int idx, char *args)
  1570. {
  1571. char s[11];
  1572. sprintf(s, "%d", idx);
  1573. Tcl_SetVar(interp, "_n", s, 0);
  1574. Tcl_SetVar(interp, "_a", args, 0);
  1575. if (Tcl_VarEval(interp, name, " $_n $_a", NULL) == TCL_ERROR) {
  1576. putlog(LOG_MISC, "*", DCC_TCLERROR, name, interp->result);
  1577. return -1;
  1578. }
  1579. return (atoi(interp->result));
  1580. }
  1581. static void dcc_script(int idx, char *buf, int len)
  1582. {
  1583. long oldsock;
  1584. strip_telnet(dcc[idx].sock, buf, &len);
  1585. if (!len)
  1586. return;
  1587. dcc[idx].timeval = now;
  1588. oldsock = dcc[idx].sock; /* Remember the socket number. */
  1589. if (call_tcl_func(dcc[idx].u.script->command, dcc[idx].sock, buf)) {
  1590. void *old_other = NULL;
  1591. /* Check whether the socket and dcc entry are still valid. They
  1592. might have been killed by `killdcc'. */
  1593. if (dcc[idx].sock != oldsock || idx > max_dcc)
  1594. return;
  1595. old_other = dcc[idx].u.script->u.other;
  1596. dcc[idx].type = dcc[idx].u.script->type;
  1597. nfree(dcc[idx].u.script);
  1598. dcc[idx].u.other = old_other;
  1599. if (dcc[idx].type == &DCC_SOCKET) {
  1600. /* Kill the whole thing off */
  1601. killsock(dcc[idx].sock);
  1602. lostdcc(idx);
  1603. return;
  1604. }
  1605. if (dcc[idx].type == &DCC_CHAT) {
  1606. if (dcc[idx].u.chat->channel >= 0) {
  1607. chanout_but(-1, dcc[idx].u.chat->channel, DCC_JOIN, dcc[idx].nick);
  1608. if (dcc[idx].u.chat->channel < 10000)
  1609. botnet_send_join_idx(idx, -1);
  1610. check_tcl_chjn(botnetnick, dcc[idx].nick, dcc[idx].u.chat->channel,
  1611. geticon(idx), dcc[idx].sock, dcc[idx].host);
  1612. }
  1613. check_tcl_chon(dcc[idx].nick, dcc[idx].sock);
  1614. }
  1615. }
  1616. }
  1617. static void eof_dcc_script(int idx)
  1618. {
  1619. void *old;
  1620. int oldflags;
  1621. /* This will stop a killdcc from working, incase the script tries
  1622. * to kill it's controlling socket while handling an EOF <cybah>
  1623. */
  1624. oldflags = dcc[idx].type->flags;
  1625. dcc[idx].type->flags &= ~(DCT_VALIDIDX);
  1626. /* Tell the script they're gone: */
  1627. call_tcl_func(dcc[idx].u.script->command, dcc[idx].sock, "");
  1628. /* Restore the flags */
  1629. dcc[idx].type->flags = oldflags;
  1630. old = dcc[idx].u.script->u.other;
  1631. dcc[idx].type = dcc[idx].u.script->type;
  1632. nfree(dcc[idx].u.script);
  1633. dcc[idx].u.other = old;
  1634. /* Then let it fall thru to the real one */
  1635. if (dcc[idx].type && dcc[idx].type->eof)
  1636. dcc[idx].type->eof(idx);
  1637. else {
  1638. putlog(LOG_MISC, "*", DCC_DEADSOCKET, dcc[idx].sock,
  1639. dcc[idx].type->name);
  1640. killsock(dcc[idx].sock);
  1641. lostdcc(idx);
  1642. }
  1643. }
  1644. static void display_dcc_script(int idx, char *buf)
  1645. {
  1646. sprintf(buf, "scri %s", dcc[idx].u.script->command);
  1647. }
  1648. static int expmem_dcc_script(void *x)
  1649. {
  1650. register struct script_info *p = (struct script_info *) x;
  1651. int tot = sizeof(struct script_info);
  1652. if (p->type && p->u.other)
  1653. tot += p->type->expmem(p->u.other);
  1654. return tot;
  1655. }
  1656. static void kill_dcc_script(int idx, void *x)
  1657. {
  1658. register struct script_info *p = (struct script_info *) x;
  1659. if (p->type && p->u.other)
  1660. p->type->kill(idx, p->u.other);
  1661. nfree(p);
  1662. }
  1663. static void out_dcc_script(int idx, char *buf, void *x)
  1664. {
  1665. register struct script_info *p = (struct script_info *) x;
  1666. if (p && p->type && p->u.other)
  1667. p->type->output(idx, buf, p->u.other);
  1668. else
  1669. tputs(dcc[idx].sock, buf, strlen(buf));
  1670. }
  1671. struct dcc_table DCC_SCRIPT =
  1672. {
  1673. "SCRIPT",
  1674. DCT_VALIDIDX,
  1675. eof_dcc_script,
  1676. dcc_script,
  1677. NULL,
  1678. NULL,
  1679. display_dcc_script,
  1680. expmem_dcc_script,
  1681. kill_dcc_script,
  1682. out_dcc_script
  1683. };
  1684. static void dcc_socket(int idx, char *buf, int len)
  1685. {
  1686. }
  1687. static void eof_dcc_socket(int idx)
  1688. {
  1689. killsock(dcc[idx].sock);
  1690. lostdcc(idx);
  1691. }
  1692. static void display_dcc_socket(int idx, char *buf)
  1693. {
  1694. strcpy(buf, "sock (stranded)");
  1695. }
  1696. struct dcc_table DCC_SOCKET =
  1697. {
  1698. "SOCKET",
  1699. DCT_VALIDIDX,
  1700. eof_dcc_socket,
  1701. dcc_socket,
  1702. NULL,
  1703. NULL,
  1704. display_dcc_socket,
  1705. NULL,
  1706. NULL,
  1707. NULL
  1708. };
  1709. static void display_dcc_lost(int idx, char *buf)
  1710. {
  1711. strcpy(buf, "lost");
  1712. }
  1713. struct dcc_table DCC_LOST =
  1714. {
  1715. "LOST",
  1716. 0,
  1717. NULL,
  1718. dcc_socket,
  1719. NULL,
  1720. NULL,
  1721. display_dcc_lost,
  1722. NULL,
  1723. NULL,
  1724. NULL
  1725. };
  1726. void dcc_identwait(int idx, char *buf, int len)
  1727. {
  1728. /* Ignore anything now */
  1729. }
  1730. void eof_dcc_identwait(int idx)
  1731. {
  1732. int i;
  1733. putlog(LOG_MISC, "*", DCC_LOSTCONN, dcc[idx].host, dcc[idx].port);
  1734. for (i = 0; i < dcc_total; i++)
  1735. if ((dcc[i].type == &DCC_IDENT) &&
  1736. (dcc[i].u.ident_sock == dcc[idx].sock)) {
  1737. killsock(dcc[i].sock); /* Cleanup ident socket */
  1738. dcc[i].u.other = 0;
  1739. lostdcc(i);
  1740. break;
  1741. }
  1742. killsock(dcc[idx].sock); /* Cleanup waiting socket */
  1743. dcc[idx].u.other = 0;
  1744. lostdcc(idx);
  1745. }
  1746. static void display_dcc_identwait(int idx, char *buf)
  1747. {
  1748. sprintf(buf, "idtw waited %lus", now - dcc[idx].timeval);
  1749. }
  1750. struct dcc_table DCC_IDENTWAIT =
  1751. {
  1752. "IDENTWAIT",
  1753. 0,
  1754. eof_dcc_identwait,
  1755. dcc_identwait,
  1756. NULL,
  1757. NULL,
  1758. display_dcc_identwait,
  1759. NULL,
  1760. NULL,
  1761. NULL
  1762. };
  1763. void dcc_ident(int idx, char *buf, int len)
  1764. {
  1765. char response[512], uid[512], buf1[UHOSTLEN];
  1766. int i;
  1767. sscanf(buf, "%*[^:]:%[^:]:%*[^:]:%[^\n]\n", response, uid);
  1768. rmspace(response);
  1769. if (response[0] != 'U') {
  1770. dcc[idx].timeval = now;
  1771. return;
  1772. }
  1773. rmspace(uid);
  1774. uid[20] = 0; /* 20 character ident max */
  1775. for (i = 0; i < dcc_total; i++)
  1776. if ((dcc[i].type == &DCC_IDENTWAIT) &&
  1777. (dcc[i].sock == dcc[idx].u.ident_sock)) {
  1778. simple_sprintf(buf1, "%s@%s", uid, dcc[idx].host);
  1779. dcc_telnet_got_ident(i, buf1);
  1780. }
  1781. dcc[idx].u.other = 0;
  1782. killsock(dcc[idx].sock);
  1783. lostdcc(idx);
  1784. }
  1785. void eof_dcc_ident(int idx)
  1786. {
  1787. char buf[UHOSTLEN];
  1788. int i;
  1789. for (i = 0; i < dcc_total; i++)
  1790. if ((dcc[i].type == &DCC_IDENTWAIT) &&
  1791. (dcc[i].sock == dcc[idx].u.ident_sock)) {
  1792. putlog(LOG_MISC, "*", DCC_EOFIDENT);
  1793. simple_sprintf(buf, "telnet@%s", dcc[idx].host);
  1794. dcc_telnet_got_ident(i, buf);
  1795. }
  1796. killsock(dcc[idx].sock);
  1797. dcc[idx].u.other = 0;
  1798. lostdcc(idx);
  1799. }
  1800. static void display_dcc_ident(int idx, char *buf)
  1801. {
  1802. sprintf(buf, "idnt (sock %d)", dcc[idx].u.ident_sock);
  1803. }
  1804. struct dcc_table DCC_IDENT =
  1805. {
  1806. "IDENT",
  1807. 0,
  1808. eof_dcc_ident,
  1809. dcc_ident,
  1810. &identtimeout,
  1811. eof_dcc_ident,
  1812. display_dcc_ident,
  1813. NULL,
  1814. NULL,
  1815. NULL
  1816. };
  1817. void dcc_telnet_got_ident(int i, char *host)
  1818. {
  1819. int idx;
  1820. char x[1024];
  1821. for (idx = 0; idx < dcc_total; idx++)
  1822. if ((dcc[idx].type == &DCC_TELNET) &&
  1823. (dcc[idx].sock == dcc[i].u.ident_sock))
  1824. break;
  1825. dcc[i].u.other = 0;
  1826. if (dcc_total == idx) {
  1827. putlog(LOG_MISC, "*", DCC_LOSTIDENT);
  1828. killsock(dcc[i].sock);
  1829. lostdcc(i);
  1830. return;
  1831. }
  1832. strncpyz(dcc[i].host, host, UHOSTLEN);
  1833. egg_snprintf(x, sizeof x, "-telnet!%s", dcc[i].host);
  1834. if (protect_telnet && !make_userfile) {
  1835. struct userrec *u;
  1836. int ok = 1;
  1837. u = get_user_by_host(x);
  1838. /* Not a user or +p & require p OR +o */
  1839. if (!u)
  1840. ok = 0;
  1841. else if (require_p && !(u->flags & USER_PARTY))
  1842. ok = 0;
  1843. else if (!require_p && !(u->flags & USER_OP))
  1844. ok = 0;
  1845. if (!ok && u && (u->flags & USER_BOT))
  1846. ok = 1;
  1847. if (!ok && (dcc[idx].status & LSTN_PUBLIC))
  1848. ok = 1;
  1849. if (!ok) {
  1850. putlog(LOG_MISC, "*", DCC_NOACCESS, dcc[i].host);
  1851. killsock(dcc[i].sock);
  1852. lostdcc(i);
  1853. return;
  1854. }
  1855. }
  1856. if (match_ignore(x)) {
  1857. killsock(dcc[i].sock);
  1858. lostdcc(i);
  1859. return;
  1860. }
  1861. /* Script? */
  1862. if (!strcmp(dcc[idx].nick, "(script)")) {
  1863. dcc[i].type = &DCC_SOCKET;
  1864. dcc[i].u.other = NULL;
  1865. strcpy(dcc[i].nick, "*");
  1866. check_tcl_listen(dcc[idx].host, dcc[i].sock);
  1867. return;
  1868. }
  1869. /* Do not buffer data anymore. All received and stored data is passed
  1870. over to the dcc functions from now on. */
  1871. sockoptions(dcc[i].sock, EGG_OPTION_UNSET, SOCK_BUFFER);
  1872. dcc[i].type = &DCC_TELNET_ID;
  1873. dcc[i].u.chat = get_data_ptr(sizeof(struct chat_info));
  1874. egg_bzero(dcc[i].u.chat, sizeof(struct chat_info));
  1875. /* Copy acceptable-nick/host mask */
  1876. dcc[i].status = STAT_TELNET | STAT_ECHO;
  1877. if (!strcmp(dcc[idx].nick, "(bots)"))
  1878. dcc[i].status |= STAT_BOTONLY;
  1879. if (!strcmp(dcc[idx].nick, "(users)"))
  1880. dcc[i].status |= STAT_USRONLY;
  1881. /* Copy acceptable-nick/host mask */
  1882. strncpyz(dcc[i].nick, dcc[idx].host, HANDLEN);
  1883. dcc[i].timeval = now;
  1884. strcpy(dcc[i].u.chat->con_chan, chanset ? chanset->name : "*");
  1885. /* Displays a customizable banner. */
  1886. if (use_telnet_banner)
  1887. show_banner(i);
  1888. /* This is so we dont tell someone doing a portscan anything
  1889. * about ourselves. <cybah>
  1890. */
  1891. if (stealth_telnets)
  1892. sub_lang(i, MISC_BANNER_STEALTH);
  1893. else {
  1894. dprintf(i, "\n\n");
  1895. sub_lang(i, MISC_BANNER);
  1896. }
  1897. if (allow_new_telnets)
  1898. dprintf(i, "(If you are new, enter 'NEW' here.)\n");
  1899. }