/[cvs]/eggdrop1.8/src/userent.c
ViewVC logotype

Annotation of /eggdrop1.8/src/userent.c

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


Revision 1.3 - (hide annotations) (download) (as text)
Tue Oct 19 12:13:33 2010 UTC (8 years, 7 months ago) by pseudo
Branch: MAIN
Changes since 1.2: +153 -29 lines
File MIME type: text/x-chdr
Added full SSL support including Tcl commands.
Added support for certificate authentication.
Added support for botnet and partyline encryption using ssl.
Documented the new features and commands.
Fixed add_server() problems with IPv6 addresses in the server list.

1 simple 1.1 /*
2     * userent.c -- handles:
3     * user-entry handling, new style more versatile.
4     *
5 pseudo 1.3 * $Id: userent.c,v 1.2 2010/08/05 18:12:05 pseudo Exp $
6 simple 1.1 */
7     /*
8     * Copyright (C) 1997 Robey Pointer
9     * Copyright (C) 1999 - 2010 Eggheads Development Team
10     *
11     * This program is free software; you can redistribute it and/or
12     * modify it under the terms of the GNU General Public License
13     * as published by the Free Software Foundation; either version 2
14     * of the License, or (at your option) any later version.
15     *
16     * This program is distributed in the hope that it will be useful,
17     * but WITHOUT ANY WARRANTY; without even the implied warranty of
18     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19     * GNU General Public License for more details.
20     *
21     * You should have received a copy of the GNU General Public License
22     * along with this program; if not, write to the Free Software
23     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24     */
25    
26     #include "main.h"
27     #include "users.h"
28    
29 pseudo 1.3
30 simple 1.1 extern int noshare;
31     extern struct userrec *userlist;
32     extern struct dcc_t *dcc;
33     extern Tcl_Interp *interp;
34     extern char whois_fields[];
35    
36    
37     int share_greet = 0; /* Share greeting info */
38     static struct user_entry_type *entry_type_list;
39    
40    
41     void init_userent()
42     {
43     entry_type_list = 0;
44     add_entry_type(&USERENTRY_COMMENT);
45     add_entry_type(&USERENTRY_XTRA);
46     add_entry_type(&USERENTRY_INFO);
47     add_entry_type(&USERENTRY_LASTON);
48     add_entry_type(&USERENTRY_BOTADDR);
49     add_entry_type(&USERENTRY_PASS);
50     add_entry_type(&USERENTRY_HOSTS);
51     add_entry_type(&USERENTRY_BOTFL);
52 pseudo 1.3 #ifdef TLS
53     add_entry_type(&USERENTRY_FPRINT);
54     #endif
55 simple 1.1 }
56    
57     void list_type_kill(struct list_type *t)
58     {
59     struct list_type *u;
60    
61     while (t) {
62     u = t->next;
63     if (t->extra)
64     nfree(t->extra);
65     nfree(t);
66     t = u;
67     }
68     }
69    
70     int list_type_expmem(struct list_type *t)
71     {
72     int tot = 0;
73    
74     for (; t; t = t->next)
75     tot += sizeof(struct list_type) + strlen(t->extra) + 1;
76    
77     return tot;
78     }
79    
80     int def_unpack(struct userrec *u, struct user_entry *e)
81     {
82     char *tmp;
83    
84     tmp = e->u.list->extra;
85     e->u.list->extra = NULL;
86     list_type_kill(e->u.list);
87     e->u.string = tmp;
88     return 1;
89     }
90    
91     int def_pack(struct userrec *u, struct user_entry *e)
92     {
93     char *tmp;
94    
95     tmp = e->u.string;
96     e->u.list = user_malloc(sizeof(struct list_type));
97     e->u.list->next = NULL;
98     e->u.list->extra = tmp;
99     return 1;
100     }
101    
102     int def_kill(struct user_entry *e)
103     {
104     nfree(e->u.string);
105     nfree(e);
106     return 1;
107     }
108    
109     int def_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
110     {
111     if (fprintf(f, "--%s %s\n", e->type->name, e->u.string) == EOF)
112     return 0;
113     return 1;
114     }
115    
116     void *def_get(struct userrec *u, struct user_entry *e)
117     {
118     return e->u.string;
119     }
120    
121     int def_set(struct userrec *u, struct user_entry *e, void *buf)
122     {
123     char *string = (char *) buf;
124    
125     if (string && !string[0])
126     string = NULL;
127     if (!string && !e->u.string)
128     return 1;
129     if (string) {
130     int l = strlen(string);
131     char *i;
132    
133     if (l > 160)
134     l = 160;
135    
136    
137     e->u.string = user_realloc(e->u.string, l + 1);
138    
139     strncpyz(e->u.string, string, l + 1);
140    
141     for (i = e->u.string; *i; i++)
142     /* Allow bold, inverse, underline, color text here...
143     * But never add cr or lf!! --rtc
144     */
145     if ((unsigned int) *i < 32 && !strchr("\002\003\026\037", *i))
146     *i = '?';
147     } else {
148     nfree(e->u.string);
149     e->u.string = NULL;
150     }
151     if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED))) {
152     if (e->type != &USERENTRY_INFO || share_greet)
153     shareout(NULL, "c %s %s %s\n", e->type->name, u->handle,
154     e->u.string ? e->u.string : "");
155     }
156     return 1;
157     }
158    
159     int def_gotshare(struct userrec *u, struct user_entry *e, char *data, int idx)
160     {
161     putlog(LOG_CMDS, "*", "%s: change %s %s", dcc[idx].nick, e->type->name,
162     u->handle);
163     return e->type->set(u, e, data);
164     }
165    
166     int def_tcl_get(Tcl_Interp * interp, struct userrec *u,
167     struct user_entry *e, int argc, char **argv)
168     {
169     Tcl_AppendResult(interp, e->u.string, NULL);
170     return TCL_OK;
171     }
172    
173     int def_tcl_set(Tcl_Interp * irp, struct userrec *u,
174     struct user_entry *e, int argc, char **argv)
175     {
176     BADARGS(4, 4, " handle type setting");
177    
178     e->type->set(u, e, argv[3]);
179     return TCL_OK;
180     }
181    
182     int def_expmem(struct user_entry *e)
183     {
184     return strlen(e->u.string) + 1;
185     }
186    
187     void def_display(int idx, struct user_entry *e)
188     {
189     dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
190     }
191    
192     int def_dupuser(struct userrec *new, struct userrec *old, struct user_entry *e)
193     {
194     return set_user(e->type, new, e->u.string);
195     }
196    
197     static void comment_display(int idx, struct user_entry *e)
198     {
199     if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER))
200     dprintf(idx, " COMMENT: %.70s\n", e->u.string);
201     }
202    
203     struct user_entry_type USERENTRY_COMMENT = {
204     0, /* always 0 ;) */
205     def_gotshare,
206     def_dupuser,
207     def_unpack,
208     def_pack,
209     def_write_userfile,
210     def_kill,
211     def_get,
212     def_set,
213     def_tcl_get,
214     def_tcl_set,
215     def_expmem,
216     comment_display,
217     "COMMENT"
218     };
219    
220     struct user_entry_type USERENTRY_INFO = {
221     0, /* always 0 ;) */
222     def_gotshare,
223     def_dupuser,
224     def_unpack,
225     def_pack,
226     def_write_userfile,
227     def_kill,
228     def_get,
229     def_set,
230     def_tcl_get,
231     def_tcl_set,
232     def_expmem,
233     def_display,
234     "INFO"
235     };
236    
237     int pass_set(struct userrec *u, struct user_entry *e, void *buf)
238     {
239     char new[32];
240     register char *pass = buf;
241    
242     if (e->u.extra)
243     nfree(e->u.extra);
244     if (!pass || !pass[0] || (pass[0] == '-'))
245     e->u.extra = NULL;
246     else {
247     unsigned char *p = (unsigned char *) pass;
248    
249     if (strlen(pass) > 30)
250     pass[30] = 0;
251     while (*p) {
252     if ((*p <= 32) || (*p == 127))
253     *p = '?';
254     p++;
255     }
256     if ((u->flags & USER_BOT) || (pass[0] == '+'))
257     strcpy(new, pass);
258     else
259     encrypt_pass(pass, new);
260     e->u.extra = user_malloc(strlen(new) + 1);
261     strcpy(e->u.extra, new);
262     }
263     if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
264     shareout(NULL, "c PASS %s %s\n", u->handle, pass ? pass : "");
265     return 1;
266     }
267    
268     static int pass_tcl_set(Tcl_Interp * irp, struct userrec *u,
269     struct user_entry *e, int argc, char **argv)
270     {
271     BADARGS(3, 4, " handle PASS ?newpass?");
272    
273     pass_set(u, e, argc == 3 ? NULL : argv[3]);
274     return TCL_OK;
275     }
276    
277     struct user_entry_type USERENTRY_PASS = {
278     0,
279     def_gotshare,
280     0,
281     def_unpack,
282     def_pack,
283     def_write_userfile,
284     def_kill,
285     def_get,
286     pass_set,
287     def_tcl_get,
288     pass_tcl_set,
289     def_expmem,
290     0,
291     "PASS"
292     };
293    
294     static int laston_unpack(struct userrec *u, struct user_entry *e)
295     {
296     char *par, *arg;
297     struct laston_info *li;
298    
299     par = e->u.list->extra;
300     arg = newsplit(&par);
301     if (!par[0])
302     par = "???";
303     li = user_malloc(sizeof(struct laston_info));
304     li->lastonplace = user_malloc(strlen(par) + 1);
305     li->laston = atoi(arg);
306     strcpy(li->lastonplace, par);
307     list_type_kill(e->u.list);
308     e->u.extra = li;
309     return 1;
310     }
311    
312     static int laston_pack(struct userrec *u, struct user_entry *e)
313     {
314     char work[1024];
315     long tv;
316     struct laston_info *li;
317     int l;
318    
319     li = (struct laston_info *) e->u.extra;
320     tv = li->laston;
321     l = sprintf(work, "%lu %s", tv, li->lastonplace);
322     e->u.list = user_malloc(sizeof(struct list_type));
323     e->u.list->next = NULL;
324     e->u.list->extra = user_malloc(l + 1);
325     strcpy(e->u.list->extra, work);
326     nfree(li->lastonplace);
327     nfree(li);
328     return 1;
329     }
330    
331     static int laston_write_userfile(FILE *f, struct userrec *u,
332     struct user_entry *e)
333     {
334     long tv;
335     struct laston_info *li = (struct laston_info *) e->u.extra;
336    
337     tv = li->laston;
338     if (fprintf(f, "--LASTON %lu %s\n", tv,
339     li->lastonplace ? li->lastonplace : "") == EOF)
340     return 0;
341     return 1;
342     }
343    
344     static int laston_kill(struct user_entry *e)
345     {
346     if (((struct laston_info *) (e->u.extra))->lastonplace)
347     nfree(((struct laston_info *) (e->u.extra))->lastonplace);
348     nfree(e->u.extra);
349     nfree(e);
350     return 1;
351     }
352    
353     static int laston_set(struct userrec *u, struct user_entry *e, void *buf)
354     {
355     struct laston_info *li = (struct laston_info *) e->u.extra;
356    
357     if (li != buf) {
358     if (li) {
359     nfree(li->lastonplace);
360     nfree(li);
361     }
362    
363     li = e->u.extra = buf;
364     }
365     /* donut share laston info */
366     return 1;
367     }
368    
369     static int laston_tcl_get(Tcl_Interp * irp, struct userrec *u,
370     struct user_entry *e, int argc, char **argv)
371     {
372     struct laston_info *li = (struct laston_info *) e->u.extra;
373     char number[20];
374     long tv;
375     struct chanuserrec *cr;
376    
377     BADARGS(3, 4, " handle LASTON ?channel?");
378    
379     if (argc == 4) {
380     for (cr = u->chanrec; cr; cr = cr->next)
381     if (!rfc_casecmp(cr->channel, argv[3])) {
382     Tcl_AppendResult(irp, int_to_base10(cr->laston), NULL);
383     break;
384     }
385     if (!cr)
386     Tcl_AppendResult(irp, "0", NULL);
387     } else {
388     tv = li->laston;
389     sprintf(number, "%lu ", tv);
390     Tcl_AppendResult(irp, number, li->lastonplace, NULL);
391     }
392     return TCL_OK;
393     }
394    
395     static int laston_tcl_set(Tcl_Interp * irp, struct userrec *u,
396     struct user_entry *e, int argc, char **argv)
397     {
398     struct laston_info *li;
399     struct chanuserrec *cr;
400    
401     BADARGS(4, 5, " handle LASTON time ?place?");
402    
403     if ((argc == 5) && argv[4][0] && strchr(CHANMETA, argv[4][0])) {
404     /* Search for matching channel */
405     for (cr = u->chanrec; cr; cr = cr->next)
406     if (!rfc_casecmp(cr->channel, argv[4])) {
407     cr->laston = atoi(argv[3]);
408     break;
409     }
410     }
411     /* Save globally */
412     li = user_malloc(sizeof(struct laston_info));
413    
414     if (argc == 5) {
415     li->lastonplace = user_malloc(strlen(argv[4]) + 1);
416     strcpy(li->lastonplace, argv[4]);
417     } else {
418     li->lastonplace = user_malloc(1);
419     li->lastonplace[0] = 0;
420     }
421     li->laston = atoi(argv[3]);
422     set_user(&USERENTRY_LASTON, u, li);
423     return TCL_OK;
424     }
425    
426     static int laston_expmem(struct user_entry *e)
427     {
428     return sizeof(struct laston_info) +
429     strlen(((struct laston_info *) (e->u.extra))->lastonplace) + 1;
430     }
431    
432     static int laston_dupuser(struct userrec *new, struct userrec *old,
433     struct user_entry *e)
434     {
435     struct laston_info *li = e->u.extra, *li2;
436    
437     if (li) {
438     li2 = user_malloc(sizeof(struct laston_info));
439    
440     li2->laston = li->laston;
441     li2->lastonplace = user_malloc(strlen(li->lastonplace) + 1);
442     strcpy(li2->lastonplace, li->lastonplace);
443     return set_user(&USERENTRY_LASTON, new, li2);
444     }
445     return 0;
446     }
447    
448     struct user_entry_type USERENTRY_LASTON = {
449     0, /* always 0 ;) */
450     0,
451     laston_dupuser,
452     laston_unpack,
453     laston_pack,
454     laston_write_userfile,
455     laston_kill,
456     def_get,
457     laston_set,
458     laston_tcl_get,
459     laston_tcl_set,
460     laston_expmem,
461     0,
462     "LASTON"
463     };
464    
465     static int botaddr_unpack(struct userrec *u, struct user_entry *e)
466     {
467     char *p, *q;
468     struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
469    
470     egg_bzero(bi, sizeof(struct bot_addr));
471    
472     if (!(q = strchr((p = e->u.list->extra), ':'))) {
473     bi->address = user_malloc(strlen(p) + 1);
474     strcpy(bi->address, p);
475     } else {
476     bi->address = user_malloc((q - p) + 1);
477     strncpy(bi->address, p, q - p);
478     bi->address[q - p] = 0;
479     q++;
480 pseudo 1.3 #ifdef TLS
481     if (*q == '+')
482     bi->ssl = 1;
483     #endif
484 simple 1.1 bi->telnet_port = atoi(q);
485     if ((q = strchr(q, '/')))
486 pseudo 1.3 #ifdef TLS
487     {
488     if (q[1] == '+')
489     bi->ssl = 1;
490     bi->relay_port = atoi(q + 1);
491     }
492     #else
493 simple 1.1 bi->relay_port = atoi(q + 1);
494 pseudo 1.3 #endif
495 simple 1.1 }
496 pseudo 1.2 #ifdef IPV6
497     for (p = bi->address; *p; p++)
498     if (*p == ';')
499     *p = ':';
500     #endif
501 simple 1.1 if (!bi->telnet_port)
502     bi->telnet_port = 3333;
503     if (!bi->relay_port)
504     bi->relay_port = bi->telnet_port;
505     list_type_kill(e->u.list);
506     e->u.extra = bi;
507     return 1;
508     }
509    
510     static int botaddr_pack(struct userrec *u, struct user_entry *e)
511     {
512 pseudo 1.3 char work[1024], *p, *q = work;
513 simple 1.1 struct bot_addr *bi;
514     int l;
515    
516     bi = (struct bot_addr *) e->u.extra;
517 pseudo 1.3 for (p = bi->address; *p; p++)
518 pseudo 1.2 if (*p == ':')
519 pseudo 1.3 *q++ = ';';
520     else
521     *q++ = *p;
522     #ifdef TLS
523     if (bi->ssl)
524     l = simple_sprintf(q, ":+%u/+%u", bi->telnet_port, bi->relay_port);
525     else
526 pseudo 1.2 #endif
527 pseudo 1.3 l = simple_sprintf(q, ":%u/%u", bi->telnet_port, bi->relay_port);
528 simple 1.1 e->u.list = user_malloc(sizeof(struct list_type));
529     e->u.list->next = NULL;
530     e->u.list->extra = user_malloc(l + 1);
531     strcpy(e->u.list->extra, work);
532     nfree(bi->address);
533     nfree(bi);
534     return 1;
535     }
536    
537     static int botaddr_kill(struct user_entry *e)
538     {
539     nfree(((struct bot_addr *) (e->u.extra))->address);
540     nfree(e->u.extra);
541     nfree(e);
542     return 1;
543     }
544    
545     static int botaddr_write_userfile(FILE *f, struct userrec *u,
546     struct user_entry *e)
547     {
548 pseudo 1.3 int ret = 1;
549     char *p, *q, *addr;
550 simple 1.1 register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
551    
552 pseudo 1.3 p = bi->address;
553     addr = user_malloc(strlen(bi->address) + 1);
554     for (q = addr; *p; p++)
555 pseudo 1.2 if (*p == ':')
556 pseudo 1.3 *q++ = ';';
557     else
558     *q++ = *p;
559     *q = 0;
560     #ifdef TLS
561     if (bi->ssl) {
562     if (fprintf(f, "--%s %s:+%u/+%u\n", e->type->name, addr,
563     bi->telnet_port, bi->relay_port) == EOF)
564     ret = 0;
565     } else
566     #endif
567 pseudo 1.2 if (fprintf(f, "--%s %s:%u/%u\n", e->type->name, addr,
568 pseudo 1.3 bi->telnet_port, bi->relay_port) == EOF)
569     ret = 0;
570 pseudo 1.2 nfree(addr);
571 pseudo 1.3 return ret;
572 simple 1.1 }
573    
574     static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
575     {
576     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
577    
578     if (!bi && !buf)
579     return 1;
580     if (bi != buf) {
581     if (bi) {
582     nfree(bi->address);
583     nfree(bi);
584     }
585     bi = e->u.extra = buf;
586     }
587     if (bi && !noshare && !(u->flags & USER_UNSHARED)) {
588 pseudo 1.3 #ifdef TLS
589     if (bi->ssl)
590     shareout(NULL, "c BOTADDR %s %s +%d +%d\n", u->handle,
591     bi->address, bi->telnet_port, bi->relay_port);
592     else
593     #endif
594 simple 1.1 shareout(NULL, "c BOTADDR %s %s %d %d\n", u->handle,
595     bi->address, bi->telnet_port, bi->relay_port);
596     }
597     return 1;
598     }
599    
600     static int botaddr_tcl_get(Tcl_Interp * interp, struct userrec *u,
601     struct user_entry *e, int argc, char **argv)
602     {
603     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
604     char number[20];
605    
606 pseudo 1.3 #ifdef TLS
607     if (bi->ssl)
608     sprintf(number, " +%d", bi->telnet_port);
609     else
610     #endif
611 simple 1.1 sprintf(number, " %d", bi->telnet_port);
612     Tcl_AppendResult(interp, bi->address, number, NULL);
613 pseudo 1.3 #ifdef TLS
614     if (bi->ssl)
615     sprintf(number, " +%d", bi->relay_port);
616     else
617     #endif
618 simple 1.1 sprintf(number, " %d", bi->relay_port);
619     Tcl_AppendResult(interp, number, NULL);
620     return TCL_OK;
621     }
622    
623     static int botaddr_tcl_set(Tcl_Interp * irp, struct userrec *u,
624     struct user_entry *e, int argc, char **argv)
625     {
626     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
627    
628     BADARGS(4, 6, " handle type address ?telnetport ?relayport??");
629    
630     if (u->flags & USER_BOT) {
631     /* Silently ignore for users */
632     if (!bi) {
633     bi = user_malloc(sizeof(struct bot_addr));
634     egg_bzero(bi, sizeof(struct bot_addr));
635     } else
636     nfree(bi->address);
637     bi->address = user_malloc(strlen(argv[3]) + 1);
638     strcpy(bi->address, argv[3]);
639     if (argc > 4)
640 pseudo 1.3 #ifdef TLS
641     {
642     if (*argv[4] == '+')
643     bi->ssl = 1;
644     bi->telnet_port = atoi(argv[4]);
645     }
646     #else
647 simple 1.1 bi->telnet_port = atoi(argv[4]);
648 pseudo 1.3 #endif
649 simple 1.1 if (argc > 5)
650 pseudo 1.3 #ifdef TLS
651     {
652     if (*argv[5] == '+')
653     bi->ssl = 1;
654     bi->relay_port = atoi(argv[5]);
655     }
656     #else
657 simple 1.1 bi->relay_port = atoi(argv[5]);
658 pseudo 1.3 #endif
659 simple 1.1 if (!bi->telnet_port)
660     bi->telnet_port = 3333;
661     if (!bi->relay_port)
662     bi->relay_port = bi->telnet_port;
663     botaddr_set(u, e, bi);
664     }
665     return TCL_OK;
666     }
667    
668     static int botaddr_expmem(struct user_entry *e)
669     {
670     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
671    
672     return strlen(bi->address) + 1 + sizeof(struct bot_addr);
673     }
674    
675     static void botaddr_display(int idx, struct user_entry *e)
676     {
677     register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
678    
679     dprintf(idx, " ADDRESS: %.70s\n", bi->address);
680 pseudo 1.3 #ifdef TLS
681     if (bi->ssl)
682     dprintf(idx, " users: +%d, bots: +%d\n", bi->relay_port,
683     bi->telnet_port);
684     else
685     #endif
686 simple 1.1 dprintf(idx, " users: %d, bots: %d\n", bi->relay_port, bi->telnet_port);
687     }
688    
689     static int botaddr_gotshare(struct userrec *u, struct user_entry *e,
690     char *buf, int idx)
691     {
692     struct bot_addr *bi = user_malloc(sizeof(struct bot_addr));
693     char *arg;
694    
695     egg_bzero(bi, sizeof(struct bot_addr));
696     arg = newsplit(&buf);
697     bi->address = user_malloc(strlen(arg) + 1);
698     strcpy(bi->address, arg);
699     arg = newsplit(&buf);
700 pseudo 1.3 #ifdef TLS
701     if (*arg == '+' || *buf == '+')
702     bi->ssl = 1;
703     #endif
704 simple 1.1 bi->telnet_port = atoi(arg);
705     bi->relay_port = atoi(buf);
706     if (!bi->telnet_port)
707     bi->telnet_port = 3333;
708     if (!bi->relay_port)
709     bi->relay_port = bi->telnet_port;
710     if (!(dcc[idx].status & STAT_GETTING))
711     putlog(LOG_CMDS, "*", "%s: change botaddr %s", dcc[idx].nick, u->handle);
712     return botaddr_set(u, e, bi);
713     }
714    
715     static int botaddr_dupuser(struct userrec *new, struct userrec *old,
716     struct user_entry *e)
717     {
718     if (old->flags & USER_BOT) {
719     struct bot_addr *bi = e->u.extra, *bi2;
720    
721     if (bi) {
722     bi2 = user_malloc(sizeof(struct bot_addr));
723    
724     bi2->telnet_port = bi->telnet_port;
725     bi2->relay_port = bi->relay_port;
726 pseudo 1.3 #ifdef TLS
727     bi2->ssl = bi->ssl;
728     #endif
729 simple 1.1 bi2->address = user_malloc(strlen(bi->address) + 1);
730     strcpy(bi2->address, bi->address);
731     return set_user(&USERENTRY_BOTADDR, new, bi2);
732     }
733     }
734     return 0;
735     }
736    
737     struct user_entry_type USERENTRY_BOTADDR = {
738     0, /* always 0 ;) */
739     botaddr_gotshare,
740     botaddr_dupuser,
741     botaddr_unpack,
742     botaddr_pack,
743     botaddr_write_userfile,
744     botaddr_kill,
745     def_get,
746     botaddr_set,
747     botaddr_tcl_get,
748     botaddr_tcl_set,
749     botaddr_expmem,
750     botaddr_display,
751     "BOTADDR"
752     };
753    
754     int xtra_set(struct userrec *u, struct user_entry *e, void *buf)
755     {
756     struct xtra_key *curr, *old = NULL, *new = buf;
757    
758     for (curr = e->u.extra; curr; curr = curr->next) {
759     if (curr->key && !egg_strcasecmp(curr->key, new->key)) {
760     old = curr;
761     break;
762     }
763     }
764     if (!old && (!new->data || !new->data[0])) {
765     /* Delete non-existant entry -- doh ++rtc */
766     nfree(new->key);
767     if (new->data)
768     nfree(new->data);
769     nfree(new);
770     return TCL_OK;
771     }
772    
773     /* We will possibly free new below, so let's send the information
774     * to the botnet now
775     */
776     if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
777     shareout(NULL, "c XTRA %s %s %s\n", u->handle, new->key,
778     new->data ? new->data : "");
779     if ((old && old != new) || !new->data || !new->data[0]) {
780     egg_list_delete(&e->u.list, (struct list_type *) old);
781     nfree(old->key);
782     nfree(old->data);
783     nfree(old);
784     }
785     if (old != new && new->data) {
786     if (new->data[0])
787     list_insert((&e->u.extra), new) /* do not add a ';' here */
788     } else {
789     if (new->data)
790     nfree(new->data);
791     nfree(new->key);
792     nfree(new);
793     }
794     return TCL_OK;
795     }
796    
797     static int xtra_tcl_set(Tcl_Interp * irp, struct userrec *u,
798     struct user_entry *e, int argc, char **argv)
799     {
800     struct xtra_key *xk;
801     int l;
802    
803     BADARGS(4, 5, " handle type key ?value?");
804    
805     xk = user_malloc(sizeof(struct xtra_key));
806     l = strlen(argv[3]);
807     egg_bzero(xk, sizeof(struct xtra_key));
808     if (l > 500)
809     l = 500;
810     xk->key = user_malloc(l + 1);
811     strncpyz(xk->key, argv[3], l + 1);
812    
813     if (argc == 5) {
814     int k = strlen(argv[4]);
815    
816     if (k > 500 - l)
817     k = 500 - l;
818     xk->data = user_malloc(k + 1);
819     strncpyz(xk->data, argv[4], k + 1);
820     }
821     xtra_set(u, e, xk);
822     return TCL_OK;
823     }
824    
825     int xtra_unpack(struct userrec *u, struct user_entry *e)
826     {
827     struct list_type *curr, *head;
828     struct xtra_key *t;
829     char *key, *data;
830    
831     head = curr = e->u.list;
832     e->u.extra = NULL;
833     while (curr) {
834     t = user_malloc(sizeof(struct xtra_key));
835    
836     data = curr->extra;
837     key = newsplit(&data);
838     if (data[0]) {
839     t->key = user_malloc(strlen(key) + 1);
840     strcpy(t->key, key);
841     t->data = user_malloc(strlen(data) + 1);
842     strcpy(t->data, data);
843     list_insert((&e->u.extra), t);
844     }
845     curr = curr->next;
846     }
847     list_type_kill(head);
848     return 1;
849     }
850    
851     static int xtra_pack(struct userrec *u, struct user_entry *e)
852     {
853     struct list_type *t;
854     struct xtra_key *curr, *next;
855    
856     curr = e->u.extra;
857     e->u.list = NULL;
858     while (curr) {
859     t = user_malloc(sizeof(struct list_type));
860     t->extra = user_malloc(strlen(curr->key) + strlen(curr->data) + 4);
861     sprintf(t->extra, "%s %s", curr->key, curr->data);
862     list_insert((&e->u.list), t);
863     next = curr->next;
864     nfree(curr->key);
865     nfree(curr->data);
866     nfree(curr);
867     curr = next;
868     }
869     return 1;
870     }
871    
872     static void xtra_display(int idx, struct user_entry *e)
873     {
874     int code, lc, j;
875     EGG_CONST char **list;
876     struct xtra_key *xk;
877    
878     code = Tcl_SplitList(interp, whois_fields, &lc, &list);
879     if (code == TCL_ERROR)
880     return;
881     /* Scan thru xtra field, searching for matches */
882     for (xk = e->u.extra; xk; xk = xk->next) {
883     /* Ok, it's a valid xtra field entry */
884     for (j = 0; j < lc; j++) {
885     if (!egg_strcasecmp(list[j], xk->key))
886     dprintf(idx, " %s: %s\n", xk->key, xk->data);
887     }
888     }
889     Tcl_Free((char *) list);
890     }
891    
892     static int xtra_gotshare(struct userrec *u, struct user_entry *e,
893     char *buf, int idx)
894     {
895     char *arg;
896     struct xtra_key *xk;
897     int l;
898    
899     arg = newsplit(&buf);
900     if (!arg[0])
901     return 1;
902    
903     xk = user_malloc(sizeof(struct xtra_key));
904     egg_bzero(xk, sizeof(struct xtra_key));
905     l = strlen(arg);
906     if (l > 500)
907     l = 500;
908     xk->key = user_malloc(l + 1);
909     strncpyz(xk->key, arg, l + 1);
910    
911     if (buf[0]) {
912     int k = strlen(buf);
913    
914     if (k > 500 - l)
915     k = 500 - l;
916     xk->data = user_malloc(k + 1);
917     strncpyz(xk->data, buf, k + 1);
918     }
919     xtra_set(u, e, xk);
920     return 1;
921     }
922    
923     static int xtra_dupuser(struct userrec *new, struct userrec *old,
924     struct user_entry *e)
925     {
926     struct xtra_key *x1, *x2;
927    
928     for (x1 = e->u.extra; x1; x1 = x1->next) {
929     x2 = user_malloc(sizeof(struct xtra_key));
930    
931     x2->key = user_malloc(strlen(x1->key) + 1);
932     strcpy(x2->key, x1->key);
933     x2->data = user_malloc(strlen(x1->data) + 1);
934     strcpy(x2->data, x1->data);
935     set_user(&USERENTRY_XTRA, new, x2);
936     }
937     return 1;
938     }
939    
940     static int xtra_write_userfile(FILE *f, struct userrec *u,
941     struct user_entry *e)
942     {
943     struct xtra_key *x;
944    
945     for (x = e->u.extra; x; x = x->next)
946     if (fprintf(f, "--XTRA %s %s\n", x->key, x->data) == EOF)
947     return 0;
948     return 1;
949     }
950    
951     int xtra_kill(struct user_entry *e)
952     {
953     struct xtra_key *x, *y;
954    
955     for (x = e->u.extra; x; x = y) {
956     y = x->next;
957     nfree(x->key);
958     nfree(x->data);
959     nfree(x);
960     }
961     nfree(e);
962     return 1;
963     }
964    
965     static int xtra_tcl_get(Tcl_Interp * irp, struct userrec *u,
966     struct user_entry *e, int argc, char **argv)
967     {
968     struct xtra_key *x;
969    
970     BADARGS(3, 4, " handle XTRA ?key?");
971    
972     if (argc == 4) {
973     for (x = e->u.extra; x; x = x->next)
974     if (!egg_strcasecmp(argv[3], x->key)) {
975     Tcl_AppendResult(irp, x->data, NULL);
976     return TCL_OK;
977     }
978     return TCL_OK;
979     }
980     for (x = e->u.extra; x; x = x->next) {
981     char *p;
982     EGG_CONST char *list[2];
983    
984     list[0] = x->key;
985     list[1] = x->data;
986     p = Tcl_Merge(2, list);
987     Tcl_AppendElement(irp, p);
988     Tcl_Free((char *) p);
989     }
990     return TCL_OK;
991     }
992    
993     static int xtra_expmem(struct user_entry *e)
994     {
995     struct xtra_key *x;
996     int tot = 0;
997    
998     for (x = e->u.extra; x; x = x->next) {
999     tot += sizeof(struct xtra_key);
1000    
1001     tot += strlen(x->key) + 1;
1002     tot += strlen(x->data) + 1;
1003     }
1004     return tot;
1005     }
1006    
1007     struct user_entry_type USERENTRY_XTRA = {
1008     0,
1009     xtra_gotshare,
1010     xtra_dupuser,
1011     xtra_unpack,
1012     xtra_pack,
1013     xtra_write_userfile,
1014     xtra_kill,
1015     def_get,
1016     xtra_set,
1017     xtra_tcl_get,
1018     xtra_tcl_set,
1019     xtra_expmem,
1020     xtra_display,
1021     "XTRA"
1022     };
1023    
1024     static int hosts_dupuser(struct userrec *new, struct userrec *old,
1025     struct user_entry *e)
1026     {
1027     struct list_type *h;
1028    
1029     for (h = e->u.extra; h; h = h->next)
1030     set_user(&USERENTRY_HOSTS, new, h->extra);
1031     return 1;
1032     }
1033    
1034     static int hosts_null(struct userrec *u, struct user_entry *e)
1035     {
1036     return 1;
1037     }
1038    
1039     static int hosts_write_userfile(FILE *f, struct userrec *u,
1040     struct user_entry *e)
1041     {
1042     struct list_type *h;
1043    
1044     for (h = e->u.extra; h; h = h->next)
1045     if (fprintf(f, "--HOSTS %s\n", h->extra) == EOF)
1046     return 0;
1047     return 1;
1048     }
1049    
1050     static int hosts_kill(struct user_entry *e)
1051     {
1052     list_type_kill(e->u.list);
1053     nfree(e);
1054     return 1;
1055     }
1056    
1057     static int hosts_expmem(struct user_entry *e)
1058     {
1059     return list_type_expmem(e->u.list);
1060     }
1061    
1062     static void hosts_display(int idx, struct user_entry *e)
1063     {
1064     char s[1024];
1065     struct list_type *q;
1066    
1067     s[0] = 0;
1068     strcpy(s, " HOSTS: ");
1069     for (q = e->u.list; q; q = q->next) {
1070     if (s[0] && !s[9])
1071     strcat(s, q->extra);
1072     else if (!s[0])
1073     sprintf(s, " %s", q->extra);
1074     else {
1075     if (strlen(s) + strlen(q->extra) + 2 > 65) {
1076     dprintf(idx, "%s\n", s);
1077     sprintf(s, " %s", q->extra);
1078     } else {
1079     strcat(s, ", ");
1080     strcat(s, q->extra);
1081     }
1082     }
1083     }
1084     if (s[0])
1085     dprintf(idx, "%s\n", s);
1086     }
1087    
1088     static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
1089     {
1090     if (!buf || !egg_strcasecmp(buf, "none")) {
1091     /* When the bot crashes, it's in this part, not in the 'else' part */
1092     list_type_kill(e->u.list);
1093     e->u.list = NULL;
1094     } else {
1095     char *host = buf, *p = strchr(host, ',');
1096     struct list_type **t;
1097    
1098     /* Can't have ,'s in hostmasks */
1099     while (p) {
1100     *p = '?';
1101     p = strchr(host, ',');
1102     }
1103     /* fred1: check for redundant hostmasks with
1104     * controversial "superpenis" algorithm ;) */
1105     /* I'm surprised Raistlin hasn't gotten involved in this controversy */
1106     t = &(e->u.list);
1107     while (*t) {
1108     if (cmp_usermasks(host, (*t)->extra)) {
1109     struct list_type *u;
1110    
1111     u = *t;
1112     *t = (*t)->next;
1113     if (u->extra)
1114     nfree(u->extra);
1115     nfree(u);
1116     } else
1117     t = &((*t)->next);
1118     }
1119     *t = user_malloc(sizeof(struct list_type));
1120    
1121     (*t)->next = NULL;
1122     (*t)->extra = user_malloc(strlen(host) + 1);
1123     strcpy((*t)->extra, host);
1124     }
1125     return 1;
1126     }
1127    
1128     static int hosts_tcl_get(Tcl_Interp * irp, struct userrec *u,
1129     struct user_entry *e, int argc, char **argv)
1130     {
1131     struct list_type *x;
1132    
1133     BADARGS(3, 3, " handle HOSTS");
1134    
1135     for (x = e->u.list; x; x = x->next)
1136     Tcl_AppendElement(irp, x->extra);
1137     return TCL_OK;
1138     }
1139    
1140     static int hosts_tcl_set(Tcl_Interp * irp, struct userrec *u,
1141     struct user_entry *e, int argc, char **argv)
1142     {
1143     BADARGS(3, 4, " handle HOSTS ?host?");
1144    
1145     if (argc == 4)
1146     addhost_by_handle(u->handle, argv[3]);
1147     else
1148     addhost_by_handle(u->handle, "none"); /* drummer */
1149     return TCL_OK;
1150     }
1151    
1152     static int hosts_gotshare(struct userrec *u, struct user_entry *e,
1153     char *buf, int idx)
1154     {
1155     /* doh, try to be too clever and it bites your butt */
1156     return 0;
1157     }
1158    
1159     struct user_entry_type USERENTRY_HOSTS = {
1160     0,
1161     hosts_gotshare,
1162     hosts_dupuser,
1163     hosts_null,
1164     hosts_null,
1165     hosts_write_userfile,
1166     hosts_kill,
1167     def_get,
1168     hosts_set,
1169     hosts_tcl_get,
1170     hosts_tcl_set,
1171     hosts_expmem,
1172     hosts_display,
1173     "HOSTS"
1174     };
1175    
1176 pseudo 1.3 #ifdef TLS
1177     int fprint_unpack(struct userrec *u, struct user_entry *e)
1178     {
1179     char *tmp;
1180    
1181     tmp = ssl_fpconv(e->u.list->extra, NULL);
1182     nfree(e->u.list->extra);
1183     e->u.list->extra = NULL;
1184     list_type_kill(e->u.list);
1185     e->u.string = tmp;
1186     return 1;
1187     }
1188    
1189     int fprint_set(struct userrec *u, struct user_entry *e, void *buf)
1190     {
1191     char *fp = buf;
1192    
1193     if (!fp || !fp[0] || (fp[0] == '-')) {
1194     if (e->u.string) {
1195     nfree(e->u.string);
1196     e->u.string = NULL;
1197     }
1198     } else {
1199     fp = ssl_fpconv(buf, e->u.string);
1200     if (fp)
1201     e->u.string = fp;
1202     else
1203     return 0;
1204     }
1205     if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
1206     shareout(NULL, "c FPRINT %s %s\n", u->handle, e->u.string ? e->u.string : "");
1207     return 1;
1208     }
1209    
1210     static int fprint_tcl_set(Tcl_Interp * irp, struct userrec *u,
1211     struct user_entry *e, int argc, char **argv)
1212     {
1213     BADARGS(3, 4, " handle FPRINT ?new-fingerprint?");
1214    
1215     fprint_set(u, e, argc == 3 ? NULL : argv[3]);
1216     return TCL_OK;
1217     }
1218    
1219     struct user_entry_type USERENTRY_FPRINT = {
1220     0,
1221     def_gotshare,
1222     0,
1223     fprint_unpack,
1224     def_pack,
1225     def_write_userfile,
1226     def_kill,
1227     def_get,
1228     fprint_set,
1229     def_tcl_get,
1230     fprint_tcl_set,
1231     def_expmem,
1232     0,
1233     "FPRINT"
1234     };
1235     #endif /* TLS */
1236    
1237 simple 1.1 int egg_list_append(struct list_type **h, struct list_type *i)
1238     {
1239     for (; *h; h = &((*h)->next));
1240     *h = i;
1241     return 1;
1242     }
1243    
1244     int egg_list_delete(struct list_type **h, struct list_type *i)
1245     {
1246     for (; *h; h = &((*h)->next))
1247     if (*h == i) {
1248     *h = i->next;
1249     return 1;
1250     }
1251     return 0;
1252     }
1253    
1254     int egg_list_contains(struct list_type *h, struct list_type *i)
1255     {
1256     for (; h; h = h->next)
1257     if (h == i) {
1258     return 1;
1259     }
1260     return 0;
1261     }
1262    
1263     int add_entry_type(struct user_entry_type *type)
1264     {
1265     struct userrec *u;
1266    
1267     list_insert(&entry_type_list, type);
1268     for (u = userlist; u; u = u->next) {
1269     struct user_entry *e = find_user_entry(type, u);
1270    
1271     if (e && e->name) {
1272     e->type = type;
1273 pseudo 1.3
1274 simple 1.1 e->type->unpack(u, e);
1275     nfree(e->name);
1276     e->name = NULL;
1277     }
1278     }
1279     return 1;
1280     }
1281    
1282     int del_entry_type(struct user_entry_type *type)
1283     {
1284     struct userrec *u;
1285    
1286     for (u = userlist; u; u = u->next) {
1287     struct user_entry *e = find_user_entry(type, u);
1288    
1289     if (e && !e->name) {
1290     e->type->pack(u, e);
1291     e->name = user_malloc(strlen(e->type->name) + 1);
1292     strcpy(e->name, e->type->name);
1293     e->type = NULL;
1294     }
1295     }
1296     return egg_list_delete((struct list_type **) &entry_type_list,
1297     (struct list_type *) type);
1298     }
1299    
1300     struct user_entry_type *find_entry_type(char *name)
1301     {
1302     struct user_entry_type *p;
1303    
1304     for (p = entry_type_list; p; p = p->next) {
1305     if (!egg_strcasecmp(name, p->name))
1306     return p;
1307     }
1308     return NULL;
1309     }
1310    
1311     struct user_entry *find_user_entry(struct user_entry_type *et,
1312     struct userrec *u)
1313     {
1314     struct user_entry **e, *t;
1315    
1316     for (e = &(u->entries); *e; e = &((*e)->next)) {
1317     if (((*e)->type == et) ||
1318     ((*e)->name && !egg_strcasecmp((*e)->name, et->name))) {
1319     t = *e;
1320     *e = t->next;
1321     t->next = u->entries;
1322     u->entries = t;
1323     return t;
1324     }
1325     }
1326     return NULL;
1327     }
1328    
1329     void *get_user(struct user_entry_type *et, struct userrec *u)
1330     {
1331     struct user_entry *e;
1332    
1333     if (u && (e = find_user_entry(et, u)))
1334     return et->get(u, e);
1335     return 0;
1336     }
1337    
1338     int set_user(struct user_entry_type *et, struct userrec *u, void *d)
1339     {
1340     struct user_entry *e;
1341     int r;
1342    
1343     if (!u || !et)
1344     return 0;
1345    
1346     if (!(e = find_user_entry(et, u))) {
1347     e = user_malloc(sizeof(struct user_entry));
1348    
1349     e->type = et;
1350     e->name = NULL;
1351     e->u.list = NULL;
1352     list_insert((&(u->entries)), e);
1353     }
1354     r = et->set(u, e, d);
1355     if (!e->u.list) {
1356     egg_list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
1357     nfree(e);
1358     }
1359     return r;
1360     }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23