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 *);
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;
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) */
}
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)))
{
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 */
}
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 */
}
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;
}
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;
{
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;
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))
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);
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;
/* 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)))
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;
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");
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,
/* 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 */
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];
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)
}
/* copy body file */
- if (source_file_override == NULL)
+ if (!source_file_override)
{
message_subdir[1] = '\0';
for (i = 0; i < 2; i++)