Malware: make "sock" cmdline default usable. Bug 2111
authorJeremy Harris <jgh146exb@wizmail.org>
Mon, 29 May 2017 16:23:12 +0000 (17:23 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 30 May 2017 19:05:40 +0000 (20:05 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/malware.c
test/confs/4012 [new file with mode: 0644]
test/scripts/4000-scanning/4012 [new file with mode: 0644]

index 6fb150428ca1a09f8154f29660507cd536c67551..b891679a0c9b3ce44a903bc5aa46ca80cd99fc37 100644 (file)
@@ -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%&
index 05dc007ded23fcc9bb052f61c7c329c1040c7628..4eb0d3b1a725a27c4a4dfa2ecfa673c3b31c1a14 100644 (file)
@@ -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
 -----------------
index 94a271b471f8c0903e1b361bb6ee605ddc2b0fea..d7be4edbb599b51a76351db980d35d0cb669c50a 100644 (file)
@@ -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 (file)
index 0000000..9afd4a0
--- /dev/null
@@ -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 (file)
index 0000000..42d108c
--- /dev/null
@@ -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:<userx@test.ex>
+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:<userx@test.ex>
+data
+Date: Fri, 17 Dec 2004 14:35:01 +0100
+Subject: message should be rejected
+
+due to the server response (above)
+.
+quit
+****