Re: Exiscan Patch - multiple spamd servers and/or virus scanners

[email protected] (Dagfinn Ilmari Mannsåker)
Newsgroups gmane.mail.exim.user,gmane.mail.exim.exiscan.user
Organization Program-, Informasjons- og Nettverksteknologisk Gruppe, UiO
Message-ID <[email protected]>
Zarjazz <[email protected]> writes:

> Hi.
>
> Attached is a patch against exiscan versions 4.30-14 or 4.30-15 to add
> the following two new features.
[...]
> *) Multiple virus (malware) scanners.
>
> For the really paranoid you can have the option to have multiple AV
> programs scan your mail. Just add the extra configuration options to
> your existing av_scanner line.
>
> Example:
>
> av_scanner = \
>         clamd:/var/run/clamav/clamd.sock:\
>         cmdline:/opt/kav/bin/aveclient -p /var/run/aveserver -s
> %s/*.eml:INFECTED:^LINFECTED (.+)
>
> - -----
>
> I have run both features on my own setup without any problems but I
> would appreciate any comments from anyone who could test on other systems.

I need the multiple anti-virus scanner functionality for a customer, and
a co-worker pointed me at this patch. The problem was it was totally
unreviewable due to including loads of irrelevant whitespace and
coding-style changes. I spent a few hours doing cycles of applying,
cleaning up, 'diff -w', lather, rinse, repeat, and here's the result for
the virus scanner part, rediffed against exiscan-acl-4.34-22.

The forward declarations are mainly for patch readability, feel free to
remove them and move the malware() function after the scan_*() functions
if you prefer that.

Also, the indentation and coding style is quite inconsistent, since
stuff has been written by different people, and I didn't reindent the
scanning functions after splitting them out. I'll follow-up with a
cleanup patch on top of this one.

--- exiscan-4.34-22/src/malware.c.orig	2004-06-18 20:33:47.000000000 +0200
+++ exiscan-4.34-22/src/malware.c	2004-06-19 00:47:44.000000000 +0200
@@ -39,6 +39,14 @@
 uschar malware_name_buffer[256];
 int malware_ok = 0;

+/* Forward declarations. */
+static int scan_drweb(uschar **pscanner, int *psep);
+static int scan_kavdaemon(uschar **pscanner, int *psep);
+static int scan_cmdline(uschar **pscanner, int *psep);
+static int scan_sophie(uschar **pscanner, int *psep);
+static int scan_clamd(uschar **pscanner, int *psep);
+static int scan_mksd(uschar **pscanner, int *psep);
+
 int malware(uschar **listptr) {
   int sep = 0;
   uschar *list = *listptr;
@@ -100,21 +108,90 @@

   /* Do not scan twice. */
   if (malware_ok == 0) {
+    int rc, n = 0;

     /* find the scanner type from the av_scanner option */
-    if ((scanner_name = string_nextinlist(&av_scanner_work, &sep,
-                                          scanner_name_buffer,
-                                          sizeof(scanner_name_buffer))) == NULL) {
+    /* loop until we find a virus or reach end of list */
+    while (malware_name == NULL &&
+           (scanner_name = string_nextinlist(&av_scanner_work, &sep,
+                                             scanner_name_buffer,
+                                             sizeof(scanner_name_buffer))) != NULL) {
+      /* "drweb" scanner type ----------------------------------------------- */
+      if (strcmpic(scanner_name, US "drweb") == 0) {
+        rc = scan_drweb(&av_scanner_work, &sep);
+        if (rc != OK)
+          return rc;
+      }
+      /* "kavdaemon" scanner type ------------------------------------------------ */
+      else if (strcmpic(scanner_name, US "kavdaemon") == 0) {
+        rc = scan_kavdaemon(&av_scanner_work, &sep);
+        if (rc != OK)
+          return rc;
+      }
+
+      /* "cmdline" scanner type ------------------------------------------------ */
+      else if (strcmpic(scanner_name, US "cmdline") == 0) {
+        rc = scan_cmdline(&av_scanner_work, &sep);
+        if (rc != OK)
+          return rc;
+      }
+
+      /* "sophie" scanner type ------------------------------------------------- */
+      else if (strcmpic(scanner_name, US "sophie") == 0) {
+        rc = scan_sophie(&av_scanner_work, &sep);
+        if (rc != OK)
+          return rc;
+      }
+
+      /* "clamd" scanner type ------------------------------------------------- */
+      else if (strcmpic(scanner_name, US "clamd") == 0) {
+        rc = scan_clamd(&av_scanner_work, &sep);
+        if (rc != OK)
+          return rc;
+      }
+
+      /* "mksd" scanner type --------------------------------------------------- */
+      else if (strcmpic(scanner_name, US "mksd") == 0) {
+        rc = scan_mksd(&av_scanner_work, &sep);
+        if (rc != OK)
+          return rc;
+      }
+
+      /* "unknown" scanner type ------------------------------------------------- */
+      else {
+        log_write(0, LOG_MAIN | LOG_PANIC,
+                  "malware condition: unknown scanner type '%s'", scanner_name);
+        return DEFER;
+      }
+      n++;
+    }
+
+    if (malware_name == NULL && n == 0) {
       /* no scanner given */
       log_write(0, LOG_MAIN|LOG_PANIC,
              "malware acl condition: av_scanner configuration variable is empty");
       return DEFER;
     };

+    /* set "been here, done that" marker */
+    malware_ok = 1;
+  };
+
+  /* match virus name against pattern (caseless ------->----------v) */
+  if ((malware_name != NULL) &&
+      (regex_match_and_setup(re, malware_name, 0, -1))) {
+    return OK;
+  }
+  else {
+    return FAIL;
+  };
+}
+
 	/* "drweb" scanner type ----------------------------------------------- */
 	/* v0.1 - added support for tcp sockets					*/
 	/* v0.0 - initial release -- support for unix sockets			*/
-	if (strcmpic(scanner_name,US"drweb") == 0) {
+static int scan_drweb(uschar ** pscanner, int *psep)
+{
 		uschar *drweb_options;
 		uschar drweb_options_buffer[1024];
 		uschar drweb_options_default[] = "/usr/local/drweb/run/drwebd.sock";
@@ -131,8 +208,10 @@
 		struct hostent *he;
 		struct in_addr in;
 		pcre *drweb_re;
+    		int roffset;
+		uschar *rerror;

-		if ((drweb_options = string_nextinlist(&av_scanner_work, &sep,
+		if ((drweb_options = string_nextinlist(pscanner, psep,
 			drweb_options_buffer, sizeof(drweb_options_buffer))) == NULL) {
 			/* no options supplied, use default options */
 			drweb_options = drweb_options_default;
@@ -355,11 +434,12 @@
 			malware_name = NULL;
 		};
 		close(sock);
-	}
-	/* ----------------------------------------------------------------------- */
+	return OK;
+}

     /* "kavdaemon" scanner type ------------------------------------------------ */
-    else if (strcmpic(scanner_name,US"kavdaemon") == 0) {
+static int scan_kavdaemon(uschar ** pscanner, int *psep)
+{
       uschar *kav_options;
       uschar kav_options_buffer[1024];
       uschar kav_options_default[] = "/var/run/AvpCtl";
@@ -372,8 +452,10 @@
       int kav_rc;
       unsigned long kav_reportlen, bread;
       pcre *kav_re;
+      int roffset;
+      uschar *rerror;

-      if ((kav_options = string_nextinlist(&av_scanner_work, &sep,
+      if ((kav_options = string_nextinlist(pscanner, psep,
                                            kav_options_buffer,
                                            sizeof(kav_options_buffer))) == NULL) {
         /* no options supplied, use default options */
@@ -520,12 +602,12 @@
       };

       close(sock);
-    }
-    /* ----------------------------------------------------------------------- */
-
+      return OK;
+}

     /* "cmdline" scanner type ------------------------------------------------ */
-    else if (strcmpic(scanner_name,US"cmdline") == 0) {
+static int scan_cmdline(uschar ** pscanner, int *psep)
+{
       uschar *cmdline_scanner;
       uschar cmdline_scanner_buffer[1024];
       uschar *cmdline_trigger;
@@ -544,9 +626,11 @@
       int trigger = 0;
       int result;
       int ovector[30];
+      int roffset;
+      const uschar *rerror;

       /* find scanner command line */
-      if ((cmdline_scanner = string_nextinlist(&av_scanner_work, &sep,
+      if ((cmdline_scanner = string_nextinlist(pscanner, psep,
                                           cmdline_scanner_buffer,
                                           sizeof(cmdline_scanner_buffer))) == NULL) {
         /* no command line supplied */
@@ -556,7 +640,7 @@
       };

       /* find scanner output trigger */
-      if ((cmdline_trigger = string_nextinlist(&av_scanner_work, &sep,
+      if ((cmdline_trigger = string_nextinlist(pscanner, psep,
                                           cmdline_trigger_buffer,
                                           sizeof(cmdline_trigger_buffer))) == NULL) {
         /* no trigger regex supplied */
@@ -574,7 +658,7 @@
       };

       /* find scanner name regex */
-      if ((cmdline_regex = string_nextinlist(&av_scanner_work, &sep,
+      if ((cmdline_regex = string_nextinlist(pscanner, psep,
                                              cmdline_regex_buffer,
                                              sizeof(cmdline_regex_buffer))) == NULL) {
         /* no name regex supplied */
@@ -663,12 +747,12 @@
         /* no virus found */
         malware_name = NULL;
       };
-    }
-    /* ----------------------------------------------------------------------- */
-
+      return OK;
+}

     /* "sophie" scanner type ------------------------------------------------- */
-    else if (strcmpic(scanner_name,US"sophie") == 0) {
+static int scan_sophie(uschar ** pscanner, int *psep)
+{
       uschar *sophie_options;
       uschar sophie_options_buffer[1024];
       uschar sophie_options_default[] = "/var/run/sophie";
@@ -678,7 +762,7 @@
       uschar file_name[1024];
       uschar av_buffer[1024];

-      if ((sophie_options = string_nextinlist(&av_scanner_work, &sep,
+      if ((sophie_options = string_nextinlist(pscanner, psep,
                                           sophie_options_buffer,
                                           sizeof(sophie_options_buffer))) == NULL) {
         /* no options supplied, use default options */
@@ -738,13 +822,13 @@
         /* all ok, no virus */
         malware_name = NULL;
       };
-    }
-    /* ----------------------------------------------------------------------- */
-
+      return OK;
+}

     /* "clamd" scanner type ------------------------------------------------- */
     /* This code was contributed by David Saez <[email protected]> */
-    else if (strcmpic(scanner_name,US"clamd") == 0) {
+static int scan_clamd(uschar ** pscanner, int *psep)
+{
       uschar *clamd_options;
       uschar clamd_options_buffer[1024];
       uschar clamd_options_default[] = "/tmp/clamd";
@@ -757,7 +841,7 @@
       struct hostent *he;
       struct in_addr in;

-      if ((clamd_options = string_nextinlist(&av_scanner_work, &sep,
+      if ((clamd_options = string_nextinlist(pscanner, psep,
                                              clamd_options_buffer,
                                              sizeof(clamd_options_buffer))) == NULL) {
         /* no options supplied, use default options */
@@ -907,12 +991,12 @@
               malware_name = NULL;
            }
       }
-    }
-    /* ----------------------------------------------------------------------- */
-
+	return OK;
+}

     /* "mksd" scanner type --------------------------------------------------- */
-    else if (strcmpic(scanner_name,US"mksd") == 0) {
+static int scan_mksd(uschar ** pscanner, int *psep)
+{
       uschar *mksd_options;
       char *mksd_options_end;
       uschar mksd_options_buffer[32];
@@ -921,7 +1005,7 @@
       int sock;
       int retval;

-      if ((mksd_options = string_nextinlist(&av_scanner_work, &sep,
+      if ((mksd_options = string_nextinlist(pscanner, psep,
                                             mksd_options_buffer,
                                             sizeof(mksd_options_buffer))) != NULL) {
         mksd_maxproc = (int) strtol(CS mksd_options, &mksd_options_end, 10);
@@ -958,31 +1042,8 @@

       if (retval != OK)
         return retval;
-    }
-    /* ----------------------------------------------------------------------- */
-
-
-
-    /* "unknown" scanner type ------------------------------------------------- */
-    else {
-      log_write(0, LOG_MAIN|LOG_PANIC,
-             "malware condition: unknown scanner type '%s'", scanner_name);
-      return DEFER;
-    };
-    /* ----------------------------------------------------------------------- */

-    /* set "been here, done that" marker */
-    malware_ok = 1;
-  };
-
-  /* match virus name against pattern (caseless ------->----------v) */
-  if ( (malware_name != NULL) &&
-       (regex_match_and_setup(re, malware_name, 0, -1)) ) {
     return OK;
-  }
-  else {
-    return FAIL;
-  };
 }

 /* ============= private routines for the "mksd" scanner type ============== */

--
ilmari


--

## List details at http://www.exim.org/mailman/listinfo/exim-users Exim details at http://www.exim.org/ ##
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.