main.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002  secwatch - Copyright (C) 2006 Nic Stevens -- See COPYING for license details
00003 ------------------------------------------------------------------------------
00004  main.c - basic program initialization and startup
00005 -----------------------------------------------------------------------------*/
00006 #ifdef HAVE_CONFIG_H
00007 #include "config.h"
00008 #endif
00009 #include <stdio.h>
00010 #include <stdlib.h>
00011 #include <string.h>
00012 #include <unistd.h>
00013 #include <getopt.h>
00014 #include <log.h>
00015 #include <strutil.h>
00016 #include <tail.h>
00017 #include <configfile.h>
00018 
00019 char * proginfo = "secwatch " VERSION " built " __TIME__" " __DATE__ " Copyright (C) 2006 Nic Stevens.\nPlease see COPYING for licensing information.\n";
00020 char * dfltConfig = "/usr/local/etc/secwatch.conf";
00021 int maxage = -1;
00022 int fork_flag = 1;
00023 int dmpCfg = 0;
00024 int dmpPat = 0;
00025 
00026 char * utxt[] = {
00027           "Dump configuration",
00028           "Dump patterns",
00029           "Configuration filename",
00030           "Show this list",
00031           "Show program version and exit.",
00032           "set the name of the patterns file",
00033           "set the name of the file holding the PID of the daemon",
00034           "set the name of the IP list",
00035           "set a comma delimited list of log files to scan",
00036           "set the maximum number of attemtps before firewalling",
00037           "set the maximum age, in minutes, of an IP ban",
00038           "set to true or false to have the daemon fork or stay in foreground",
00039           "set the address to send alerts to",
00040           "set the address to send alerts from",
00041           "set the location of the sendmail binary",
00042           "set the syslog priority to use",
00043           "set the syslog facility to use",
00044           "set the firewall reject selections",
00045           "set the inprej firewall rule",
00046           "set the outrej firewall rule",
00047           "set the fwdrej firewall rule",
00048           "set the firewall accept selections",
00049           "set the inpalw firewall rule",
00050           "set the outalw firewall rule",
00051           "set the fwdalw firewall rule",
00052           NULL
00053 };
00054 
00055 static struct option _opts[] = {
00056      {"dump-cfg",no_argument,&dmpCfg,'d'},
00057      {"dump-pat",no_argument,&dmpPat,'p'},
00058      {"config", required_argument, 0,   'f'},
00059      {"help",   no_argument,       0,   'h'},
00060      {"version",no_argument,       0,   'v'},
00061      {0,0,0,0}
00062 };
00063 #define BASEOPTS 5
00064 struct option *opts = NULL;
00065 int numopts = 0;
00066 
00067 void makeopts(void) {
00068      int i, ip;
00069      char desc[100];
00070      struct option op;
00071      for(i = 0; i < BASEOPTS; i++) {
00072           numopts++;
00073           if((opts = realloc(opts,sizeof(struct option)*(numopts+1))) == NULL) {
00074                fprintf(stderr,"Fatal: Could not create option space\n");
00075                exit(-1);
00076           }
00077           opts[i] = _opts[i];
00078           opts[i+1].name = NULL;
00079      }
00080      for(i = 0; config[i].name != NULL; i++) {
00081           ip = numopts++;
00082           if((opts = realloc(opts,(sizeof(struct option )*(numopts+1)))) == NULL) {
00083                fprintf(stderr,"Fatal: Could not create option space\n");
00084                exit(-1);
00085           }
00086           sprintf(desc,"set-%s",config[i].name);
00087           op.has_arg = 1;
00088           op.name = strdup(desc);
00089           op.flag = NULL;
00090           op.val = BASEOPTS+i;
00091           opts[ip] = op;
00092           opts[numopts].name = NULL;
00093      }
00094 }
00095 
00096 void showProgInfo(FILE *o) {
00097      fprintf(o,"%s\n",proginfo);
00098 }
00099 void usage(FILE *o) {
00100      int i, j;
00101      showProgInfo(o);
00102      for(i = 0; opts[i].val != 0; i++) {
00103           if(i < BASEOPTS)
00104                fprintf(o,"-%c, --%-12.12s  %s\n",
00105                        opts[i].val,opts[i].name,utxt[i]);
00106           else {
00107                cfgitem_t *c = &config[i-BASEOPTS];
00108                char **a, *p, buf[128];
00109                int x;
00110                p = &buf[0];
00111                switch(c->type) {
00112                case ci_pathname:
00113                     p = confVarPath(c->name,&x);
00114                     break;
00115                case ci_text:
00116                     p = confVarText(c->name,&x);
00117                     break;
00118                case ci_integer:
00119                     sprintf(buf,"%d",confVarInt(c->name,&x));
00120                     break;
00121                case ci_boolean:
00122                     if(c->val.i)
00123                          strcpy(p,"true");
00124                     else
00125                          strcpy(p,"false");
00126                     break;
00127                case ci_logpri:
00128                case ci_logfac:
00129                     p = (c->type == ci_logpri) ? sysLogPriId(c->val.i) : sysLogFacId(c->val.i);
00130                     break;
00131                case ci_flist:
00132                     bzero(buf,sizeof(buf));
00133                     for(j = 0; c->val.a[j] != NULL; j++) {
00134                          char *foo = ",";
00135                          strcat(buf,c->val.a[j]);
00136                          if(c->val.a[j+1] != NULL)
00137                               strcat(buf,foo);
00138                     }
00139                     break;
00140                }
00141                fprintf(o,"    --%-12.12s  %s [Default: %s]\n",
00142                        opts[i].name,
00143                        utxt[i],
00144                        p);
00145           }
00146      }
00147 }
00148 char **argvw;
00149 int main(int argc, char *argv[]) {
00150      int c, i, x;
00151      int optind, error = 0;
00152      char _maxage[10];
00153      char ebuf[10240];
00154      char *s, * configFile = dfltConfig;
00155      char ** logs;
00156      argvw = argv;
00157      makeopts();
00158      while(1) {
00159           c = getopt_long(argc, argv, "nf:dphv",opts,&optind);
00160           if(c == -1)
00161                break;
00162           switch(c) {
00163           case 'd':
00164           case 0: // no-fork, no option, do nothing
00165           case 'p':
00166           case '1':
00167           case '2':
00168                break;
00169           case 'f':
00170                configFile = optarg;
00171                break;
00172           case 'h':
00173                usage(stdout);
00174                return 0;
00175                break;
00176           case 'v':
00177                showProgInfo(stdout);
00178                return 0;
00179                break;
00180           default:
00181                if(c >= 6 && c < numopts) {
00182                     i = c -6;
00183                     switch(config[i].type) {
00184                     case ci_pathname:
00185                          config[i].val.s = strdup(optarg);
00186                          break;
00187                     case ci_text:
00188                          config[i].val.s = strdup(optarg);
00189                          break;
00190                     case ci_logfac:
00191                          config[i].val.i = sysLogFac(optarg);
00192                          break;
00193                     case ci_logpri:
00194                          config[i].val.i = sysLogPri(optarg);
00195                          break;
00196                     case ci_boolean:
00197                          getBooleanValue(optarg,&config[i].val.i);
00198                          break;
00199                     case ci_integer:
00200                          config[i].val.i = atoi(optarg);
00201                          break;
00202                     case ci_flist:
00203                          config[i].val.a = split(",",optarg);
00204                          break;
00205                     }
00206                } else {
00207                     fprintf(stderr,"%s: invalid argument(%d)\n",*argv,c);
00208                     error = 1;
00209                     break;
00210                }
00211           }
00212      }
00213      if(error) {
00214           usage(stderr);
00215           return -1;
00216      }
00217      if(configFile != NULL) {
00218           if(readConfig(configFile,ebuf,sizeof(ebuf))) {
00219                fprintf(stderr,"%s: Configuration error %s\n",*argv,ebuf);
00220                return -1;
00221           }
00222      }
00223      if(dmpCfg || dmpPat)
00224           showProgInfo(stdout);
00225      
00226      if(dmpCfg) 
00227           dumpConfig();
00228           
00229      if(loadPatterns(confVarPath("patterns",&x),&ebuf,sizeof(ebuf))) {
00230           fprintf(stderr,"%s: Pattern error: %s\n",*argv,ebuf);
00231           return -1;
00232      }
00233      if(dmpPat)
00234           dumpPats();
00235 
00236      if((logs = split(",",confVarText("logfiles",&x))) == NULL) {
00237           fprintf(stderr,"%s: No logs defined.\n",*argv);
00238           return -1;
00239      }
00240      for(i = 0; logs[i] != 0; i++) {
00241           logs[i] = trim(logs[i]);
00242           if(addtailsource(logs[i])) {
00243                fprintf(stderr,"%s: Error adding log source \"%s\": %m\n",*argv,logs[i]);
00244                return -1;
00245           }
00246      }
00247      if(dmpPat | dmpCfg)
00248           return 0;
00249      if(fork_flag) {
00250           if((i = fork()) == -1) {
00251                fprintf(stderr,"%s: Cannot fork: %m\n",*argv);
00252                return -1;
00253           }
00254           if(i == 0) 
00255                return 0;
00256      }
00257      setsid();
00258      secwatch();
00259 }

Generated on Tue Oct 31 10:17:23 2006 for secwatch by  doxygen 1.4.6