Refactor reges operations
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 2 Feb 2014 23:10:07 +0000 (23:10 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 2 Feb 2014 23:10:07 +0000 (23:10 +0000)
src/src/malware.c

index 62758580cf1829b9a7ac2e3c9b24299ffbb38d92..b72253e7b87cc72f759d8d62c0db7e67cc798c62 100644 (file)
@@ -336,6 +336,32 @@ m_sock_send(int sock, uschar * buf, int cnt, uschar ** errstr)
   return sock;
 }
 
+static const pcre *
+m_pcre_compile(const uschar * re, uschar ** errstr)
+{
+  const uschar * rerror;
+  int roffset;
+  const pcre * cre;
+
+  cre = pcre_compile(re, PCRE_COPT, (const char **)&rerror, &roffset, NULL);
+  if (!cre)
+    *errstr= string_sprintf("regular expression error in '%s': %s at offset %d",
+       re, rerror, roffset);
+  return cre;
+}
+
+uschar *
+m_pcre_exec(const pcre * cre, uschar * text)
+{
+  int ovector[10*3];
+  int i = pcre_exec(cre, NULL, CS text, Ustrlen(text), 0, 0,
+               ovector, nelements(ovector));
+  uschar * substr = NULL;
+  if (i >= 2)                          /* Got it */
+    pcre_get_substring(CS text, ovector, i, 1, (const char **) &substr);
+  return substr;
+}
+
 /*************************************************
 *          Scan content for malware              *
 *************************************************/
@@ -384,9 +410,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
   uschar malware_regex_default[] = ".+";
   unsigned long mbox_size;
   FILE *mbox_file;
-  int roffset;
   const pcre *re;
-  const uschar *rerror;
   uschar * errstr;
   struct scan * scanent;
   const uschar * scanner_options;
@@ -424,11 +448,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
   sep = 0;
 
   /* compile the regex, see if it works */
