X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/5df838645bcdb135355205a115bf918c85987caf..4a5cbaff2f9addfc9b4375a97ec6669bf18ee4db:/src/src/malware.c diff --git a/src/src/malware.c b/src/src/malware.c index b626b18a8..32f2e9e49 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -147,9 +147,10 @@ uses the returned in_addr to get a second connection to the same system. */ static inline int m_tcpsocket(const uschar * hostname, unsigned int port, - host_item * host, uschar ** errstr) + host_item * host, uschar ** errstr, const blob * fastopen) { -return ip_connectedsocket(SOCK_STREAM, hostname, port, port, 5, host, errstr); +return ip_connectedsocket(SOCK_STREAM, hostname, port, port, 5, + host, errstr, fastopen); } static int @@ -1254,6 +1255,7 @@ badseek: err = errno; #else uint32_t send_size, send_final_zeroblock; #endif + blob cmd_str; /*XXX if unixdomain socket, only one server supported. Needs fixing; there's no reason we should not mix local and remote servers */ @@ -1349,6 +1351,19 @@ badseek: err = errno; string_sprintf("local/SCAN mode incompatible with" \ " : in path to email filename [%s]", eml_filename)); + /* Set up the very first data we will be sending */ + if (!use_scan_command) +#ifdef WITH_OLD_CLAMAV_STREAM + { cmd_str.data = US"STREAM\n"; cmd_str.len = 7; } +#else + { cmd_str.data = US"zINSTREAM"; cmd_str.len = 10; } +#endif + else + { + cmd_str.data = string_sprintf("SCAN %s\n", eml_filename); + cmd_str.len = Ustrlen(cmd_str.data); + } + /* We have some network servers specified */ if (num_servers) { @@ -1358,7 +1373,7 @@ badseek: err = errno; while (num_servers > 0) { - int i = random_number( num_servers ); + int i = random_number(num_servers); clamd_address * cd = cv[i]; DEBUG(D_acl) debug_printf_indent("trying server name %s, port %u\n", @@ -1368,11 +1383,12 @@ badseek: err = errno; * on both connections (as one host could resolve to multiple ips) */ for (;;) { - sock= m_tcpsocket(cd->hostspec, cd->tcp_port, &connhost, &errstr); - if (sock >= 0) + if ((sock = m_tcpsocket(cd->hostspec, cd->tcp_port, + &connhost, &errstr, &cmd_str)) >= 0) { /* Connection successfully established with a server */ hostname = cd->hostspec; + cmd_str.len = 0; break; } if (cd->retry <= 0) break; @@ -1421,9 +1437,10 @@ badseek: err = errno; "Malware scan: issuing %s old-style remote scan (PORT)\n", scanner_name); - /* Pass the string to ClamAV (7 = "STREAM\n") */ - if (m_sock_send(sock, US"STREAM\n", 7, &errstr) < 0) - return m_errlog_defer(scanent, CUS callout_address, errstr); + /* Pass the string to ClamAV (7 = "STREAM\n"), if not already sent */ + if (cmd_str.len) + if (m_sock_send(sock, cmd_str.data, cmd_str.len, &errstr) < 0) + return m_errlog_defer(scanent, CUS callout_address, errstr); memset(av_buffer2, 0, sizeof(av_buffer2)); bread = ip_recv(sock, av_buffer2, sizeof(av_buffer2), tmo-time(NULL)); @@ -1443,13 +1460,13 @@ badseek: err = errno; "ClamAV returned null", sock); av_buffer2[bread] = '\0'; - if( sscanf(CS av_buffer2, "PORT %u\n", &port) != 1 ) + if(sscanf(CS av_buffer2, "PORT %u\n", &port) != 1) return m_errlog_defer_3(scanent, CUS callout_address, string_sprintf("Expected port information from clamd, got '%s'", av_buffer2), sock); - sockData = m_tcpsocket(connhost.address, port, NULL, &errstr); + sockData = m_tcpsocket(connhost.address, port, NULL, &errstr, NULL); if (sockData < 0) return m_errlog_defer_3(scanent, CUS callout_address, errstr, sock); @@ -1463,12 +1480,13 @@ badseek: err = errno; "Malware scan: issuing %s new-style remote scan (zINSTREAM)\n", scanner_name); - /* Pass the string to ClamAV (10 = "zINSTREAM\0") */ - if (send(sock, "zINSTREAM", 10, 0) < 0) - return m_errlog_defer_3(scanent, CUS hostname, - string_sprintf("unable to send zINSTREAM to socket (%s)", - strerror(errno)), - sock); + /* Pass the string to ClamAV (10 = "zINSTREAM\0"), if not already sent */ + if (cmd_str.len) + if (send(sock, cmd_str.data, cmd_str.len, 0) < 0) + return m_errlog_defer_3(scanent, CUS hostname, + string_sprintf("unable to send zINSTREAM to socket (%s)", + strerror(errno)), + sock); # define CLOSE_SOCKDATA /**/ #endif @@ -1569,17 +1587,17 @@ b_seek: err = errno; scanned twice, in the broken out files and from the original .eml. Since ClamAV now handles emails (and has for quite some time) we can just use the email file itself. */ - /* Pass the string to ClamAV (7 = "SCAN \n" + \0) */ - file_name = string_sprintf("SCAN %s\n", eml_filename); + /* Pass the string to ClamAV (7 = "SCAN \n" + \0), if not already sent */ DEBUG(D_acl) debug_printf_indent( "Malware scan: issuing %s local-path scan [%s]\n", scanner_name, scanner_options); - if (send(sock, file_name, Ustrlen(file_name), 0) < 0) - return m_errlog_defer_3(scanent, CUS callout_address, - string_sprintf("unable to write to socket (%s)", strerror(errno)), - sock); + if (cmd_str.len) + if (send(sock, cmd_str.data, cmd_str.len, 0) < 0) + return m_errlog_defer_3(scanent, CUS callout_address, + string_sprintf("unable to write to socket (%s)", strerror(errno)), + sock); /* Do not shut down the socket for writing; a user report noted that * clamd 0.70 does not react well to this. */