misc.c 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814
  1. /*
  2. * misc.c -- handles:
  3. * split() maskhost() dumplots() daysago() days() daysdur()
  4. * logging things
  5. * queueing output for the bot (msg and help)
  6. * resync buffers for sharebots
  7. * motd display and %var substitution
  8. *
  9. */
  10. #include "main.h"
  11. #include <sys/stat.h>
  12. #include <sys/types.h>
  13. #include <sys/wait.h>
  14. #include <unistd.h>
  15. #include <fcntl.h>
  16. #include "chan.h"
  17. #include "tandem.h"
  18. #include "modules.h"
  19. #include <pwd.h>
  20. #include <errno.h>
  21. #ifdef S_ANTITRACE
  22. #include <sys/ptrace.h>
  23. #include <sys/wait.h>
  24. #endif
  25. #include <net/if.h>
  26. #include <sys/ioctl.h>
  27. #include <sys/socket.h>
  28. #include <signal.h>
  29. #ifdef HAVE_UNAME
  30. # include <sys/utsname.h>
  31. #endif
  32. #include "stat.h"
  33. #include "bg.h"
  34. extern struct userrec *userlist;
  35. extern struct dcc_t *dcc;
  36. extern struct chanset_t *chanset;
  37. extern tand_t *tandbot;
  38. extern char version[], origbotname[], botname[],
  39. admin[], network[], motdfile[], ver[], botnetnick[],
  40. bannerfile[], logfile_suffix[], textdir[], userfile[],
  41. *binname, pid_file[], netpass[], tempdir[];
  42. extern int backgrd, con_chan, term_z, use_stderr, dcc_total, timesync,
  43. #ifdef HUB
  44. my_port,
  45. #endif
  46. keep_all_logs, quick_logs, strict_host, loading,
  47. localhub;
  48. extern time_t now;
  49. extern Tcl_Interp *interp;
  50. void detected(int, char *);
  51. int shtime = 1; /* Whether or not to display the time
  52. with console output */
  53. log_t *logs = 0; /* Logfiles */
  54. int max_logs = 5; /* Current maximum log files */
  55. int max_logsize = 0; /* Maximum logfile size, 0 for no limit */
  56. int conmask = LOG_MODES | LOG_CMDS | LOG_MISC; /* Console mask */
  57. int debug_output = 1; /* Disply output to server to LOG_SERVEROUT */
  58. int auth_total = 0;
  59. int max_auth = 100;
  60. struct auth_t *auth = 0;
  61. char authkey[121];
  62. char cmdprefix[1] = "+";
  63. struct cfg_entry CFG_MOTD = {
  64. "motd", CFGF_GLOBAL, NULL, NULL,
  65. NULL, NULL, NULL
  66. };
  67. void authkey_describe(struct cfg_entry * entry, int idx) {
  68. dprintf(idx, "authkey is used for authing, give to your users if they are to use DCC chat or IRC cmds. (can be bot specific)\n");
  69. }
  70. void authkey_changed(struct cfg_entry * entry, char * olddata, int * valid) {
  71. if (entry->ldata) {
  72. strncpy0(authkey, (char *) entry->ldata, sizeof authkey);
  73. } else if (entry->gdata) {
  74. strncpy0(authkey, (char *) entry->gdata, sizeof authkey);
  75. }
  76. }
  77. struct cfg_entry CFG_AUTHKEY = {
  78. "authkey", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  79. authkey_changed, authkey_changed, authkey_describe
  80. };
  81. void cmdprefix_describe(struct cfg_entry *entry, int idx) {
  82. dprintf(idx, "cmdprefix is the prefix used for msg cmds, ie: !op or .op\n");
  83. }
  84. void cmdprefix_changed(struct cfg_entry * entry, char * olddata, int * valid) {
  85. if (entry->ldata) {
  86. strncpy0(cmdprefix, (char *) entry->ldata, sizeof cmdprefix);
  87. } else if (entry->gdata) {
  88. strncpy0(cmdprefix, (char *) entry->gdata, sizeof cmdprefix);
  89. }
  90. }
  91. struct cfg_entry CFG_CMDPREFIX = {
  92. "cmdprefix", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  93. cmdprefix_changed, cmdprefix_changed, cmdprefix_describe
  94. };
  95. void misc_describe(struct cfg_entry *cfgent, int idx)
  96. {
  97. int i = 0;
  98. if (!strcmp(cfgent->name, STR("fork-interval"))) {
  99. 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"));
  100. i = 1;
  101. #ifdef S_LASTCHECK
  102. } else if (!strcmp(cfgent->name, STR("login"))) {
  103. dprintf(idx, STR("login sets how to handle someone logging in to the shell\n"));
  104. #endif
  105. #ifdef S_ANTITRACE
  106. } else if (!strcmp(cfgent->name, STR("trace"))) {
  107. dprintf(idx, STR("trace sets how to handle someone tracing/debugging the bot\n"));
  108. #endif
  109. #ifdef S_PROMISC
  110. } else if (!strcmp(cfgent->name, STR("promisc"))) {
  111. dprintf(idx, STR("promisc sets how to handle when a interface is set to promiscous mode\n"));
  112. #endif
  113. #ifdef S_PROCESSCHECK
  114. } else if (!strcmp(cfgent->name, STR("bad-process"))) {
  115. dprintf(idx, STR("bad-process sets how to handle when a running process not listed in process-list is detected\n"));
  116. } else if (!strcmp(cfgent->name, STR("process-list"))) {
  117. dprintf(idx, STR("process-list is a comma-separated list of \"expected processes\" running on the bots uid\n"));
  118. i = 1;
  119. #endif
  120. #ifdef S_HIJACKCHECK
  121. } else if (!strcmp(cfgent->name, STR("hijack"))) {
  122. dprintf(idx, STR("hijack sets how to handle when a commonly used hijack method attempt is detected. (recommended: die)\n"));
  123. #endif
  124. }
  125. if (!i)
  126. dprintf(idx, STR("Valid settings are: nocheck, ignore, warn, die, reject, suicide\n"));
  127. }
  128. void fork_lchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
  129. if (!cfgent->ldata)
  130. return;
  131. if (atoi(cfgent->ldata)<=0)
  132. *valid=0;
  133. }
  134. void fork_gchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
  135. if (!cfgent->gdata)
  136. return;
  137. if (atoi(cfgent->gdata)<=0)
  138. *valid=0;
  139. }
  140. void fork_describe(struct cfg_entry * cfgent, int idx) {
  141. 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"));
  142. }
  143. struct cfg_entry CFG_FORKINTERVAL = {
  144. "fork-interval", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  145. fork_gchanged, fork_lchanged, fork_describe
  146. };
  147. void detect_lchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
  148. char * p = cfgent->ldata;
  149. if (!p)
  150. *valid=1;
  151. else if (strcmp(p, STR("ignore")) && strcmp(p, STR("die")) && strcmp(p, STR("reject"))
  152. && strcmp(p, STR("suicide")) && strcmp(p, STR("nocheck")) && strcmp(p, STR("warn")))
  153. *valid=0;
  154. }
  155. void detect_gchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
  156. char * p = (char *) cfgent->ldata;
  157. if (!p)
  158. *valid=1;
  159. else if (strcmp(p, STR("ignore")) && strcmp(p, STR("die")) && strcmp(p, STR("reject"))
  160. && strcmp(p, STR("suicide")) && strcmp(p, STR("nocheck")) && strcmp(p, STR("warn")))
  161. *valid=0;
  162. }
  163. #ifdef S_LASTCHECK
  164. struct cfg_entry CFG_LOGIN = {
  165. "login", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  166. detect_gchanged, detect_lchanged, misc_describe
  167. };
  168. #endif
  169. #ifdef S_HIJACKCHECK
  170. struct cfg_entry CFG_HIJACK = {
  171. "hijack", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  172. detect_gchanged, detect_lchanged, misc_describe
  173. };
  174. #endif
  175. #ifdef S_ANTITRACE
  176. struct cfg_entry CFG_TRACE = {
  177. "trace", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  178. detect_gchanged, detect_lchanged, misc_describe
  179. };
  180. #endif
  181. #ifdef S_PROMISC
  182. struct cfg_entry CFG_PROMISC = {
  183. "promisc", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  184. detect_gchanged, detect_lchanged, misc_describe
  185. };
  186. #endif
  187. #ifdef S_PROCESSCHECK
  188. struct cfg_entry CFG_BADPROCESS = {
  189. "bad-process", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  190. detect_gchanged, detect_lchanged, misc_describe
  191. };
  192. struct cfg_entry CFG_PROCESSLIST = {
  193. "process-list", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  194. NULL, NULL, misc_describe
  195. };
  196. #endif
  197. #ifdef S_DCCPASS
  198. struct cmd_pass *cmdpass = NULL;
  199. #endif
  200. /* unixware has no strcasecmp() without linking in a hefty library */
  201. #define upcase(c) (((c)>='a' && (c)<='z') ? (c)-'a'+'A' : (c))
  202. #if !HAVE_STRCASECMP
  203. #define strcasecmp strcasecmp2
  204. #endif
  205. int strcasecmp2(char *s1, char *s2)
  206. {
  207. while ((*s1) && (*s2) && (upcase(*s1) == upcase(*s2))) {
  208. s1++;
  209. s2++;
  210. }
  211. return upcase(*s1) - upcase(*s2);
  212. }
  213. /* this is cfg shit from servers/irc/ctcp because hub doesnt load
  214. * these mods */
  215. #ifdef HUB
  216. void servers_describe(struct cfg_entry * entry, int idx) {
  217. dprintf(idx, STR("servers is a comma-separated list of servers the bot will use\n"));
  218. }
  219. void servers_changed(struct cfg_entry * entry, char * olddata, int * valid) {
  220. }
  221. void servers6_describe(struct cfg_entry * entry, int idx) {
  222. dprintf(idx, STR("servers6 is a comma-separated list of servers the bot will use (FOR IPv6)\n"));
  223. }
  224. void servers6_changed(struct cfg_entry * entry, char * olddata, int * valid) {
  225. }
  226. void nick_describe(struct cfg_entry * entry, int idx) {
  227. dprintf(idx, "nick is the bots preferred nick when connecting/using .resetnick\n");
  228. }
  229. void nick_changed(struct cfg_entry * entry, char * olddata, int * valid) {
  230. }
  231. void realname_describe(struct cfg_entry * entry, int idx) {
  232. dprintf(idx, STR("realname is the bots \"real name\" when connecting\n"));
  233. }
  234. void realname_changed(struct cfg_entry * entry, char * olddata, int * valid) {
  235. }
  236. struct cfg_entry CFG_SERVERS = {
  237. "servers", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  238. servers_changed, servers_changed, servers_describe
  239. };
  240. struct cfg_entry CFG_SERVERS6 = {
  241. "servers6", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  242. servers6_changed, servers6_changed, servers6_describe
  243. };
  244. struct cfg_entry CFG_NICK = {
  245. "nick", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  246. nick_changed, nick_changed, nick_describe
  247. };
  248. struct cfg_entry CFG_REALNAME = {
  249. "realname", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
  250. realname_changed, realname_changed, realname_describe
  251. };
  252. void getin_describe(struct cfg_entry *cfgent, int idx)
  253. {
  254. if (!strcmp(cfgent->name, STR("op-bots")))
  255. dprintf(idx, STR("op-bots is number of bots to ask every time a oprequest is to be made\n"));
  256. else if (!strcmp(cfgent->name, STR("in-bots")))
  257. dprintf(idx, STR("in-bots is number of bots to ask every time a inrequest is to be made\n"));
  258. else if (!strcmp(cfgent->name, STR("op-requests")))
  259. dprintf(idx, STR("op-requests (requests:seconds) limits how often the bot will ask for ops\n"));
  260. else if (!strcmp(cfgent->name, STR("lag-threshold")))
  261. dprintf(idx, STR("lag-threshold is maximum acceptable server lag for the bot to send/honor requests\n"));
  262. else if (!strcmp(cfgent->name, STR("op-time-slack")))
  263. dprintf(idx, STR("op-time-slack is number of seconds a opcookies encoded time value can be off from the bots current time\n"));
  264. else if (!strcmp(cfgent->name, STR("lock-threshold")))
  265. dprintf(idx, STR("Format H:L. When at least H hubs but L or less leafs are linked, lock all channels\n"));
  266. else if (!strcmp(cfgent->name, STR("kill-threshold")))
  267. dprintf(idx, STR("When more than kill-threshold bots have been killed/k-lined the last minute, channels are locked\n"));
  268. else if (!strcmp(cfgent->name, STR("fight-threshold")))
  269. 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"));
  270. else {
  271. dprintf(idx, STR("No description for %s ???\n"), cfgent->name);
  272. putlog(LOG_ERRORS, "*", STR("getin_describe() called with unknown config entry %s"), cfgent->name);
  273. }
  274. }
  275. void getin_changed(struct cfg_entry *cfgent, char *oldval, int *valid)
  276. {
  277. int i;
  278. if (!cfgent->gdata)
  279. return;
  280. *valid = 0;
  281. if (!strcmp(cfgent->name, STR("op-requests"))) {
  282. int L,
  283. R;
  284. char *value = cfgent->gdata;
  285. L = atoi(value);
  286. value = strchr(value, ':');
  287. if (!value)
  288. return;
  289. value++;
  290. R = atoi(value);
  291. if ((R >= 60) || (R <= 3) || (L < 1) || (L > R))
  292. return;
  293. *valid = 1;
  294. return;
  295. }
  296. if (!strcmp(cfgent->name, STR("lock-threshold"))) {
  297. int L,
  298. R;
  299. char *value = cfgent->gdata;
  300. L = atoi(value);
  301. value = strchr(value, ':');
  302. if (!value)
  303. return;
  304. value++;
  305. R = atoi(value);
  306. if ((R >= 1000) || (R < 0) || (L < 0) || (L > 100))
  307. return;
  308. *valid = 1;
  309. return;
  310. }
  311. i = atoi(cfgent->gdata);
  312. if (!strcmp(cfgent->name, STR("op-bots"))) {
  313. if ((i < 1) || (i > 10))
  314. return;
  315. } else if (!strcmp(cfgent->name, STR("invite-bots"))) {
  316. if ((i < 1) || (i > 10))
  317. return;
  318. } else if (!strcmp(cfgent->name, STR("key-bots"))) {
  319. if ((i < 1) || (i > 10))
  320. return;
  321. } else if (!strcmp(cfgent->name, STR("limit-bots"))) {
  322. if ((i < 1) || (i > 10))
  323. return;
  324. } else if (!strcmp(cfgent->name, STR("unban-bots"))) {
  325. if ((i < 1) || (i > 10))
  326. return;
  327. } else if (!strcmp(cfgent->name, STR("lag-threshold"))) {
  328. if ((i < 3) || (i > 60))
  329. return;
  330. } else if (!strcmp(cfgent->name, STR("fight-threshold"))) {
  331. if (i && ((i < 50) || (i > 1000)))
  332. return;
  333. } else if (!strcmp(cfgent->name, STR("kill-threshold"))) {
  334. if ((i < 0) || (i >= 200))
  335. return;
  336. } else if (!strcmp(cfgent->name, STR("op-time-slack"))) {
  337. if ((i < 30) || (i > 1200))
  338. return;
  339. }
  340. *valid = 1;
  341. return;
  342. }
  343. struct cfg_entry CFG_OPBOTS = {
  344. "op-bots", CFGF_GLOBAL, NULL, NULL,
  345. getin_changed, NULL, getin_describe
  346. };
  347. struct cfg_entry CFG_INBOTS = {
  348. "in-bots", CFGF_GLOBAL, NULL, NULL,
  349. getin_changed, NULL, getin_describe
  350. };
  351. struct cfg_entry CFG_LAGTHRESHOLD = {
  352. "lag-threshold", CFGF_GLOBAL, NULL, NULL,
  353. getin_changed, NULL, getin_describe
  354. };
  355. struct cfg_entry CFG_OPREQUESTS = {
  356. "op-requests", CFGF_GLOBAL, NULL, NULL,
  357. getin_changed, NULL, getin_describe
  358. };
  359. struct cfg_entry CFG_OPTIMESLACK = {
  360. "op-time-slack", CFGF_GLOBAL, NULL, NULL,
  361. getin_changed, NULL, getin_describe
  362. };
  363. #ifdef G_AUTOLOCK
  364. struct cfg_entry CFG_LOCKTHRESHOLD = {
  365. "lock-threshold", CFGF_GLOBAL, NULL, NULL,
  366. getin_changed, NULL, getin_describe
  367. };
  368. struct cfg_entry CFG_KILLTHRESHOLD = {
  369. "kill-threshold", CFGF_GLOBAL, NULL, NULL,
  370. getin_changed, NULL, getin_describe
  371. };
  372. struct cfg_entry CFG_FIGHTTHRESHOLD = {
  373. "fight-threshold", CFGF_GLOBAL, NULL, NULL,
  374. getin_changed, NULL, getin_describe
  375. };
  376. #endif /* G_AUTOLOCK */
  377. /* cloak
  378. void cloak_describe(struct cfg_entry *cfgent, int idx)
  379. {
  380. dprintf(idx, STR("cloak-script decides which BitchX script the bot cloaks. If set to 6, a random script will be cloaked.\n"));
  381. dprintf(idx, STR("Available: 0=crackrock, 1=neonapple, 2=tunnelvision, 3=argon, 4=evolver, 5=prevail\n"));
  382. }
  383. void cloak_changed(struct cfg_entry *cfgent, char * oldval, int * valid) {
  384. char * p;
  385. int i;
  386. p = cfgent->ldata ? cfgent->ldata : cfgent->gdata;
  387. if (!p)
  388. return;
  389. i=atoi(p);
  390. #ifdef LEAF
  391. if (i>=6)
  392. i = random() % 6;
  393. #endif
  394. *valid = ( (i>=0) && (i<=6));
  395. if (*valid)
  396. cloak_script = i;
  397. #ifdef LEAF
  398. scriptchanged();
  399. #endif
  400. }
  401. struct cfg_entry CFG_CLOAK_SCRIPT = {
  402. "cloak-script", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
  403. cloak_changed, cloak_changed, cloak_describe
  404. };
  405. */
  406. #endif
  407. /* end hub compat cfg */
  408. int cfg_count=0;
  409. struct cfg_entry ** cfg = NULL;
  410. int cfg_noshare=0;
  411. /* Expected memory usage
  412. */
  413. int expmem_misc()
  414. {
  415. #ifdef S_DCCPASS
  416. struct cmd_pass *cp = NULL;
  417. #endif
  418. int tot = 0, i;
  419. for (i=0;i<cfg_count;i++) {
  420. tot += sizeof(void *);
  421. if (cfg[i]->gdata)
  422. tot += strlen(cfg[i]->gdata) + 1;
  423. if (cfg[i]->ldata)
  424. tot += strlen(cfg[i]->ldata) + 1;
  425. }
  426. #ifdef S_DCCPASS
  427. for (cp=cmdpass;cp;cp=cp->next) {
  428. tot += sizeof(struct cmd_pass) + strlen(cp->name)+1;
  429. }
  430. #endif
  431. tot = sizeof(struct auth_t) * max_auth;
  432. return tot + (max_logs * sizeof(log_t));
  433. }
  434. void init_auth_max()
  435. {
  436. if (max_auth < 1)
  437. max_auth = 1;
  438. if (auth)
  439. auth = nrealloc(auth, sizeof(struct auth_t) * max_auth);
  440. else
  441. auth = nmalloc(sizeof(struct auth_t) * max_auth);
  442. }
  443. void init_misc()
  444. {
  445. static int last = 0;
  446. init_auth_max();
  447. if (max_logs < 1)
  448. max_logs = 1;
  449. if (logs)
  450. logs = nrealloc(logs, max_logs * sizeof(log_t));
  451. else
  452. logs = nmalloc(max_logs * sizeof(log_t));
  453. for (; last < max_logs; last++) {
  454. logs[last].filename = logs[last].chname = NULL;
  455. logs[last].mask = 0;
  456. logs[last].f = NULL;
  457. /* Added by cybah */
  458. logs[last].szlast[0] = 0;
  459. logs[last].repeats = 0;
  460. /* Added by rtc */
  461. logs[last].flags = 0;
  462. }
  463. add_cfg(&CFG_AUTHKEY);
  464. // add_cfg(&CFG_CMDPREFIX);
  465. add_cfg(&CFG_MOTD);
  466. add_cfg(&CFG_FORKINTERVAL);
  467. #ifdef S_LASTCHECK
  468. add_cfg(&CFG_LOGIN);
  469. #endif
  470. #ifdef S_HIJACKCHECK
  471. add_cfg(&CFG_HIJACK);
  472. #endif
  473. #ifdef S_ANTITRACE
  474. add_cfg(&CFG_TRACE);
  475. #endif
  476. #ifdef S_PROMISC
  477. add_cfg(&CFG_PROMISC);
  478. #endif
  479. #ifdef S_PROCESSCHECK
  480. add_cfg(&CFG_BADPROCESS);
  481. add_cfg(&CFG_PROCESSLIST);
  482. #endif
  483. #ifdef HUB
  484. add_cfg(&CFG_NICK);
  485. add_cfg(&CFG_SERVERS);
  486. add_cfg(&CFG_SERVERS6);
  487. add_cfg(&CFG_REALNAME);
  488. set_cfg_str(NULL, STR("realname"), "A deranged product of evil coders");
  489. add_cfg(&CFG_OPBOTS);
  490. add_cfg(&CFG_INBOTS);
  491. add_cfg(&CFG_LAGTHRESHOLD);
  492. add_cfg(&CFG_OPREQUESTS);
  493. add_cfg(&CFG_OPTIMESLACK);
  494. #ifdef G_AUTOLOCK
  495. add_cfg(&CFG_LOCKTHRESHOLD);
  496. add_cfg(&CFG_KILLTHRESHOLD);
  497. add_cfg(&CFG_FIGHTTHRESHOLD);
  498. #endif
  499. //cloak add_cfg(&CFG_CLOAK_SCRIPT);
  500. #endif
  501. }
  502. /*
  503. * Misc functions
  504. */
  505. /* low-level stuff for other modules
  506. */
  507. int is_file(const char *s)
  508. {
  509. struct stat ss;
  510. int i = stat(s, &ss);
  511. if (i < 0)
  512. return 0;
  513. if ((ss.st_mode & S_IFREG) || (ss.st_mode & S_IFLNK))
  514. return 1;
  515. return 0;
  516. }
  517. /* This implementation wont overrun dst - 'max' is the max bytes that dst
  518. * can be, including the null terminator. So if 'dst' is a 128 byte buffer,
  519. * pass 128 as 'max'. The function will _always_ null-terminate 'dst'.
  520. *
  521. * Returns: The number of characters appended to 'dst'.
  522. *
  523. * Usage eg.
  524. *
  525. * char buf[128];
  526. * size_t bufsize = sizeof(buf);
  527. *
  528. * buf[0] = 0, bufsize--;
  529. *
  530. * while (blah && bufsize) {
  531. * bufsize -= egg_strcatn(buf, <some-long-string>, sizeof(buf));
  532. * }
  533. *
  534. * <Cybah>
  535. */
  536. int egg_strcatn(char *dst, const char *src, size_t max)
  537. {
  538. size_t tmpmax = 0;
  539. /* find end of 'dst' */
  540. while (*dst && max > 0) {
  541. dst++;
  542. max--;
  543. }
  544. /* Store 'max', so we can use it to workout how many characters were
  545. * written later on.
  546. */
  547. tmpmax = max;
  548. /* copy upto, but not including the null terminator */
  549. while (*src && max > 1) {
  550. *dst++ = *src++;
  551. max--;
  552. }
  553. /* null-terminate the buffer */
  554. *dst = 0;
  555. /* Don't include the terminating null in our count, as it will cumulate
  556. * in loops - causing a headache for the caller.
  557. */
  558. return tmpmax - max;
  559. }
  560. int my_strcpy(register char *a, register char *b)
  561. {
  562. register char *c = b;
  563. while (*b)
  564. *a++ = *b++;
  565. *a = *b;
  566. return b - c;
  567. }
  568. /* Split first word off of rest and put it in first
  569. */
  570. void splitc(char *first, char *rest, char divider)
  571. {
  572. char *p = strchr(rest, divider);
  573. if (p == NULL) {
  574. if (first != rest && first)
  575. first[0] = 0;
  576. return;
  577. }
  578. *p = 0;
  579. if (first != NULL)
  580. strcpy(first, rest);
  581. if (first != rest)
  582. /* In most circumstances, strcpy with src and dst being the same buffer
  583. * can produce undefined results. We're safe here, as the src is
  584. * guaranteed to be at least 2 bytes higher in memory than dest. <Cybah>
  585. */
  586. strcpy(rest, p + 1);
  587. }
  588. /* As above, but lets you specify the 'max' number of bytes (EXCLUDING the
  589. * terminating null).
  590. *
  591. * Example of use:
  592. *
  593. * char buf[HANDLEN + 1];
  594. *
  595. * splitcn(buf, input, "@", HANDLEN);
  596. *
  597. * <Cybah>
  598. */
  599. void splitcn(char *first, char *rest, char divider, size_t max)
  600. {
  601. char *p = strchr(rest, divider);
  602. if (p == NULL) {
  603. if (first != rest && first)
  604. first[0] = 0;
  605. return;
  606. }
  607. *p = 0;
  608. if (first != NULL)
  609. strncpyz(first, rest, max);
  610. if (first != rest)
  611. /* In most circumstances, strcpy with src and dst being the same buffer
  612. * can produce undefined results. We're safe here, as the src is
  613. * guaranteed to be at least 2 bytes higher in memory than dest. <Cybah>
  614. */
  615. strcpy(rest, p + 1);
  616. }
  617. char *splitnick(char **blah)
  618. {
  619. char *p = strchr(*blah, '!'), *q = *blah;
  620. if (p) {
  621. *p = 0;
  622. *blah = p + 1;
  623. return q;
  624. }
  625. return "";
  626. }
  627. char *newsplit(char **rest)
  628. {
  629. register char *o, *r;
  630. if (!rest)
  631. return *rest = "";
  632. o = *rest;
  633. while (*o == ' ')
  634. o++;
  635. r = o;
  636. while (*o && (*o != ' '))
  637. o++;
  638. if (*o)
  639. *o++ = 0;
  640. *rest = o;
  641. return r;
  642. }
  643. /* Convert "abc!user@a.b.host" into "*!user@*.b.host"
  644. * or "abc!user@1.2.3.4" into "*!user@1.2.3.*"
  645. * or "abc!user@0:0:0:0:0:ffff:1.2.3.4" into "*!user@0:0:0:0:0:ffff:1.2.3.*"
  646. * or "abc!user@3ffe:604:2:b02e:6174:7265:6964:6573" into
  647. * "*!user@3ffe:604:2:b02e:6174:7265:6964:*"
  648. */
  649. void maskhost(const char *s, char *nw)
  650. {
  651. register const char *p, *q, *e, *f;
  652. int i;
  653. *nw++ = '*';
  654. *nw++ = '!';
  655. p = (q = strchr(s, '!')) ? q + 1 : s;
  656. /* Strip of any nick, if a username is found, use last 8 chars */
  657. if ((q = strchr(p, '@'))) {
  658. int fl = 0;
  659. if ((q - p) > 9) {
  660. nw[0] = '*';
  661. p = q - 7;
  662. i = 1;
  663. } else
  664. i = 0;
  665. while (*p != '@') {
  666. if (!fl && strchr("~+-^=", *p)) {
  667. if (strict_host)
  668. nw[i] = '?';
  669. else
  670. i--;
  671. } else
  672. nw[i] = *p;
  673. fl++;
  674. p++;
  675. i++;
  676. }
  677. nw[i++] = '@';
  678. q++;
  679. } else {
  680. nw[0] = '*';
  681. nw[1] = '@';
  682. i = 2;
  683. q = s;
  684. }
  685. nw += i;
  686. e = NULL;
  687. /* Now q points to the hostname, i point to where to put the mask */
  688. if ((!(p = strchr(q, '.')) || !(e = strchr(p + 1, '.'))) && !strchr(q, ':'))
  689. /* TLD or 2 part host */
  690. strcpy(nw, q);
  691. else {
  692. if (e == NULL) { /* IPv6 address? */
  693. const char *mask_str;
  694. f = strrchr(q, ':');
  695. if (strchr(f, '.')) { /* IPv4 wrapped in an IPv6? */
  696. f = strrchr(f, '.');
  697. mask_str = ".*";
  698. } else /* ... no, true IPv6. */
  699. mask_str = ":*";
  700. strncpy(nw, q, f - q);
  701. /* No need to nw[f-q] = 0 here, as the strcpy below will
  702. * terminate the string for us.
  703. */
  704. nw += (f - q);
  705. strcpy(nw, mask_str);
  706. } else {
  707. for (f = e; *f; f++);
  708. f--;
  709. if (*f >= '0' && *f <= '9') { /* Numeric IP address */
  710. while (*f != '.')
  711. f--;
  712. strncpy(nw, q, f - q);
  713. /* No need to nw[f-q] = 0 here, as the strcpy below will
  714. * terminate the string for us.
  715. */
  716. nw += (f - q);
  717. strcpy(nw, ".*");
  718. } else { /* Normal host >= 3 parts */
  719. /* a.b.c -> *.b.c
  720. * a.b.c.d -> *.b.c.d if tld is a country (2 chars)
  721. * OR *.c.d if tld is com/edu/etc (3 chars)
  722. * a.b.c.d.e -> *.c.d.e etc
  723. */
  724. const char *x = strchr(e + 1, '.');
  725. if (!x)
  726. x = p;
  727. else if (strchr(x + 1, '.'))
  728. x = e;
  729. else if (strlen(x) == 3)
  730. x = p;
  731. else
  732. x = e;
  733. sprintf(nw, "*%s", x);
  734. }
  735. }
  736. }
  737. }
  738. /* Dump a potentially super-long string of text.
  739. */
  740. void dumplots(int idx, const char *prefix, char *data)
  741. {
  742. char *p = data, *q, *n, c;
  743. const int max_data_len = 500 - strlen(prefix);
  744. if (!*data) {
  745. dprintf(idx, "%s\n", prefix);
  746. return;
  747. }
  748. while (strlen(p) > max_data_len) {
  749. q = p + max_data_len;
  750. /* Search for embedded linefeed first */
  751. n = strchr(p, '\n');
  752. if (n && n < q) {
  753. /* Great! dump that first line then start over */
  754. *n = 0;
  755. dprintf(idx, "%s%s\n", prefix, p);
  756. *n = '\n';
  757. p = n + 1;
  758. } else {
  759. /* Search backwards for the last space */
  760. while (*q != ' ' && q != p)
  761. q--;
  762. if (q == p)
  763. q = p + max_data_len;
  764. c = *q;
  765. *q = 0;
  766. dprintf(idx, "%s%s\n", prefix, p);
  767. *q = c;
  768. p = q;
  769. if (c == ' ')
  770. p++;
  771. }
  772. }
  773. /* Last trailing bit: split by linefeeds if possible */
  774. n = strchr(p, '\n');
  775. while (n) {
  776. *n = 0;
  777. dprintf(idx, "%s%s\n", prefix, p);
  778. *n = '\n';
  779. p = n + 1;
  780. n = strchr(p, '\n');
  781. }
  782. if (*p)
  783. dprintf(idx, "%s%s\n", prefix, p); /* Last trailing bit */
  784. }
  785. /* Convert an interval (in seconds) to one of:
  786. * "19 days ago", "1 day ago", "18:12"
  787. */
  788. void daysago(time_t now, time_t then, char *out)
  789. {
  790. if (now - then > 86400) {
  791. int days = (now - then) / 86400;
  792. sprintf(out, "%d day%s ago", days, (days == 1) ? "" : "s");
  793. return;
  794. }
  795. egg_strftime(out, 6, "%H:%M", localtime(&then));
  796. }
  797. /* Convert an interval (in seconds) to one of:
  798. * "in 19 days", "in 1 day", "at 18:12"
  799. */
  800. void days(time_t now, time_t then, char *out)
  801. {
  802. if (now - then > 86400) {
  803. int days = (now - then) / 86400;
  804. sprintf(out, "in %d day%s", days, (days == 1) ? "" : "s");
  805. return;
  806. }
  807. egg_strftime(out, 9, "at %H:%M", localtime(&now));
  808. }
  809. /* Convert an interval (in seconds) to one of:
  810. * "for 19 days", "for 1 day", "for 09:10"
  811. */
  812. void daysdur(time_t now, time_t then, char *out)
  813. {
  814. char s[81];
  815. int hrs, mins;
  816. if (now - then > 86400) {
  817. int days = (now - then) / 86400;
  818. sprintf(out, "for %d day%s", days, (days == 1) ? "" : "s");
  819. return;
  820. }
  821. strcpy(out, "for ");
  822. now -= then;
  823. hrs = (int) (now / 3600);
  824. mins = (int) ((now - (hrs * 3600)) / 60);
  825. sprintf(s, "%02d:%02d", hrs, mins);
  826. strcat(out, s);
  827. }
  828. /* show l33t banner */
  829. void show_banner(int idx)
  830. {
  831. dprintf(idx, STR(" _ _ _ \n"));
  832. dprintf(idx, STR("__ ___ __ __ _(_) |_| |__ \n"));
  833. dprintf(idx, STR("\\ \\ /\\ / / '__/ _` | | __| '_ \\ \n"));
  834. dprintf(idx, STR(" \\ V V /| | | (_| | | |_| | | |\n"));
  835. dprintf(idx, STR(" \\_/\\_/ |_| \\__,_|_|\\__|_| |_|\n"));
  836. dprintf(idx, STR(" by bryan \n"));
  837. }
  838. /* show motd to dcc chatter */
  839. void show_motd(int idx)
  840. {
  841. dprintf(idx, STR("Motd: "));
  842. if (CFG_MOTD.gdata && *(char *) CFG_MOTD.gdata)
  843. dprintf(idx, STR("%s\n"), (char *) CFG_MOTD.gdata);
  844. else
  845. dprintf(idx, STR("none\n"));
  846. }
  847. void show_channels(int idx, char *handle)
  848. {
  849. struct chanset_t *chan;
  850. struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0, 0 };
  851. struct userrec *u;
  852. int first = 0, l = 0;
  853. char format[120];
  854. for (chan = chanset;chan;chan = chan->next)
  855. if (l < strlen(chan->dname))
  856. l = strlen(chan->dname);
  857. Context;
  858. if (handle)
  859. u = get_user_by_handle(userlist, handle);
  860. else
  861. u = dcc[idx].user;
  862. Context;
  863. egg_snprintf(format, sizeof format, " %%-%us %%-s%%-s%%-s%%-s%%-s\n", (l+2));
  864. for (chan = chanset;chan;chan = chan->next) {
  865. get_user_flagrec(u, &fr, chan->dname);
  866. Context;
  867. if ((!channel_private(chan) || (channel_private(chan) && (chan_op(fr) || glob_owner(fr)))) &&
  868. (glob_owner(fr) || ((glob_op(fr) || chan_op(fr)) && !(chan_deop(fr) || glob_deop(fr))))) {
  869. if (!first) {
  870. dprintf(idx, STR("%s %s access to these channels:\n"), handle ? u->handle : "You", handle ? "has" : "have");
  871. first = 1;
  872. }
  873. dprintf(idx, format, chan->dname, channel_inactive(chan) ? "(inactive) " : "",
  874. channel_private(chan) ? "(private) " : "", !channel_manop(chan) ? "(no manop) " : "",
  875. channel_bitch(chan) ? "(bitch) " : "", channel_closed(chan) ? "(closed)" : "");
  876. }
  877. }
  878. if (!first)
  879. dprintf(idx, "%s %s not have access to any channels.\n", handle ? u->handle : "You", handle ? "does" : "do");
  880. Context;
  881. }
  882. int getting_users()
  883. {
  884. int i;
  885. for (i = 0; i < dcc_total; i++)
  886. if ((dcc[i].type == &DCC_BOT) && (dcc[i].status & STAT_GETTING))
  887. return 1;
  888. return 0;
  889. }
  890. int prand(int *seed, int range)
  891. {
  892. long long i1;
  893. i1 = *seed;
  894. i1 = (i1 * 0x08088405 + 1) & 0xFFFFFFFF;
  895. *seed = i1;
  896. i1 = (i1 * range) >> 32;
  897. return i1;
  898. }
  899. /*
  900. * Logging functions
  901. */
  902. /* Log something
  903. * putlog(level,channel_name,format,...);
  904. */
  905. void putlog EGG_VARARGS_DEF(int, arg1)
  906. {
  907. int i, type, tsl = 0, dohl = 0; //hl
  908. char *format, *chname, s[LOGLINELEN], s1[256], *out, ct[81], *s2, stamp[34], buf2[LOGLINELEN]; // *hub, hublog[20], mys[256]
  909. va_list va;
  910. #ifdef HUB
  911. time_t now2 = time(NULL);
  912. #endif
  913. struct tm *t;
  914. t = 0;
  915. type = EGG_VARARGS_START(int, arg1, va);
  916. chname = va_arg(va, char *);
  917. format = va_arg(va, char *);
  918. //The putlog should not be broadcast over bots, @ is *.
  919. if ((chname[0] == '*'))
  920. dohl = 1;
  921. #ifdef HUB
  922. if (shtime) {
  923. t = localtime(&now2);
  924. egg_strftime(stamp, sizeof(stamp) - 2, LOG_TS, t);
  925. strcat(stamp, " ");
  926. tsl = strlen(stamp);
  927. }
  928. #endif
  929. /* Format log entry at offset 'tsl,' then i can prepend the timestamp */
  930. out = s+tsl;
  931. /* No need to check if out should be null-terminated here,
  932. * just do it! <cybah>
  933. */
  934. egg_vsnprintf(out, LOGLINEMAX - tsl, format, va);
  935. // egg_vsnprintf(hub, LOGLINEMAX - hl, format, va);
  936. out[LOGLINEMAX - tsl] = 0;
  937. // hub[LOGLINEMAX - hl] = 0;
  938. if (keep_all_logs) {
  939. if (!logfile_suffix[0])
  940. egg_strftime(ct, 12, ".%d%b%Y", t);
  941. else {
  942. egg_strftime(ct, 80, logfile_suffix, t);
  943. ct[80] = 0;
  944. s2 = ct;
  945. /* replace spaces by underscores */
  946. while (s2[0]) {
  947. if (s2[0] == ' ')
  948. s2[0] = '_';
  949. s2++;
  950. }
  951. }
  952. }
  953. /* Place the timestamp in the string to be printed */
  954. if ((out[0]) && (shtime)) {
  955. strncpy(s, stamp, tsl);
  956. out = s;
  957. }
  958. /* if (hub[0]) {
  959. strncpy(mys, hublog, hl);
  960. hub = mys;
  961. }*/
  962. strcat(out, "\n");
  963. // strcat(hub, "\n");
  964. if (!use_stderr) {
  965. for (i = 0; i < max_logs; i++) {
  966. if ((logs[i].filename != NULL) && (logs[i].mask & type) &&
  967. ((chname[0] == '@') || (chname[0] == '*') || (logs[i].chname[0] == '*') ||
  968. (!rfc_casecmp(chname, logs[i].chname)))) {
  969. if (logs[i].f == NULL) {
  970. /* Open this logfile */
  971. if (keep_all_logs) {
  972. egg_snprintf(s1, 256, "%s%s", logs[i].filename, ct);
  973. logs[i].f = fopen(s1, "a+");
  974. } else
  975. logs[i].f = fopen(logs[i].filename, "a+");
  976. }
  977. if (logs[i].f != NULL) {
  978. /* Check if this is the same as the last line added to
  979. * the log. <cybah>
  980. */
  981. if (!egg_strcasecmp(out + tsl, logs[i].szlast))
  982. /* It is a repeat, so increment repeats */
  983. logs[i].repeats++;
  984. else {
  985. /* Not a repeat, check if there were any repeat
  986. * lines previously...
  987. */
  988. if (logs[i].repeats > 0) {
  989. /* Yep.. so display 'last message repeated x times'
  990. * then reset repeats. We want the current time here,
  991. * so put that in the file first.
  992. */
  993. fprintf(logs[i].f, stamp);
  994. fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
  995. logs[i].repeats = 0;
  996. /* No need to reset logs[i].szlast here
  997. * because we update it later on...
  998. */
  999. }
  1000. fputs(out, logs[i].f);
  1001. strncpyz(logs[i].szlast, out + tsl, LOGLINEMAX);
  1002. }
  1003. }
  1004. }
  1005. }
  1006. }
  1007. /* echo line to hubs (not if it was on a +h though)*/
  1008. if (dohl) {
  1009. tand_t *bot;
  1010. struct userrec *ubot;
  1011. sprintf(buf2, "hl %d %s", type, out);
  1012. if (userlist && !loading) {
  1013. for (bot = tandbot ;bot ; bot = bot->next) {
  1014. ubot = get_user_by_handle(userlist, bot->bot);
  1015. if (ubot) {
  1016. if (bot_hublevel(ubot) < 999) {
  1017. putbot(ubot->handle, buf2);
  1018. }
  1019. }
  1020. }
  1021. } else {
  1022. botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
  1023. }
  1024. }
  1025. for (i = 0; i < dcc_total; i++)
  1026. if ((dcc[i].type == &DCC_CHAT) && (dcc[i].u.chat->con_flags & type)) {
  1027. if ((chname[0] == '@') || (chname[0] == '*') || (dcc[i].u.chat->con_chan[0] == '*') ||
  1028. (!rfc_casecmp(chname, dcc[i].u.chat->con_chan)))
  1029. dprintf(i, "%s", out);
  1030. }
  1031. if ((!backgrd) && (!con_chan) && (!term_z))
  1032. dprintf(DP_STDOUT, "%s", out);
  1033. else if ((type & LOG_MISC) && use_stderr) {
  1034. if (shtime)
  1035. out += tsl;
  1036. dprintf(DP_STDERR, "%s", s);
  1037. }
  1038. va_end(va);
  1039. }
  1040. /* Called as soon as the logfile suffix changes. All logs are closed
  1041. * and the new suffix is stored in `logfile_suffix'.
  1042. */
  1043. void logsuffix_change(char *s)
  1044. {
  1045. int i;
  1046. char *s2 = logfile_suffix;
  1047. debug0("Logfile suffix changed. Closing all open logs.");
  1048. strcpy(logfile_suffix, s);
  1049. while (s2[0]) {
  1050. if (s2[0] == ' ')
  1051. s2[0] = '_';
  1052. s2++;
  1053. }
  1054. for (i = 0; i < max_logs; i++) {
  1055. if (logs[i].f) {
  1056. fflush(logs[i].f);
  1057. fclose(logs[i].f);
  1058. logs[i].f = NULL;
  1059. }
  1060. }
  1061. }
  1062. void check_logsize()
  1063. {
  1064. struct stat ss;
  1065. int i;
  1066. /* int x=1; */
  1067. char buf[1024]; /* Should be plenty */
  1068. if (!keep_all_logs && max_logsize > 0) {
  1069. for (i = 0; i < max_logs; i++) {
  1070. if (logs[i].filename) {
  1071. if (stat(logs[i].filename, &ss) != 0) {
  1072. break;
  1073. }
  1074. if ((ss.st_size >> 10) > max_logsize) {
  1075. if (logs[i].f) {
  1076. /* write to the log before closing it huh.. */
  1077. putlog(LOG_MISC, "*", MISC_CLOGS, logs[i].filename, ss.st_size);
  1078. fflush(logs[i].f);
  1079. fclose(logs[i].f);
  1080. logs[i].f = NULL;
  1081. }
  1082. egg_snprintf(buf, sizeof buf, "%s.yesterday", logs[i].filename);
  1083. buf[1023] = 0;
  1084. unlink(buf);
  1085. movefile(logs[i].filename, buf);
  1086. }
  1087. }
  1088. }
  1089. }
  1090. }
  1091. /* Flush the logfiles to disk
  1092. */
  1093. void flushlogs()
  1094. {
  1095. int i;
  1096. /* Logs may not be initialised yet. */
  1097. if (!logs)
  1098. return;
  1099. /* Now also checks to see if there's a repeat message and
  1100. * displays the 'last message repeated...' stuff too <cybah>
  1101. */
  1102. for (i = 0; i < max_logs; i++) {
  1103. if (logs[i].f != NULL) {
  1104. if ((logs[i].repeats > 0) && quick_logs) {
  1105. /* Repeat.. if quicklogs used then display 'last message
  1106. * repeated x times' and reset repeats.
  1107. */
  1108. char stamp[32];
  1109. egg_strftime(&stamp[0], 32, LOG_TS, localtime(&now));
  1110. fprintf(logs[i].f, "%s ", stamp);
  1111. fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
  1112. /* Reset repeats */
  1113. logs[i].repeats = 0;
  1114. }
  1115. fflush(logs[i].f);
  1116. }
  1117. }
  1118. }
  1119. char *extracthostname(char *hostmask)
  1120. {
  1121. char *p = strrchr(hostmask, '@');
  1122. return p ? p + 1 : "";
  1123. }
  1124. /* Create a string with random letters and digits
  1125. */
  1126. void make_rand_str(char *s, int len)
  1127. {
  1128. int j, r = 0;
  1129. Context;
  1130. for (j = 0; j < len; j++) {
  1131. r = random();
  1132. if (r % 4 == 0)
  1133. s[j] = '0' + (random() % 10);
  1134. else if (r % 4 == 1)
  1135. s[j] = 'a' + (random() % 26);
  1136. else if (r % 4 == 2)
  1137. s[j] = 'A' + (random() % 26);
  1138. else
  1139. s[j] = '!' + (random() % 15);
  1140. if (s[j] == 33 || s[j] == 37 || s[j] == 34 || s[j] == 40 || s[j] == 41 || s[j] == 38 || s[j] == 36) //no % ( ) &
  1141. s[j] = 35;
  1142. }
  1143. s[len] = '\0';
  1144. // s[len] = 0;
  1145. }
  1146. /* Convert an octal string into a decimal integer value. If the string
  1147. * is empty or contains non-octal characters, -1 is returned.
  1148. */
  1149. int oatoi(const char *octal)
  1150. {
  1151. register int i;
  1152. if (!*octal)
  1153. return -1;
  1154. for (i = 0; ((*octal >= '0') && (*octal <= '7')); octal++)
  1155. i = (i * 8) + (*octal - '0');
  1156. if (*octal)
  1157. return -1;
  1158. return i;
  1159. }
  1160. /* Return an allocated buffer which contains a copy of the string
  1161. * 'str', with all 'div' characters escaped by 'mask'. 'mask'
  1162. * characters are escaped too.
  1163. *
  1164. * Remember to free the returned memory block.
  1165. */
  1166. char *str_escape(const char *str, const char div, const char mask)
  1167. {
  1168. const int len = strlen(str);
  1169. int buflen = (2 * len), blen = 0;
  1170. char *buf = nmalloc(buflen + 1), *b = buf;
  1171. const char *s;
  1172. if (!buf)
  1173. return NULL;
  1174. for (s = str; *s; s++) {
  1175. /* Resize buffer. */
  1176. if ((buflen - blen) <= 3) {
  1177. buflen = (buflen * 2);
  1178. buf = nrealloc(buf, buflen + 1);
  1179. if (!buf)
  1180. return NULL;
  1181. b = buf + blen;
  1182. }
  1183. if (*s == div || *s == mask) {
  1184. sprintf(b, "%c%02x", mask, *s);
  1185. b += 3;
  1186. blen += 3;
  1187. } else {
  1188. *(b++) = *s;
  1189. blen++;
  1190. }
  1191. }
  1192. *b = 0;
  1193. return buf;
  1194. }
  1195. /* Search for a certain character 'div' in the string 'str', while
  1196. * ignoring escaped characters prefixed with 'mask'.
  1197. *
  1198. * The string
  1199. *
  1200. * "\\3a\\5c i am funny \\3a):further text\\5c):oink"
  1201. *
  1202. * as str, '\\' as mask and ':' as div would change the str buffer
  1203. * to
  1204. *
  1205. * ":\\ i am funny :)"
  1206. *
  1207. * and return a pointer to "further text\\5c):oink".
  1208. *
  1209. * NOTE: If you look carefully, you'll notice that strchr_unescape()
  1210. * behaves differently than strchr().
  1211. */
  1212. char *strchr_unescape(char *str, const char div, register const char esc_char)
  1213. {
  1214. char buf[3];
  1215. register char *s, *p;
  1216. buf[3] = 0;
  1217. for (s = p = str; *s; s++, p++) {
  1218. if (*s == esc_char) { /* Found escape character. */
  1219. /* Convert code to character. */
  1220. buf[0] = s[1], buf[1] = s[2];
  1221. *p = (unsigned char) strtol(buf, NULL, 16);
  1222. s += 2;
  1223. } else if (*s == div) {
  1224. *p = *s = 0;
  1225. return (s + 1); /* Found searched for character. */
  1226. } else
  1227. *p = *s;
  1228. }
  1229. *p = 0;
  1230. return NULL;
  1231. }
  1232. /* As strchr_unescape(), but converts the complete string, without
  1233. * searching for a specific delimiter character.
  1234. */
  1235. void str_unescape(char *str, register const char esc_char)
  1236. {
  1237. (void) strchr_unescape(str, 0, esc_char);
  1238. }
  1239. /* Kills the bot. s1 is the reason shown to other bots,
  1240. * s2 the reason shown on the partyline. (Sup 25Jul2001)
  1241. */
  1242. void kill_bot(char *s1, char *s2)
  1243. {
  1244. #ifdef HUB
  1245. write_userfile(-1);
  1246. #endif
  1247. call_hook(HOOK_DIE);
  1248. chatout("*** %s\n", s1);
  1249. botnet_send_chat(-1, botnetnick, s1);
  1250. botnet_send_bye();
  1251. fatal(s2, 0);
  1252. }
  1253. int isupdatehub()
  1254. {
  1255. #ifdef HUB
  1256. struct userrec *buser;
  1257. buser = get_user_by_handle(userlist, botnetnick);
  1258. if ((buser) && (buser->flags & USER_UPDATEHUB))
  1259. return 1;
  1260. else
  1261. #endif
  1262. return 0;
  1263. }
  1264. int ischanhub()
  1265. {
  1266. struct userrec *buser;
  1267. buser = get_user_by_handle(userlist, botnetnick);
  1268. if ((buser) && (buser->flags & USER_CHANHUB))
  1269. return 1;
  1270. else
  1271. return 0;
  1272. }
  1273. int issechub()
  1274. {
  1275. struct userrec *buser;
  1276. buser = get_user_by_handle(userlist, botnetnick);
  1277. if ((buser) && (buser->flags & USER_SECHUB))
  1278. return 1;
  1279. else
  1280. return 0;
  1281. }
  1282. #ifdef S_DCCPASS
  1283. int check_cmd_pass(char *cmd, char *pass)
  1284. {
  1285. struct cmd_pass *cp;
  1286. for (cp = cmdpass; cp; cp = cp->next)
  1287. if (!strcasecmp2(cmd, cp->name)) {
  1288. char tmp[32];
  1289. encrypt_pass(pass, tmp);
  1290. if (!strcmp(tmp, cp->pass))
  1291. return 1;
  1292. return 0;
  1293. }
  1294. return 0;
  1295. }
  1296. int has_cmd_pass(char *cmd)
  1297. {
  1298. struct cmd_pass *cp;
  1299. for (cp = cmdpass; cp; cp = cp->next)
  1300. if (!strcasecmp2(cmd, cp->name))
  1301. return 1;
  1302. return 0;
  1303. }
  1304. void set_cmd_pass(char *ln, int shareit) {
  1305. struct cmd_pass *cp;
  1306. char *cmd;
  1307. cmd = newsplit(&ln);
  1308. for (cp = cmdpass; cp; cp = cp->next)
  1309. if (!strcmp(cmd, cp->name))
  1310. break;
  1311. if (cp)
  1312. if (ln[0]) {
  1313. /* change */
  1314. strcpy(cp->pass, ln);
  1315. if (shareit)
  1316. botnet_send_cmdpass(-1, cp->name, cp->pass);
  1317. } else {
  1318. if (cp == cmdpass)
  1319. cmdpass = cp->next;
  1320. else {
  1321. struct cmd_pass *cp2;
  1322. cp2 = cmdpass;
  1323. while (cp2->next != cp)
  1324. cp2 = cp2->next;
  1325. cp2->next = cp->next;
  1326. }
  1327. if (shareit)
  1328. botnet_send_cmdpass(-1, cp->name, "");
  1329. nfree(cp->name);
  1330. nfree(cp);
  1331. } else if (ln[0]) {
  1332. /* create */
  1333. cp = nmalloc(sizeof(struct cmd_pass));
  1334. cp->next = cmdpass;
  1335. cmdpass = cp;
  1336. cp->name = nmalloc(strlen(cmd) + 1);
  1337. strcpy(cp->name, cmd);
  1338. strcpy(cp->pass, ln);
  1339. if (shareit)
  1340. botnet_send_cmdpass(-1, cp->name, cp->pass);
  1341. }
  1342. }
  1343. #endif
  1344. #ifdef S_LASTCHECK
  1345. char last_buf[128]="";
  1346. #endif
  1347. void check_last() {
  1348. #ifdef S_LASTCHECK
  1349. char user[20];
  1350. struct passwd *pw;
  1351. if (!strcmp((char *) CFG_LOGIN.ldata ? CFG_LOGIN.ldata : CFG_LOGIN.gdata ? CFG_LOGIN.gdata : "", STR("nocheck")))
  1352. return;
  1353. Context;
  1354. pw = getpwuid(geteuid());
  1355. Context;
  1356. if (!pw) return;
  1357. strncpy0(user, pw->pw_name ? pw->pw_name : "" , sizeof(user));
  1358. if (user[0]) {
  1359. char *out;
  1360. char buf[50];
  1361. sprintf(buf, STR("last %s"), user);
  1362. if (shell_exec(buf, NULL, &out, NULL)) {
  1363. if (out) {
  1364. char *p;
  1365. p = strchr(out, '\n');
  1366. if (p)
  1367. *p = 0;
  1368. if (strlen(out) > 10) {
  1369. if (last_buf[0]) {
  1370. if (strncmp(last_buf, out, sizeof(last_buf))) {
  1371. char wrk[16384];
  1372. sprintf(wrk, STR("Login: %s"), out);
  1373. detected(DETECT_LOGIN, wrk);
  1374. }
  1375. }
  1376. strncpy0(last_buf, out, sizeof(last_buf));
  1377. }
  1378. nfree(out);
  1379. }
  1380. }
  1381. }
  1382. #endif
  1383. }
  1384. void check_processes()
  1385. {
  1386. #ifdef S_PROCESSCHECK
  1387. char *proclist,
  1388. *out,
  1389. *p,
  1390. *np,
  1391. *curp,
  1392. buf[1024],
  1393. bin[128];
  1394. if (!strcmp((char *) CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : "", STR("nocheck")))
  1395. return;
  1396. proclist = (char *) (CFG_PROCESSLIST.ldata && ((char *) CFG_PROCESSLIST.ldata)[0] ?
  1397. CFG_PROCESSLIST.ldata : CFG_PROCESSLIST.gdata && ((char *) CFG_PROCESSLIST.gdata)[0] ? CFG_PROCESSLIST.gdata : NULL);
  1398. if (!proclist)
  1399. return;
  1400. if (!shell_exec(STR("ps x"), NULL, &out, NULL))
  1401. return;
  1402. /* Get this binary's filename */
  1403. strncpy0(buf, binname, sizeof(buf));
  1404. p = strrchr(buf, '/');
  1405. if (p) {
  1406. p++;
  1407. strncpy0(bin, p, sizeof(bin));
  1408. } else {
  1409. bin[0] = 0;
  1410. }
  1411. /* Fix up the "permitted processes" list */
  1412. p = nmalloc(strlen(proclist) + strlen(bin) + 6);
  1413. strcpy(p, proclist);
  1414. strcat(p, " ");
  1415. strcat(p, bin);
  1416. strcat(p, " ");
  1417. proclist = p;
  1418. curp = out;
  1419. while (curp) {
  1420. np = strchr(curp, '\n');
  1421. if (np)
  1422. *np++ = 0;
  1423. if (atoi(curp) > 0) {
  1424. char *pid,
  1425. *tty,
  1426. *stat,
  1427. *time,
  1428. cmd[512],
  1429. line[2048];
  1430. strncpy0(line, curp, sizeof(line));
  1431. /* it's a process line */
  1432. /* Assuming format: pid tty stat time cmd */
  1433. pid = newsplit(&curp);
  1434. tty = newsplit(&curp);
  1435. stat = newsplit(&curp);
  1436. time = newsplit(&curp);
  1437. strncpy0(cmd, curp, sizeof(cmd));
  1438. /* skip any <defunct> procs "/bin/sh -c" crontab stuff and binname crontab stuff */
  1439. if (!strstr(cmd, STR("<defunct>")) && !strncmp(cmd, STR("/bin/sh -c"), 10)
  1440. && !strncmp(cmd, binname, strlen(binname))) {
  1441. /* get rid of any args */
  1442. if ((p = strchr(cmd, ' ')))
  1443. *p = 0;
  1444. /* remove [] or () */
  1445. if (strlen(cmd)) {
  1446. p = cmd + strlen(cmd) - 1;
  1447. if (((cmd[0] == '(') && (*p == ')')) || ((cmd[0] == '[') && (*p == ']'))) {
  1448. *p = 0;
  1449. strcpy(buf, cmd + 1);
  1450. strcpy(cmd, buf);
  1451. }
  1452. }
  1453. /* remove path */
  1454. if ((p = strrchr(cmd, '/'))) {
  1455. p++;
  1456. strcpy(buf, p);
  1457. strcpy(cmd, buf);
  1458. }
  1459. /* skip "ps" */
  1460. if (strcmp(cmd, "ps")) {
  1461. /* see if proc's in permitted list */
  1462. strcat(cmd, " ");
  1463. if ((p = strstr(proclist, cmd))) {
  1464. /* Remove from permitted list */
  1465. while (*p != ' ')
  1466. *p++ = 1;
  1467. } else {
  1468. char wrk[16384];
  1469. sprintf(wrk, STR("Unexpected process: %s"), line);
  1470. detected(DETECT_PROCESS, wrk);
  1471. }
  1472. }
  1473. }
  1474. }
  1475. curp = np;
  1476. }
  1477. nfree(proclist);
  1478. if (out)
  1479. nfree(out);
  1480. #endif /* S_PROCESSCHECK */
  1481. }
  1482. void check_promisc()
  1483. {
  1484. #ifdef S_PROMISC
  1485. #ifdef SIOCGIFCONF
  1486. char buf[8192];
  1487. struct ifreq ifreq,
  1488. *ifr;
  1489. struct ifconf ifcnf;
  1490. char *cp,
  1491. *cplim;
  1492. int sock;
  1493. if (!strcmp((char *) CFG_PROMISC.ldata ? CFG_PROMISC.ldata : CFG_PROMISC.gdata ? CFG_PROMISC.gdata : "", STR("nocheck")))
  1494. return;
  1495. sock = socket(AF_INET, SOCK_STREAM, 0);
  1496. ifcnf.ifc_len = 8191;
  1497. ifcnf.ifc_buf = buf;
  1498. if (ioctl(sock, SIOCGIFCONF, (char *) &ifcnf) < 0) {
  1499. close(sock);
  1500. return;
  1501. }
  1502. ifr = ifcnf.ifc_req;
  1503. cplim = buf + ifcnf.ifc_len;
  1504. for (cp = buf; cp < cplim; cp += sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr)) {
  1505. ifr = (struct ifreq *) cp;
  1506. ifreq = *ifr;
  1507. if (!ioctl(sock, SIOCGIFFLAGS, (char *) &ifreq)) {
  1508. if (ifreq.ifr_flags & IFF_PROMISC) {
  1509. close(sock);
  1510. detected(DETECT_PROMISC, STR("Detected promiscous mode"));
  1511. return;
  1512. }
  1513. }
  1514. }
  1515. close(sock);
  1516. #endif /* SIOCGIFCONF */
  1517. #endif /* S_PROMISC */
  1518. }
  1519. #ifdef S_ANTITRACE
  1520. int traced = 0;
  1521. void got_trace(int z)
  1522. {
  1523. traced = 0;
  1524. }
  1525. #endif
  1526. void check_trace(int n)
  1527. {
  1528. #ifdef S_ANTITRACE
  1529. int x,
  1530. parent,
  1531. i;
  1532. struct sigaction sv,
  1533. *oldsv = NULL;
  1534. if (n && !strcmp((char *) CFG_TRACE.ldata ? CFG_TRACE.ldata : CFG_TRACE.gdata ? CFG_TRACE.gdata : "", STR("nocheck")))
  1535. return;
  1536. parent = getpid();
  1537. #ifdef __linux__
  1538. egg_bzero(&sv, sizeof(sv));
  1539. sv.sa_handler = got_trace;
  1540. sigemptyset(&sv.sa_mask);
  1541. oldsv = NULL;
  1542. sigaction(SIGTRAP, &sv, oldsv);
  1543. traced = 1;
  1544. asm("INT3");
  1545. sigaction(SIGTRAP, oldsv, NULL);
  1546. if (traced)
  1547. detected(DETECT_TRACE, STR("I'm being traced!"));
  1548. else {
  1549. x = fork();
  1550. if (x == -1)
  1551. return;
  1552. else if (x == 0) {
  1553. i = ptrace(PTRACE_ATTACH, parent, 0, 0);
  1554. if (i == (-1) && errno == EPERM)
  1555. detected(DETECT_TRACE, STR("I'm being traced!"));
  1556. else {
  1557. waitpid(parent, &i, 0);
  1558. kill(parent, SIGCHLD);
  1559. ptrace(PTRACE_DETACH, parent, 0, 0);
  1560. kill(parent, SIGCHLD);
  1561. }
  1562. exit(0);
  1563. } else
  1564. wait(&i);
  1565. }
  1566. #endif
  1567. #ifdef __FreeBSD__
  1568. x = fork();
  1569. if (x == -1)
  1570. return;
  1571. else if (x == 0) {
  1572. i = ptrace(PT_ATTACH, parent, 0, 0);
  1573. if (i == (-1) && errno == EBUSY)
  1574. detected(DETECT_TRACE, STR("I'm being traced"));
  1575. else {
  1576. wait(&i);
  1577. i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
  1578. kill(parent, SIGCHLD);
  1579. wait(&i);
  1580. i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
  1581. wait(&i);
  1582. }
  1583. exit(0);
  1584. } else
  1585. waitpid(x, NULL, 0);
  1586. #endif /* __FreeBSD__ */
  1587. #ifdef __OpenBD__
  1588. x = fork();
  1589. if (x == -1)
  1590. return;
  1591. else if (x == 0) {
  1592. i = ptrace(PT_ATTACH, parent, 0, 0);
  1593. if (i == (-1) && errno == EBUSY)
  1594. detected(DETECT_TRACE, STR("I'm being traced"));
  1595. else {
  1596. wait(&i);
  1597. i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
  1598. kill(parent, SIGCHLD);
  1599. wait(&i);
  1600. i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
  1601. wait(&i);
  1602. }
  1603. exit(0);
  1604. } else
  1605. waitpid(x, NULL, 0);
  1606. #endif /* __OpenBSD__ */
  1607. #endif /* S_ANTITRACE */
  1608. }
  1609. struct cfg_entry *check_can_set_cfg(char *target, char *entryname)
  1610. {
  1611. int i;
  1612. struct userrec *u;
  1613. struct cfg_entry *entry = NULL;
  1614. for (i = 0; i < cfg_count; i++)
  1615. if (!strcmp(cfg[i]->name, entryname)) {
  1616. entry = cfg[i];
  1617. break;
  1618. }
  1619. if (!entry)
  1620. return 0;
  1621. if (target) {
  1622. if (!(entry->flags & CFGF_LOCAL))
  1623. return 0;
  1624. if (!(u = get_user_by_handle(userlist, target)))
  1625. return 0;
  1626. if (!(u->flags & USER_BOT))
  1627. return 0;
  1628. } else {
  1629. if (!(entry->flags & CFGF_GLOBAL))
  1630. return 0;
  1631. }
  1632. return entry;
  1633. }
  1634. void set_cfg_str(char *target, char *entryname, char *data)
  1635. {
  1636. struct cfg_entry *entry;
  1637. int free = 0;
  1638. if (!(entry = check_can_set_cfg(target, entryname)))
  1639. return;
  1640. if (data && !strcmp(data, "-"))
  1641. data = NULL;
  1642. if (data && (strlen(data) >= 1024))
  1643. data[1023] = 0;
  1644. if (target) {
  1645. struct userrec *u = get_user_by_handle(userlist, target);
  1646. struct xtra_key *xk;
  1647. char *olddata = entry->ldata;
  1648. if (u && !strcmp(botnetnick, u->handle)) {
  1649. if (data) {
  1650. entry->ldata = nmalloc(strlen(data) + 1);
  1651. strcpy(entry->ldata, data);
  1652. } else
  1653. entry->ldata = NULL;
  1654. if (entry->localchanged) {
  1655. int valid = 1;
  1656. entry->localchanged(entry, olddata, &valid);
  1657. if (!valid) {
  1658. if (entry->ldata)
  1659. nfree(entry->ldata);
  1660. entry->ldata = olddata;
  1661. data = olddata;
  1662. olddata = NULL;
  1663. }
  1664. }
  1665. }
  1666. xk = nmalloc(sizeof(struct xtra_key));
  1667. egg_bzero(xk, sizeof(struct xtra_key));
  1668. xk->key = nmalloc(strlen(entry->name) + 1);
  1669. strcpy(xk->key, entry->name);
  1670. if (data) {
  1671. xk->data = nmalloc(strlen(data) + 1);
  1672. strcpy(xk->data, data);
  1673. }
  1674. set_user(&USERENTRY_CONFIG, u, xk);
  1675. if (olddata)
  1676. nfree(olddata);
  1677. } else {
  1678. char *olddata = entry->gdata;
  1679. if (data) {
  1680. free = 1;
  1681. entry->gdata = nmalloc(strlen(data) + 1);
  1682. strcpy(entry->gdata, data);
  1683. } else
  1684. entry->gdata = NULL;
  1685. if (entry->globalchanged) {
  1686. int valid = 1;
  1687. entry->globalchanged(entry, olddata, &valid);
  1688. if (!valid) {
  1689. if (entry->gdata)
  1690. nfree(entry->gdata);
  1691. entry->gdata = olddata;
  1692. olddata = NULL;
  1693. }
  1694. }
  1695. if (!cfg_noshare)
  1696. botnet_send_cfg_broad(-1, entry);
  1697. if (olddata)
  1698. nfree(olddata);
  1699. }
  1700. // if (free)
  1701. // nfree(entry->gdata);
  1702. }
  1703. void userfile_cfg_line(char *ln)
  1704. {
  1705. char *name;
  1706. int i;
  1707. struct cfg_entry *cfgent = NULL;
  1708. name = newsplit(&ln);
  1709. for (i = 0; !cfgent && (i < cfg_count); i++)
  1710. if (!strcmp(cfg[i]->name, name))
  1711. cfgent = cfg[i];
  1712. if (cfgent) {
  1713. set_cfg_str(NULL, cfgent->name, ln[0] ? ln : NULL);
  1714. } else
  1715. putlog(LOG_ERRORS, "*", STR("Unrecognized config entry %s in userfile"), name);
  1716. }
  1717. void got_config_share(int idx, char *ln)
  1718. {
  1719. char *name;
  1720. int i;
  1721. struct cfg_entry *cfgent = NULL;
  1722. cfg_noshare++;
  1723. name = newsplit(&ln);
  1724. for (i = 0; !cfgent && (i < cfg_count); i++)
  1725. if (!strcmp(cfg[i]->name, name))
  1726. cfgent = cfg[i];
  1727. if (cfgent) {
  1728. set_cfg_str(NULL, cfgent->name, ln[0] ? ln : NULL);
  1729. botnet_send_cfg_broad(idx, cfgent);
  1730. } else
  1731. putlog(LOG_ERRORS, "*", STR("Unrecognized config entry %s in userfile"), name);
  1732. cfg_noshare--;
  1733. }
  1734. void add_cfg(struct cfg_entry *entry)
  1735. {
  1736. cfg = (void *) user_realloc(cfg, sizeof(void *) * (cfg_count + 1));
  1737. cfg[cfg_count] = entry;
  1738. cfg_count++;
  1739. entry->ldata = NULL;
  1740. entry->gdata = NULL;
  1741. }
  1742. void trigger_cfg_changed()
  1743. {
  1744. int i;
  1745. struct userrec *u;
  1746. struct xtra_key *xk;
  1747. u = get_user_by_handle(userlist, botnetnick);
  1748. for (i = 0; i < cfg_count; i++) {
  1749. if (cfg[i]->flags & CFGF_LOCAL) {
  1750. xk = get_user(&USERENTRY_CONFIG, u);
  1751. while (xk && strcmp(xk->key, cfg[i]->name))
  1752. xk = xk->next;
  1753. if (xk) {
  1754. putlog(LOG_DEBUG, "*", STR("trigger_cfg_changed for %s"), cfg[i]->name ? cfg[i]->name : "(null)");
  1755. if (!strcmp(cfg[i]->name, xk->key ? xk->key : "")) {
  1756. set_cfg_str(botnetnick, cfg[i]->name, xk->data);
  1757. }
  1758. }
  1759. }
  1760. }
  1761. }
  1762. int shell_exec(char *cmdline, char *input, char **output, char **erroutput)
  1763. {
  1764. FILE *inpFile,
  1765. *outFile,
  1766. *errFile;
  1767. char tmpfile[161];
  1768. int x,
  1769. fd;
  1770. if (!cmdline)
  1771. return 0;
  1772. /* Set up temp files */
  1773. /* always use mkstemp() when handling temp filess! -dizz */
  1774. sprintf(tmpfile, STR("%s.in-XXXXXX"), tempdir);
  1775. if ((fd = mkstemp(tmpfile)) == -1 || (inpFile = fdopen(fd, "w+")) == NULL) {
  1776. if (fd != -1) {
  1777. unlink(tmpfile);
  1778. close(fd);
  1779. }
  1780. putlog(LOG_ERRORS, "*" , STR("exec: Couldn't open %s"), tmpfile);
  1781. return 0;
  1782. }
  1783. unlink(tmpfile);
  1784. if (input) {
  1785. if (fwrite(input, 1, strlen(input), inpFile) != strlen(input)) {
  1786. fclose(inpFile);
  1787. putlog(LOG_ERRORS, "*", STR("exec: Couldn't write to %s"), tmpfile);
  1788. return 0;
  1789. }
  1790. fseek(inpFile, 0, SEEK_SET);
  1791. }
  1792. unlink(tmpfile);
  1793. sprintf(tmpfile, STR("%s.err-XXXXXX"), tempdir);
  1794. if ((fd = mkstemp(tmpfile)) == -1 || (errFile = fdopen(fd, "w+")) == NULL) {
  1795. if (fd != -1) {
  1796. unlink(tmpfile);
  1797. close(fd);
  1798. }
  1799. putlog(LOG_ERRORS, "*", STR("exec: Couldn't open %s"), tmpfile);
  1800. return 0;
  1801. }
  1802. unlink(tmpfile);
  1803. sprintf(tmpfile, STR("%s.out-XXXXXX"), tempdir);
  1804. if ((fd = mkstemp(tmpfile)) == -1 || (outFile = fdopen(fd, "w+")) == NULL) {
  1805. if (fd != -1) {
  1806. unlink(tmpfile);
  1807. close(fd);
  1808. }
  1809. putlog(LOG_ERRORS, "*", STR("exec: Couldn't open %s"), tmpfile);
  1810. return 0;
  1811. }
  1812. unlink(tmpfile);
  1813. x = fork();
  1814. if (x == -1) {
  1815. putlog(LOG_ERRORS, "*", STR("exec: fork() failed"));
  1816. fclose(inpFile);
  1817. fclose(errFile);
  1818. fclose(outFile);
  1819. return 0;
  1820. }
  1821. if (x) {
  1822. /* Parent: wait for the child to complete */
  1823. int st = 0;
  1824. waitpid(x, &st, 0);
  1825. /* Now read the files into the buffers */
  1826. fclose(inpFile);
  1827. fflush(outFile);
  1828. fflush(errFile);
  1829. if (erroutput) {
  1830. char *buf;
  1831. int fs;
  1832. fseek(errFile, 0, SEEK_END);
  1833. fs = ftell(errFile);
  1834. if (fs == 0) {
  1835. (*erroutput) = NULL;
  1836. } else {
  1837. buf = nmalloc(fs + 1);
  1838. fseek(errFile, 0, SEEK_SET);
  1839. fread(buf, 1, fs, errFile);
  1840. buf[fs] = 0;
  1841. (*erroutput) = buf;
  1842. }
  1843. }
  1844. fclose(errFile);
  1845. if (output) {
  1846. char *buf;
  1847. int fs;
  1848. fseek(outFile, 0, SEEK_END);
  1849. fs = ftell(outFile);
  1850. if (fs == 0) {
  1851. (*output) = NULL;
  1852. } else {
  1853. buf = nmalloc(fs + 1);
  1854. fseek(outFile, 0, SEEK_SET);
  1855. fread(buf, 1, fs, outFile);
  1856. buf[fs] = 0;
  1857. (*output) = buf;
  1858. }
  1859. }
  1860. fclose(outFile);
  1861. return 1;
  1862. } else {
  1863. /* Child: make fd's and set them up as std* */
  1864. int ind,
  1865. outd,
  1866. errd;
  1867. char *argv[4];
  1868. ind = fileno(inpFile);
  1869. outd = fileno(outFile);
  1870. errd = fileno(errFile);
  1871. if (dup2(ind, STDIN_FILENO) == (-1)) {
  1872. exit(1);
  1873. }
  1874. if (dup2(outd, STDOUT_FILENO) == (-1)) {
  1875. exit(1);
  1876. }
  1877. if (dup2(errd, STDERR_FILENO) == (-1)) {
  1878. exit(1);
  1879. }
  1880. argv[0] = STR("/bin/sh");
  1881. argv[1] = STR("-c");
  1882. argv[2] = cmdline;
  1883. argv[3] = NULL;
  1884. execvp(argv[0], &argv[0]);
  1885. exit(1);
  1886. }
  1887. }
  1888. int ucnt = 0;
  1889. static void updatelocal(void)
  1890. {
  1891. #ifdef LEAF
  1892. module_entry *me;
  1893. #endif
  1894. Context;
  1895. if (ucnt < 300) {
  1896. ucnt++;
  1897. return;
  1898. }
  1899. del_hook(HOOK_SECONDLY, (Function) updatelocal);
  1900. ucnt = 0;
  1901. /* let's drop the server connection ASAP */
  1902. #ifdef LEAF
  1903. if ((me = module_find("server", 0, 0))) {
  1904. Function *func = me->funcs;
  1905. (func[SERVER_NUKESERVER]) ("Updating...");
  1906. }
  1907. #endif
  1908. botnet_send_chat(-1, botnetnick, "Updating...");
  1909. botnet_send_bye();
  1910. fatal("Updating...", 1);
  1911. usleep(2000 * 500);
  1912. bg_send_quit(BG_ABORT);
  1913. unlink(pid_file); //if this fails it is ok, cron will restart the bot, *hopefully*
  1914. system(binname); //start new bot.
  1915. exit(0);
  1916. }
  1917. int updatebin (int idx, char *par, int autoi)
  1918. {
  1919. char *path = NULL,
  1920. *newbin;
  1921. char buf[2048], old[1024];
  1922. struct stat sb;
  1923. int i;
  1924. #ifdef LEAF
  1925. module_entry *me;
  1926. #endif
  1927. path = newsplit(&par);
  1928. par = path;
  1929. if (!par[0]) {
  1930. if (idx)
  1931. dprintf(idx, "Not enough parameters.\n");
  1932. return 1;
  1933. }
  1934. path = nmalloc(strlen(binname) + strlen(par));
  1935. strcpy(path, binname);
  1936. newbin = strrchr(path, '/');
  1937. if (!newbin) {
  1938. nfree(path);
  1939. if (idx)
  1940. dprintf(idx, "Don't know current binary name\n");
  1941. return 1;
  1942. }
  1943. newbin++;
  1944. if (strchr(par, '/')) {
  1945. *newbin = 0;
  1946. if (idx)
  1947. dprintf(idx, "New binary must be in %s and name must be specified without path information\n", path);
  1948. nfree(path);
  1949. return 1;
  1950. }
  1951. strcpy(newbin, par);
  1952. if (!strcmp(path, binname)) {
  1953. nfree(path);
  1954. if (idx)
  1955. dprintf(idx, "Can't update with the current binary\n");
  1956. return 1;
  1957. }
  1958. if (stat(path, &sb)) {
  1959. if (idx)
  1960. dprintf(idx, "%s can't be accessed\n", path);
  1961. nfree(path);
  1962. return 1;
  1963. }
  1964. if (chmod(path, S_IRUSR | S_IWUSR | S_IXUSR)) {
  1965. if (idx)
  1966. dprintf(idx, "Can't set mode 0600 on %s\n", path);
  1967. nfree(path);
  1968. return 1;
  1969. }
  1970. //make a backup just in case.
  1971. egg_snprintf(old, sizeof old, "%s.bin.old", tempdir);
  1972. copyfile(binname, old);
  1973. if (movefile(path, binname)) {
  1974. if (idx)
  1975. dprintf(idx, "Can't rename %s to %s\n", path, binname);
  1976. nfree(path);
  1977. return 1;
  1978. }
  1979. sprintf(buf, "%s", binname);
  1980. #ifdef LEAF
  1981. if (localhub) {
  1982. /* if localhub = 1, this is the spawn bot and controls
  1983. * the spawning of new bots. */
  1984. sprintf(buf, "%s -P %d", buf, getpid());
  1985. }
  1986. #endif
  1987. //safe to run new binary..
  1988. #ifdef LEAF
  1989. if (!autoi && !localhub) //dont delete pid for auto update!!!
  1990. #endif
  1991. unlink(pid_file); //delete pid so new binary doesnt exit.
  1992. #ifdef HUB
  1993. listen_all(my_port, 1); //close the listening port...
  1994. #endif
  1995. i = system(buf);
  1996. if (i == -1 || i == 1) {
  1997. if (idx)
  1998. dprintf(idx, "Couldn't restart new binary (error %d)\n", i);
  1999. putlog(LOG_MISC, "*", "Couldn't restart new binary (error %d)\n", i);
  2000. return i;
  2001. } else {
  2002. #ifdef LEAF
  2003. if (!autoi && !localhub) {
  2004. /* let's drop the server connection ASAP */
  2005. if ((me = module_find("server", 0, 0))) {
  2006. Function *func = me->funcs;
  2007. (func[SERVER_NUKESERVER]) ("Updating...");
  2008. }
  2009. #endif
  2010. if (idx)
  2011. dprintf(idx, "Updating...bye\n");
  2012. putlog(LOG_MISC, "*", "Updating...\n");
  2013. botnet_send_chat(-1, botnetnick, "Updating...");
  2014. botnet_send_bye();
  2015. fatal("Updating...", 1);
  2016. usleep(2000 * 500);
  2017. bg_send_quit(BG_ABORT);
  2018. exit(0);
  2019. //No need to return :)
  2020. #ifdef LEAF
  2021. } else {
  2022. if (localhub && autoi) {
  2023. add_hook(HOOK_SECONDLY, (Function) updatelocal);
  2024. return 0;
  2025. }
  2026. }
  2027. #endif
  2028. }
  2029. //This shouldn't happen...
  2030. return 2;
  2031. }
  2032. void EncryptFile(char *infile, char *outfile)
  2033. {
  2034. char buf[8192];
  2035. // char *temps;
  2036. FILE *f, *f2;
  2037. Context;
  2038. f = fopen(infile, "r");
  2039. if(!f)
  2040. return;
  2041. f2 = fopen(outfile, "w");
  2042. if (!f2)
  2043. return;
  2044. Context;
  2045. while (fscanf(f,"%[^\n]\n",buf) != EOF) {
  2046. Context;
  2047. lfprintf(f2, "%s\n", buf);
  2048. Context;
  2049. }
  2050. fclose(f);
  2051. fclose(f2);
  2052. }
  2053. void DecryptFile(char *infile, char *outfile)
  2054. {
  2055. char buf[8192], *temps;
  2056. FILE *f, *f2;
  2057. f = fopen(infile, "r");
  2058. if (!f)
  2059. return;
  2060. f2 = fopen(outfile, "w");
  2061. if (!f2)
  2062. return;
  2063. while (fscanf(f,"%[^\n]\n",buf) != EOF) {
  2064. temps = (char *) decrypt_string(netpass, decryptit(buf));
  2065. fprintf(f2, "%s\n",temps);
  2066. nfree(temps);
  2067. }
  2068. fclose(f);
  2069. fclose(f2);
  2070. }
  2071. int bot_aggressive_to(struct userrec *u)
  2072. {
  2073. char mypval[20],
  2074. botpval[20];
  2075. link_pref_val(u, botpval);
  2076. link_pref_val(get_user_by_handle(userlist, botnetnick), mypval);
  2077. //printf("vals: my: %s them: %s\n", mypval, botpval);
  2078. if (strcmp(mypval, botpval) < 0)
  2079. return 1;
  2080. else
  2081. return 0;
  2082. }
  2083. void detected(int code, char *msg)
  2084. {
  2085. #ifdef LEAF
  2086. module_entry *me;
  2087. #endif
  2088. char *p = NULL;
  2089. char tmp[512];
  2090. struct userrec *u;
  2091. struct flag_record fr = { FR_GLOBAL, 0, 0 };
  2092. int act;
  2093. u = get_user_by_handle(userlist, botnetnick);
  2094. #ifdef S_LASTCHECK
  2095. if (code == DETECT_LOGIN)
  2096. p = (char *) (CFG_LOGIN.ldata ? CFG_LOGIN.ldata : (CFG_LOGIN.gdata ? CFG_LOGIN.gdata : NULL));
  2097. #endif
  2098. #ifdef S_ANTITRACE
  2099. if (code == DETECT_TRACE)
  2100. p = (char *) (CFG_TRACE.ldata ? CFG_TRACE.ldata : (CFG_TRACE.gdata ? CFG_TRACE.gdata : NULL));
  2101. #endif
  2102. #ifdef S_PROMISC
  2103. if (code == DETECT_PROMISC)
  2104. p = (char *) (CFG_PROMISC.ldata ? CFG_PROMISC.ldata : (CFG_PROMISC.gdata ? CFG_PROMISC.gdata : NULL));
  2105. #endif
  2106. #ifdef S_PROCESSCHECK
  2107. if (code == DETECT_PROCESS)
  2108. p = (char *) (CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : (CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : NULL));
  2109. #endif
  2110. #ifdef S_HIJACKCHECK
  2111. if (code == DETECT_SIGCONT)
  2112. p = (char *) (CFG_HIJACK.ldata ? CFG_HIJACK.ldata : (CFG_HIJACK.gdata ? CFG_HIJACK.gdata : NULL));
  2113. #endif
  2114. if (!p)
  2115. act = DET_WARN;
  2116. else if (!strcmp(p, STR("die")))
  2117. act = DET_DIE;
  2118. else if (!strcmp(p, STR("reject")))
  2119. act = DET_REJECT;
  2120. else if (!strcmp(p, STR("suicide")))
  2121. act = DET_SUICIDE;
  2122. else if (!strcmp(p, STR("nocheck")))
  2123. act = DET_NOCHECK;
  2124. else if (!strcmp(p, STR("ignore")))
  2125. act = DET_IGNORE;
  2126. else
  2127. act = DET_WARN;
  2128. switch (act) {
  2129. case DET_IGNORE:
  2130. break;
  2131. case DET_WARN:
  2132. putlog(LOG_WARN, "*", msg);
  2133. break;
  2134. case DET_REJECT:
  2135. do_fork();
  2136. putlog(LOG_WARN, "*", STR("Setting myself +d: %s"), msg);
  2137. sprintf(tmp, STR("+d: %s"), msg);
  2138. set_user(&USERENTRY_COMMENT, u, tmp);
  2139. get_user_flagrec(u, &fr, 0);
  2140. fr.global = USER_DEOP | USER_BOT;
  2141. set_user_flagrec(u, &fr, 0);
  2142. sleep(1);
  2143. break;
  2144. case DET_DIE:
  2145. putlog(LOG_WARN, "*", STR("Dying: %s"), msg);
  2146. sprintf(tmp, STR("Dying: %s"), msg);
  2147. set_user(&USERENTRY_COMMENT, u, tmp);
  2148. #ifdef LEAF
  2149. if ((me = module_find("server", 0, 0))) {
  2150. Function *func = me->funcs;
  2151. (func[SERVER_NUKESERVER]) ("BBL");
  2152. }
  2153. #endif
  2154. sleep(1);
  2155. fatal(msg, 0);
  2156. break;
  2157. case DET_SUICIDE:
  2158. putlog(LOG_WARN, "*", STR("Comitting suicide: %s"), msg);
  2159. sprintf(tmp, STR("Suicide: %s"), msg);
  2160. set_user(&USERENTRY_COMMENT, u, tmp);
  2161. #ifdef LEAF
  2162. if ((me = module_find("server", 0, 0))) {
  2163. Function *func = me->funcs;
  2164. (func[SERVER_NUKESERVER]) ("HARAKIRI!!");
  2165. }
  2166. #endif
  2167. sleep(1);
  2168. unlink(binname);
  2169. #ifdef HUB
  2170. unlink(userfile);
  2171. sprintf(tmp, STR("%s~"), userfile);
  2172. unlink(tmp);
  2173. // unlink(logfile);
  2174. // sprintf(tmp, STR("%s~"), logfile);
  2175. // unlink(tmp);
  2176. #endif
  2177. fatal(msg, 0);
  2178. break;
  2179. case DET_NOCHECK:
  2180. break;
  2181. }
  2182. }
  2183. char * kickreason(int kind) {
  2184. int r;
  2185. r=random();
  2186. switch (kind) {
  2187. case KICK_BANNED:
  2188. switch (r % 6) {
  2189. case 0: return STR("bye");
  2190. case 1: return STR("banned");
  2191. case 2: return STR("bummer");
  2192. case 3: return STR("go away");
  2193. case 4: return STR("cya around looser");
  2194. case 5: return STR("unwanted!");
  2195. }
  2196. case KICK_KUSER:
  2197. switch (r % 4) {
  2198. case 0: return STR("not wanted");
  2199. case 1: return STR("something tells me you're annoying");
  2200. case 2: return STR("don't bug me looser");
  2201. case 3: return STR("creep");
  2202. }
  2203. case KICK_KICKBAN:
  2204. switch (r % 4) {
  2205. case 0: return STR("gone");
  2206. case 1: return STR("stupid");
  2207. case 2: return STR("looser");
  2208. case 3: return STR("...");
  2209. }
  2210. case KICK_MASSDEOP:
  2211. switch (r % 8) {
  2212. case 0: return STR("spammer!");
  2213. case 1: return STR("easy on the modes now");
  2214. case 2: return STR("mode this");
  2215. case 3: return STR("nice try");
  2216. case 4: return STR("really?");
  2217. case 5: return STR("mIRC sux for mdop kiddo");
  2218. case 6: return STR("scary... really scary...");
  2219. case 7: return STR("you lost the game!");
  2220. }
  2221. case KICK_BADOP:
  2222. switch (r % 5) {
  2223. case 0: return STR("neat...");
  2224. case 1: return STR("oh, no you don't. go away.");
  2225. case 2: return STR("didn't you forget something now?");
  2226. case 3: return STR("no");
  2227. case 4: return STR("hijack this");
  2228. }
  2229. case KICK_BADOPPED:
  2230. switch (r % 5) {
  2231. case 0: return STR("buggar off kid");
  2232. case 1: return STR("asl?");
  2233. case 2: return STR("whoa... what a hacker... skills!");
  2234. case 3: return STR("yes! yes! yes! hit me baby one more time!");
  2235. case 4: return STR("with your skills, you're better off jacking off than hijacking");
  2236. }
  2237. case KICK_MANUALOP:
  2238. switch (r % 6) {
  2239. case 0: return STR("naughty kid");
  2240. case 1: return STR("didn't someone tell you that is bad?");
  2241. case 2: return STR("want perm?");
  2242. case 3: return STR("see how much good that did you?");
  2243. case 4: return STR("not a smart move...");
  2244. case 5: return STR("jackass!");
  2245. }
  2246. case KICK_MANUALOPPED:
  2247. switch (r % 8) {
  2248. case 0: return STR("your pal got mean friends. like me.");
  2249. case 1: return STR("uhh now.. don't wake me up...");
  2250. case 2: return STR("hi hun. missed me?");
  2251. case 3: return STR("spammer! die!");
  2252. case 4: return STR("boo!");
  2253. case 5: return STR("that @ was useful, don't ya think?");
  2254. case 6: return STR("not in my book");
  2255. case 7: return STR("lol, really?");
  2256. }
  2257. case KICK_CLOSED:
  2258. switch (r % 17) {
  2259. case 0: return STR("locked");
  2260. case 1: return STR("later");
  2261. case 2: return STR("closed for now");
  2262. case 3: return STR("sorry, but it's getting late, locking channel. cya around");
  2263. case 4: return STR("better safe than sorry");
  2264. case 5: return STR("cleanup, come back later");
  2265. case 6: return STR("this channel is closed");
  2266. case 7: return STR("shutting down for now");
  2267. case 8: return STR("lockdown");
  2268. case 9: return STR("reopening later");
  2269. case 10: return STR("not for the public atm");
  2270. case 11: return STR("private channel for now");
  2271. case 12: return STR("might reopen soon, might reopen later");
  2272. case 13: return STR("you're not supposed to be here right now");
  2273. case 14: return STR("sorry, closed");
  2274. case 15: return STR("try us later, atm we're locked down");
  2275. case 16: return STR("closed. try tomorrow");
  2276. }
  2277. case KICK_FLOOD:
  2278. switch (r % 7) {
  2279. case 0: return STR("so much bullshit in such a short time. amazing.");
  2280. case 1: return STR("slow down. i'm trying to read here.");
  2281. case 2: return STR("uhm... you actually think irc is for talking?");
  2282. case 3: return STR("talk talk talk");
  2283. case 4: return STR("blabbering are we?");
  2284. case 5: return STR("... and i don't even like you!");
  2285. case 6: return STR("and you're outa here...");
  2286. }
  2287. case KICK_NICKFLOOD:
  2288. switch (r % 7) {
  2289. case 0: return STR("make up your mind?");
  2290. case 1: return STR("be schizofrenic elsewhere");
  2291. case 2: return STR("I'm loosing track of you... not!");
  2292. case 3: return STR("that is REALLY annoying");
  2293. case 4: return STR("try this: /NICK looser");
  2294. case 5: return STR("playing hide 'n' seek?");
  2295. case 6: return STR("gotcha!");
  2296. }
  2297. case KICK_KICKFLOOD:
  2298. switch (r % 6) {
  2299. case 0: return STR("easier to just leave if you wan't to be alone");
  2300. case 1: return STR("cool down");
  2301. case 2: return STR("don't be so damned aggressive. that's my job.");
  2302. case 3: return STR("kicking's fun, isn't it?");
  2303. case 4: return STR("what's the rush?");
  2304. case 5: return STR("next time you do that, i'll kick you again");
  2305. }
  2306. case KICK_BOGUSUSERNAME:
  2307. return STR("bogus username");
  2308. case KICK_MEAN:
  2309. switch (r % 11) {
  2310. case 0: return STR("hey! that wasn't very nice!");
  2311. case 1: return STR("don't fuck with my pals");
  2312. case 2: return STR("meanie!");
  2313. case 3: return STR("I can be a bitch too...");
  2314. case 4: return STR("leave the bots alone, will ya?");
  2315. case 5: return STR("not very clever");
  2316. case 6: return STR("watch it");
  2317. case 7: return STR("fuck off");
  2318. case 8: return STR("easy now. that's a friend.");
  2319. case 9: return STR("abuse of power. leave that to me, will ya?");
  2320. case 10: return STR("there as some things you cannot do, and that was one of them...");
  2321. }
  2322. case KICK_BOGUSKEY:
  2323. return STR("I have a really hard time reading that key");
  2324. default:
  2325. return "OMFG@YUO";
  2326. }
  2327. }
  2328. char kickprefix[25] = "";
  2329. char bankickprefix[25] = "";
  2330. void makeplaincookie(char *chname, char *nick, char *buf)
  2331. {
  2332. /*
  2333. plain cookie:
  2334. Last 6 digits of time
  2335. Last 5 chars of nick
  2336. Last 4 regular chars of chan
  2337. */
  2338. char work[256],
  2339. work2[256];
  2340. int i,
  2341. n;
  2342. sprintf(work, STR("%010li"), (now + timesync));
  2343. strcpy(buf, (char *) &work[4]);
  2344. work[0] = 0;
  2345. if (strlen(nick) < 5)
  2346. while (strlen(work) + strlen(nick) < 5)
  2347. strcat(work, " ");
  2348. else
  2349. strcpy(work, (char *) &nick[strlen(nick) - 5]);
  2350. strcat(buf, work);
  2351. n = 3;
  2352. for (i = strlen(chname) - 1; (i >= 0) && (n >= 0); i--)
  2353. if (((unsigned char) chname[i] < 128) && ((unsigned char) chname[i] > 32)) {
  2354. work2[n] = tolower(chname[i]);
  2355. n--;
  2356. }
  2357. while (n >= 0)
  2358. work2[n--] = ' ';
  2359. work2[4] = 0;
  2360. strcat(buf, work2);
  2361. }
  2362. int goodpass(char *pass, int idx, char *nick)
  2363. {
  2364. int i, nalpha = 0, lcase = 0, ucase = 0, ocase = 0, tc;
  2365. char *tell;
  2366. tell = nmalloc(300);
  2367. if (!pass[0])
  2368. return 0;
  2369. for (i = 0; i < strlen(pass); i++) {
  2370. tc = (int) pass[i];
  2371. if (tc < 58 && tc > 47)
  2372. ocase++; //number
  2373. else if (tc < 91 && tc > 64)
  2374. ucase++; //upper case
  2375. else if (tc < 123 && tc > 96)
  2376. lcase++; //lower case
  2377. else
  2378. nalpha++; //non-alphabet/number
  2379. }
  2380. if (ocase < 1 || lcase < 2 || ucase < 2 || nalpha < 1 || strlen(pass) < 8) {
  2381. sprintf(tell, "Insecure pass, must be: ");
  2382. if (ocase < 1)
  2383. strcat(tell, "\002>= 1 number\002, ");
  2384. else
  2385. strcat(tell, ">= 1 number, ");
  2386. if (lcase < 2)
  2387. strcat(tell, "\002>= 2 lcase\002, ");
  2388. else
  2389. strcat(tell, ">= 2 lowercase, ");
  2390. if (ucase < 2)
  2391. strcat(tell, "\002>= 2 ucase\002, ");
  2392. else
  2393. strcat(tell, ">= 2 uppercase, ");
  2394. if (nalpha < 1)
  2395. strcat(tell, "\002>= 1 non-alpha/num\002, ");
  2396. else
  2397. strcat(tell, ">= 1 non-alpha/num, ");
  2398. if (strlen(pass) < 8)
  2399. strcat(tell, "\002>= 8 chars.\002");
  2400. else
  2401. strcat(tell, ">= 8 chars.");
  2402. if (idx)
  2403. dprintf(idx, "%s\n", tell);
  2404. else if (nick[0])
  2405. dprintf(DP_HELP, "NOTICE %s :%s\n", nick, tell);
  2406. return 0;
  2407. }
  2408. return 1;
  2409. }
  2410. //strcpy(dcc[idx].nick, char *string);
  2411. //.nick is char nick[uhostlen]
  2412. char *makehash(struct userrec *u, char *rand)
  2413. {
  2414. int i = 0;
  2415. MD5_CTX ctx;
  2416. unsigned char md5out[33];
  2417. char md5string[33], hash[500], *ret = NULL;
  2418. Context;
  2419. // strcpy(hash, rand);
  2420. Context;
  2421. // strcat(hash, get_user(&USERENTRY_SECPASS, u));
  2422. sprintf(hash, "%s%s%s", rand, (char *) get_user(&USERENTRY_SECPASS, u), authkey ? authkey : "");
  2423. putlog(LOG_DEBUG, "*", "Making hash from %s %s: %s", rand, get_user(&USERENTRY_SECPASS, u), hash);
  2424. MD5_Init(&ctx);
  2425. MD5_Update(&ctx, hash, strlen(hash));
  2426. MD5_Final(md5out, &ctx);
  2427. for(i=0; i<16; i++)
  2428. sprintf(md5string + (i*2), "%.2x", md5out[i]);
  2429. putlog(LOG_DEBUG, "*", "MD5 of hash: %s", md5string);
  2430. Context;
  2431. ret = md5string;
  2432. Context;
  2433. // sprintf(ret, "%s", md5string);
  2434. return ret;
  2435. }
  2436. int new_auth(void)
  2437. {
  2438. int i = auth_total;
  2439. Context;
  2440. if (auth_total == max_auth)
  2441. return -1;
  2442. auth_total++;
  2443. Context;
  2444. egg_bzero((char *) &auth[i], sizeof(struct auth_t));
  2445. Context;
  2446. return i;
  2447. }
  2448. int isauthed(char *host)
  2449. {
  2450. int i = 0;
  2451. Context;
  2452. for (i = 0; i < auth_total; i++) {
  2453. Context;
  2454. if (auth[i].host[0] && host[0] && !strcmp(auth[i].host, host))
  2455. Context;
  2456. return i;
  2457. }
  2458. Context;
  2459. return -1;
  2460. }
  2461. void removeauth(int n)
  2462. {
  2463. Context;
  2464. auth_total--;
  2465. if (n < auth_total)
  2466. egg_memcpy(&auth[n], &auth[auth_total], sizeof(struct auth_t));
  2467. else
  2468. egg_bzero(&auth[n], sizeof(struct auth_t)); /* drummer */
  2469. }
  2470. #ifdef S_GARBLESTRINGS
  2471. #define GARBLE_BUFFERS 40
  2472. unsigned char *garble_buffer[GARBLE_BUFFERS] = {
  2473. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  2474. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
  2475. };
  2476. int garble_ptr = (-1);
  2477. char *degarble(int len, char *g)
  2478. {
  2479. int i;
  2480. unsigned char x;
  2481. garble_ptr++;
  2482. if (garble_ptr == GARBLE_BUFFERS)
  2483. garble_ptr = 0;
  2484. if (garble_buffer[garble_ptr])
  2485. nfree(garble_buffer[garble_ptr]);
  2486. garble_buffer[garble_ptr] = nmalloc(len + 1);
  2487. x = 0xFF;
  2488. for (i = 0; i < len; i++) {
  2489. garble_buffer[garble_ptr][i] = g[i] ^ x;
  2490. x = garble_buffer[garble_ptr][i];
  2491. }
  2492. garble_buffer[garble_ptr][len] = 0;
  2493. return (char *) garble_buffer[garble_ptr];
  2494. }
  2495. #endif
  2496. char *replace (char *string, char *oldie, char *newbie)
  2497. {
  2498. static char newstring[1024] = "";
  2499. int str_index, newstr_index, oldie_index, end, new_len, old_len, cpy_len;
  2500. char *c;
  2501. if (string == NULL) return "";
  2502. if ((c = (char *) strstr(string, oldie)) == NULL) return string;
  2503. new_len = strlen(newbie);
  2504. old_len = strlen(oldie);
  2505. end = strlen(string) - old_len;
  2506. oldie_index = c - string;
  2507. newstr_index = 0;
  2508. str_index = 0;
  2509. while(str_index <= end && c != NULL) {
  2510. cpy_len = oldie_index-str_index;
  2511. strncpy(newstring + newstr_index, string + str_index, cpy_len);
  2512. newstr_index += cpy_len;
  2513. str_index += cpy_len;
  2514. strcpy(newstring + newstr_index, newbie);
  2515. newstr_index += new_len;
  2516. str_index += old_len;
  2517. if((c = (char *) strstr(string + str_index, oldie)) != NULL)
  2518. oldie_index = c - string;
  2519. }
  2520. strcpy(newstring + newstr_index, string + str_index);
  2521. return (newstring);
  2522. }