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/ ##