cfg.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. /*
  2. * config.c -- handles:
  3. * botnet config
  4. * cmdpass functions
  5. */
  6. #include "common.h"
  7. #include "cfg.h"
  8. #include "cmds.h"
  9. #include "userrec.h"
  10. #include "auth.h"
  11. #include "misc.h"
  12. #include "users.h"
  13. #include "dccutil.h"
  14. #include "botmsg.h"
  15. #include <sys/stat.h>
  16. #include <sys/types.h>
  17. #include <unistd.h>
  18. #include <fcntl.h>
  19. #include "chan.h"
  20. #include "tandem.h"
  21. #include "src/mod/channels.mod/channels.h"
  22. #include "src/mod/ctcp.mod/ctcp.h"
  23. #ifdef LEAF
  24. #include "src/chanprog.h"
  25. #include "src/mod/server.mod/server.h"
  26. #endif /* LEAF */
  27. #include "botnet.h"
  28. #include <net/if.h>
  29. #include "stat.h"
  30. int cfg_count = 0;
  31. bool cfg_noshare = 0;
  32. struct cfg_entry **cfg = NULL;
  33. char cmdprefix = '+'; /* This is the prefix for msg/channel cmds */
  34. struct cmd_pass *cmdpass = NULL;
  35. #ifdef HUB
  36. static void chanset_describe(struct cfg_entry * entry, int idx) {
  37. dprintf(idx, STR("chanset is a list of default options for when a channel is added. Same format as .chanset.\n"));
  38. }
  39. #endif /* HUB */
  40. #ifdef LEAF
  41. static void chanset_changed(struct cfg_entry *entry, int *valid) {
  42. if (entry->ldata)
  43. strncpyz(cfg_glob_chanset, (char *) entry->ldata, 512);
  44. else if (entry->gdata)
  45. strncpyz(cfg_glob_chanset, (char *) entry->gdata, 512);
  46. }
  47. #endif /* LEAF */
  48. struct cfg_entry CFG_CHANSET = {
  49. "chanset", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  50. #ifdef LEAF
  51. chanset_changed, chanset_changed
  52. #else
  53. NULL, NULL, chanset_describe
  54. #endif /* LEAF */
  55. };
  56. #ifdef HUB
  57. static void servport_describe(struct cfg_entry * entry, int idx) {
  58. dprintf(idx, STR("servport is the default port to use for server connections.\n"));
  59. }
  60. #endif /* HUB */
  61. #ifdef LEAF
  62. static void servport_changed(struct cfg_entry *entry, int *valid) {
  63. if (entry->ldata)
  64. default_port = atoi(entry->ldata);
  65. else if (entry->gdata)
  66. default_port = atoi(entry->gdata);
  67. }
  68. #endif /* LEAF */
  69. struct cfg_entry CFG_SERVPORT = {
  70. "servport", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  71. #ifdef LEAF
  72. servport_changed, servport_changed
  73. #else
  74. NULL, NULL, servport_describe
  75. #endif /* LEAF */
  76. };
  77. #ifdef HUB
  78. static void authkey_describe(struct cfg_entry *entry, int idx) {
  79. dprintf(idx,
  80. STR("authkey is used for authing, give to your users if they are to use DCC chat or IRC cmds. (can be bot specific)\n"));
  81. }
  82. #endif /* HUB */
  83. struct cfg_entry CFG_AUTHKEY = {
  84. "authkey", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  85. #ifdef LEAF
  86. NULL, NULL
  87. #else
  88. NULL, NULL, authkey_describe
  89. #endif /* LEAF */
  90. };
  91. #ifdef HUB
  92. static void msgcmds_describe(struct cfg_entry *entry, int idx) {
  93. if (entry == &CFG_MSGOP)
  94. dprintf(idx, STR("msgop defines the cmd for opping via msging the bot (leave blank to disable)\n"));
  95. else if (entry == &CFG_MSGPASS)
  96. dprintf(idx, STR("msgpass defines the cmd for setting a pass via msging the bot (leave blank to disable)\n"));
  97. else if (entry == &CFG_MSGINVITE)
  98. dprintf(idx, STR("msginvite defines the cmd for requesting invite via msging the bot (leave blank to disable)\n"));
  99. else if (entry == &CFG_MSGIDENT)
  100. dprintf(idx, STR("msgident defines the cmd for identing via msging the bot (leave blank to disable)\n"));
  101. }
  102. #endif /* HUB */
  103. struct cfg_entry CFG_MSGOP = {
  104. "msgop", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  105. NULL, NULL
  106. #ifdef HUB
  107. , msgcmds_describe
  108. #endif /* HUB */
  109. };
  110. struct cfg_entry CFG_MSGPASS = {
  111. "msgpass", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  112. NULL, NULL
  113. #ifdef HUB
  114. , msgcmds_describe
  115. #endif /* HUB */
  116. };
  117. struct cfg_entry CFG_MSGINVITE = {
  118. "msginvite", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  119. NULL, NULL
  120. #ifdef HUB
  121. , msgcmds_describe
  122. #endif /* HUB */
  123. };
  124. struct cfg_entry CFG_MSGIDENT = {
  125. "msgident", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  126. NULL, NULL
  127. #ifdef HUB
  128. , msgcmds_describe
  129. #endif /* HUB */
  130. };
  131. #ifdef HUB
  132. static void cmdprefix_describe(struct cfg_entry *entry, int idx) {
  133. dprintf(idx, STR("cmdprefix is the prefix character used for msg cmds, ie: !op or .op\n"));
  134. }
  135. #endif /* HUB */
  136. #ifdef LEAF
  137. static void cmdprefix_changed(struct cfg_entry *entry, int *valid) {
  138. if (entry->ldata)
  139. cmdprefix = entry->ldata[0];
  140. else if (entry->gdata)
  141. cmdprefix = entry->gdata[0];
  142. }
  143. #endif /* LEAF */
  144. struct cfg_entry CFG_CMDPREFIX = {
  145. "cmdprefix", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  146. #ifdef LEAF
  147. cmdprefix_changed, cmdprefix_changed
  148. #else
  149. NULL, NULL, cmdprefix_describe
  150. #endif /* LEAF */
  151. };
  152. void deflag_user(struct userrec *u, int why, char *msg, struct chanset_t *chan)
  153. {
  154. if (!u)
  155. return;
  156. char tmp[256] = "", tmp2[1024] = "";
  157. struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0 };
  158. int which = 0;
  159. switch (why) {
  160. case DEFLAG_BADCOOKIE:
  161. strcpy(tmp, "Bad op cookie");
  162. which = chan->bad_cookie;
  163. break;
  164. case DEFLAG_MANUALOP:
  165. strcpy(tmp, STR("Manual op in -manop channel"));
  166. which = chan->manop;
  167. break;
  168. #ifdef G_MEAN
  169. case DEFLAG_MEAN_DEOP:
  170. strcpy(tmp, STR("Deopped bot in +mean channel"));
  171. ent = &CFG_MEANDEOP;
  172. break;
  173. case DEFLAG_MEAN_KICK:
  174. strcpy(tmp, STR("Kicked bot in +mean channel"));
  175. ent = &CFG_MEANDEOP;
  176. break;
  177. case DEFLAG_MEAN_BAN:
  178. strcpy(tmp, STR("Banned bot in +mean channel"));
  179. ent = &CFG_MEANDEOP;
  180. break;
  181. #endif /* G_MEAN */
  182. case DEFLAG_MDOP:
  183. strcpy(tmp, "Mass deop");
  184. which = chan->mdop;
  185. break;
  186. case DEFLAG_MOP:
  187. strcpy(tmp, "Mass op");
  188. which = chan->mop;
  189. break;
  190. default:
  191. sprintf(tmp, "Reason #%i", why);
  192. }
  193. if (which == P_DEOP) {
  194. putlog(LOG_WARN, "*", "Setting %s +d (%s): %s", u->handle, tmp, msg);
  195. sprintf(tmp2, "+d: %s (%s)", tmp, msg);
  196. set_user(&USERENTRY_COMMENT, u, tmp2);
  197. get_user_flagrec(u, &fr, chan->dname);
  198. fr.global = USER_DEOP;
  199. fr.chan = USER_DEOP;
  200. set_user_flagrec(u, &fr, chan->dname);
  201. } else if (which == P_KICK) {
  202. putlog(LOG_WARN, "*", "Setting %s +dk (%s): %s", u->handle, tmp, msg);
  203. sprintf(tmp2, "+dk: %s (%s)", tmp, msg);
  204. set_user(&USERENTRY_COMMENT, u, tmp2);
  205. get_user_flagrec(u, &fr, chan->dname);
  206. fr.global = USER_DEOP | USER_KICK;
  207. fr.chan = USER_DEOP | USER_KICK;
  208. set_user_flagrec(u, &fr, chan->dname);
  209. } else if (which == P_DELETE) {
  210. putlog(LOG_WARN, "*", "Deleting %s (%s): %s", u->handle, tmp, msg);
  211. deluser(u->handle);
  212. } else {
  213. putlog(LOG_WARN, "*", "No user flag effects for %s (%s): %s", u->handle, tmp, msg);
  214. sprintf(tmp2, "Warning: %s (%s)", tmp, msg);
  215. set_user(&USERENTRY_COMMENT, u, tmp2);
  216. }
  217. }
  218. #ifdef HUB
  219. static void misc_describe(struct cfg_entry *cfgent, int idx)
  220. {
  221. int i = 0;
  222. if (!strcmp(cfgent->name, "fork-interval")) {
  223. dprintf(idx, STR("fork-interval is number of seconds in between each fork() call made by the bot, to change process ID and reset cpu usage counters.\n"));
  224. i = 1;
  225. } else if (!strcmp(cfgent->name, "login")) {
  226. dprintf(idx, STR("login sets how to handle someone logging in to the shell\n"));
  227. } else if (!strcmp(cfgent->name, "trace")) {
  228. dprintf(idx, STR("trace sets how to handle someone tracing/debugging the bot\n"));
  229. } else if (!strcmp(cfgent->name, "promisc")) {
  230. dprintf(idx, STR("promisc sets how to handle when a interface is set to promiscuous mode\n"));
  231. } else if (!strcmp(cfgent->name, "bad-process")) {
  232. dprintf(idx, STR("bad-process sets how to handle when a running process not listed in process-list is detected\n"));
  233. } else if (!strcmp(cfgent->name, "process-list")) {
  234. dprintf(idx, STR("process-list is a comma-separated list of \"expected processes\" running on the bots uid\n"));
  235. i = 1;
  236. } else if (!strcmp(cfgent->name, "hijack")) {
  237. dprintf(idx, STR("hijack sets how to handle when a commonly used hijack method attempt is detected. (recommended: die)\n"));
  238. }
  239. if (!i)
  240. dprintf(idx, "Valid settings are: ignore, warn, die, reject, suicide\n");
  241. }
  242. #endif /* HUB */
  243. static void fork_lchanged(struct cfg_entry * cfgent, int * valid) {
  244. if (!cfgent->ldata)
  245. return;
  246. if (atoi(cfgent->ldata) <= 0)
  247. *valid = 0;
  248. }
  249. static void fork_gchanged(struct cfg_entry * cfgent, int * valid) {
  250. if (!cfgent->gdata)
  251. return;
  252. if (atoi(cfgent->gdata) <= 0)
  253. *valid = 0;
  254. }
  255. #ifdef HUB
  256. static void fork_describe(struct cfg_entry * cfgent, int idx) {
  257. dprintf(idx, STR("fork-interval is number of seconds in between each fork() call made by the bot, to change process ID and reset cpu usage counters.\n"));
  258. }
  259. #endif /* HUB */
  260. struct cfg_entry CFG_FORKINTERVAL = {
  261. "fork-interval", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  262. fork_gchanged, fork_lchanged
  263. #ifdef HUB
  264. , fork_describe
  265. #endif /* HUB */
  266. };
  267. static void detect_lchanged(struct cfg_entry * cfgent, int * valid) {
  268. char *p = NULL;
  269. if (!(p = (char *) cfgent->ldata))
  270. *valid = 1;
  271. else if (strcmp(p, "ignore") && strcmp(p, "die") && strcmp(p, "reject") && strcmp(p, "suicide") && strcmp(p, "warn"))
  272. *valid = 0;
  273. }
  274. static void detect_gchanged(struct cfg_entry * cfgent, int * valid) {
  275. char *p = (char *) cfgent->ldata;
  276. if (!p)
  277. *valid=1;
  278. else if (strcmp(p, "ignore") && strcmp(p, "die") && strcmp(p, "reject") && strcmp(p, "suicide") && strcmp(p, "warn"))
  279. *valid=0;
  280. }
  281. struct cfg_entry CFG_LOGIN = {
  282. "login", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  283. detect_gchanged, detect_lchanged
  284. #ifdef HUB
  285. , misc_describe
  286. #endif /* HUB */
  287. };
  288. struct cfg_entry CFG_HIJACK = {
  289. "hijack", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  290. detect_gchanged, detect_lchanged
  291. #ifdef HUB
  292. , misc_describe
  293. #endif /* HUB */
  294. };
  295. struct cfg_entry CFG_TRACE = {
  296. "trace", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  297. detect_gchanged, detect_lchanged
  298. #ifdef HUB
  299. , misc_describe
  300. #endif /* HUB */
  301. };
  302. struct cfg_entry CFG_PROMISC = {
  303. "promisc", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  304. detect_gchanged, detect_lchanged
  305. #ifdef HUB
  306. , misc_describe
  307. #endif /* HUB */
  308. };
  309. struct cfg_entry CFG_BADPROCESS = {
  310. "bad-process", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  311. detect_gchanged, detect_lchanged
  312. #ifdef HUB
  313. , misc_describe
  314. #endif /* HUB */
  315. };
  316. struct cfg_entry CFG_PROCESSLIST = {
  317. "process-list", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  318. NULL, NULL
  319. #ifdef HUB
  320. , misc_describe
  321. #endif /* HUB */
  322. };
  323. #ifdef LEAF
  324. static void servers_changed(struct cfg_entry * entry, int * valid) {
  325. if (!strcmp(entry->name, "servers")) {
  326. if (conf.bot->host6 || conf.bot->ip6) /* we want to use the servers6 entry. */
  327. return;
  328. } else if (!strcmp(entry->name, "servers6")) {
  329. if (!conf.bot->host6 && !conf.bot->ip6) /* we probably want to use the normal server list.. */
  330. return;
  331. }
  332. char *slist = NULL, *p = NULL;
  333. slist = (char *) (entry->ldata ? entry->ldata : (entry->gdata ? entry->gdata : ""));
  334. if (serverlist) {
  335. clearq(serverlist);
  336. serverlist = NULL;
  337. }
  338. shuffle(slist, ",");
  339. p = strdup(slist);
  340. add_server(p);
  341. free(p);
  342. }
  343. #endif /* LEAF */
  344. #ifdef HUB
  345. static void servers_describe(struct cfg_entry * entry, int idx) {
  346. if (!strcmp(entry->name, "servers"))
  347. dprintf(idx, STR("servers is a comma-separated list of servers the bot will use\n"));
  348. else
  349. dprintf(idx, STR("servers6 is a comma-separated list of servers the bot will use (FOR IPv6)\n"));
  350. }
  351. #endif /* HUB */
  352. struct cfg_entry CFG_SERVERS = {
  353. "servers", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  354. #ifdef LEAF
  355. servers_changed, servers_changed
  356. #else
  357. NULL, NULL, servers_describe
  358. #endif /* LEAF */
  359. };
  360. struct cfg_entry CFG_SERVERS6 = {
  361. "servers6", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  362. #ifdef LEAF
  363. servers_changed, servers_changed
  364. #else
  365. NULL, NULL, servers_describe
  366. #endif /* LEAF */
  367. };
  368. #ifdef LEAF
  369. static void nick_changed(struct cfg_entry * entry, int * valid) {
  370. char *p = NULL;
  371. if (entry->ldata)
  372. p = entry->ldata;
  373. else if (entry->gdata)
  374. p = entry->gdata;
  375. else
  376. p = NULL;
  377. if (p && p[0])
  378. strncpyz(origbotname, p, NICKLEN + 1);
  379. else
  380. strncpyz(origbotname, conf.bot->nick, NICKLEN + 1);
  381. if (server_online)
  382. dprintf(DP_SERVER, "NICK %s\n", origbotname);
  383. }
  384. #endif /* LEAF */
  385. #ifdef HUB
  386. static void nick_describe(struct cfg_entry * entry, int idx) {
  387. dprintf(idx, STR("nick is the bots preferred nick when connecting/using .resetnick\n"));
  388. }
  389. #endif /* HUB */
  390. struct cfg_entry CFG_NICK = {
  391. "nick", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  392. #ifdef LEAF
  393. nick_changed, nick_changed
  394. #else
  395. NULL, NULL, nick_describe
  396. #endif /* LEAF */
  397. };
  398. #ifdef HUB
  399. static void realname_describe(struct cfg_entry * entry, int idx) {
  400. dprintf(idx, STR("realname is the bots \"real name\" when connecting\n"));
  401. }
  402. #endif /* HUB */
  403. #ifdef LEAF
  404. static void realname_changed(struct cfg_entry * entry, int * valid) {
  405. if (entry->ldata)
  406. strncpyz(botrealname, (char *) entry->ldata, 121);
  407. else if (entry->gdata)
  408. strncpyz(botrealname, (char *) entry->gdata, 121);
  409. }
  410. #endif /* LEAF */
  411. struct cfg_entry CFG_REALNAME = {
  412. "realname", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  413. #ifdef LEAF
  414. realname_changed, realname_changed
  415. #else
  416. NULL, NULL, realname_describe
  417. #endif /* LEAF */
  418. };
  419. #ifdef HUB
  420. static void dccauth_describe(struct cfg_entry *cfgent, int idx)
  421. {
  422. dprintf(idx, STR("dccauth is boolean (0 or 1). Set to use auth checking on dcc/telnet login.\n"));
  423. }
  424. #endif /* HUB */
  425. struct cfg_entry CFG_DCCAUTH = {
  426. "dccauth", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  427. NULL, NULL
  428. #ifdef HUB
  429. , dccauth_describe
  430. #endif /* HUB */
  431. };
  432. #ifdef HUB
  433. static void getin_describe(struct cfg_entry *cfgent, int idx)
  434. {
  435. if (!strcmp(cfgent->name, "op-bots"))
  436. dprintf(idx, STR("op-bots is number of bots to ask every time a oprequest is to be made\n"));
  437. else if (!strcmp(cfgent->name, "in-bots"))
  438. dprintf(idx, STR("in-bots is number of bots to ask every time a inrequest is to be made\n"));
  439. else if (!strcmp(cfgent->name, "op-requests"))
  440. dprintf(idx, STR("op-requests (requests:seconds) limits how often the bot will ask for ops\n"));
  441. else if (!strcmp(cfgent->name, "lag-threshold"))
  442. dprintf(idx, STR("lag-threshold is maximum acceptable server lag for the bot to send/honor requests\n"));
  443. else if (!strcmp(cfgent->name, "op-time-slack"))
  444. dprintf(idx, STR("op-time-slack is number of seconds a opcookies encoded time value can be off from the bots current time\n"));
  445. else if (!strcmp(cfgent->name, "close-threshold"))
  446. dprintf(idx, STR("Format H:L. When at least H hubs but L or less leafs are linked, close all channels\n"));
  447. else if (!strcmp(cfgent->name, "kill-threshold"))
  448. dprintf(idx, STR("When more than kill-threshold bots have been killed/k-lined the last minute, channels are locked\n"));
  449. else if (!strcmp(cfgent->name, "fight-threshold"))
  450. dprintf(idx, STR("When more than fight-threshold ops/deops/kicks/bans/unbans altogether have happened on a channel in one minute, the channel is locked\n"));
  451. else {
  452. dprintf(idx, STR("No description for %s ???\n"), cfgent->name);
  453. putlog(LOG_ERRORS, "*", STR("getin_describe() called with unknown config entry %s"), cfgent->name);
  454. }
  455. }
  456. #endif /* HUB */
  457. static void getin_changed(struct cfg_entry *cfgent, int *valid)
  458. {
  459. if (!cfgent->gdata)
  460. return;
  461. *valid = 0;
  462. if (!strcmp(cfgent->name, "op-requests")) {
  463. int L,
  464. R;
  465. char *value = cfgent->gdata;
  466. L = atoi(value);
  467. value = strchr(value, ':');
  468. if (!value)
  469. return;
  470. value++;
  471. R = atoi(value);
  472. if ((R >= 60) || (R <= 3) || (L < 1) || (L > R))
  473. return;
  474. *valid = 1;
  475. return;
  476. }
  477. if (!strcmp(cfgent->name, "close-threshold")) {
  478. int L, R;
  479. char *value = NULL;
  480. value = cfgent->gdata;
  481. L = atoi(value);
  482. value = strchr(value, ':');
  483. if (!value)
  484. return;
  485. value++;
  486. R = atoi(value);
  487. if ((R >= 1000) || (R < 0) || (L < 0) || (L > 100))
  488. return;
  489. *valid = 1;
  490. return;
  491. }
  492. int i = atoi(cfgent->gdata);
  493. if (!strcmp(cfgent->name, "op-bots")) {
  494. if ((i < 1) || (i > 10))
  495. return;
  496. } else if (!strcmp(cfgent->name, "invite-bots")) {
  497. if ((i < 1) || (i > 10))
  498. return;
  499. } else if (!strcmp(cfgent->name, "key-bots")) {
  500. if ((i < 1) || (i > 10))
  501. return;
  502. } else if (!strcmp(cfgent->name, "limit-bots")) {
  503. if ((i < 1) || (i > 10))
  504. return;
  505. } else if (!strcmp(cfgent->name, "unban-bots")) {
  506. if ((i < 1) || (i > 10))
  507. return;
  508. } else if (!strcmp(cfgent->name, "lag-threshold")) {
  509. if ((i < 3) || (i > 60))
  510. return;
  511. } else if (!strcmp(cfgent->name, "fight-threshold")) {
  512. if (i && ((i < 50) || (i > 1000)))
  513. return;
  514. } else if (!strcmp(cfgent->name, "kill-threshold")) {
  515. if ((i < 0) || (i >= 200))
  516. return;
  517. } else if (!strcmp(cfgent->name, "op-time-slack")) {
  518. if ((i < 30) || (i > 1200))
  519. return;
  520. }
  521. *valid = 1;
  522. return;
  523. }
  524. struct cfg_entry CFG_OPBOTS = {
  525. "op-bots", CFGF_GLOBAL, NULL, NULL,
  526. getin_changed, NULL
  527. #ifdef HUB
  528. , getin_describe
  529. #endif /* HUB */
  530. };
  531. struct cfg_entry CFG_FIGHTTHRESHOLD = {
  532. "fight-threshold", CFGF_GLOBAL, NULL, NULL,
  533. getin_changed, NULL
  534. #ifdef HUB
  535. , getin_describe
  536. #endif /* HUB */
  537. };
  538. struct cfg_entry CFG_CLOSETHRESHOLD = {
  539. "close-threshold", CFGF_GLOBAL, NULL, NULL,
  540. getin_changed, NULL
  541. #ifdef HUB
  542. , getin_describe
  543. #endif /* HUB */
  544. };
  545. struct cfg_entry CFG_KILLTHRESHOLD = {
  546. "kill-threshold", CFGF_GLOBAL, NULL, NULL,
  547. getin_changed, NULL
  548. #ifdef HUB
  549. , getin_describe
  550. #endif /* HUB */
  551. };
  552. struct cfg_entry CFG_INBOTS = {
  553. "in-bots", CFGF_GLOBAL, NULL, NULL,
  554. getin_changed, NULL
  555. #ifdef HUB
  556. , getin_describe
  557. #endif /* HUB */
  558. };
  559. struct cfg_entry CFG_LAGTHRESHOLD = {
  560. "lag-threshold", CFGF_GLOBAL, NULL, NULL,
  561. getin_changed, NULL
  562. #ifdef HUB
  563. , getin_describe
  564. #endif /* HUB */
  565. };
  566. struct cfg_entry CFG_OPREQUESTS = {
  567. "op-requests", CFGF_GLOBAL, NULL, NULL,
  568. getin_changed, NULL
  569. #ifdef HUB
  570. , getin_describe
  571. #endif /* HUB */
  572. };
  573. void add_cfg(struct cfg_entry *entry)
  574. {
  575. cfg = (struct cfg_entry **) realloc(cfg, sizeof(void *) * (cfg_count + 1));
  576. cfg[cfg_count] = entry;
  577. cfg_count++;
  578. entry->ldata = NULL;
  579. entry->gdata = NULL;
  580. }
  581. static struct cfg_entry *check_can_set_cfg(char *target, char *entryname)
  582. {
  583. struct cfg_entry *entry = NULL;
  584. for (int i = 0; i < cfg_count; i++)
  585. if (!strcmp(cfg[i]->name, entryname)) {
  586. entry = cfg[i];
  587. break;
  588. }
  589. if (!entry)
  590. return 0;
  591. struct userrec *u = NULL;
  592. if (target) {
  593. if (!(entry->flags & CFGF_LOCAL))
  594. return 0;
  595. if (!(u = get_user_by_handle(userlist, target)))
  596. return 0;
  597. if (!u->bot)
  598. return 0;
  599. } else {
  600. if (!(entry->flags & CFGF_GLOBAL))
  601. return 0;
  602. }
  603. return entry;
  604. }
  605. void set_cfg_str(char *target, char *entryname, char *data)
  606. {
  607. struct cfg_entry *entry = NULL;
  608. if (!(entry = check_can_set_cfg(target, entryname)))
  609. return;
  610. if (data && !strcmp(data, "-"))
  611. data = NULL;
  612. if (data && (strlen(data) >= 1024))
  613. data[1023] = 0;
  614. if (target) {
  615. struct userrec *u = get_user_by_handle(userlist, target);
  616. struct xtra_key *xk = NULL;
  617. char *olddata = entry->ldata;
  618. if (u && !strcmp(conf.bot->nick, u->handle)) {
  619. if (data) {
  620. entry->ldata = strdup(data);
  621. } else
  622. entry->ldata = NULL;
  623. if (entry->localchanged) {
  624. int valid = 1;
  625. /* entry->localchanged(entry, olddata, &valid); */
  626. entry->localchanged(entry, &valid);
  627. if (!valid) {
  628. if (entry->ldata)
  629. free(entry->ldata);
  630. entry->ldata = olddata;
  631. data = olddata;
  632. olddata = NULL;
  633. }
  634. }
  635. }
  636. xk = (struct xtra_key *) calloc(1, sizeof(struct xtra_key));
  637. xk->key = strdup(entry->name);
  638. if (data) {
  639. xk->data = strdup(data);
  640. }
  641. set_user(&USERENTRY_CONFIG, u, xk);
  642. if (olddata)
  643. free(olddata);
  644. } else {
  645. char *olddata = entry->gdata;
  646. if (data) {
  647. entry->gdata = strdup(data);
  648. } else
  649. entry->gdata = NULL;
  650. if (entry->globalchanged) {
  651. int valid = 1;
  652. /* entry->globalchanged(entry, olddata, &valid); */
  653. entry->globalchanged(entry, &valid);
  654. if (!valid) {
  655. if (entry->gdata)
  656. free(entry->gdata);
  657. entry->gdata = olddata;
  658. olddata = NULL;
  659. }
  660. }
  661. if (!cfg_noshare)
  662. botnet_send_cfg_broad(-1, entry);
  663. if (olddata)
  664. free(olddata);
  665. }
  666. }
  667. struct cfg_entry CFG_MOTD = {
  668. "motd", CFGF_GLOBAL, NULL, NULL,
  669. NULL, NULL
  670. #ifdef HUB
  671. , NULL
  672. #endif /* HUB */
  673. };
  674. void init_config()
  675. {
  676. add_cfg(&CFG_AUTHKEY);
  677. add_cfg(&CFG_BADPROCESS);
  678. add_cfg(&CFG_DCCAUTH);
  679. add_cfg(&CFG_CHANSET);
  680. add_cfg(&CFG_CLOAK_SCRIPT);
  681. add_cfg(&CFG_CLOSETHRESHOLD);
  682. add_cfg(&CFG_CMDPREFIX);
  683. add_cfg(&CFG_FIGHTTHRESHOLD);
  684. add_cfg(&CFG_FORKINTERVAL);
  685. add_cfg(&CFG_HIJACK);
  686. add_cfg(&CFG_INBOTS);
  687. add_cfg(&CFG_KILLTHRESHOLD);
  688. add_cfg(&CFG_LAGTHRESHOLD);
  689. add_cfg(&CFG_LOGIN);
  690. add_cfg(&CFG_MOTD);
  691. #ifdef G_MEAN
  692. add_cfg(&CFG_MEANBAN);
  693. add_cfg(&CFG_MEANDEOP);
  694. add_cfg(&CFG_MEANKICK);
  695. #endif /* G_MEAN */
  696. add_cfg(&CFG_MSGIDENT);
  697. add_cfg(&CFG_MSGINVITE);
  698. add_cfg(&CFG_MSGOP);
  699. add_cfg(&CFG_MSGPASS);
  700. add_cfg(&CFG_NICK);
  701. add_cfg(&CFG_OPBOTS);
  702. add_cfg(&CFG_OPREQUESTS);
  703. add_cfg(&CFG_PROCESSLIST);
  704. add_cfg(&CFG_PROMISC);
  705. add_cfg(&CFG_REALNAME);
  706. add_cfg(&CFG_SERVERS);
  707. add_cfg(&CFG_SERVERS6);
  708. add_cfg(&CFG_SERVPORT);
  709. add_cfg(&CFG_TRACE);
  710. }
  711. int check_cmd_pass(const char *cmd, char *pass)
  712. {
  713. if (check_master(pass))
  714. return 1;
  715. struct cmd_pass *cp = NULL;
  716. for (cp = cmdpass; cp; cp = cp->next)
  717. if (!egg_strcasecmp(cmd, cp->name)) {
  718. char tmp[32] = "";
  719. encrypt_pass(pass, tmp);
  720. if (!strcmp(tmp, cp->pass))
  721. return 1;
  722. return 0;
  723. }
  724. return 0;
  725. }
  726. int has_cmd_pass(const char *cmd)
  727. {
  728. struct cmd_pass *cp = NULL;
  729. for (cp = cmdpass; cp; cp = cp->next)
  730. if (!egg_strcasecmp(cmd, cp->name))
  731. return 1;
  732. return 0;
  733. }
  734. void set_cmd_pass(char *ln, int shareit)
  735. {
  736. struct cmd_pass *cp = NULL;
  737. char *cmd = NULL;
  738. cmd = newsplit(&ln);
  739. for (cp = cmdpass; cp; cp = cp->next)
  740. if (!strcmp(cmd, cp->name))
  741. break;
  742. if (cp)
  743. if (ln[0]) {
  744. /* change */
  745. strcpy(cp->pass, ln);
  746. if (shareit)
  747. botnet_send_cmdpass(-1, cp->name, cp->pass);
  748. } else {
  749. if (cp == cmdpass)
  750. cmdpass = cp->next;
  751. else {
  752. struct cmd_pass *cp2;
  753. cp2 = cmdpass;
  754. while (cp2->next != cp)
  755. cp2 = cp2->next;
  756. cp2->next = cp->next;
  757. }
  758. if (shareit)
  759. botnet_send_cmdpass(-1, cp->name, "");
  760. free(cp->name);
  761. free(cp);
  762. } else if (ln[0]) {
  763. /* create */
  764. cp = (struct cmd_pass *) calloc(1, sizeof(struct cmd_pass));
  765. cp->next = cmdpass;
  766. cmdpass = cp;
  767. cp->name = strdup(cmd);
  768. strcpy(cp->pass, ln);
  769. if (shareit)
  770. botnet_send_cmdpass(-1, cp->name, cp->pass);
  771. }
  772. }
  773. void userfile_cfg_line(char *ln)
  774. {
  775. char *name = NULL;
  776. int i;
  777. struct cfg_entry *cfgent = NULL;
  778. name = newsplit(&ln);
  779. for (i = 0; !cfgent && (i < cfg_count); i++)
  780. if (!strcmp(cfg[i]->name, name))
  781. cfgent = cfg[i];
  782. if (cfgent) {
  783. /* if we are a leaf, dont share the cfg line. */
  784. if (bot_hublevel(conf.bot->u) == 999)
  785. cfg_noshare = 1;
  786. set_cfg_str(NULL, cfgent->name, (ln && ln[0]) ? ln : NULL);
  787. /* regardless of leaf/hub it is safe to set this to 0 */
  788. cfg_noshare = 0;
  789. } else
  790. putlog(LOG_ERRORS, "*", "Unrecognized config entry %s in userfile", name);
  791. }
  792. void got_config_share(int idx, char *ln, int broad)
  793. {
  794. char *name = NULL;
  795. int i;
  796. struct cfg_entry *cfgent = NULL;
  797. cfg_noshare = 1;
  798. name = newsplit(&ln);
  799. for (i = 0; !cfgent && (i < cfg_count); i++)
  800. if (!strcmp(cfg[i]->name, name))
  801. cfgent = cfg[i];
  802. if (cfgent) {
  803. set_cfg_str(NULL, cfgent->name, (ln && ln[0]) ? ln : NULL);
  804. if (broad)
  805. botnet_send_cfg_broad(idx, cfgent);
  806. } else
  807. putlog(LOG_ERRORS, "*", "Unrecognized config entry %s in userfile", name);
  808. cfg_noshare = 0;
  809. }
  810. void trigger_cfg_changed()
  811. {
  812. int i;
  813. struct xtra_key *xk = NULL;
  814. for (i = 0; i < cfg_count; i++) {
  815. if (cfg[i]->flags & CFGF_LOCAL) {
  816. xk = (struct xtra_key *) get_user(&USERENTRY_CONFIG, conf.bot->u);
  817. while (xk && strcmp(xk->key, cfg[i]->name))
  818. xk = xk->next;
  819. if (xk) {
  820. putlog(LOG_DEBUG, "*", "trigger_cfg_changed for %s", cfg[i]->name ? cfg[i]->name : "(null)");
  821. if (!strcmp(cfg[i]->name, xk->key ? xk->key : "")) {
  822. set_cfg_str(conf.bot->nick, cfg[i]->name, xk->data);
  823. }
  824. }
  825. }
  826. }
  827. }