-  re = pcre_compile(CS malware_regex, PCRE_COPT, (const char **)&rerror, &roffset, NULL);
-  if (!re)
-    return malware_errlog_defer(
-        string_sprintf("regular expression error in '%s': %s at offset %d",
-            malware_regex, rerror, roffset));
+  if (!(re = m_pcre_compile(CS malware_regex, &errstr)))
+    return malware_errlog_defer(errstr);
 
   /* if av_scanner starts with a dollar, expand it first */
   if (*av_scanner == '$') {
@@ -513,13 +534,13 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
     /* v0.0 - initial release -- support for unix sockets      */
       {
        struct sockaddr_un server;
-       int sock, result, ovector[10*3];
+       int sock, result;
        unsigned int fsize;
        uschar * tmpbuf, *drweb_fbuf;
        int drweb_rc, drweb_cmd, drweb_flags = 0x0000, drweb_fd,
            drweb_vnum, drweb_slen, drweb_fin = 0x0000;
        unsigned long bread;
-       pcre *drweb_re;
+       const pcre *drweb_re;
 
        if (*scanner_options != '/') {
          if ((sock = m_tcpsocket_fromdef(scanner_options, &errstr)) < 0)
@@ -640,13 +661,12 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
          malware_name = malware_name_internal;
 
          /* set up match regex */
-         drweb_re = pcre_compile( "infected\\swith\\s*(.+?)$", PCRE_COPT,
-           (const char **)&rerror, &roffset, NULL );
+         drweb_re = m_pcre_compile( "infected\\swith\\s*(.+?)$", &errstr);
 
          /* read and concatenate virus names into one string */
          for (i=0;i<drweb_vnum;i++)
          {
-           int size = 0, off = 0;
+           int size = 0, off = 0, ovector[10*3];
            /* read the size of report */
            if ((bread = recv(sock, &drweb_slen, sizeof(drweb_slen), 0) != sizeof(drweb_slen))) {
              (void)close(sock);
@@ -788,7 +808,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
        int sock, i, j, bread = 0;
        uschar * file_name;
        uschar av_buffer[1024];
-       pcre * fs_inf;
+       const pcre * fs_inf;
        static uschar *cmdopt[] = { US"CONFIGURE\tARCHIVE\t1\n",
                                        US"CONFIGURE\tTIMEOUT\t0\n",
                                        US"CONFIGURE\tMAXARCH\t5\n",
@@ -834,11 +854,10 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
 
        /* set up match */
        /* todo also SUSPICION\t */
-       fs_inf = pcre_compile("\\S{0,5}INFECTED\\t[^\\t]*\\t([^\\t]+)\\t\\S*$", PCRE_COPT, (const char **)&rerror, &roffset, NULL);
+       fs_inf = m_pcre_compile("\\S{0,5}INFECTED\\t[^\\t]*\\t([^\\t]+)\\t\\S*$", &errstr);
 
        /* read report, linewise */
        do {
-         int ovector[10*3];
          i = 0;
          memset(av_buffer, 0, sizeof(av_buffer));
          do {
@@ -856,17 +875,9 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
          /* debug_printf("got line \"%s\"\n",av_buffer); */
 
          /* Really search for virus again? */
-         if (malware_name == NULL) {
+         if (malware_name == NULL)
            /* try matcher on the line, grab substring */
-           i = pcre_exec(fs_inf, NULL, CS av_buffer, Ustrlen(av_buffer), 0, 0,
-                         ovector, nelements(ovector));
-           if (i >= 2) {
-             /* Got it */
-             pcre_get_substring(CS av_buffer, ovector, i, 1,
-                                 (const char **) &malware_name_internal);
-             malware_name = malware_name_internal;
-           }
-         }
+           malware_name = m_pcre_exec(fs_inf, av_buffer);
        }
        while (Ustrstr(av_buffer, "OK\tScan ok.") == NULL);
        (void)close(sock);
@@ -882,7 +893,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
        uschar * scanrequest;
        int kav_rc;
        unsigned long kav_reportlen, bread;
-       pcre *kav_re;
+       const pcre *kav_re;
        uschar *p;
 
        if((sock = m_unixsocket(scanner_options, &errstr)) < 0)
@@ -958,19 +969,13 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
            reportsize is 0 (!?) */
            if (kav_reportlen > 0) {
              /* set up match regex, depends on retcode */
-             kav_re = pcre_compile( kav_rc == 3
-                                    ? "suspicion:\\s*(.+?)\\s*$"
-                                    : "infected:\\s*(.+?)\\s*$",
-                                    PCRE_COPT,
-                                    (const char **)&rerror,
-                                    &roffset,
-                                    NULL );
+             kav_re = m_pcre_compile( kav_rc == 3
+                                      ? "suspicion:\\s*(.+?)\\s*$"
+                                      : "infected:\\s*(.+?)\\s*$",
+                                      &errstr );
 
              /* read report, linewise */
              while (kav_reportlen > 0) {
-               int result = 0;
-               int ovector[10*3];
-
                bread = 0;
                while ( recv(sock, &tmpbuf[bread], 1, 0) == 1 ) {
                  kav_reportlen--;
@@ -981,13 +986,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
                tmpbuf[bread] = '\0';
 
                /* try matcher on the line, grab substring */
-               result = pcre_exec(kav_re, NULL, CS tmpbuf, Ustrlen(tmpbuf), 0, 0,
-                                 ovector, nelements(ovector));
-               if (result >= 2) {
-                 pcre_get_substring(CS tmpbuf, ovector, result, 1,
-                                     (const char **) &malware_name_internal);
+               if ((malware_name = m_pcre_exec(kav_re, tmpbuf)))
                  break;
-               }
              }
            }
          }
@@ -1014,8 +1014,6 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
        FILE *scanner_record = NULL;
        uschar linebuffer[32767];
        int trigger = 0;
-       int result;
-       int ovector[10*3];
        uschar *p;
        BOOL fits;
 
@@ -1027,22 +1025,16 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
          return cmdl_errlog_defer("missing trigger specification");
 
        /* precompile trigger regex */
-       cmdline_trigger_re = pcre_compile(CS cmdline_trigger, PCRE_COPT, (const char **)&rerror, &roffset, NULL);
-       if (cmdline_trigger_re == NULL)
-         return cmdl_errlog_defer(
-           string_sprintf("regular expression error in '%s': %s at offset %d",
-             cmdline_trigger, rerror, roffset));
+       if (!(cmdline_trigger_re = m_pcre_compile(CS cmdline_trigger, &errstr)))
+         return cmdl_errlog_defer(errstr);
 
        /* find scanner name regex */
        if (!(cmdline_regex = string_nextinlist(&av_scanner_work, &sep, NULL, 0)))
          return cmdl_errlog_defer("missing virus name regex specification");
 
        /* precompile name regex */
-       cmdline_regex_re = pcre_compile(CS cmdline_regex, PCRE_COPT, (const char **)&rerror, &roffset, NULL);
-       if (cmdline_regex_re == NULL)
-         return cmdl_errlog_defer(
-           string_sprintf("regular expression error in '%s': %s at offset %d",
-             cmdline_regex, rerror, roffset));
+       if (!(cmdline_regex_re = m_pcre_compile(CS cmdline_regex, &errstr)))
+         return cmdl_errlog_defer(errstr);
 
        /* prepare scanner call; despite the naming, file_name holds a directory
        name which is documented as the value given to %s. */
@@ -1106,6 +1098,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
        signal(SIGPIPE,eximsigpipe);
 
        if (trigger) {
+         uschar * s;
          /* setup default virus name */
          malware_name = US"unknown";
 
@@ -1113,12 +1106,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
          scanner_record = fopen(CS file_name, "rb");
          while(fgets(CS linebuffer,32767,scanner_record) != NULL) {
            /* try match */
-           result = pcre_exec(cmdline_regex_re, NULL,
-                                 CS linebuffer, Ustrlen(linebuffer), 0, 0,
-                                 ovector, nelements(ovector));
-           if (result >= 2)
-             pcre_get_substring(CS linebuffer, ovector, result, 1,
-                                 (const char **) &malware_name_internal);
+           if ((s = m_pcre_exec(cmdline_regex_re, linebuffer)))
+             malware_name = s;
          }
          (void)fclose(scanner_record);
        }
@@ -1606,11 +1595,9 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
        uschar *sockline_scanner;
        uschar sockline_scanner_default[] = "%s\n";
        uschar *sockline_trigger;
-       const pcre *sockline_trigger_re;
+       const pcre *sockline_trig_re;
        uschar *sockline_regex;
-       const pcre *sockline_regex_re;
-       int result;
-       int ovector[10*3];
+       const pcre *sockline_name_re;
 
        /* find scanner command line */
        if (!(sockline_scanner = string_nextinlist(&av_scanner_work, &sep,
@@ -1623,11 +1610,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
          return sock_errlog_defer("missing trigger specification");
 
        /* precompile trigger regex */
-       sockline_trigger_re = pcre_compile(CS sockline_trigger, PCRE_COPT, (const char **)&rerror, &roffset, NULL);
-       if (sockline_trigger_re == NULL)
-         return sock_errlog_defer(
-           string_sprintf("regular expression error in '%s': %s at offset %d",
-             sockline_trigger, rerror, roffset));
+       if (!(sockline_trig_re = m_pcre_compile(CS sockline_trigger, &errstr)))
+         return sock_errlog_defer(errstr);
 
        /* find virus name regex */
        if (!(sockline_regex = string_nextinlist(&av_scanner_work, &sep,
@@ -1635,11 +1619,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
          return sock_errlog_defer("missing virus name regex specification");
 
        /* precompile name regex */
-       sockline_regex_re = pcre_compile(CS sockline_regex, PCRE_COPT, (const char **)&rerror, &roffset, NULL);
-       if (sockline_regex_re == NULL)
-         return sock_errlog_defer(
-           string_sprintf("regular expression error in '%s': %s at offset %d",
-             sockline_regex, rerror, roffset));
+       if (!(sockline_name_re = m_pcre_compile(CS sockline_regex, &errstr)))
+         return sock_errlog_defer(errstr);
 
        /* prepare scanner call */
        commandline = string_sprintf("%s/scan/%s/%s.eml", spool_directory, message_id, message_id);
@@ -1674,14 +1655,8 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
        linebuffer = string_copy(av_buffer);
 
        /* try trigger match */
-       if (regex_match_and_setup(sockline_trigger_re, linebuffer, 0, -1)) {
-         result = pcre_exec(sockline_regex_re, NULL,
-                             CS av_buffer, Ustrlen(av_buffer), 0, 0,
-                             ovector, nelements(ovector));
-         if (result >= 2)
-           pcre_get_substring(CS av_buffer, ovector, result, 1,
-                             (const char **)&malware_name);
-         else
+       if (regex_match_and_setup(sockline_trig_re, linebuffer, 0, -1)) {
+         if (!(malware_name = m_pcre_exec(sockline_name_re, av_buffer)))
            malware_name = US "unknown";
        }
        else /* no virus found */