summaryrefslogtreecommitdiff
path: root/src/src/malware.c
diff options
context:
space:
mode:
authorAndrew Colin Kissa <andrew@topdog.za.net>2017-03-12 19:14:47 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2017-03-12 19:14:47 +0000
commit71b32d412ac4792ca5e8d4a697afddb46c407bd9 (patch)
treee69ba0ceada72514eda7e058a7d73fd3e26b0264 /src/src/malware.c
parentea0d0cfba5fa9267c0f82af617f2094bc7545745 (diff)
downloadexim4-71b32d412ac4792ca5e8d4a697afddb46c407bd9.tar.gz
Malware: new connection type "f-prot6d" for FPSCAND protocol over TCP
Diffstat (limited to 'src/src/malware.c')
-rw-r--r--src/src/malware.c57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/src/malware.c b/src/src/malware.c
index 549422ebb..f9c4c414f 100644
--- a/src/src/malware.c
+++ b/src/src/malware.c
@@ -13,7 +13,7 @@
#ifdef WITH_CONTENT_SCAN
typedef enum {M_FPROTD, M_DRWEB, M_AVES, M_FSEC, M_KAVD, M_CMDL,
- M_SOPHIE, M_CLAMD, M_SOCK, M_MKSD, M_AVAST} scanner_t;
+ M_SOPHIE, M_CLAMD, M_SOCK, M_MKSD, M_AVAST, M_FPROT6D} scanner_t;
typedef enum {MC_NONE, MC_TCP, MC_UNIX, MC_STRM} contype_t;
static struct scan
{
@@ -34,6 +34,7 @@ static struct scan
{ M_SOCK, US"sock", US"/tmp/malware.sock", MC_STRM },
{ M_MKSD, US"mksd", NULL, MC_NONE },
{ M_AVAST, US"avast", US"/var/run/avast/scan.sock", MC_STRM },
+ { M_FPROT6D, US"f-prot6d", US"localhost 10200", MC_TCP },
{ -1, NULL, NULL, MC_NONE } /* end-marker */
};
@@ -84,6 +85,11 @@ static const uschar * ava_re_virus_str = US "(?!\\\\)\\t\\[L\\]\\d\\.\\d\\t\\d\\
static const pcre * ava_re_clean = NULL;
static const pcre * ava_re_virus = NULL;
+static const uschar * fprot6d_re_error_str = US "^\\d+\\s<(.+?)>$";
+static const uschar * fprot6d_re_virus_str = US "^\\d+\\s<infected:\\s+(.+?)>\\s+.+$";
+static const pcre * fprot6d_re_error = NULL;
+static const pcre * fprot6d_re_virus = NULL;
+
/******************************************************************************/
@@ -1911,8 +1917,53 @@ if (!malware_ok)
sock);
default: break;
}
+ break;
}
+
+ case M_FPROT6D: /* "f-prot6d" scanner type ----------------------------------- */
+ {
+ int bread;
+ uschar * e;
+ uschar * linebuffer;
+ uschar * scanrequest;
+ uschar av_buffer[1024];
+
+ if ((!fprot6d_re_virus && !(fprot6d_re_virus = m_pcre_compile(fprot6d_re_virus_str, &errstr)))
+ || (!fprot6d_re_error && !(fprot6d_re_error = m_pcre_compile(fprot6d_re_error_str, &errstr))))
+ return malware_errlog_defer(errstr);
+
+ scanrequest = string_sprintf("SCAN FILE %s\n", eml_filename);
+ DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s: %s\n",
+ scanner_name, scanrequest);
+
+ if (m_sock_send(sock, scanrequest, Ustrlen(scanrequest), &errstr) < 0)
+ return m_errlog_defer(scanent, CUS callout_address, errstr);
+
+ bread = ip_recv(sock, av_buffer, sizeof(av_buffer), tmo-time(NULL));
+
+ if (bread <= 0)
+ return m_errlog_defer_3(scanent, CUS callout_address,
+ string_sprintf("unable to read from socket (%s)", strerror(errno)),
+ sock);
+
+ if (bread == sizeof(av_buffer))
+ return m_errlog_defer_3(scanent, CUS callout_address,
+ US"buffer too small", sock);
+
+ av_buffer[bread] = '\0';
+ linebuffer = string_copy(av_buffer);
+
+ m_sock_send(sock, US"QUIT\n", 5, 0);
+
+ if ((e = m_pcre_exec(fprot6d_re_error, linebuffer)))
+ return m_errlog_defer_3(scanent, CUS callout_address,
+ string_sprintf("scanner reported error (%s)", e), sock);
+
+ if (!(malware_name = m_pcre_exec(fprot6d_re_virus, linebuffer)))
+ malware_name = NULL;
+
break;
+ } /* f-prot6d */
} /* scanner type switch */
if (sock >= 0)
@@ -2028,6 +2079,10 @@ if (!ava_re_clean)
ava_re_clean = regex_must_compile(ava_re_clean_str, FALSE, TRUE);
if (!ava_re_virus)
ava_re_virus = regex_must_compile(ava_re_virus_str, FALSE, TRUE);
+if (!fprot6d_re_error)
+ fprot6d_re_error = regex_must_compile(fprot6d_re_error_str, FALSE, TRUE);
+if (!fprot6d_re_virus)
+ fprot6d_re_virus = regex_must_compile(fprot6d_re_virus_str, FALSE, TRUE);
}
#endif /*WITH_CONTENT_SCAN*/