From ac4d558b5e07523392bab2b4468b4c9f73745af9 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 29 May 2017 17:23:12 +0100 Subject: [PATCH] Malware: make "sock" cmdline default usable. Bug 2111 --- doc/doc-docbook/spec.xfpt | 10 +++++--- doc/doc-txt/ChangeLog | 4 +++ src/src/malware.c | 28 +++++++++++++++----- test/confs/4012 | 29 +++++++++++++++++++++ test/scripts/4000-scanning/4012 | 45 +++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 test/confs/4012 create mode 100644 test/scripts/4000-scanning/4012 diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt index 6fb150428..b891679a0 100644 --- a/doc/doc-docbook/spec.xfpt +++ b/doc/doc-docbook/spec.xfpt @@ -31702,13 +31702,17 @@ an address (which may be an IP address and port, or the path of a Unix socket), a commandline to send (may include a single %s which will be replaced with the path to the mail file to be scanned), an RE to trigger on from the returned data, -an RE to extract malware_name from the returned data. +and an RE to extract malware_name from the returned data. For example: .code -av_scanner = sock:127.0.0.1 6001:%s:(SPAM|VIRUS):(.*)\$ +av_scanner = sock:127.0.0.1 6001:%s:(SPAM|VIRUS):(.*)$ .endd +.new +Note that surrounding whitespace is stripped from each option, meaning +there is no way to specify a trailing newline. +.wen Default for the socket specifier is &_/tmp/malware.sock_&. -Default for the commandline is &_%s\n_&. +Default for the commandline is &_%s\n_& (note this does have a trailing newline). Both regular-expressions are required. .vitem &%sophie%& diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 05dc007de..4eb0d3b1a 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -98,6 +98,10 @@ PP/05 OpenSSL/1.1: use DH_bits() for more accurate DH param sizes. This configured limit or use OpenSSL 1.1. Nothing we can do for older versions. +JH/14 For the "sock" variant of the malware scanner interface, accept an empty + cmdline element to get the documented default one. Previously it was + inaccessible. + Exim version 4.89 ----------------- diff --git a/src/src/malware.c b/src/src/malware.c index 94a271b47..d7be4edbb 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -202,7 +202,11 @@ const pcre * cre = NULL; if (!(list_ele = string_nextinlist(list, sep, NULL, 0))) *errstr = US listerr; else + { + DEBUG(D_acl) debug_printf_indent("%15s%10s'%s'\n", "", "RE: ", + string_printing(list_ele)); cre = m_pcre_compile(CUS list_ele, errstr); + } return cre; } @@ -472,9 +476,6 @@ if ( strcmpic(malware_re,US"true") == 0 else if (!(re = m_pcre_compile(malware_re, &errstr))) return malware_errlog_defer(errstr); -/* Reset sep that is set by previous string_nextinlist() call */ -sep = 0; - /* if av_scanner starts with a dollar, expand it first */ if (*av_scanner == '$') { @@ -506,10 +507,15 @@ if (!malware_ok) scanner_name)); if (strcmpic(scanner_name, US scanent->name) != 0) continue; + DEBUG(D_acl) debug_printf_indent("Malware scan: %s tmo=%s\n", + scanner_name, readconf_printtime(timeout)); + if (!(scanner_options = string_nextinlist(&av_scanner_work, &sep, NULL, 0))) scanner_options = scanent->options_default; if (scanent->conn == MC_NONE) break; + + DEBUG(D_acl) debug_printf_indent("%15s%10s%s\n", "", "socket: ", scanner_options); switch(scanent->conn) { case MC_TCP: sock = ip_tcpsocket(scanner_options, &errstr, 5); break; @@ -521,7 +527,6 @@ if (!malware_ok) return m_errlog_defer(scanent, CUS callout_address, errstr); break; } - DEBUG(D_acl) debug_printf_indent("Malware scan: %s tmo %s\n", scanner_name, readconf_printtime(timeout)); switch (scanent->scancode) { @@ -1701,8 +1706,10 @@ b_seek: err = errno; const pcre *sockline_name_re; /* find scanner command line */ - if ((sockline_scanner = string_nextinlist(&av_scanner_work, &sep, - NULL, 0))) + if ( (sockline_scanner = string_nextinlist(&av_scanner_work, &sep, + NULL, 0)) + && *sockline_scanner + ) { /* check for no expansions apart from one %s */ uschar * s = Ustrchr(sockline_scanner, '%'); if (s++) @@ -1712,6 +1719,8 @@ b_seek: err = errno; } else sockline_scanner = sockline_scanner_default; + DEBUG(D_acl) debug_printf_indent("%15s%10s'%s'\n", "", "cmdline: ", + string_printing(sockline_scanner)); /* find scanner output trigger */ sockline_trig_re = m_pcre_nextinlist(&av_scanner_work, &sep, @@ -1727,7 +1736,8 @@ b_seek: err = errno; /* prepare scanner call - security depends on expansions check above */ commandline = string_sprintf( CS sockline_scanner, CS eml_filename); - + DEBUG(D_acl) debug_printf_indent("%15s%10s'%s'\n", "", "expanded: ", + string_printing(commandline)); /* Pass the command string to the socket */ if (m_sock_send(sock, commandline, Ustrlen(commandline), &errstr) < 0) @@ -1746,12 +1756,16 @@ b_seek: err = errno; US"buffer too small", sock); av_buffer[bread] = '\0'; linebuffer = string_copy(av_buffer); + DEBUG(D_acl) debug_printf_indent("%15s%10s'%s'\n", "", "answer: ", + string_printing(linebuffer)); /* try trigger match */ 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"; + DEBUG(D_acl) debug_printf_indent("%15s%10s'%s'\n", "", "name: ", + string_printing(malware_name)); } else /* no virus found */ malware_name = NULL; diff --git a/test/confs/4012 b/test/confs/4012 new file mode 100644 index 000000000..9afd4a07c --- /dev/null +++ b/test/confs/4012 @@ -0,0 +1,29 @@ +# Exim test configuration 4012 +# Content-scan: sock interface + +.include DIR/aux-var/std_conf_prefix + +primary_hostname = myhost.test.ex + +av_scanner = sock : 127.0.0.1 PORT_S : : BAD : NAME:: (\w+) + +# ----- Main settings ----- + +acl_smtp_rcpt = accept +acl_smtp_data = c_data + +begin acl + +c_data: + accept !malware = * OPT + deny logwrite = $callout_address malware_name $malware_name + +# ----- Routers ----- + +begin routers + +r: + driver = redirect + data = :blackhole: + +# End diff --git a/test/scripts/4000-scanning/4012 b/test/scripts/4000-scanning/4012 new file mode 100644 index 000000000..42d108c86 --- /dev/null +++ b/test/scripts/4000-scanning/4012 @@ -0,0 +1,45 @@ +# content scan interface: sock +need_ipv4 +munge loopback +# +server PORT_S +/ +>LF>RESULT: OK +**** +# +# +# +exim -odi -bs -DOPT= +ehlo test.ex +mail from:<> +rcpt to: +data +Date: Fri, 17 Dec 2004 14:35:01 +0100 +Subject: message should be accepted + +. +quit +**** +# +# +# +server PORT_S +/ +>LF>RESULT: BAD +>LF>NAME: wibble +**** +# +# +# +exim -odi -bs -DOPT= +ehlo test.ex +mail from:<> +rcpt to: +data +Date: Fri, 17 Dec 2004 14:35:01 +0100 +Subject: message should be rejected + +due to the server response (above) +. +quit +**** -- 2.25.1