| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814 |
- /*
- * misc.c -- handles:
- * split() maskhost() dumplots() daysago() days() daysdur()
- * logging things
- * queueing output for the bot (msg and help)
- * resync buffers for sharebots
- * motd display and %var substitution
- *
- */
- #include "main.h"
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include "chan.h"
- #include "tandem.h"
- #include "modules.h"
- #include <pwd.h>
- #include <errno.h>
- #ifdef S_ANTITRACE
- #include <sys/ptrace.h>
- #include <sys/wait.h>
- #endif
- #include <net/if.h>
- #include <sys/ioctl.h>
- #include <sys/socket.h>
- #include <signal.h>
- #ifdef HAVE_UNAME
- # include <sys/utsname.h>
- #endif
- #include "stat.h"
- #include "bg.h"
- extern struct userrec *userlist;
- extern struct dcc_t *dcc;
- extern struct chanset_t *chanset;
- extern tand_t *tandbot;
- extern char version[], origbotname[], botname[],
- admin[], network[], motdfile[], ver[], botnetnick[],
- bannerfile[], logfile_suffix[], textdir[], userfile[],
- *binname, pid_file[], netpass[], tempdir[];
- extern int backgrd, con_chan, term_z, use_stderr, dcc_total, timesync,
- #ifdef HUB
- my_port,
- #endif
- keep_all_logs, quick_logs, strict_host, loading,
- localhub;
- extern time_t now;
- extern Tcl_Interp *interp;
- void detected(int, char *);
- int shtime = 1; /* Whether or not to display the time
- with console output */
- log_t *logs = 0; /* Logfiles */
- int max_logs = 5; /* Current maximum log files */
- int max_logsize = 0; /* Maximum logfile size, 0 for no limit */
- int conmask = LOG_MODES | LOG_CMDS | LOG_MISC; /* Console mask */
- int debug_output = 1; /* Disply output to server to LOG_SERVEROUT */
- int auth_total = 0;
- int max_auth = 100;
- struct auth_t *auth = 0;
- char authkey[121];
- char cmdprefix[1] = "+";
- struct cfg_entry CFG_MOTD = {
- "motd", CFGF_GLOBAL, NULL, NULL,
- NULL, NULL, NULL
- };
- void authkey_describe(struct cfg_entry * entry, int idx) {
- 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");
- }
- void authkey_changed(struct cfg_entry * entry, char * olddata, int * valid) {
- if (entry->ldata) {
- strncpy0(authkey, (char *) entry->ldata, sizeof authkey);
- } else if (entry->gdata) {
- strncpy0(authkey, (char *) entry->gdata, sizeof authkey);
- }
- }
- struct cfg_entry CFG_AUTHKEY = {
- "authkey", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
- authkey_changed, authkey_changed, authkey_describe
- };
- void cmdprefix_describe(struct cfg_entry *entry, int idx) {
- dprintf(idx, "cmdprefix is the prefix used for msg cmds, ie: !op or .op\n");
- }
- void cmdprefix_changed(struct cfg_entry * entry, char * olddata, int * valid) {
- if (entry->ldata) {
- strncpy0(cmdprefix, (char *) entry->ldata, sizeof cmdprefix);
- } else if (entry->gdata) {
- strncpy0(cmdprefix, (char *) entry->gdata, sizeof cmdprefix);
- }
- }
- struct cfg_entry CFG_CMDPREFIX = {
- "cmdprefix", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
- cmdprefix_changed, cmdprefix_changed, cmdprefix_describe
- };
- void misc_describe(struct cfg_entry *cfgent, int idx)
- {
- int i = 0;
- if (!strcmp(cfgent->name, STR("fork-interval"))) {
- 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"));
- i = 1;
- #ifdef S_LASTCHECK
- } else if (!strcmp(cfgent->name, STR("login"))) {
- dprintf(idx, STR("login sets how to handle someone logging in to the shell\n"));
- #endif
- #ifdef S_ANTITRACE
- } else if (!strcmp(cfgent->name, STR("trace"))) {
- dprintf(idx, STR("trace sets how to handle someone tracing/debugging the bot\n"));
- #endif
- #ifdef S_PROMISC
- } else if (!strcmp(cfgent->name, STR("promisc"))) {
- dprintf(idx, STR("promisc sets how to handle when a interface is set to promiscous mode\n"));
- #endif
- #ifdef S_PROCESSCHECK
- } else if (!strcmp(cfgent->name, STR("bad-process"))) {
- dprintf(idx, STR("bad-process sets how to handle when a running process not listed in process-list is detected\n"));
- } else if (!strcmp(cfgent->name, STR("process-list"))) {
- dprintf(idx, STR("process-list is a comma-separated list of \"expected processes\" running on the bots uid\n"));
- i = 1;
- #endif
- #ifdef S_HIJACKCHECK
- } else if (!strcmp(cfgent->name, STR("hijack"))) {
- dprintf(idx, STR("hijack sets how to handle when a commonly used hijack method attempt is detected. (recommended: die)\n"));
- #endif
- }
- if (!i)
- dprintf(idx, STR("Valid settings are: nocheck, ignore, warn, die, reject, suicide\n"));
- }
- void fork_lchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
- if (!cfgent->ldata)
- return;
- if (atoi(cfgent->ldata)<=0)
- *valid=0;
- }
- void fork_gchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
- if (!cfgent->gdata)
- return;
- if (atoi(cfgent->gdata)<=0)
- *valid=0;
- }
- void fork_describe(struct cfg_entry * cfgent, int idx) {
- 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"));
- }
- struct cfg_entry CFG_FORKINTERVAL = {
- "fork-interval", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
- fork_gchanged, fork_lchanged, fork_describe
- };
- void detect_lchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
- char * p = cfgent->ldata;
- if (!p)
- *valid=1;
- else if (strcmp(p, STR("ignore")) && strcmp(p, STR("die")) && strcmp(p, STR("reject"))
- && strcmp(p, STR("suicide")) && strcmp(p, STR("nocheck")) && strcmp(p, STR("warn")))
- *valid=0;
- }
- void detect_gchanged(struct cfg_entry * cfgent, char * oldval, int * valid) {
- char * p = (char *) cfgent->ldata;
- if (!p)
- *valid=1;
- else if (strcmp(p, STR("ignore")) && strcmp(p, STR("die")) && strcmp(p, STR("reject"))
- && strcmp(p, STR("suicide")) && strcmp(p, STR("nocheck")) && strcmp(p, STR("warn")))
- *valid=0;
- }
- #ifdef S_LASTCHECK
- struct cfg_entry CFG_LOGIN = {
- "login", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
- detect_gchanged, detect_lchanged, misc_describe
- };
- #endif
- #ifdef S_HIJACKCHECK
- struct cfg_entry CFG_HIJACK = {
- "hijack", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
- detect_gchanged, detect_lchanged, misc_describe
- };
- #endif
- #ifdef S_ANTITRACE
- struct cfg_entry CFG_TRACE = {
- "trace", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
- detect_gchanged, detect_lchanged, misc_describe
- };
- #endif
- #ifdef S_PROMISC
- struct cfg_entry CFG_PROMISC = {
- "promisc", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
- detect_gchanged, detect_lchanged, misc_describe
- };
- #endif
- #ifdef S_PROCESSCHECK
- struct cfg_entry CFG_BADPROCESS = {
- "bad-process", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
- detect_gchanged, detect_lchanged, misc_describe
- };
- struct cfg_entry CFG_PROCESSLIST = {
- "process-list", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
- NULL, NULL, misc_describe
- };
- #endif
- #ifdef S_DCCPASS
- struct cmd_pass *cmdpass = NULL;
- #endif
- /* unixware has no strcasecmp() without linking in a hefty library */
- #define upcase(c) (((c)>='a' && (c)<='z') ? (c)-'a'+'A' : (c))
- #if !HAVE_STRCASECMP
- #define strcasecmp strcasecmp2
- #endif
- int strcasecmp2(char *s1, char *s2)
- {
- while ((*s1) && (*s2) && (upcase(*s1) == upcase(*s2))) {
- s1++;
- s2++;
- }
- return upcase(*s1) - upcase(*s2);
- }
- /* this is cfg shit from servers/irc/ctcp because hub doesnt load
- * these mods */
- #ifdef HUB
- void servers_describe(struct cfg_entry * entry, int idx) {
- dprintf(idx, STR("servers is a comma-separated list of servers the bot will use\n"));
- }
- void servers_changed(struct cfg_entry * entry, char * olddata, int * valid) {
- }
- void servers6_describe(struct cfg_entry * entry, int idx) {
- dprintf(idx, STR("servers6 is a comma-separated list of servers the bot will use (FOR IPv6)\n"));
- }
- void servers6_changed(struct cfg_entry * entry, char * olddata, int * valid) {
- }
- void nick_describe(struct cfg_entry * entry, int idx) {
- dprintf(idx, "nick is the bots preferred nick when connecting/using .resetnick\n");
- }
- void nick_changed(struct cfg_entry * entry, char * olddata, int * valid) {
- }
- void realname_describe(struct cfg_entry * entry, int idx) {
- dprintf(idx, STR("realname is the bots \"real name\" when connecting\n"));
- }
- void realname_changed(struct cfg_entry * entry, char * olddata, int * valid) {
- }
- struct cfg_entry CFG_SERVERS = {
- "servers", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
- servers_changed, servers_changed, servers_describe
- };
- struct cfg_entry CFG_SERVERS6 = {
- "servers6", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
- servers6_changed, servers6_changed, servers6_describe
- };
- struct cfg_entry CFG_NICK = {
- "nick", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
- nick_changed, nick_changed, nick_describe
- };
- struct cfg_entry CFG_REALNAME = {
- "realname", CFGF_LOCAL | CFGF_GLOBAL, NULL, NULL,
- realname_changed, realname_changed, realname_describe
- };
- void getin_describe(struct cfg_entry *cfgent, int idx)
- {
- if (!strcmp(cfgent->name, STR("op-bots")))
- dprintf(idx, STR("op-bots is number of bots to ask every time a oprequest is to be made\n"));
- else if (!strcmp(cfgent->name, STR("in-bots")))
- dprintf(idx, STR("in-bots is number of bots to ask every time a inrequest is to be made\n"));
- else if (!strcmp(cfgent->name, STR("op-requests")))
- dprintf(idx, STR("op-requests (requests:seconds) limits how often the bot will ask for ops\n"));
- else if (!strcmp(cfgent->name, STR("lag-threshold")))
- dprintf(idx, STR("lag-threshold is maximum acceptable server lag for the bot to send/honor requests\n"));
- else if (!strcmp(cfgent->name, STR("op-time-slack")))
- dprintf(idx, STR("op-time-slack is number of seconds a opcookies encoded time value can be off from the bots current time\n"));
- else if (!strcmp(cfgent->name, STR("lock-threshold")))
- dprintf(idx, STR("Format H:L. When at least H hubs but L or less leafs are linked, lock all channels\n"));
- else if (!strcmp(cfgent->name, STR("kill-threshold")))
- dprintf(idx, STR("When more than kill-threshold bots have been killed/k-lined the last minute, channels are locked\n"));
- else if (!strcmp(cfgent->name, STR("fight-threshold")))
- 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"));
- else {
- dprintf(idx, STR("No description for %s ???\n"), cfgent->name);
- putlog(LOG_ERRORS, "*", STR("getin_describe() called with unknown config entry %s"), cfgent->name);
- }
- }
- void getin_changed(struct cfg_entry *cfgent, char *oldval, int *valid)
- {
- int i;
- if (!cfgent->gdata)
- return;
- *valid = 0;
- if (!strcmp(cfgent->name, STR("op-requests"))) {
- int L,
- R;
- char *value = cfgent->gdata;
- L = atoi(value);
- value = strchr(value, ':');
- if (!value)
- return;
- value++;
- R = atoi(value);
- if ((R >= 60) || (R <= 3) || (L < 1) || (L > R))
- return;
- *valid = 1;
- return;
- }
- if (!strcmp(cfgent->name, STR("lock-threshold"))) {
- int L,
- R;
- char *value = cfgent->gdata;
- L = atoi(value);
- value = strchr(value, ':');
- if (!value)
- return;
- value++;
- R = atoi(value);
- if ((R >= 1000) || (R < 0) || (L < 0) || (L > 100))
- return;
- *valid = 1;
- return;
- }
- i = atoi(cfgent->gdata);
- if (!strcmp(cfgent->name, STR("op-bots"))) {
- if ((i < 1) || (i > 10))
- return;
- } else if (!strcmp(cfgent->name, STR("invite-bots"))) {
- if ((i < 1) || (i > 10))
- return;
- } else if (!strcmp(cfgent->name, STR("key-bots"))) {
- if ((i < 1) || (i > 10))
- return;
- } else if (!strcmp(cfgent->name, STR("limit-bots"))) {
- if ((i < 1) || (i > 10))
- return;
- } else if (!strcmp(cfgent->name, STR("unban-bots"))) {
- if ((i < 1) || (i > 10))
- return;
- } else if (!strcmp(cfgent->name, STR("lag-threshold"))) {
- if ((i < 3) || (i > 60))
- return;
- } else if (!strcmp(cfgent->name, STR("fight-threshold"))) {
- if (i && ((i < 50) || (i > 1000)))
- return;
- } else if (!strcmp(cfgent->name, STR("kill-threshold"))) {
- if ((i < 0) || (i >= 200))
- return;
- } else if (!strcmp(cfgent->name, STR("op-time-slack"))) {
- if ((i < 30) || (i > 1200))
- return;
- }
- *valid = 1;
- return;
- }
- struct cfg_entry CFG_OPBOTS = {
- "op-bots", CFGF_GLOBAL, NULL, NULL,
- getin_changed, NULL, getin_describe
- };
- struct cfg_entry CFG_INBOTS = {
- "in-bots", CFGF_GLOBAL, NULL, NULL,
- getin_changed, NULL, getin_describe
- };
- struct cfg_entry CFG_LAGTHRESHOLD = {
- "lag-threshold", CFGF_GLOBAL, NULL, NULL,
- getin_changed, NULL, getin_describe
- };
- struct cfg_entry CFG_OPREQUESTS = {
- "op-requests", CFGF_GLOBAL, NULL, NULL,
- getin_changed, NULL, getin_describe
- };
- struct cfg_entry CFG_OPTIMESLACK = {
- "op-time-slack", CFGF_GLOBAL, NULL, NULL,
- getin_changed, NULL, getin_describe
- };
- #ifdef G_AUTOLOCK
- struct cfg_entry CFG_LOCKTHRESHOLD = {
- "lock-threshold", CFGF_GLOBAL, NULL, NULL,
- getin_changed, NULL, getin_describe
- };
- struct cfg_entry CFG_KILLTHRESHOLD = {
- "kill-threshold", CFGF_GLOBAL, NULL, NULL,
- getin_changed, NULL, getin_describe
- };
- struct cfg_entry CFG_FIGHTTHRESHOLD = {
- "fight-threshold", CFGF_GLOBAL, NULL, NULL,
- getin_changed, NULL, getin_describe
- };
- #endif /* G_AUTOLOCK */
- /* cloak
- void cloak_describe(struct cfg_entry *cfgent, int idx)
- {
- dprintf(idx, STR("cloak-script decides which BitchX script the bot cloaks. If set to 6, a random script will be cloaked.\n"));
- dprintf(idx, STR("Available: 0=crackrock, 1=neonapple, 2=tunnelvision, 3=argon, 4=evolver, 5=prevail\n"));
- }
- void cloak_changed(struct cfg_entry *cfgent, char * oldval, int * valid) {
- char * p;
- int i;
- p = cfgent->ldata ? cfgent->ldata : cfgent->gdata;
- if (!p)
- return;
- i=atoi(p);
- #ifdef LEAF
- if (i>=6)
- i = random() % 6;
- #endif
- *valid = ( (i>=0) && (i<=6));
- if (*valid)
- cloak_script = i;
- #ifdef LEAF
- scriptchanged();
- #endif
- }
- struct cfg_entry CFG_CLOAK_SCRIPT = {
- "cloak-script", CFGF_GLOBAL | CFGF_LOCAL, NULL, NULL,
- cloak_changed, cloak_changed, cloak_describe
- };
- */
- #endif
- /* end hub compat cfg */
- int cfg_count=0;
- struct cfg_entry ** cfg = NULL;
- int cfg_noshare=0;
- /* Expected memory usage
- */
- int expmem_misc()
- {
- #ifdef S_DCCPASS
- struct cmd_pass *cp = NULL;
- #endif
- int tot = 0, i;
- for (i=0;i<cfg_count;i++) {
- tot += sizeof(void *);
- if (cfg[i]->gdata)
- tot += strlen(cfg[i]->gdata) + 1;
- if (cfg[i]->ldata)
- tot += strlen(cfg[i]->ldata) + 1;
- }
- #ifdef S_DCCPASS
- for (cp=cmdpass;cp;cp=cp->next) {
- tot += sizeof(struct cmd_pass) + strlen(cp->name)+1;
- }
- #endif
- tot = sizeof(struct auth_t) * max_auth;
- return tot + (max_logs * sizeof(log_t));
- }
- void init_auth_max()
- {
- if (max_auth < 1)
- max_auth = 1;
- if (auth)
- auth = nrealloc(auth, sizeof(struct auth_t) * max_auth);
- else
- auth = nmalloc(sizeof(struct auth_t) * max_auth);
- }
- void init_misc()
- {
- static int last = 0;
- init_auth_max();
- if (max_logs < 1)
- max_logs = 1;
- if (logs)
- logs = nrealloc(logs, max_logs * sizeof(log_t));
- else
- logs = nmalloc(max_logs * sizeof(log_t));
- for (; last < max_logs; last++) {
- logs[last].filename = logs[last].chname = NULL;
- logs[last].mask = 0;
- logs[last].f = NULL;
- /* Added by cybah */
- logs[last].szlast[0] = 0;
- logs[last].repeats = 0;
- /* Added by rtc */
- logs[last].flags = 0;
- }
- add_cfg(&CFG_AUTHKEY);
- // add_cfg(&CFG_CMDPREFIX);
- add_cfg(&CFG_MOTD);
- add_cfg(&CFG_FORKINTERVAL);
- #ifdef S_LASTCHECK
- add_cfg(&CFG_LOGIN);
- #endif
- #ifdef S_HIJACKCHECK
- add_cfg(&CFG_HIJACK);
- #endif
- #ifdef S_ANTITRACE
- add_cfg(&CFG_TRACE);
- #endif
- #ifdef S_PROMISC
- add_cfg(&CFG_PROMISC);
- #endif
- #ifdef S_PROCESSCHECK
- add_cfg(&CFG_BADPROCESS);
- add_cfg(&CFG_PROCESSLIST);
- #endif
- #ifdef HUB
- add_cfg(&CFG_NICK);
- add_cfg(&CFG_SERVERS);
- add_cfg(&CFG_SERVERS6);
- add_cfg(&CFG_REALNAME);
- set_cfg_str(NULL, STR("realname"), "A deranged product of evil coders");
- add_cfg(&CFG_OPBOTS);
- add_cfg(&CFG_INBOTS);
- add_cfg(&CFG_LAGTHRESHOLD);
- add_cfg(&CFG_OPREQUESTS);
- add_cfg(&CFG_OPTIMESLACK);
- #ifdef G_AUTOLOCK
- add_cfg(&CFG_LOCKTHRESHOLD);
- add_cfg(&CFG_KILLTHRESHOLD);
- add_cfg(&CFG_FIGHTTHRESHOLD);
- #endif
- //cloak add_cfg(&CFG_CLOAK_SCRIPT);
- #endif
- }
- /*
- * Misc functions
- */
- /* low-level stuff for other modules
- */
- int is_file(const char *s)
- {
- struct stat ss;
- int i = stat(s, &ss);
- if (i < 0)
- return 0;
- if ((ss.st_mode & S_IFREG) || (ss.st_mode & S_IFLNK))
- return 1;
- return 0;
- }
- /* This implementation wont overrun dst - 'max' is the max bytes that dst
- * can be, including the null terminator. So if 'dst' is a 128 byte buffer,
- * pass 128 as 'max'. The function will _always_ null-terminate 'dst'.
- *
- * Returns: The number of characters appended to 'dst'.
- *
- * Usage eg.
- *
- * char buf[128];
- * size_t bufsize = sizeof(buf);
- *
- * buf[0] = 0, bufsize--;
- *
- * while (blah && bufsize) {
- * bufsize -= egg_strcatn(buf, <some-long-string>, sizeof(buf));
- * }
- *
- * <Cybah>
- */
- int egg_strcatn(char *dst, const char *src, size_t max)
- {
- size_t tmpmax = 0;
- /* find end of 'dst' */
- while (*dst && max > 0) {
- dst++;
- max--;
- }
- /* Store 'max', so we can use it to workout how many characters were
- * written later on.
- */
- tmpmax = max;
- /* copy upto, but not including the null terminator */
- while (*src && max > 1) {
- *dst++ = *src++;
- max--;
- }
- /* null-terminate the buffer */
- *dst = 0;
- /* Don't include the terminating null in our count, as it will cumulate
- * in loops - causing a headache for the caller.
- */
- return tmpmax - max;
- }
- int my_strcpy(register char *a, register char *b)
- {
- register char *c = b;
- while (*b)
- *a++ = *b++;
- *a = *b;
- return b - c;
- }
- /* Split first word off of rest and put it in first
- */
- void splitc(char *first, char *rest, char divider)
- {
- char *p = strchr(rest, divider);
- if (p == NULL) {
- if (first != rest && first)
- first[0] = 0;
- return;
- }
- *p = 0;
- if (first != NULL)
- strcpy(first, rest);
- if (first != rest)
- /* In most circumstances, strcpy with src and dst being the same buffer
- * can produce undefined results. We're safe here, as the src is
- * guaranteed to be at least 2 bytes higher in memory than dest. <Cybah>
- */
- strcpy(rest, p + 1);
- }
- /* As above, but lets you specify the 'max' number of bytes (EXCLUDING the
- * terminating null).
- *
- * Example of use:
- *
- * char buf[HANDLEN + 1];
- *
- * splitcn(buf, input, "@", HANDLEN);
- *
- * <Cybah>
- */
- void splitcn(char *first, char *rest, char divider, size_t max)
- {
- char *p = strchr(rest, divider);
- if (p == NULL) {
- if (first != rest && first)
- first[0] = 0;
- return;
- }
- *p = 0;
- if (first != NULL)
- strncpyz(first, rest, max);
- if (first != rest)
- /* In most circumstances, strcpy with src and dst being the same buffer
- * can produce undefined results. We're safe here, as the src is
- * guaranteed to be at least 2 bytes higher in memory than dest. <Cybah>
- */
- strcpy(rest, p + 1);
- }
- char *splitnick(char **blah)
- {
- char *p = strchr(*blah, '!'), *q = *blah;
- if (p) {
- *p = 0;
- *blah = p + 1;
- return q;
- }
- return "";
- }
- char *newsplit(char **rest)
- {
- register char *o, *r;
- if (!rest)
- return *rest = "";
- o = *rest;
- while (*o == ' ')
- o++;
- r = o;
- while (*o && (*o != ' '))
- o++;
- if (*o)
- *o++ = 0;
- *rest = o;
- return r;
- }
- /* Convert "abc!user@a.b.host" into "*!user@*.b.host"
- * or "abc!user@1.2.3.4" into "*!user@1.2.3.*"
- * or "abc!user@0:0:0:0:0:ffff:1.2.3.4" into "*!user@0:0:0:0:0:ffff:1.2.3.*"
- * or "abc!user@3ffe:604:2:b02e:6174:7265:6964:6573" into
- * "*!user@3ffe:604:2:b02e:6174:7265:6964:*"
- */
- void maskhost(const char *s, char *nw)
- {
- register const char *p, *q, *e, *f;
- int i;
- *nw++ = '*';
- *nw++ = '!';
- p = (q = strchr(s, '!')) ? q + 1 : s;
- /* Strip of any nick, if a username is found, use last 8 chars */
- if ((q = strchr(p, '@'))) {
- int fl = 0;
- if ((q - p) > 9) {
- nw[0] = '*';
- p = q - 7;
- i = 1;
- } else
- i = 0;
- while (*p != '@') {
- if (!fl && strchr("~+-^=", *p)) {
- if (strict_host)
- nw[i] = '?';
- else
- i--;
- } else
- nw[i] = *p;
- fl++;
- p++;
- i++;
- }
- nw[i++] = '@';
- q++;
- } else {
- nw[0] = '*';
- nw[1] = '@';
- i = 2;
- q = s;
- }
- nw += i;
- e = NULL;
- /* Now q points to the hostname, i point to where to put the mask */
- if ((!(p = strchr(q, '.')) || !(e = strchr(p + 1, '.'))) && !strchr(q, ':'))
- /* TLD or 2 part host */
- strcpy(nw, q);
- else {
- if (e == NULL) { /* IPv6 address? */
- const char *mask_str;
- f = strrchr(q, ':');
- if (strchr(f, '.')) { /* IPv4 wrapped in an IPv6? */
- f = strrchr(f, '.');
- mask_str = ".*";
- } else /* ... no, true IPv6. */
- mask_str = ":*";
- strncpy(nw, q, f - q);
- /* No need to nw[f-q] = 0 here, as the strcpy below will
- * terminate the string for us.
- */
- nw += (f - q);
- strcpy(nw, mask_str);
- } else {
- for (f = e; *f; f++);
- f--;
- if (*f >= '0' && *f <= '9') { /* Numeric IP address */
- while (*f != '.')
- f--;
- strncpy(nw, q, f - q);
- /* No need to nw[f-q] = 0 here, as the strcpy below will
- * terminate the string for us.
- */
- nw += (f - q);
- strcpy(nw, ".*");
- } else { /* Normal host >= 3 parts */
- /* a.b.c -> *.b.c
- * a.b.c.d -> *.b.c.d if tld is a country (2 chars)
- * OR *.c.d if tld is com/edu/etc (3 chars)
- * a.b.c.d.e -> *.c.d.e etc
- */
- const char *x = strchr(e + 1, '.');
- if (!x)
- x = p;
- else if (strchr(x + 1, '.'))
- x = e;
- else if (strlen(x) == 3)
- x = p;
- else
- x = e;
- sprintf(nw, "*%s", x);
- }
- }
- }
- }
- /* Dump a potentially super-long string of text.
- */
- void dumplots(int idx, const char *prefix, char *data)
- {
- char *p = data, *q, *n, c;
- const int max_data_len = 500 - strlen(prefix);
- if (!*data) {
- dprintf(idx, "%s\n", prefix);
- return;
- }
- while (strlen(p) > max_data_len) {
- q = p + max_data_len;
- /* Search for embedded linefeed first */
- n = strchr(p, '\n');
- if (n && n < q) {
- /* Great! dump that first line then start over */
- *n = 0;
- dprintf(idx, "%s%s\n", prefix, p);
- *n = '\n';
- p = n + 1;
- } else {
- /* Search backwards for the last space */
- while (*q != ' ' && q != p)
- q--;
- if (q == p)
- q = p + max_data_len;
- c = *q;
- *q = 0;
- dprintf(idx, "%s%s\n", prefix, p);
- *q = c;
- p = q;
- if (c == ' ')
- p++;
- }
- }
- /* Last trailing bit: split by linefeeds if possible */
- n = strchr(p, '\n');
- while (n) {
- *n = 0;
- dprintf(idx, "%s%s\n", prefix, p);
- *n = '\n';
- p = n + 1;
- n = strchr(p, '\n');
- }
- if (*p)
- dprintf(idx, "%s%s\n", prefix, p); /* Last trailing bit */
- }
- /* Convert an interval (in seconds) to one of:
- * "19 days ago", "1 day ago", "18:12"
- */
- void daysago(time_t now, time_t then, char *out)
- {
- if (now - then > 86400) {
- int days = (now - then) / 86400;
- sprintf(out, "%d day%s ago", days, (days == 1) ? "" : "s");
- return;
- }
- egg_strftime(out, 6, "%H:%M", localtime(&then));
- }
- /* Convert an interval (in seconds) to one of:
- * "in 19 days", "in 1 day", "at 18:12"
- */
- void days(time_t now, time_t then, char *out)
- {
- if (now - then > 86400) {
- int days = (now - then) / 86400;
- sprintf(out, "in %d day%s", days, (days == 1) ? "" : "s");
- return;
- }
- egg_strftime(out, 9, "at %H:%M", localtime(&now));
- }
- /* Convert an interval (in seconds) to one of:
- * "for 19 days", "for 1 day", "for 09:10"
- */
- void daysdur(time_t now, time_t then, char *out)
- {
- char s[81];
- int hrs, mins;
- if (now - then > 86400) {
- int days = (now - then) / 86400;
- sprintf(out, "for %d day%s", days, (days == 1) ? "" : "s");
- return;
- }
- strcpy(out, "for ");
- now -= then;
- hrs = (int) (now / 3600);
- mins = (int) ((now - (hrs * 3600)) / 60);
- sprintf(s, "%02d:%02d", hrs, mins);
- strcat(out, s);
- }
- /* show l33t banner */
- void show_banner(int idx)
- {
- dprintf(idx, STR(" _ _ _ \n"));
- dprintf(idx, STR("__ ___ __ __ _(_) |_| |__ \n"));
- dprintf(idx, STR("\\ \\ /\\ / / '__/ _` | | __| '_ \\ \n"));
- dprintf(idx, STR(" \\ V V /| | | (_| | | |_| | | |\n"));
- dprintf(idx, STR(" \\_/\\_/ |_| \\__,_|_|\\__|_| |_|\n"));
- dprintf(idx, STR(" by bryan \n"));
- }
- /* show motd to dcc chatter */
- void show_motd(int idx)
- {
- dprintf(idx, STR("Motd: "));
- if (CFG_MOTD.gdata && *(char *) CFG_MOTD.gdata)
- dprintf(idx, STR("%s\n"), (char *) CFG_MOTD.gdata);
- else
- dprintf(idx, STR("none\n"));
- }
- void show_channels(int idx, char *handle)
- {
- struct chanset_t *chan;
- struct flag_record fr = { FR_CHAN | FR_GLOBAL, 0, 0, 0, 0 };
- struct userrec *u;
- int first = 0, l = 0;
- char format[120];
- for (chan = chanset;chan;chan = chan->next)
- if (l < strlen(chan->dname))
- l = strlen(chan->dname);
- Context;
- if (handle)
- u = get_user_by_handle(userlist, handle);
- else
- u = dcc[idx].user;
- Context;
- egg_snprintf(format, sizeof format, " %%-%us %%-s%%-s%%-s%%-s%%-s\n", (l+2));
- for (chan = chanset;chan;chan = chan->next) {
- get_user_flagrec(u, &fr, chan->dname);
- Context;
- if ((!channel_private(chan) || (channel_private(chan) && (chan_op(fr) || glob_owner(fr)))) &&
- (glob_owner(fr) || ((glob_op(fr) || chan_op(fr)) && !(chan_deop(fr) || glob_deop(fr))))) {
- if (!first) {
- dprintf(idx, STR("%s %s access to these channels:\n"), handle ? u->handle : "You", handle ? "has" : "have");
-
- first = 1;
- }
- dprintf(idx, format, chan->dname, channel_inactive(chan) ? "(inactive) " : "",
- channel_private(chan) ? "(private) " : "", !channel_manop(chan) ? "(no manop) " : "",
- channel_bitch(chan) ? "(bitch) " : "", channel_closed(chan) ? "(closed)" : "");
- }
- }
- if (!first)
- dprintf(idx, "%s %s not have access to any channels.\n", handle ? u->handle : "You", handle ? "does" : "do");
- Context;
- }
- int getting_users()
- {
- int i;
- for (i = 0; i < dcc_total; i++)
- if ((dcc[i].type == &DCC_BOT) && (dcc[i].status & STAT_GETTING))
- return 1;
- return 0;
- }
- int prand(int *seed, int range)
- {
- long long i1;
- i1 = *seed;
- i1 = (i1 * 0x08088405 + 1) & 0xFFFFFFFF;
- *seed = i1;
- i1 = (i1 * range) >> 32;
- return i1;
- }
- /*
- * Logging functions
- */
- /* Log something
- * putlog(level,channel_name,format,...);
- */
- void putlog EGG_VARARGS_DEF(int, arg1)
- {
- int i, type, tsl = 0, dohl = 0; //hl
- char *format, *chname, s[LOGLINELEN], s1[256], *out, ct[81], *s2, stamp[34], buf2[LOGLINELEN]; // *hub, hublog[20], mys[256]
- va_list va;
- #ifdef HUB
- time_t now2 = time(NULL);
- #endif
- struct tm *t;
- t = 0;
- type = EGG_VARARGS_START(int, arg1, va);
- chname = va_arg(va, char *);
- format = va_arg(va, char *);
- //The putlog should not be broadcast over bots, @ is *.
- if ((chname[0] == '*'))
- dohl = 1;
- #ifdef HUB
- if (shtime) {
- t = localtime(&now2);
- egg_strftime(stamp, sizeof(stamp) - 2, LOG_TS, t);
- strcat(stamp, " ");
- tsl = strlen(stamp);
- }
- #endif
-
- /* Format log entry at offset 'tsl,' then i can prepend the timestamp */
- out = s+tsl;
- /* No need to check if out should be null-terminated here,
- * just do it! <cybah>
- */
- egg_vsnprintf(out, LOGLINEMAX - tsl, format, va);
- // egg_vsnprintf(hub, LOGLINEMAX - hl, format, va);
- out[LOGLINEMAX - tsl] = 0;
- // hub[LOGLINEMAX - hl] = 0;
- if (keep_all_logs) {
- if (!logfile_suffix[0])
- egg_strftime(ct, 12, ".%d%b%Y", t);
- else {
- egg_strftime(ct, 80, logfile_suffix, t);
- ct[80] = 0;
- s2 = ct;
- /* replace spaces by underscores */
- while (s2[0]) {
- if (s2[0] == ' ')
- s2[0] = '_';
- s2++;
- }
- }
- }
- /* Place the timestamp in the string to be printed */
- if ((out[0]) && (shtime)) {
- strncpy(s, stamp, tsl);
- out = s;
- }
- /* if (hub[0]) {
- strncpy(mys, hublog, hl);
- hub = mys;
- }*/
- strcat(out, "\n");
- // strcat(hub, "\n");
- if (!use_stderr) {
- for (i = 0; i < max_logs; i++) {
- if ((logs[i].filename != NULL) && (logs[i].mask & type) &&
- ((chname[0] == '@') || (chname[0] == '*') || (logs[i].chname[0] == '*') ||
- (!rfc_casecmp(chname, logs[i].chname)))) {
- if (logs[i].f == NULL) {
- /* Open this logfile */
- if (keep_all_logs) {
- egg_snprintf(s1, 256, "%s%s", logs[i].filename, ct);
- logs[i].f = fopen(s1, "a+");
- } else
- logs[i].f = fopen(logs[i].filename, "a+");
- }
- if (logs[i].f != NULL) {
- /* Check if this is the same as the last line added to
- * the log. <cybah>
- */
- if (!egg_strcasecmp(out + tsl, logs[i].szlast))
- /* It is a repeat, so increment repeats */
- logs[i].repeats++;
- else {
- /* Not a repeat, check if there were any repeat
- * lines previously...
- */
- if (logs[i].repeats > 0) {
- /* Yep.. so display 'last message repeated x times'
- * then reset repeats. We want the current time here,
- * so put that in the file first.
- */
- fprintf(logs[i].f, stamp);
- fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
-
- logs[i].repeats = 0;
- /* No need to reset logs[i].szlast here
- * because we update it later on...
- */
- }
- fputs(out, logs[i].f);
- strncpyz(logs[i].szlast, out + tsl, LOGLINEMAX);
- }
- }
- }
- }
- }
- /* echo line to hubs (not if it was on a +h though)*/
- if (dohl) {
- tand_t *bot;
- struct userrec *ubot;
- sprintf(buf2, "hl %d %s", type, out);
- if (userlist && !loading) {
- for (bot = tandbot ;bot ; bot = bot->next) {
- ubot = get_user_by_handle(userlist, bot->bot);
- if (ubot) {
- if (bot_hublevel(ubot) < 999) {
- putbot(ubot->handle, buf2);
- }
- }
- }
- } else {
- botnet_send_zapf_broad(-1, botnetnick, NULL, buf2);
- }
- }
- for (i = 0; i < dcc_total; i++)
- if ((dcc[i].type == &DCC_CHAT) && (dcc[i].u.chat->con_flags & type)) {
- if ((chname[0] == '@') || (chname[0] == '*') || (dcc[i].u.chat->con_chan[0] == '*') ||
- (!rfc_casecmp(chname, dcc[i].u.chat->con_chan)))
- dprintf(i, "%s", out);
- }
- if ((!backgrd) && (!con_chan) && (!term_z))
- dprintf(DP_STDOUT, "%s", out);
- else if ((type & LOG_MISC) && use_stderr) {
- if (shtime)
- out += tsl;
- dprintf(DP_STDERR, "%s", s);
- }
- va_end(va);
- }
- /* Called as soon as the logfile suffix changes. All logs are closed
- * and the new suffix is stored in `logfile_suffix'.
- */
- void logsuffix_change(char *s)
- {
- int i;
- char *s2 = logfile_suffix;
- debug0("Logfile suffix changed. Closing all open logs.");
- strcpy(logfile_suffix, s);
- while (s2[0]) {
- if (s2[0] == ' ')
- s2[0] = '_';
- s2++;
- }
- for (i = 0; i < max_logs; i++) {
- if (logs[i].f) {
- fflush(logs[i].f);
- fclose(logs[i].f);
- logs[i].f = NULL;
- }
- }
- }
- void check_logsize()
- {
- struct stat ss;
- int i;
- /* int x=1; */
- char buf[1024]; /* Should be plenty */
- if (!keep_all_logs && max_logsize > 0) {
- for (i = 0; i < max_logs; i++) {
- if (logs[i].filename) {
- if (stat(logs[i].filename, &ss) != 0) {
- break;
- }
- if ((ss.st_size >> 10) > max_logsize) {
- if (logs[i].f) {
- /* write to the log before closing it huh.. */
- putlog(LOG_MISC, "*", MISC_CLOGS, logs[i].filename, ss.st_size);
- fflush(logs[i].f);
- fclose(logs[i].f);
- logs[i].f = NULL;
- }
- egg_snprintf(buf, sizeof buf, "%s.yesterday", logs[i].filename);
- buf[1023] = 0;
- unlink(buf);
- movefile(logs[i].filename, buf);
- }
- }
- }
- }
- }
- /* Flush the logfiles to disk
- */
- void flushlogs()
- {
- int i;
- /* Logs may not be initialised yet. */
- if (!logs)
- return;
- /* Now also checks to see if there's a repeat message and
- * displays the 'last message repeated...' stuff too <cybah>
- */
- for (i = 0; i < max_logs; i++) {
- if (logs[i].f != NULL) {
- if ((logs[i].repeats > 0) && quick_logs) {
- /* Repeat.. if quicklogs used then display 'last message
- * repeated x times' and reset repeats.
- */
- char stamp[32];
- egg_strftime(&stamp[0], 32, LOG_TS, localtime(&now));
- fprintf(logs[i].f, "%s ", stamp);
- fprintf(logs[i].f, MISC_LOGREPEAT, logs[i].repeats);
- /* Reset repeats */
- logs[i].repeats = 0;
- }
- fflush(logs[i].f);
- }
- }
- }
- char *extracthostname(char *hostmask)
- {
- char *p = strrchr(hostmask, '@');
- return p ? p + 1 : "";
- }
- /* Create a string with random letters and digits
- */
- void make_rand_str(char *s, int len)
- {
- int j, r = 0;
- Context;
- for (j = 0; j < len; j++) {
- r = random();
- if (r % 4 == 0)
- s[j] = '0' + (random() % 10);
- else if (r % 4 == 1)
- s[j] = 'a' + (random() % 26);
- else if (r % 4 == 2)
- s[j] = 'A' + (random() % 26);
- else
- s[j] = '!' + (random() % 15);
- if (s[j] == 33 || s[j] == 37 || s[j] == 34 || s[j] == 40 || s[j] == 41 || s[j] == 38 || s[j] == 36) //no % ( ) &
- s[j] = 35;
-
- }
- s[len] = '\0';
- // s[len] = 0;
- }
- /* Convert an octal string into a decimal integer value. If the string
- * is empty or contains non-octal characters, -1 is returned.
- */
- int oatoi(const char *octal)
- {
- register int i;
- if (!*octal)
- return -1;
- for (i = 0; ((*octal >= '0') && (*octal <= '7')); octal++)
- i = (i * 8) + (*octal - '0');
- if (*octal)
- return -1;
- return i;
- }
- /* Return an allocated buffer which contains a copy of the string
- * 'str', with all 'div' characters escaped by 'mask'. 'mask'
- * characters are escaped too.
- *
- * Remember to free the returned memory block.
- */
- char *str_escape(const char *str, const char div, const char mask)
- {
- const int len = strlen(str);
- int buflen = (2 * len), blen = 0;
- char *buf = nmalloc(buflen + 1), *b = buf;
- const char *s;
- if (!buf)
- return NULL;
- for (s = str; *s; s++) {
- /* Resize buffer. */
- if ((buflen - blen) <= 3) {
- buflen = (buflen * 2);
- buf = nrealloc(buf, buflen + 1);
- if (!buf)
- return NULL;
- b = buf + blen;
- }
- if (*s == div || *s == mask) {
- sprintf(b, "%c%02x", mask, *s);
- b += 3;
- blen += 3;
- } else {
- *(b++) = *s;
- blen++;
- }
- }
- *b = 0;
- return buf;
- }
- /* Search for a certain character 'div' in the string 'str', while
- * ignoring escaped characters prefixed with 'mask'.
- *
- * The string
- *
- * "\\3a\\5c i am funny \\3a):further text\\5c):oink"
- *
- * as str, '\\' as mask and ':' as div would change the str buffer
- * to
- *
- * ":\\ i am funny :)"
- *
- * and return a pointer to "further text\\5c):oink".
- *
- * NOTE: If you look carefully, you'll notice that strchr_unescape()
- * behaves differently than strchr().
- */
- char *strchr_unescape(char *str, const char div, register const char esc_char)
- {
- char buf[3];
- register char *s, *p;
- buf[3] = 0;
- for (s = p = str; *s; s++, p++) {
- if (*s == esc_char) { /* Found escape character. */
- /* Convert code to character. */
- buf[0] = s[1], buf[1] = s[2];
- *p = (unsigned char) strtol(buf, NULL, 16);
- s += 2;
- } else if (*s == div) {
- *p = *s = 0;
- return (s + 1); /* Found searched for character. */
- } else
- *p = *s;
- }
- *p = 0;
- return NULL;
- }
- /* As strchr_unescape(), but converts the complete string, without
- * searching for a specific delimiter character.
- */
- void str_unescape(char *str, register const char esc_char)
- {
- (void) strchr_unescape(str, 0, esc_char);
- }
- /* Kills the bot. s1 is the reason shown to other bots,
- * s2 the reason shown on the partyline. (Sup 25Jul2001)
- */
- void kill_bot(char *s1, char *s2)
- {
- #ifdef HUB
- write_userfile(-1);
- #endif
- call_hook(HOOK_DIE);
- chatout("*** %s\n", s1);
- botnet_send_chat(-1, botnetnick, s1);
- botnet_send_bye();
- fatal(s2, 0);
- }
- int isupdatehub()
- {
- #ifdef HUB
- struct userrec *buser;
- buser = get_user_by_handle(userlist, botnetnick);
- if ((buser) && (buser->flags & USER_UPDATEHUB))
- return 1;
- else
- #endif
- return 0;
- }
- int ischanhub()
- {
- struct userrec *buser;
- buser = get_user_by_handle(userlist, botnetnick);
- if ((buser) && (buser->flags & USER_CHANHUB))
- return 1;
- else
- return 0;
- }
- int issechub()
- {
- struct userrec *buser;
- buser = get_user_by_handle(userlist, botnetnick);
- if ((buser) && (buser->flags & USER_SECHUB))
- return 1;
- else
- return 0;
-
- }
- #ifdef S_DCCPASS
- int check_cmd_pass(char *cmd, char *pass)
- {
- struct cmd_pass *cp;
- for (cp = cmdpass; cp; cp = cp->next)
- if (!strcasecmp2(cmd, cp->name)) {
- char tmp[32];
- encrypt_pass(pass, tmp);
- if (!strcmp(tmp, cp->pass))
- return 1;
- return 0;
- }
- return 0;
- }
- int has_cmd_pass(char *cmd)
- {
- struct cmd_pass *cp;
- for (cp = cmdpass; cp; cp = cp->next)
- if (!strcasecmp2(cmd, cp->name))
- return 1;
- return 0;
- }
- void set_cmd_pass(char *ln, int shareit) {
- struct cmd_pass *cp;
- char *cmd;
- cmd = newsplit(&ln);
- for (cp = cmdpass; cp; cp = cp->next)
- if (!strcmp(cmd, cp->name))
- break;
- if (cp)
- if (ln[0]) {
- /* change */
- strcpy(cp->pass, ln);
- if (shareit)
- botnet_send_cmdpass(-1, cp->name, cp->pass);
- } else {
- if (cp == cmdpass)
- cmdpass = cp->next;
- else {
- struct cmd_pass *cp2;
- cp2 = cmdpass;
- while (cp2->next != cp)
- cp2 = cp2->next;
- cp2->next = cp->next;
- }
- if (shareit)
- botnet_send_cmdpass(-1, cp->name, "");
- nfree(cp->name);
- nfree(cp);
- } else if (ln[0]) {
- /* create */
- cp = nmalloc(sizeof(struct cmd_pass));
- cp->next = cmdpass;
- cmdpass = cp;
- cp->name = nmalloc(strlen(cmd) + 1);
- strcpy(cp->name, cmd);
- strcpy(cp->pass, ln);
- if (shareit)
- botnet_send_cmdpass(-1, cp->name, cp->pass);
- }
- }
- #endif
- #ifdef S_LASTCHECK
- char last_buf[128]="";
- #endif
- void check_last() {
- #ifdef S_LASTCHECK
- char user[20];
- struct passwd *pw;
- if (!strcmp((char *) CFG_LOGIN.ldata ? CFG_LOGIN.ldata : CFG_LOGIN.gdata ? CFG_LOGIN.gdata : "", STR("nocheck")))
- return;
- Context;
- pw = getpwuid(geteuid());
- Context;
- if (!pw) return;
- strncpy0(user, pw->pw_name ? pw->pw_name : "" , sizeof(user));
- if (user[0]) {
- char *out;
- char buf[50];
- sprintf(buf, STR("last %s"), user);
- if (shell_exec(buf, NULL, &out, NULL)) {
- if (out) {
- char *p;
- p = strchr(out, '\n');
- if (p)
- *p = 0;
- if (strlen(out) > 10) {
- if (last_buf[0]) {
- if (strncmp(last_buf, out, sizeof(last_buf))) {
- char wrk[16384];
- sprintf(wrk, STR("Login: %s"), out);
- detected(DETECT_LOGIN, wrk);
- }
- }
- strncpy0(last_buf, out, sizeof(last_buf));
- }
- nfree(out);
- }
- }
- }
- #endif
- }
- void check_processes()
- {
- #ifdef S_PROCESSCHECK
- char *proclist,
- *out,
- *p,
- *np,
- *curp,
- buf[1024],
- bin[128];
- if (!strcmp((char *) CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : "", STR("nocheck")))
- return;
- proclist = (char *) (CFG_PROCESSLIST.ldata && ((char *) CFG_PROCESSLIST.ldata)[0] ?
- CFG_PROCESSLIST.ldata : CFG_PROCESSLIST.gdata && ((char *) CFG_PROCESSLIST.gdata)[0] ? CFG_PROCESSLIST.gdata : NULL);
- if (!proclist)
- return;
- if (!shell_exec(STR("ps x"), NULL, &out, NULL))
- return;
- /* Get this binary's filename */
- strncpy0(buf, binname, sizeof(buf));
- p = strrchr(buf, '/');
- if (p) {
- p++;
- strncpy0(bin, p, sizeof(bin));
- } else {
- bin[0] = 0;
- }
- /* Fix up the "permitted processes" list */
- p = nmalloc(strlen(proclist) + strlen(bin) + 6);
- strcpy(p, proclist);
- strcat(p, " ");
- strcat(p, bin);
- strcat(p, " ");
- proclist = p;
- curp = out;
- while (curp) {
- np = strchr(curp, '\n');
- if (np)
- *np++ = 0;
- if (atoi(curp) > 0) {
- char *pid,
- *tty,
- *stat,
- *time,
- cmd[512],
- line[2048];
- strncpy0(line, curp, sizeof(line));
- /* it's a process line */
- /* Assuming format: pid tty stat time cmd */
- pid = newsplit(&curp);
- tty = newsplit(&curp);
- stat = newsplit(&curp);
- time = newsplit(&curp);
- strncpy0(cmd, curp, sizeof(cmd));
- /* skip any <defunct> procs "/bin/sh -c" crontab stuff and binname crontab stuff */
- if (!strstr(cmd, STR("<defunct>")) && !strncmp(cmd, STR("/bin/sh -c"), 10)
- && !strncmp(cmd, binname, strlen(binname))) {
- /* get rid of any args */
- if ((p = strchr(cmd, ' ')))
- *p = 0;
- /* remove [] or () */
- if (strlen(cmd)) {
- p = cmd + strlen(cmd) - 1;
- if (((cmd[0] == '(') && (*p == ')')) || ((cmd[0] == '[') && (*p == ']'))) {
- *p = 0;
- strcpy(buf, cmd + 1);
- strcpy(cmd, buf);
- }
- }
- /* remove path */
- if ((p = strrchr(cmd, '/'))) {
- p++;
- strcpy(buf, p);
- strcpy(cmd, buf);
- }
- /* skip "ps" */
- if (strcmp(cmd, "ps")) {
- /* see if proc's in permitted list */
- strcat(cmd, " ");
- if ((p = strstr(proclist, cmd))) {
- /* Remove from permitted list */
- while (*p != ' ')
- *p++ = 1;
- } else {
- char wrk[16384];
- sprintf(wrk, STR("Unexpected process: %s"), line);
- detected(DETECT_PROCESS, wrk);
- }
- }
- }
- }
- curp = np;
- }
- nfree(proclist);
- if (out)
- nfree(out);
- #endif /* S_PROCESSCHECK */
- }
- void check_promisc()
- {
- #ifdef S_PROMISC
- #ifdef SIOCGIFCONF
- char buf[8192];
- struct ifreq ifreq,
- *ifr;
- struct ifconf ifcnf;
- char *cp,
- *cplim;
- int sock;
- if (!strcmp((char *) CFG_PROMISC.ldata ? CFG_PROMISC.ldata : CFG_PROMISC.gdata ? CFG_PROMISC.gdata : "", STR("nocheck")))
- return;
- sock = socket(AF_INET, SOCK_STREAM, 0);
- ifcnf.ifc_len = 8191;
- ifcnf.ifc_buf = buf;
- if (ioctl(sock, SIOCGIFCONF, (char *) &ifcnf) < 0) {
- close(sock);
- return;
- }
- ifr = ifcnf.ifc_req;
- cplim = buf + ifcnf.ifc_len;
- for (cp = buf; cp < cplim; cp += sizeof(ifr->ifr_name) + sizeof(ifr->ifr_addr)) {
- ifr = (struct ifreq *) cp;
- ifreq = *ifr;
- if (!ioctl(sock, SIOCGIFFLAGS, (char *) &ifreq)) {
- if (ifreq.ifr_flags & IFF_PROMISC) {
- close(sock);
- detected(DETECT_PROMISC, STR("Detected promiscous mode"));
- return;
- }
- }
- }
- close(sock);
- #endif /* SIOCGIFCONF */
- #endif /* S_PROMISC */
- }
- #ifdef S_ANTITRACE
- int traced = 0;
- void got_trace(int z)
- {
- traced = 0;
- }
- #endif
- void check_trace(int n)
- {
- #ifdef S_ANTITRACE
- int x,
- parent,
- i;
- struct sigaction sv,
- *oldsv = NULL;
- if (n && !strcmp((char *) CFG_TRACE.ldata ? CFG_TRACE.ldata : CFG_TRACE.gdata ? CFG_TRACE.gdata : "", STR("nocheck")))
- return;
- parent = getpid();
- #ifdef __linux__
- egg_bzero(&sv, sizeof(sv));
- sv.sa_handler = got_trace;
- sigemptyset(&sv.sa_mask);
- oldsv = NULL;
- sigaction(SIGTRAP, &sv, oldsv);
- traced = 1;
- asm("INT3");
- sigaction(SIGTRAP, oldsv, NULL);
- if (traced)
- detected(DETECT_TRACE, STR("I'm being traced!"));
- else {
- x = fork();
- if (x == -1)
- return;
- else if (x == 0) {
- i = ptrace(PTRACE_ATTACH, parent, 0, 0);
- if (i == (-1) && errno == EPERM)
- detected(DETECT_TRACE, STR("I'm being traced!"));
- else {
- waitpid(parent, &i, 0);
- kill(parent, SIGCHLD);
- ptrace(PTRACE_DETACH, parent, 0, 0);
- kill(parent, SIGCHLD);
- }
- exit(0);
- } else
- wait(&i);
- }
- #endif
- #ifdef __FreeBSD__
- x = fork();
- if (x == -1)
- return;
- else if (x == 0) {
- i = ptrace(PT_ATTACH, parent, 0, 0);
- if (i == (-1) && errno == EBUSY)
- detected(DETECT_TRACE, STR("I'm being traced"));
- else {
- wait(&i);
- i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
- kill(parent, SIGCHLD);
- wait(&i);
- i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
- wait(&i);
- }
- exit(0);
- } else
- waitpid(x, NULL, 0);
- #endif /* __FreeBSD__ */
- #ifdef __OpenBD__
- x = fork();
- if (x == -1)
- return;
- else if (x == 0) {
- i = ptrace(PT_ATTACH, parent, 0, 0);
- if (i == (-1) && errno == EBUSY)
- detected(DETECT_TRACE, STR("I'm being traced"));
- else {
- wait(&i);
- i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
- kill(parent, SIGCHLD);
- wait(&i);
- i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
- wait(&i);
- }
- exit(0);
- } else
- waitpid(x, NULL, 0);
- #endif /* __OpenBSD__ */
- #endif /* S_ANTITRACE */
- }
- struct cfg_entry *check_can_set_cfg(char *target, char *entryname)
- {
- int i;
- struct userrec *u;
- struct cfg_entry *entry = NULL;
- for (i = 0; i < cfg_count; i++)
- if (!strcmp(cfg[i]->name, entryname)) {
- entry = cfg[i];
- break;
- }
- if (!entry)
- return 0;
- if (target) {
- if (!(entry->flags & CFGF_LOCAL))
- return 0;
- if (!(u = get_user_by_handle(userlist, target)))
- return 0;
- if (!(u->flags & USER_BOT))
- return 0;
- } else {
- if (!(entry->flags & CFGF_GLOBAL))
- return 0;
- }
- return entry;
- }
- void set_cfg_str(char *target, char *entryname, char *data)
- {
- struct cfg_entry *entry;
- int free = 0;
- if (!(entry = check_can_set_cfg(target, entryname)))
- return;
- if (data && !strcmp(data, "-"))
- data = NULL;
- if (data && (strlen(data) >= 1024))
- data[1023] = 0;
- if (target) {
- struct userrec *u = get_user_by_handle(userlist, target);
- struct xtra_key *xk;
- char *olddata = entry->ldata;
- if (u && !strcmp(botnetnick, u->handle)) {
- if (data) {
- entry->ldata = nmalloc(strlen(data) + 1);
- strcpy(entry->ldata, data);
- } else
- entry->ldata = NULL;
- if (entry->localchanged) {
- int valid = 1;
- entry->localchanged(entry, olddata, &valid);
- if (!valid) {
- if (entry->ldata)
- nfree(entry->ldata);
- entry->ldata = olddata;
- data = olddata;
- olddata = NULL;
- }
- }
- }
- xk = nmalloc(sizeof(struct xtra_key));
- egg_bzero(xk, sizeof(struct xtra_key));
- xk->key = nmalloc(strlen(entry->name) + 1);
- strcpy(xk->key, entry->name);
- if (data) {
- xk->data = nmalloc(strlen(data) + 1);
- strcpy(xk->data, data);
- }
- set_user(&USERENTRY_CONFIG, u, xk);
- if (olddata)
- nfree(olddata);
- } else {
- char *olddata = entry->gdata;
- if (data) {
- free = 1;
- entry->gdata = nmalloc(strlen(data) + 1);
- strcpy(entry->gdata, data);
- } else
- entry->gdata = NULL;
- if (entry->globalchanged) {
- int valid = 1;
- entry->globalchanged(entry, olddata, &valid);
- if (!valid) {
- if (entry->gdata)
- nfree(entry->gdata);
- entry->gdata = olddata;
- olddata = NULL;
- }
- }
- if (!cfg_noshare)
- botnet_send_cfg_broad(-1, entry);
- if (olddata)
- nfree(olddata);
- }
- // if (free)
- // nfree(entry->gdata);
- }
- void userfile_cfg_line(char *ln)
- {
- char *name;
- int i;
- struct cfg_entry *cfgent = NULL;
- name = newsplit(&ln);
- for (i = 0; !cfgent && (i < cfg_count); i++)
- if (!strcmp(cfg[i]->name, name))
- cfgent = cfg[i];
- if (cfgent) {
- set_cfg_str(NULL, cfgent->name, ln[0] ? ln : NULL);
- } else
- putlog(LOG_ERRORS, "*", STR("Unrecognized config entry %s in userfile"), name);
- }
- void got_config_share(int idx, char *ln)
- {
- char *name;
- int i;
- struct cfg_entry *cfgent = NULL;
- cfg_noshare++;
- name = newsplit(&ln);
- for (i = 0; !cfgent && (i < cfg_count); i++)
- if (!strcmp(cfg[i]->name, name))
- cfgent = cfg[i];
- if (cfgent) {
- set_cfg_str(NULL, cfgent->name, ln[0] ? ln : NULL);
- botnet_send_cfg_broad(idx, cfgent);
- } else
- putlog(LOG_ERRORS, "*", STR("Unrecognized config entry %s in userfile"), name);
- cfg_noshare--;
- }
- void add_cfg(struct cfg_entry *entry)
- {
- cfg = (void *) user_realloc(cfg, sizeof(void *) * (cfg_count + 1));
- cfg[cfg_count] = entry;
- cfg_count++;
- entry->ldata = NULL;
- entry->gdata = NULL;
- }
- void trigger_cfg_changed()
- {
- int i;
- struct userrec *u;
- struct xtra_key *xk;
- u = get_user_by_handle(userlist, botnetnick);
- for (i = 0; i < cfg_count; i++) {
- if (cfg[i]->flags & CFGF_LOCAL) {
- xk = get_user(&USERENTRY_CONFIG, u);
- while (xk && strcmp(xk->key, cfg[i]->name))
- xk = xk->next;
- if (xk) {
- putlog(LOG_DEBUG, "*", STR("trigger_cfg_changed for %s"), cfg[i]->name ? cfg[i]->name : "(null)");
- if (!strcmp(cfg[i]->name, xk->key ? xk->key : "")) {
- set_cfg_str(botnetnick, cfg[i]->name, xk->data);
- }
- }
- }
- }
- }
- int shell_exec(char *cmdline, char *input, char **output, char **erroutput)
- {
- FILE *inpFile,
- *outFile,
- *errFile;
- char tmpfile[161];
- int x,
- fd;
- if (!cmdline)
- return 0;
- /* Set up temp files */
- /* always use mkstemp() when handling temp filess! -dizz */
- sprintf(tmpfile, STR("%s.in-XXXXXX"), tempdir);
- if ((fd = mkstemp(tmpfile)) == -1 || (inpFile = fdopen(fd, "w+")) == NULL) {
- if (fd != -1) {
- unlink(tmpfile);
- close(fd);
- }
- putlog(LOG_ERRORS, "*" , STR("exec: Couldn't open %s"), tmpfile);
- return 0;
- }
- unlink(tmpfile);
- if (input) {
- if (fwrite(input, 1, strlen(input), inpFile) != strlen(input)) {
- fclose(inpFile);
- putlog(LOG_ERRORS, "*", STR("exec: Couldn't write to %s"), tmpfile);
- return 0;
- }
- fseek(inpFile, 0, SEEK_SET);
- }
- unlink(tmpfile);
- sprintf(tmpfile, STR("%s.err-XXXXXX"), tempdir);
- if ((fd = mkstemp(tmpfile)) == -1 || (errFile = fdopen(fd, "w+")) == NULL) {
- if (fd != -1) {
- unlink(tmpfile);
- close(fd);
- }
- putlog(LOG_ERRORS, "*", STR("exec: Couldn't open %s"), tmpfile);
- return 0;
- }
- unlink(tmpfile);
- sprintf(tmpfile, STR("%s.out-XXXXXX"), tempdir);
- if ((fd = mkstemp(tmpfile)) == -1 || (outFile = fdopen(fd, "w+")) == NULL) {
- if (fd != -1) {
- unlink(tmpfile);
- close(fd);
- }
- putlog(LOG_ERRORS, "*", STR("exec: Couldn't open %s"), tmpfile);
- return 0;
- }
- unlink(tmpfile);
- x = fork();
- if (x == -1) {
- putlog(LOG_ERRORS, "*", STR("exec: fork() failed"));
- fclose(inpFile);
- fclose(errFile);
- fclose(outFile);
- return 0;
- }
- if (x) {
- /* Parent: wait for the child to complete */
- int st = 0;
- waitpid(x, &st, 0);
- /* Now read the files into the buffers */
- fclose(inpFile);
- fflush(outFile);
- fflush(errFile);
- if (erroutput) {
- char *buf;
- int fs;
- fseek(errFile, 0, SEEK_END);
- fs = ftell(errFile);
- if (fs == 0) {
- (*erroutput) = NULL;
- } else {
- buf = nmalloc(fs + 1);
- fseek(errFile, 0, SEEK_SET);
- fread(buf, 1, fs, errFile);
- buf[fs] = 0;
- (*erroutput) = buf;
- }
- }
- fclose(errFile);
- if (output) {
- char *buf;
- int fs;
- fseek(outFile, 0, SEEK_END);
- fs = ftell(outFile);
- if (fs == 0) {
- (*output) = NULL;
- } else {
- buf = nmalloc(fs + 1);
- fseek(outFile, 0, SEEK_SET);
- fread(buf, 1, fs, outFile);
- buf[fs] = 0;
- (*output) = buf;
- }
- }
- fclose(outFile);
- return 1;
- } else {
- /* Child: make fd's and set them up as std* */
- int ind,
- outd,
- errd;
- char *argv[4];
- ind = fileno(inpFile);
- outd = fileno(outFile);
- errd = fileno(errFile);
- if (dup2(ind, STDIN_FILENO) == (-1)) {
- exit(1);
- }
- if (dup2(outd, STDOUT_FILENO) == (-1)) {
- exit(1);
- }
- if (dup2(errd, STDERR_FILENO) == (-1)) {
- exit(1);
- }
- argv[0] = STR("/bin/sh");
- argv[1] = STR("-c");
- argv[2] = cmdline;
- argv[3] = NULL;
- execvp(argv[0], &argv[0]);
- exit(1);
- }
- }
- int ucnt = 0;
- static void updatelocal(void)
- {
- #ifdef LEAF
- module_entry *me;
- #endif
- Context;
- if (ucnt < 300) {
- ucnt++;
- return;
- }
- del_hook(HOOK_SECONDLY, (Function) updatelocal);
- ucnt = 0;
- /* let's drop the server connection ASAP */
- #ifdef LEAF
- if ((me = module_find("server", 0, 0))) {
- Function *func = me->funcs;
- (func[SERVER_NUKESERVER]) ("Updating...");
- }
- #endif
- botnet_send_chat(-1, botnetnick, "Updating...");
- botnet_send_bye();
- fatal("Updating...", 1);
- usleep(2000 * 500);
- bg_send_quit(BG_ABORT);
- unlink(pid_file); //if this fails it is ok, cron will restart the bot, *hopefully*
- system(binname); //start new bot.
- exit(0);
- }
- int updatebin (int idx, char *par, int autoi)
- {
- char *path = NULL,
- *newbin;
- char buf[2048], old[1024];
- struct stat sb;
- int i;
- #ifdef LEAF
- module_entry *me;
- #endif
- path = newsplit(&par);
- par = path;
- if (!par[0]) {
- if (idx)
- dprintf(idx, "Not enough parameters.\n");
- return 1;
- }
- path = nmalloc(strlen(binname) + strlen(par));
- strcpy(path, binname);
- newbin = strrchr(path, '/');
- if (!newbin) {
- nfree(path);
- if (idx)
- dprintf(idx, "Don't know current binary name\n");
- return 1;
- }
- newbin++;
- if (strchr(par, '/')) {
- *newbin = 0;
- if (idx)
- dprintf(idx, "New binary must be in %s and name must be specified without path information\n", path);
- nfree(path);
- return 1;
- }
- strcpy(newbin, par);
- if (!strcmp(path, binname)) {
- nfree(path);
- if (idx)
- dprintf(idx, "Can't update with the current binary\n");
- return 1;
- }
- if (stat(path, &sb)) {
- if (idx)
- dprintf(idx, "%s can't be accessed\n", path);
- nfree(path);
- return 1;
- }
- if (chmod(path, S_IRUSR | S_IWUSR | S_IXUSR)) {
- if (idx)
- dprintf(idx, "Can't set mode 0600 on %s\n", path);
- nfree(path);
- return 1;
- }
- //make a backup just in case.
- egg_snprintf(old, sizeof old, "%s.bin.old", tempdir);
- copyfile(binname, old);
- if (movefile(path, binname)) {
- if (idx)
- dprintf(idx, "Can't rename %s to %s\n", path, binname);
- nfree(path);
- return 1;
- }
- sprintf(buf, "%s", binname);
-
- #ifdef LEAF
- if (localhub) {
- /* if localhub = 1, this is the spawn bot and controls
- * the spawning of new bots. */
- sprintf(buf, "%s -P %d", buf, getpid());
- }
- #endif
- //safe to run new binary..
- #ifdef LEAF
- if (!autoi && !localhub) //dont delete pid for auto update!!!
- #endif
- unlink(pid_file); //delete pid so new binary doesnt exit.
- #ifdef HUB
- listen_all(my_port, 1); //close the listening port...
- #endif
- i = system(buf);
- if (i == -1 || i == 1) {
- if (idx)
- dprintf(idx, "Couldn't restart new binary (error %d)\n", i);
- putlog(LOG_MISC, "*", "Couldn't restart new binary (error %d)\n", i);
- return i;
- } else {
- #ifdef LEAF
- if (!autoi && !localhub) {
- /* let's drop the server connection ASAP */
- if ((me = module_find("server", 0, 0))) {
- Function *func = me->funcs;
- (func[SERVER_NUKESERVER]) ("Updating...");
- }
- #endif
- if (idx)
- dprintf(idx, "Updating...bye\n");
- putlog(LOG_MISC, "*", "Updating...\n");
- botnet_send_chat(-1, botnetnick, "Updating...");
- botnet_send_bye();
- fatal("Updating...", 1);
- usleep(2000 * 500);
- bg_send_quit(BG_ABORT);
- exit(0);
- //No need to return :)
- #ifdef LEAF
- } else {
- if (localhub && autoi) {
- add_hook(HOOK_SECONDLY, (Function) updatelocal);
- return 0;
- }
- }
- #endif
- }
- //This shouldn't happen...
- return 2;
- }
- void EncryptFile(char *infile, char *outfile)
- {
- char buf[8192];
- // char *temps;
- FILE *f, *f2;
- Context;
- f = fopen(infile, "r");
- if(!f)
- return;
- f2 = fopen(outfile, "w");
- if (!f2)
- return;
- Context;
- while (fscanf(f,"%[^\n]\n",buf) != EOF) {
- Context;
- lfprintf(f2, "%s\n", buf);
- Context;
- }
- fclose(f);
- fclose(f2);
- }
- void DecryptFile(char *infile, char *outfile)
- {
- char buf[8192], *temps;
- FILE *f, *f2;
- f = fopen(infile, "r");
- if (!f)
- return;
- f2 = fopen(outfile, "w");
- if (!f2)
- return;
- while (fscanf(f,"%[^\n]\n",buf) != EOF) {
- temps = (char *) decrypt_string(netpass, decryptit(buf));
- fprintf(f2, "%s\n",temps);
- nfree(temps);
- }
- fclose(f);
- fclose(f2);
- }
- int bot_aggressive_to(struct userrec *u)
- {
- char mypval[20],
- botpval[20];
- link_pref_val(u, botpval);
- link_pref_val(get_user_by_handle(userlist, botnetnick), mypval);
- //printf("vals: my: %s them: %s\n", mypval, botpval);
- if (strcmp(mypval, botpval) < 0)
- return 1;
- else
- return 0;
- }
- void detected(int code, char *msg)
- {
- #ifdef LEAF
- module_entry *me;
- #endif
- char *p = NULL;
- char tmp[512];
- struct userrec *u;
- struct flag_record fr = { FR_GLOBAL, 0, 0 };
- int act;
- u = get_user_by_handle(userlist, botnetnick);
- #ifdef S_LASTCHECK
- if (code == DETECT_LOGIN)
- p = (char *) (CFG_LOGIN.ldata ? CFG_LOGIN.ldata : (CFG_LOGIN.gdata ? CFG_LOGIN.gdata : NULL));
- #endif
- #ifdef S_ANTITRACE
- if (code == DETECT_TRACE)
- p = (char *) (CFG_TRACE.ldata ? CFG_TRACE.ldata : (CFG_TRACE.gdata ? CFG_TRACE.gdata : NULL));
- #endif
- #ifdef S_PROMISC
- if (code == DETECT_PROMISC)
- p = (char *) (CFG_PROMISC.ldata ? CFG_PROMISC.ldata : (CFG_PROMISC.gdata ? CFG_PROMISC.gdata : NULL));
- #endif
- #ifdef S_PROCESSCHECK
- if (code == DETECT_PROCESS)
- p = (char *) (CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : (CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : NULL));
- #endif
- #ifdef S_HIJACKCHECK
- if (code == DETECT_SIGCONT)
- p = (char *) (CFG_HIJACK.ldata ? CFG_HIJACK.ldata : (CFG_HIJACK.gdata ? CFG_HIJACK.gdata : NULL));
- #endif
- if (!p)
- act = DET_WARN;
- else if (!strcmp(p, STR("die")))
- act = DET_DIE;
- else if (!strcmp(p, STR("reject")))
- act = DET_REJECT;
- else if (!strcmp(p, STR("suicide")))
- act = DET_SUICIDE;
- else if (!strcmp(p, STR("nocheck")))
- act = DET_NOCHECK;
- else if (!strcmp(p, STR("ignore")))
- act = DET_IGNORE;
- else
- act = DET_WARN;
- switch (act) {
- case DET_IGNORE:
- break;
- case DET_WARN:
- putlog(LOG_WARN, "*", msg);
- break;
- case DET_REJECT:
- do_fork();
- putlog(LOG_WARN, "*", STR("Setting myself +d: %s"), msg);
- sprintf(tmp, STR("+d: %s"), msg);
- set_user(&USERENTRY_COMMENT, u, tmp);
- get_user_flagrec(u, &fr, 0);
- fr.global = USER_DEOP | USER_BOT;
- set_user_flagrec(u, &fr, 0);
- sleep(1);
- break;
- case DET_DIE:
- putlog(LOG_WARN, "*", STR("Dying: %s"), msg);
- sprintf(tmp, STR("Dying: %s"), msg);
- set_user(&USERENTRY_COMMENT, u, tmp);
- #ifdef LEAF
- if ((me = module_find("server", 0, 0))) {
- Function *func = me->funcs;
- (func[SERVER_NUKESERVER]) ("BBL");
- }
- #endif
- sleep(1);
- fatal(msg, 0);
- break;
- case DET_SUICIDE:
- putlog(LOG_WARN, "*", STR("Comitting suicide: %s"), msg);
- sprintf(tmp, STR("Suicide: %s"), msg);
- set_user(&USERENTRY_COMMENT, u, tmp);
- #ifdef LEAF
- if ((me = module_find("server", 0, 0))) {
- Function *func = me->funcs;
- (func[SERVER_NUKESERVER]) ("HARAKIRI!!");
- }
- #endif
- sleep(1);
- unlink(binname);
- #ifdef HUB
- unlink(userfile);
- sprintf(tmp, STR("%s~"), userfile);
- unlink(tmp);
- // unlink(logfile);
- // sprintf(tmp, STR("%s~"), logfile);
- // unlink(tmp);
- #endif
- fatal(msg, 0);
- break;
- case DET_NOCHECK:
- break;
- }
- }
- char * kickreason(int kind) {
- int r;
- r=random();
- switch (kind) {
- case KICK_BANNED:
- switch (r % 6) {
- case 0: return STR("bye");
- case 1: return STR("banned");
- case 2: return STR("bummer");
- case 3: return STR("go away");
- case 4: return STR("cya around looser");
- case 5: return STR("unwanted!");
- }
- case KICK_KUSER:
- switch (r % 4) {
- case 0: return STR("not wanted");
- case 1: return STR("something tells me you're annoying");
- case 2: return STR("don't bug me looser");
- case 3: return STR("creep");
- }
- case KICK_KICKBAN:
- switch (r % 4) {
- case 0: return STR("gone");
- case 1: return STR("stupid");
- case 2: return STR("looser");
- case 3: return STR("...");
- }
- case KICK_MASSDEOP:
- switch (r % 8) {
- case 0: return STR("spammer!");
- case 1: return STR("easy on the modes now");
- case 2: return STR("mode this");
- case 3: return STR("nice try");
- case 4: return STR("really?");
- case 5: return STR("mIRC sux for mdop kiddo");
- case 6: return STR("scary... really scary...");
- case 7: return STR("you lost the game!");
- }
- case KICK_BADOP:
- switch (r % 5) {
- case 0: return STR("neat...");
- case 1: return STR("oh, no you don't. go away.");
- case 2: return STR("didn't you forget something now?");
- case 3: return STR("no");
- case 4: return STR("hijack this");
- }
- case KICK_BADOPPED:
- switch (r % 5) {
- case 0: return STR("buggar off kid");
- case 1: return STR("asl?");
- case 2: return STR("whoa... what a hacker... skills!");
- case 3: return STR("yes! yes! yes! hit me baby one more time!");
- case 4: return STR("with your skills, you're better off jacking off than hijacking");
- }
- case KICK_MANUALOP:
- switch (r % 6) {
- case 0: return STR("naughty kid");
- case 1: return STR("didn't someone tell you that is bad?");
- case 2: return STR("want perm?");
- case 3: return STR("see how much good that did you?");
- case 4: return STR("not a smart move...");
- case 5: return STR("jackass!");
- }
- case KICK_MANUALOPPED:
- switch (r % 8) {
- case 0: return STR("your pal got mean friends. like me.");
- case 1: return STR("uhh now.. don't wake me up...");
- case 2: return STR("hi hun. missed me?");
- case 3: return STR("spammer! die!");
- case 4: return STR("boo!");
- case 5: return STR("that @ was useful, don't ya think?");
- case 6: return STR("not in my book");
- case 7: return STR("lol, really?");
- }
- case KICK_CLOSED:
- switch (r % 17) {
- case 0: return STR("locked");
- case 1: return STR("later");
- case 2: return STR("closed for now");
- case 3: return STR("sorry, but it's getting late, locking channel. cya around");
- case 4: return STR("better safe than sorry");
- case 5: return STR("cleanup, come back later");
- case 6: return STR("this channel is closed");
- case 7: return STR("shutting down for now");
- case 8: return STR("lockdown");
- case 9: return STR("reopening later");
- case 10: return STR("not for the public atm");
- case 11: return STR("private channel for now");
- case 12: return STR("might reopen soon, might reopen later");
- case 13: return STR("you're not supposed to be here right now");
- case 14: return STR("sorry, closed");
- case 15: return STR("try us later, atm we're locked down");
- case 16: return STR("closed. try tomorrow");
- }
- case KICK_FLOOD:
- switch (r % 7) {
- case 0: return STR("so much bullshit in such a short time. amazing.");
- case 1: return STR("slow down. i'm trying to read here.");
- case 2: return STR("uhm... you actually think irc is for talking?");
- case 3: return STR("talk talk talk");
- case 4: return STR("blabbering are we?");
- case 5: return STR("... and i don't even like you!");
- case 6: return STR("and you're outa here...");
- }
- case KICK_NICKFLOOD:
- switch (r % 7) {
- case 0: return STR("make up your mind?");
- case 1: return STR("be schizofrenic elsewhere");
- case 2: return STR("I'm loosing track of you... not!");
- case 3: return STR("that is REALLY annoying");
- case 4: return STR("try this: /NICK looser");
- case 5: return STR("playing hide 'n' seek?");
- case 6: return STR("gotcha!");
- }
- case KICK_KICKFLOOD:
- switch (r % 6) {
- case 0: return STR("easier to just leave if you wan't to be alone");
- case 1: return STR("cool down");
- case 2: return STR("don't be so damned aggressive. that's my job.");
- case 3: return STR("kicking's fun, isn't it?");
- case 4: return STR("what's the rush?");
- case 5: return STR("next time you do that, i'll kick you again");
- }
- case KICK_BOGUSUSERNAME:
- return STR("bogus username");
- case KICK_MEAN:
- switch (r % 11) {
- case 0: return STR("hey! that wasn't very nice!");
- case 1: return STR("don't fuck with my pals");
- case 2: return STR("meanie!");
- case 3: return STR("I can be a bitch too...");
- case 4: return STR("leave the bots alone, will ya?");
- case 5: return STR("not very clever");
- case 6: return STR("watch it");
- case 7: return STR("fuck off");
- case 8: return STR("easy now. that's a friend.");
- case 9: return STR("abuse of power. leave that to me, will ya?");
- case 10: return STR("there as some things you cannot do, and that was one of them...");
- }
- case KICK_BOGUSKEY:
- return STR("I have a really hard time reading that key");
- default:
- return "OMFG@YUO";
- }
- }
- char kickprefix[25] = "";
- char bankickprefix[25] = "";
- void makeplaincookie(char *chname, char *nick, char *buf)
- {
- /*
- plain cookie:
- Last 6 digits of time
- Last 5 chars of nick
- Last 4 regular chars of chan
- */
- char work[256],
- work2[256];
- int i,
- n;
- sprintf(work, STR("%010li"), (now + timesync));
- strcpy(buf, (char *) &work[4]);
- work[0] = 0;
- if (strlen(nick) < 5)
- while (strlen(work) + strlen(nick) < 5)
- strcat(work, " ");
- else
- strcpy(work, (char *) &nick[strlen(nick) - 5]);
- strcat(buf, work);
- n = 3;
- for (i = strlen(chname) - 1; (i >= 0) && (n >= 0); i--)
- if (((unsigned char) chname[i] < 128) && ((unsigned char) chname[i] > 32)) {
- work2[n] = tolower(chname[i]);
- n--;
- }
- while (n >= 0)
- work2[n--] = ' ';
- work2[4] = 0;
- strcat(buf, work2);
- }
- int goodpass(char *pass, int idx, char *nick)
- {
- int i, nalpha = 0, lcase = 0, ucase = 0, ocase = 0, tc;
- char *tell;
- tell = nmalloc(300);
- if (!pass[0])
- return 0;
- for (i = 0; i < strlen(pass); i++) {
- tc = (int) pass[i];
- if (tc < 58 && tc > 47)
- ocase++; //number
- else if (tc < 91 && tc > 64)
- ucase++; //upper case
- else if (tc < 123 && tc > 96)
- lcase++; //lower case
- else
- nalpha++; //non-alphabet/number
- }
- if (ocase < 1 || lcase < 2 || ucase < 2 || nalpha < 1 || strlen(pass) < 8) {
- sprintf(tell, "Insecure pass, must be: ");
- if (ocase < 1)
- strcat(tell, "\002>= 1 number\002, ");
- else
- strcat(tell, ">= 1 number, ");
- if (lcase < 2)
- strcat(tell, "\002>= 2 lcase\002, ");
- else
- strcat(tell, ">= 2 lowercase, ");
- if (ucase < 2)
- strcat(tell, "\002>= 2 ucase\002, ");
- else
- strcat(tell, ">= 2 uppercase, ");
- if (nalpha < 1)
- strcat(tell, "\002>= 1 non-alpha/num\002, ");
- else
- strcat(tell, ">= 1 non-alpha/num, ");
- if (strlen(pass) < 8)
- strcat(tell, "\002>= 8 chars.\002");
- else
- strcat(tell, ">= 8 chars.");
- if (idx)
- dprintf(idx, "%s\n", tell);
- else if (nick[0])
- dprintf(DP_HELP, "NOTICE %s :%s\n", nick, tell);
-
- return 0;
- }
-
- return 1;
- }
- //strcpy(dcc[idx].nick, char *string);
- //.nick is char nick[uhostlen]
- char *makehash(struct userrec *u, char *rand)
- {
- int i = 0;
- MD5_CTX ctx;
- unsigned char md5out[33];
- char md5string[33], hash[500], *ret = NULL;
- Context;
- // strcpy(hash, rand);
- Context;
- // strcat(hash, get_user(&USERENTRY_SECPASS, u));
-
- sprintf(hash, "%s%s%s", rand, (char *) get_user(&USERENTRY_SECPASS, u), authkey ? authkey : "");
- putlog(LOG_DEBUG, "*", "Making hash from %s %s: %s", rand, get_user(&USERENTRY_SECPASS, u), hash);
- MD5_Init(&ctx);
- MD5_Update(&ctx, hash, strlen(hash));
- MD5_Final(md5out, &ctx);
- for(i=0; i<16; i++)
- sprintf(md5string + (i*2), "%.2x", md5out[i]);
-
- putlog(LOG_DEBUG, "*", "MD5 of hash: %s", md5string);
- Context;
- ret = md5string;
- Context;
- // sprintf(ret, "%s", md5string);
- return ret;
- }
- int new_auth(void)
- {
- int i = auth_total;
- Context;
- if (auth_total == max_auth)
- return -1;
- auth_total++;
- Context;
- egg_bzero((char *) &auth[i], sizeof(struct auth_t));
- Context;
- return i;
- }
- int isauthed(char *host)
- {
- int i = 0;
- Context;
- for (i = 0; i < auth_total; i++) {
- Context;
- if (auth[i].host[0] && host[0] && !strcmp(auth[i].host, host))
- Context;
- return i;
- }
- Context;
- return -1;
- }
-
- void removeauth(int n)
- {
- Context;
- auth_total--;
- if (n < auth_total)
- egg_memcpy(&auth[n], &auth[auth_total], sizeof(struct auth_t));
- else
- egg_bzero(&auth[n], sizeof(struct auth_t)); /* drummer */
- }
- #ifdef S_GARBLESTRINGS
- #define GARBLE_BUFFERS 40
- unsigned char *garble_buffer[GARBLE_BUFFERS] = {
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- };
- int garble_ptr = (-1);
- char *degarble(int len, char *g)
- {
- int i;
- unsigned char x;
- garble_ptr++;
- if (garble_ptr == GARBLE_BUFFERS)
- garble_ptr = 0;
- if (garble_buffer[garble_ptr])
- nfree(garble_buffer[garble_ptr]);
- garble_buffer[garble_ptr] = nmalloc(len + 1);
- x = 0xFF;
- for (i = 0; i < len; i++) {
- garble_buffer[garble_ptr][i] = g[i] ^ x;
- x = garble_buffer[garble_ptr][i];
- }
- garble_buffer[garble_ptr][len] = 0;
- return (char *) garble_buffer[garble_ptr];
- }
- #endif
- char *replace (char *string, char *oldie, char *newbie)
- {
- static char newstring[1024] = "";
- int str_index, newstr_index, oldie_index, end, new_len, old_len, cpy_len;
- char *c;
- if (string == NULL) return "";
- if ((c = (char *) strstr(string, oldie)) == NULL) return string;
- new_len = strlen(newbie);
- old_len = strlen(oldie);
- end = strlen(string) - old_len;
- oldie_index = c - string;
- newstr_index = 0;
- str_index = 0;
- while(str_index <= end && c != NULL) {
- cpy_len = oldie_index-str_index;
- strncpy(newstring + newstr_index, string + str_index, cpy_len);
- newstr_index += cpy_len;
- str_index += cpy_len;
- strcpy(newstring + newstr_index, newbie);
- newstr_index += new_len;
- str_index += old_len;
- if((c = (char *) strstr(string + str_index, oldie)) != NULL)
- oldie_index = c - string;
- }
- strcpy(newstring + newstr_index, string + str_index);
- return (newstring);
- }
|