binary.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. /*
  2. * binary.c -- handles:
  3. * misc update functions
  4. * md5 hash verifying
  5. *
  6. */
  7. #include "common.h"
  8. #include "binary.h"
  9. #include "settings.h"
  10. #include "crypt.h"
  11. #include "shell.h"
  12. #include "misc.h"
  13. #include "main.h"
  14. #include "misc_file.h"
  15. /*
  16. typedef struct encdata_struct {
  17. char prefix[PREFIXLEN];
  18. char data[65];
  19. } encdata_t;
  20. static encdata_t encdata = {
  21. "AAAAAAAAAAAAAAAA",
  22. ""
  23. };
  24. */
  25. settings_t settings = {
  26. "AAAAAAAAAAAAAAA",
  27. /* -- STATIC -- */
  28. "", "", "", "", "", "", "", "", "", "",
  29. /* -- DYNAMIC -- */
  30. "", "", "", "", "", "", "", "", "", "", "", "", "",
  31. /* -- PADDING */
  32. ""
  33. };
  34. #define PACK_ENC 1
  35. #define PACK_DEC 2
  36. static void edpack(settings_t *, const char *, int);
  37. int checked_bin_buf = 0;
  38. static char *
  39. bin_md5(const char *fname, int todo, MD5_CTX * ctx)
  40. {
  41. static char hash[MD5_HASH_LENGTH + 1] = "";
  42. unsigned char md5out[MD5_HASH_LENGTH + 1] = "", buf[PREFIXLEN + 1] = "";
  43. FILE *f = NULL;
  44. size_t len = 0;
  45. checked_bin_buf++;
  46. if (!(f = fopen(fname, "rb")))
  47. werr(ERR_BINSTAT);
  48. while ((len = fread(buf, 1, sizeof buf - 1, f))) {
  49. if (!memcmp(buf, &settings.prefix, PREFIXLEN)) {
  50. break;
  51. }
  52. MD5_Update(ctx, buf, len);
  53. }
  54. fclose(f);
  55. MD5_Final(md5out, ctx);
  56. strncpyz(hash, btoh(md5out, MD5_DIGEST_LENGTH), sizeof(hash));
  57. OPENSSL_cleanse(&ctx, sizeof(ctx));
  58. if (todo == WRITE_MD5) {
  59. Tempfile *newbin = new Tempfile("bin");
  60. char *fname_bak = NULL;
  61. size_t size = 0, i = 0;
  62. size = strlen(fname) + 2;
  63. fname_bak = (char *) calloc(1, size);
  64. egg_snprintf(fname_bak, size, "%s~", fname);
  65. size = 0;
  66. if (!(f = fopen(fname, "rb")))
  67. werr(ERR_BINSTAT);
  68. fseek(f, 0, SEEK_END);
  69. size = ftell(f);
  70. fseek(f, 0, SEEK_SET);
  71. while ((len = fread(buf, 1, sizeof(buf) - 1, f))) {
  72. if (i) { /* to skip bytes for hash */
  73. i -= sizeof(buf) - 1;
  74. continue;
  75. }
  76. if (fwrite(buf, sizeof(buf) - 1, 1, newbin->f) != 1) {
  77. fclose(f);
  78. delete newbin;
  79. werr(ERR_BINSTAT);
  80. }
  81. /*
  82. if (!memcmp(buf, &encdata.prefix, PREFIXLEN)) {
  83. // now we have 65 for data :D
  84. char *enc_hash = NULL;
  85. enc_hash = encrypt_string(SALT1, hash);
  86. fwrite(enc_hash, strlen(enc_hash), 1, fn);
  87. i = strlen(enc_hash); // skip the next strlen(enc_hash) bytes
  88. free(enc_hash);
  89. }
  90. */
  91. if (!memcmp(buf, &settings.prefix, PREFIXLEN)) {
  92. strncpyz(settings.hash, hash, 65);
  93. edpack(&settings, hash, PACK_ENC);
  94. fwrite(&settings.hash, sizeof(settings_t) - PREFIXLEN, 1, newbin->f);
  95. i = sizeof(settings_t) - PREFIXLEN;
  96. }
  97. }
  98. fclose(f);
  99. if (movefile(fname, fname_bak))
  100. fatal("Crappy os :D", 0);
  101. if (movefile(newbin->file, fname))
  102. fatal("Crappy os :D", 0);
  103. fixmod(fname);
  104. unlink(fname_bak);
  105. delete newbin;
  106. }
  107. return hash;
  108. }
  109. static int
  110. readcfg(const char *cfgfile)
  111. {
  112. FILE *f = NULL;
  113. if ((f = fopen(cfgfile, "r")) == NULL) {
  114. printf("Error: Can't open '%s' for reading\n", cfgfile);
  115. exit(1);
  116. }
  117. char *buffer = NULL, *p = NULL;
  118. int skip = 0, line = 0;
  119. printf("Reading '%s' ", cfgfile);
  120. while ((!feof(f)) && ((buffer = step_thru_file(f)) != NULL)) {
  121. line++;
  122. if ((*buffer)) {
  123. if (strchr(buffer, '\n'))
  124. *(char *) strchr(buffer, '\n') = 0;
  125. if ((skipline(buffer, &skip)))
  126. continue;
  127. if (strchr(buffer, '<') || strchr(buffer, '>')) {
  128. printf(" Failed\n");
  129. printf("%s:%d: error: Look at your configuration file again...\n", cfgfile, line);
  130. exit(1);
  131. }
  132. p = strchr(buffer, ' ');
  133. while (p && (strchr(LISTSEPERATORS, p[0])))
  134. *p++ = 0;
  135. if (p) {
  136. if (!egg_strcasecmp(buffer, "packname")) {
  137. strncpyz(settings.packname, trim(p), sizeof settings.packname);
  138. printf(".");
  139. } else if (!egg_strcasecmp(buffer, "shellhash")) {
  140. strncpyz(settings.shellhash, trim(p), sizeof settings.shellhash);
  141. printf(".");
  142. } else if (!egg_strcasecmp(buffer, "bdhash")) {
  143. strncpyz(settings.bdhash, trim(p), sizeof settings.bdhash);
  144. printf(".");
  145. } else if (!egg_strcasecmp(buffer, "dccprefix")) {
  146. strncpyz(settings.dcc_prefix, trim(p), sizeof settings.dcc_prefix);
  147. printf(".");
  148. } else if (!egg_strcasecmp(buffer, "owner")) {
  149. strcat(settings.owners, trim(p));
  150. strcat(settings.owners, ",");
  151. printf(".");
  152. } else if (!egg_strcasecmp(buffer, "owneremail")) {
  153. strcat(settings.owneremail, trim(p));
  154. strcat(settings.owneremail, ",");
  155. printf(".");
  156. } else if (!egg_strcasecmp(buffer, "hub")) {
  157. strcat(settings.hubs, trim(p));
  158. strcat(settings.hubs, ",");
  159. printf(".");
  160. } else if (!egg_strcasecmp(buffer, "salt1")) {
  161. strcat(settings.salt1, trim(p));
  162. printf(".");
  163. } else if (!egg_strcasecmp(buffer, "salt2")) {
  164. strcat(settings.salt2, trim(p));
  165. printf(".");
  166. } else {
  167. printf("%s %s\n", buffer, p);
  168. printf(",");
  169. }
  170. }
  171. }
  172. buffer = NULL;
  173. }
  174. if (f)
  175. fclose(f);
  176. if (!settings.salt1[0] || !settings.salt2[0]) {
  177. /* Write salts back to the cfgfile */
  178. char salt1[SALT1LEN + 1] = "", salt2[SALT2LEN + 1] = "";
  179. printf("Creating Salts");
  180. if ((f = fopen(cfgfile, "a")) == NULL) {
  181. printf("Cannot open cfgfile for appending.. aborting\n");
  182. exit(1);
  183. }
  184. make_rand_str(salt1, SALT1LEN);
  185. make_rand_str(salt2, SALT2LEN);
  186. salt1[sizeof salt1] = salt2[sizeof salt2] = 0;
  187. fprintf(f, "SALT1 %s\n", salt1);
  188. fprintf(f, "SALT2 %s\n", salt2);
  189. fflush(f);
  190. fclose(f);
  191. }
  192. printf(" Success\n");
  193. return 1;
  194. }
  195. static void edpack(settings_t *incfg, const char *hash, int what)
  196. {
  197. char *tmp = NULL;
  198. char *(*enc_dec_string)(const char *, char *);
  199. if (what == PACK_ENC)
  200. enc_dec_string = encrypt_string;
  201. else
  202. enc_dec_string = decrypt_string;
  203. #define dofield(_field) do { \
  204. tmp = enc_dec_string(hash, _field); \
  205. egg_snprintf(_field, sizeof(_field), tmp); \
  206. free(tmp); \
  207. } while (0)
  208. /* -- STATIC -- */
  209. dofield(incfg->hash);
  210. dofield(incfg->packname);
  211. dofield(incfg->shellhash);
  212. dofield(incfg->bdhash);
  213. dofield(incfg->dcc_prefix);
  214. dofield(incfg->owners);
  215. dofield(incfg->owneremail);
  216. dofield(incfg->hubs);
  217. /* -- DYNAMIC -- */
  218. //printf("BOTS: %s\n", incfg->bots);
  219. dofield(incfg->bots);
  220. //printf("EBOTS: %s\n", incfg->bots);
  221. dofield(incfg->uid);
  222. dofield(incfg->autouname);
  223. dofield(incfg->pscloak);
  224. dofield(incfg->autocron);
  225. dofield(incfg->watcher);
  226. dofield(incfg->uname);
  227. dofield(incfg->username);
  228. dofield(incfg->homedir);
  229. dofield(incfg->binpath);
  230. dofield(incfg->binname);
  231. dofield(incfg->portmin);
  232. dofield(incfg->portmax);
  233. #undef dofield
  234. }
  235. /*
  236. static void
  237. tellconfig(settings_t *incfg)
  238. {
  239. #define dofield(_field) printf("%s: %s\n", #_field, _field);
  240. // -- STATIC --
  241. dofield(incfg->hash);
  242. dofield(incfg->packname);
  243. dofield(incfg->shellhash);
  244. dofield(incfg->bdhash);
  245. dofield(incfg->dcc_prefix);
  246. dofield(incfg->owners);
  247. dofield(incfg->owneremail);
  248. dofield(incfg->hubs);
  249. // -- DYNAMIC --
  250. dofield(incfg->bots);
  251. dofield(incfg->uid);
  252. dofield(incfg->autouname);
  253. dofield(incfg->pscloak);
  254. dofield(incfg->autocron);
  255. dofield(incfg->watcher);
  256. dofield(incfg->uname);
  257. dofield(incfg->username);
  258. dofield(incfg->homedir);
  259. dofield(incfg->binpath);
  260. dofield(incfg->binname);
  261. dofield(incfg->portmin);
  262. dofield(incfg->portmax);
  263. #undef dofield
  264. }
  265. */
  266. void
  267. check_sum(const char *fname, const char *cfgfile)
  268. {
  269. MD5_CTX ctx;
  270. MD5_Init(&ctx);
  271. if (!settings.hash[0]) {
  272. if (!cfgfile)
  273. fatal("Binary not initialized.", 0);
  274. readcfg(cfgfile);
  275. // tellconfig(&settings);
  276. if (bin_md5(fname, WRITE_MD5, &ctx))
  277. printf("* Wrote settings to binary.\n");
  278. exit(0);
  279. } else {
  280. char *hash = bin_md5(fname, GET_MD5, &ctx);
  281. // tellconfig(&settings);
  282. edpack(&settings, hash, PACK_DEC);
  283. // tellconfig(&settings);
  284. if (strcmp(settings.hash, hash)) {
  285. unlink(fname);
  286. fatal("!! Invalid binary", 0);
  287. }
  288. }
  289. }
  290. void write_settings(const char *fname, int die)
  291. {
  292. MD5_CTX ctx;
  293. char *hash = NULL;
  294. MD5_Init(&ctx);
  295. if ((hash = bin_md5(fname, WRITE_MD5, &ctx))) {
  296. printf("* Wrote settings to %s.\n", fname);
  297. edpack(&settings, hash, PACK_DEC);
  298. }
  299. if (die) {
  300. if (old_hack == 2)
  301. exit(2); /* we were called with -2 so exit with 2 ! */
  302. else
  303. exit(0);
  304. }
  305. }
  306. static void
  307. clear_settings(void)
  308. {
  309. memset(&settings.bots, 0, sizeof(settings_t) - 3467);
  310. }
  311. void conf_to_bin(conf_t *in)
  312. {
  313. conf_bot *bot = NULL;
  314. char *newbin = NULL;
  315. clear_settings();
  316. sdprintf("converting conf to bin\n");
  317. sprintf(settings.uid, "%d", in->uid);
  318. sprintf(settings.watcher, "%d", in->watcher);
  319. sprintf(settings.autocron, "%d", in->autocron);
  320. sprintf(settings.autouname, "%d", in->autouname);
  321. sprintf(settings.portmin, "%d", in->portmin);
  322. sprintf(settings.portmax, "%d", in->portmax);
  323. sprintf(settings.pscloak, "%d", in->pscloak);
  324. strncpyz(settings.binname, in->binname, 16);
  325. strncpyz(settings.username, in->username, 16);
  326. strncpyz(settings.uname, in->uname, 350);
  327. strncpyz(settings.homedir, in->homedir, 350);
  328. strncpyz(settings.binpath, in->binpath, 350);
  329. for (bot = in->bots; bot && bot->nick; bot = bot->next) {
  330. sprintf(settings.bots, "%s%s %s %s%s %s,", settings.bots && settings.bots[0] ? settings.bots : "",
  331. bot->nick,
  332. bot->ip ? bot->ip : ".",
  333. bot->host6 ? "+" : "",
  334. bot->host ? bot->host : (bot->host6 ? bot->host6 : "."),
  335. bot->ip6 ? bot->ip6 : "");
  336. }
  337. newbin = move_bin(in->binpath, in->binname, 0);
  338. /* tellconfig(&settings); */
  339. write_settings(newbin, 1);
  340. }