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

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

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


Revision 1.5 - (show annotations) (download) (as text)
Sat Oct 27 19:55:51 2007 UTC (12 years, 11 months ago) by sven
Branch: MAIN
Changes since 1.4: +152 -3 lines
File MIME type: text/x-chdr
Full botnet support.
The login needs some work, the netburst handling sucks and nobody pings
anyone but it works.

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

webmaster@eggheads.org
ViewVC Help
Powered by ViewVC 1.1.23