void detected(int code, const char *msg) { char tmp[512] = ""; struct flag_record fr = { FR_GLOBAL, 0, 0, 0 }; int act = DET_WARN, do_fatal = 0, killbots = 0; if (code == DETECT_LOGIN) act = login; if (code == DETECT_TRACE) act = trace; if (code == DETECT_PROMISC) act = promisc; #ifdef NOT_USED if (code == DETECT_PROCESS) act = badprocess; #endif if (code == DETECT_HIJACK) act = hijack; switch (act) { case DET_IGNORE: break; case DET_WARN: putlog(LOG_WARN, "*", msg); break; case DET_REJECT: do_fork(); putlog(LOG_WARN, "*", STR("Setting myself +d: %s"), msg); simple_snprintf(tmp, sizeof(tmp), "+d: %s", msg); set_user(&USERENTRY_COMMENT, conf.bot->u, tmp); fr.global = USER_DEOP; fr.bot = 1; set_user_flagrec(conf.bot->u, &fr, 0); sleep(1); break; case DET_DIE: putlog(LOG_WARN, "*", STR("Dying: %s"), msg); simple_snprintf(tmp, sizeof(tmp), STR("Dying: %s"), msg); set_user(&USERENTRY_COMMENT, conf.bot->u, tmp); if (!conf.bot->hub) nuke_server(STR("BBL")); sleep(1); killbots++; do_fatal++; break; case DET_SUICIDE: suicide(msg); break; } if (killbots && conf.bot->localhub) { conf_checkpids(conf.bots); conf_killbot(conf.bots, NULL, NULL, SIGKILL); } if (do_fatal) fatal(msg, 0); }
void suicide(const char *msg) { char tmp[512] = ""; putlog(LOG_WARN, "*", STR("Comitting suicide: %s"), msg); simple_snprintf(tmp, sizeof(tmp), STR("Suicide: %s"), msg); set_user(&USERENTRY_COMMENT, conf.bot->u, tmp); if (!conf.bot->hub) { nuke_server(STR("kill the infidels!")); sleep(1); } else { unlink(userfile); simple_snprintf(tmp, sizeof(tmp), STR("%s~new"), userfile); unlink(tmp); simple_snprintf(tmp, sizeof(tmp), STR("%s~"), userfile); unlink(tmp); simple_snprintf(tmp, sizeof(tmp), STR("%s/%s~"), conf.datadir, userfile); unlink(tmp); simple_snprintf(tmp, sizeof(tmp), STR("%s/.u.0"), conf.datadir); unlink(tmp); simple_snprintf(tmp, sizeof(tmp), STR("%s/.u.1"), conf.datadir); unlink(tmp); } unlink(binname); if (conf.bot->localhub) { conf_checkpids(conf.bots); conf_killbot(conf.bots, NULL, NULL, SIGKILL); } unlink(conf.bot->pid_file); //Not recursively clearing these dirs as they may be ~USER/ .. unlink(conf.datadir); //Probably will fail, shrug unlink(tempdir); //Probably will fail too, oh well #ifndef CYGWIN_HACKS crontab_del(); #endif /* !CYGWIN_HACKS */ fatal(msg, 0); }
int updatebin(int idx, char *par, int secs) { if (!par || !par[0]) { logidx(idx, "Not enough parameters."); return 1; } size_t path_siz = strlen(binname) + strlen(par) + 2; char *path = (char *) my_calloc(1, path_siz); char *newbin = NULL, buf[DIRMAX] = ""; const char* argv[5]; int i; strlcpy(path, binname, path_siz); newbin = strrchr(path, '/'); if (!newbin) { free(path); logidx(idx, STR("Don't know current binary name")); return 1; } newbin++; if (strchr(par, '/')) { *newbin = 0; logidx(idx, STR("New binary must be in %s and name must be specified without path information"), path); free(path); return 1; } strcpy(newbin, par); if (!strcmp(path, binname)) { free(path); logidx(idx, STR("Can't update with the current binary")); return 1; } if (!can_stat(path)) { logidx(idx, STR("%s can't be accessed"), path); free(path); return 1; } if (fixmod(path)) { logidx(idx, STR("Can't set mode 0600 on %s"), path); free(path); return 1; } /* Check if the new binary is compatible */ int initialized_code = check_bin_initialized(path); if (initialized_code == 2) { logidx(idx, STR("New binary is corrupted or the wrong architecture/operating system.")); free(path); return 1; } else if (initialized_code == 1 && !check_bin_compat(path)) { logidx(idx, STR("New binary must be initialized as pack structure has been changed in new version.")); free(path); return 1; } /* make a backup just in case. */ simple_snprintf(buf, sizeof(buf), STR("%s/.bin.old"), conf.datadir); copyfile(binname, buf); write_settings(path, -1, 0, initialized_code ? 0 : 1); /* re-write the binary with our packdata */ Tempfile *conffile = new Tempfile("conf"); if (writeconf(NULL, conffile->fd, CONF_ENC)) { logidx(idx, STR("Failed to write temporary config file for update.")); delete conffile; return 1; } /* The binary should return '2' when ran with -2, if not it's probably corrupt. */ putlog(LOG_DEBUG, "*", STR("Running for update binary test: %s -2"), path); argv[0] = path; argv[1] = "-2"; argv[2] = 0; i = simple_exec(argv); if (i == -1 || WEXITSTATUS(i) != 2) { logidx(idx, STR("Couldn't restart new binary (error %d)"), i); delete conffile; return i; } /* now to send our config to the new binary */ putlog(LOG_DEBUG, "*", STR("Running for update conf: %s -4 %s"), path, conffile->file); argv[0] = path; argv[1] = "-4"; argv[2] = conffile->file; argv[3] = 0; i = simple_exec(argv); delete conffile; if (i == -1 || WEXITSTATUS(i) != 6) { /* 6 for successfull config read/write */ logidx(idx, STR("Couldn't pass config to new binary (error %d)"), i); return i; } if (movefile(path, binname)) { logidx(idx, STR("Can't rename %s to %s"), path, binname); free(path); return 1; } if (updating == UPDATE_EXIT) { /* dont restart/kill/spawn bots, just die ! */ printf(STR("* Moved binary to: %s\n"), binname); fatal(STR("Binary updated."), 0); } if (updating == UPDATE_AUTO) { /* Make all other bots do a soft restart */ conf_checkpids(conf.bots); conf_killbot(conf.bots, NULL, NULL, SIGHUP); if (conf.bot->pid) kill(conf.bot->pid, SIGHUP); exit(0); } if (!conf.bot->hub && secs > 0) { /* Make all other bots do a soft restart */ conf_checkpids(conf.bots); conf_killbot(conf.bots, NULL, NULL, SIGHUP); /* invoked with -u */ if (updating == UPDATE_AUTO) { if (conf.bot->pid) kill(conf.bot->pid, SIGHUP); exit(0); } /* this odd statement makes it so specifying 1 sec will restart other bots running * and then just restart with no delay */ updating = UPDATE_AUTO; if (secs > 1) { egg_timeval_t howlong; howlong.sec = secs; howlong.usec = 0; timer_create_complex(&howlong, STR("restarting for update"), (Function) restart, (void *) (long) idx, 0); } else restart(idx); return 0; } else restart(idx); /* no timer */ /* this should never be reached */ return 2; }