cfg.c 24 KB

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