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