X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fsmtp_in.c;h=66f752dd4a3acdaa394c92827f71f12046cd53c0;hb=afd5e75ffc8f64f0ebed1df9dce64793011c14a6;hp=bd29d2c1f9b74619050b4ae6e39b73127f6bb704;hpb=81344b40e3de597f60758926e5e1ae7a81dd5457;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index bd29d2c1f..66f752dd4 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -877,6 +877,8 @@ flush for non-TLS connections. The smtp_fflush() function is available for checking that: for convenience, TLS output errors are remembered here so that they are also picked up later by smtp_fflush(). +This function is exposed to the local_scan API; do not change the signature. + Arguments: format format string more further data expected @@ -897,7 +899,10 @@ va_end(ap); /* This is split off so that verify.c:respond_printf() can, in effect, call smtp_printf(), bearing in mind that in C a vararg function can't directly -call another vararg function, only a function which accepts a va_list. */ +call another vararg function, only a function which accepts a va_list. + +This function is exposed to the local_scan API; do not change the signature. +*/ /*XXX consider passing caller-info in, for string_vformat-onward */ void @@ -947,16 +952,13 @@ if (fl.rcpt_in_progress) /* Now write the string */ +if ( #ifndef DISABLE_TLS -if (tls_in.active.sock >= 0) - { - if (tls_write(NULL, gs.s, gs.ptr, more) < 0) - smtp_write_error = -1; - } -else + tls_in.active.sock >= 0 ? (tls_write(NULL, gs.s, gs.ptr, more) < 0) : #endif - -if (fprintf(smtp_out, "%s", gs.s) < 0) smtp_write_error = -1; + (fwrite(gs.s, gs.ptr, 1, smtp_out) == 0) + ) + smtp_write_error = -1; } @@ -967,8 +969,7 @@ if (fprintf(smtp_out, "%s", gs.s) < 0) smtp_write_error = -1; /* This function isn't currently used within Exim (it detects errors when it tries to read the next SMTP input), but is available for use in local_scan(). -For non-TLS connections, it flushes the output and checks for errors. For -TLS-connections, it checks for a previously-detected TLS write error. +It flushes the output and checks for errors. Arguments: none Returns: 0 for no error; -1 after an error @@ -978,6 +979,15 @@ int smtp_fflush(void) { if (tls_in.active.sock < 0 && fflush(smtp_out) != 0) smtp_write_error = -1; + +if ( +#ifndef DISABLE_TLS + tls_in.active.sock >= 0 ? (tls_write(NULL, NULL, 0, FALSE) < 0) : +#endif + (fflush(smtp_out) != 0) + ) + smtp_write_error = -1; + return smtp_write_error; } @@ -2082,6 +2092,7 @@ dmarc_used_domain = NULL; #endif #ifdef EXPERIMENTAL_ARC arc_state = arc_state_reason = NULL; +arc_received_instance = 0; #endif dsn_ret = 0; dsn_envid = NULL; @@ -2395,24 +2406,47 @@ return FALSE; static void tfo_in_check(void) { -# ifdef TCP_INFO +# ifdef __FreeBSD__ +int is_fastopen; +socklen_t len = sizeof(is_fastopen); + +/* The tinfo TCPOPT_FAST_OPEN bit seems unreliable, and we don't see state +TCP_SYN_RCV (as of 12.1) so no idea about data-use. */ + +if (getsockopt(fileno(smtp_out), IPPROTO_TCP, TCP_FASTOPEN, &is_fastopen, &len) == 0) + { + if (is_fastopen) + { + DEBUG(D_receive) + debug_printf("TFO mode connection (TCP_FASTOPEN getsockopt)\n"); + f.tcp_in_fastopen = TRUE; + } + } +else DEBUG(D_receive) + debug_printf("TCP_INFO getsockopt: %s\n", strerror(errno)); + +# elif defined(TCP_INFO) struct tcp_info tinfo; socklen_t len = sizeof(tinfo); if (getsockopt(fileno(smtp_out), IPPROTO_TCP, TCP_INFO, &tinfo, &len) == 0) -#ifdef TCPI_OPT_SYN_DATA /* FreeBSD 11 does not seem to have this yet */ +# ifdef TCPI_OPT_SYN_DATA /* FreeBSD 11,12 do not seem to have this yet */ if (tinfo.tcpi_options & TCPI_OPT_SYN_DATA) { - DEBUG(D_receive) debug_printf("TCP_FASTOPEN mode connection (ACKd data-on-SYN)\n"); + DEBUG(D_receive) + debug_printf("TFO mode connection (ACKd data-on-SYN)\n"); f.tcp_in_fastopen_data = f.tcp_in_fastopen = TRUE; } else -#endif - if (tinfo.tcpi_state == TCP_SYN_RECV) +# endif + if (tinfo.tcpi_state == TCP_SYN_RECV) /* Not seen on FreeBSD 12.1 */ { - DEBUG(D_receive) debug_printf("TCP_FASTOPEN mode connection (state TCP_SYN_RECV)\n"); + DEBUG(D_receive) + debug_printf("TFO mode connection (state TCP_SYN_RECV)\n"); f.tcp_in_fastopen = TRUE; } +else DEBUG(D_receive) + debug_printf("TCP_INFO getsockopt: %s\n", strerror(errno)); # endif } #endif @@ -2466,7 +2500,7 @@ if (!host_checking && !f.sender_host_notsocket) authenticated_by = NULL; #ifndef DISABLE_TLS -tls_in.cipher = tls_in.peerdn = NULL; +tls_in.ver = tls_in.cipher = tls_in.peerdn = NULL; tls_in.ourcert = tls_in.peercert = NULL; tls_in.sni = NULL; tls_in.ocsp = OCSP_NOT_REQ; @@ -3030,7 +3064,7 @@ smtp_printf("%s", handshake arrived. If so we must have managed a TFO. */ #ifdef TCP_FASTOPEN -tfo_in_check(); +if (sender_host_address && !f.sender_host_notsocket) tfo_in_check(); #endif return TRUE; @@ -3714,60 +3748,60 @@ if (rc != OK) switch(rc) { case OK: - if (!au->set_id || set_id) /* Complete success */ - { - if (set_id) authenticated_id = string_copy_perm(set_id, TRUE); - sender_host_authenticated = au->name; - sender_host_auth_pubname = au->public_name; - authentication_failed = FALSE; - authenticated_fail_id = NULL; /* Impossible to already be set? */ - - received_protocol = - (sender_host_address ? protocols : protocols_local) - [pextend + pauthed + (tls_in.active.sock >= 0 ? pcrpted:0)]; - *s = *ss = US"235 Authentication succeeded"; - authenticated_by = au; - break; - } + if (!au->set_id || set_id) /* Complete success */ + { + if (set_id) authenticated_id = string_copy_perm(set_id, TRUE); + sender_host_authenticated = au->name; + sender_host_auth_pubname = au->public_name; + authentication_failed = FALSE; + authenticated_fail_id = NULL; /* Impossible to already be set? */ - /* Authentication succeeded, but we failed to expand the set_id string. - Treat this as a temporary error. */ + received_protocol = + (sender_host_address ? protocols : protocols_local) + [pextend + pauthed + (tls_in.active.sock >= 0 ? pcrpted:0)]; + *s = *ss = US"235 Authentication succeeded"; + authenticated_by = au; + break; + } - auth_defer_msg = expand_string_message; - /* Fall through */ + /* Authentication succeeded, but we failed to expand the set_id string. + Treat this as a temporary error. */ + + auth_defer_msg = expand_string_message; + /* Fall through */ case DEFER: - if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = string_sprintf("435 Unable to authenticate at present%s", - auth_defer_user_msg); - *ss = string_sprintf("435 Unable to authenticate at present%s: %s", - set_id, auth_defer_msg); - break; + if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); + *s = string_sprintf("435 Unable to authenticate at present%s", + auth_defer_user_msg); + *ss = string_sprintf("435 Unable to authenticate at present%s: %s", + set_id, auth_defer_msg); + break; case BAD64: - *s = *ss = US"501 Invalid base64 data"; - break; + *s = *ss = US"501 Invalid base64 data"; + break; case CANCELLED: - *s = *ss = US"501 Authentication cancelled"; - break; + *s = *ss = US"501 Authentication cancelled"; + break; case UNEXPECTED: - *s = *ss = US"553 Initial data not expected"; - break; + *s = *ss = US"553 Initial data not expected"; + break; case FAIL: - if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = US"535 Incorrect authentication data"; - *ss = string_sprintf("535 Incorrect authentication data%s", set_id); - break; + if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); + *s = US"535 Incorrect authentication data"; + *ss = string_sprintf("535 Incorrect authentication data%s", set_id); + break; default: - if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); - *s = US"435 Internal error"; - *ss = string_sprintf("435 Internal error%s: return %d from authentication " - "check", set_id, rc); - break; + if (set_id) authenticated_fail_id = string_copy_perm(set_id, TRUE); + *s = US"435 Internal error"; + *ss = string_sprintf("435 Internal error%s: return %d from authentication " + "check", set_id, rc); + break; } return rc; @@ -4374,8 +4408,8 @@ while (done <= 0) if (au->server) { DEBUG(D_auth+D_expand) debug_printf_indent( - "Evaluating advertise_condition for %s athenticator\n", - au->public_name); + "Evaluating advertise_condition for %s %s athenticator\n", + au->name, au->public_name); if ( !au->advertise_condition || expand_check_condition(au->advertise_condition, au->name, US"authenticator") @@ -5765,7 +5799,7 @@ while (done <= 0) } enq_end(etrn_serialize_key); - exim_underbar_exit(EXIT_SUCCESS); + exim_underbar_exit(EXIT_SUCCESS, US"etrn-serialize-interproc"); } /* Back in the top level SMTP process. Check that we started a subprocess