config.c 24 KB

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