pattern.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002  secwatch - Copyright (C) 2006 Nic Stevens -- See COPYING for license details
00003 ------------------------------------------------------------------------------
00004  pattern.c - Implement pattern matching functions using PCRE or simple text
00005  comparisons
00006 -----------------------------------------------------------------------------*/
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <unistd.h>
00010 #include <string.h>
00011 #include <sys/types.h>
00012 #include <pcre.h>
00013 #include "strutil.h"
00014 
00019 typedef struct _pattern {
00020      char * logdef;             // logfile name
00021      pcre *logrx;               // compiled RE for logfile
00022      char * match[2];           // match1/2 strings
00023      pcre *matchrx[2];          // compiled REs for match 1/2
00024      int pos;                   // where to expect IP addr in log file line
00025 } pat_t;
00026 
00027 static pat_t ** _pats;
00028 static int _patcnt = 0;
00029 static int _regxerr = 0;
00030 
00036 void dumpPats(void) {
00037      int i;
00038      pat_t *p;
00039      printf(">> Pattern Dump << \n");
00040      for(i = 0; i < _patcnt; i++) {
00041           p = _pats[i];
00042           printf("Pattern %d PCRE:[%s,%s,%s]: %s:%s:%s@%d\n\n",
00043                  i,
00044                  (p->logrx != NULL) ? "yes" : "no",
00045                  (p->matchrx[0] != NULL) ? "yes" : "no",
00046                  (p->matchrx[1] != NULL) ? "yes" : "no",
00047                  p->logdef,p->match[0],p->match[1],p->pos);
00048      }
00049 }
00053 static pcre * patrx(const char *buf,char *errbuf, size_t ebufsz) {
00054      pcre *p;
00055      char *errptr;
00056      int eoff;
00057      char rebuf[10240];
00058      memset(rebuf,'\0',sizeof(rebuf));
00059      strncpy(rebuf,&buf[1],strlen(buf)-2);
00060      if((p = pcre_compile(rebuf,0,(const char **)&errptr, &eoff,NULL)) == NULL) {
00061           strncpy(errbuf,errptr,ebufsz);
00062           return NULL;
00063      }
00064      return p;
00065 }
00073 int patternMatch(char *filename, char *str, int *ip) {
00074      int i, j;
00075      pat_t *p;
00076      for(i = 0; i < _patcnt; i++) {
00077           p = _pats[i];
00078           if(p->logrx != NULL) {
00079                if(pcre_exec(p->logrx,NULL,filename,strlen(filename),0,0,NULL,0) <= 0)
00080                     continue;
00081           } else {
00082                if(strpos(filename,p->logdef) < 0)
00083                     continue;
00084           }
00085           if(p->matchrx[0] != NULL) {
00086                if(pcre_exec(p->matchrx[0],NULL,str,strlen(str),0,0,NULL,0) <= 0)
00087                     continue;
00088           } else {
00089                if(strpos(str,p->match[0]) <= 0)
00090                     continue;
00091           }
00092           if(p->matchrx[1] != NULL) {
00093                if(pcre_exec(p->matchrx[1],NULL,str,strlen(str),0,0,NULL,0) <= 0)
00094                     continue;
00095           } else {
00096                if(strpos(str,p->match[1]) <= 0)
00097                     continue;
00098           }
00099           *ip = p->pos;
00100           return 0;
00101      }
00102      return -1;
00103 }
00109 int loadPatterns(char *file, char *ebuf, size_t ebsiz) {
00110      char eb2[10240];
00111      char buf[1024], name[1024], val[1024];
00112      char *p, *ep, *p1;
00113      int ipp, i, line = 0;
00114      struct cfgitem *c;
00115      pat_t x;
00116      FILE *f;
00117      
00118      if((f = fopen(file,"r")) == NULL) {
00119           snprintf(ebuf,ebsiz,"%s(%d) Cannot open config file \"%s\": %m",file,line);
00120           return -1;
00121      }
00122      while((p = fgets(buf,sizeof(buf)-1,f)) != NULL) {
00123           line ++; 
00124           if(*p == '#') continue;
00125           if((p = strchr(buf,'#')) != NULL)
00126                *p = '\0';
00127           p = trim(buf);
00128           if(*p == '\0' || strlen(p) == 0)
00129                continue;
00130           x.logdef = p;
00131           if((p = strchr(x.logdef,':')) == NULL)
00132                continue;
00133           *p++ = '\0';
00134           x.match[0] = p;
00135           if((p = strchr(x.match[0],':')) == NULL)
00136                continue;
00137           *p++ = '\0';
00138           x.match[1] = p;
00139           if((p = strchr(x.match[1],'@')) == NULL)
00140                continue;
00141           *p++ = '\0';
00142           if((x.pos = atoi(p)) <= 0) {
00143                snprintf(ebuf,ebsiz,"%s:(%d) Invalid position specified in rule.",file,line);
00144                fclose(f);
00145                return -1;
00146           }
00147           if(strncmp(x.logdef,"//",2) == 0) {
00148                if((x.logrx = patrx(x.logdef,eb2,sizeof(eb2))) == NULL)
00149                     snprintf(ebuf,ebsiz,"%s(%d): WARNING: pcre compile failed for logmatch: %s",file,line,eb2);
00150           }
00151           else
00152                x.logrx = NULL;
00153           for(i = 0; i < 2; i++) {
00154                x.matchrx[i] = NULL;
00155                if(x.match[i][0] == '/') {
00156                     if((x.matchrx[i] = patrx(x.match[i],eb2,sizeof(eb2))) == NULL) 
00157                          snprintf(ebuf,ebsiz,"%s(%d): WARNING: pcre compile failed for match %d: %s",file,line,i+1,eb2);
00158                }
00159           }
00160           //
00161           // realloc and catenation of pattern to pats
00162           // 
00163           ipp = _patcnt ++;
00164           if((_pats = realloc(_pats,(sizeof(pat_t *)*_patcnt))) == NULL){
00165                snprintf(ebuf,ebsiz,"%s(%d): Could not allocate space for pat_t: %m",file,line);
00166                fclose(f);
00167                return -1;
00168           }
00169           if((_pats[ipp] = calloc(sizeof(pat_t),1)) == NULL) {
00170                snprintf(ebuf,ebsiz,"%s(%d): Could not allocate space for pat_t: %m",file,line);
00171                fclose(f);
00172                return -1;
00173           }
00174           x.logdef = strdup(x.logdef);
00175           for(i = 0; i < 2; i++) 
00176                x.match[i] = strdup(x.match[i]);
00177           *_pats[ipp] = x;
00178      }
00179      fclose(f);
00180      return 0;
00181 }

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