From 040721f2bc088d5e717c0475975ed6158352dce6 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 17 Apr 2017 20:43:23 +0100 Subject: [PATCH 1/1] Reduce number of places knowing about filename-construction for mbox file-for-scanning --- src/src/functions.h | 2 +- src/src/malware.c | 47 ++++++++++++++++++++------------------------ src/src/mime.c | 11 ++++------- src/src/receive.c | 35 +++++++++++++-------------------- src/src/regex.c | 2 +- src/src/spam.c | 7 ++----- src/src/spool_mbox.c | 23 +++++++++++++++------- 7 files changed, 59 insertions(+), 68 deletions(-) diff --git a/src/src/functions.h b/src/src/functions.h index a10b743c9..ec4aba6ec 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -420,7 +420,7 @@ extern BOOL smtp_verify_helo(void); extern int smtp_write_command(smtp_outblock *, BOOL, const char *, ...) PRINTF_FUNCTION(3,4); #ifdef WITH_CONTENT_SCAN extern int spam(const uschar **); -extern FILE *spool_mbox(unsigned long *, const uschar *); +extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **); #endif extern BOOL spool_move_message(uschar *, uschar *, uschar *, uschar *); extern uschar *spool_dname(const uschar *, uschar *); diff --git a/src/src/malware.c b/src/src/malware.c index f9c4c414f..e995f47b4 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -413,16 +413,16 @@ is via malware(), or there's malware_in_file() used for testing/debugging. Arguments: malware_re match condition for "malware=" - eml_filename the file holding the email to be scanned + scan_filename the file holding the email to be scanned, if we're faking + this up for the -bmalware test, else NULL timeout if nonzero, non-default timeoutl - faking whether or not we're faking this up for the -bmalware test Returns: Exim message processing code (OK, FAIL, DEFER, ...) where true means malware was found (condition applies) */ static int -malware_internal(const uschar * malware_re, const uschar * eml_filename, - int timeout, BOOL faking) +malware_internal(const uschar * malware_re, const uschar * scan_filename, + int timeout) { int sep = 0; const uschar *av_scanner_work = av_scanner; @@ -435,21 +435,24 @@ struct scan * scanent; const uschar * scanner_options; int sock = -1; time_t tmo; +uschar * eml_filename, * eml_dir; -/* make sure the eml mbox file is spooled up */ -if (!(mbox_file = spool_mbox(&mbox_size, faking ? eml_filename : NULL))) +if (!malware_re) + return FAIL; /* empty means "don't match anything" */ + +/* Ensure the eml mbox file is spooled up */ + +if (!(mbox_file = spool_mbox(&mbox_size, scan_filename, &eml_filename))) return malware_errlog_defer(US"error while creating mbox spool file"); -/* none of our current scanners need the mbox - file as a stream, so we can close it right away */ -(void)fclose(mbox_file); +/* None of our current scanners need the mbox file as a stream (they use +the name), so we can close it right away. Get the directory too. */ -if (!malware_re) - return FAIL; /* empty means "don't match anything" */ +(void) fclose(mbox_file); +eml_dir = string_copyn(eml_filename, Ustrrchr(eml_filename, '/') - eml_filename); /* parse 1st option */ - if ( (strcmpic(malware_re, US"false") == 0) || - (Ustrcmp(malware_re,"0") == 0) ) +if (strcmpic(malware_re, US"false") == 0 || Ustrcmp(malware_re,"0") == 0) return FAIL; /* explicitly no matching */ /* special cases (match anything except empty) */ @@ -1091,8 +1094,7 @@ if (!malware_ok) } scanner_fd = fileno(scanner_out); - file_name = string_sprintf("%s/scan/%s/%s_scanner_output", - spool_directory, message_id, message_id); + file_name = string_sprintf("%s/%s_scanner_output", eml_dir, message_id); if (!(scanner_record = modefopen(file_name, "wb", SPOOL_MODE))) { @@ -1720,8 +1722,7 @@ if (!malware_ok) return m_errlog_defer_3(scanent, NULL, errstr, sock); /* prepare scanner call - security depends on expansions check above */ - commandline = string_sprintf("%s/scan/%s/%s.eml", spool_directory, message_id, message_id); - commandline = string_sprintf( CS sockline_scanner, CS commandline); + commandline = string_sprintf( CS sockline_scanner, CS eml_filename); /* Pass the command string to the socket */ @@ -1844,8 +1845,7 @@ if (!malware_ok) } else { - scanrequest = string_sprintf("SCAN %s/scan/%s\n", - spool_directory, message_id); + scanrequest = string_sprintf("SCAN %s\n", eml_dir); avast_stage = AVA_RSP; /* just sent command */ } @@ -2000,14 +2000,9 @@ Returns: Exim message processing code (OK, FAIL, DEFER, ...) int malware(const uschar * malware_re, int timeout) { -uschar * scan_filename; -int ret; +int ret = malware_internal(malware_re, NULL, timeout); -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; } @@ -2045,7 +2040,7 @@ recipients_list = NULL; receive_add_recipient(US"malware-victim@example.net", -1); enable_dollar_recipients = TRUE; -ret = malware_internal(US"*", eml_filename, 0, TRUE); +ret = malware_internal(US"*", eml_filename, 0); Ustrncpy(spooled_message_id, message_id, sizeof(spooled_message_id)); spool_mbox_ok = 1; diff --git a/src/src/mime.c b/src/src/mime.c index 3a30e6e4c..80e820b2b 100644 --- a/src/src/mime.c +++ b/src/src/mime.c @@ -217,9 +217,8 @@ mime_decode(const uschar **listptr) { int sep = 0; const uschar *list = *listptr; -uschar *option; -uschar option_buffer[1024]; -uschar decode_path[1024]; +uschar * option; +uschar * decode_path; FILE *decode_file = NULL; long f_pos = 0; ssize_t size_counter = 0; @@ -229,12 +228,10 @@ if (!mime_stream || (f_pos = ftell(mime_stream)) < 0) return FAIL; /* build default decode path (will exist since MBOX must be spooled up) */ -(void)string_format(decode_path,1024,"%s/scan/%s",spool_directory,message_id); +decode_path = string_sprintf("%s/scan/%s", spool_directory, message_id); /* try to find 1st option */ -if ((option = string_nextinlist(&list, &sep, - option_buffer, - sizeof(option_buffer))) != NULL) +if ((option = string_nextinlist(&list, &sep, NULL, 0))) { /* parse 1st option */ if ((Ustrcmp(option,"false") == 0) || (Ustrcmp(option,"0") == 0)) diff --git a/src/src/receive.c b/src/src/receive.c index 64a8d511c..731c76d77 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -1306,36 +1306,30 @@ unsigned long mbox_size; header_line *my_headerlist; uschar *user_msg, *log_msg; int mime_part_count_buffer = -1; +uschar * mbox_filename; int rc = OK; memset(CS rfc822_file_path,0,2048); /* check if it is a MIME message */ -my_headerlist = header_list; -while (my_headerlist != NULL) - { - /* skip deleted headers */ - if (my_headerlist->type == '*') - { - my_headerlist = my_headerlist->next; - continue; - } - if (strncmpic(my_headerlist->text, US"Content-Type:", 13) == 0) + +for (my_headerlist = header_list; my_headerlist; my_headerlist = my_headerlist->next) + if ( my_headerlist->type != '*' /* skip deleted headers */ + && strncmpic(my_headerlist->text, US"Content-Type:", 13) == 0 + ) { DEBUG(D_receive) debug_printf("Found Content-Type: header - executing acl_smtp_mime.\n"); goto DO_MIME_ACL; } - my_headerlist = my_headerlist->next; - } DEBUG(D_receive) debug_printf("No Content-Type: header - presumably not a MIME message.\n"); return TRUE; DO_MIME_ACL: + /* make sure the eml mbox file is spooled up */ -mbox_file = spool_mbox(&mbox_size, NULL); -if (mbox_file == NULL) { - /* error while spooling */ +if (!(mbox_file = spool_mbox(&mbox_size, NULL, &mbox_filename))) + { /* error while spooling */ log_write(0, LOG_MAIN|LOG_PANIC, "acl_smtp_mime: error while creating mbox spool file, message temporarily rejected."); Uunlink(spool_name); @@ -1347,7 +1341,7 @@ if (mbox_file == NULL) { message_id[0] = 0; /* Indicate no message accepted */ *smtp_reply_ptr = US""; /* Indicate reply already sent */ return FALSE; /* Indicate skip to end of receive function */ -}; + } mime_is_rfc822 = 0; @@ -1371,14 +1365,13 @@ if (Ustrlen(rfc822_file_path) > 0) /* check if we must check any message/rfc822 attachments */ if (rc == OK) { - uschar temp_path[1024]; + uschar * scandir; struct dirent * entry; DIR * tempdir; - (void) string_format(temp_path, sizeof(temp_path), "%s/scan/%s", - spool_directory, message_id); + scandir = string_copyn(mbox_filename, Ustrrchr(mbox_filename, '/') - mbox_filename); - tempdir = opendir(CS temp_path); + tempdir = opendir(CS scandir); for (;;) { if (!(entry = readdir(tempdir))) @@ -1386,7 +1379,7 @@ if (rc == OK) if (strncmpic(US entry->d_name, US"__rfc822_", 9) == 0) { (void) string_format(rfc822_file_path, sizeof(rfc822_file_path), - "%s/scan/%s/%s", spool_directory, message_id, entry->d_name); + "%s/%s", scandir, entry->d_name); DEBUG(D_receive) debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n", rfc822_file_path); break; diff --git a/src/src/regex.c b/src/src/regex.c index 9274f9095..3560bef52 100644 --- a/src/src/regex.c +++ b/src/src/regex.c @@ -105,7 +105,7 @@ regex_match_string = NULL; if (!mime_stream) /* We are in the DATA ACL */ { - if (!(mbox_file = spool_mbox(&mbox_size, NULL))) + if (!(mbox_file = spool_mbox(&mbox_size, NULL, NULL))) { /* error while spooling */ log_write(0, LOG_MAIN|LOG_PANIC, "regex acl condition: error while creating mbox spool file"); diff --git a/src/src/spam.c b/src/src/spam.c index d4b95b2f9..477ab62b4 100644 --- a/src/src/spam.c +++ b/src/src/spam.c @@ -265,9 +265,7 @@ if (spam_ok && Ustrcmp(prev_user_name, user_name) == 0) return override ? OK : spam_rc; /* make sure the eml mbox file is spooled up */ -mbox_file = spool_mbox(&mbox_size, NULL); - -if (mbox_file == NULL) +if (!(mbox_file = spool_mbox(&mbox_size, NULL, NULL))) { /* error while spooling */ log_write(0, LOG_MAIN|LOG_PANIC, @@ -287,8 +285,7 @@ start = time(NULL); /* Check how many spamd servers we have and register their addresses */ sep = 0; /* default colon-sep */ - while ((address = string_nextinlist(&spamd_address_list_ptr, &sep, - NULL, 0)) != NULL) + while ((address = string_nextinlist(&spamd_address_list_ptr, &sep, NULL, 0))) { const uschar * sublist; int sublist_sep = -(int)' '; /* default space-sep */ diff --git a/src/src/spool_mbox.c b/src/src/spool_mbox.c index b1de39e7d..89bdb7ddc 100644 --- a/src/src/spool_mbox.c +++ b/src/src/spool_mbox.c @@ -19,11 +19,17 @@ extern int spam_ok; int spool_mbox_ok = 0; uschar spooled_message_id[MESSAGE_ID_LENGTH+1]; -/* returns a pointer to the FILE, and puts the size in bytes into mbox_file_size - * normally, source_file_override is NULL */ +/* +Create an MBOX-style message file from the spooled files. + +Returns a pointer to the FILE, and puts the size in bytes into mbox_file_size. +If mbox_fname is non-null, fill in a pointer to the name. +Normally, source_file_override is NULL +*/ FILE * -spool_mbox(unsigned long *mbox_file_size, const uschar *source_file_override) +spool_mbox(unsigned long *mbox_file_size, const uschar *source_file_override, + uschar ** mbox_fname) { uschar message_subdir[2]; uschar buffer[16384]; @@ -35,10 +41,13 @@ FILE *yield = NULL; header_line *my_headerlist; struct stat statbuf; int i, j; -void *reset_point = store_get(0); +void *reset_point; + +mbox_path = string_sprintf("%s/scan/%s/%s.eml", + spool_directory, message_id, message_id); +if (mbox_fname) *mbox_fname = mbox_path; -mbox_path = string_sprintf("%s/scan/%s/%s.eml", spool_directory, message_id, - message_id); +reset_point = store_get(0); /* Skip creation if already spooled out as mbox file */ if (!spool_mbox_ok) @@ -108,7 +117,7 @@ if (!spool_mbox_ok) } /* copy body file */ - if (source_file_override == NULL) + if (!source_file_override) { message_subdir[1] = '\0'; for (i = 0; i < 2; i++) -- 2.30.2