X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/459fca581ce9f1215a96885852b912558cdc9c63..306c6c7751cf6953dc544a607b584a9ca58623ad:/src/src/receive.c diff --git a/src/src/receive.c b/src/src/receive.c index 93c091c80..8c7e2b525 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -1023,7 +1023,8 @@ int ch; /* Remember that this message uses wireformat. */ -DEBUG(D_receive) debug_printf("CHUNKING: writing spoolfile in wire format\n"); +DEBUG(D_receive) debug_printf("CHUNKING: %s\n", + fout ? "writing spoolfile in wire format" : "flushing input"); spool_file_wireformat = TRUE; for (;;) @@ -1077,9 +1078,10 @@ Returns: nothing void receive_swallow_smtp(void) { -/*XXX CHUNKING: not enough. read chunks until RSET? */ if (message_ended >= END_NOTENDED) - message_ended = read_message_data_smtp(NULL); + message_ended = chunking_state <= CHUNKING_OFFERED + ? read_message_data_smtp(NULL) + : read_message_bdat_smtp_wire(NULL); } @@ -1346,7 +1348,7 @@ run_mime_acl(uschar *acl, BOOL *smtp_yield_ptr, uschar **smtp_reply_ptr, uschar **blackholed_by_ptr) { FILE *mbox_file; -uschar rfc822_file_path[2048]; +uschar * rfc822_file_path = NULL; unsigned long mbox_size; header_line *my_headerlist; uschar *user_msg, *log_msg; @@ -1354,8 +1356,6 @@ 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 */ for (my_headerlist = header_list; my_headerlist; my_headerlist = my_headerlist->next) @@ -1395,7 +1395,7 @@ mime_part_count = -1; rc = mime_acl_check(acl, mbox_file, NULL, &user_msg, &log_msg); (void)fclose(mbox_file); -if (Ustrlen(rfc822_file_path) > 0) +if (rfc822_file_path) { mime_part_count = mime_part_count_buffer; @@ -1403,36 +1403,31 @@ if (Ustrlen(rfc822_file_path) > 0) { log_write(0, LOG_PANIC, "acl_smtp_mime: can't unlink RFC822 spool file, skipping."); - goto END_MIME_ACL; + goto END_MIME_ACL; } + rfc822_file_path = NULL; } /* check if we must check any message/rfc822 attachments */ if (rc == OK) { - uschar * scandir; + uschar * scandir = string_copyn(mbox_filename, + Ustrrchr(mbox_filename, '/') - mbox_filename); struct dirent * entry; DIR * tempdir; - scandir = string_copyn(mbox_filename, Ustrrchr(mbox_filename, '/') - mbox_filename); - - tempdir = opendir(CS scandir); - for (;;) - { - if (!(entry = readdir(tempdir))) - break; + for (tempdir = opendir(CS scandir); entry = readdir(tempdir); ) if (strncmpic(US entry->d_name, US"__rfc822_", 9) == 0) { - (void) string_format(rfc822_file_path, sizeof(rfc822_file_path), - "%s/%s", scandir, entry->d_name); - DEBUG(D_receive) debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n", - rfc822_file_path); + rfc822_file_path = string_sprintf("%s/%s", scandir, entry->d_name); + DEBUG(D_receive) + debug_printf("RFC822 attachment detected: running MIME ACL for '%s'\n", + rfc822_file_path); break; } - } closedir(tempdir); - if (entry) + if (rfc822_file_path) { if ((mbox_file = Ufopen(rfc822_file_path, "rb"))) { @@ -1461,10 +1456,10 @@ else if (rc != OK) #ifdef EXPERIMENTAL_DCC dcc_ok = 0; #endif - if ( smtp_input - && smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0) + if (smtp_input) { - *smtp_yield_ptr = FALSE; /* No more messages after dropped connection */ + if (smtp_handle_acl_fail(ACL_WHERE_MIME, rc, user_msg, log_msg) != 0) + *smtp_yield_ptr = FALSE; /* No more messages after dropped connection */ *smtp_reply_ptr = US""; /* Indicate reply already sent */ } message_id[0] = 0; /* Indicate no message accepted */ @@ -1747,7 +1742,7 @@ message id creation below. */ /* 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.XXX */ +things like ultimate message timeouts. */ received_time = message_id_tv; @@ -1859,7 +1854,7 @@ for (;;) prevent further reading), and break out of the loop, having freed the empty header, and set next = NULL to indicate no data line. */ - if (ptr == 0 && ch == '.' && (smtp_input || dot_ends)) + if (ptr == 0 && ch == '.' && dot_ends) { ch = (receive_getc)(GETC_BUFFER_UNLIMITED); if (ch == '\r') @@ -2046,32 +2041,30 @@ for (;;) these lines in SMTP messages. There is now an option to ignore them from specified hosts or networks. Sigh. */ - if (header_last == header_list && - (!smtp_input - || - (sender_host_address != NULL && - verify_check_host(&ignore_fromline_hosts) == OK) - || - (sender_host_address == NULL && ignore_fromline_local) - ) && - regex_match_and_setup(regex_From, next->text, 0, -1)) + if ( header_last == header_list + && ( !smtp_input + || ( sender_host_address + && verify_check_host(&ignore_fromline_hosts) == OK + ) + || (!sender_host_address && ignore_fromline_local) + ) + && regex_match_and_setup(regex_From, next->text, 0, -1) + ) { if (!sender_address_forced) { uschar *uucp_sender = expand_string(uucp_from_sender); - if (uucp_sender == NULL) - { + if (!uucp_sender) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of \"%s\" failed after matching " "\"From \" line: %s", uucp_from_sender, expand_string_message); - } else { int start, end, domain; uschar *errmess; uschar *newsender = parse_extract_address(uucp_sender, &errmess, &start, &end, &domain, TRUE); - if (newsender != NULL) + if (newsender) { if (domain == 0 && newsender[0] != 0) newsender = rewrite_address_qualify(newsender, FALSE); @@ -2166,13 +2159,11 @@ for (;;) } else - { give_local_error(ERRMESS_VLONGHDRLINE, string_sprintf("message header line longer than %d characters " "received: message not accepted", header_line_maxsize), US"", error_rc, stdin, header_list->next); /* Does not return */ - } } /* Note if any resent- fields exist. */ @@ -2628,7 +2619,7 @@ checked when it was read, to ensure it isn't too big. The timing granularity is left in id_resolution so that an appropriate wait can be done after receiving the message, if necessary (we hope it won't be). */ -if (host_number_string != NULL) +if (host_number_string) { id_resolution = (BASE_62 == 62)? 5000 : 10000; sprintf(CS(message_id + MESSAGE_ID_LENGTH - 3), "-%2s", @@ -2664,9 +2655,8 @@ one, but only for local (without suppress_local_fixups) or submission mode messages. This can be user-configured if required, but we had better flatten any illegal characters therein. */ -if (msgid_header == NULL && - ((sender_host_address == NULL && !suppress_local_fixups) - || submission_mode)) +if ( !msgid_header + && ((!sender_host_address && !suppress_local_fixups) || submission_mode)) { uschar *p; uschar *id_text = US""; @@ -2674,20 +2664,20 @@ if (msgid_header == NULL && /* Permit only letters, digits, dots, and hyphens in the domain */ - if (message_id_domain != NULL) + if (message_id_domain) { uschar *new_id_domain = expand_string(message_id_domain); - if (new_id_domain == NULL) + if (!new_id_domain) { if (!expand_string_forcedfail) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of \"%s\" (message_id_header_domain) " "failed: %s", message_id_domain, expand_string_message); } - else if (*new_id_domain != 0) + else if (*new_id_domain) { id_domain = new_id_domain; - for (p = id_domain; *p != 0; p++) + for (p = id_domain; *p; p++) if (!isalnum(*p) && *p != '.') *p = '-'; /* No need to test '-' ! */ } } @@ -2695,21 +2685,20 @@ if (msgid_header == NULL && /* Permit all characters except controls and RFC 2822 specials in the additional text part. */ - if (message_id_text != NULL) + if (message_id_text) { uschar *new_id_text = expand_string(message_id_text); - if (new_id_text == NULL) + if (!new_id_text) { if (!expand_string_forcedfail) log_write(0, LOG_MAIN|LOG_PANIC, "expansion of \"%s\" (message_id_header_text) " "failed: %s", message_id_text, expand_string_message); } - else if (*new_id_text != 0) + else if (*new_id_text) { id_text = new_id_text; - for (p = id_text; *p != 0; p++) - if (mac_iscntrl_or_special(*p)) *p = '-'; + for (p = id_text; *p; p++) if (mac_iscntrl_or_special(*p)) *p = '-'; } } @@ -2752,9 +2741,8 @@ possible addition of a Sender: header, because untrusted_set_sender allows an untrusted user to set anything in the envelope (which might then get info From:) but we still want to ensure a valid Sender: if it is required. */ -if (from_header == NULL && - ((sender_host_address == NULL && !suppress_local_fixups) - || submission_mode)) +if ( !from_header + && ((!sender_host_address && !suppress_local_fixups) || submission_mode)) { uschar *oname = US""; @@ -2763,7 +2751,7 @@ if (from_header == NULL && force its value or if we have a non-SMTP message for which -f was not used to set the sender. */ - if (sender_host_address == NULL) + if (!sender_host_address) { if (!trusted_caller || sender_name_forced || (!smtp_input && !sender_address_forced)) @@ -2773,46 +2761,38 @@ if (from_header == NULL && /* For non-locally submitted messages, the only time we use the originator name is when it was forced by the /name= option on control=submission. */ - else - { - if (submission_name != NULL) oname = submission_name; - } + else if (submission_name) oname = submission_name; /* Envelope sender is empty */ - if (sender_address[0] == 0) + if (!*sender_address) { uschar *fromstart, *fromend; - fromstart = string_sprintf("%sFrom: %s%s", resent_prefix, - oname, (oname[0] == 0)? "" : " <"); - fromend = (oname[0] == 0)? US"" : US">"; + fromstart = string_sprintf("%sFrom: %s%s", + resent_prefix, oname, *oname ? " <" : ""); + fromend = *oname ? US">" : US""; if (sender_local || local_error_message) - { header_add(htype_from, "%s%s@%s%s\n", fromstart, local_part_quote(originator_login), qualify_domain_sender, fromend); - } - else if (submission_mode && authenticated_id != NULL) + + else if (submission_mode && authenticated_id) { - if (submission_domain == NULL) - { + if (!submission_domain) header_add(htype_from, "%s%s@%s%s\n", fromstart, local_part_quote(authenticated_id), qualify_domain_sender, fromend); - } - else if (submission_domain[0] == 0) /* empty => whole address set */ - { + + else if (!*submission_domain) /* empty => whole address set */ header_add(htype_from, "%s%s%s\n", fromstart, authenticated_id, fromend); - } + else - { header_add(htype_from, "%s%s@%s%s\n", fromstart, - local_part_quote(authenticated_id), submission_domain, - fromend); - } + local_part_quote(authenticated_id), submission_domain, fromend); + from_header = header_last; /* To get it checked for Sender: */ } } @@ -2825,10 +2805,9 @@ if (from_header == NULL && { header_add(htype_from, "%sFrom: %s%s%s%s\n", resent_prefix, oname, - (oname[0] == 0)? "" : " <", - (sender_address_unrewritten == NULL)? - sender_address : sender_address_unrewritten, - (oname[0] == 0)? "" : ">"); + *oname ? " <" : "", + sender_address_unrewritten ? sender_address_unrewritten : sender_address, + *oname ? ">" : ""); from_header = header_last; /* To get it checked for Sender: */ } @@ -2845,11 +2824,11 @@ trusted callers to forge From: without supplying -f, we have to test explicitly here. If the From: header contains more than one address, then the call to parse_extract_address fails, and a Sender: header is inserted, as required. */ -if (from_header != NULL && - (active_local_from_check && - ((sender_local && !trusted_caller && !suppress_local_fixups) || - (submission_mode && authenticated_id != NULL)) - )) +if ( from_header + && ( active_local_from_check + && ( sender_local && !trusted_caller && !suppress_local_fixups + || submission_mode && authenticated_id + ) ) ) { BOOL make_sender = TRUE; int start, end, domain; @@ -2859,37 +2838,26 @@ if (from_header != NULL && &start, &end, &domain, FALSE); uschar *generated_sender_address; - if (submission_mode) - { - if (submission_domain == NULL) - { - generated_sender_address = string_sprintf("%s@%s", - local_part_quote(authenticated_id), qualify_domain_sender); - } - else if (submission_domain[0] == 0) /* empty => full address */ - { - generated_sender_address = string_sprintf("%s", - authenticated_id); - } - else - { - generated_sender_address = string_sprintf("%s@%s", - local_part_quote(authenticated_id), submission_domain); - } - } - else - generated_sender_address = string_sprintf("%s@%s", - local_part_quote(originator_login), qualify_domain_sender); + generated_sender_address = submission_mode + ? !submission_domain + ? string_sprintf("%s@%s", + local_part_quote(authenticated_id), qualify_domain_sender) + : !*submission_domain /* empty => full address */ + ? string_sprintf("%s", authenticated_id) + : string_sprintf("%s@%s", + local_part_quote(authenticated_id), submission_domain) + : string_sprintf("%s@%s", + local_part_quote(originator_login), qualify_domain_sender); /* Remove permitted prefixes and suffixes from the local part of the From: address before doing the comparison with the generated sender. */ - if (from_address != NULL) + if (from_address) { int slen; - uschar *at = (domain == 0)? NULL : from_address + domain - 1; + uschar *at = domain ? from_address + domain - 1 : NULL; - if (at != NULL) *at = 0; + if (at) *at = 0; from_address += route_check_prefix(from_address, local_from_prefix); slen = route_check_suffix(from_address, local_from_suffix); if (slen > 0) @@ -2897,10 +2865,10 @@ if (from_header != NULL && memmove(from_address+slen, from_address, Ustrlen(from_address)-slen); from_address += slen; } - if (at != NULL) *at = '@'; + if (at) *at = '@'; - if (strcmpic(generated_sender_address, from_address) == 0 || - (domain == 0 && strcmpic(from_address, originator_login) == 0)) + if ( strcmpic(generated_sender_address, from_address) == 0 + || (!domain && strcmpic(from_address, originator_login) == 0)) make_sender = FALSE; } @@ -2908,8 +2876,7 @@ if (from_header != NULL && appropriate rewriting rules. */ if (make_sender) - { - if (submission_mode && submission_name == NULL) + if (submission_mode && !submission_name) header_add(htype_sender, "%sSender: %s\n", resent_prefix, generated_sender_address); else @@ -2917,14 +2884,13 @@ if (from_header != NULL && resent_prefix, submission_mode? submission_name : originator_name, generated_sender_address); - } /* Ensure that a non-null envelope sender address corresponds to the submission mode sender address. */ - if (submission_mode && sender_address[0] != 0) + if (submission_mode && *sender_address) { - if (sender_address_unrewritten == NULL) + if (!sender_address_unrewritten) sender_address_unrewritten = sender_address; sender_address = generated_sender_address; if (Ustrcmp(sender_address_unrewritten, generated_sender_address) != 0) @@ -2937,8 +2903,7 @@ if (from_header != NULL && /* If there are any rewriting rules, apply them to the sender address, unless it has already been rewritten as part of verification for SMTP input. */ -if (global_rewrite_rules != NULL && sender_address_unrewritten == NULL && - sender_address[0] != 0) +if (global_rewrite_rules && !sender_address_unrewritten && *sender_address) { sender_address = rewrite_address(sender_address, FALSE, TRUE, global_rewrite_rules, rewrite_existflags); @@ -2987,9 +2952,8 @@ to be more confusing if Exim adds one to all remotely-originated messages. As per Message-Id, we prepend if resending, else append. */ -if (!date_header_exists && - ((sender_host_address == NULL && !suppress_local_fixups) - || submission_mode)) +if ( !date_header_exists + && ((!sender_host_address && !suppress_local_fixups) || submission_mode)) header_add_at_position(!resents_exist, NULL, FALSE, htype_other, "%sDate: %s\n", resent_prefix, tod_stamp(tod_full)); @@ -3001,7 +2965,7 @@ new Received:) has not yet been set. */ DEBUG(D_receive) { debug_printf(">>Headers after rewriting and local additions:\n"); - for (h = header_list->next; h != NULL; h = h->next) + for (h = header_list->next; h; h = h->next) debug_printf("%c %s", h->type, h->text); debug_printf("\n"); } @@ -3103,7 +3067,7 @@ format); write it (remembering that it might contain binary zeros). The result of fwrite() isn't inspected; instead we call ferror() below. */ fprintf(data_file, "%s-D\n", message_id); -if (next != NULL) +if (next) { uschar *s = next->text; int len = next->slen; @@ -3158,10 +3122,10 @@ if (!ferror(data_file) && !(receive_feof)() && message_ended != END_DOT) log_write(L_size_reject, LOG_MAIN|LOG_REJECT, "rejected from <%s>%s%s%s%s: " "message too big: read=%d max=%d", sender_address, - (sender_fullhost == NULL)? "" : " H=", - (sender_fullhost == NULL)? US"" : sender_fullhost, - (sender_ident == NULL)? "" : " U=", - (sender_ident == NULL)? US"" : sender_ident, + sender_fullhost ? " H=" : "", + sender_fullhost ? sender_fullhost : US"", + sender_ident ? " U=" : "", + sender_ident ? sender_ident : US"", message_size, thismessage_size_limit); @@ -3214,7 +3178,7 @@ if (fflush(data_file) == EOF || ferror(data_file) || uschar *msg = string_sprintf("%s error (%s) while receiving message from %s", input_error? "Input read" : "Spool write", msg_errno, - (sender_fullhost != NULL)? sender_fullhost : sender_ident); + sender_fullhost ? sender_fullhost : sender_ident); log_write(0, LOG_MAIN, "Message abandoned: %s", msg); Uunlink(spool_name); /* Lose the data file */ @@ -3246,6 +3210,7 @@ if (fflush(data_file) == EOF || ferror(data_file) || /* No I/O errors were encountered while writing the data file. */ DEBUG(D_receive) debug_printf("Data file written for message %s\n", message_id); +if (LOGGING(receive_time)) timesince(&received_time_taken, &received_time); /* If there were any bad addresses extracted by -t, or there were no recipients @@ -3259,12 +3224,12 @@ recipients or stderr error writing, throw the data file away afterwards, and exit. (This can't be SMTP, which always ensures there's at least one syntactically good recipient address.) */ -if (extract_recip && (bad_addresses != NULL || recipients_count == 0)) +if (extract_recip && (bad_addresses || recipients_count == 0)) { DEBUG(D_receive) { if (recipients_count == 0) debug_printf("*** No recipients\n"); - if (bad_addresses != NULL) + if (bad_addresses) { error_block *eblock = bad_addresses; debug_printf("*** Bad address(es)\n"); @@ -3295,7 +3260,7 @@ if (extract_recip && (bad_addresses != NULL || recipients_count == 0)) } else { - if (bad_addresses == NULL) + if (!bad_addresses) { if (extracted_ignored) fprintf(stderr, "exim: all -t recipients overridden by command line\n"); @@ -3340,7 +3305,7 @@ Note: the checking for too many Received: headers is handled by the delivery code. */ /*XXX eventually add excess Received: check for cutthrough case back when classifying them */ -if (received_header->text == NULL) /* Non-cutthrough case */ +if (!received_header->text) /* Non-cutthrough case */ { received_header_gen(); @@ -3437,7 +3402,7 @@ else continue; } - seen_items = string_catn(seen_items, ":", 1); + seen_items = string_catn(seen_items, US":", 1); } seen_items = string_cat(seen_items, item); @@ -3477,9 +3442,10 @@ else #endif /* DISABLE_DKIM */ #ifdef WITH_CONTENT_SCAN - if (recipients_count > 0 && - acl_smtp_mime != NULL && - !run_mime_acl(acl_smtp_mime, &smtp_yield, &smtp_reply, &blackholed_by)) + if ( recipients_count > 0 + && acl_smtp_mime + && !run_mime_acl(acl_smtp_mime, &smtp_yield, &smtp_reply, &blackholed_by) + ) goto TIDYUP; #endif /* WITH_CONTENT_SCAN */ @@ -3599,9 +3565,10 @@ else { #ifdef WITH_CONTENT_SCAN - if (acl_not_smtp_mime != NULL && - !run_mime_acl(acl_not_smtp_mime, &smtp_yield, &smtp_reply, - &blackholed_by)) + if ( acl_not_smtp_mime + && !run_mime_acl(acl_not_smtp_mime, &smtp_yield, &smtp_reply, + &blackholed_by) + ) goto TIDYUP; #endif /* WITH_CONTENT_SCAN */ @@ -3769,32 +3736,32 @@ else switch(rc) { default: - log_write(0, LOG_MAIN, "invalid return %d from local_scan(). Temporary " - "rejection given", rc); - goto TEMPREJECT; + log_write(0, LOG_MAIN, "invalid return %d from local_scan(). Temporary " + "rejection given", rc); + goto TEMPREJECT; case LOCAL_SCAN_REJECT_NOLOGHDR: - BIT_CLEAR(log_selector, log_selector_size, Li_rejected_header); - /* Fall through */ + BIT_CLEAR(log_selector, log_selector_size, Li_rejected_header); + /* Fall through */ case LOCAL_SCAN_REJECT: - smtp_code = US"550"; - if (errmsg == NULL) errmsg = US"Administrative prohibition"; - break; + smtp_code = US"550"; + if (!errmsg) errmsg = US"Administrative prohibition"; + break; case LOCAL_SCAN_TEMPREJECT_NOLOGHDR: - BIT_CLEAR(log_selector, log_selector_size, Li_rejected_header); - /* Fall through */ + BIT_CLEAR(log_selector, log_selector_size, Li_rejected_header); + /* Fall through */ case LOCAL_SCAN_TEMPREJECT: TEMPREJECT: - smtp_code = US"451"; - if (errmsg == NULL) errmsg = US"Temporary local problem"; - istemp = US"temporarily "; - break; + smtp_code = US"451"; + if (!errmsg) errmsg = US"Temporary local problem"; + istemp = US"temporarily "; + break; } - g = string_append(g, 2, US"F=", + g = string_append(NULL, 2, US"F=", sender_address[0] == 0 ? US"<>" : sender_address); g = add_host_info_for_log(g); @@ -3991,6 +3958,14 @@ if (LOGGING(8bitmime)) g = string_append(g, 2, US" M8S=", big_buffer); } +#ifndef DISABLE_DKIM +if (LOGGING(dkim) && dkim_verify_overall) + g = string_append(g, 2, US" DKIM=", dkim_verify_overall); +#endif + +if (LOGGING(receive_time)) + g = string_append(g, 2, US" RT=", string_timediff(&received_time_taken)); + if (*queue_name) g = string_append(g, 2, US" Q=", queue_name); @@ -4014,7 +3989,7 @@ if (msgid_header) /* If subject logging is turned on, create suitable printing-character text. By expanding $h_subject: we make use of the MIME decoding. */ -if (LOGGING(subject) && subject_header != NULL) +if (LOGGING(subject) && subject_header) { int i; uschar *p = big_buffer;