static int tcl_boot(ClientData cd, Tcl_Interp *irp, int argc, char *argv[]) { char who[NOTENAMELEN + 1]; int i, ok = 0; BADARGS(2, 3, " user@bot ?reason?"); strncpyz(who, argv[1], sizeof who); if (strchr(who, '@') != NULL) { char whonick[HANDLEN + 1]; splitc(whonick, who, '@'); whonick[HANDLEN] = 0; if (!egg_strcasecmp(who, botnetnick)) strncpyz(who, whonick, sizeof who); else if (remote_boots > 0) { i = nextbot(who); if (i < 0) return TCL_OK; botnet_send_reject(i, botnetnick, NULL, whonick, who, argv[2] ? argv[2] : ""); } else return TCL_OK; } for (i = 0; i < dcc_total; i++) if (!ok && (dcc[i].type->flags & DCT_CANBOOT) && !egg_strcasecmp(dcc[i].nick, who)) { do_boot(i, botnetnick, argv[2] ? argv[2] : ""); ok = 1; } return TCL_OK; }
/* once a minute, send 'ping' to each bot -- no exceptions */ void check_botnet_pings() { int i; Context; for (i = 0; i < dcc_total; i++) if (dcc[i].type == &DCC_BOT) if (dcc[i].status & STAT_PINGED) { char s[1024]; putlog(LOG_BOTS, "*", "%s: %s", BOT_PINGTIMEOUT, dcc[i].nick); simple_sprintf(s, "%s: %s", BOT_PINGTIMEOUT, dcc[i].nick); chatout("*** %s\n", s); botnet_send_unlinked(i, dcc[i].nick, s); killsock(dcc[i].sock); lostdcc(i); } Context; for (i = 0; i < dcc_total; i++) if (dcc[i].type == &DCC_BOT) { botnet_send_ping(i); dcc[i].status |= STAT_PINGED; } Context; for (i = 0; i < dcc_total; i++) if ((dcc[i].type == &DCC_BOT) && (dcc[i].status & STAT_LEAF)) { tand_t *bot, *via = findbot(dcc[i].nick); for (bot = tandbot; bot; bot = bot->next) { if ((via == bot->via) && (bot != via)) { /* not leaflike behavior */ if (dcc[i].status & STAT_WARNED) { char s[1024]; putlog(LOG_BOTS, "*", "%s %s (%s).", BOT_DISCONNECTED, dcc[i].nick, BOT_BOTNOTLEAFLIKE); dprintf(i, "bye\n"); simple_sprintf(s, "%s %s (%s)", BOT_DISCONNECTED, dcc[i].nick, BOT_BOTNOTLEAFLIKE); chatout("*** %s\n", s); botnet_send_unlinked(i, dcc[i].nick, s); killsock(dcc[i].sock); lostdcc(i); } else { botnet_send_reject(i, botnetnick, NULL, bot->bot, NULL, NULL); dcc[i].status |= STAT_WARNED; } } else dcc[i].status &= ~STAT_WARNED; } } Context; }
/* reject <from> <bot> */ static void bot_reject(int idx, char *par) { char *from = NULL, *who = NULL, *destbot = NULL, *frombot = NULL; struct userrec *u = NULL; int i; from = newsplit(&par); frombot = strchr(from, '@'); if (frombot) frombot++; else frombot = from; i = nextbot(frombot); if (i != idx) { fake_alert(idx, "direction", frombot, "reject"); return; } who = newsplit(&par); if (!(destbot = strchr(who, '@'))) { /* Rejecting a bot */ i = nextbot(who); if (i < 0) { botnet_send_priv(idx, conf.bot->nick, from, NULL, "Can't unlink %s (doesn't exist)", who); } else if (!strcasecmp(dcc[i].nick, who)) { char s[1024]; /* I'm the connection to the rejected bot */ putlog(LOG_BOTS, "*", "%s rejected %s", from, dcc[i].nick); dprintf(i, "bye %s\n", par[0] ? par : "rejected"); simple_sprintf(s, "Disconnected %s (%s: %s)", dcc[i].nick, from, par[0] ? par : "rejected"); chatout("*** %s\n", s); botnet_send_unlinked(i, dcc[i].nick, s); killsock(dcc[i].sock); lostdcc(i); } else { if (i >= 0) botnet_send_reject(i, from, NULL, who, NULL, par); } } else { /* Rejecting user */ *destbot++ = 0; if (!strcasecmp(destbot, conf.bot->nick)) { /* Kick someone here! */ int ok = 0; for (i = 0; i < dcc_total; i++) { if (dcc[i].type && dcc[i].simul == -1 && !strcasecmp(who, dcc[i].nick) && (dcc[i].type->flags & DCT_CHAT)) { u = get_user_by_handle(userlist, from); if (u) { if (!whois_access(u, dcc[idx].user)) { add_note(from, conf.bot->nick, "Sorry, you cannot boot them.", -1, 0); return; } do_boot(i, from, par); putlog(LOG_CMDS, "*", "#%s# boot %s (%s)", from, who, par[0] ? par : "No reason"); ok = 1; } } } } else { i = nextbot(destbot); *--destbot = '@'; if (i >= 0) botnet_send_reject(i, from, NULL, who, NULL, par); } } }
/* reject <from> <bot> */ static void bot_reject(int idx, char *par) { char *from, *who, *destbot, *frombot; struct userrec *u; int i; if (bot_flags(dcc[idx].user) & BOT_ISOLATE) return; from = newsplit(&par); frombot = strchr(from, '@'); if (frombot) frombot++; else frombot = from; i = nextbot(frombot); if (i != idx) { fake_alert(idx, "direction", frombot); return; } who = newsplit(&par); if (!(destbot = strchr(who, '@'))) { /* Rejecting a bot */ i = nextbot(who); if (i < 0) { botnet_send_priv(idx, botnetnick, from, NULL, "%s %s (%s)", BOT_CANTUNLINK, who, BOT_DOESNTEXIST); } else if (!egg_strcasecmp(dcc[i].nick, who)) { char s[1024]; /* I'm the connection to the rejected bot */ putlog(LOG_BOTS, "*", "%s %s %s", from, MISC_REJECTED, dcc[i].nick); dprintf(i, "bye %s\n", par[0] ? par : MISC_REJECTED); simple_sprintf(s, "%s %s (%s: %s)", MISC_DISCONNECTED, dcc[i].nick, from, par[0] ? par : MISC_REJECTED); chatout("*** %s\n", s); botnet_send_unlinked(i, dcc[i].nick, s); killsock(dcc[i].sock); lostdcc(i); } else { if (i >= 0) botnet_send_reject(i, from, NULL, who, NULL, par); } } else { /* Rejecting user */ *destbot++ = 0; if (!egg_strcasecmp(destbot, botnetnick)) { /* Kick someone here! */ int ok = 0; if (remote_boots == 1) { frombot = strchr(from, '@'); if (frombot == NULL) frombot = from; else frombot++; u = get_user_by_handle(userlist, frombot); if (!(bot_flags(u) & BOT_SHARE)) { add_note(from, botnetnick, "No non sharebot boots.", -1, 0); ok = 1; } } else if (remote_boots == 0) { botnet_send_priv(idx, botnetnick, from, NULL, "%s", BOT_NOREMOTEBOOT); ok = 1; } for (i = 0; (i < dcc_total) && !ok; i++) if ((!egg_strcasecmp(who, dcc[i].nick)) && (dcc[i].type->flags & DCT_CHAT)) { u = get_user_by_handle(userlist, dcc[i].nick); if (u && (u->flags & USER_OWNER)) { add_note(from, botnetnick, BOT_NOOWNERBOOT, -1, 0); return; } do_boot(i, from, par); ok = 1; putlog(LOG_CMDS, "*", "#%s# boot %s (%s)", from, who, par[0] ? par : "No reason"); } } else { i = nextbot(destbot); *--destbot = '@'; if (i >= 0) botnet_send_reject(i, from, NULL, who, NULL, par); } } }
/* Newbot next share? */ static void bot_nlinked(int idx, char *par) { char *newbot, *next, *p, s[1024], x; int bogus = 0, i; struct userrec *u; newbot = newsplit(&par); next = newsplit(&par); s[0] = 0; if (!next[0]) { putlog(LOG_BOTS, "*", "Invalid eggnet protocol from %s (zapfing)", dcc[idx].nick); simple_sprintf(s, "%s %s (%s)", MISC_DISCONNECTED, dcc[idx].nick, MISC_INVALIDBOT); dprintf(idx, "error invalid eggnet protocol for 'nlinked'\n"); } else if ((in_chain(newbot)) || (!egg_strcasecmp(newbot, botnetnick))) { /* Loop! */ putlog(LOG_BOTS, "*", "%s %s (mutual: %s)", BOT_LOOPDETECT, dcc[idx].nick, newbot); simple_sprintf(s, "%s %s: disconnecting %s", MISC_LOOP, newbot, dcc[idx].nick); dprintf(idx, "error Loop (%s)\n", newbot); } if (!s[0]) { for (p = newbot; *p; p++) if ((*p < 32) || (*p == 127) || ((p - newbot) >= HANDLEN)) bogus = 1; i = nextbot(next); if (i != idx) bogus = 1; } if (bogus) { putlog(LOG_BOTS, "*", "%s %s! (%s -> %s)", BOT_BOGUSLINK, dcc[idx].nick, next, newbot); simple_sprintf(s, "%s: %s %s", BOT_BOGUSLINK, dcc[idx].nick, MISC_DISCONNECTED); dprintf(idx, "error %s (%s -> %s)\n", BOT_BOGUSLINK, next, newbot); } if (bot_flags(dcc[idx].user) & BOT_LEAF) { putlog(LOG_BOTS, "*", "%s %s (%s %s)", BOT_DISCONNLEAF, dcc[idx].nick, newbot, BOT_LINKEDTO); simple_sprintf(s, "%s %s (to %s): %s", BOT_ILLEGALLINK, dcc[idx].nick, newbot, MISC_DISCONNECTED); dprintf(idx, "error %s\n", BOT_YOUREALEAF); } if (s[0]) { chatout("*** %s\n", s); botnet_send_unlinked(idx, dcc[idx].nick, s); dprintf(idx, "bye %s\n", BOT_ILLEGALLINK); killsock(dcc[idx].sock); lostdcc(idx); return; } x = par[0]; if (x) par++; else x = '-'; #ifndef NO_OLD_BOTNET if (dcc[idx].u.bot->numver < NEAT_BOTNET) i = atoi(par); else #endif i = base64_to_int(par); botnet_send_nlinked(idx, newbot, next, x, i); if (x == '!') { chatout("*** (%s) %s %s.\n", next, NET_LINKEDTO, newbot); x = '-'; } addbot(newbot, dcc[idx].nick, next, x, i); check_tcl_link(newbot, next); u = get_user_by_handle(userlist, newbot); if (bot_flags(u) & BOT_REJECT) { botnet_send_reject(idx, botnetnick, NULL, newbot, NULL, NULL); putlog(LOG_BOTS, "*", "%s %s %s %s", BOT_REJECTING, newbot, MISC_FROM, dcc[idx].nick); } }