X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fsmtp_in.c;h=a0e44d89a798eeb39dbea46751e683482459c722;hb=9d4319dfec653f43b64562c8f31b87f2890365b2;hp=d646fe0bdfc5aea41938197ab94bcec895192b1e;hpb=50dc740948ba43eaeb6d33757bc83beff33f2a64;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index d646fe0bd..a0e44d89a 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -133,6 +133,9 @@ static BOOL rcpt_smtp_response_same; static BOOL rcpt_in_progress; static int nonmail_command_count; static BOOL smtp_exit_function_called = 0; +#ifdef EXPERIMENTAL_INTERNATIONAL +static BOOL smtputf8_advertised; +#endif static int synprot_error_count; static int unknown_command_count; static int sync_cmd_limit; @@ -158,6 +161,8 @@ QUIT is also "falsely" labelled as a mail command so that it doesn't up the count of non-mail commands and possibly provoke an error. */ static smtp_cmd_list cmd_list[] = { + /* name len cmd has_arg is_mail_cmd */ + { "rset", sizeof("rset")-1, RSET_CMD, FALSE, FALSE }, /* First */ { "helo", sizeof("helo")-1, HELO_CMD, TRUE, FALSE }, { "ehlo", sizeof("ehlo")-1, EHLO_CMD, TRUE, FALSE }, @@ -219,6 +224,9 @@ enum { ENV_MAIL_OPT_PRDR, #endif ENV_MAIL_OPT_RET, ENV_MAIL_OPT_ENVID, +#ifdef EXPERIMENTAL_INTERNATIONAL + ENV_MAIL_OPT_UTF8, +#endif ENV_MAIL_OPT_NULL }; typedef struct { @@ -236,6 +244,9 @@ static env_mail_type_t env_mail_type_list[] = { #endif { US"RET", ENV_MAIL_OPT_RET, TRUE }, { US"ENVID", ENV_MAIL_OPT_ENVID, TRUE }, +#ifdef EXPERIMENTAL_INTERNATIONAL + { US"SMTPUTF8",ENV_MAIL_OPT_UTF8, FALSE }, /* rfc6531 */ +#endif { US"NULL", ENV_MAIL_OPT_NULL, FALSE } }; @@ -1494,6 +1505,8 @@ sender_verified_list = NULL; /* No senders verified */ memset(sender_address_cache, 0, sizeof(sender_address_cache)); memset(sender_domain_cache, 0, sizeof(sender_domain_cache)); +prdr_requested = FALSE; + /* Reset the DSN flags */ dsn_ret = 0; dsn_envid = NULL; @@ -1514,6 +1527,9 @@ spf_received = NULL; spf_result = NULL; spf_smtp_comment = NULL; #endif +#ifdef EXPERIMENTAL_INTERNATIONAL +message_smtputf8 = FALSE; +#endif body_linecount = body_zerocount = 0; sender_rate = sender_rate_limit = sender_rate_period = NULL; @@ -1848,6 +1864,9 @@ tls_in.ocsp = OCSP_NOT_REQ; tls_advertised = FALSE; #endif dsn_advertised = FALSE; +#ifdef EXPERIMENTAL_INTERNATIONAL +smtputf8_advertised = FALSE; +#endif /* Reset ACL connection variables */ @@ -2129,6 +2148,19 @@ if (!sender_host_unknown) set_process_info("handling incoming connection from %s", host_and_ident(FALSE)); + /* Expand smtp_receive_timeout, if needed */ + + if (smtp_receive_timeout_s) + { + uschar * exp; + if ( !(exp = expand_string(smtp_receive_timeout_s)) + || !(*exp) + || (smtp_receive_timeout = readconf_readtime(exp, 0, FALSE)) < 0 + ) + log_write(0, LOG_MAIN|LOG_PANIC, + "bad value for smtp_receive_timeout: '%s'", exp ? exp : US""); + } + /* Start up TLS if tls_on_connect is set. This is for supporting the legacy smtps port for use with older style SSL MTAs. */ @@ -3119,7 +3151,7 @@ value. The values are 2 larger than the required yield of the function. */ while (done <= 0) { - uschar **argv; + const uschar **argv; uschar *etrn_command; uschar *etrn_serialize_key; uschar *errmess; @@ -3127,7 +3159,7 @@ while (done <= 0) uschar *user_msg = NULL; uschar *recipient = NULL; uschar *hello = NULL; - uschar *set_id = NULL; + const uschar *set_id = NULL; uschar *s, *ss; BOOL was_rej_mail = FALSE; BOOL was_rcpt = FALSE; @@ -3411,7 +3443,7 @@ while (done <= 0) if (sender_host_name == NULL && (deliver_domain = sender_helo_name, /* set $domain */ - match_isinlist(sender_helo_name, &helo_lookup_domains, 0, + match_isinlist(sender_helo_name, CUSS &helo_lookup_domains, 0, &domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL)) == OK) (void)host_name_lookup(); @@ -3480,10 +3512,13 @@ while (done <= 0) auth_advertised = FALSE; pipelining_advertised = FALSE; - #ifdef SUPPORT_TLS +#ifdef SUPPORT_TLS tls_advertised = FALSE; - #endif +#endif dsn_advertised = FALSE; +#ifdef EXPERIMENTAL_INTERNATIONAL + smtputf8_advertised = FALSE; +#endif smtp_code = US"250 "; /* Default response code plus space*/ if (user_msg == NULL) @@ -3654,7 +3689,7 @@ while (done <= 0) tls_advertise_hosts. We must *not* advertise if we are already in a secure connection. */ - #ifdef SUPPORT_TLS +#ifdef SUPPORT_TLS if (tls_in.active < 0 && verify_check_host(&tls_advertise_hosts) != FAIL) { @@ -3662,16 +3697,26 @@ while (done <= 0) s = string_cat(s, &size, &ptr, US"-STARTTLS\r\n", 11); tls_advertised = TRUE; } - #endif +#endif - #ifndef DISABLE_PRDR +#ifndef DISABLE_PRDR /* Per Recipient Data Response, draft by Eric A. Hall extending RFC */ if (prdr_enable) { s = string_cat(s, &size, &ptr, smtp_code, 3); s = string_cat(s, &size, &ptr, US"-PRDR\r\n", 7); } - #endif +#endif + +#ifdef EXPERIMENTAL_INTERNATIONAL + if ( accept_8bitmime + && verify_check_host(&smtputf8_advertise_hosts) != FAIL) + { + s = string_cat(s, &size, &ptr, smtp_code, 3); + s = string_cat(s, &size, &ptr, US"-SMTPUTF8\r\n", 11); + smtputf8_advertised = TRUE; + } +#endif /* Finish off the multiline reply with one that is always available. */ @@ -3684,9 +3729,9 @@ while (done <= 0) s[ptr] = 0; - #ifdef SUPPORT_TLS +#ifdef SUPPORT_TLS if (tls_in.active >= 0) (void)tls_write(TRUE, s, ptr); else - #endif +#endif { int i = fwrite(s, 1, ptr, smtp_out); i = i; /* compiler quietening */ @@ -3783,10 +3828,8 @@ while (done <= 0) (char *)mail_args < (char *)env_mail_type_list + sizeof(env_mail_type_list); mail_args++ ) - { if (strcmpic(name, mail_args->name) == 0) break; - } if (mail_args->need_value && strcmpic(value, US"") == 0) break; @@ -3814,16 +3857,17 @@ while (done <= 0) and "7BIT" as body types, but take no action. */ case ENV_MAIL_OPT_BODY: if (accept_8bitmime) { - if (strcmpic(value, US"8BITMIME") == 0) { + if (strcmpic(value, US"8BITMIME") == 0) body_8bitmime = 8; - } else if (strcmpic(value, US"7BIT") == 0) { + else if (strcmpic(value, US"7BIT") == 0) body_8bitmime = 7; - } else { + else + { body_8bitmime = 0; done = synprot_error(L_smtp_syntax_error, 501, NULL, US"invalid data for BODY"); goto COMMAND_LOOP; - } + } DEBUG(D_receive) debug_printf("8BITMIME: %d\n", body_8bitmime); break; } @@ -3835,35 +3879,43 @@ while (done <= 0) is included only if configured in at build time. */ case ENV_MAIL_OPT_RET: - if (dsn_advertised) { + if (dsn_advertised) + { /* Check if RET has already been set */ - if (dsn_ret > 0) { + if (dsn_ret > 0) + { synprot_error(L_smtp_syntax_error, 501, NULL, US"RET can be specified once only"); goto COMMAND_LOOP; - } - dsn_ret = (strcmpic(value, US"HDRS") == 0)? dsn_ret_hdrs : - (strcmpic(value, US"FULL") == 0)? dsn_ret_full : 0; + } + dsn_ret = strcmpic(value, US"HDRS") == 0 + ? dsn_ret_hdrs + : strcmpic(value, US"FULL") == 0 + ? dsn_ret_full + : 0; DEBUG(D_receive) debug_printf("DSN_RET: %d\n", dsn_ret); /* Check for invalid invalid value, and exit with error */ - if (dsn_ret == 0) { + if (dsn_ret == 0) + { synprot_error(L_smtp_syntax_error, 501, NULL, US"Value for RET is invalid"); goto COMMAND_LOOP; - } - } + } + } break; case ENV_MAIL_OPT_ENVID: - if (dsn_advertised) { + if (dsn_advertised) + { /* Check if the dsn envid has been already set */ - if (dsn_envid != NULL) { + if (dsn_envid != NULL) + { synprot_error(L_smtp_syntax_error, 501, NULL, US"ENVID can be specified once only"); goto COMMAND_LOOP; - } + } dsn_envid = string_copy(value); DEBUG(D_receive) debug_printf("DSN_ENVID: %s\n", dsn_envid); - } + } break; /* Handle the AUTH extension. If the value given is not "<>" and either @@ -3903,34 +3955,34 @@ while (done <= 0) switch (rc) { case OK: - if (authenticated_by == NULL || - authenticated_by->mail_auth_condition == NULL || - expand_check_condition(authenticated_by->mail_auth_condition, - authenticated_by->name, US"authenticator")) - break; /* Accept the AUTH */ - - ignore_msg = US"server_mail_auth_condition failed"; - if (authenticated_id != NULL) - ignore_msg = string_sprintf("%s: authenticated ID=\"%s\"", - ignore_msg, authenticated_id); + if (authenticated_by == NULL || + authenticated_by->mail_auth_condition == NULL || + expand_check_condition(authenticated_by->mail_auth_condition, + authenticated_by->name, US"authenticator")) + break; /* Accept the AUTH */ + + ignore_msg = US"server_mail_auth_condition failed"; + if (authenticated_id != NULL) + ignore_msg = string_sprintf("%s: authenticated ID=\"%s\"", + ignore_msg, authenticated_id); /* Fall through */ case FAIL: - authenticated_sender = NULL; - log_write(0, LOG_MAIN, "ignoring AUTH=%s from %s (%s)", - value, host_and_ident(TRUE), ignore_msg); - break; + authenticated_sender = NULL; + log_write(0, LOG_MAIN, "ignoring AUTH=%s from %s (%s)", + value, host_and_ident(TRUE), ignore_msg); + break; /* Should only get DEFER or ERROR here. Put back terminator overrides for error message */ default: - value[-1] = '='; - name[-1] = ' '; - (void)smtp_handle_acl_fail(ACL_WHERE_MAILAUTH, rc, user_msg, - log_msg); - goto COMMAND_LOOP; + value[-1] = '='; + name[-1] = ' '; + (void)smtp_handle_acl_fail(ACL_WHERE_MAILAUTH, rc, user_msg, + log_msg); + goto COMMAND_LOOP; } } break; @@ -3942,6 +3994,12 @@ while (done <= 0) break; #endif +#ifdef EXPERIMENTAL_INTERNATIONAL + case ENV_MAIL_OPT_UTF8: + if (smtputf8_advertised) + message_smtputf8 = allow_utf8_domains = TRUE; + break; +#endif /* Unknown option. Stick back the terminator characters and break the loop. Do the name-terminator second as extract_option sets value==name when it found no equal-sign. @@ -3974,9 +4032,10 @@ while (done <= 0) /* Now extract the address, first applying any SMTP-time rewriting. The TRUE flag allows "<>" as a sender address. */ - raw_sender = ((rewrite_existflags & rewrite_smtp) != 0)? - rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", - global_rewrite_rules) : smtp_cmd_data; + raw_sender = rewrite_existflags & rewrite_smtp + ? rewrite_one(smtp_cmd_data, rewrite_smtp, NULL, FALSE, US"", + global_rewrite_rules) + : smtp_cmd_data; /* rfc821_domains = TRUE; << no longer needed */ raw_sender = @@ -4435,7 +4494,7 @@ while (done <= 0) ACL may have delayed. To handle cutthrough delivery enforce a dummy call to get the DATA command sent. */ - if (acl_smtp_predata == NULL && cutthrough_fd < 0) rc = OK; else + if (acl_smtp_predata == NULL && cutthrough.fd < 0) rc = OK; else { uschar * acl= acl_smtp_predata ? acl_smtp_predata : US"accept"; enable_dollar_recipients = TRUE; @@ -4837,7 +4896,7 @@ while (done <= 0) break; } etrn_command = US"exim -R"; - argv = child_exec_exim(CEE_RETURN_ARGV, TRUE, NULL, TRUE, 2, US"-R", + argv = CUSS child_exec_exim(CEE_RETURN_ARGV, TRUE, NULL, TRUE, 2, US"-R", smtp_cmd_data); }