/[cvs]/eggdrop1.4/src/dcc.c
ViewVC logotype

Contents of /eggdrop1.4/src/dcc.c

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Thu Jun 24 15:34:13 1999 UTC (20 years, 2 months ago) by segfault
Branch: MAIN
Changes since 1.1: +6 -1 lines
File MIME type: text/x-chdr
This patch fixes the problem of users with +f still being ignored in the
case of a telnet flood.  Patch sent by dw, manually applied by SegFault.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23