binary.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /* I hereby release this into the Public Domain - Bryan Drewery */
  2. /*
  3. * binary.c -- handles:
  4. * misc update functions
  5. * md5 hash verifying
  6. *
  7. */
  8. #include "common.h"
  9. #include "binary.h"
  10. #include "settings.h"
  11. #include "crypt.h"
  12. #include "shell.h"
  13. #include "misc.h"
  14. #include "main.h"
  15. #include "misc_file.h"
  16. #include "tandem.h"
  17. #include "botnet.h"
  18. #include "userrec.h"
  19. #include <sys/wait.h>
  20. #include <sys/types.h>
  21. #include <sys/mman.h>
  22. #include <signal.h>
  23. #include <sys/stat.h>
  24. #include <fcntl.h>
  25. settings_t settings = {
  26. "\200\200\200\200\200\200\200\200\200\200\200\200\200\200\200",
  27. /* -- STATIC -- */
  28. "", "", "", "", "", "", "", "", "", "",
  29. /* -- DYNAMIC -- */
  30. "", "", "", "", "", "", "", "", "", "", "", "", "", "",
  31. /* -- PADDING */
  32. ""
  33. };
  34. static void edpack(settings_t *, const char *, int);
  35. #ifdef DEBUG
  36. static void tellconfig(settings_t *);
  37. #endif
  38. #define PACK_ENC 1
  39. #define PACK_DEC 2
  40. int checked_bin_buf = 0;
  41. #define MMAP_LOOP(_offset, _block_len, _total, _len) \
  42. for ((_offset) = 0; \
  43. (_offset) < (_total); \
  44. (_offset) += (_block_len), \
  45. (_len) = ((_total) - (_offset)) < (_block_len) ? \
  46. ((_total) - (_offset)) : \
  47. (_block_len) \
  48. )
  49. #define MMAP_READ(_map, _dest, _offset, _len) \
  50. memcpy((_dest), &(_map)[(_offset)], (_len)); \
  51. (_offset) += (_len);
  52. static char *
  53. bin_checksum(const char *fname, int todo)
  54. {
  55. MD5_CTX ctx;
  56. static char hash[MD5_HASH_LENGTH + 1] = "";
  57. unsigned char md5out[MD5_HASH_LENGTH + 1] = "", buf[PREFIXLEN + 1] = "";
  58. int fd = -1;
  59. size_t len = 0, offset = 0, size = 0, newpos = 0;
  60. unsigned char *map = NULL, *outmap = NULL;
  61. char *fname_bak = NULL;
  62. Tempfile *newbin = NULL;
  63. MD5_Init(&ctx);
  64. ++checked_bin_buf;
  65. hash[0] = 0;
  66. fixmod(fname);
  67. if (todo == GET_CHECKSUM) {
  68. fd = open(fname, O_RDONLY);
  69. if (fd == -1) werr(ERR_BINSTAT);
  70. size = lseek(fd, 0, SEEK_END);
  71. map = (unsigned char*) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
  72. if ((void*)map == MAP_FAILED) goto fatal;
  73. MMAP_LOOP(offset, sizeof(buf) - 1, size, len) {
  74. if (!memcmp(&map[offset], &settings.prefix, PREFIXLEN))
  75. break;
  76. }
  77. MD5_Update(&ctx, map, offset);
  78. /* Hash everything after the packdata too */
  79. offset += sizeof(settings_t);
  80. MD5_Update(&ctx, &map[offset], size - offset);
  81. MD5_Final(md5out, &ctx);
  82. strlcpy(hash, btoh(md5out, MD5_DIGEST_LENGTH), sizeof(hash));
  83. OPENSSL_cleanse(&ctx, sizeof(ctx));
  84. munmap(map, size);
  85. close(fd);
  86. }
  87. if (todo == GET_CONF) {
  88. fd = open(fname, O_RDONLY);
  89. if (fd == -1) werr(ERR_BINSTAT);
  90. size = lseek(fd, 0, SEEK_END);
  91. map = (unsigned char*) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
  92. if ((void*)map == MAP_FAILED) goto fatal;
  93. /* Find the packdata */
  94. MMAP_LOOP(offset, sizeof(buf) - 1, size, len) {
  95. if (!memcmp(&map[offset], &settings.prefix, PREFIXLEN))
  96. break;
  97. }
  98. MD5_Update(&ctx, map, offset);
  99. /* Hash everything after the packdata too */
  100. MD5_Update(&ctx, &map[offset + sizeof(settings_t)], size - (offset + sizeof(settings_t)));
  101. MD5_Final(md5out, &ctx);
  102. strlcpy(hash, btoh(md5out, MD5_DIGEST_LENGTH), sizeof(hash));
  103. OPENSSL_cleanse(&ctx, sizeof(ctx));
  104. settings_t newsettings;
  105. /* Read the settings struct into newsettings */
  106. MMAP_READ(map, &newsettings, offset, sizeof(settings));
  107. /* Decrypt the new data */
  108. edpack(&newsettings, hash, PACK_DEC);
  109. OPENSSL_cleanse(hash, sizeof(hash));
  110. /* Copy over only the dynamic data, leaving the pack config static */
  111. memcpy(&settings.bots, &newsettings.bots, SIZE_CONF);
  112. OPENSSL_cleanse(&newsettings, sizeof(settings_t));
  113. munmap(map, size);
  114. close(fd);
  115. return ".";
  116. }
  117. if (todo & WRITE_CHECKSUM) {
  118. newbin = new Tempfile("bin", 0);
  119. size = strlen(fname) + 2;
  120. fname_bak = (char *) my_calloc(1, size);
  121. simple_snprintf(fname_bak, size, "%s~", fname);
  122. fd = open(fname, O_RDONLY);
  123. if (fd == -1) werr(ERR_BINSTAT);
  124. size = lseek(fd, 0, SEEK_END);
  125. map = (unsigned char*) mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
  126. if ((void*)map == MAP_FAILED) goto fatal;
  127. /* Find settings struct in original binary */
  128. MMAP_LOOP(offset, sizeof(buf) - 1, size, len) {
  129. if (!memcmp(&map[offset], &settings.prefix, PREFIXLEN))
  130. break;
  131. }
  132. MD5_Update(&ctx, map, offset);
  133. /* Hash everything after the packdata too */
  134. MD5_Update(&ctx, &map[offset + sizeof(settings_t)], size - (offset + sizeof(settings_t)));
  135. MD5_Final(md5out, &ctx);
  136. strlcpy(hash, btoh(md5out, MD5_DIGEST_LENGTH), sizeof(hash));
  137. OPENSSL_cleanse(&ctx, sizeof(ctx));
  138. strlcpy(settings.hash, hash, sizeof(settings.hash));
  139. /* encrypt the entire struct with the hash (including hash) */
  140. edpack(&settings, hash, PACK_ENC);
  141. //Don't clear hash if requested during the write.
  142. if (!(todo & GET_CHECKSUM))
  143. OPENSSL_cleanse(hash, sizeof(hash));
  144. /* Copy everything up to this point into the new binary (including the settings header/prefix) */
  145. outmap = (unsigned char*) mmap(0, size, PROT_WRITE, MAP_SHARED, newbin->fd, 0);
  146. if ((void*)outmap == MAP_FAILED) goto fatal;
  147. if (lseek(newbin->fd, size - 1, SEEK_SET) == -1) goto fatal;
  148. if (write(newbin->fd, "", 1) != 1) goto fatal;
  149. offset += PREFIXLEN;
  150. memcpy(outmap, map, offset);
  151. newpos = offset;
  152. if (todo & WRITE_PACK) {
  153. /* Now copy in our encrypted settings struct */
  154. memcpy(&outmap[newpos], &settings.hash, SIZE_PACK);
  155. #ifdef DEBUG
  156. sdprintf(STR("writing pack: %d\n"), SIZE_PACK);
  157. #endif
  158. } else {
  159. /* Just copy the original pack data to the new binary */
  160. memcpy(&outmap[newpos], &map[offset], SIZE_PACK);
  161. }
  162. offset += SIZE_PACK;
  163. newpos += SIZE_PACK;
  164. if (todo & WRITE_CONF) {
  165. /* Copy in the encrypted conf data */
  166. memcpy(&outmap[newpos], &settings.bots, SIZE_CONF);
  167. #ifdef DEBUG
  168. sdprintf(STR("writing conf: %d\n"), SIZE_CONF);
  169. #endif
  170. } else {
  171. /* Just copy the original conf data to the new binary */
  172. memcpy(&outmap[newpos], &map[offset], SIZE_CONF);
  173. }
  174. newpos += SIZE_CONF;
  175. offset += SIZE_CONF;
  176. /* Write the rest of the binary */
  177. memcpy(&outmap[newpos], &map[offset], size - offset);
  178. newpos += size - offset;
  179. offset += size - offset;
  180. munmap(map, size);
  181. close(fd);
  182. munmap(outmap, size);
  183. newbin->my_close();
  184. if (size != newpos) {
  185. delete newbin;
  186. fatal(STR("Binary corrupted"), 0);
  187. }
  188. if (movefile(fname, fname_bak)) {
  189. printf(STR("Failed to move file (%s -> %s): %s\n"), fname, fname_bak, strerror(errno));
  190. delete newbin;
  191. fatal("", 0);
  192. }
  193. if (movefile(newbin->file, fname)) {
  194. printf(STR("Failed to move file (%s -> %s): %s\n"), newbin->file, fname, strerror(errno));
  195. delete newbin;
  196. fatal("", 0);
  197. }
  198. fixmod(fname);
  199. unlink(fname_bak);
  200. delete newbin;
  201. return hash;
  202. fatal:
  203. if ((void*)map != MAP_FAILED)
  204. munmap(map, size);
  205. if (fd != -1)
  206. close(fd);
  207. if ((void*)outmap != MAP_FAILED)
  208. munmap(outmap, size);
  209. delete newbin;
  210. werr(ERR_BINSTAT);
  211. }
  212. return hash;
  213. }
  214. static int
  215. features_find(const char *buffer)
  216. {
  217. if (!egg_strcasecmp(buffer, STR("no_take")))
  218. return FEATURE_NO_TAKE;
  219. else if (!egg_strcasecmp(buffer, STR("no_mdop")))
  220. return FEATURE_NO_MDOP;
  221. return 0;
  222. }
  223. static int
  224. readcfg(const char *cfgfile)
  225. {
  226. FILE *f = NULL;
  227. if ((f = fopen(cfgfile, "r")) == NULL) {
  228. printf(STR("Error: Can't open '%s' for reading\n"), cfgfile);
  229. exit(1);
  230. }
  231. char *buffer = NULL, *p = NULL;
  232. int skip = 0, line = 0, feature = 0;
  233. printf(STR("Reading '%s' "), cfgfile);
  234. while ((!feof(f)) && ((buffer = step_thru_file(f)) != NULL)) {
  235. ++line;
  236. if ((*buffer)) {
  237. if (strchr(buffer, '\n'))
  238. *(char *) strchr(buffer, '\n') = 0;
  239. if ((skipline(buffer, &skip)))
  240. continue;
  241. if ((strchr(buffer, '<') || strchr(buffer, '>')) && !strstr(buffer, "SALT")) {
  242. printf(STR(" Failed\n"));
  243. printf(STR("%s:%d: error: Look at your configuration file again...\n"), cfgfile, line);
  244. // exit(1);
  245. }
  246. p = strchr(buffer, ' ');
  247. while (p && (strchr(LISTSEPERATORS, p[0])))
  248. *p++ = 0;
  249. if (p) {
  250. if (!egg_strcasecmp(buffer, STR("packname"))) {
  251. strlcpy(settings.packname, trim(p), sizeof settings.packname);
  252. printf(".");
  253. } else if (!egg_strcasecmp(buffer, STR("shellhash"))) {
  254. strlcpy(settings.shellhash, trim(p), sizeof settings.shellhash);
  255. printf(".");
  256. } else if (!egg_strcasecmp(buffer, STR("dccprefix"))) {
  257. strlcpy(settings.dcc_prefix, trim(p), sizeof settings.dcc_prefix);
  258. printf(".");
  259. } else if (!egg_strcasecmp(buffer, STR("owner"))) {
  260. strlcat(settings.owners, trim(p), sizeof(settings.owners));
  261. strlcat(settings.owners, ",", sizeof(settings.owners));
  262. printf(".");
  263. } else if (!egg_strcasecmp(buffer, STR("owneremail"))) {
  264. strlcat(settings.owneremail, trim(p), sizeof(settings.owneremail));
  265. strlcat(settings.owneremail, ",", sizeof(settings.owneremail));
  266. printf(".");
  267. } else if (!egg_strcasecmp(buffer, STR("hub"))) {
  268. strlcat(settings.hubs, trim(p), sizeof(settings.hubs));
  269. strlcat(settings.hubs, ",", sizeof(settings.hubs));
  270. printf(".");
  271. } else if (!egg_strcasecmp(buffer, STR("salt1"))) {
  272. strlcat(settings.salt1, trim(p), sizeof(settings.salt1));
  273. printf(".");
  274. } else if (!egg_strcasecmp(buffer, STR("salt2"))) {
  275. strlcat(settings.salt2, trim(p), sizeof(settings.salt2));
  276. printf(".");
  277. } else {
  278. printf("%s %s\n", buffer, p);
  279. printf(",");
  280. }
  281. } else { /* SINGLE DIRECTIVES */
  282. if ((feature = features_find(buffer))) {
  283. int features = atol(settings.features);
  284. features |= feature;
  285. simple_snprintf(settings.features, sizeof(settings.features), "%d", features);
  286. printf(".");
  287. }
  288. }
  289. }
  290. buffer = NULL;
  291. }
  292. if (f)
  293. fclose(f);
  294. if (!settings.salt1[0] || !settings.salt2[0]) {
  295. /* Write salts back to the cfgfile */
  296. char salt1[SALT1LEN + 1] = "", salt2[SALT2LEN + 1] = "";
  297. printf(STR("Creating Salts"));
  298. if ((f = fopen(cfgfile, "a")) == NULL) {
  299. printf(STR("Cannot open cfgfile for appending.. aborting\n"));
  300. exit(1);
  301. }
  302. make_rand_str(salt1, SALT1LEN);
  303. make_rand_str(salt2, SALT2LEN);
  304. salt1[sizeof salt1 - 1] = salt2[sizeof salt2 - 1] = 0;
  305. strlcpy(settings.salt1, salt1, sizeof(settings.salt1));
  306. strlcpy(settings.salt2, salt2, sizeof(settings.salt2));
  307. fprintf(f, STR("SALT1 %s\n"), salt1);
  308. fprintf(f, STR("SALT2 %s\n"), salt2);
  309. fflush(f);
  310. fclose(f);
  311. }
  312. printf(STR(" Success\n"));
  313. return 1;
  314. }
  315. static void edpack(settings_t *incfg, const char *in_hash, int what)
  316. {
  317. char *tmp = NULL, *hash = (char *) in_hash, nhash[51] = "";
  318. unsigned char *(*enc_dec_string)(const char *, unsigned char *, size_t *);
  319. size_t len = 0;
  320. if (what == PACK_ENC)
  321. enc_dec_string = encrypt_binary;
  322. else
  323. enc_dec_string = decrypt_binary;
  324. #define dofield(_field) do { \
  325. if (_field) { \
  326. len = sizeof(_field) - 1; \
  327. tmp = (char *) enc_dec_string(hash, (unsigned char *) _field, &len); \
  328. if (what == PACK_ENC) \
  329. egg_memcpy(_field, tmp, len); \
  330. else \
  331. simple_snprintf(_field, sizeof(_field), "%s", tmp); \
  332. OPENSSL_cleanse(tmp, len); \
  333. free(tmp); \
  334. } \
  335. } while (0)
  336. #define dohash(_field) do { \
  337. if (what == PACK_ENC) \
  338. strlcat(nhash, _field, sizeof(nhash)); \
  339. dofield(_field); \
  340. if (what == PACK_DEC) \
  341. strlcat(nhash, _field, sizeof(nhash)); \
  342. } while (0)
  343. #define update_hash() do { \
  344. MD5(NULL); \
  345. hash = MD5(nhash); \
  346. OPENSSL_cleanse(nhash, sizeof(nhash)); \
  347. nhash[0] = 0; \
  348. } while (0)
  349. /* -- STATIC -- */
  350. dohash(incfg->hash);
  351. dohash(incfg->packname);
  352. update_hash();
  353. dohash(incfg->shellhash);
  354. update_hash();
  355. dofield(incfg->dcc_prefix);
  356. dofield(incfg->features);
  357. dofield(incfg->owners);
  358. dofield(incfg->owneremail);
  359. dofield(incfg->hubs);
  360. dohash(incfg->salt1);
  361. dohash(incfg->salt2);
  362. update_hash();
  363. /* -- DYNAMIC -- */
  364. dofield(incfg->bots);
  365. dofield(incfg->uid);
  366. dofield(incfg->autouname);
  367. dofield(incfg->pscloak);
  368. dofield(incfg->autocron);
  369. dofield(incfg->watcher);
  370. dofield(incfg->uname);
  371. dofield(incfg->username);
  372. dofield(incfg->datadir);
  373. dofield(incfg->homedir);
  374. dofield(incfg->binpath);
  375. dofield(incfg->binname);
  376. dofield(incfg->portmin);
  377. dofield(incfg->portmax);
  378. OPENSSL_cleanse(nhash, sizeof(nhash));
  379. #undef dofield
  380. #undef dohash
  381. #undef update_hash
  382. }
  383. #ifdef DEBUG
  384. static void
  385. tellconfig(settings_t *incfg)
  386. {
  387. #define dofield(_field) printf("%s: %s\n", #_field, _field);
  388. // -- STATIC --
  389. dofield(incfg->hash);
  390. dofield(incfg->packname);
  391. dofield(incfg->shellhash);
  392. dofield(incfg->dcc_prefix);
  393. dofield(incfg->features);
  394. dofield(incfg->owners);
  395. dofield(incfg->owneremail);
  396. dofield(incfg->hubs);
  397. // dofield(incfg->salt1);
  398. // dofield(incfg->salt2);
  399. // -- DYNAMIC --
  400. dofield(incfg->bots);
  401. dofield(incfg->uid);
  402. dofield(incfg->autouname);
  403. dofield(incfg->pscloak);
  404. dofield(incfg->autocron);
  405. dofield(incfg->watcher);
  406. dofield(incfg->uname);
  407. dofield(incfg->username);
  408. dofield(incfg->datadir);
  409. dofield(incfg->homedir);
  410. dofield(incfg->binpath);
  411. dofield(incfg->binname);
  412. dofield(incfg->portmin);
  413. dofield(incfg->portmax);
  414. #undef dofield
  415. }
  416. #endif
  417. void
  418. check_sum(const char *fname, const char *cfgfile)
  419. {
  420. if (!settings.hash[0]) {
  421. if (!cfgfile)
  422. fatal(STR("Binary not initialized."), 0);
  423. readcfg(cfgfile);
  424. // tellconfig(&settings);
  425. if (bin_checksum(fname, WRITE_CHECKSUM|WRITE_CONF|WRITE_PACK))
  426. printf(STR("* Wrote settings to binary.\n"));
  427. exit(0);
  428. } else {
  429. char *hash = bin_checksum(fname, GET_CHECKSUM);
  430. // tellconfig(&settings);
  431. edpack(&settings, hash, PACK_DEC);
  432. INIT_SALTS;
  433. OPENSSL_cleanse(settings.salt1, sizeof(settings.salt1));
  434. OPENSSL_cleanse(settings.salt2, sizeof(settings.salt2));
  435. #ifdef DEBUG
  436. tellconfig(&settings);
  437. #endif
  438. int n = strcmp(settings.hash, hash);
  439. OPENSSL_cleanse(settings.hash, sizeof(settings.hash));
  440. OPENSSL_cleanse(hash, strlen(hash));
  441. if (n) {
  442. unlink(fname);
  443. fatal(STR("!! Invalid binary"), 0);
  444. }
  445. }
  446. }
  447. static bool check_bin_initialized(const char *fname)
  448. {
  449. int i = 0;
  450. size_t len = strlen(shell_escape(fname)) + 3 + 1;
  451. char *path = (char *) my_calloc(1, len);
  452. simple_snprintf(path, len, STR("%s -p"), shell_escape(fname));
  453. i = system(path);
  454. free(path);
  455. if (i != -1 && WEXITSTATUS(i) == 4)
  456. return 1;
  457. return 0;
  458. }
  459. void write_settings(const char *fname, int die, bool doconf)
  460. {
  461. char *hash = NULL;
  462. int bits = WRITE_CHECKSUM;
  463. /* see if the binary is already initialized or not */
  464. bool initialized = check_bin_initialized(fname);
  465. /* only write pack data if the binary is uninitialized
  466. * otherwise, assume it has similar/correct/updated pack data
  467. */
  468. if (!initialized)
  469. bits |= WRITE_PACK;
  470. if (doconf)
  471. bits |= WRITE_CONF;
  472. /* only bother writing anything if we have pack or doconf, checksum is worthless to write out */
  473. if (bits & (WRITE_PACK|WRITE_CONF)) {
  474. // Also get the checksum
  475. if (die == -1)
  476. bits |= GET_CHECKSUM;
  477. const char salt1[] = SALT1;
  478. const char salt2[] = SALT2;
  479. strlcpy(settings.salt1, salt1, sizeof(settings.salt1));
  480. strlcpy(settings.salt2, salt2, sizeof(settings.salt2));
  481. if ((hash = bin_checksum(fname, bits))) {
  482. printf(STR("* Wrote %ssettings to: %s.\n"), ((bits & WRITE_PACK) && !(bits & WRITE_CONF)) ? "pack " :
  483. ((bits & WRITE_CONF) && !(bits & WRITE_PACK)) ? "conf " :
  484. ((bits & WRITE_PACK) && (bits & WRITE_CONF)) ? "pack/conf " :
  485. "",
  486. fname);
  487. if (die == -1) { /* only bother decrypting if we aren't about to exit */
  488. edpack(&settings, hash, PACK_DEC);
  489. INIT_SALTS;
  490. OPENSSL_cleanse(hash, strlen(hash));
  491. }
  492. }
  493. if (die == -1) {
  494. OPENSSL_cleanse(settings.salt1, sizeof(settings.salt1));
  495. OPENSSL_cleanse(settings.salt2, sizeof(settings.salt2));
  496. }
  497. }
  498. if (die >= 0)
  499. exit(die);
  500. }
  501. static void
  502. clear_settings(void)
  503. {
  504. // egg_memset(&settings.bots, 0, sizeof(settings_t) - SIZE_PACK - PREFIXLEN);
  505. egg_memset(&settings.bots, 0, SIZE_CONF);
  506. }
  507. void conf_to_bin(conf_t *in, bool move, int die)
  508. {
  509. conf_bot *bot = NULL;
  510. char *newbin = NULL;
  511. clear_settings();
  512. sdprintf("converting conf to bin\n");
  513. simple_snprintf(settings.uid, sizeof(settings.uid), "%d", in->uid);
  514. simple_snprintf(settings.watcher, sizeof(settings.watcher), "%d", in->watcher);
  515. simple_snprintf(settings.autocron, sizeof(settings.autocron), "%d", in->autocron);
  516. simple_snprintf(settings.autouname, sizeof(settings.autouname), "%d", in->autouname);
  517. simple_snprintf(settings.portmin, sizeof(settings.portmin), "%d", in->portmin);
  518. simple_snprintf(settings.portmax, sizeof(settings.portmax), "%d", in->portmax);
  519. simple_snprintf(settings.pscloak, sizeof(settings.pscloak), "%d", in->pscloak);
  520. strlcpy(settings.binname, in->binname, sizeof(settings.binname));
  521. if (in->username)
  522. strlcpy(settings.username, in->username, sizeof(settings.username));
  523. if (in->uname)
  524. strlcpy(settings.uname, in->uname, sizeof(settings.uname));
  525. strlcpy(settings.datadir, in->datadir, sizeof(settings.datadir));
  526. if (in->homedir)
  527. strlcpy(settings.homedir, in->homedir, sizeof(settings.homedir));
  528. strlcpy(settings.binpath, in->binpath, sizeof(settings.binpath));
  529. for (bot = in->bots; bot && bot->nick; bot = bot->next) {
  530. simple_snprintf(settings.bots, sizeof(settings.bots), STR("%s%s%s %s %s%s %s,"),
  531. settings.bots && settings.bots[0] ? settings.bots : "",
  532. bot->disabled ? "/" : "",
  533. bot->nick,
  534. bot->net.ip ? bot->net.ip : "*",
  535. bot->net.host6 ? "+" : "",
  536. bot->net.host ? bot->net.host : (bot->net.host6 ? bot->net.host6 : "*"),
  537. bot->net.ip6 ? bot->net.ip6 : "");
  538. }
  539. #ifndef CYGWIN_HACKS
  540. if (move)
  541. newbin = move_bin(in->binpath, in->binname, 0);
  542. else
  543. #endif /* !CYGWIN_HACKS */
  544. newbin = binname;
  545. // tellconfig(&settings);
  546. write_settings(newbin, -1, 1);
  547. if (die >= 0)
  548. exit(die);
  549. }
  550. void reload_bin_data() {
  551. if (bin_checksum(binname, GET_CONF)) {
  552. putlog(LOG_MISC, "*", STR("Rehashed config data from binary."));
  553. conf_bot *oldbots = NULL, *oldbot = NULL;
  554. bool was_localhub = conf.bot->localhub ? 1 : 0;
  555. /* save the old bots list */
  556. if (conf.bots)
  557. oldbots = conf_bots_dup(conf.bots);
  558. /* Save the old conf.bot */
  559. oldbot = (conf_bot *) my_calloc(1, sizeof(conf_bot));
  560. conf_bot_dup(oldbot, conf.bot);
  561. /* free up our current conf struct */
  562. free_conf();
  563. /* Fill conf[] with binary data from settings[] */
  564. bin_to_conf();
  565. /* fill up conf.bot using origbotname */
  566. fill_conf_bot(0); /* 0 to avoid exiting if conf.bot cannot be filled */
  567. if (was_localhub) {
  568. /* add any new bots not in userfile */
  569. conf_add_userlist_bots();
  570. /* deluser removed bots from conf */
  571. if (oldbots)
  572. deluser_removed_bots(oldbots, conf.bots);
  573. }
  574. if (conf.bot && conf.bot->disabled) {
  575. if (tands > 0) {
  576. botnet_send_chat(-1, conf.bot->nick, STR("Bot disabled in binary."));
  577. botnet_send_bye(STR("Bot disabled in binary."));
  578. }
  579. if (server_online)
  580. nuke_server(STR("bbl"));
  581. werr(ERR_BOTDISABLED);
  582. } else if (!conf.bot) {
  583. conf.bot = oldbot;
  584. if (tands > 0) {
  585. botnet_send_chat(-1, conf.bot->nick, STR("Bot removed from binary."));
  586. botnet_send_bye(STR("Bot removed from binary."));
  587. }
  588. if (server_online)
  589. nuke_server(STR("it's been good, cya"));
  590. werr(ERR_BADBOT);
  591. }
  592. /* The bot nick changed! (case) */
  593. if (strcmp(conf.bot->nick, oldbot->nick)) {
  594. change_handle(conf.bot->u, conf.bot->nick);
  595. // var_set_by_name(conf.bot->nick, "nick", conf.bot->nick);
  596. // var_set_userentry(conf.bot->nick, "nick", conf.bot->nick);
  597. }
  598. free_bot(oldbot);
  599. if (oldbots)
  600. free_conf_bots(oldbots);
  601. if (!conf.bot->localhub)
  602. free_conf_bots(conf.bots);
  603. }
  604. }