Apply timeout to Fsecure malware response. Bug 1549
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 21 Nov 2014 18:04:07 +0000 (18:04 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 20 Dec 2014 18:28:19 +0000 (18:28 +0000)
src/src/malware.c

index 167f47f2c05b79e4c057c652632e22e965a78ae1..1a3dc7f9b02c8b8070e5168a9e9adaf45de70a17 100644 (file)
@@ -710,12 +710,13 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
                                        US"CONFIGURE\tTIMEOUT\t0\n",
                                        US"CONFIGURE\tMAXARCH\t5\n",
                                        US"CONFIGURE\tMIME\t1\n" };
+       time_t tmo;
 
        malware_name = NULL;
 
        DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan [%s]\n",
            scanner_name, scanner_options);
-
+       tmo = time(NULL) + MALWARE_TIMEOUT;
        /* pass options */
        memset(av_buffer, 0, sizeof(av_buffer));
        for (i=0; i != nelements(cmdopt); i++) {
@@ -744,24 +745,46 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking)
        /* todo also SUSPICION\t */
        fs_inf = m_pcre_compile(US"\\S{0,5}INFECTED\\t[^\\t]*\\t([^\\t]+)\\t\\S*$", &errstr);
 
-       /* read report, linewise */
-       do {
-         i = 0;
-         memset(av_buffer, 0, sizeof(av_buffer));
-         do {
-           if ((bread= ip_recv(sock, &av_buffer[i], 1, MALWARE_TIMEOUT)) < 0)
+       /* read report, linewise. Apply a timeout as the Fsecure daemon
+       sometimes wants an answer to "PING" but they won't tell us what */
+       {
+         uschar * p = av_buffer;
+         uschar * q;
+
+         for (;;)
+           {
+           int t = tmo - time(NULL);
+
+           errno = ETIME;
+           i =  av_buffer+sizeof(av_buffer)-p;
+           if (  t <= 0
+              || (bread= ip_recv(sock, p, i-1, t)) < 0
+              )
              return m_errlog_defer_3(scanent,
                string_sprintf("unable to read result (%s)", strerror(errno)),
                sock);
-         } while (++i < sizeof(av_buffer)-1  &&  av_buffer[i-1] != '\n');
-         av_buffer[i-1] = '\0';
 
-         /* Really search for virus again? */
-         if (malware_name == NULL)
-           /* try matcher on the line, grab substring */
-           malware_name = m_pcre_exec(fs_inf, av_buffer);
+           for (p[bread] = '\0'; q = strchr(p, '\n'); p = q+1)
+             {
+             *q = '\0';
+
+             /* Really search for virus again? */
+             if (!malware_name)
+               /* try matcher on the line, grab substring */
+               malware_name = m_pcre_exec(fs_inf, p);
+
+             if (Ustrstr(p, "OK\tScan ok."))
+               goto fsec_found;
+             }
+
+           /* copy down the trailing partial line then read another chunk */
+           i =  av_buffer+sizeof(av_buffer)-p;
+           memmove(av_buffer, p, i);
+           p = av_buffer+i;
+         }
        }
-       while (Ustrstr(av_buffer, "OK\tScan ok.") == NULL);
+
+      fsec_found:
        break;
       }        /* fsecure */