X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/cb570b5ea1ff234ae16b2c32a236ccd520a80f7a..e1d04f48a45c9f8e8ff75610003048f8ead73219:/src/src/malware.c diff --git a/src/src/malware.c b/src/src/malware.c index 9451392f2..547bc26e6 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -2,8 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) Tom Kistner 2003 - 2015 */ -/* License: GPL */ +/* Copyright (c) Tom Kistner 2003 - 2015 + * License: GPL + * Copyright (c) The Exim Maintainers 2016 + */ /* Code for calling virus (malware) scanners. Called from acl.c. */ @@ -106,7 +108,7 @@ BOOL malware_ok = FALSE; the scan directory normally for that case, but look into rigging up the needed header variables if not already set on the command-line? */ extern int spool_mbox_ok; -extern uschar spooled_message_id[17]; +extern uschar spooled_message_id[MESSAGE_ID_LENGTH+1]; @@ -229,13 +231,13 @@ while ((rcv = read(fd, p, 1)) > 0) } if (!ok) { - DEBUG(D_acl) debug_printf("Malware scan: read %s (%s)\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: read %s (%s)\n", rcv==0 ? "EOF" : "error", strerror(errno)); return rcv==0 ? -1 : -2; } *p = '\0'; -DEBUG(D_acl) debug_printf("Malware scan: read '%s'\n", buffer); +DEBUG(D_acl) debug_printf_indent("Malware scan: read '%s'\n", buffer); return p - buffer; } @@ -473,7 +475,7 @@ if (*av_scanner == '$') expand_string_message)); DEBUG(D_acl) - debug_printf("Expanded av_scanner global: %s\n", av_scanner_work); + debug_printf_indent("Expanded av_scanner global: %s\n", av_scanner_work); /* disable result caching in this case */ malware_name = NULL; malware_ok = FALSE; @@ -510,7 +512,7 @@ if (!malware_ok) return m_errlog_defer(scanent, CUS callout_address, errstr); break; } - DEBUG(D_acl) debug_printf("Malware scan: %s tmo %s\n", scanner_name, readconf_printtime(timeout)); + DEBUG(D_acl) debug_printf_indent("Malware scan: %s tmo %s\n", scanner_name, readconf_printtime(timeout)); switch (scanent->scancode) { @@ -533,7 +535,7 @@ if (!malware_ok) par_count++; } scanrequest = string_sprintf("%s HTTP/1.0\r\n\r\n", scanrequest); - DEBUG(D_acl) debug_printf("Malware scan: issuing %s: %s\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s: %s\n", scanner_name, scanrequest); /* send scan request */ @@ -613,7 +615,7 @@ if (!malware_ok) drweb_slen = htonl(fsize); lseek(drweb_fd, 0, SEEK_SET); - DEBUG(D_acl) debug_printf("Malware scan: issuing %s remote scan [%s]\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s remote scan [%s]\n", scanner_name, scanner_options); /* send scan request */ @@ -628,7 +630,7 @@ if (!malware_ok) sock); } - if (!(drweb_fbuf = (uschar *) malloc (fsize_uint))) + if (!(drweb_fbuf = US malloc(fsize_uint))) { (void)close(drweb_fd); return m_errlog_defer_3(scanent, NULL, @@ -662,7 +664,7 @@ if (!malware_ok) { drweb_slen = htonl(Ustrlen(eml_filename)); - DEBUG(D_acl) debug_printf("Malware scan: issuing %s local scan [%s]\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s local scan [%s]\n", scanner_name, scanner_options); /* send scan request */ @@ -780,7 +782,7 @@ if (!malware_ok) eml_filename); /* and send it */ - DEBUG(D_acl) debug_printf("Malware scan: issuing %s %s\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s %s\n", scanner_name, buf); if (m_sock_send(sock, buf, Ustrlen(buf), &errstr) < 0) return m_errlog_defer(scanent, CUS callout_address, errstr); @@ -840,7 +842,7 @@ if (!malware_ok) malware_name = NULL; - DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan [%s]\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s scan [%s]\n", scanner_name, scanner_options); /* pass options */ memset(av_buffer, 0, sizeof(av_buffer)); @@ -936,7 +938,7 @@ if (!malware_ok) if (p) *p = '\0'; - DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan [%s]\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s scan [%s]\n", scanner_name, scanner_options); /* send scan request */ @@ -964,7 +966,7 @@ if (!malware_ok) US"reported 'kavdaemon damaged' (code 7).", sock); } - /* code 8 is not handled, since it is ambigous. It appears mostly on + /* code 8 is not handled, since it is ambiguous. It appears mostly on bounces where part of a file has been cut off */ /* "virus found" return codes (2-4) */ @@ -1001,7 +1003,9 @@ if (!malware_ok) kav_re = kav_re_inf; } - /* read report, linewise */ + /* read report, linewise. Using size from stream to read amount of data + from same stream is safe enough. */ + /* coverity[tainted_data] */ while (kav_reportlen > 0) { if ((bread = recv_line(sock, tmpbuf, sizeof(tmpbuf), tmo)) < 0) @@ -1065,7 +1069,7 @@ if (!malware_ok) /* redirect STDERR too */ commandline = string_sprintf("%s 2>&1", commandline); - DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan [%s]\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s scan [%s]\n", scanner_name, commandline); /* store exims signal handlers */ @@ -1168,7 +1172,7 @@ if (!malware_ok) if ((p = Ustrrchr(file_name, '/'))) *p = '\0'; - DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan [%s]\n", + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s scan [%s]\n", scanner_name, scanner_options); if ( write(sock, file_name, Ustrlen(file_name)) < 0 @@ -1342,7 +1346,7 @@ if (!malware_ok) int i = random_number( num_servers ); clamd_address * cd = cv[i]; - DEBUG(D_acl) debug_printf("trying server name %s, port %u\n", + DEBUG(D_acl) debug_printf_indent("trying server name %s, port %u\n", cd->hostspec, cd->tcp_port); /* Lookup the host. This is to ensure that we connect to the same IP @@ -1398,7 +1402,7 @@ if (!malware_ok) * that port on a second connection; then in the scan-method-neutral * part, read the response back on the original connection. */ - DEBUG(D_acl) debug_printf( + DEBUG(D_acl) debug_printf_indent( "Malware scan: issuing %s old-style remote scan (PORT)\n", scanner_name); @@ -1440,7 +1444,7 @@ if (!malware_ok) chunks, a 4-byte number (network order), terminated by a zero-length chunk. */ - DEBUG(D_acl) debug_printf( + DEBUG(D_acl) debug_printf_indent( "Malware scan: issuing %s new-style remote scan (zINSTREAM)\n", scanner_name); @@ -1484,7 +1488,7 @@ if (!malware_ok) } lseek(clam_fd, 0, SEEK_SET); - if (!(clamav_fbuf = (uschar *) malloc (fsize_uint))) + if (!(clamav_fbuf = US malloc(fsize_uint))) { CLOSE_SOCKDATA; (void)close(clam_fd); return m_errlog_defer_3(scanent, NULL, @@ -1551,7 +1555,7 @@ if (!malware_ok) /* Pass the string to ClamAV (7 = "SCAN \n" + \0) */ file_name = string_sprintf("SCAN %s\n", eml_filename); - DEBUG(D_acl) debug_printf( + DEBUG(D_acl) debug_printf_indent( "Malware scan: issuing %s local-path scan [%s]\n", scanner_name, scanner_options); @@ -1612,7 +1616,7 @@ if (!malware_ok) p = av_buffer + Ustrlen(av_buffer) - 1; if (*p == '\n') *p = '\0'; - DEBUG(D_acl) debug_printf("Malware response: %s\n", av_buffer); + DEBUG(D_acl) debug_printf_indent("Malware response: %s\n", av_buffer); while (isspace(*--p) && (p > av_buffer)) *p = '\0'; @@ -1649,7 +1653,7 @@ if (!malware_ok) *p = '\0'; } malware_name = string_copy(vname); - DEBUG(D_acl) debug_printf("Malware found, name \"%s\"\n", malware_name); + DEBUG(D_acl) debug_printf_indent("Malware found, name \"%s\"\n", malware_name); } else if (Ustrcmp(result_tag, "ERROR") == 0) @@ -1660,7 +1664,7 @@ if (!malware_ok) { /* Everything should be OK */ malware_name = NULL; - DEBUG(D_acl) debug_printf("Malware not found\n"); + DEBUG(D_acl) debug_printf_indent("Malware not found\n"); } else @@ -1766,7 +1770,7 @@ if (!malware_ok) malware_name = NULL; - DEBUG(D_acl) debug_printf("Malware scan: issuing %s scan\n", scanner_name); + DEBUG(D_acl) debug_printf_indent("Malware scan: issuing %s scan\n", scanner_name); if ((retval = mksd_scan_packed(scanent, sock, eml_filename, tmo)) != OK) { @@ -1808,7 +1812,7 @@ if (!malware_ok) int slen = Ustrlen(buf); if (slen >= 1) { - DEBUG(D_acl) debug_printf("got from avast: %s\n", buf); + DEBUG(D_acl) debug_printf_indent("got from avast: %s\n", buf); switch (avast_stage) { case AVA_HELO: @@ -1919,7 +1923,7 @@ if (!malware_ok) /* match virus name against pattern (caseless ------->----------v) */ if (malware_name && regex_match_and_setup(re, malware_name, 0, -1)) { - DEBUG(D_acl) debug_printf( + DEBUG(D_acl) debug_printf_indent( "Matched regex to malware [%s] [%s]\n", malware_re, malware_name); return OK; } @@ -1945,15 +1949,15 @@ Returns: Exim message processing code (OK, FAIL, DEFER, ...) int malware(const uschar * malware_re, int timeout) { - uschar * scan_filename; - int ret; +uschar * scan_filename; +int ret; - scan_filename = string_sprintf("%s/scan/%s/%s.eml", - spool_directory, message_id, message_id); - ret = malware_internal(malware_re, scan_filename, timeout, FALSE); - if (ret == DEFER) av_failed = TRUE; +scan_filename = string_sprintf("%s/scan/%s/%s.eml", + spool_directory, message_id, message_id); +ret = malware_internal(malware_re, scan_filename, timeout, FALSE); +if (ret == DEFER) av_failed = TRUE; - return ret; +return ret; } @@ -1975,32 +1979,35 @@ Returns: Exim message processing code (OK, FAIL, DEFER, ...) int malware_in_file(uschar *eml_filename) { - uschar message_id_buf[64]; - int ret; - - /* spool_mbox() assumes various parameters exist, when creating - the relevant directory and the email within */ - (void) string_format(message_id_buf, sizeof(message_id_buf), - "dummy-%d", vaguely_random_number(INT_MAX)); - message_id = message_id_buf; - sender_address = US"malware-sender@example.net"; - return_path = US""; - recipients_list = NULL; - receive_add_recipient(US"malware-victim@example.net", -1); - enable_dollar_recipients = TRUE; - - ret = malware_internal(US"*", eml_filename, 0, TRUE); - - Ustrncpy(spooled_message_id, message_id, sizeof(spooled_message_id)); - spool_mbox_ok = 1; - /* don't set no_mbox_unspool; at present, there's no way for it to become - set, but if that changes, then it should apply to these tests too */ - unspool_mbox(); - - /* silence static analysis tools */ - message_id = NULL; - - return ret; +uschar message_id_buf[64]; +int ret; + +/* spool_mbox() assumes various parameters exist, when creating +the relevant directory and the email within */ + +(void) string_format(message_id_buf, sizeof(message_id_buf), + "dummy-%d", vaguely_random_number(INT_MAX)); +message_id = message_id_buf; +sender_address = US"malware-sender@example.net"; +return_path = US""; +recipients_list = NULL; +receive_add_recipient(US"malware-victim@example.net", -1); +enable_dollar_recipients = TRUE; + +ret = malware_internal(US"*", eml_filename, 0, TRUE); + +Ustrncpy(spooled_message_id, message_id, sizeof(spooled_message_id)); +spool_mbox_ok = 1; + +/* don't set no_mbox_unspool; at present, there's no way for it to become +set, but if that changes, then it should apply to these tests too */ + +unspool_mbox(); + +/* silence static analysis tools */ +message_id = NULL; + +return ret; }