00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "main.h"
00029 #include <ctype.h>
00030 #include <errno.h>
00031 #include "modules.h"
00032 #include "tandem.h"
00033
00034
00035 #include "md5/md5.h"
00036
00037 extern struct userrec *userlist;
00038 extern struct chanset_t *chanset;
00039 extern Tcl_Interp *interp;
00040 extern time_t now;
00041 extern char botnetnick[], ver[], origbotname[], notify_new[];
00042 extern int egg_numver, connect_timeout, conmask, backgrd, max_dcc,
00043 make_userfile, default_flags, raw_log, ignore_time,
00044 par_telnet_flood;
00045
00046 struct dcc_t *dcc = NULL;
00047 int dcc_total = 0;
00048 char tempdir[121] = "";
00049
00050 int require_p = 0;
00051
00052 int allow_new_telnets = 0;
00053
00054 int stealth_telnets = 0;
00055 int use_telnet_banner = 0;
00056 char network[41] = "unknown-net";
00057 int password_timeout = 180;
00058 int bot_timeout = 60;
00059 int identtimeout = 5;
00060 int dupwait_timeout = 5;
00061 int protect_telnet = 1;
00062 int flood_telnet_thr = 5;
00063
00064 int flood_telnet_time = 60;
00065 char bannerfile[121] = "text/banner";
00066
00067 static void dcc_telnet_hostresolved(int);
00068 static void dcc_telnet_got_ident(int, char *);
00069 static void dcc_telnet_pass(int, int);
00070
00071
00072
00073
00074
00075
00076 static int detect_telnet(unsigned char *buf)
00077 {
00078 if (!buf || !buf[0] || !buf[1])
00079 return 0;
00080 while (buf[2]) {
00081 if (buf[0] == TLN_IAC && (buf[1] == TLN_DO || buf[1] == TLN_DONT) &&
00082 buf[2] == TLN_STATUS)
00083 return 1;
00084 buf++;
00085 }
00086 return 0;
00087 }
00088
00089
00090 static char *escape_telnet(char *s)
00091 {
00092 static char buf[1024];
00093 char *p;
00094
00095 for (p = buf; *s && (p < (buf + sizeof(buf) - 2)); *p++ = *s++)
00096 if ((unsigned char) *s == TLN_IAC)
00097 *p++ = *s;
00098 else if (*s == '\n')
00099 *p++ = '\r';
00100 *p = 0;
00101
00102 return buf;
00103 }
00104
00105 static void strip_telnet(int sock, char *buf, int *len)
00106 {
00107 unsigned char *p = (unsigned char *) buf, *o = (unsigned char *) buf;
00108 int mark;
00109
00110 while (*p != 0) {
00111 while ((*p != TLN_IAC) && (*p != 0))
00112 *o++ = *p++;
00113 if (*p == TLN_IAC) {
00114 p++;
00115 mark = 2;
00116 if (!*p)
00117 mark = 1;
00118 if ((*p >= TLN_WILL) && (*p <= TLN_DONT)) {
00119 mark = 3;
00120 if (!*(p + 1))
00121 mark = 2;
00122 } else if (*p == TLN_WILL) {
00123
00124
00125 if (*(p + 1) != TLN_ECHO) {
00126 write(sock, TLN_IAC_C TLN_DONT_C, 2);
00127 write(sock, p + 1, 1);
00128 }
00129 } else if (*p == TLN_DO) {
00130
00131
00132 if (*(p + 1) != TLN_ECHO) {
00133 write(sock, TLN_IAC_C TLN_WONT_C, 2);
00134 write(sock, p + 1, 1);
00135 }
00136 } else if (*p == TLN_AYT) {
00137
00138
00139 write(sock, "\r\nHell, yes!\r\n", 14);
00140 } else if (*p == TLN_IAC) {
00141
00142 *o++ = *p++;
00143 mark = 1;
00144 }
00145
00146 p += mark - 1;
00147 *len = *len - mark;
00148 }
00149 }
00150 *o = *p;
00151 }
00152
00153 static void greet_new_bot(int idx)
00154 {
00155 int bfl = bot_flags(dcc[idx].user);
00156 int i;
00157
00158 dcc[idx].timeval = now;
00159 dcc[idx].u.bot->version[0] = 0;
00160 dcc[idx].u.bot->numver = 0;
00161 if (bfl & BOT_REJECT) {
00162 putlog(LOG_BOTS, "*", DCC_REJECT, dcc[idx].nick);
00163 dprintf(idx, "bye %s\n", "rejected");
00164 killsock(dcc[idx].sock);
00165 lostdcc(idx);
00166 return;
00167 }
00168 if (bfl & BOT_LEAF)
00169 dcc[idx].status |= STAT_LEAF;
00170 dcc[idx].status |= STAT_LINKING;
00171 #ifndef NO_OLD_BOTNET
00172 dprintf(idx, "version %d %d %s <%s>\n", egg_numver, HANDLEN, ver, network);
00173 #else
00174 dprintf(idx, "v %d %d %s <%s>\n", egg_numver, HANDLEN, ver, network);
00175 #endif
00176 for (i = 0; i < dcc_total; i++)
00177 if (dcc[i].type == &DCC_FORK_BOT) {
00178 killsock(dcc[i].sock);
00179 lostdcc(i);
00180 }
00181 }
00182
00183 static void bot_version(int idx, char *par)
00184 {
00185 char x[1024];
00186 int l;
00187
00188 dcc[idx].timeval = now;
00189 if (in_chain(dcc[idx].nick)) {
00190 dprintf(idx, "error Sorry, already connected.\n");
00191 dprintf(idx, "bye\n");
00192 killsock(dcc[idx].sock);
00193 lostdcc(idx);
00194 return;
00195 }
00196 if ((par[0] >= '0') && (par[0] <= '9')) {
00197 char *work;
00198
00199 work = newsplit(&par);
00200 dcc[idx].u.bot->numver = atoi(work);
00201 } else
00202 dcc[idx].u.bot->numver = 0;
00203
00204 #ifndef NO_OLD_BOTNET
00205 if (b_numver(idx) < NEAT_BOTNET) {
00206 #if HANDLEN != 9
00207 putlog(LOG_BOTS, "*", "Non-matching handle lengths with %s, they use 9 "
00208 "characters.", dcc[idx].nick);
00209 dprintf(idx, "error Non-matching handle length: mine %d, yours 9\n",
00210 HANDLEN);
00211 dprintf(idx, "bye %s\n", "bad handlen");
00212 killsock(dcc[idx].sock);
00213 lostdcc(idx);
00214 return;
00215 #else
00216 dprintf(idx, "thisbot %s\n", botnetnick);
00217 #endif
00218 } else {
00219 #endif
00220 dprintf(idx, "tb %s\n", botnetnick);
00221 l = atoi(newsplit(&par));
00222 if (l != HANDLEN) {
00223 putlog(LOG_BOTS, "*", "Non-matching handle lengths with %s, they use %d "
00224 "characters.", dcc[idx].nick, l);
00225 dprintf(idx, "error Non-matching handle length: mine %d, yours %d\n",
00226 HANDLEN, l);
00227 dprintf(idx, "bye %s\n", "bad handlen");
00228 killsock(dcc[idx].sock);
00229 lostdcc(idx);
00230 return;
00231 }
00232 #ifndef NO_OLD_BOTNET
00233 }
00234 #endif
00235 strncpyz(dcc[idx].u.bot->version, par, 120);
00236 putlog(LOG_BOTS, "*", DCC_LINKED, dcc[idx].nick);
00237 chatout("*** Linked to %s\n", dcc[idx].nick);
00238 botnet_send_nlinked(idx, dcc[idx].nick, botnetnick, '!',
00239 dcc[idx].u.bot->numver);
00240 touch_laston(dcc[idx].user, "linked", now);
00241 dump_links(idx);
00242 dcc[idx].type = &DCC_BOT;
00243 addbot(dcc[idx].nick, dcc[idx].nick, botnetnick, '-', dcc[idx].u.bot->numver);
00244 check_tcl_link(dcc[idx].nick, botnetnick);
00245 egg_snprintf(x, sizeof x, "v %d", dcc[idx].u.bot->numver);
00246 bot_share(idx, x);
00247 dprintf(idx, "el\n");
00248 }
00249
00250 void failed_link(int idx)
00251 {
00252 char s[81], s1[512];
00253
00254 if (dcc[idx].port >= dcc[idx].u.bot->port + 3) {
00255 if (dcc[idx].u.bot->linker[0]) {
00256 egg_snprintf(s, sizeof s, "Couldn't link to %s.", dcc[idx].nick);
00257 strcpy(s1, dcc[idx].u.bot->linker);
00258 add_note(s1, botnetnick, s, -2, 0);
00259 }
00260 if (dcc[idx].u.bot->numver >= -1)
00261 putlog(LOG_BOTS, "*", DCC_LINKFAIL, dcc[idx].nick);
00262 killsock(dcc[idx].sock);
00263 strcpy(s, dcc[idx].nick);
00264 lostdcc(idx);
00265 autolink_cycle(s);
00266 return;
00267 }
00268
00269
00270 killsock(dcc[idx].sock);
00271 dcc[idx].sock = getsock(SOCK_STRONGCONN);
00272 dcc[idx].port++;
00273 dcc[idx].timeval = now;
00274 if (dcc[idx].sock < 0 ||
00275 open_telnet_raw(dcc[idx].sock, dcc[idx].addr ?
00276 iptostr(htonl(dcc[idx].addr)) : dcc[idx].host,
00277 dcc[idx].port) < 0) {
00278 failed_link(idx);
00279 }
00280 }
00281
00282 static void cont_link(int idx, char *buf, int i)
00283 {
00284 char x[1024];
00285 int atr = bot_flags(dcc[idx].user);
00286 int users, bots;
00287
00288 if (atr & BOT_HUB) {
00289
00290 for (i = 0; i < dcc_total; i++) {
00291 if ((i != idx) && (bot_flags(dcc[i].user) & BOT_ALT)) {
00292 if ((dcc[i].type == &DCC_FORK_BOT) || (dcc[i].type == &DCC_BOT_NEW)) {
00293 killsock(dcc[i].sock);
00294 lostdcc(i);
00295 }
00296 }
00297 }
00298
00299 if (in_chain(dcc[idx].nick)) {
00300 i = nextbot(dcc[idx].nick);
00301 if (i > 0) {
00302 bots = bots_in_subtree(findbot(dcc[idx].nick));
00303 users = users_in_subtree(findbot(dcc[idx].nick));
00304 egg_snprintf(x, sizeof x,
00305 "Unlinked %s (restructure) (lost %d bot%s and %d user%s)",
00306 dcc[i].nick, bots, (bots != 1) ? "s" : "",
00307 users, (users != 1) ? "s" : "");
00308 chatout("*** %s\n", x);
00309 botnet_send_unlinked(i, dcc[i].nick, x);
00310 dprintf(i, "bye %s\n", "restructure");
00311 killsock(dcc[i].sock);
00312 lostdcc(i);
00313 }
00314 }
00315 }
00316 dcc[idx].type = &DCC_BOT_NEW;
00317 dcc[idx].u.bot->numver = 0;
00318
00319
00320
00321
00322
00323 dprintf(idx, "%s\n", botnetnick);
00324 return;
00325 }
00326
00327
00328
00329
00330 static void dcc_bot_digest(int idx, char *challenge, char *password)
00331 {
00332 MD5_CTX md5context;
00333 char digest_string[33];
00334 unsigned char digest[16];
00335 int i;
00336
00337 MD5_Init(&md5context);
00338 MD5_Update(&md5context, (unsigned char *) challenge, strlen(challenge));
00339 MD5_Update(&md5context, (unsigned char *) password, strlen(password));
00340 MD5_Final(digest, &md5context);
00341
00342 for (i = 0; i < 16; i++)
00343 sprintf(digest_string + (i * 2), "%.2x", digest[i]);
00344 dprintf(idx, "digest %s\n", digest_string);
00345 putlog(LOG_BOTS, "*", "Received challenge from %s... sending response ...",
00346 dcc[idx].nick);
00347 }
00348
00349 static void dcc_bot_new(int idx, char *buf, int x)
00350 {
00351 struct userrec *u = get_user_by_handle(userlist, dcc[idx].nick);
00352 char *code;
00353
00354 code = newsplit(&buf);
00355 if (!egg_strcasecmp(code, "*hello!"))
00356 greet_new_bot(idx);
00357 else if (!egg_strcasecmp(code, "version") || !egg_strcasecmp(code, "v"))
00358 bot_version(idx, buf);
00359 else if (!egg_strcasecmp(code, "badpass"))
00360
00361 putlog(LOG_BOTS, "*", DCC_BADPASS, dcc[idx].nick);
00362 else if (!egg_strcasecmp(code, "passreq")) {
00363 char *pass = get_user(&USERENTRY_PASS, u);
00364
00365 if (!pass || !strcmp(pass, "-")) {
00366 putlog(LOG_BOTS, "*", DCC_PASSREQ, dcc[idx].nick);
00367 dprintf(idx, "-\n");
00368 } else {
00369
00370
00371
00372 if (buf && buf[0] && strchr(buf, '<') && strchr(buf + 1, '>'))
00373 dcc_bot_digest(idx, buf, pass);
00374 else
00375 dprintf(idx, "%s\n", pass);
00376 }
00377 } else if (!egg_strcasecmp(code, "error"))
00378 putlog(LOG_BOTS, "*", DCC_LINKERROR, dcc[idx].nick, buf);
00379
00380 }
00381
00382 static void eof_dcc_bot_new(int idx)
00383 {
00384 putlog(LOG_BOTS, "*", DCC_LOSTBOT, dcc[idx].nick, dcc[idx].port);
00385 killsock(dcc[idx].sock);
00386 lostdcc(idx);
00387 }
00388
00389 static void timeout_dcc_bot_new(int idx)
00390 {
00391 putlog(LOG_BOTS, "*", DCC_TIMEOUT, dcc[idx].nick,
00392 dcc[idx].host, dcc[idx].port);
00393 killsock(dcc[idx].sock);
00394 lostdcc(idx);
00395 }
00396
00397 static void display_dcc_bot_new(int idx, char *buf)
00398 {
00399 long tv;
00400
00401 tv = now - dcc[idx].timeval;
00402 sprintf(buf, "bot* waited %lis", tv);
00403 }
00404
00405 static int expmem_dcc_bot_(void *x)
00406 {
00407 return sizeof(struct bot_info);
00408 }
00409
00410 static void free_dcc_bot_(int n, void *x)
00411 {
00412 if (dcc[n].type == &DCC_BOT) {
00413 unvia(n, findbot(dcc[n].nick));
00414 rembot(dcc[n].nick);
00415 }
00416 nfree(x);
00417 }
00418
00419 struct dcc_table DCC_BOT_NEW = {
00420 "BOT_NEW",
00421 0,
00422 eof_dcc_bot_new,
00423 dcc_bot_new,
00424 &bot_timeout,
00425 timeout_dcc_bot_new,
00426 display_dcc_bot_new,
00427 expmem_dcc_bot_,
00428 free_dcc_bot_,
00429 NULL
00430 };
00431
00432
00433 extern botcmd_t C_bot[];
00434
00435 static void dcc_bot(int idx, char *code, int i)
00436 {
00437 char *msg;
00438 int f;
00439
00440 if (raw_log) {
00441 if (code[0] == 's')
00442 putlog(LOG_BOTSHARE, "*", "{%s} %s", dcc[idx].nick, code + 2);
00443 else
00444 putlog(LOG_BOTNET, "*", "[%s] %s", dcc[idx].nick, code);
00445 }
00446 msg = strchr(code, ' ');
00447 if (msg) {
00448 *msg = 0;
00449 msg++;
00450 } else
00451 msg = "";
00452 for (f = i = 0; C_bot[i].name && !f; i++) {
00453 int y = egg_strcasecmp(code, C_bot[i].name);
00454
00455 if (!y) {
00456
00457 (C_bot[i].func) (idx, msg);
00458 f = 1;
00459 } else if (y < 0)
00460 return;
00461 }
00462 }
00463
00464 static void eof_dcc_bot(int idx)
00465 {
00466 char x[1024];
00467 int bots, users;
00468
00469 bots = bots_in_subtree(findbot(dcc[idx].nick));
00470 users = users_in_subtree(findbot(dcc[idx].nick));
00471 egg_snprintf(x, sizeof x,
00472 "Lost bot: %s (lost %d bot%s and %d user%s)",
00473 dcc[idx].nick, bots, (bots != 1) ? "s" : "", users,
00474 (users != 1) ? "s" : "");
00475 putlog(LOG_BOTS, "*", "%s.", x);
00476 chatout("*** %s\n", x);
00477 botnet_send_unlinked(idx, dcc[idx].nick, x);
00478 killsock(dcc[idx].sock);
00479 lostdcc(idx);
00480 }
00481
00482 static void display_dcc_bot(int idx, char *buf)
00483 {
00484 int i = simple_sprintf(buf, "bot flags: ");
00485
00486 buf[i++] = b_status(idx) & STAT_PINGED ? 'P' : 'p';
00487 buf[i++] = b_status(idx) & STAT_SHARE ? 'U' : 'u';
00488 buf[i++] = b_status(idx) & STAT_CALLED ? 'C' : 'c';
00489 buf[i++] = b_status(idx) & STAT_OFFERED ? 'O' : 'o';
00490 buf[i++] = b_status(idx) & STAT_SENDING ? 'S' : 's';
00491 buf[i++] = b_status(idx) & STAT_GETTING ? 'G' : 'g';
00492 buf[i++] = b_status(idx) & STAT_WARNED ? 'W' : 'w';
00493 buf[i++] = b_status(idx) & STAT_LEAF ? 'L' : 'l';
00494 buf[i++] = b_status(idx) & STAT_LINKING ? 'I' : 'i';
00495 buf[i++] = b_status(idx) & STAT_AGGRESSIVE ? 'a' : 'A';
00496 buf[i++] = 0;
00497 }
00498
00499 static void display_dcc_fork_bot(int idx, char *buf)
00500 {
00501 sprintf(buf, "conn bot");
00502 }
00503
00504 struct dcc_table DCC_BOT = {
00505 "BOT",
00506 DCT_BOT | DCT_VALIDIDX,
00507 eof_dcc_bot,
00508 dcc_bot,
00509 NULL,
00510 NULL,
00511 display_dcc_bot,
00512 expmem_dcc_bot_,
00513 free_dcc_bot_,
00514 NULL
00515 };
00516
00517 struct dcc_table DCC_FORK_BOT = {
00518 "FORK_BOT",
00519 0,
00520 failed_link,
00521 cont_link,
00522 &connect_timeout,
00523 failed_link,
00524 display_dcc_fork_bot,
00525 expmem_dcc_bot_,
00526 free_dcc_bot_,
00527 NULL
00528 };
00529
00530
00531
00532
00533
00534
00535
00536
00537 static int dcc_bot_check_digest(int idx, char *remote_digest)
00538 {
00539 MD5_CTX md5context;
00540 char digest_string[33];
00541 unsigned char digest[16];
00542 int i;
00543 char *password = get_user(&USERENTRY_PASS, dcc[idx].user);
00544
00545 if (!password)
00546 return 1;
00547
00548 MD5_Init(&md5context);
00549
00550 egg_snprintf(digest_string, 33, "<%x%x@", getpid(),
00551 (unsigned int) dcc[idx].timeval);
00552 MD5_Update(&md5context, (unsigned char *) digest_string,
00553 strlen(digest_string));
00554 MD5_Update(&md5context, (unsigned char *) botnetnick, strlen(botnetnick));
00555 MD5_Update(&md5context, (unsigned char *) ">", 1);
00556 MD5_Update(&md5context, (unsigned char *) password, strlen(password));
00557
00558 MD5_Final(digest, &md5context);
00559
00560 for (i = 0; i < 16; i++)
00561 sprintf(digest_string + (i * 2), "%.2x", digest[i]);
00562
00563 if (!strcmp(digest_string, remote_digest))
00564 return 1;
00565
00566 putlog(LOG_BOTS, "*", "Response (password hash) from %s incorrect",
00567 dcc[idx].nick);
00568 return 0;
00569 }
00570
00571 static void dcc_chat_pass(int idx, char *buf, int atr)
00572 {
00573 if (!atr)
00574 return;
00575 if (dcc[idx].status & STAT_TELNET)
00576 strip_telnet(dcc[idx].sock, buf, &atr);
00577 else if (detect_telnet((unsigned char *) buf))
00578 buf += 3;
00579 atr = dcc[idx].user ? dcc[idx].user->flags : 0;
00580
00581
00582 if ((atr & USER_BOT) && !egg_strncasecmp(buf, "digest ", 7)) {
00583 if (dcc_bot_check_digest(idx, buf + 7)) {
00584 nfree(dcc[idx].u.chat);
00585 dcc[idx].type = &DCC_BOT_NEW;
00586 dcc[idx].u.bot = get_data_ptr(sizeof(struct bot_info));
00587 dcc[idx].status = STAT_CALLED;
00588 dprintf(idx, "*hello!\n");
00589 greet_new_bot(idx);
00590 return;
00591 } else {
00592
00593 dprintf(idx, "badpass\n");
00594 putlog(LOG_MISC, "*", DCC_BADLOGIN, dcc[idx].nick, dcc[idx].host,
00595 dcc[idx].port);
00596 killsock(dcc[idx].sock);
00597 lostdcc(idx);
00598 return;
00599 }
00600 }
00601
00602 if (u_pass_match(dcc[idx].user, buf)) {
00603 if (atr & USER_BOT) {
00604 nfree(dcc[idx].u.chat);
00605 dcc[idx].type = &DCC_BOT_NEW;
00606 dcc[idx].u.bot = get_data_ptr(sizeof(struct bot_info));
00607
00608 dcc[idx].status = STAT_CALLED;
00609 dprintf(idx, "*hello!\n");
00610 greet_new_bot(idx);
00611 } else {
00612
00613 putlog(LOG_MISC, "*", DCC_LOGGEDIN, dcc[idx].nick,
00614 dcc[idx].host, dcc[idx].port);
00615 if (dcc[idx].u.chat->away) {
00616 nfree(dcc[idx].u.chat->away);
00617 dcc[idx].u.chat->away = NULL;
00618 }
00619 dcc[idx].type = &DCC_CHAT;
00620 dcc[idx].status &= ~STAT_CHAT;
00621 dcc[idx].u.chat->con_flags = (atr & USER_MASTER) ? conmask : 0;
00622 dcc[idx].u.chat->channel = -2;
00623
00624 if (dcc[idx].status & STAT_TELNET)
00625 tputs(dcc[idx].sock, TLN_IAC_C TLN_WONT_C TLN_ECHO_C "\n", 4);
00626 dcc_chatter(idx);
00627 }
00628 } else {
00629 if (atr & USER_BOT)
00630 dprintf(idx, "badpass\n");
00631 else
00632 dprintf(idx, DCC_HOUSTON);
00633 putlog(LOG_MISC, "*", DCC_BADLOGIN, dcc[idx].nick,
00634 dcc[idx].host, dcc[idx].port);
00635 if (dcc[idx].u.chat->away) {
00636
00637 if (dcc[idx].status & STAT_TELNET)
00638 tputs(dcc[idx].sock, TLN_IAC_C TLN_WONT_C TLN_ECHO_C "\n", 4);
00639 dcc[idx].user = get_user_by_handle(userlist, dcc[idx].u.chat->away);
00640 strcpy(dcc[idx].nick, dcc[idx].u.chat->away);
00641 nfree(dcc[idx].u.chat->away);
00642 nfree(dcc[idx].u.chat->su_nick);
00643 dcc[idx].u.chat->away = NULL;
00644 dcc[idx].u.chat->su_nick = NULL;
00645 dcc[idx].type = &DCC_CHAT;
00646 if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
00647 botnet_send_join_idx(idx, -1);
00648 chanout_but(-1, dcc[idx].u.chat->channel, DCC_JOIN, dcc[idx].nick);
00649 } else {
00650 killsock(dcc[idx].sock);
00651 lostdcc(idx);
00652 }
00653 }
00654 }
00655
00656 static void eof_dcc_general(int idx)
00657 {
00658 putlog(LOG_MISC, "*", DCC_LOSTDCC, dcc[idx].nick,
00659 dcc[idx].host, dcc[idx].port);
00660 killsock(dcc[idx].sock);
00661 lostdcc(idx);
00662 }
00663
00664 static void tout_dcc_chat_pass(int idx)
00665 {
00666 dprintf(idx, "Timeout.\n");
00667 putlog(LOG_MISC, "*", DCC_PWDTIMEOUT, dcc[idx].nick, dcc[idx].host);
00668 killsock(dcc[idx].sock);
00669 lostdcc(idx);
00670 }
00671
00672 static void display_dcc_chat_pass(int idx, char *buf)
00673 {
00674 long tv;
00675
00676 tv = now - dcc[idx].timeval;
00677 sprintf(buf, "pass waited %lis", tv);
00678 }
00679
00680 static int expmem_dcc_general(void *x)
00681 {
00682 register struct chat_info *p = (struct chat_info *) x;
00683 int tot = sizeof(struct chat_info);
00684
00685 if (p->away)
00686 tot += strlen(p->away) + 1;
00687 if (p->buffer) {
00688 struct msgq *q = p->buffer;
00689
00690 while (q) {
00691 tot += sizeof(struct list_type);
00692
00693 tot += q->len + 1;
00694 q = q->next;
00695 }
00696 }
00697 if (p->su_nick)
00698 tot += strlen(p->su_nick) + 1;
00699 return tot;
00700 }
00701
00702 static void kill_dcc_general(int idx, void *x)
00703 {
00704 register struct chat_info *p = (struct chat_info *) x;
00705
00706 if (p) {
00707 if (p->buffer) {
00708 struct msgq *r, *q;
00709
00710 for (r = dcc[idx].u.chat->buffer; r; r = q) {
00711 q = r->next;
00712 nfree(r->msg);
00713 nfree(r);
00714 }
00715 }
00716 if (p->away) {
00717 nfree(p->away);
00718 }
00719 nfree(p);
00720 }
00721 }
00722
00723
00724
00725
00726
00727
00728 void strip_mirc_codes(int flags, char *text)
00729 {
00730 char *dd = text;
00731
00732 while (*text) {
00733 switch (*text) {
00734 case 2:
00735 if (flags & STRIP_BOLD) {
00736 text++;
00737 continue;
00738 }
00739 break;
00740 case 3:
00741 if (flags & STRIP_COLOR) {
00742 if (egg_isdigit(text[1])) {
00743 text += 2;
00744 if (egg_isdigit(*text))
00745 text++;
00746 if (*text == ',') {
00747 if (egg_isdigit(text[1]))
00748 text += 2;
00749 if (egg_isdigit(*text))
00750 text++;
00751 }
00752 } else
00753 text++;
00754 continue;
00755 }
00756 break;
00757 case 7:
00758 if (flags & STRIP_BELLS) {
00759 text++;
00760 continue;
00761 }
00762 break;
00763 case 0x16:
00764 if (flags & STRIP_REV) {
00765 text++;
00766 continue;
00767 }
00768 break;
00769 case 0x1f:
00770 if (flags & STRIP_UNDER) {
00771 text++;
00772 continue;
00773 }
00774 break;
00775 case 033:
00776 if (flags & STRIP_ANSI) {
00777 text++;
00778 if (*text == '[') {
00779 text++;
00780 while ((*text == ';') || egg_isdigit(*text))
00781 text++;
00782 if (*text)
00783 text++;
00784 }
00785 continue;
00786 }
00787 break;
00788 }
00789 *dd++ = *text++;
00790 }
00791 *dd = 0;
00792 }
00793
00794 static void append_line(int idx, char *line)
00795 {
00796 int l = strlen(line);
00797 struct msgq *p, *q;
00798 struct chat_info *c = (dcc[idx].type == &DCC_CHAT) ? dcc[idx].u.chat :
00799 dcc[idx].u.file->chat;
00800
00801 if (c->current_lines > 1000) {
00802
00803 for (p = c->buffer; p; p = q) {
00804 q = p->next;
00805 nfree(p->msg);
00806 nfree(p);
00807 }
00808 c->buffer = 0;
00809 dcc[idx].status &= ~STAT_PAGE;
00810 do_boot(idx, botnetnick, "too many pages - sendq full");
00811 return;
00812 }
00813 if ((c->line_count < c->max_line) && (c->buffer == NULL)) {
00814 c->line_count++;
00815 tputs(dcc[idx].sock, line, l);
00816 } else {
00817 c->current_lines++;
00818 if (c->buffer == NULL)
00819 q = NULL;
00820 else
00821 for (q = c->buffer; q->next; q = q->next);
00822
00823 p = get_data_ptr(sizeof(struct msgq));
00824
00825 p->len = l;
00826 p->msg = get_data_ptr(l + 1);
00827 p->next = NULL;
00828 strcpy(p->msg, line);
00829 if (q == NULL)
00830 c->buffer = p;
00831 else
00832 q->next = p;
00833 }
00834 }
00835
00836
00837 static void out_dcc_general(int idx, char *buf, void *x)
00838 {
00839 register struct chat_info *p = (struct chat_info *) x;
00840 char *y = buf;
00841
00842 strip_mirc_codes(p->strip_flags, buf);
00843 if (dcc[idx].status & STAT_TELNET)
00844 y = escape_telnet(buf);
00845 if (dcc[idx].status & STAT_PAGE)
00846 append_line(idx, y);
00847 else
00848 tputs(dcc[idx].sock, y, strlen(y));
00849 }
00850
00851 struct dcc_table DCC_CHAT_PASS = {
00852 "CHAT_PASS",
00853 0,
00854 eof_dcc_general,
00855 dcc_chat_pass,
00856 &password_timeout,
00857 tout_dcc_chat_pass,
00858 display_dcc_chat_pass,
00859 expmem_dcc_general,
00860 kill_dcc_general,
00861 out_dcc_general
00862 };
00863
00864
00865 int check_ansi(char *v)
00866 {
00867 int count = 2;
00868
00869 if (*v++ != '\033')
00870 return 1;
00871 if (*v++ != '[')
00872 return 1;
00873 while (*v) {
00874 if (*v == 'm')
00875 return 0;
00876 if ((*v != ';') && ((*v < '0') || (*v > '9')))
00877 return count;
00878 v++;
00879 count++;
00880 }
00881 return count;
00882 }
00883
00884 static void eof_dcc_chat(int idx)
00885 {
00886 putlog(LOG_MISC, "*", DCC_LOSTDCC, dcc[idx].nick,
00887 dcc[idx].host, dcc[idx].port);
00888 if (dcc[idx].u.chat->channel >= 0) {
00889 chanout_but(idx, dcc[idx].u.chat->channel, "*** %s lost dcc link.\n",
00890 dcc[idx].nick);
00891 if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
00892 botnet_send_part_idx(idx, "lost dcc link");
00893 check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
00894 dcc[idx].u.chat->channel);
00895 }
00896 check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
00897 killsock(dcc[idx].sock);
00898 lostdcc(idx);
00899 }
00900
00901 static void dcc_chat(int idx, char *buf, int i)
00902 {
00903 int nathan = 0, doron = 0, fixed = 0;
00904 char *v, *d, filtbuf[2048];
00905
00906 if (dcc[idx].status & STAT_TELNET)
00907 strip_telnet(dcc[idx].sock, buf, &i);
00908 if (buf[0] && (buf[0] != '.') &&
00909 detect_dcc_flood(&dcc[idx].timeval, dcc[idx].u.chat, idx))
00910 return;
00911 dcc[idx].timeval = now;
00912 if (buf[0]) {
00913 const char *filt = check_tcl_filt(idx, buf);
00914 if (filt != buf) {
00915 strncpyz(filtbuf, filt, sizeof(filtbuf));
00916 buf = filtbuf;
00917 }
00918 }
00919 if (buf[0]) {
00920
00921 v = buf;
00922 d = buf;
00923 while (*v)
00924 switch (*v) {
00925 case 7:
00926 nathan++;
00927 if (nathan > 3)
00928 v++;
00929 else
00930 *d++ = *v++;
00931 break;
00932 case 8:
00933 if (d > buf) {
00934 d--;
00935 }
00936 v++;
00937 break;
00938 case 27:
00939 doron = check_ansi(v);
00940
00941 if (!doron) {
00942 *d++ = *v++;
00943 fixed = 1;
00944 } else
00945 v += doron;
00946 break;
00947 case '\r':
00948 v++;
00949 break;
00950 default:
00951 *d++ = *v++;
00952 }
00953 if (fixed)
00954 strcpy(d, "\033[0m");
00955 else
00956 *d = 0;
00957 if (buf[0]) {
00958 if ((buf[0] == '.') || (dcc[idx].u.chat->channel < 0)) {
00959 if (buf[0] == '.')
00960 buf++;
00961 v = newsplit(&buf);
00962 rmspace(buf);
00963 if (check_tcl_dcc(v, idx, buf)) {
00964 if (dcc[idx].u.chat->channel >= 0)
00965 check_tcl_chpt(botnetnick, dcc[idx].nick, dcc[idx].sock,
00966 dcc[idx].u.chat->channel);
00967 check_tcl_chof(dcc[idx].nick, dcc[idx].sock);
00968 dprintf(idx, "*** Ja mata!\n");
00969 flush_lines(idx, dcc[idx].u.chat);
00970 putlog(LOG_MISC, "*", DCC_CLOSED, dcc[idx].nick, dcc[idx].host);
00971 if (dcc[idx].u.chat->channel >= 0) {
00972 chanout_but(-1, dcc[idx].u.chat->channel,
00973 "*** %s left the party line%s%s\n",
00974 dcc[idx].nick, buf[0] ? ": " : ".", buf);
00975 if (dcc[idx].u.chat->channel < GLOBAL_CHANS)
00976 botnet_send_part_idx(idx, buf);
00977 }
00978 if (dcc[idx].u.chat->su_nick) {
00979 dcc[idx].user = get_user_by_handle(userlist,
00980 dcc[idx].u.chat->su_nick);
00981 strcpy(dcc[idx].nick, dcc[idx].u.chat->su_nick);
00982 dcc[idx].type = &DCC_CHAT;
00983 dprintf(idx, "Returning to real nick %s!\n",
00984 dcc[idx].u.chat->su_nick);
00985 nfree(dcc[idx].u.chat->su_nick);
00986 dcc[idx].u.chat->su_nick = NULL;
00987 dcc_chatter(idx);
00988 if (dcc[idx].u.chat->channel < GLOBAL_CHANS &&
00989 dcc[idx].u.chat->channel >= 0)
00990 botnet_send_join_idx(idx, -1);
00991 return;
00992 } else if ((dcc[idx].sock != STDOUT) || backgrd) {
00993 killsock(dcc[idx].sock);
00994 lostdcc(idx);
00995 return;
00996 } else {
00997 dprintf(DP_STDOUT, "\n### SIMULATION RESET\n\n");
00998 dcc_chatter(idx);
00999 return;
01000 }
01001 }
01002 } else if (buf[0] == ',') {
01003 int me = 0;
01004
01005 if ((buf[1] == 'm') && (buf[2] == 'e') && buf[3] == ' ')
01006 me = 1;
01007 for (i = 0; i < dcc_total; i++) {
01008 int ok = 0;
01009
01010 if ((dcc[i].type->flags & DCT_MASTER) &&
01011 ((dcc[i].type != &DCC_CHAT) || (dcc[i].u.chat->channel >= 0)) &&
01012 ((i != idx) || (dcc[idx].status & STAT_ECHO)))
01013 ok = 1;
01014 if (ok) {
01015 struct userrec *u = get_user_by_handle(userlist, dcc[i].nick);
01016
01017 if (u && (u->flags & USER_MASTER)) {
01018 if (me)
01019 dprintf(i, "-> %s%s\n", dcc[idx].nick, buf + 3);
01020 else
01021 dprintf(i, "-%s-> %s\n", dcc[idx].nick, buf + 1);
01022 }
01023 }
01024 }
01025 } else if (buf[0] == '\'') {
01026 int me = 0;
01027
01028 if ((buf[1] == 'm') && (buf[2] == 'e') &&
01029 ((buf[3] == ' ') || (buf[3] == '\'') || (buf[3] == ',')))
01030 me = 1;
01031 for (i = 0; i < dcc_total; i++) {
01032 if (dcc[i].type->flags & DCT_CHAT) {
01033 if (me)
01034 dprintf(i, "=> %s%s\n", dcc[idx].nick, buf + 3);
01035 else
01036 dprintf(i, "=%s=> %s\n", dcc[idx].nick, buf + 1);
01037 }
01038 }
01039 } else {
01040 if (dcc[idx].u.chat->away != NULL)
01041 not_away(idx);
01042 if (dcc[idx].status & STAT_ECHO)
01043 chanout_but(-1, dcc[idx].u.chat->channel,
01044 "<%s> %s\n", dcc[idx].nick, buf);
01045 else
01046 chanout_but(idx, dcc[idx].u.chat->channel, "<%s> %s\n",
01047 dcc[idx].nick, buf);
01048 botnet_send_chan(-1, botnetnick, dcc[idx].nick,
01049 dcc[idx].u.chat->channel, buf);
01050 check_tcl_chat(dcc[idx].nick, dcc[idx].u.chat->channel, buf);
01051 }
01052 }
01053 }
01054 if (dcc[idx].type == &DCC_CHAT)
01055 if (dcc[idx].status & STAT_PAGE)
01056 flush_lines(idx, dcc[idx].u.chat);
01057 }
01058
01059 static void display_dcc_chat(int idx, char *buf)
01060 {
01061 int i = simple_sprintf(buf, "chat flags: ");
01062
01063 buf[i++] = dcc[idx].status & STAT_CHAT ? 'C' : 'c';
01064 buf[i++] = dcc[idx].status & STAT_PARTY ? 'P' : 'p';
01065 buf[i++] = dcc[idx].status & STAT_TELNET ? 'T' : 't';
01066 buf[i++] = dcc[idx].status & STAT_ECHO ? 'E' : 'e';
01067 buf[i++] = dcc[idx].status & STAT_PAGE ? 'P' : 'p';
01068 simple_sprintf(buf + i, "/%d", dcc[idx].u.chat->channel);
01069 }
01070
01071 struct dcc_table DCC_CHAT = {
01072 "CHAT",
01073 DCT_CHAT | DCT_MASTER | DCT_SHOWWHO | DCT_VALIDIDX | DCT_SIMUL |
01074 DCT_CANBOOT | DCT_REMOTEWHO,
01075 eof_dcc_chat,
01076 dcc_chat,
01077 NULL,
01078 NULL,
01079 display_dcc_chat,
01080 expmem_dcc_general,
01081 kill_dcc_general,
01082 out_dcc_general
01083 };
01084
01085 static int lasttelnets;
01086 static char lasttelnethost[81];
01087 static time_t lasttelnettime;
01088
01089
01090
01091 static int detect_telnet_flood(char *floodhost)
01092 {
01093 struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
01094
01095 get_user_flagrec(get_user_by_host(floodhost), &fr, NULL);
01096 if (!flood_telnet_thr || (glob_friend(fr) && !par_telnet_flood))
01097 return 0;
01098 if (egg_strcasecmp(lasttelnethost, floodhost)) {
01099 strcpy(lasttelnethost, floodhost);
01100 lasttelnettime = now;
01101 lasttelnets = 0;
01102 return 0;
01103 }
01104 if (lasttelnettime < now - flood_telnet_time) {
01105
01106 lasttelnettime = now;
01107 lasttelnets = 0;
01108 return 0;
01109 }
01110 lasttelnets++;
01111 if (lasttelnets >= flood_telnet_thr) {
01112
01113 lasttelnets = 0;
01114 lasttelnettime = 0;
01115 lasttelnethost[0] = 0;
01116 putlog(LOG_MISC, "*", IRC_TELNETFLOOD, floodhost);
01117 addignore(floodhost, origbotname, "Telnet connection flood",
01118 now + (60 * ignore_time));
01119 return 1;
01120 }
01121 return 0;
01122 }
01123
01124 static void dcc_telnet(int idx, char *buf, int i)
01125 {
01126 unsigned long ip;
01127 unsigned short port;
01128 int j = 0, sock;
01129 char s[UHOSTLEN + 1];
01130
01131 if (dcc_total + 1 > max_dcc && increase_socks_max()) {
01132 j = answer(dcc[idx].sock, s, &ip, &port, 0);
01133 if (j != -1) {
01134 dprintf(-j, "Sorry, too many connections already.\r\n");
01135 killsock(j);
01136 }
01137 return;
01138 }
01139 sock = answer(dcc[idx].sock, s, &ip, &port, 0);
01140 while ((sock == -1) && (errno == EAGAIN))
01141 sock = answer(sock, s, &ip, &port, 0);
01142 if (sock < 0) {
01143 neterror(s);
01144 putlog(LOG_MISC, "*", DCC_FAILED, s);
01145 return;
01146 }
01147
01148 sockoptions(sock, EGG_OPTION_SET, SOCK_BUFFER);
01149
01150 #if (SIZEOF_SHORT == 2)
01151 if (port < 1024) {
01152 #else
01153 if (port < 1024 || port > 65535) {
01154 #endif
01155 putlog(LOG_BOTS, "*", DCC_BADSRC, s, port);
01156 killsock(sock);
01157 return;
01158 }
01159
01160 i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
01161 dcc[i].sock = sock;
01162 dcc[i].addr = ip;
01163 dcc[i].port = port;
01164 dcc[i].timeval = now;
01165 strcpy(dcc[i].nick, "*");
01166 dcc[i].u.dns->ip = ip;
01167 dcc[i].u.dns->dns_success = dcc_telnet_hostresolved;
01168 dcc[i].u.dns->dns_failure = dcc_telnet_hostresolved;
01169 dcc[i].u.dns->dns_type = RES_HOSTBYIP;
01170 dcc[i].u.dns->ibuf = dcc[idx].sock;
01171 dcc[i].u.dns->type = &DCC_IDENTWAIT;
01172 dcc_dnshostbyip(ip);
01173 }
01174
01175 static void dcc_telnet_hostresolved(int i)
01176 {
01177 int idx;
01178 int j = 0, sock;
01179 char s[UHOSTLEN], s2[UHOSTLEN + 20];
01180
01181 strncpyz(dcc[i].host, dcc[i].u.dns->host, UHOSTLEN);
01182
01183 for (idx = 0; idx < dcc_total; idx++)
01184 if ((dcc[idx].type == &DCC_TELNET) &&
01185 (dcc[idx].sock == dcc[i].u.dns->ibuf)) {
01186 break;
01187 }
01188 if (dcc_total == idx) {
01189 putlog(LOG_BOTS, "*", "Lost listening socket while resolving %s",
01190 dcc[i].host);
01191 killsock(dcc[i].sock);
01192 lostdcc(i);
01193 return;
01194 }
01195 if (dcc[idx].host[0] == '@') {
01196
01197 if (!wild_match(dcc[idx].host + 1, dcc[i].host)) {
01198 putlog(LOG_BOTS, "*", DCC_BADHOST, dcc[i].host);
01199 killsock(dcc[i].sock);
01200 lostdcc(i);
01201 return;
01202 }
01203 }
01204 sprintf(s2, "-telnet!telnet@%s", dcc[i].host);
01205 if (match_ignore(s2) || detect_telnet_flood(s2)) {
01206 killsock(dcc[i].sock);
01207 lostdcc(i);
01208 return;
01209 }
01210
01211 changeover_dcc(i, &DCC_IDENTWAIT, 0);
01212 dcc[i].timeval = now;
01213 dcc[i].u.ident_sock = dcc[idx].sock;
01214 sock = open_telnet(iptostr(htonl(dcc[i].addr)), 113);
01215 putlog(LOG_MISC, "*", DCC_TELCONN, dcc[i].host, dcc[i].port);
01216 s[0] = 0;
01217 if (sock < 0) {
01218 if (sock == -2)
01219 strcpy(s, "DNS lookup failed for ident");
01220 else
01221 neterror(s);
01222 } else {
01223 j = new_dcc(&DCC_IDENT, 0);
01224 if (j < 0) {
01225 killsock(sock);
01226 strcpy(s, "No Free DCC's");
01227 }
01228 }
01229 if (s[0]) {
01230 putlog(LOG_MISC, "*", DCC_IDENTFAIL, dcc[i].host, s);
01231 sprintf(s, "telnet@%s", dcc[i].host);
01232 dcc_telnet_got_ident(i, s);
01233 return;
01234 }
01235 dcc[j].sock = sock;
01236 dcc[j].port = 113;
01237 dcc[j].addr = dcc[i].addr;
01238 strcpy(dcc[j].host, dcc[i].host);
01239 strcpy(dcc[j].nick, "*");
01240 dcc[j].u.ident_sock = dcc[i].sock;
01241 dcc[j].timeval = now;
01242 dprintf(j, "%d, %d\n", dcc[i].port, dcc[idx].port);
01243 }
01244
01245 static void eof_dcc_telnet(int idx)
01246 {
01247 putlog(LOG_MISC, "*", DCC_PORTDIE, dcc[idx].port);
01248 killsock(dcc[idx].sock);
01249 lostdcc(idx);
01250 }
01251
01252 static void display_telnet(int idx, char *buf)
01253 {
01254 sprintf(buf, "lstn %d%s", dcc[idx].port,
01255 (dcc[idx].status & LSTN_PUBLIC) ? " pub" : "");
01256 }
01257
01258 struct dcc_table DCC_TELNET = {
01259 "TELNET",
01260 DCT_LISTEN,
01261 eof_dcc_telnet,
01262 dcc_telnet,
01263 NULL,
01264 NULL,
01265 display_telnet,
01266 NULL,
01267 NULL,
01268 NULL
01269 };
01270
01271 static void eof_dcc_dupwait(int idx)
01272 {
01273 putlog(LOG_BOTS, "*", DCC_LOSTDUP, dcc[idx].host);
01274 killsock(dcc[idx].sock);
01275 lostdcc(idx);
01276 }
01277
01278 static void dcc_dupwait(int idx, char *buf, int i)
01279 {
01280
01281 return;
01282 }
01283
01284
01285
01286
01287 static void timeout_dupwait(int idx)
01288 {
01289 char x[100];
01290
01291
01292 if (in_chain(dcc[idx].nick)) {
01293 egg_snprintf(x, sizeof x, "%s!%s", dcc[idx].nick, dcc[idx].host);
01294 dprintf(idx, "error Already connected.\n");
01295 putlog(LOG_BOTS, "*", DCC_DUPLICATE, x);
01296 killsock(dcc[idx].sock);
01297 lostdcc(idx);
01298 } else {
01299
01300 dcc_telnet_pass(idx, dcc[idx].u.dupwait->atr);
01301 }
01302 }
01303
01304 static void display_dupwait(int idx, char *buf)
01305 {
01306 sprintf(buf, "wait duplicate?");
01307 }
01308
01309 static int expmem_dupwait(void *x)
01310 {
01311 register struct dupwait_info *p = (struct dupwait_info *) x;
01312 int tot = sizeof(struct dupwait_info);
01313
01314 if (p && p->chat && DCC_CHAT.expmem)
01315 tot += DCC_CHAT.expmem(p->chat);
01316 return tot;
01317 }
01318
01319 static void kill_dupwait(int idx, void *x)
01320 {
01321 register struct dupwait_info *p = (struct dupwait_info *) x;
01322
01323 if (p) {
01324 if (p->chat && DCC_CHAT.kill)
01325 DCC_CHAT.kill(idx, p->chat);
01326 nfree(p);
01327 }
01328 }
01329
01330 struct dcc_table DCC_DUPWAIT = {
01331 "DUPWAIT",
01332 DCT_VALIDIDX,
01333 eof_dcc_dupwait,
01334 dcc_dupwait,
01335 &dupwait_timeout,
01336 timeout_dupwait,
01337 display_dupwait,
01338 expmem_dupwait,
01339 kill_dupwait,
01340 NULL
01341 };
01342
01343
01344
01345
01346
01347 void dupwait_notify(char *who)
01348 {
01349 register int idx;
01350
01351 Assert(who);
01352 for (idx = 0; idx < dcc_total; idx++)
01353 if ((dcc[idx].type == &DCC_DUPWAIT) &&
01354 !egg_strcasecmp(dcc[idx].nick, who)) {
01355 dcc_telnet_pass(idx, dcc[idx].u.dupwait->atr);
01356 break;
01357 }
01358 }
01359
01360 static void dcc_telnet_id(int idx, char *buf, int atr)
01361 {
01362 int ok = 0;
01363 struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
01364
01365 if (detect_telnet((unsigned char *) buf)) {
01366 dcc[idx].status |= STAT_TELNET;
01367 strip_telnet(dcc[idx].sock, buf, &atr);
01368 } else
01369 dcc[idx].status &= ~STAT_TELNET;
01370 buf[HANDLEN] = 0;
01371
01372 if (dcc[idx].nick[0] != '@' && !wild_match(dcc[idx].nick, buf)) {
01373 dprintf(idx, "Sorry, that nickname format is invalid.\n");
01374 putlog(LOG_BOTS, "*", DCC_BADNICK, dcc[idx].host);
01375 killsock(dcc[idx].sock);
01376 lostdcc(idx);
01377 return;
01378 }
01379 dcc[idx].user = get_user_by_handle(userlist, buf);
01380 get_user_flagrec(dcc[idx].user, &fr, NULL);
01381
01382 if ((dcc[idx].status & STAT_BOTONLY) && !glob_bot(fr)) {
01383 dprintf(idx, "This telnet port is for bots only.\n");
01384 putlog(LOG_BOTS, "*", DCC_NONBOT, dcc[idx].host);
01385 killsock(dcc[idx].sock);
01386 lostdcc(idx);
01387 return;
01388 }
01389 if ((dcc[idx].status & STAT_USRONLY) && glob_bot(fr)) {
01390 dprintf(idx, "error Only users may connect at this port.\n");
01391 putlog(LOG_BOTS, "*", DCC_NONUSER, dcc[idx].host);
01392 killsock(dcc[idx].sock);
01393 lostdcc(idx);
01394 return;
01395 }
01396 dcc[idx].status &= ~(STAT_BOTONLY | STAT_USRONLY);
01397 if (!egg_strcasecmp(buf, "NEW") && (allow_new_telnets || make_userfile)) {
01398 dcc[idx].type = &DCC_TELNET_NEW;
01399 dcc[idx].timeval = now;
01400 dprintf(idx, "\n");
01401 dprintf(idx, IRC_TELNET, botnetnick);
01402 dprintf(idx, IRC_TELNET1);
01403 dprintf(idx, "\nEnter the nickname you would like to use.\n");
01404 return;
01405 }
01406 if (chan_op(fr)) {
01407 if (!require_p)
01408 ok = 1;
01409 }
01410 if (!ok && (glob_party(fr) || glob_bot(fr)))
01411 ok = 1;
01412
01413 if (!ok) {
01414 dprintf(idx, "You don't have access.\n");
01415 putlog(LOG_BOTS, "*", DCC_INVHANDLE, dcc[idx].host, buf);
01416 killsock(dcc[idx].sock);
01417 lostdcc(idx);
01418 return;
01419 }
01420 correct_handle(buf);
01421 strcpy(dcc[idx].nick, buf);
01422 if (glob_bot(fr)) {
01423 if (!egg_strcasecmp(botnetnick, dcc[idx].nick)) {
01424 dprintf(idx, "error You cannot link using my botnetnick.\n");
01425 putlog(LOG_BOTS, "*", DCC_MYBOTNETNICK, dcc[idx].host);
01426 killsock(dcc[idx].sock);
01427 lostdcc(idx);
01428 return;
01429 } else if (in_chain(dcc[idx].nick)) {
01430 struct chat_info *ci;
01431
01432 ci = dcc[idx].u.chat;
01433 dcc[idx].type = &DCC_DUPWAIT;
01434 dcc[idx].u.dupwait = get_data_ptr(sizeof(struct dupwait_info));
01435 dcc[idx].u.dupwait->chat = ci;
01436 dcc[idx].u.dupwait->atr = atr;
01437 return;
01438 }
01439 }
01440 dcc_telnet_pass(idx, atr);
01441 }
01442
01443 static void dcc_telnet_pass(int idx, int atr)
01444 {
01445 int ok = 0;
01446 struct flag_record fr = { FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0 };
01447
01448 get_user_flagrec(dcc[idx].user, &fr, NULL);
01449
01450 if (u_pass_match(dcc[idx].user, "-")) {
01451 if (glob_bot(fr)) {
01452 char ps[20];
01453
01454 makepass(ps);
01455 set_user(&USERENTRY_PASS, dcc[idx].user, ps);
01456 changeover_dcc(idx, &DCC_BOT_NEW, sizeof(struct bot_info));
01457
01458 dcc[idx].status = STAT_CALLED;
01459 dprintf(idx, "*hello!\n");
01460 greet_new_bot(idx);
01461 #ifdef NO_OLD_BOTNET
01462 dprintf(idx, "h %s\n", ps);
01463 #else
01464 dprintf(idx, "handshake %s\n", ps);
01465 #endif
01466 return;
01467 }
01468 dprintf(idx, "Can't telnet until you have a password set.\n");
01469 putlog(LOG_MISC, "*", DCC_NOPASS, dcc[idx].nick, dcc[idx].host);
01470 killsock(dcc[idx].sock);
01471 lostdcc(idx);
01472 return;
01473 }
01474 ok = 0;
01475 if (dcc[idx].type == &DCC_DUPWAIT) {
01476 struct chat_info *ci;
01477
01478 ci = dcc[idx].u.dupwait->chat;
01479 nfree(dcc[idx].u.dupwait);
01480 dcc[idx].u.chat = ci;
01481 }
01482 dcc[idx].type = &DCC_CHAT_PASS;
01483 dcc[idx].timeval = now;
01484 if (glob_botmast(fr))
01485 ok = 1;
01486 else if (chan_op(fr)) {
01487 if (!require_p)
01488 ok = 1;
01489 else if (glob_party(fr))
01490 ok = 1;
01491 } else if (glob_party(fr)) {
01492 ok = 1;
01493 dcc[idx].status |= STAT_PARTY;
01494 }
01495 if (glob_bot(fr))
01496 ok = 1;
01497 if (!ok) {
01498 struct chat_info *ci;
01499
01500 ci = dcc[idx].u.chat;
01501 dcc[idx].u.file = get_data_ptr(sizeof(struct file_info));
01502 dcc[idx].u.file->chat = ci;
01503 }
01504
01505 if (glob_bot(fr)) {
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516 putlog(LOG_BOTS, "*", "Challenging %s...", dcc[idx].nick);
01517 dprintf(idx, "passreq <%x%x@%s>\n", getpid(), dcc[idx].timeval, botnetnick);
01518 } else {
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528 if (dcc[idx].status & STAT_TELNET) {
01529 char buf[1030];
01530 snprintf(buf, sizeof buf, "\n%s%s\r\n", escape_telnet(DCC_ENTERPASS),
01531 TLN_IAC_C TLN_WILL_C TLN_ECHO_C);
01532 tputs(dcc[idx].sock, buf, strlen(buf));
01533 } else
01534 dprintf(idx, "\n%s\n", DCC_ENTERPASS);
01535 }
01536 }
01537
01538 static void eof_dcc_telnet_id(int idx)
01539 {
01540 putlog(LOG_MISC, "*", DCC_LOSTCON, dcc[idx].host, dcc[idx].port);
01541 killsock(dcc[idx].sock);
01542 lostdcc(idx);
01543 }
01544
01545 static void timeout_dcc_telnet_id(int idx)
01546 {
01547 dprintf(idx, "Timeout.\n");
01548 putlog(LOG_MISC, "*", DCC_TTIMEOUT, dcc[idx].host);
01549 killsock(dcc[idx].sock);
01550 lostdcc(idx);
01551 }
01552
01553 static void display_dcc_telnet_id(int idx, char *buf)
01554 {
01555 long tv;
01556
01557 tv = now - dcc[idx].timeval;
01558 sprintf(buf, "t-in waited %lis", tv);
01559 }
01560
01561 struct dcc_table DCC_TELNET_ID = {
01562 "TELNET_ID",
01563 0,
01564 eof_dcc_telnet_id,
01565 dcc_telnet_id,
01566 &password_timeout,
01567 timeout_dcc_telnet_id,
01568 display_dcc_telnet_id,
01569 expmem_dcc_general,
01570 kill_dcc_general,
01571 out_dcc_general
01572 };
01573
01574 static void dcc_telnet_new(int idx, char *buf, int x)
01575 {
01576 int ok = 1;
01577 char work[1024], *p, *q, *r;
01578
01579 buf[HANDLEN] = 0;
01580 if (dcc[idx].status & STAT_TELNET)
01581 strip_telnet(dcc[idx].sock, buf, &x);
01582 dcc[idx].timeval = now;
01583 for (x = 0; x < strlen(buf); x++)
01584 if (buf[x] <= 32)
01585 ok = 0;
01586 if (!ok) {
01587 dprintf(idx, "\nYou can't use weird symbols in your nick.\n");
01588 dprintf(idx, "Try another one please:\n");
01589 } else if (strchr(BADHANDCHARS, buf[0]) != NULL) {
01590 dprintf(idx, "\nYou can't start your nick with the character '%c'\n",
01591 buf[0]);
01592 dprintf(idx, "Try another one please:\n");
01593 } else if (get_user_by_handle(userlist, buf)) {
01594 dprintf(idx, "\nSorry, that nickname is taken already.\n");
01595 dprintf(idx, "Try another one please:\n");
01596 return;
01597 } else if (!egg_strcasecmp(buf, botnetnick))
01598 dprintf(idx, "Sorry, can't use my name for a nick.\n");
01599 else {
01600 strcpy(dcc[idx].nick, buf);
01601 if (make_userfile)
01602 userlist = adduser(userlist,
01603 buf, "-telnet!*@*", "-", sanity_check(default_flags |
01604 USER_PARTY | USER_MASTER | USER_OWNER));
01605 else {
01606 p = strchr(dcc[idx].host, '@');
01607 if (p) {
01608 q = p;
01609 *q = 0;
01610 p++;
01611 r = strchr(p, '.');
01612 if (!r)
01613 simple_sprintf(work, "-telnet!%s@%s", dcc[idx].host, p);
01614 else
01615 simple_sprintf(work, "-telnet!%s@*%s", dcc[idx].host, r);
01616 *q = '@';
01617 } else
01618 simple_sprintf(work, "-telnet!*@*%s", dcc[idx].host);
01619 userlist = adduser(userlist, buf, work, "-",
01620 sanity_check(USER_PARTY | default_flags));
01621 }
01622 reaffirm_owners();
01623 dcc[idx].status = STAT_ECHO | STAT_TELNET;
01624 dcc[idx].type = &DCC_CHAT;
01625 dcc[idx].user = get_user_by_handle(userlist, buf);
01626 check_dcc_attrs(dcc[idx].user, USER_PARTY | default_flags);
01627 dcc[idx].type = &DCC_TELNET_PW;
01628 if (make_userfile) {
01629 dprintf(idx, "\nYOU ARE THE MASTER/OWNER ON THIS BOT NOW\n");
01630 dprintf(idx, IRC_LIMBO);
01631 putlog(LOG_MISC, "*", DCC_INSTCOMPL, buf);
01632 make_userfile = 0;
01633 write_userfile(-1);
01634 add_note(buf, botnetnick, "Welcome to eggdrop! :)", -1, 0);
01635 }
01636 dprintf(idx, "\nOkay, now choose and enter a password:\n");
01637 dprintf(idx, "(Only the first 15 letters are significant.)\n");
01638 }
01639 }
01640
01641 static void dcc_telnet_pw(int idx, char *buf, int x)
01642 {
01643 char *newpass;
01644 int ok;
01645
01646 if (dcc[idx].status & STAT_TELNET)
01647 strip_telnet(dcc[idx].sock, buf, &x);
01648 buf[16] = 0;
01649 ok = 1;
01650 if (strlen(buf) < 4) {
01651 dprintf(idx, "\nTry to use at least 4 characters in your password.\n");
01652 dprintf(idx, "Choose and enter a password:\n");
01653 return;
01654 }
01655 for (x = 0; x < strlen(buf); x++)
01656 if ((buf[x] <= 32) || (buf[x] == 127))
01657 ok = 0;
01658 if (!ok) {
01659 dprintf(idx, "\nYou can't use weird symbols in your password.\n");
01660 dprintf(idx, "Try another one please:\n");
01661 return;
01662 }
01663 putlog(LOG_MISC, "*", DCC_NEWUSER, dcc[idx].nick, dcc[idx].host,
01664 dcc[idx].port);
01665 if (notify_new[0]) {
01666 char s[121], s1[121], s2[121];
01667
01668 sprintf(s, "Introduced to %s, %s", dcc[idx].nick, dcc[idx].host);
01669 strcpy(s1, notify_new);
01670 splitc(s2, s1, ',');
01671 while (s2[0]) {
01672 rmspace(s2);
01673 add_note(s2, botnetnick, s, -1, 0);
01674 splitc(s2, s1, ',');
01675 }
01676 rmspace(s1);
01677 add_note(s1, botnetnick, s, -1, 0);
01678 }
01679 newpass = newsplit(&buf);
01680 set_user(&USERENTRY_PASS, dcc[idx].user, newpass);
01681 dprintf(idx, "\nRemember that! You'll need it next time you log in.\n");
01682 dprintf(idx, "You now have an account on %s...\n\n\n", botnetnick);
01683 dcc[idx].type = &DCC_CHAT;
01684 dcc[idx].u.chat->channel = -2;
01685 dcc_chatter(idx);
01686 }
01687
01688 static void eof_dcc_telnet_new(int idx)
01689 {
01690 putlog(LOG_MISC, "*", DCC_LOSTNEWUSER, dcc[idx].host, dcc[idx].port);
01691 killsock(dcc[idx].sock);
01692 lostdcc(idx);
01693 }
01694
01695 static void eof_dcc_telnet_pw(int idx)
01696 {
01697 putlog(LOG_MISC, "*", DCC_LOSTNEWUSR2, dcc[idx].nick, dcc[idx].host,
01698 dcc[idx].port);
01699 deluser(dcc[idx].nick);
01700 killsock(dcc[idx].sock);
01701 lostdcc(idx);
01702 }
01703
01704 static void tout_dcc_telnet_new(int idx)
01705 {
01706 dprintf(idx, "Guess you're not there. Bye.\n");
01707 putlog(LOG_MISC, "*", DCC_TIMEOUTUSER, dcc[idx].host, dcc[idx].port);
01708 killsock(dcc[idx].sock);
01709 lostdcc(idx);
01710 }
01711
01712 static void tout_dcc_telnet_pw(int idx)
01713 {
01714 dprintf(idx, "Guess you're not there. Bye.\n");
01715 putlog(LOG_MISC, "*", DCC_TIMEOUTUSR2, dcc[idx].nick,
01716 dcc[idx].host, dcc[idx].port);
01717 killsock(dcc[idx].sock);
01718 lostdcc(idx);
01719 }
01720
01721 static void display_dcc_telnet_new(int idx, char *buf)
01722 {
01723 long tv;
01724
01725 tv = now - dcc[idx].timeval;
01726 sprintf(buf, "new waited %lis", tv);
01727 }
01728
01729 static void display_dcc_telnet_pw(int idx, char *buf)
01730 {
01731 long tv;
01732
01733 tv = now - dcc[idx].timeval;
01734 sprintf(buf, "newp waited %lis", tv);
01735 }
01736
01737 struct dcc_table DCC_TELNET_NEW = {
01738 "TELNET_NEW",
01739 0,
01740 eof_dcc_telnet_new,
01741 dcc_telnet_new,
01742 &password_timeout,
01743 tout_dcc_telnet_new,
01744 display_dcc_telnet_new,
01745 expmem_dcc_general,
01746 kill_dcc_general,
01747 out_dcc_general
01748 };
01749
01750 struct dcc_table DCC_TELNET_PW = {
01751 "TELNET_PW",
01752 0,
01753 eof_dcc_telnet_pw,
01754 dcc_telnet_pw,
01755 &password_timeout,
01756 tout_dcc_telnet_pw,
01757 display_dcc_telnet_pw,
01758 expmem_dcc_general,
01759 kill_dcc_general,
01760 out_dcc_general
01761 };
01762
01763 static int call_tcl_func(char *name, int idx, char *args)
01764 {
01765 char s[11];
01766
01767 sprintf(s, "%d", idx);
01768 Tcl_SetVar(interp, "_n", s, 0);
01769 Tcl_SetVar(interp, "_a", args, 0);
01770 if (Tcl_VarEval(interp, name, " $_n $_a", NULL) == TCL_ERROR) {
01771 putlog(LOG_MISC, "*", DCC_TCLERROR, name, tcl_resultstring());
01772 return -1;
01773 }
01774 return tcl_resultint();
01775 }
01776
01777 static void dcc_script(int idx, char *buf, int len)
01778 {
01779 long oldsock;
01780
01781 if (dcc[idx].status & STAT_TELNET)
01782 strip_telnet(dcc[idx].sock, buf, &len);
01783 if (!len)
01784 return;
01785
01786 dcc[idx].timeval = now;
01787 oldsock = dcc[idx].sock;
01788 if (call_tcl_func(dcc[idx].u.script->command, dcc[idx].sock, buf)) {
01789 void *old_other = NULL;
01790
01791
01792
01793 if (dcc[idx].sock != oldsock || idx > max_dcc)
01794 return;
01795
01796 old_other = dcc[idx].u.script->u.other;
01797 dcc[idx].type = dcc[idx].u.script->type;
01798 nfree(dcc[idx].u.script);
01799 dcc[idx].u.other = old_other;
01800 if (dcc[idx].type == &DCC_SOCKET) {
01801
01802 killsock(dcc[idx].sock);
01803 lostdcc(idx);
01804 return;
01805 }
01806 if (dcc[idx].type == &DCC_CHAT) {
01807 if (dcc[idx].u.chat->channel >= 0) {
01808 chanout_but(-1, dcc[idx].u.chat->channel, DCC_JOIN, dcc[idx].nick);
01809 if (dcc[idx].u.chat->channel < 10000)
01810 botnet_send_join_idx(idx, -1);
01811 check_tcl_chjn(botnetnick, dcc[idx].nick, dcc[idx].u.chat->channel,
01812 geticon(idx), dcc[idx].sock, dcc[idx].host);
01813 }
01814 check_tcl_chon(dcc[idx].nick, dcc[idx].sock);
01815 }
01816 }
01817 }
01818
01819 static void eof_dcc_script(int idx)
01820 {
01821 void *old;
01822 int oldflags;
01823
01824
01825
01826
01827 oldflags = dcc[idx].type->flags;
01828 dcc[idx].type->flags &= ~(DCT_VALIDIDX);
01829
01830 call_tcl_func(dcc[idx].u.script->command, dcc[idx].sock, "");
01831
01832 dcc[idx].type->flags = oldflags;
01833 old = dcc[idx].u.script->u.other;
01834 dcc[idx].type = dcc[idx].u.script->type;
01835 nfree(dcc[idx].u.script);
01836 dcc[idx].u.other = old;
01837
01838 if (dcc[idx].type && dcc[idx].type->eof)
01839 dcc[idx].type->eof(idx);
01840 else {
01841 putlog(LOG_MISC, "*", DCC_DEADSOCKET, dcc[idx].sock, dcc[idx].type->name);
01842 killsock(dcc[idx].sock);
01843 lostdcc(idx);
01844 }
01845 }
01846
01847 static void display_dcc_script(int idx, char *buf)
01848 {
01849 sprintf(buf, "scri %s", dcc[idx].u.script->command);
01850 }
01851
01852 static int expmem_dcc_script(void *x)
01853 {
01854 register struct script_info *p = (struct script_info *) x;
01855 int tot = sizeof(struct script_info);
01856
01857 if (p->type && p->u.other)
01858 tot += p->type->expmem(p->u.other);
01859 return tot;
01860 }
01861
01862 static void kill_dcc_script(int idx, void *x)
01863 {
01864 register struct script_info *p = (struct script_info *) x;
01865
01866 if (p->type && p->u.other)
01867 p->type->kill(idx, p->u.other);
01868 nfree(p);
01869 }
01870
01871 static void out_dcc_script(int idx, char *buf, void *x)
01872 {
01873 register struct script_info *p = (struct script_info *) x;
01874
01875 if (p && p->type && p->u.other)
01876 p->type->output(idx, buf, p->u.other);
01877 else
01878 tputs(dcc[idx].sock, buf, strlen(buf));
01879 }
01880
01881 struct dcc_table DCC_SCRIPT = {
01882 "SCRIPT",
01883 DCT_VALIDIDX,
01884 eof_dcc_script,
01885 dcc_script,
01886 NULL,
01887 NULL,
01888 display_dcc_script,
01889 expmem_dcc_script,
01890 kill_dcc_script,
01891 out_dcc_script
01892 };
01893
01894 static void dcc_socket(int idx, char *buf, int len)
01895 {
01896 }
01897
01898 static void eof_dcc_socket(int idx)
01899 {
01900 killsock(dcc[idx].sock);
01901 lostdcc(idx);
01902 }
01903
01904 static void display_dcc_socket(int idx, char *buf)
01905 {
01906 strcpy(buf, "sock (stranded)");
01907 }
01908
01909 struct dcc_table DCC_SOCKET = {
01910 "SOCKET",
01911 DCT_VALIDIDX,
01912 eof_dcc_socket,
01913 dcc_socket,
01914 NULL,
01915 NULL,
01916 display_dcc_socket,
01917 NULL,
01918 NULL,
01919 NULL
01920 };
01921
01922 static void display_dcc_lost(int idx, char *buf)
01923 {
01924 strcpy(buf, "lost");
01925 }
01926
01927 struct dcc_table DCC_LOST = {
01928 "LOST",
01929 0,
01930 NULL,
01931 dcc_socket,
01932 NULL,
01933 NULL,
01934 display_dcc_lost,
01935 NULL,
01936 NULL,
01937 NULL
01938 };
01939
01940 void dcc_identwait(int idx, char *buf, int len)
01941 {
01942
01943 }
01944
01945 void eof_dcc_identwait(int idx)
01946 {
01947 int i;
01948
01949 putlog(LOG_MISC, "*", DCC_LOSTCONN, dcc[idx].host, dcc[idx].port);
01950 for (i = 0; i < dcc_total; i++)
01951 if ((dcc[i].type == &DCC_IDENT) &&
01952 (dcc[i].u.ident_sock == dcc[idx].sock)) {
01953 killsock(dcc[i].sock);
01954 dcc[i].u.other = 0;
01955 lostdcc(i);
01956 break;
01957 }
01958 killsock(dcc[idx].sock);
01959 dcc[idx].u.other = 0;
01960 lostdcc(idx);
01961 }
01962
01963 static void display_dcc_identwait(int idx, char *buf)
01964 {
01965 long tv;
01966
01967 tv = now - dcc[idx].timeval;
01968 sprintf(buf, "idtw waited %lis", tv);
01969 }
01970
01971 struct dcc_table DCC_IDENTWAIT = {
01972 "IDENTWAIT",
01973 0,
01974 eof_dcc_identwait,
01975 dcc_identwait,
01976 NULL,
01977 NULL,
01978 display_dcc_identwait,
01979 NULL,
01980 NULL,
01981 NULL
01982 };
01983
01984 void dcc_ident(int idx, char *buf, int len)
01985 {
01986 char response[512], uid[512], buf1[UHOSTLEN];
01987 int i;
01988
01989 *response = *uid = '\0';
01990 sscanf(buf, "%*[^:]:%[^:]:%*[^:]:%[^\n]\n", response, uid);
01991 rmspace(response);
01992 if (response[0] != 'U') {
01993 dcc[idx].timeval = now;
01994 return;
01995 }
01996 rmspace(uid);
01997 uid[20] = 0;
01998 for (i = 0; i < dcc_total; i++)
01999 if ((dcc[i].type == &DCC_IDENTWAIT) &&
02000 (dcc[i].sock == dcc[idx].u.ident_sock)) {
02001 simple_sprintf(buf1, "%s@%s", uid, dcc[idx].host);
02002 dcc_telnet_got_ident(i, buf1);
02003 }
02004 dcc[idx].u.other = 0;
02005 killsock(dcc[idx].sock);
02006 lostdcc(idx);
02007 }
02008
02009 void eof_dcc_ident(int idx)
02010 {
02011 char buf[UHOSTLEN];
02012 int i;
02013
02014 for (i = 0; i < dcc_total; i++)
02015 if ((dcc[i].type == &DCC_IDENTWAIT) &&
02016 (dcc[i].sock == dcc[idx].u.ident_sock)) {
02017 putlog(LOG_MISC, "*", DCC_EOFIDENT);
02018 simple_sprintf(buf, "telnet@%s", dcc[idx].host);
02019 dcc_telnet_got_ident(i, buf);
02020 }
02021 killsock(dcc[idx].sock);
02022 dcc[idx].u.other = 0;
02023 lostdcc(idx);
02024 }
02025
02026 static void display_dcc_ident(int idx, char *buf)
02027 {
02028 sprintf(buf, "idnt (sock %d)", dcc[idx].u.ident_sock);
02029 }
02030
02031 struct dcc_table DCC_IDENT = {
02032 "IDENT",
02033 0,
02034 eof_dcc_ident,
02035 dcc_ident,
02036 &identtimeout,
02037 eof_dcc_ident,
02038 display_dcc_ident,
02039 NULL,
02040 NULL,
02041 NULL
02042 };
02043
02044 static void dcc_telnet_got_ident(int i, char *host)
02045 {
02046 int idx;
02047 char x[1024];
02048
02049 for (idx = 0; idx < dcc_total; idx++)
02050 if ((dcc[idx].type == &DCC_TELNET) &&
02051 (dcc[idx].sock == dcc[i].u.ident_sock))
02052 break;
02053 dcc[i].u.other = 0;
02054 if (dcc_total == idx) {
02055 putlog(LOG_MISC, "*", DCC_LOSTIDENT);
02056 killsock(dcc[i].sock);
02057 lostdcc(i);
02058 return;
02059 }
02060 strncpyz(dcc[i].host, host, UHOSTLEN);
02061 egg_snprintf(x, sizeof x, "-telnet!%s", dcc[i].host);
02062 if (protect_telnet && !make_userfile) {
02063 struct userrec *u;
02064 int ok = 1;
02065
02066 u = get_user_by_host(x);
02067
02068 if (!u)
02069 ok = 0;
02070 else if (require_p && !(u->flags & USER_PARTY))
02071 ok = 0;
02072 else if (!require_p && !(u->flags & USER_OP))
02073 ok = 0;
02074 if (!ok && u && (u->flags & USER_BOT))
02075 ok = 1;
02076 if (!ok && (dcc[idx].status & LSTN_PUBLIC))
02077 ok = 1;
02078 if (!ok) {
02079 putlog(LOG_MISC, "*", DCC_NOACCESS, dcc[i].host);
02080 killsock(dcc[i].sock);
02081 lostdcc(i);
02082 return;
02083 }
02084 }
02085 if (match_ignore(x)) {
02086 killsock(dcc[i].sock);
02087 lostdcc(i);
02088 return;
02089 }
02090
02091 if (!strcmp(dcc[idx].nick, "(script)")) {
02092 dcc[i].type = &DCC_SOCKET;
02093 dcc[i].u.other = NULL;
02094 strcpy(dcc[i].nick, "*");
02095 check_tcl_listen(dcc[idx].host, dcc[i].sock);
02096 return;
02097 }
02098
02099
02100 sockoptions(dcc[i].sock, EGG_OPTION_UNSET, SOCK_BUFFER);
02101
02102 dcc[i].type = &DCC_TELNET_ID;
02103 dcc[i].u.chat = get_data_ptr(sizeof(struct chat_info));
02104 egg_bzero(dcc[i].u.chat, sizeof(struct chat_info));
02105
02106
02107
02108
02109 dprintf(i, TLN_IAC_C TLN_WILL_C TLN_STATUS_C "\n");
02110
02111
02112 dcc[i].status = STAT_TELNET | STAT_ECHO;
02113 if (!strcmp(dcc[idx].nick, "(bots)"))
02114 dcc[i].status |= STAT_BOTONLY;
02115 if (!strcmp(dcc[idx].nick, "(users)"))
02116 dcc[i].status |= STAT_USRONLY;
02117
02118 strncpyz(dcc[i].nick, dcc[idx].host, HANDLEN);
02119 dcc[i].timeval = now;
02120 strcpy(dcc[i].u.chat->con_chan, chanset ? chanset->dname : "*");
02121
02122 if (use_telnet_banner)
02123 show_banner(i);
02124
02125
02126
02127 if (stealth_telnets)
02128 sub_lang(i, MISC_BANNER_STEALTH);
02129 else {
02130 dprintf(i, "\n\n");
02131 sub_lang(i, MISC_BANNER);
02132 }
02133 if (allow_new_telnets)
02134 dprintf(i, "(If you are new, enter 'NEW' here.)\n");
02135 }