/[cvs]/eggdrop1.9/modules/botnet/botnet.c
ViewVC logotype

Annotation of /eggdrop1.9/modules/botnet/botnet.c

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


Revision 1.6 - (hide annotations) (download) (as text)
Tue Nov 6 00:05:40 2007 UTC (11 years, 7 months ago) by sven
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +73 -16 lines
File MIME type: text/x-chdr
 * Added a new socketfilter that provides a per socket timer for easy
   implementation of various timeouts.
 * All sockets that expect user logins now have a 60 second timeout for
   the user to supply a valid login.
 * All botnet sockets now have a 30 second timeout for the bot to do a
   successful login. After that it has a 90 second timeout after which
   a ping will be sent. After another 90 seconds the socket is closed.

1 sven 1.1 /* botnet.c: support for linking with other bots
2     *
3     * Copyright (C) 2003, 2004 Eggheads Development Team
4     *
5     * This program is free software; you can redistribute it and/or
6     * modify it under the terms of the GNU General Public License
7     * as published by the Free Software Foundation; either version 2
8     * of the License, or (at your option) any later version.
9     *
10     * This program is distributed in the hope that it will be useful,
11     * but WITHOUT ANY WARRANTY; without even the implied warranty of
12     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13     * GNU General Public License for more details.
14     *
15     * You should have received a copy of the GNU General Public License
16     * along with this program; if not, write to the Free Software
17     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18     */
19    
20     #ifndef lint
21 sven 1.6 static const char rcsid[] = "$Id: botnet.c,v 1.5 2007-10-27 19:55:51 sven Exp $";
22 sven 1.1 #endif
23    
24     #include <eggdrop/eggdrop.h>
25    
26     #include "botnet.h"
27    
28     EXPORT_SCOPE int botnet_LTX_start(egg_module_t *modinfo);
29    
30     typedef struct {
31     char *ip;
32     int port;
33     } botnet_config_t;
34    
35     static int bot_close(int why);
36     static int do_link(user_t *u, const char *text);
37    
38     static int bot_on_delete(event_owner_t *owner, void *client_data);
39     //static int sock_on_delete(event_owner_t *owner, void *client_data);
40    
41     /* Partyline commands. */
42     static int party_plus_bot(partymember_t *p, char *nick, user_t *u, char *cmd, char *text);
43     static int party_minus_bot(partymember_t *p, char *nick, user_t *u, char *cmd, char *text);
44    
45     /* Sockbuf handler. */
46     static int idx_on_newclient(void *client_data, int idx, int newidx, const char *peer_ip, int peer_port);
47     static int idx_on_connect(void *client_data, int idx, const char *peer_ip, int peer_port);
48     static int idx_on_read(void *client_data, int idx, char *data, int len);
49     static int idx_on_eof(void *client_data, int idx, int err, const char *errmsg);
50 sven 1.4 static int idx_on_delete(event_owner_t *owner, void *client_data);
51 sven 1.1
52 sven 1.5 static int got_bbroadcast(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
53     static int got_botmsg(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
54     static int got_bquit(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
55     static int got_broadcast(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
56     static int got_chanmsg(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
57     static int got_endlink(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
58     static int got_extension(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
59 sven 1.4 static int got_join(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
60 sven 1.5 static int got_link(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
61 sven 1.4 static int got_login(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
62 sven 1.2 static int got_newbot(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
63 sven 1.5 static int got_nick(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
64     static int got_part(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
65 sven 1.6 static int got_ping(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
66     static int got_pong(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
67 sven 1.5 static int got_privmsg(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
68     static int got_quit(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
69     static int got_unlink(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
70 sven 1.2
71     static struct {
72     char *cmd;
73     int source;
74 sven 1.4 int min_argc;
75 sven 1.2 int (*function)(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len);
76     } cmd_mapping[] = {
77 sven 1.5 {"bbroadcast", ENTITY_BOT, 1, got_bbroadcast},
78     {"botmsg", ENTITY_BOT, 1, got_botmsg},
79     {"bquit", ENTITY_BOT, 0, got_bquit},
80     {"broadcast", 0, 1, got_broadcast},
81     {"chanmsg", 0, 2, got_chanmsg},
82     {"el", ENTITY_BOT, 0, got_endlink},
83     {"extension", 0, 2, got_extension},
84 sven 1.4 {"join", ENTITY_PARTYMEMBER, 1, got_join},
85 sven 1.5 {"link", 0, 2, got_link},
86 sven 1.4 {"login", ENTITY_BOT, 4, got_login},
87 sven 1.5 {"newbot", ENTITY_BOT, 4, got_newbot},
88     {"nick", ENTITY_PARTYMEMBER, 1, got_nick},
89     {"part", ENTITY_PARTYMEMBER, 1, got_part},
90 sven 1.6 {"ping", ENTITY_BOT, 0, got_ping},
91     {"pong", ENTITY_BOT, 0, got_pong},
92 sven 1.5 {"privmsg", 0, 2, got_privmsg},
93     {"quit", ENTITY_PARTYMEMBER, 0, got_quit},
94     {"unlink", 0, 2, got_unlink}
95 sven 1.2 };
96    
97     static int cmd_num = sizeof(cmd_mapping) / sizeof(cmd_mapping[0]);
98    
99 sven 1.1 static int listen_idx;
100    
101     static botnet_config_t botnet_config;
102    
103     static sockbuf_handler_t server_handler = {
104     "botnet server",
105     NULL, NULL, idx_on_newclient,
106     NULL, NULL
107     };
108    
109     static config_var_t botnet_config_vars[] = {
110     {"my-ip", &botnet_config.ip, CONFIG_STRING},
111     {"port", &botnet_config.port, CONFIG_INT},
112     {0}
113     };
114    
115     static event_owner_t bot_owner = {
116     "botnet", NULL,
117     NULL, NULL,
118     bot_on_delete
119     };
120    
121 sven 1.4 static event_owner_t sock_owner = {
122     "botnet", NULL,
123     NULL, NULL,
124     idx_on_delete
125     };
126    
127 sven 1.1 static event_owner_t generic_owner = {
128     "botnet", NULL,
129     NULL, NULL,
130     NULL
131     };
132    
133     /*static event_owner_t sock_owner = {
134     "oldbotnet", NULL,
135     NULL, NULL,
136     sock_on_delete
137     };*/
138    
139     static bind_list_t party_binds[] = {
140     {"n", "+bot", party_plus_bot},
141     {"n", "-bot", party_minus_bot},
142     {0}
143     };
144    
145     static sockbuf_handler_t client_handler = {
146     "botnet",
147     idx_on_connect, idx_on_eof, NULL,
148 sven 1.4 idx_on_read, NULL
149 sven 1.1 };
150    
151     /* +bot <bot> <host> <port> */
152     static int party_plus_bot(partymember_t *p, char *nick, user_t *u, char *cmd, char *text)
153     {
154     char *name, *host, *port;
155     user_t *bot;
156    
157     egg_get_words(text, NULL, &name, &host, &port, NULL);
158     if (!port) {
159     partymember_printf(p, _("Syntax: +bot <bot> <host> <port>"));
160     goto done;
161     }
162    
163     bot = user_new(name);
164     if (!bot) {
165     partymember_printf(p, _("Could not create bot '%s'."), name);
166     goto done;
167     }
168    
169     user_set_flags_str(bot, NULL, "+b");
170     user_set_setting(bot, "bot", "type", "eggdrop");
171     user_set_setting(bot, "bot", "host", host);
172     user_set_setting(bot, "bot", "port", port);
173    
174     done:
175     if (name) free(name);
176     if (host) free(host);
177     if (port) free(port);
178     return 0;
179     }
180    
181     /* -bot <bot> */
182     static int party_minus_bot(partymember_t *p, char *nick, user_t *u, char *cmd, char *text)
183     {
184     char *type;
185     user_t *bot;
186    
187     while (isspace(*text)) text++;
188    
189     if (!text || !*text) {
190     partymember_printf(p, "Syntax: -bot <bot>");
191     return(0);
192     }
193    
194     bot = user_lookup_by_handle(text);
195     if (!bot) {
196     partymember_printf(p, _("Could not find user '%s'."), text);
197     return(0);
198     }
199    
200     user_get_setting(bot, "bot", "type", &type);
201     if (!type || !(bot->flags | USER_BOT) || strcmp(type, "eggdrop")) {
202     partymember_printf(p, _("Error: '%s' is not an eggdrop bot."), bot->handle);
203     return(0);
204     }
205    
206     partymember_printf(p, _("Deleting user '%s'."), bot->handle);
207     user_delete(bot);
208     return(BIND_RET_LOG);
209     }
210    
211 sven 1.5 static int get_entity(botnet_entity_t *ent, char *text)
212 sven 1.2 {
213     char *p;
214     int id = -1;
215     botnet_bot_t *bot;
216     partymember_t *pm;
217    
218     p = strchr(text, '@');
219     if (p) {
220     *p = 0;
221     id = b64dec_int(text);
222     text = p + 1;
223     }
224     bot = botnet_lookup(text);
225     if (!bot && strcmp(text, botnet_get_name())) return 1;
226     if (id == -1) {
227     set_bot_entity(ent, bot);
228     return 0;
229     }
230     pm = partymember_lookup(NULL, bot, id);
231     if (!pm) return 1;
232     set_user_entity(ent, pm);
233     return 0;
234     }
235    
236 sven 1.1 static int do_link(user_t *user, const char *type)
237     {
238     char *host = NULL, *portstr = NULL, *password = NULL;
239     int port;
240     bot_t *data;
241    
242     user_get_setting(user, NULL, "bot.host", &host);
243     user_get_setting(user, NULL, "bot.port", &portstr);
244     user_get_setting(user, NULL, "bot.password", &password);
245    
246     if (portstr) port = atoi(portstr);
247 sven 1.2 if (!host || !portstr || port <= 0 || port > 65535) {
248 sven 1.1 putlog(LOG_MISC, "*", _("Error linking %s: Invalid telnet address:port stored."), user->handle);
249     return BIND_RET_BREAK;
250     }
251    
252     data = malloc(sizeof(*data));
253     data->bot = NULL;
254     data->user = user;
255     data->idx = egg_connect(host, port, -1);
256 sven 1.2 data->proto = NULL;
257     if (password) data->pass = strdup(password);
258     else data->pass = NULL;
259 sven 1.1 data->incoming = 0;
260     data->linking = 1;
261     data->idle = 0;
262    
263 sven 1.4 sockbuf_set_handler(data->idx, &client_handler, data, &sock_owner);
264 sven 1.1 netstring_on(data->idx);
265 sven 1.6 socktimer_on(data->idx, 30, 0, NULL, NULL, &generic_owner);
266 sven 1.1
267     putlog(LOG_MISC, "*", _("Linking to %s (%s %d) on idx %d."), user->handle, host, port, data->idx);
268     return BIND_RET_BREAK;
269     }
270    
271 sven 1.6 static void do_ping(int idx, void *client_data)
272     {
273     bot_t *bot = client_data;
274    
275     if (bot->idle == -1) {
276     botnet_delete(bot->bot, _("Ping timeout"));
277     } else if (bot->idle == 0) {
278     bot->idle = 1;
279     } else {
280     bot->idle = -1;
281     egg_iprintf(bot->idx, "ping\n");
282     }
283     }
284    
285 sven 1.5 static int got_bbroadcast(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
286     {
287     if (argc <= 1) len = 0;
288     botnet_botbroadcast(src->bot, argv[0], argv[argc - 1], len);
289    
290     return 0;
291     }
292    
293     static int got_botmsg(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
294     {
295     botnet_entity_t dst;
296    
297     if (get_entity(&dst, argv[0])) return 0;
298     if (dst.what != ENTITY_BOT) return 0;
299    
300     if (argc <= 2) len = 0;
301     botnet_botmsg(src->bot, dst.bot, argv[1], argv[argc - 1], len);
302    
303     return 0;
304     }
305    
306     static int got_bquit(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
307     {
308     botnet_delete(src->bot, len ? argv[0] : "No reason");
309    
310     return 0;
311     }
312    
313     static int got_broadcast(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
314     {
315     botnet_broadcast(src, argv[0], len);
316    
317     return 0;
318     }
319    
320     static int got_chanmsg(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
321     {
322     partychan_msg_name(argv[0], src, argv[1], len);
323    
324     return 0;
325     }
326    
327     static int got_endlink(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
328     {
329     botnet_link_success(src->bot);
330    
331     return 0;
332     }
333    
334     static int got_extension(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
335     {
336     botnet_entity_t dst;
337    
338     if (argc <= 2) len = 0;
339    
340     if (argv[0][0] == '*') {
341     botnet_extension(EXTENSION_ALL, src, NULL, NULL, argv[1], argv[argc - 1], len);
342     }
343    
344     if (get_entity(&dst, argv[0])) return 0;
345     if (dst.what != ENTITY_BOT) return 0;
346    
347     botnet_extension(EXTENSION_ONE, src, dst.bot, NULL, argv[1], argv[argc - 1], len);
348    
349     return 0;
350     }
351    
352 sven 1.4 /* login channel [netburst] */
353    
354     static int got_join(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
355     {
356     int netburst = 0;
357    
358     if (argc >= 2) netburst = b64dec_int(argv[1]) & 1;
359     partychan_join_name(argv[0], src->user, netburst);
360    
361     return 0;
362     }
363    
364 sven 1.5 static int got_link(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
365     {
366     botnet_entity_t dst;
367    
368     if (get_entity(&dst, argv[0])) return 0;
369     if (dst.what != ENTITY_BOT) return 0;
370    
371     botnet_link(src, dst.bot, argv[1]);
372     return 0;
373     }
374    
375 sven 1.4 /* login nick ident host id */
376    
377     static int got_login(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
378     {
379     partymember_new(b64dec_int(argv[3]), NULL, src->bot, argv[0], argv[1], argv[2], NULL, NULL, &generic_owner);
380     return 0;
381     }
382    
383 sven 1.2 /* newbot uplink name type version fullversion linking */
384    
385     static int got_newbot(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
386     {
387 sven 1.4 int flags = 0;
388 sven 1.3 xml_node_t *info;
389 sven 1.2 botnet_bot_t *new;
390    
391 sven 1.4 if (argc >= 5) flags = b64dec_int(argv[4]);
392 sven 1.3
393     info = xml_node_new();
394     xml_node_set_str(argv[1], info, "type", 0, (void *) 0);
395     xml_node_set_int(b64dec_int(argv[2]), info, "numversion", 0, (void *) 0);
396 sven 1.4 xml_node_set_str(argv[3], info, "version", 0, (void *) 0);
397 sven 1.3
398     new = botnet_new(argv[0], NULL, src->bot, bot->bot, info, NULL, NULL, &generic_owner, flags & 1);
399 sven 1.2 if (!new) {
400     botnet_delete(bot->bot, _("Couldn't create introduced bot"));
401 sven 1.3 xml_node_delete(info);
402 sven 1.2 return 0;
403     }
404    
405     return 0;
406     }
407    
408 sven 1.5 static int got_nick(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
409     {
410     partymember_set_nick(src->user, argv[0]);
411     return 0;
412     }
413    
414     static int got_part(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
415     {
416     char *reason = NULL;
417    
418     if (argc >= 2) reason = argv[argc - 1];
419     partychan_part_name(argv[0], src->user, reason);
420    
421     return 0;
422     }
423    
424 sven 1.6 static int got_ping(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
425     {
426     egg_iprintf(bot->idx, "pong\n");
427    
428     return 0;
429     }
430    
431     static int got_pong(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
432     {
433     return 0;
434     }
435    
436 sven 1.5 static int got_privmsg(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
437     {
438     partymember_t *dst;
439     botnet_entity_t ent;
440    
441     if (get_entity(&ent, argv[0])) return 0;
442     if (ent.what != ENTITY_PARTYMEMBER) return 0;
443     dst = ent.user;
444     partymember_msg(dst, src, argv[1], len);
445     return 0;
446     }
447    
448     static int got_quit(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
449     {
450     partymember_delete(src->user, NULL, len ? argv[0] : "No reason.");
451     return 0;
452     }
453    
454     static int got_unlink(bot_t *bot, botnet_entity_t *src, char *cmd, int argc, char *argv[21], int len)
455     {
456     botnet_entity_t dst;
457    
458     if (get_entity(&dst, argv[0])) return 0;
459     if (dst.what != ENTITY_BOT) return 0;
460    
461     botnet_link(src, dst.bot, argv[1]);
462     return 0;
463     }
464    
465 sven 1.1 static int idx_on_newclient(void *client_data, int idx, int newidx, const char *peer_ip, int peer_port)
466     {
467     bot_t *session;
468    
469     session = malloc(sizeof(*session));
470     session->bot = NULL;
471     session->user = NULL;
472     session->idx = newidx;
473 sven 1.2 session->proto = NULL;
474     session->pass = NULL;
475 sven 1.1 session->incoming = 1;
476     session->linking = 1;
477     session->idle = 0;
478    
479 sven 1.4 sockbuf_set_handler(newidx, &client_handler, session, &sock_owner);
480 sven 1.1 netstring_on(newidx);
481 sven 1.6 socktimer_on(newidx, 30, 0, NULL, NULL, &generic_owner);
482 sven 1.1
483     return 0;
484     }
485    
486     static int idx_on_connect(void *client_data, int idx, const char *peer_ip, int peer_port)
487     {
488 sven 1.6 bot_t *bot = client_data;
489    
490     // no special features yet
491     // egg_iprintf(idx, "proto para1 para2");
492     bot->proto = malloc(sizeof(*bot->proto));
493     bot->proto->dummy = 0;
494     egg_iprintf(idx, ":%s hello %s", botnet_get_name(), bot->user->handle);
495 sven 1.2
496     return 0;
497     }
498    
499     /*!
500     * \brief Handles the login for incomming links.
501     *
502     * \param bot The ::bot_t struct for this link.
503     * \param src The source of this message. This is a string!
504     * \param cmd The command.
505     * \param argc The number of parameters.
506     * \param argv Up to 20 parameters. NULL terminated.
507     * \param len The length of the last parameter.
508     *
509     * \return Always 0.
510     */
511    
512     static int recving_login(bot_t *bot, char *src, char *cmd, int argc, char *argv[], int len) {
513 sven 1.6 if (src) {
514     if (!bot->user) {
515 sven 1.2 bot->user = user_lookup_by_handle(src);
516     if (!bot->user || !(bot->user->flags & USER_BOT) || !strcmp(src, botnet_get_name())) {
517     sockbuf_delete(bot->idx);
518     return 0;
519     }
520     if (botnet_lookup(src) || bot->user->flags & (USER_LINKING_BOT | USER_LINKED_BOT)) {
521     sockbuf_delete(bot->idx);
522     return 0;
523     }
524 sven 1.6 } else {
525     if (src && strcmp(src, bot->user->handle)) {
526     sockbuf_delete(bot->idx);
527     return 0;
528     }
529 sven 1.2 }
530     }
531     if (!strcasecmp(cmd, "PROTO")) {
532     if (bot->proto) {
533     sockbuf_delete(bot->idx);
534     return 0;
535     }
536     bot->proto = malloc(sizeof(*bot->proto));
537     bot->proto->dummy = 0;
538     egg_iprintf(bot->idx, "PROTO");
539 sven 1.6 return 0;
540     }
541     if (!bot->user) {
542     sockbuf_delete(bot->idx);
543     return 0;
544     }
545     if (!bot->proto) {
546     bot->proto = malloc(sizeof(*bot->proto));
547     bot->proto->dummy = 0;
548     }
549    
550     if (!strcasecmp(cmd, "HELLO")) {
551 sven 1.2 int i;
552     char salt[33], *pass = NULL;
553     unsigned char hash[16];
554     MD5_CTX md5;
555    
556     if (bot->pass || argc != 1 || strcmp(argv[0], botnet_get_name())) {
557     sockbuf_delete(bot->idx);
558     return 0;
559     }
560     user_get_setting(bot->user, NULL, "bot.password", &pass);
561     if (!pass || !*pass) {
562     egg_iprintf(bot->idx, "thisbot eggdrop %s %s %s :%s", botnet_get_name(), "1090000", "eggdrop1.9.0+cvs", "some informative stuff");
563     bot->pass = calloc(1, 1);
564     return 0;
565     }
566     for (i = 0; i < 32; ++i) {
567     salt[i] = random() % 62;
568     if (salt[i] < 26) salt[i] += 'A';
569 sven 1.6 else if (salt[i] < 52) salt[i] += 'a' - 26;
570     else salt[i] += '0' - 52;
571 sven 1.2 }
572     salt[32] = 0;
573     MD5_Init(&md5);
574     MD5_Update(&md5, salt, 32);
575     MD5_Update(&md5, pass, strlen(pass));
576     MD5_Final(hash, &md5);
577     bot->pass = malloc(33);
578     MD5_Hex(hash, bot->pass);
579     egg_iprintf(bot->idx, "passreq %s", salt);
580     } else if (!strcasecmp(cmd, "PASS")) {
581     if (!bot->pass || argc != 1 || strcmp(argv[0], bot->pass)) {
582     sockbuf_delete(bot->idx);
583     return 0;
584     }
585     *bot->pass = 0;
586 sven 1.4 egg_iprintf(bot->idx, ":%s thisbot eggdrop %s %s :%s", botnet_get_name(), b64enc_int(1090000), "eggdrop1.9.0+cvs", "some informative stuff");
587 sven 1.2 } else if (!strcasecmp(cmd, "THISBOT")) {
588 sven 1.3 xml_node_t *info;
589    
590 sven 1.4 if (!bot->pass || *bot->pass || argc != 4) {
591 sven 1.2 sockbuf_delete(bot->idx);
592     return 0;
593     }
594     free(bot->pass);
595     bot->pass = NULL;
596     bot->linking = 0;
597 sven 1.3
598     info = xml_node_new();
599     xml_node_set_str(argv[0], info, "type", 0, (void *) 0);
600 sven 1.4 xml_node_set_int(b64dec_int(argv[1]), info, "numversion", 0, (void *) 0);
601     xml_node_set_str(argv[2], info, "version", 0, (void *) 0);
602 sven 1.3
603     bot->bot = botnet_new(bot->user->handle, bot->user, NULL, NULL, info, &bothandler, bot, &bot_owner, 0);
604 sven 1.6 socktimer_on(bot->idx, 90, TIMER_REPEAT, do_ping, bot, &generic_owner);
605 sven 1.2 botnet_replay_net(bot->bot);
606     egg_iprintf(bot->idx, "el");
607     } else {
608     sockbuf_delete(bot->idx);
609     }
610     return 0;
611     }
612 sven 1.1
613 sven 1.2 static int sending_login(bot_t *bot, char *src, char *cmd, int argc, char *argv[], int len)
614     {
615     if (src && strcmp(src, bot->user->handle)) {
616     egg_iprintf(bot->idx, "error :Wrong bot.");
617     sockbuf_delete(bot->idx);
618     return 0;
619     }
620     if (!strcasecmp(cmd, "PROTO")) {
621     if (bot->proto) {
622     egg_iprintf(bot->idx, "error :Been there, done that.");
623     sockbuf_delete(bot->idx);
624     return 0;
625     }
626     bot->proto = malloc(sizeof(*bot->proto));
627     bot->proto->dummy = 0;
628 sven 1.6 egg_iprintf(bot->idx, ":%s hello %s", botnet_get_name(), bot->user->handle);
629 sven 1.2 } else if (!strcasecmp(cmd, "PASSREQ")) {
630     char buf[33];
631     unsigned char hash[16];
632     MD5_CTX md5;
633     if (argc != 1 || !bot->proto || !bot->pass || !*bot->pass) {
634     if (!bot->pass) putlog(LOG_MISC, "*", "botnet error: password on %s needs to be reset.", bot->user->handle);
635     egg_iprintf(bot->idx, "error :Expected something else.");
636     sockbuf_delete(bot->idx);
637     return 0;
638     }
639     MD5_Init(&md5);
640     MD5_Update(&md5, argv[0], len);
641     MD5_Update(&md5, bot->pass, strlen(bot->pass));
642     MD5_Final(hash, &md5);
643     MD5_Hex(hash, buf);
644     egg_iprintf(bot->idx, "pass %s", buf);
645     *bot->pass = 0;
646     } else if (!strcasecmp(cmd, "THISBOT")) {
647 sven 1.3 xml_node_t *info;
648    
649 sven 1.4 if (argc != 4) {
650 sven 1.2 sockbuf_delete(bot->idx);
651     return 0;
652     }
653 sven 1.4 egg_iprintf(bot->idx, ":%s thisbot eggdrop %s %s :%s", botnet_get_name(), b64enc_int(1090000), "eggdrop1.9.0+cvs", "some informative stuff");
654 sven 1.2 free(bot->pass);
655     bot->pass = NULL;
656     bot->linking = 0;
657 sven 1.3
658     info = xml_node_new();
659     xml_node_set_str(argv[0], info, "type", 0, (void *) 0);
660 sven 1.4 xml_node_set_int(b64dec_int(argv[1]), info, "numversion", 0, (void *) 0);
661     xml_node_set_str(argv[2], info, "version", 0, (void *) 0);
662 sven 1.3
663     bot->bot = botnet_new(bot->user->handle, bot->user, NULL, NULL, info, &bothandler, bot, &bot_owner, 0);
664 sven 1.6 socktimer_on(bot->idx, 90, TIMER_REPEAT, do_ping, bot, &generic_owner);
665 sven 1.2 botnet_replay_net(bot->bot);
666     egg_iprintf(bot->idx, "el");
667     } else {
668     sockbuf_delete(bot->idx);
669     }
670 sven 1.1 return 0;
671     }
672    
673     static int idx_on_read(void *client_data, int idx, char *data, int len)
674     {
675 sven 1.2 int argc = 0;
676     char *start = data, *p, *srcstr = NULL, *argv[22];
677 sven 1.1 bot_t *bot = client_data;
678 sven 1.2 botnet_entity_t src;
679    
680     if (!len) return 0;
681     if (*data == ':') {
682     srcstr = data + 1;
683     p = strchr(srcstr, ' ');
684     if (!p) return 0;
685     *p = 0;
686     data = p + 1;
687     while (isspace(*data)) ++data;
688     }
689 sven 1.1
690 sven 1.2 while (*data) {
691     argv[argc++] = data;
692     if (*data == ':') {
693     argv[argc - 1]++;
694     break;
695     }
696     if (argc == 21) break;
697     p = strchr(data, ' ');
698     if (!p) break;
699     *p = 0;
700     data = p + 1;
701     while (isspace(*data)) ++data;
702     }
703    
704     if (!argc) return 0;
705    
706     len -= argv[argc - 1] - start;
707     argv[argc] = NULL;
708 sven 1.6
709     if (!strcasecmp(argv[0], "error")) {
710     putlog(LOG_MISC, "*", _("Botnet: Error from %s: %s"), bot->user ? bot->user->handle : "unknown", argv[1] ? argv[1] : "no reason");
711     if (bot->bot) botnet_delete(bot->bot, "Error from bot.");
712     else sockbuf_delete(bot->idx);
713     return 0;
714     }
715    
716 sven 1.2 if (!bot->bot) {
717 sven 1.4 if (bot->incoming) return recving_login(bot, srcstr, argv[0], argc - 1, argv + 1, len);
718     else return sending_login(bot, srcstr, argv[0], argc - 1, argv + 1, len);
719 sven 1.2 }
720    
721     if (srcstr) {
722 sven 1.4 char *at;
723 sven 1.2 botnet_bot_t *srcbot;
724 sven 1.4
725     at = strchr(srcstr, '@');
726     if (get_entity(&src, srcstr)) {
727     if (at && !*at) putlog(LOG_MISC, "*", _("Botnet: Desync! %s says %s came from %s@%s who doesn't exist!"), bot->bot->name, argv[0], srcstr, at + 1);
728     else putlog(LOG_MISC, "*", _("Botnet: Desync! %s says %s came from %s who doesn't exist!"), bot->bot->name, argv[0], srcstr);
729     return 0;
730     }
731 sven 1.2 if (src.what == ENTITY_BOT) srcbot = src.bot;
732     else srcbot = src.user->bot;
733     if (botnet_check_direction(bot->bot, srcbot)) return 0;
734     } else {
735     set_bot_entity(&src, bot->bot);
736     }
737    
738     int min = 0, max = cmd_num - 1, cur = max / 2;
739     while (min <= max) {
740     int ret = strcasecmp(argv[0], cmd_mapping[cur].cmd);
741     if (!ret) {
742 sven 1.4 if (argc < cmd_mapping[cur].min_argc) return 0;
743 sven 1.2 if (cmd_mapping[cur].source && cmd_mapping[cur].source != src.what) return 0;
744 sven 1.4 return cmd_mapping[cur].function(bot, &src, argv[0], argc - 1, argv + 1, len);
745 sven 1.2 } else if (ret < 0) {
746 sven 1.4 max = cur - 1;
747 sven 1.2 } else {
748 sven 1.4 min = cur + 1;
749 sven 1.2 }
750     cur = (min + max) / 2;
751     }
752     putlog(LOG_MISC, "*", _("Botnet: Got unknown something from %s: %s"), bot->user->handle, argv[0]);
753 sven 1.1 return 0;
754     }
755    
756     static int idx_on_eof(void *client_data, int idx, int err, const char *errmsg)
757     {
758     bot_t *bot = client_data;
759    
760     if (!bot->bot) {
761     if (!bot->incoming) {
762     if (bot->user->flags & USER_LINKING_BOT) botnet_link_failed(bot->user, errmsg ? errmsg : "no error");
763     bot->user = NULL; /* Might already be in the process of being reconnected, forget about it. */
764     }
765     sockbuf_delete(idx);
766     } else {
767     putlog(LOG_MISC, "*", _("eof from %s (%s)."), bot->bot->name, errmsg ? errmsg : "no error");
768     botnet_delete(bot->bot, errmsg ? errmsg : "eof");
769     }
770    
771     return 0;
772     }
773    
774 sven 1.4 static int idx_on_delete(event_owner_t *owner, void *client_data)
775 sven 1.1 {
776     bot_t *bot = client_data;
777    
778     bot->idx = -1;
779     if (bot->bot) botnet_delete(bot->bot, _("Socket deleted."));
780     else if (!bot->incoming && bot->user && bot->user->flags & USER_LINKING_BOT) botnet_link_failed(bot->user, "Socket deleted.");
781    
782 sven 1.2 if (bot->pass) free(bot->pass);
783 sven 1.1 free(bot);
784    
785     return 0;
786     }
787    
788 sven 1.2 /*!
789     * \brief on_delete callback for ::botnet_bot_t.
790     *
791     * Gets called every time a directly linked bot created by this module is
792     * deleted. Marks it as deleted in the ::bot_t struct and deletes the
793     * ::sockbuf_t.
794     *
795     * \param owner The ::event_owner_t struct belonging to this bot. It's bot_owner.
796     * \param client_data Our callback data. The ::bot_t struct of the deleted bot.
797     * \return Always 0.
798     */
799    
800 sven 1.1 static int bot_on_delete(event_owner_t *owner, void *client_data)
801     {
802     bot_t *bot = client_data;
803    
804     bot->bot = NULL;
805     if (bot->idx >= 0) sockbuf_delete(bot->idx);
806    
807     return 0;
808     }
809    
810     static void bot_init()
811     {
812     int real_port;
813     void *config_root;
814    
815     botnet_config.port = 3333;
816    
817     config_root = config_get_root("eggdrop");
818     config_link_table(botnet_config_vars, config_root, "botnet", 0, NULL);
819     config_update_table(botnet_config_vars, config_root, "botnet", 0, NULL);
820    
821     listen_idx = egg_server(botnet_config.ip, botnet_config.port, &real_port);
822 sven 1.6 sockbuf_set_handler(listen_idx, &server_handler, NULL, &generic_owner);
823 sven 1.2
824     bind_add_simple(BTN_BOTNET_REQUEST_LINK, NULL, "eggdrop", do_link);
825 sven 1.1 }
826    
827     static int bot_close(int why)
828     {
829     void *config_root;
830    
831     config_root = config_get_root("eggdrop");
832     config_unlink_table(botnet_config_vars, config_root, "botnet", 0, NULL);
833    
834     sockbuf_delete(listen_idx);
835    
836 sven 1.2 bind_rem_simple(BTN_BOTNET_REQUEST_LINK, NULL, "eggdrop", do_link);
837    
838 sven 1.1 return 0;
839     }
840    
841     int botnet_LTX_start(egg_module_t *modinfo)
842     {
843 sven 1.4 bot_owner.module = sock_owner.module = generic_owner.module = modinfo;
844 sven 1.1 modinfo->name = "botnet";
845     modinfo->author = "eggdev";
846     modinfo->version = "1.0.0";
847     modinfo->description = "botnet support";
848     modinfo->close_func = bot_close;
849    
850     bot_init();
851    
852     return 0;
853     }

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23