summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2014-11-21 18:04:07 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2015-01-12 18:58:37 +0000
commitfd02dc0e4e20ecebb0f247641c5aff519bc5e4db (patch)
treeca9cdc3de7fdb5cc2c883236f2fdf57eec95e594
parentb6fbf22d63de88b77d79cd0b1d2337e589cac6d7 (diff)
Apply timeout to Fsecure malware response. Bug 1549
-rw-r--r--src/src/malware.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/src/src/malware.c b/src/src/malware.c
index 167f47f2c..1a3dc7f9b 100644
--- a/src/src/malware.c
+++ b/src/src/malware.c
@@ -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 */