cfg.c 24 KB

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