/* Some (currently avast only) use backslash escaped whitespace,
this function undoes these escapes */
+#ifndef DISABLE_MAL_AVAST
static inline void
unescape(uschar *p)
{
if (*p == '\\' && (isspace(p[1]) || p[1] == '\\'))
for (p0 = p; *p0; ++p0) *p0 = p0[1];
}
+#endif
/* --- malware_*_defer --- */
static inline int
return malware_panic_defer(string_sprintf("%s %s : %s",
scanent->name, hostport ? hostport : CUS"", str));
}
-static inline int
-m_log_defer(struct scan * scanent, const uschar * hostport,
- const uschar * str)
-{
-return malware_log_defer(string_sprintf("%s %s : %s",
- scanent->name, hostport ? hostport : CUS"", str));
-}
/* --- m_*_defer_3 */
static inline int
m_panic_defer_3(struct scan * scanent, const uschar * hostport,
const uschar * str, int fd_to_close)
{
+DEBUG(D_acl) debug_print_socket(fd_to_close);
(void) close(fd_to_close);
return m_panic_defer(scanent, hostport, str);
}
m_tcpsocket(const uschar * hostname, unsigned int port,
host_item * host, uschar ** errstr, const blob * fastopen_blob)
{
-return ip_connectedsocket(SOCK_STREAM, hostname, port, port, 5,
+int fd = ip_connectedsocket(SOCK_STREAM, hostname, port, port, 5,
host, errstr, fastopen_blob);
+#ifdef EXIM_TFO_FREEBSD
+/* Under some fault conditions, FreeBSD 12.2 seen to send a (non-TFO) SYN
+and, getting no response, wait for a long time. Impose a 5s max. */
+if (fd >= 0)
+ {
+ struct timeval tv = {.tv_sec = 5};
+ fd_set fds;
+ FD_ZERO(fds); FD_SET(fd, &fds); (void) select(fd+1, NULL, &fds, NULL, &tv);
+ }
+#endif
+return fd;
}
#endif
return cre;
}
+
/*
Simple though inefficient wrapper for reading a line. Drop CRs and the
trailing newline. Can return early on buffer full. Null-terminate.
}
if (!ok)
{
- DEBUG(D_acl) debug_printf_indent("Malware scan: read %s (%s)\n",
+ DEBUG(D_acl)
+ {
+ debug_printf_indent("Malware scan: read %s (%s)\n",
rcv==0 ? "EOF" : "error", strerror(errno));
+ debug_print_socket(fd);
+ }
return rcv==0 ? -1 : -2;
}
*p = '\0';
}
/* return TRUE iff size as requested */
+#ifndef DISABLE_MAL_DRWEB
static BOOL
recv_len(int sock, void * buf, int size, time_t tmo)
{
? recv(sock, buf, size, 0) == size
: FALSE;
}
+#endif
host_item connhost;
uschar *clamav_fbuf;
int clam_fd, result;
- off_t fsize;
unsigned int fsize_uint;
BOOL use_scan_command = FALSE;
clamd_address * cv[MAX_CLAMD_SERVERS];
if (!use_scan_command)
{
+ struct stat st;
/* New protocol: "zINSTREAM\n" followed by a sequence of <length><data>
chunks, <n> a 4-byte number (network order), terminated by a zero-length
chunk. */
strerror(errno)),
malware_daemon_ctx.sock);
- /* calc file size */
if ((clam_fd = exim_open2(CS eml_filename, O_RDONLY)) < 0)
{
int err = errno;
eml_filename, strerror(err)),
malware_daemon_ctx.sock);
}
- if ((fsize = lseek(clam_fd, 0, SEEK_END)) < 0)
+ if (fstat(clam_fd, &st) < 0)
{
- int err;
-b_seek: err = errno;
+ int err = errno;
(void)close(clam_fd);
return m_panic_defer_3(scanent, NULL,
- string_sprintf("can't seek spool file %s: %s",
+ string_sprintf("can't stat spool file %s: %s",
eml_filename, strerror(err)),
malware_daemon_ctx.sock);
}
- fsize_uint = (unsigned int) fsize;
- if ((off_t)fsize_uint != fsize)
+ fsize_uint = (unsigned int) st.st_size;
+ if ((off_t)fsize_uint != st.st_size)
{
(void)close(clam_fd);
return m_panic_defer_3(scanent, NULL,
- string_sprintf("seeking spool file %s, size overflow",
- eml_filename),
+ string_sprintf("stat spool file %s, size overflow", eml_filename),
malware_daemon_ctx.sock);
}
- if (lseek(clam_fd, 0, SEEK_SET) < 0)
- goto b_seek;
- if (!(clamav_fbuf = store_malloc(fsize_uint)))
- {
- (void)close(clam_fd);
+ /* send file body to socket */
+ send_size = htonl(fsize_uint);
+ if (send(malware_daemon_ctx.sock, &send_size, sizeof(send_size), 0) < 0)
return m_panic_defer_3(scanent, NULL,
- string_sprintf("unable to allocate memory %u for file (%s)",
- fsize_uint, eml_filename),
+ string_sprintf("unable to send file size to socket (%s)", hostname),
malware_daemon_ctx.sock);
- }
- if ((result = read(clam_fd, clamav_fbuf, fsize_uint)) < 0)
+ while (fsize_uint)
{
- int err = errno;
- store_free(clamav_fbuf); (void)close(clam_fd);
- return m_panic_defer_3(scanent, NULL,
- string_sprintf("can't read spool file %s: %s",
- eml_filename, strerror(err)),
- malware_daemon_ctx.sock);
+ unsigned n = MIN(fsize_uint, big_buffer_size);
+ if ((n = read(clam_fd, big_buffer, n)) < 0)
+ return m_panic_defer_3(scanent, NULL,
+ string_sprintf("can't read spool file %s: %s",
+ eml_filename, strerror(errno)),
+ malware_daemon_ctx.sock);
+ if ((n = send(malware_daemon_ctx.sock, clamav_fbuf, n, 0)) < 0)
+ return m_panic_defer_3(scanent, NULL,
+ string_sprintf("unable to send file body to socket (%s)", hostname),
+ malware_daemon_ctx.sock);
+ fsize_uint -= n;
}
- (void)close(clam_fd);
- /* send file body to socket */
- send_size = htonl(fsize_uint);
send_final_zeroblock = 0;
- if ((send(malware_daemon_ctx.sock, &send_size, sizeof(send_size), 0) < 0) ||
- (send(malware_daemon_ctx.sock, clamav_fbuf, fsize_uint, 0) < 0) ||
- (send(malware_daemon_ctx.sock, &send_final_zeroblock, sizeof(send_final_zeroblock), 0) < 0))
- {
- store_free(clamav_fbuf);
+ if (send(malware_daemon_ctx.sock, &send_final_zeroblock, sizeof(send_final_zeroblock), 0) < 0)
return m_panic_defer_3(scanent, NULL,
- string_sprintf("unable to send file body to socket (%s)", hostname),
+ string_sprintf("unable to send file terminator to socket (%s)", hostname),
malware_daemon_ctx.sock);
- }
- store_free(clamav_fbuf);
}
else
{ /* use scan command */