X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/b64d13ee7a7b9a398159d75e6e71c018a3cf2690..d3e58fcb87faf7131a2712fcfaef200ffd191f05:/src/src/smtp_in.c diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 28586f33d..823fcd27d 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2017 */ +/* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions for handling an incoming SMTP call. */ @@ -427,6 +427,53 @@ log_write(L_smtp_incomplete_transaction, LOG_MAIN|LOG_SENDER|LOG_RECIPIENTS, +void +smtp_command_timeout_exit(void) +{ +log_write(L_lost_incoming_connection, + LOG_MAIN, "SMTP command timeout on%s connection from %s", + tls_in.active >= 0 ? " TLS" : "", host_and_ident(FALSE)); +if (smtp_batched_input) + moan_smtp_batch(NULL, "421 SMTP command timeout"); /* Does not return */ +smtp_notquit_exit(US"command-timeout", US"421", + US"%s: SMTP command timeout - closing connection", + smtp_active_hostname); +exim_exit(EXIT_FAILURE, US"receiving"); +} + +void +smtp_command_sigterm_exit(void) +{ +log_write(0, LOG_MAIN, "%s closed after SIGTERM", smtp_get_connection_info()); +if (smtp_batched_input) + moan_smtp_batch(NULL, "421 SIGTERM received"); /* Does not return */ +smtp_notquit_exit(US"signal-exit", US"421", + US"%s: Service not available - closing connection", smtp_active_hostname); +exim_exit(EXIT_FAILURE, US"receiving"); +} + +void +smtp_data_timeout_exit(void) +{ +log_write(L_lost_incoming_connection, + LOG_MAIN, "SMTP data timeout (message abandoned) on connection from %s F=<%s>", + sender_fullhost ? sender_fullhost : US"local process", sender_address); +receive_bomb_out(US"data-timeout", US"SMTP incoming data timeout"); +/* Does not return */ +} + +void +smtp_data_sigint_exit(void) +{ +log_write(0, LOG_MAIN, "%s closed after %s", + smtp_get_connection_info(), had_data_sigint == SIGTERM ? "SIGTERM":"SIGINT"); +receive_bomb_out(US"signal-exit", + US"Service not available - SIGTERM or SIGINT received"); +/* Does not return */ +} + + + /* Refill the buffer, and notify DKIM verification code. Return false for error or EOF. */ @@ -443,18 +490,28 @@ if (smtp_receive_timeout > 0) alarm(smtp_receive_timeout); rc = read(fileno(smtp_in), smtp_inbuffer, MIN(IN_BUFFER_SIZE, lim)); save_errno = errno; -alarm(0); +if (smtp_receive_timeout > 0) alarm(0); if (rc <= 0) { /* Must put the error text in fixed store, because this might be during header reading, where it releases unused store above the header. */ if (rc < 0) { + if (had_command_timeout) /* set by signal handler */ + smtp_command_timeout_exit(); /* does not return */ + if (had_command_sigterm) + smtp_command_sigterm_exit(); + if (had_data_timeout) + smtp_data_timeout_exit(); + if (had_data_sigint) + smtp_data_sigint_exit(); + smtp_had_error = save_errno; smtp_read_error = string_copy_malloc( string_sprintf(" (error: %s)", strerror(save_errno))); } - else smtp_had_eof = 1; + else + smtp_had_eof = 1; return FALSE; } #ifndef DISABLE_DKIM @@ -653,7 +710,7 @@ next_cmd: } receive_getc = bdat_getc; - receive_getbuf = bdat_getbuf; + receive_getbuf = bdat_getbuf; /* r~getbuf is never actually used */ receive_ungetc = bdat_ungetc; #ifndef DISABLE_DKIM dkim_collect_input = dkim_save; @@ -682,10 +739,10 @@ void bdat_flush_data(void) { while (chunking_data_left) -{ + { unsigned n = chunking_data_left; - (void) bdat_getbuf(&n); -} + if (!bdat_getbuf(&n)) break; + } receive_getc = lwr_receive_getc; receive_getbuf = lwr_receive_getbuf; @@ -916,16 +973,7 @@ Returns: nothing static void command_timeout_handler(int sig) { -sig = sig; /* Keep picky compilers happy */ -log_write(L_lost_incoming_connection, - LOG_MAIN, "SMTP command timeout on%s connection from %s", - (tls_in.active >= 0)? " TLS" : "", - host_and_ident(FALSE)); -if (smtp_batched_input) - moan_smtp_batch(NULL, "421 SMTP command timeout"); /* Does not return */ -smtp_notquit_exit(US"command-timeout", US"421", - US"%s: SMTP command timeout - closing connection", smtp_active_hostname); -exim_exit(EXIT_FAILURE, US"receiving"); +had_command_timeout = sig; } @@ -943,13 +991,7 @@ Returns: nothing static void command_sigterm_handler(int sig) { -sig = sig; /* Keep picky compilers happy */ -log_write(0, LOG_MAIN, "%s closed after SIGTERM", smtp_get_connection_info()); -if (smtp_batched_input) - moan_smtp_batch(NULL, "421 SIGTERM received"); /* Does not return */ -smtp_notquit_exit(US"signal-exit", US"421", - US"%s: Service not available - closing connection", smtp_active_hostname); -exim_exit(EXIT_FAILURE, US"receiving"); +had_command_sigterm = sig; } @@ -1509,6 +1551,7 @@ int ptr = 0; smtp_cmd_list *p; BOOL hadnull = FALSE; +had_command_timeout = 0; os_non_restarting_signal(SIGALRM, command_timeout_handler); while ((c = (receive_getc)(buffer_lim)) != '\n' && c != EOF) @@ -1646,27 +1689,27 @@ Returns: nothing void smtp_closedown(uschar *message) { -if (smtp_in == NULL || smtp_batched_input) return; +if (!smtp_in || smtp_batched_input) return; receive_swallow_smtp(); smtp_printf("421 %s\r\n", FALSE, message); for (;;) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED)) { case EOF_CMD: - return; + return; case QUIT_CMD: - smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname); - mac_smtp_fflush(); - return; + smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname); + mac_smtp_fflush(); + return; case RSET_CMD: - smtp_printf("250 Reset OK\r\n", FALSE); - break; + smtp_printf("250 Reset OK\r\n", FALSE); + break; default: - smtp_printf("421 %s\r\n", FALSE, message); - break; + smtp_printf("421 %s\r\n", FALSE, message); + break; } } @@ -1755,7 +1798,7 @@ gstring * g = NULL; if (smtp_mailcmd_count > 0 || !LOGGING(smtp_no_mail)) return; -if (sender_host_authenticated != NULL) +if (sender_host_authenticated) { g = string_append(g, 2, US" A=", sender_host_authenticated); if (authenticated_id) g = string_append(g, 2, US":", authenticated_id); @@ -1838,7 +1881,7 @@ BOOL yield = helo_accept_junk; /* Discard any previous helo name */ -if (sender_helo_name != NULL) +if (sender_helo_name) { store_free(sender_helo_name); sender_helo_name = NULL; @@ -1847,7 +1890,7 @@ if (sender_helo_name != NULL) /* Skip tests if junk is permitted. */ if (!yield) - { + /* Allow the new standard form for IPv6 address literals, namely, [IPv6:....], and because someone is bound to use it, allow an equivalent IPv4 form. Allow plain addresses as well. */ @@ -1870,21 +1913,14 @@ if (!yield) /* Non-literals must be alpha, dot, hyphen, plus any non-valid chars that have been configured (usually underscore - sigh). */ - else if (*s != 0) - { - yield = TRUE; - while (*s != 0) - { + else if (*s) + for (yield = TRUE; *s; s++) if (!isalnum(*s) && *s != '.' && *s != '-' && Ustrchr(helo_allow_chars, *s) == NULL) { yield = FALSE; break; } - s++; - } - } - } /* Save argument if OK */ @@ -1954,13 +1990,13 @@ return TRUE; *************************************************/ /* This function is called whenever the SMTP session is reset from -within either of the setup functions. +within either of the setup functions; also from the daemon loop. Argument: the stacking pool storage reset point Returns: nothing */ -static void +void smtp_reset(void *reset_point) { recipients_list = NULL; @@ -2004,9 +2040,8 @@ bmi_verdicts = NULL; #endif dnslist_domain = dnslist_matched = NULL; #ifndef DISABLE_DKIM -dkim_signers = NULL; -dkim_disable_verify = FALSE; -dkim_collect_input = FALSE; +dkim_cur_signer = dkim_signers = NULL; +dkim_disable_verify = dkim_collect_input = FALSE; #endif dsn_ret = 0; dsn_envid = NULL; @@ -2014,11 +2049,11 @@ deliver_host = deliver_host_address = NULL; /* Can be set by ACL */ #ifndef DISABLE_PRDR prdr_requested = FALSE; #endif -#ifdef EXPERIMENTAL_SPF -spf_header_comment = NULL; -spf_received = NULL; -spf_result = NULL; -spf_smtp_comment = NULL; +#ifdef SUPPORT_SPF +spf_header_comment = spf_received = spf_result = spf_smtp_comment = NULL; +#endif +#ifdef EXPERIMENTAL_ARC +arc_state = arc_state_reason = NULL; #endif #ifdef SUPPORT_I18N message_smtputf8 = FALSE; @@ -2117,14 +2152,14 @@ while (done <= 0) case HELO_CMD: case EHLO_CMD: - check_helo(smtp_cmd_data); - /* Fall through */ + check_helo(smtp_cmd_data); + /* Fall through */ case RSET_CMD: - cancel_cutthrough_connection(TRUE, US"RSET received"); - smtp_reset(reset_point); - bsmtp_transaction_linecount = receive_linecount; - break; + cancel_cutthrough_connection(TRUE, US"RSET received"); + smtp_reset(reset_point); + bsmtp_transaction_linecount = receive_linecount; + break; /* The MAIL FROM command requires an address as an operand. All we @@ -2134,53 +2169,53 @@ while (done <= 0) it is the canonical extracted address which is all that is kept. */ case MAIL_CMD: - smtp_mailcmd_count++; /* Count for no-mail log */ - if (sender_address != NULL) - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "503 Sender already given"); + smtp_mailcmd_count++; /* Count for no-mail log */ + if (sender_address != NULL) + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "503 Sender already given"); - if (smtp_cmd_data[0] == 0) - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "501 MAIL FROM must have an address operand"); + if (smtp_cmd_data[0] == 0) + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "501 MAIL FROM must have an address operand"); - /* Reset to start of message */ + /* Reset to start of message */ - cancel_cutthrough_connection(TRUE, US"MAIL received"); - smtp_reset(reset_point); + cancel_cutthrough_connection(TRUE, US"MAIL received"); + smtp_reset(reset_point); - /* Apply SMTP rewrite */ + /* Apply SMTP rewrite */ - raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)? - rewrite_one(smtp_cmd_data, rewrite_smtp|rewrite_smtp_sender, NULL, FALSE, - US"", global_rewrite_rules) : smtp_cmd_data; + raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)? + rewrite_one(smtp_cmd_data, rewrite_smtp|rewrite_smtp_sender, NULL, FALSE, + US"", global_rewrite_rules) : smtp_cmd_data; - /* Extract the address; the TRUE flag allows <> as valid */ + /* Extract the address; the TRUE flag allows <> as valid */ - raw_sender = - parse_extract_address(raw_sender, &errmess, &start, &end, &sender_domain, - TRUE); + raw_sender = + parse_extract_address(raw_sender, &errmess, &start, &end, &sender_domain, + TRUE); - if (raw_sender == NULL) - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "501 %s", errmess); + if (!raw_sender) + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "501 %s", errmess); - sender_address = string_copy(raw_sender); + sender_address = string_copy(raw_sender); - /* Qualify unqualified sender addresses if permitted to do so. */ + /* Qualify unqualified sender addresses if permitted to do so. */ - if (sender_domain == 0 && sender_address[0] != 0 && sender_address[0] != '@') - { - if (allow_unqualified_sender) - { - sender_address = rewrite_address_qualify(sender_address, FALSE); - DEBUG(D_receive) debug_printf("unqualified address %s accepted " - "and rewritten\n", raw_sender); - } - /* The function moan_smtp_batch() does not return. */ - else moan_smtp_batch(smtp_cmd_buffer, "501 sender address must contain " - "a domain"); - } - break; + if ( !sender_domain + && sender_address[0] != 0 && sender_address[0] != '@') + if (allow_unqualified_sender) + { + sender_address = rewrite_address_qualify(sender_address, FALSE); + DEBUG(D_receive) debug_printf("unqualified address %s accepted " + "and rewritten\n", raw_sender); + } + /* The function moan_smtp_batch() does not return. */ + else + moan_smtp_batch(smtp_cmd_buffer, "501 sender address must contain " + "a domain"); + break; /* The RCPT TO command requires an address as an operand. All we do @@ -2191,53 +2226,54 @@ while (done <= 0) extracted address. */ case RCPT_CMD: - if (sender_address == NULL) - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "503 No sender yet given"); + if (!sender_address) + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "503 No sender yet given"); - if (smtp_cmd_data[0] == 0) - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "501 RCPT TO must have an address operand"); + if (smtp_cmd_data[0] == 0) + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, + "501 RCPT TO must have an address operand"); - /* Check maximum number allowed */ + /* Check maximum number allowed */ - if (recipients_max > 0 && recipients_count + 1 > recipients_max) - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "%s too many recipients", - recipients_max_reject? "552": "452"); + if (recipients_max > 0 && recipients_count + 1 > recipients_max) + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "%s too many recipients", + recipients_max_reject? "552": "452"); - /* Apply SMTP rewrite, then extract address. Don't allow "<>" as a - recipient address */ + /* Apply SMTP rewrite, then extract address. Don't allow "<>" as a + recipient address */ - recipient = rewrite_existflags & rewrite_smtp - ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", - global_rewrite_rules) - : smtp_cmd_data; + recipient = rewrite_existflags & rewrite_smtp + ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", + global_rewrite_rules) + : smtp_cmd_data; - recipient = parse_extract_address(recipient, &errmess, &start, &end, - &recipient_domain, FALSE); + recipient = parse_extract_address(recipient, &errmess, &start, &end, + &recipient_domain, FALSE); - if (!recipient) - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "501 %s", errmess); + if (!recipient) + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "501 %s", errmess); - /* If the recipient address is unqualified, qualify it if permitted. Then - add it to the list of recipients. */ + /* If the recipient address is unqualified, qualify it if permitted. Then + add it to the list of recipients. */ - if (recipient_domain == 0) - { - if (allow_unqualified_recipient) - { - DEBUG(D_receive) debug_printf("unqualified address %s accepted\n", - recipient); - recipient = rewrite_address_qualify(recipient, TRUE); - } - /* The function moan_smtp_batch() does not return. */ - else moan_smtp_batch(smtp_cmd_buffer, "501 recipient address must contain " - "a domain"); - } - receive_add_recipient(recipient, -1); - break; + if (!recipient_domain) + if (allow_unqualified_recipient) + { + DEBUG(D_receive) debug_printf("unqualified address %s accepted\n", + recipient); + recipient = rewrite_address_qualify(recipient, TRUE); + } + /* The function moan_smtp_batch() does not return. */ + else + moan_smtp_batch(smtp_cmd_buffer, + "501 recipient address must contain a domain"); + + receive_add_recipient(recipient, -1); + break; /* The DATA command is legal only if it follows successful MAIL FROM @@ -2245,22 +2281,20 @@ while (done <= 0) command is encountered. */ case DATA_CMD: - if (sender_address == NULL || recipients_count <= 0) - { - /* The function moan_smtp_batch() does not return. */ - if (sender_address == NULL) - moan_smtp_batch(smtp_cmd_buffer, - "503 MAIL FROM: command must precede DATA"); + if (!sender_address || recipients_count <= 0) + /* The function moan_smtp_batch() does not return. */ + if (!sender_address) + moan_smtp_batch(smtp_cmd_buffer, + "503 MAIL FROM: command must precede DATA"); + else + moan_smtp_batch(smtp_cmd_buffer, + "503 RCPT TO: must precede DATA"); else - moan_smtp_batch(smtp_cmd_buffer, - "503 RCPT TO: must precede DATA"); - } - else - { - done = 3; /* DATA successfully achieved */ - message_ended = END_NOTENDED; /* Indicate in middle of message */ - } - break; + { + done = 3; /* DATA successfully achieved */ + message_ended = END_NOTENDED; /* Indicate in middle of message */ + } + break; /* The VRFY, EXPN, HELP, ETRN, and NOOP commands are ignored. */ @@ -2270,32 +2304,32 @@ while (done <= 0) case HELP_CMD: case NOOP_CMD: case ETRN_CMD: - bsmtp_transaction_linecount = receive_linecount; - break; + bsmtp_transaction_linecount = receive_linecount; + break; case EOF_CMD: case QUIT_CMD: - done = 2; - break; + done = 2; + break; case BADARG_CMD: - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "501 Unexpected argument data"); - break; + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "501 Unexpected argument data"); + break; case BADCHAR_CMD: - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "501 Unexpected NULL in SMTP command"); - break; + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "501 Unexpected NULL in SMTP command"); + break; default: - /* The function moan_smtp_batch() does not return. */ - moan_smtp_batch(smtp_cmd_buffer, "500 Command unrecognized"); - break; + /* The function moan_smtp_batch() does not return. */ + moan_smtp_batch(smtp_cmd_buffer, "500 Command unrecognized"); + break; } } @@ -2383,7 +2417,8 @@ smtp_exit_function_called = FALSE; /* For avoiding loop in not-quit exit */ /* If receiving by -bs from a trusted user, or testing with -bh, we allow authentication settings from -oMaa to remain in force. */ -if (!host_checking && !sender_host_notsocket) sender_host_authenticated = NULL; +if (!host_checking && !sender_host_notsocket) + sender_host_auth_pubname = sender_host_authenticated = NULL; authenticated_by = NULL; #ifdef SUPPORT_TLS @@ -2445,7 +2480,7 @@ smtp_had_eof = smtp_had_error = 0; /* Set up the message size limit; this may be host-specific */ thismessage_size_limit = expand_string_integer(message_size_limit, TRUE); -if (expand_string_message != NULL) +if (expand_string_message) { if (thismessage_size_limit == -1) log_write(0, LOG_MAIN|LOG_PANIC, "unable to expand message_size_limit: " @@ -2896,7 +2931,7 @@ do /* At least once, in case we have an empty string */ int len; uschar *linebreak = Ustrchr(p, '\n'); ss = string_catn(ss, code, 3); - if (linebreak == NULL) + if (!linebreak) { len = Ustrlen(p); ss = string_catn(ss, US" ", 1); @@ -2910,9 +2945,9 @@ do /* At least once, in case we have an empty string */ ss = string_catn(ss, p, len); ss = string_catn(ss, US"\r\n", 2); p += len; - if (linebreak != NULL) p++; + if (linebreak) p++; } -while (*p != 0); +while (*p); /* Before we write the banner, check that there is no input pending, unless this synchronisation check is disabled. */ @@ -3142,7 +3177,7 @@ return; /* This function is called when acl_check() fails. As well as calls from within this module, it is called from receive.c for an ACL after DATA. It sorts out -logging the incident, and sets up the error response. A message containing +logging the incident, and sends the error response. A message containing newlines is turned into a multiline SMTP response, but for logging, only the first line is used. @@ -3530,7 +3565,7 @@ else HDEBUG(D_receive) debug_printf("getting IP address for %s\n", sender_helo_name); - rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A, + rc = host_find_bydns(&h, NULL, HOST_FIND_BY_A | HOST_FIND_BY_AAAA, NULL, NULL, NULL, &d, NULL, NULL); if (rc == HOST_FOUND || rc == HOST_FOUND_LOCAL) for (hh = &h; hh; hh = hh->next) @@ -3633,6 +3668,7 @@ switch(rc) { if (set_id) authenticated_id = string_copy_malloc(set_id); sender_host_authenticated = au->name; + sender_host_auth_pubname = au->public_name; authentication_failed = FALSE; authenticated_fail_id = NULL; /* Impossible to already be set? */ @@ -3732,7 +3768,7 @@ else smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname); #ifdef SUPPORT_TLS -tls_close(TRUE, TRUE); +tls_close(TRUE, TLS_SHUTDOWN_NOWAIT); #endif log_write(L_smtp_connection, LOG_MAIN, "%s closed by QUIT", @@ -3808,6 +3844,7 @@ cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = TRUE; /* Set the local signal handler for SIGTERM - it tries to end off tidily */ +had_command_sigterm = 0; os_non_restarting_signal(SIGTERM, command_sigterm_handler); /* Batched SMTP is handled in a different function. */ @@ -4048,9 +4085,9 @@ while (done <= 0) /* Force a reverse lookup if HELO quoted something in helo_lookup_domains because otherwise the log can be confusing. */ - if (sender_host_name == NULL && - (deliver_domain = sender_helo_name, /* set $domain */ - match_isinlist(sender_helo_name, CUSS &helo_lookup_domains, 0, + if ( !sender_host_name + && (deliver_domain = sender_helo_name, /* set $domain */ + match_isinlist(sender_helo_name, CUSS &helo_lookup_domains, 0, &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) == OK) (void)host_name_lookup(); @@ -4090,7 +4127,7 @@ while (done <= 0) } } -#ifdef EXPERIMENTAL_SPF +#ifdef SUPPORT_SPF /* set up SPF context */ spf_init(sender_helo_name, sender_host_address); #endif @@ -4103,7 +4140,11 @@ while (done <= 0) &user_msg, &log_msg)) != OK) { done = smtp_handle_acl_fail(ACL_WHERE_HELO, rc, user_msg, log_msg); - sender_helo_name = NULL; + if (sender_helo_name) + { + store_free(sender_helo_name); + sender_helo_name = NULL; + } host_build_sender_fullhost(); /* Rebuild */ break; } @@ -4560,10 +4601,10 @@ while (done <= 0) US"invalid data for AUTH"); goto COMMAND_LOOP; } - if (acl_smtp_mailauth == NULL) + if (!acl_smtp_mailauth) { ignore_msg = US"client not authenticated"; - rc = (sender_host_authenticated != NULL)? OK : FAIL; + rc = sender_host_authenticated ? OK : FAIL; } else { @@ -5097,17 +5138,24 @@ while (done <= 0) DEBUG(D_receive) debug_printf("chunking state %d, %d bytes\n", (int)chunking_state, chunking_data_left); + /* push the current receive_* function on the "stack", and + replace them by bdat_getc(), which in turn will use the lwr_receive_* + functions to do the dirty work. */ lwr_receive_getc = receive_getc; lwr_receive_getbuf = receive_getbuf; lwr_receive_ungetc = receive_ungetc; + receive_getc = bdat_getc; receive_ungetc = bdat_ungetc; + dot_ends = FALSE; + goto DATA_BDAT; } case DATA_CMD: HAD(SCH_DATA); + dot_ends = TRUE; DATA_BDAT: /* Common code for DATA and BDAT */ if (!discarded && recipients_count <= 0) @@ -5337,7 +5385,7 @@ while (done <= 0) cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE; cmd_list[CMD_LIST_AUTH].is_mail_cmd = TRUE; cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE; - if (sender_helo_name != NULL) + if (sender_helo_name) { store_free(sender_helo_name); sender_helo_name = NULL; @@ -5353,7 +5401,7 @@ while (done <= 0) + (tls_in.active >= 0 ? pcrpted : 0) ]; - sender_host_authenticated = NULL; + sender_host_auth_pubname = sender_host_authenticated = NULL; authenticated_id = NULL; sync_cmd_limit = NON_SYNC_CMD_NON_PIPELINING; DEBUG(D_tls) debug_printf("TLS active\n"); @@ -5410,7 +5458,7 @@ while (done <= 0) smtp_printf("554 Security failure\r\n", FALSE); break; } - tls_close(TRUE, TRUE); + tls_close(TRUE, TLS_SHUTDOWN_NOWAIT); break; #endif @@ -5498,7 +5546,7 @@ while (done <= 0) case ETRN_CMD: HAD(SCH_ETRN); - if (sender_address != NULL) + if (sender_address) { done = synprot_error(L_smtp_protocol_error, 503, NULL, US"ETRN is not permitted inside a transaction"); @@ -5524,7 +5572,7 @@ while (done <= 0) since that is strictly the only kind of ETRN that can be implemented according to the RFC. */ - if (smtp_etrn_command != NULL) + if (smtp_etrn_command) { uschar *error; BOOL rc; @@ -5740,6 +5788,30 @@ while (done <= 0) return done - 2; /* Convert yield values */ } + + +gstring * +authres_smtpauth(gstring * g) +{ +if (!sender_host_authenticated) + return g; + +g = string_append(g, 2, US";\n\tauth=pass (", sender_host_auth_pubname); + +if (Ustrcmp(sender_host_auth_pubname, "tls") != 0) + g = string_append(g, 2, US") smtp.auth=", authenticated_id); +else if (authenticated_id) + g = string_append(g, 2, US") x509.auth=", authenticated_id); +else + g = string_catn(g, US") reason=x509.auth", 17); + +if (authenticated_sender) + g = string_append(g, 2, US" smtp.mailfrom=", authenticated_sender); +return g; +} + + + /* vi: aw ai sw=2 */ /* End of smtp_in.c */