cfg.c 24 KB

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