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

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

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


Revision 1.6 - (hide annotations) (download) (as text)
Wed Aug 4 15:51:58 1999 UTC (20 years, 2 months ago) by guppy
Branch: MAIN
Changes since 1.5: +6 -4 lines
File MIME type: text/x-chdr
*** empty log message ***

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23