X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/f870028fd26f8ac1a2fcb6e43e0d7d1c76c110ec..889894461aa958da4604299acc161c29e2aa603c:/src/src/receive.c diff --git a/src/src/receive.c b/src/src/receive.c index ce7da5719..5471aa7cb 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -490,9 +490,16 @@ if (recipients_count >= recipients_list_max) { recipient_item *oldlist = recipients_list; int oldmax = recipients_list_max; + + const int safe_recipients_limit = INT_MAX / 2 / sizeof(recipient_item); + if (recipients_list_max < 0 || recipients_list_max >= safe_recipients_limit) + { + log_write(0, LOG_MAIN|LOG_PANIC_DIE, "Too many recipients: %d", recipients_list_max); + } + recipients_list_max = recipients_list_max ? 2*recipients_list_max : 50; recipients_list = store_get(recipients_list_max * sizeof(recipient_item), FALSE); - if (oldlist != NULL) + if (oldlist) memcpy(recipients_list, oldlist, oldmax * sizeof(recipient_item)); } @@ -1516,11 +1523,10 @@ return TRUE; void received_header_gen(void) { -uschar *received; -uschar *timestamp; -header_line *received_header= header_list; +uschar * received; +uschar * timestamp = expand_string(US"${tod_full}"); +header_line * received_header= header_list; -timestamp = expand_string(US"${tod_full}"); if (recipients_count == 1) received_for = recipients_list[0].address; received = expand_string(received_header_text); received_for = NULL; @@ -1539,14 +1545,14 @@ so all we have to do is fill in the text pointer, and set the type. However, if the result of the expansion is an empty string, we leave the header marked as "old" so as to refrain from adding a Received header. */ -if (received[0] == 0) +if (!received[0]) { received_header->text = string_sprintf("Received: ; %s\n", timestamp); received_header->type = htype_old; } else { - received_header->text = string_sprintf("%s; %s\n", received, timestamp); + received_header->text = string_sprintf("%s;\n\t%s\n", received, timestamp); received_header->type = htype_received; } @@ -1657,7 +1663,6 @@ int process_info_len = Ustrlen(process_info); int error_rc = error_handling == ERRORS_SENDER ? errors_sender_rc : EXIT_FAILURE; int header_size = 256; -int start, end, domain; int id_resolution = 0; int had_zero = 0; int prevlines_length = 0; @@ -1782,15 +1787,19 @@ if (sender_host_address) dmarc_init(); /* initialize libopendmarc */ /* Remember the time of reception. Exim uses time+pid for uniqueness of message ids, and fractions of a second are required. See the comments that precede the -message id creation below. */ +message id creation below. +We use a routine that if possible uses a monotonic clock, and can be used again +after reception for the tick-wait even under the Linux non-Posix behaviour. */ exim_gettime(&message_id_tv); /* For other uses of the received time we can operate with granularity of one second, and for that we use the global variable received_time. This is for -things like ultimate message timeouts. */ +things like ultimate message timeouts. +For this we do not care about the Linux suspend/resume problem, so rather than +use exim_gettime() everywhere we use a plain gettimeofday() here. */ -received_time = message_id_tv; +gettimeofday(&received_time, NULL); /* If SMTP input, set the special handler for timeouts. The alarm() calls happen in the smtp_getc() function when it refills its buffer. */ @@ -2123,7 +2132,8 @@ OVERSIZE: if (newsender) { if (domain == 0 && newsender[0] != 0) - newsender = rewrite_address_qualify(newsender, FALSE); + /* deconst ok as newsender was not const */ + newsender = US rewrite_address_qualify(newsender, FALSE); if (filter_test != FTEST_NONE || receive_check_set_sender(newsender)) { @@ -2503,7 +2513,7 @@ if (extract_recip) { while (recipients_count-- > 0) { - uschar *s = rewrite_address(recipients_list[recipients_count].address, + const uschar * s = rewrite_address(recipients_list[recipients_count].address, TRUE, TRUE, global_rewrite_rules, rewrite_existflags); tree_add_nonrecipient(s); } @@ -2554,11 +2564,12 @@ if (extract_recip) &domain, FALSE); #ifdef SUPPORT_I18N - if (string_is_utf8(recipient)) - message_smtputf8 = TRUE; - else - allow_utf8_domains = b; + if (recipient) + if (string_is_utf8(recipient)) message_smtputf8 = TRUE; + else allow_utf8_domains = b; } +#else + ; #endif /* Keep a list of all the bad addresses so we can send a single @@ -2790,8 +2801,8 @@ recipients will get here only if the conditions were right (allow_unqualified_ recipient is TRUE). */ for (int i = 0; i < recipients_count; i++) - recipients_list[i].address = - rewrite_address(recipients_list[i].address, TRUE, TRUE, + recipients_list[i].address = /* deconst ok as src was not cont */ + US rewrite_address(recipients_list[i].address, TRUE, TRUE, global_rewrite_rules, rewrite_existflags); /* If there is no From: header, generate one for local (without @@ -2966,7 +2977,8 @@ it has already been rewritten as part of verification for SMTP input. */ if (global_rewrite_rules && !sender_address_unrewritten && *sender_address) { - sender_address = rewrite_address(sender_address, FALSE, TRUE, + /* deconst ok as src was not const */ + sender_address = US rewrite_address(sender_address, FALSE, TRUE, global_rewrite_rules, rewrite_existflags); DEBUG(D_receive|D_rewrite) debug_printf("rewritten sender = %s\n", sender_address); @@ -4071,6 +4083,8 @@ if ( LOGGING(msg_id) && msgid_header uschar * old_id; BOOL save_allow_domain_literals = allow_domain_literals; allow_domain_literals = TRUE; + int start, end, domain; + old_id = parse_extract_address(Ustrchr(msgid_header->text, ':') + 1, &errmsg, &start, &end, &domain, FALSE); allow_domain_literals = save_allow_domain_literals; @@ -4317,7 +4331,10 @@ pid can be re-used within our time interval. We can't shorten the interval without re-designing the message-id. See comments above where the message id is created. This is Something For The Future. Do this wait any time we have created a message-id, even if we rejected the -message. This gives unique IDs for logging done by ACLs. */ +message. This gives unique IDs for logging done by ACLs. +The initial timestamp must have been obtained via exim_gettime() to avoid +issues on Linux with suspend/resume. +It would be Nicer to only pause before a follow-on message. */ if (id_resolution != 0) {