From 35e0883492c90d29479a1a57786379c208538a57 Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Mon, 3 Feb 2014 00:19:23 +0000 Subject: [PATCH] Refactor listarg RE compiles --- src/src/malware.c | 151 ++++++++++++++++++++-------------------------- 1 file changed, 67 insertions(+), 84 deletions(-) diff --git a/src/src/malware.c b/src/src/malware.c index b72253e7b..ba62e103b 100644 --- a/src/src/malware.c +++ b/src/src/malware.c @@ -62,8 +62,7 @@ test_byte_order() return(byte[0] ? LITTLE_MY_ENDIAN : BIG_MY_ENDIAN); } -static uschar * malware_name_internal = NULL; -int malware_ok = 0; +BOOL malware_ok = FALSE; /* Gross hacks for the -bmalware option; perhaps we should just create the scan directory normally for that case, but look into rigging up the @@ -362,6 +361,19 @@ m_pcre_exec(const pcre * cre, uschar * text) return substr; } +static const pcre * +m_pcre_nextinlist(uschar ** list, int * sep, char * listerr, uschar ** errstr) +{ + const uschar * list_ele; + const pcre * cre = NULL; + + if (!(list_ele = string_nextinlist(list, sep, NULL, 0))) + *errstr = US listerr; + else + cre = m_pcre_compile(CS list_ele, errstr); + return cre; +} + /************************************************* * Scan content for malware * *************************************************/ @@ -416,12 +428,12 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) const uschar * scanner_options; /* make sure the eml mbox file is spooled up */ - mbox_file = spool_mbox(&mbox_size, faking ? eml_filename : NULL); - if (mbox_file == NULL) /* error while spooling */ + if (!(mbox_file = spool_mbox(&mbox_size, faking ? eml_filename : NULL))) return malware_errlog_defer("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 */ + /*XXX drweb and clamd do!! */ (void)fclose(mbox_file); /* extract the malware regex to match against from the option list */ @@ -429,17 +441,14 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* parse 1st option */ if ( (strcmpic(malware_regex,US"false") == 0) || - (Ustrcmp(malware_regex,"0") == 0) ) { - /* explicitly no matching */ - return FAIL; - } + (Ustrcmp(malware_regex,"0") == 0) ) + return FAIL; /* explicitly no matching */ /* special cases (match anything except empty) */ if ( (strcmpic(malware_regex,US"true") == 0) || (Ustrcmp(malware_regex,"*") == 0) || - (Ustrcmp(malware_regex,"1") == 0) ) { + (Ustrcmp(malware_regex,"1") == 0) ) malware_regex = malware_regex_default; - } } else /* empty means "don't match anything" */ return FAIL; @@ -453,21 +462,19 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* if av_scanner starts with a dollar, expand it first */ if (*av_scanner == '$') { - av_scanner_work = expand_string(av_scanner); - if (!av_scanner_work) + if (!(av_scanner_work = expand_string(av_scanner))) return malware_errlog_defer( string_sprintf("av_scanner starts with $, but expansion failed: %s", expand_string_message)); - else { - debug_printf("Expanded av_scanner global: %s\n", av_scanner_work); - /* disable result caching in this case */ - malware_name = NULL; - malware_ok = 0; - } + + debug_printf("Expanded av_scanner global: %s\n", av_scanner_work); + /* disable result caching in this case */ + malware_name = NULL; + malware_ok = FALSE; } /* Do not scan twice. */ - if (malware_ok == 0) { + if (!malware_ok) { /* find the scanner type from the av_scanner option */ if (!(scanner_name = string_nextinlist(&av_scanner_work, &sep, NULL, 0))) @@ -491,6 +498,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) int sock; uschar * scanrequest; uschar buf[32768], *strhelper, *strhelper2; + uschar * malware_name_internal = NULL; if ((sock = m_tcpsocket_fromdef(scanner_options, &errstr)) < 0) return fprotd_errlog_defer(errstr); @@ -512,7 +520,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* We get a lot of empty lines, so we need this hack to check for any data at all */ while( recv(sock, buf, 1, MSG_PEEK) > 0 ) { - if ( recv_line(sock, buf, 32768) > 0) { + if ( recv_line(sock, buf, sizeof(buf)) > 0) { if ( Ustrstr(buf, US"")) ) { @@ -614,8 +622,9 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) string_sprintf("unable to send file body to socket (%s)", scanner_options)); } (void)close(drweb_fd); - } - else { + + } else { + if((sock = m_unixsocket(scanner_options, &errstr)) < 0) return drweb_errlog_defer(errstr); @@ -657,8 +666,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) int i; /* setup default virus name */ - malware_name_internal = "unknown"; - malware_name = malware_name_internal; + malware_name = "unknown"; /* set up match regex */ drweb_re = m_pcre_compile( "infected\\swith\\s*(.+?)$", &errstr); @@ -690,14 +698,13 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) pcre_get_substring(CS tmpbuf, ovector, result, 1, &pre_malware_nb); - /* the first name we just copy to malware_name */ - if (i==0) - malware_name_internal = string_append(NULL, &size, &off, + if (i==0) /* the first name we just copy to malware_name */ + malware_name = string_append(NULL, &size, &off, 1, pre_malware_nb); - else - /* concatenate each new virus name to previous */ - malware_name_internal = string_append(malware_name_internal, - &size, &off, 2, "/", pre_malware_nb); + + else /* concatenate each new virus name to previous */ + malware_name = string_append(malware_name, &size, &off, + 2, "/", pre_malware_nb); pcre_free_substring(pre_malware_nb); } @@ -763,26 +770,20 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) debug_printf("aveserver: %s\n", buf); if (buf[0] == '2') break; - if (buf[0] == '5') { - /* aveserver is having problems */ - log_write(0, LOG_MAIN|LOG_PANIC, - "malware acl condition: unable to scan file %s (Responded: %s).", - eml_filename, buf); - result = DEFER; + if (buf[0] == '5') { /* aveserver is having problems */ + result = aves_errlog_defer( + string_sprintf("unable to scan file %s (Responded: %s).", + eml_filename, buf)); break; } else if (Ustrncmp(buf,"322",3) == 0) { uschar *p = Ustrchr(&buf[4],' '); *p = '\0'; - malware_name_internal = string_copy(&buf[4]); - malware_name = malware_name_internal; + malware_name = string_copy(&buf[4]); } } - /* prepare our command */ - (void)string_format(buf, sizeof(buf), "quit\r\n"); - /* and send it */ - if (m_sock_send(sock, buf, Ustrlen(buf), &errstr) < 0) + if (m_sock_send(sock, "quit\r\n", 6, &errstr) < 0) return aves_errlog_defer(errstr); /* read aveserver's greeting and see if it is ready (2xx greeting) */ @@ -952,8 +953,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) int report_flag = 0; /* setup default virus name */ - malware_name_internal = string_copy("unknown"); - malware_name = malware_name_internal; + malware_name = "unknown"; report_flag = tmpbuf[ test_byte_order() == LITTLE_MY_ENDIAN ? 1 : 0 ]; @@ -1002,9 +1002,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) case M_CMDL: /* "cmdline" scanner type ---------------------------------- */ { const uschar *cmdline_scanner = scanner_options; - uschar *cmdline_trigger; const pcre *cmdline_trigger_re; - uschar *cmdline_regex; const pcre *cmdline_regex_re; uschar * file_name; uschar * commandline; @@ -1021,19 +1019,15 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) return cmdl_errlog_defer("missing commandline specification"); /* find scanner output trigger */ - if (!(cmdline_trigger = string_nextinlist(&av_scanner_work, &sep, NULL, 0))) - return cmdl_errlog_defer("missing trigger specification"); - - /* precompile trigger regex */ - if (!(cmdline_trigger_re = m_pcre_compile(CS cmdline_trigger, &errstr))) + cmdline_trigger_re = m_pcre_nextinlist(&av_scanner_work, &sep, + "missing trigger specification", &errstr); + if (!cmdline_trigger_re) return cmdl_errlog_defer(errstr); /* find scanner name regex */ - if (!(cmdline_regex = string_nextinlist(&av_scanner_work, &sep, NULL, 0))) - return cmdl_errlog_defer("missing virus name regex specification"); - - /* precompile name regex */ - if (!(cmdline_regex_re = m_pcre_compile(CS cmdline_regex, &errstr))) + cmdline_regex_re = m_pcre_nextinlist(&av_scanner_work, &sep, + "missing virus name regex specification", &errstr); + if (!cmdline_regex_re) return cmdl_errlog_defer(errstr); /* prepare scanner call; despite the naming, file_name holds a directory @@ -1078,7 +1072,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) } /* look for trigger while recording output */ - while(fgets(CS linebuffer, sizeof(linebuffer), scanner_out) != NULL) { + while(fgets(CS linebuffer, sizeof(linebuffer), scanner_out)) { if ( Ustrlen(linebuffer) > fwrite(linebuffer, 1, Ustrlen(linebuffer), scanner_record) ) { /* short write */ pclose(scanner_out); @@ -1104,7 +1098,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* re-open the scanner output file, look for name match */ scanner_record = fopen(CS file_name, "rb"); - while(fgets(CS linebuffer,32767,scanner_record) != NULL) { + while(fgets(CS linebuffer, sizeof(linebuffer), scanner_record)) { /* try match */ if ((s = m_pcre_exec(cmdline_regex_re, linebuffer))) malware_name = s; @@ -1156,9 +1150,10 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) /* infected ? */ if (av_buffer[0] == '1') { - if (Ustrchr(av_buffer, '\n')) *Ustrchr(av_buffer, '\n') = '\0'; - malware_name_internal = string_copy(&av_buffer[2]); - malware_name = malware_name_internal; + uschar * s = Ustrchr(av_buffer, '\n'); + if (s) + *s = '\0'; + malware_name = string_copy(&av_buffer[2]); } else if (!strncmp(CS av_buffer, "-1", 2)) return soph_errlog_defer("scanner reported error"); @@ -1563,8 +1558,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) if (p) *p = '\0'; } - malware_name_internal = string_copy(vname); - malware_name = malware_name_internal; + malware_name = string_copy(vname); DEBUG(D_acl) debug_printf("Malware found, name \"%s\"\n", malware_name); } else if (Ustrcmp(result_tag, "ERROR") == 0) @@ -1594,9 +1588,7 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) uschar * linebuffer; uschar *sockline_scanner; uschar sockline_scanner_default[] = "%s\n"; - uschar *sockline_trigger; const pcre *sockline_trig_re; - uschar *sockline_regex; const pcre *sockline_name_re; /* find scanner command line */ @@ -1605,21 +1597,15 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) sockline_scanner = sockline_scanner_default; /* find scanner output trigger */ - if (!(sockline_trigger = string_nextinlist(&av_scanner_work, &sep, - NULL, 0))) - return sock_errlog_defer("missing trigger specification"); - - /* precompile trigger regex */ - if (!(sockline_trig_re = m_pcre_compile(CS sockline_trigger, &errstr))) + sockline_trig_re = m_pcre_nextinlist(&av_scanner_work, &sep, + "missing trigger specification", &errstr); + if (!sockline_trig_re) return sock_errlog_defer(errstr); /* find virus name regex */ - if (!(sockline_regex = string_nextinlist(&av_scanner_work, &sep, - NULL, 0))) - return sock_errlog_defer("missing virus name regex specification"); - - /* precompile name regex */ - if (!(sockline_name_re = m_pcre_compile(CS sockline_regex, &errstr))) + sockline_name_re = m_pcre_nextinlist(&av_scanner_work, &sep, + "missing virus name regex specification", &errstr); + if (!sockline_name_re) return sock_errlog_defer(errstr); /* prepare scanner call */ @@ -1696,13 +1682,11 @@ malware_internal(uschar **listptr, uschar *eml_filename, BOOL faking) } } - /* set "been here, done that" marker */ - malware_ok = 1; + malware_ok = TRUE; /* set "been here, done that" marker */ } /* match virus name against pattern (caseless ------->----------v) */ - if ( (malware_name != NULL) && - (regex_match_and_setup(re, malware_name, 0, -1)) ) { + if ( malware_name && (regex_match_and_setup(re, malware_name, 0, -1)) ) { DEBUG(D_acl) debug_printf("Matched regex to malware [%s] [%s]\n", malware_regex, malware_name); return OK; } @@ -1810,8 +1794,7 @@ mksd_parse_line (char *line) if (((p-line) > 5) && (line[3] == ' ')) if (((p = strchr (line+4, ' ')) != NULL) && ((p-line) > 4)) { *p = '\0'; - malware_name_internal = string_copy(line+4); - malware_name = malware_name_internal; + malware_name = string_copy(line+4); return OK; } } -- 2.30.2