X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fsmtp_in.c;h=bf7a308db098da4da790e0fc888623c5f015ddc9;hb=db57e575c97e06b0f0765f958073864b1729d085;hp=b5839f5443f75c2e023132d72c77af970cd00709;hpb=acec9514b1006e352ef283f205ecec75a9b6ff0d;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index b5839f544..bf7a308db 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -187,7 +187,7 @@ static smtp_cmd_list cmd_list[] = { { "auth", sizeof("auth")-1, AUTH_CMD, TRUE, TRUE }, #ifdef SUPPORT_TLS { "starttls", sizeof("starttls")-1, STARTTLS_CMD, FALSE, FALSE }, - { "tls_auth", 0, TLS_AUTH_CMD, FALSE, TRUE }, + { "tls_auth", 0, TLS_AUTH_CMD, FALSE, FALSE }, #endif /* If you change anything above here, also fix the definitions below. */ @@ -681,8 +681,11 @@ return buf; void bdat_flush_data(void) { -unsigned n = chunking_data_left; -(void) bdat_getbuf(&n); +while (chunking_data_left) + { + unsigned n = chunking_data_left; + (void) bdat_getbuf(&n); + } receive_getc = lwr_receive_getc; receive_getbuf = lwr_receive_getbuf; @@ -842,7 +845,7 @@ if (!yield) { log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_printf()"); smtp_closedown(US"Unexpected error"); - exim_exit(EXIT_FAILURE); + exim_exit(EXIT_FAILURE, NULL); } /* If this is the first output for a (non-batch) RCPT command, see if all RCPTs @@ -922,7 +925,7 @@ 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); +exim_exit(EXIT_FAILURE, US"receiving"); } @@ -946,7 +949,7 @@ 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); +exim_exit(EXIT_FAILURE, US"receiving"); } @@ -1643,27 +1646,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; } } @@ -1752,7 +1755,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); @@ -1844,7 +1847,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. */ @@ -1867,21 +1870,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 */ @@ -2114,14 +2110,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 @@ -2131,53 +2127,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 @@ -2188,53 +2184,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 @@ -2242,22 +2239,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. */ @@ -2267,32 +2262,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; } } @@ -2442,7 +2437,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: " @@ -2823,8 +2818,12 @@ if (check_proxy_protocol_host()) smtps port for use with older style SSL MTAs. */ #ifdef SUPPORT_TLS - if (tls_in.on_connect && tls_server_start(tls_require_ciphers, &user_msg) != OK) - return smtp_log_tls_fail(user_msg); + if (tls_in.on_connect) + { + if (tls_server_start(tls_require_ciphers, &user_msg) != OK) + return smtp_log_tls_fail(user_msg); + cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE; + } #endif /* Run the connect ACL if it exists */ @@ -2889,7 +2888,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); @@ -2903,9 +2902,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. */ @@ -3797,7 +3796,6 @@ cmd_list[CMD_LIST_HELO].is_mail_cmd = TRUE; cmd_list[CMD_LIST_EHLO].is_mail_cmd = TRUE; #ifdef SUPPORT_TLS cmd_list[CMD_LIST_STARTTLS].is_mail_cmd = TRUE; -cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = TRUE; #endif /* Set the local signal handler for SIGTERM - it tries to end off tidily */ @@ -3843,24 +3841,24 @@ while (done <= 0) ) { cmd_list[CMD_LIST_TLS_AUTH].is_mail_cmd = FALSE; - if ( acl_smtp_auth - && (rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth, - &user_msg, &log_msg)) != OK - ) - { - done = smtp_handle_acl_fail(ACL_WHERE_AUTH, rc, user_msg, log_msg); - continue; - } for (au = auths; au; au = au->next) if (strcmpic(US"tls", au->driver_name) == 0) { - smtp_cmd_data = NULL; - - if (smtp_in_auth(au, &s, &ss) == OK) - { DEBUG(D_auth) debug_printf("tls auth succeeded\n"); } + if ( acl_smtp_auth + && (rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth, + &user_msg, &log_msg)) != OK + ) + done = smtp_handle_acl_fail(ACL_WHERE_AUTH, rc, user_msg, log_msg); else - { DEBUG(D_auth) debug_printf("tls auth not succeeded\n"); } + { + smtp_cmd_data = NULL; + + if (smtp_in_auth(au, &s, &ss) == OK) + { DEBUG(D_auth) debug_printf("tls auth succeeded\n"); } + else + { DEBUG(D_auth) debug_printf("tls auth not succeeded\n"); } + } break; } } @@ -5091,17 +5089,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)