{ "serialize_hosts", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, serialize_hosts) },
{ "size_addition", opt_int,
- (void *)offsetof(smtp_transport_options_block, size_addition) }
+ (void *)offsetof(smtp_transport_options_block, size_addition) },
#ifdef SUPPORT_SOCKS
- ,{ "socks_proxy", opt_stringptr,
- (void *)offsetof(smtp_transport_options_block, socks_proxy) }
+ { "socks_proxy", opt_stringptr,
+ (void *)offsetof(smtp_transport_options_block, socks_proxy) },
#endif
#ifdef SUPPORT_TLS
- ,{ "tls_certificate", opt_stringptr,
+ { "tls_certificate", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_certificate) },
{ "tls_crl", opt_stringptr,
(void *)offsetof(smtp_transport_options_block, tls_crl) },
if (sx->pending_MAIL)
{
+ DEBUG(D_transport) debug_printf("%s expect mail\n", __FUNCTION__);
count--;
- if (!smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer),
+ if (!smtp_read_response(sx, sx->buffer, sizeof(sx->buffer),
'2', ob->command_timeout))
{
DEBUG(D_transport) debug_printf("bad response for MAIL\n");
}
while (count-- > 0)
{
- if (!smtp_read_response(&sx->inblock, flushbuffer, sizeof(flushbuffer),
+ if (!smtp_read_response(sx, flushbuffer, sizeof(flushbuffer),
'2', ob->command_timeout)
&& (errno != 0 || flushbuffer[0] == 0))
break;
/* The address was accepted */
addr->host_used = sx->host;
- if (smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer),
+ DEBUG(D_transport) debug_printf("%s expect rcpt\n", __FUNCTION__);
+ if (smtp_read_response(sx, sx->buffer, sizeof(sx->buffer),
'2', ob->command_timeout))
{
yield |= 1;
/* Handle a response to DATA. If we have not had any good recipients, either
previously or in this block, the response is ignored. */
-if (pending_DATA != 0 &&
- !smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer),
- '3', ob->command_timeout))
+if (pending_DATA != 0)
{
- int code;
- uschar *msg;
- BOOL pass_message;
- if (pending_DATA > 0 || (yield & 1) != 0)
+ DEBUG(D_transport) debug_printf("%s expect data\n", __FUNCTION__);
+ if (!smtp_read_response(sx, sx->buffer, sizeof(sx->buffer),
+ '3', ob->command_timeout))
{
- if (errno == 0 && sx->buffer[0] == '4')
+ int code;
+ uschar *msg;
+ BOOL pass_message;
+ if (pending_DATA > 0 || (yield & 1) != 0)
{
- errno = ERRNO_DATA4XX;
- sx->first_addr->more_errno |= ((sx->buffer[1] - '0')*10 + sx->buffer[2] - '0') << 8;
+ if (errno == 0 && sx->buffer[0] == '4')
+ {
+ errno = ERRNO_DATA4XX;
+ sx->first_addr->more_errno |= ((sx->buffer[1] - '0')*10 + sx->buffer[2] - '0') << 8;
+ }
+ return -3;
}
- return -3;
+ (void)check_response(sx->host, &errno, 0, sx->buffer, &code, &msg, &pass_message);
+ DEBUG(D_transport) debug_printf("%s\nerror for DATA ignored: pipelining "
+ "is in use and there were no good recipients\n", msg);
}
- (void)check_response(sx->host, &errno, 0, sx->buffer, &code, &msg, &pass_message);
- DEBUG(D_transport) debug_printf("%s\nerror for DATA ignored: pipelining "
- "is in use and there were no good recipients\n", msg);
}
/* All responses read and handled; MAIL (if present) received 2xx and DATA (if
/* Do the client side of smtp-level authentication */
/*
Arguments:
+ sx smtp connection
buffer EHLO response from server (gets overwritten)
- addrlist chain of potential addresses to deliver
- host host to deliver to
- ob transport options
- ibp, obp comms channel control blocks
Returns:
OK Success, or failed (but not required): global "smtp_authenticated" set
FAIL - response
*/
-int
-smtp_auth(uschar *buffer, unsigned bufsize, address_item *addrlist, host_item *host,
- smtp_transport_options_block *ob, BOOL is_esmtp,
- smtp_inblock *ibp, smtp_outblock *obp)
+static int
+smtp_auth(smtp_context * sx, uschar * buffer, unsigned bufsize)
{
+smtp_transport_options_block * ob = sx->ob;
int require_auth;
uschar *fail_reason = US"server did not advertise AUTH support";
-smtp_authenticated = FALSE;
+f.smtp_authenticated = FALSE;
client_authenticator = client_authenticated_id = client_authenticated_sender = NULL;
-require_auth = verify_check_given_host(&ob->hosts_require_auth, host);
+require_auth = verify_check_given_host(CUSS &ob->hosts_require_auth, sx->host);
-if (is_esmtp && !regex_AUTH) regex_AUTH =
+if (sx->esmtp && !regex_AUTH) regex_AUTH =
regex_must_compile(US"\\n250[\\s\\-]AUTH\\s+([\\-\\w\\s]+)(?:\\n|$)",
FALSE, TRUE);
-if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1))
+if (sx->esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1))
{
uschar *names = string_copyn(expand_nstring[1], expand_nlength[1]);
expand_nmax = -1; /* reset */
regex match above. */
if (require_auth == OK ||
- verify_check_given_host(&ob->hosts_try_auth, host) == OK)
+ verify_check_given_host(CUSS &ob->hosts_try_auth, sx->host) == OK)
{
auth_instance *au;
fail_reason = US"no common mechanisms were found";
If one is found, attempt to authenticate by calling its client function.
*/
- for (au = auths; !smtp_authenticated && au; au = au->next)
+ for (au = auths; !f.smtp_authenticated && au; au = au->next)
{
uschar *p = names;
if (!au->client ||
that reflections don't show it. */
fail_reason = US"authentication attempt(s) failed";
- obp->authenticating = TRUE;
- rc = (au->info->clientcode)(au, ibp, obp,
+ sx->outblock.authenticating = TRUE;
+ rc = (au->info->clientcode)(au, sx,
ob->command_timeout, buffer, bufsize);
- obp->authenticating = FALSE;
+ sx->outblock.authenticating = FALSE;
DEBUG(D_transport) debug_printf("%s authenticator yielded %d\n",
au->name, rc);
switch(rc)
{
case OK:
- smtp_authenticated = TRUE; /* stops the outer loop */
+ f.smtp_authenticated = TRUE; /* stops the outer loop */
client_authenticator = au->name;
if (au->set_client_id != NULL)
client_authenticated_id = expand_string(au->set_client_id);
case FAIL:
if (errno != 0 || buffer[0] != '5') return FAIL;
log_write(0, LOG_MAIN, "%s authenticator failed H=%s [%s] %s",
- au->name, host->name, host->address, buffer);
+ au->name, sx->host->name, sx->host->address, buffer);
break;
/* Failure by some other means. In effect, the authenticator
case CANCELLED:
if (*buffer != 0)
log_write(0, LOG_MAIN, "%s authenticator cancelled "
- "authentication H=%s [%s] %s", au->name, host->name,
- host->address, buffer);
+ "authentication H=%s [%s] %s", au->name, sx->host->name,
+ sx->host->address, buffer);
break;
/* Internal problem, message in buffer. */
case ERROR:
- set_errno_nohost(addrlist, ERRNO_AUTHPROB, string_copy(buffer),
+ set_errno_nohost(sx->addrlist, ERRNO_AUTHPROB, string_copy(buffer),
DEFER, FALSE);
return ERROR;
}
/* If we haven't authenticated, but are required to, give up. */
-if (require_auth == OK && !smtp_authenticated)
+if (require_auth == OK && !f.smtp_authenticated)
{
- set_errno_nohost(addrlist, ERRNO_AUTHFAIL,
+ set_errno_nohost(sx->addrlist, ERRNO_AUTHFAIL,
string_sprintf("authentication required but %s", fail_reason), DEFER,
FALSE);
return DEFER;
addrlist chain of potential addresses to deliver
ob transport options
-Globals smtp_authenticated
+Globals f.smtp_authenticated
client_authenticated_sender
Return True on error, otherwise buffer has (possibly empty) terminated string
*/
uschar *local_authenticated_sender = authenticated_sender;
#ifdef notdef
- debug_printf("smtp_mail_auth_str: as<%s> os<%s> SA<%s>\n", authenticated_sender, ob->authenticated_sender, smtp_authenticated?"Y":"N");
+ debug_printf("smtp_mail_auth_str: as<%s> os<%s> SA<%s>\n", authenticated_sender, ob->authenticated_sender, f.smtp_authenticated?"Y":"N");
#endif
if (ob->authenticated_sender != NULL)
uschar *new = expand_string(ob->authenticated_sender);
if (new == NULL)
{
- if (!expand_string_forcedfail)
+ if (!f.expand_string_forcedfail)
{
uschar *message = string_sprintf("failed to expand "
"authenticated_sender: %s", expand_string_message);
/* Add the authenticated sender address if present */
-if ((smtp_authenticated || ob->authenticated_sender_force) &&
+if ((f.smtp_authenticated || ob->authenticated_sender_force) &&
local_authenticated_sender != NULL)
{
string_format(buffer, bufsize, " AUTH=%s",
return DEFER; /* just defer this TLS'd conn */
case DNS_SUCCEED:
- if (sec) return OK;
+ if (sec)
+ {
+ DEBUG(D_transport)
+ {
+ dns_scan dnss;
+ dns_record * rr;
+ for (rr = dns_next_rr(dnsa, &dnss, RESET_ANSWERS); rr;
+ rr = dns_next_rr(dnsa, &dnss, RESET_NEXT)) if (rr->type == T_TLSA)
+ {
+ uint16_t payload_length = rr->size - 3;
+ uschar s[MAX_TLSA_EXPANDED_SIZE], * sp = s, * p = US rr->data;
+
+ sp += sprintf(CS sp, "%d ", *p++); /* usage */
+ sp += sprintf(CS sp, "%d ", *p++); /* selector */
+ sp += sprintf(CS sp, "%d ", *p++); /* matchtype */
+ while (payload_length-- > 0 && sp-s < (MAX_TLSA_EXPANDED_SIZE - 4))
+ sp += sprintf(CS sp, "%02x", *p++);
+
+ debug_printf(" %s\n", s);
+ }
+ }
+ return OK;
+ }
log_write(0, LOG_MAIN,
"DANE error: TLSA lookup for %s not DNSSEC", host->name);
/*FALLTRHOUGH*/
if (chunk_size > 0)
{
- if((cmd_count = smtp_write_command(&sx->outblock,
+ if((cmd_count = smtp_write_command(sx,
flags & tc_reap_prev ? SCMD_FLUSH : SCMD_MORE,
"BDAT %u%s\r\n", chunk_size, flags & tc_chunk_last ? " LAST" : "")
) < 0) return ERROR;
{
DEBUG(D_transport) debug_printf("look for one response for BDAT\n");
- if (!smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer), '2',
+ if (!smtp_read_response(sx, sx->buffer, sizeof(sx->buffer), '2',
ob->command_timeout))
{
if (errno == 0 && sx->buffer[0] == '4')
#if defined(SUPPORT_TLS) && defined(SUPPORT_DANE)
sx->dane = FALSE;
sx->dane_required =
- verify_check_given_host(&sx->ob->hosts_require_dane, sx->host) == OK;
+ verify_check_given_host(CUSS &sx->ob->hosts_require_dane, sx->host) == OK;
#endif
if ((sx->max_rcpt = sx->tblock->max_addresses) == 0) sx->max_rcpt = 999999;
if (sx->host->dnssec == DS_YES)
{
if( sx->dane_required
- || verify_check_given_host(&sx->ob->hosts_try_dane, sx->host) == OK
+ || verify_check_given_host(CUSS &sx->ob->hosts_try_dane, sx->host) == OK
)
switch (rc = tlsa_lookup(sx->host, &tlsa_dnsa, sx->dane_required))
{
#ifdef TCP_QUICKACK
(void) setsockopt(sx->cctx.sock, IPPROTO_TCP, TCP_QUICKACK, US &off, sizeof(off));
#endif
- good_response = smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer),
+ good_response = smtp_read_response(sx, sx->buffer, sizeof(sx->buffer),
'2', sx->ob->command_timeout);
#ifdef EXPERIMENTAL_DSN_INFO
sx->smtp_greeting = string_copy(sx->buffer);
mailers use upper case for some reason (the RFC is quite clear about case
independence) so, for peace of mind, I gave in. */
- sx->esmtp = verify_check_given_host(&sx->ob->hosts_avoid_esmtp, sx->host) != OK;
+ sx->esmtp = verify_check_given_host(CUSS &sx->ob->hosts_avoid_esmtp, sx->host) != OK;
/* Alas; be careful, since this goto is not an error-out, so conceivably
we might set data between here and the target which we assume to exist
if (sx->esmtp)
{
- if (smtp_write_command(&sx->outblock, SCMD_FLUSH, "%s %s\r\n",
+ if (smtp_write_command(sx, SCMD_FLUSH, "%s %s\r\n",
sx->lmtp ? "LHLO" : "EHLO", sx->helo_data) < 0)
goto SEND_FAILED;
sx->esmtp_sent = TRUE;
- if (!smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer), '2',
+ if (!smtp_read_response(sx, sx->buffer, sizeof(sx->buffer), '2',
sx->ob->command_timeout))
{
if (errno != 0 || sx->buffer[0] == 0 || sx->lmtp)
if (sx->esmtp_sent && (n = Ustrlen(sx->buffer)) < sizeof(sx->buffer)/2)
{ rsp = sx->buffer + n + 1; n = sizeof(sx->buffer) - n; }
- if (smtp_write_command(&sx->outblock, SCMD_FLUSH, "HELO %s\r\n", sx->helo_data) < 0)
+ if (smtp_write_command(sx, SCMD_FLUSH, "HELO %s\r\n", sx->helo_data) < 0)
goto SEND_FAILED;
- good_response = smtp_read_response(&sx->inblock, rsp, n,
- '2', sx->ob->command_timeout);
+ good_response = smtp_read_response(sx, rsp, n, '2', sx->ob->command_timeout);
#ifdef EXPERIMENTAL_DSN_INFO
sx->helo_response = string_copy(rsp);
#endif
)
{
sx->peer_offered = smtp_peer_options;
- pipelining_active = !!(smtp_peer_options & OPTION_PIPE);
+ sx->pipelining_used = pipelining_active = !!(smtp_peer_options & OPTION_PIPE);
HDEBUG(D_transport) debug_printf("continued connection, %s TLS\n",
continue_proxy_cipher ? "proxied" : "verify conn with");
return OK;
#ifdef SUPPORT_TLS
if ( smtp_peer_options & OPTION_TLS
&& !suppress_tls
- && verify_check_given_host(&sx->ob->hosts_avoid_tls, sx->host) != OK
+ && verify_check_given_host(CUSS &sx->ob->hosts_avoid_tls, sx->host) != OK
&& ( !sx->verify
- || verify_check_given_host(&sx->ob->hosts_verify_avoid_tls, sx->host) != OK
+ || verify_check_given_host(CUSS &sx->ob->hosts_verify_avoid_tls, sx->host) != OK
) )
{
uschar buffer2[4096];
- if (smtp_write_command(&sx->outblock, SCMD_FLUSH, "STARTTLS\r\n") < 0)
+ if (smtp_write_command(sx, SCMD_FLUSH, "STARTTLS\r\n") < 0)
goto SEND_FAILED;
/* If there is an I/O error, transmission of this message is deferred. If
STARTTLS, we carry on. This means we will try to send the message in clear,
unless the host is in hosts_require_tls (tested below). */
- if (!smtp_read_response(&sx->inblock, buffer2, sizeof(buffer2), '2',
+ if (!smtp_read_response(sx, buffer2, sizeof(buffer2), '2',
sx->ob->command_timeout))
{
if ( errno != 0
/* For SMTPS we need to wait for the initial OK response. */
if (sx->smtps)
{
- good_response = smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer),
+ good_response = smtp_read_response(sx, sx->buffer, sizeof(sx->buffer),
'2', sx->ob->command_timeout);
#ifdef EXPERIMENTAL_DSN_INFO
sx->smtp_greeting = string_copy(sx->buffer);
debug_printf("not sending EHLO (host matches hosts_avoid_esmtp)\n");
}
- if (smtp_write_command(&sx->outblock, SCMD_FLUSH, "%s %s\r\n",
+ if (smtp_write_command(sx, SCMD_FLUSH, "%s %s\r\n",
sx->lmtp ? "LHLO" : greeting_cmd, sx->helo_data) < 0)
goto SEND_FAILED;
- good_response = smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer),
+ good_response = smtp_read_response(sx, sx->buffer, sizeof(sx->buffer),
'2', sx->ob->command_timeout);
#ifdef EXPERIMENTAL_DSN_INFO
sx->helo_response = string_copy(sx->buffer);
# ifdef EXPERIMENTAL_REQUIRETLS
|| tls_requiretls & REQUIRETLS_MSG
# endif
- || verify_check_given_host(&sx->ob->hosts_require_tls, sx->host) == OK
+ || verify_check_given_host(CUSS &sx->ob->hosts_require_tls, sx->host) == OK
)
{
errno =
the current host matches hosts_avoid_pipelining, don't do it. */
if ( sx->peer_offered & OPTION_PIPE
- && verify_check_given_host(&sx->ob->hosts_avoid_pipelining, sx->host) != OK)
+ && verify_check_given_host(CUSS &sx->ob->hosts_avoid_pipelining, sx->host) != OK)
smtp_peer_options |= OPTION_PIPE;
DEBUG(D_transport) debug_printf("%susing PIPELINING\n",
smtp_peer_options & OPTION_PIPE ? "" : "not ");
if ( sx->peer_offered & OPTION_CHUNKING
- && verify_check_given_host(&sx->ob->hosts_try_chunking, sx->host) != OK)
+ && verify_check_given_host(CUSS &sx->ob->hosts_try_chunking, sx->host) != OK)
sx->peer_offered &= ~OPTION_CHUNKING;
if (sx->peer_offered & OPTION_CHUNKING)
#ifndef DISABLE_PRDR
if ( sx->peer_offered & OPTION_PRDR
- && verify_check_given_host(&sx->ob->hosts_try_prdr, sx->host) != OK)
+ && verify_check_given_host(CUSS &sx->ob->hosts_try_prdr, sx->host) != OK)
sx->peer_offered &= ~OPTION_PRDR;
if (sx->peer_offered & OPTION_PRDR)
the business. The host name and address must be available when the
authenticator's client driver is running. */
- switch (yield = smtp_auth(sx->buffer, sizeof(sx->buffer), sx->addrlist, sx->host,
- sx->ob, sx->esmtp, &sx->inblock, &sx->outblock))
+ switch (yield = smtp_auth(sx, sx->buffer, sizeof(sx->buffer)))
{
default: goto SEND_QUIT;
case OK: break;
}
}
}
-pipelining_active = !!(smtp_peer_options & OPTION_PIPE);
+sx->pipelining_used = pipelining_active = !!(smtp_peer_options & OPTION_PIPE);
/* The setting up of the SMTP call is now complete. Any subsequent errors are
message-specific. */
SEND_QUIT:
if (sx->send_quit)
- (void)smtp_write_command(&sx->outblock, SCMD_FLUSH, "QUIT\r\n");
+ (void)smtp_write_command(sx, SCMD_FLUSH, "QUIT\r\n");
#ifdef SUPPORT_TLS
if (sx->cctx.tls_ctx)
}
#endif
- rc = smtp_write_command(&sx->outblock, pipelining_active ? SCMD_BUFFER : SCMD_FLUSH,
+ rc = smtp_write_command(sx, pipelining_active ? SCMD_BUFFER : SCMD_FLUSH,
"MAIL FROM:<%s>%s\r\n", s, sx->buffer);
}
return -5;
case +1: /* Cmd was sent */
- if (!smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer), '2',
+ if (!smtp_read_response(sx, sx->buffer, sizeof(sx->buffer), '2',
sx->ob->command_timeout))
{
if (errno == 0 && sx->buffer[0] == '4')
BOOL no_flush;
uschar * rcpt_addr;
- if (tcp_out_fastopen && !tcp_out_fastopen_logged)
+ if (tcp_out_fastopen && !f.tcp_out_fastopen_logged)
{
setflag(addr, af_tcp_fastopen_conn);
if (tcp_out_fastopen > 1) setflag(addr, af_tcp_fastopen);
}
#endif
- count = smtp_write_command(&sx->outblock, no_flush ? SCMD_BUFFER : SCMD_FLUSH,
+ count = smtp_write_command(sx, no_flush ? SCMD_BUFFER : SCMD_FLUSH,
"RCPT TO:<%s>%s%s\r\n", rcpt_addr, sx->igquotstr, sx->buffer);
if (count < 0) return -5;
}
} /* Loop for next address */
-tcp_out_fastopen_logged = TRUE;
+f.tcp_out_fastopen_logged = TRUE;
sx->next_addr = addr;
return 0;
}
_exit(rc < 0 ? EXIT_FAILURE : EXIT_SUCCESS);
}
-if (running_in_test_harness) millisleep(100); /* let parent debug out */
+if (f.running_in_test_harness) millisleep(100); /* let parent debug out */
set_process_info("proxying TLS connection for continued transport");
FD_ZERO(&rfds);
FD_SET(tls_out.active.sock, &rfds);
}
done:
- if (running_in_test_harness) millisleep(100); /* let logging complete */
+ if (f.running_in_test_harness) millisleep(100); /* let logging complete */
exim_exit(0, US"TLS proxy");
}
#endif
if ( !(sx.peer_offered & OPTION_CHUNKING)
&& (sx.ok || (pipelining_active && !mua_wrapper)))
{
- int count = smtp_write_command(&sx.outblock, SCMD_FLUSH, "DATA\r\n");
+ int count = smtp_write_command(&sx, SCMD_FLUSH, "DATA\r\n");
if (count < 0) goto SEND_FAILED;
switch(sync_responses(&sx, count, sx.ok ? +1 : -1))
{
if (!(sx.ob->dkim.arc_signspec = s = expand_string(s)))
{
- if (!expand_string_forcedfail)
+ if (!f.expand_string_forcedfail)
{
message = US"failed to expand arc_sign";
sx.ok = FALSE;
* with per non-PRDR. */
if(sx.prdr_active)
{
- sx.ok = smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer), '3',
+ sx.ok = smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '3',
sx.ob->final_timeout);
if (!sx.ok && errno == 0) switch(sx.buffer[0])
{
if (!sx.lmtp)
{
- sx.ok = smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer), '2',
+ sx.ok = smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2',
sx.ob->final_timeout);
if (!sx.ok && errno == 0 && sx.buffer[0] == '4')
{
if (sx.lmtp)
#endif
{
- if (!smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer), '2',
+ if (!smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2',
sx.ob->final_timeout))
{
if (errno != 0 || sx.buffer[0] == 0) goto RESPONSE_FAILED;
addr->host_used = host;
addr->special_action = flag;
addr->message = conf;
+
+ if (sx.pipelining_used) setflag(addr, af_pipelining);
#ifndef DISABLE_PRDR
if (sx.prdr_active) setflag(addr, af_prdr_used);
#endif
/* PRDR - get the final, overall response. For any non-success
upgrade all the address statuses. */
- sx.ok = smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer), '2',
+ sx.ok = smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2',
sx.ob->final_timeout);
if (!sx.ok)
{
DEBUG(D_transport)
debug_printf("ok=%d send_quit=%d send_rset=%d continue_more=%d "
"yield=%d first_address is %sNULL\n", sx.ok, sx.send_quit,
- sx.send_rset, continue_more, yield, sx.first_addr ? "not " : "");
+ sx.send_rset, f.continue_more, yield, sx.first_addr ? "not " : "");
if (sx.completed_addr && sx.ok && sx.send_quit)
{
t_compare.current_sender_address = sender_address;
if ( sx.first_addr != NULL
- || continue_more
+ || f.continue_more
|| (
#ifdef SUPPORT_TLS
( tls_out.active.sock < 0 && !continue_proxy_cipher
- || verify_check_given_host(&sx.ob->hosts_nopass_tls, host) != OK
+ || verify_check_given_host(CUSS &sx.ob->hosts_nopass_tls, host) != OK
)
&&
#endif
BOOL pass_message;
if (sx.send_rset)
- if (! (sx.ok = smtp_write_command(&sx.outblock, SCMD_FLUSH, "RSET\r\n") >= 0))
+ if (! (sx.ok = smtp_write_command(&sx, SCMD_FLUSH, "RSET\r\n") >= 0))
{
msg = US string_sprintf("send() to %s [%s] failed: %s", host->name,
host->address, strerror(errno));
sx.send_quit = FALSE;
}
- else if (! (sx.ok = smtp_read_response(&sx.inblock, sx.buffer,
+ else if (! (sx.ok = smtp_read_response(&sx, sx.buffer,
sizeof(sx.buffer), '2', sx.ob->command_timeout)))
{
int code;
if (sx.ok)
{
+#ifdef SUPPORT_TLS
int pfd[2];
+#endif
int socket_fd = sx.cctx.sock;
#ifdef SUPPORT_TLS
if (tls_out.active.sock >= 0)
- if ( continue_more
- || verify_check_given_host(&sx.ob->hosts_noproxy_tls, host) == OK)
+ if ( f.continue_more
+ || verify_check_given_host(CUSS &sx.ob->hosts_noproxy_tls, host) == OK)
{
/* Before passing the socket on, or returning to caller with it still
open, we must shut down TLS. Not all MTAs allow for the continuation
sx.cctx.tls_ctx = NULL;
smtp_peer_options = smtp_peer_options_wrap;
sx.ok = !sx.smtps
- && smtp_write_command(&sx.outblock, SCMD_FLUSH,
- "EHLO %s\r\n", sx.helo_data) >= 0
- && smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer),
+ && smtp_write_command(&sx, SCMD_FLUSH, "EHLO %s\r\n", sx.helo_data)
+ >= 0
+ && smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer),
'2', sx.ob->command_timeout);
- if (sx.ok && continue_more)
+ if (sx.ok && f.continue_more)
return yield; /* More addresses for another run */
}
else
}
else
#endif
- if (continue_more)
+ if (f.continue_more)
return yield; /* More addresses for another run */
/* If the socket is successfully passed, we mustn't send QUIT (or
int pid = fork();
if (pid == 0) /* child; fork again to disconnect totally */
{
- if (running_in_test_harness) millisleep(100); /* let parent debug out */
+ if (f.running_in_test_harness) millisleep(100); /* let parent debug out */
/* does not return */
smtp_proxy_tls(sx.cctx.tls_ctx, sx.buffer, sizeof(sx.buffer), pfd,
sx.ob->command_timeout);
operation, the old commented-out code was removed on 17-Sep-99. */
SEND_QUIT:
-if (sx.send_quit) (void)smtp_write_command(&sx.outblock, SCMD_FLUSH, "QUIT\r\n");
+if (sx.send_quit) (void)smtp_write_command(&sx, SCMD_FLUSH, "QUIT\r\n");
END_OFF:
smtp_transport_options_block *ob =
(smtp_transport_options_block *)tblock->options_block;
client_conn_ctx cctx;
-smtp_inblock inblock;
-smtp_outblock outblock;
+smtp_context sx;
uschar buffer[256];
uschar inbuffer[4096];
uschar outbuffer[16];
cctx.sock = fileno(stdin);
cctx.tls_ctx = cctx.sock == tls_out.active.sock ? tls_out.active.tls_ctx : NULL;
-inblock.cctx = &cctx;
-inblock.buffer = inbuffer;
-inblock.buffersize = sizeof(inbuffer);
-inblock.ptr = inbuffer;
-inblock.ptrend = inbuffer;
-
-outblock.cctx = &cctx;
-outblock.buffersize = sizeof(outbuffer);
-outblock.buffer = outbuffer;
-outblock.ptr = outbuffer;
-outblock.cmd_count = 0;
-outblock.authenticating = FALSE;
-
-(void)smtp_write_command(&outblock, SCMD_FLUSH, "QUIT\r\n");
-(void)smtp_read_response(&inblock, buffer, sizeof(buffer), '2',
- ob->command_timeout);
+sx.inblock.cctx = &cctx;
+sx.inblock.buffer = inbuffer;
+sx.inblock.buffersize = sizeof(inbuffer);
+sx.inblock.ptr = inbuffer;
+sx.inblock.ptrend = inbuffer;
+
+sx.outblock.cctx = &cctx;
+sx.outblock.buffersize = sizeof(outbuffer);
+sx.outblock.buffer = outbuffer;
+sx.outblock.ptr = outbuffer;
+sx.outblock.cmd_count = 0;
+sx.outblock.authenticating = FALSE;
+
+(void)smtp_write_command(&sx, SCMD_FLUSH, "QUIT\r\n");
+(void)smtp_read_response(&sx, buffer, sizeof(buffer), '2', ob->command_timeout);
(void)close(cctx.sock);
}
{
addrlist->message = string_sprintf("failed to expand list of hosts "
"\"%s\" in %s transport: %s", s, tblock->name, expand_string_message);
- addrlist->transport_return = search_find_defer ? DEFER : PANIC;
+ addrlist->transport_return = f.search_find_defer ? DEFER : PANIC;
return FALSE; /* Only top address has status */
}
DEBUG(D_transport) debug_printf("expanded list of hosts \"%s\" to "
were not in it. We don't want to hold up all SMTP deliveries! Except when
doing a two-stage queue run, don't do this if forcing. */
- if ((!deliver_force || queue_2stage) && (queue_smtp ||
+ if ((!f.deliver_force || f.queue_2stage) && (f.queue_smtp ||
match_isinlist(addrlist->domain,
(const uschar **)&queue_smtp_domains, 0,
&domainlist_anchor, NULL, MCL_DOMAIN, TRUE, NULL) == OK))
sending the message down a pre-existing connection. */
if ( !continue_hostname
- && verify_check_given_host(&ob->serialize_hosts, host) == OK)
+ && verify_check_given_host(CUSS &ob->serialize_hosts, host) == OK)
{
serialize_key = string_sprintf("host-serialize-%s", host->name);
if (!enq_start(serialize_key, 1))
/* This is not for real; don't do the delivery. If there are
any remaining hosts, list them. */
- if (dont_deliver)
+ if (f.dont_deliver)
{
host_item *host2;
set_errno_nohost(addrlist, 0, NULL, OK, FALSE);
if ( rc == DEFER
&& first_addr->basic_errno == ERRNO_TLSFAILURE
&& ob->tls_tempfail_tryclear
- && verify_check_given_host(&ob->hosts_require_tls, host) != OK
+ && verify_check_given_host(CUSS &ob->hosts_require_tls, host) != OK
)
{
log_write(0, LOG_MAIN,
setflag(addr, af_retry_skipped);
}
- if (queue_smtp) /* no deliveries attempted */
+ if (f.queue_smtp) /* no deliveries attempted */
{
addr->transport_return = DEFER;
addr->basic_errno = 0;