From: Jeremy Harris Date: Wed, 29 Aug 2018 18:10:41 +0000 (+0100) Subject: Refactor authenticators API to take an (opaque) smtp connection context X-Git-Url: https://git.exim.org/users/heiko/exim.git/commitdiff_plain/251b9eb4698f569864c35127ddb7c309b92ccecb Refactor authenticators API to take an (opaque) smtp connection context --- diff --git a/src/src/auths/README b/src/src/auths/README index 21b0cda92..0e0c09703 100644 --- a/src/src/auths/README +++ b/src/src/auths/README @@ -68,7 +68,7 @@ CLIENT AUTHENTICATION The third function performs authentication as a client. It receives a pointer to the instance block, and four further arguments: - The smtp_inblock item for the connection to the remote host. + The smtp_context item for the connection to the remote host. The normal command-reading timeout value. diff --git a/src/src/auths/cram_md5.c b/src/src/auths/cram_md5.c index b9607b194..8e4794ca6 100644 --- a/src/src/auths/cram_md5.c +++ b/src/src/auths/cram_md5.c @@ -52,8 +52,8 @@ auth_cram_md5_options_block auth_cram_md5_option_defaults = { /* Dummy values */ void auth_cram_md5_init(auth_instance *ablock) {} int auth_cram_md5_server(auth_instance *ablock, uschar *data) {return 0;} -int auth_cram_md5_client(auth_instance *ablock, smtp_inblock *inblock, - smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;} +int auth_cram_md5_client(auth_instance *ablock, void *sx, int timeout, + uschar *buffer, int buffsize) {return 0;} #else /*!MACRO_PREDEF*/ @@ -259,8 +259,7 @@ return auth_check_serv_cond(ablock); int auth_cram_md5_client( auth_instance *ablock, /* authenticator block */ - smtp_inblock *inblock, /* input connection */ - smtp_outblock *outblock, /* output connection */ + void * sx, /* smtp connextion */ int timeout, /* command timeout */ uschar *buffer, /* for reading response */ int buffsize) /* size of buffer */ @@ -293,10 +292,9 @@ if (!secret || !name) /* Initiate the authentication exchange and read the challenge, which arrives in base 64. */ -if (smtp_write_command(outblock, SCMD_FLUSH, "AUTH %s\r\n", - ablock->public_name) < 0) +if (smtp_write_command(sx, SCMD_FLUSH, "AUTH %s\r\n", ablock->public_name) < 0) return FAIL_SEND; -if (!smtp_read_response(inblock, buffer, buffsize, '3', timeout)) +if (!smtp_read_response(sx, buffer, buffsize, '3', timeout)) return FAIL; if (b64decode(buffer + 4, &challenge) < 0) @@ -324,10 +322,10 @@ in big_buffer, but b64encode() returns its result in working store, so calling smtp_write_command(), which uses big_buffer, is OK. */ buffer[0] = 0; -if (smtp_write_command(outblock, SCMD_FLUSH, "%s\r\n", b64encode(big_buffer, +if (smtp_write_command(sx, SCMD_FLUSH, "%s\r\n", b64encode(big_buffer, p - big_buffer)) < 0) return FAIL_SEND; -return smtp_read_response(inblock, US buffer, buffsize, '2', timeout) +return smtp_read_response(sx, US buffer, buffsize, '2', timeout) ? OK : FAIL; } #endif /* STAND_ALONE */ diff --git a/src/src/auths/cram_md5.h b/src/src/auths/cram_md5.h index e1363bf05..95644db68 100644 --- a/src/src/auths/cram_md5.h +++ b/src/src/auths/cram_md5.h @@ -26,7 +26,6 @@ extern auth_cram_md5_options_block auth_cram_md5_option_defaults; extern void auth_cram_md5_init(auth_instance *); extern int auth_cram_md5_server(auth_instance *, uschar *); -extern int auth_cram_md5_client(auth_instance *, smtp_inblock *, - smtp_outblock *, int, uschar *, int); +extern int auth_cram_md5_client(auth_instance *, void *, int, uschar *, int); /* End of cram_md5.h */ diff --git a/src/src/auths/cyrus_sasl.c b/src/src/auths/cyrus_sasl.c index 7bb86b815..2cfed7a4b 100644 --- a/src/src/auths/cyrus_sasl.c +++ b/src/src/auths/cyrus_sasl.c @@ -68,8 +68,8 @@ auth_cyrus_sasl_options_block auth_cyrus_sasl_option_defaults = { /* Dummy values */ void auth_cyrus_sasl_init(auth_instance *ablock) {} int auth_cyrus_sasl_server(auth_instance *ablock, uschar *data) {return 0;} -int auth_cyrus_sasl_client(auth_instance *ablock, smtp_inblock *inblock, - smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;} +int auth_cyrus_sasl_client(auth_instance *ablock, void * sx, + int timeout, uschar *buffer, int buffsize) {return 0;} void auth_cyrus_sasl_version_report(FILE *f) {} #else /*!MACRO_PREDEF*/ @@ -529,8 +529,7 @@ auth_cyrus_sasl_version_report(FILE *f) int auth_cyrus_sasl_client( auth_instance *ablock, /* authenticator block */ - smtp_inblock *inblock, /* input connection */ - smtp_outblock *outblock, /* output connection */ + void * sx, /* connexction */ int timeout, /* command timeout */ uschar *buffer, /* for reading response */ int buffsize) /* size of buffer */ diff --git a/src/src/auths/cyrus_sasl.h b/src/src/auths/cyrus_sasl.h index 848105428..da6f3cd1b 100644 --- a/src/src/auths/cyrus_sasl.h +++ b/src/src/auths/cyrus_sasl.h @@ -29,8 +29,7 @@ extern auth_cyrus_sasl_options_block auth_cyrus_sasl_option_defaults; extern void auth_cyrus_sasl_init(auth_instance *); extern int auth_cyrus_sasl_server(auth_instance *, uschar *); -extern int auth_cyrus_sasl_client(auth_instance *, smtp_inblock *, - smtp_outblock *, int, uschar *, int); +extern int auth_cyrus_sasl_client(auth_instance *, void *, int, uschar *, int); extern void auth_cyrus_sasl_version_report(FILE *f); /* End of cyrus_sasl.h */ diff --git a/src/src/auths/dovecot.c b/src/src/auths/dovecot.c index 8c5b411de..b1dde06af 100644 --- a/src/src/auths/dovecot.c +++ b/src/src/auths/dovecot.c @@ -78,8 +78,8 @@ auth_dovecot_options_block auth_dovecot_option_defaults = { /* Dummy values */ void auth_dovecot_init(auth_instance *ablock) {} int auth_dovecot_server(auth_instance *ablock, uschar *data) {return 0;} -int auth_dovecot_client(auth_instance *ablock, smtp_inblock *inblock, - smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;} +int auth_dovecot_client(auth_instance *ablock, void * sx, + int timeout, uschar *buffer, int buffsize) {return 0;} #else /*!MACRO_PREDEF*/ diff --git a/src/src/auths/gsasl_exim.c b/src/src/auths/gsasl_exim.c index 6611de3f8..0e3a91619 100644 --- a/src/src/auths/gsasl_exim.c +++ b/src/src/auths/gsasl_exim.c @@ -84,8 +84,8 @@ auth_gsasl_options_block auth_gsasl_option_defaults = { /* Dummy values */ void auth_gsasl_init(auth_instance *ablock) {} int auth_gsasl_server(auth_instance *ablock, uschar *data) {return 0;} -int auth_gsasl_client(auth_instance *ablock, smtp_inblock *inblock, - smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;} +int auth_gsasl_client(auth_instance *ablock, void * sx, + int timeout, uschar *buffer, int buffsize) {return 0;} void auth_gsasl_version_report(FILE *f) {} #else /*!MACRO_PREDEF*/ @@ -588,8 +588,7 @@ server_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop, auth_insta int auth_gsasl_client( auth_instance *ablock, /* authenticator block */ - smtp_inblock *inblock, /* connection inblock */ - smtp_outblock *outblock, /* connection outblock */ + void * sx, /* connection */ int timeout, /* command timeout */ uschar *buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ diff --git a/src/src/auths/heimdal_gssapi.c b/src/src/auths/heimdal_gssapi.c index eafdccc5c..381898050 100644 --- a/src/src/auths/heimdal_gssapi.c +++ b/src/src/auths/heimdal_gssapi.c @@ -82,8 +82,8 @@ auth_heimdal_gssapi_options_block auth_heimdal_gssapi_option_defaults = { /* Dummy values */ void auth_heimdal_gssapi_init(auth_instance *ablock) {} int auth_heimdal_gssapi_server(auth_instance *ablock, uschar *data) {return 0;} -int auth_heimdal_gssapi_client(auth_instance *ablock, smtp_inblock *inblock, - smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;} +int auth_heimdal_gssapi_client(auth_instance *ablock, void * sx, + int timeout, uschar *buffer, int buffsize) {return 0;} void auth_heimdal_gssapi_version_report(FILE *f) {} #else /*!MACRO_PREDEF*/ @@ -578,8 +578,7 @@ exim_gssapi_error_defer(uschar *store_reset_point, int auth_heimdal_gssapi_client( auth_instance *ablock, /* authenticator block */ - smtp_inblock *inblock, /* connection inblock */ - smtp_outblock *outblock, /* connection outblock */ + void * sx, /* connection */ int timeout, /* command timeout */ uschar *buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ diff --git a/src/src/auths/plaintext.c b/src/src/auths/plaintext.c index bdd05699d..7a0f78852 100644 --- a/src/src/auths/plaintext.c +++ b/src/src/auths/plaintext.c @@ -40,8 +40,8 @@ auth_plaintext_options_block auth_plaintext_option_defaults = { /* Dummy values */ void auth_plaintext_init(auth_instance *ablock) {} int auth_plaintext_server(auth_instance *ablock, uschar *data) {return 0;} -int auth_plaintext_client(auth_instance *ablock, smtp_inblock *inblock, - smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;} +int auth_plaintext_client(auth_instance *ablock, void * sx, int timeout, + uschar *buffer, int buffsize) {return 0;} #else /*!MACRO_PREDEF*/ @@ -167,8 +167,7 @@ return auth_check_serv_cond(ablock); int auth_plaintext_client( auth_instance *ablock, /* authenticator block */ - smtp_inblock *inblock, /* connection inblock */ - smtp_outblock *outblock, /* connection outblock */ + void * sx, /* smtp connextion */ int timeout, /* command timeout */ uschar *buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ @@ -201,8 +200,8 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size))) uschar *ssave = string_copy(s); if (!first) { - if (smtp_write_command(outblock, SCMD_FLUSH, "*\r\n") >= 0) - (void) smtp_read_response(inblock, US buffer, buffsize, '2', timeout); + if (smtp_write_command(sx, SCMD_FLUSH, "*\r\n") >= 0) + (void) smtp_read_response(sx, US buffer, buffsize, '2', timeout); } if (f.expand_string_forcedfail) { @@ -236,15 +235,13 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size))) if (first) { first = FALSE; - if (smtp_write_command(outblock, SCMD_FLUSH, "AUTH %s%s%s\r\n", - ablock->public_name, (len == 0)? "" : " ", - b64encode(ss, len)) < 0) + if (smtp_write_command(sx, SCMD_FLUSH, "AUTH %s%s%s\r\n", + ablock->public_name, len == 0 ? "" : " ", b64encode(ss, len)) < 0) return FAIL_SEND; } else { - if (smtp_write_command(outblock, SCMD_FLUSH, "%s\r\n", - b64encode(ss, len)) < 0) + if (smtp_write_command(sx, SCMD_FLUSH, "%s\r\n", b64encode(ss, len)) < 0) return FAIL_SEND; } @@ -252,7 +249,7 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size))) has succeeded. There may be more data to send, but is there any point in provoking an error here? */ - if (smtp_read_response(inblock, US buffer, buffsize, '2', timeout)) return OK; + if (smtp_read_response(sx, US buffer, buffsize, '2', timeout)) return OK; /* Not a success response. If errno != 0 there is some kind of transmission error. Otherwise, check the response code in the buffer. If it starts with @@ -263,10 +260,10 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size))) /* If there is no more data to send, we have to cancel the authentication exchange and return ERROR. */ - if (text == NULL) + if (!text) { - if (smtp_write_command(outblock, SCMD_FLUSH, "*\r\n") >= 0) - (void)smtp_read_response(inblock, US buffer, buffsize, '2', timeout); + if (smtp_write_command(sx, SCMD_FLUSH, "*\r\n") >= 0) + (void)smtp_read_response(sx, US buffer, buffsize, '2', timeout); string_format(buffer, buffsize, "Too few items in client_send in %s " "authenticator", ablock->name); return ERROR; @@ -287,8 +284,8 @@ while ((s = string_nextinlist(&text, &sep, big_buffer, big_buffer_size))) uschar *save_bad = string_copy(buffer); if (!ob->client_ignore_invalid_base64) { - if (smtp_write_command(outblock, SCMD_FLUSH, "*\r\n") >= 0) - (void)smtp_read_response(inblock, US buffer, buffsize, '2', timeout); + if (smtp_write_command(sx, SCMD_FLUSH, "*\r\n") >= 0) + (void)smtp_read_response(sx, US buffer, buffsize, '2', timeout); string_format(buffer, buffsize, "Invalid base64 string in server " "response \"%s\"", save_bad); return CANCELLED; diff --git a/src/src/auths/plaintext.h b/src/src/auths/plaintext.h index 6cf3522c4..4c6d01136 100644 --- a/src/src/auths/plaintext.h +++ b/src/src/auths/plaintext.h @@ -26,7 +26,6 @@ extern auth_plaintext_options_block auth_plaintext_option_defaults; extern void auth_plaintext_init(auth_instance *); extern int auth_plaintext_server(auth_instance *, uschar *); -extern int auth_plaintext_client(auth_instance *, smtp_inblock *, - smtp_outblock *, int, uschar *, int); +extern int auth_plaintext_client(auth_instance *, void *, int, uschar *, int); /* End of plaintext.h */ diff --git a/src/src/auths/spa.c b/src/src/auths/spa.c index 50a4feab9..97e3b102c 100644 --- a/src/src/auths/spa.c +++ b/src/src/auths/spa.c @@ -76,8 +76,8 @@ auth_spa_options_block auth_spa_option_defaults = { /* Dummy values */ void auth_spa_init(auth_instance *ablock) {} int auth_spa_server(auth_instance *ablock, uschar *data) {return 0;} -int auth_spa_client(auth_instance *ablock, smtp_inblock *inblock, - smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;} +int auth_spa_client(auth_instance *ablock, void * sx, int timeout, + uschar *buffer, int buffsize) {return 0;} #else /*!MACRO_PREDEF*/ @@ -268,8 +268,7 @@ return FAIL; int auth_spa_client( auth_instance *ablock, /* authenticator block */ - smtp_inblock *inblock, /* connection inblock */ - smtp_outblock *outblock, /* connection outblock */ + void * sx, /* connection */ int timeout, /* command timeout */ uschar *buffer, /* buffer for reading response */ int buffsize) /* size of buffer */ @@ -306,7 +305,6 @@ if (!(password = CS expand_string(ob->spa_password))) } if (ob->spa_domain) - { if (!(domain = CS expand_string(ob->spa_domain))) { if (f.expand_string_forcedfail) return CANCELLED; @@ -315,16 +313,14 @@ if (ob->spa_domain) expand_string_message); return ERROR; } - } /* Original code */ -if (smtp_write_command(outblock, SCMD_FLUSH, "AUTH %s\r\n", - ablock->public_name) < 0) +if (smtp_write_command(sx, SCMD_FLUSH, "AUTH %s\r\n", ablock->public_name) < 0) return FAIL_SEND; /* wait for the 3XX OK message */ -if (!smtp_read_response(inblock, US buffer, buffsize, '3', timeout)) +if (!smtp_read_response(sx, US buffer, buffsize, '3', timeout)) return FAIL; DSPA("\n\n%s authenticator: using domain %s\n\n", ablock->name, domain); @@ -336,11 +332,11 @@ spa_bits_to_base64 (US msgbuf, (unsigned char*)&request, DSPA("\n\n%s authenticator: sending request (%s)\n\n", ablock->name, msgbuf); /* send the encrypted password */ -if (smtp_write_command(outblock, SCMD_FLUSH, "%s\r\n", msgbuf) < 0) +if (smtp_write_command(sx, SCMD_FLUSH, "%s\r\n", msgbuf) < 0) return FAIL_SEND; /* wait for the auth challenge */ -if (!smtp_read_response(inblock, US buffer, buffsize, '3', timeout)) +if (!smtp_read_response(sx, US buffer, buffsize, '3', timeout)) return FAIL; /* convert the challenge into the challenge struct */ @@ -353,14 +349,14 @@ spa_bits_to_base64 (US msgbuf, (unsigned char*)&response, DSPA("\n\n%s authenticator: challenge response (%s)\n\n", ablock->name, msgbuf); /* send the challenge response */ -if (smtp_write_command(outblock, SCMD_FLUSH, "%s\r\n", msgbuf) < 0) +if (smtp_write_command(sx, SCMD_FLUSH, "%s\r\n", msgbuf) < 0) return FAIL_SEND; /* If we receive a success response from the server, authentication has succeeded. There may be more data to send, but is there any point in provoking an error here? */ -if (smtp_read_response(inblock, US buffer, buffsize, '2', timeout)) +if (smtp_read_response(sx, US buffer, buffsize, '2', timeout)) return OK; /* Not a success response. If errno != 0 there is some kind of transmission diff --git a/src/src/auths/spa.h b/src/src/auths/spa.h index c140fe57a..ca93469a3 100644 --- a/src/src/auths/spa.h +++ b/src/src/auths/spa.h @@ -33,7 +33,6 @@ extern auth_spa_options_block auth_spa_option_defaults; extern void auth_spa_init(auth_instance *); extern int auth_spa_server(auth_instance *, uschar *); -extern int auth_spa_client(auth_instance *, smtp_inblock *, - smtp_outblock *, int, uschar *, int); +extern int auth_spa_client(auth_instance *, void *, int, uschar *, int); /* End of spa.h */ diff --git a/src/src/auths/tls.c b/src/src/auths/tls.c index 2d0d8de5e..56f5f5e92 100644 --- a/src/src/auths/tls.c +++ b/src/src/auths/tls.c @@ -45,8 +45,8 @@ auth_tls_options_block auth_tls_option_defaults = { /* Dummy values */ void auth_tls_init(auth_instance *ablock) {} int auth_tls_server(auth_instance *ablock, uschar *data) {return 0;} -int auth_tls_client(auth_instance *ablock, smtp_inblock *inblock, - smtp_outblock *outblock, int timeout, uschar *buffer, int buffsize) {return 0;} +int auth_tls_client(auth_instance *ablock, void * sx, + int timeout, uschar *buffer, int buffsize) {return 0;} #else /*!MACRO_PREDEF*/ diff --git a/src/src/functions.h b/src/src/functions.h index 58cab8238..920f3d96f 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -452,7 +452,7 @@ extern int smtp_handle_acl_fail(int, int, uschar *, uschar *); extern void smtp_log_no_mail(void); extern void smtp_message_code(uschar **, int *, uschar **, uschar **, BOOL); extern void smtp_proxy_tls(void *, uschar *, size_t, int *, int); -extern BOOL smtp_read_response(smtp_inblock *, uschar *, int, int, int); +extern BOOL smtp_read_response(void *, uschar *, int, int, int); extern void smtp_reset(void *); extern void smtp_respond(uschar *, int, BOOL, uschar *); extern void smtp_notquit_exit(uschar *, uschar *, uschar *, ...); @@ -462,7 +462,7 @@ extern int smtp_setup_msg(void); extern BOOL smtp_start_session(void); extern int smtp_ungetc(int); extern BOOL smtp_verify_helo(void); -extern int smtp_write_command(smtp_outblock *, int, const char *, ...) PRINTF_FUNCTION(3,4); +extern int smtp_write_command(void *, int, const char *, ...) PRINTF_FUNCTION(3,4); #ifdef WITH_CONTENT_SCAN extern int spam(const uschar **); extern FILE *spool_mbox(unsigned long *, const uschar *, uschar **); diff --git a/src/src/smtp_out.c b/src/src/smtp_out.c index 31e9a36f1..6fd0bf729 100644 --- a/src/src/smtp_out.c +++ b/src/src/smtp_out.c @@ -444,7 +444,7 @@ return TRUE; any error message. Arguments: - outblock contains buffer for pipelining, and socket + sx SMTP connection, contains buffer for pipelining, and socket mode buffer, write-with-more-likely, write format a format, starting with one of of HELO, MAIL FROM, RCPT TO, DATA, ".", or QUIT. @@ -457,8 +457,9 @@ Returns: 0 if command added to pipelining buffer, with nothing transmitted */ int -smtp_write_command(smtp_outblock * outblock, int mode, const char *format, ...) +smtp_write_command(void * sx, int mode, const char *format, ...) { +smtp_outblock * outblock = &((smtp_context *)sx)->outblock; int count; int rc = 0; va_list ap; @@ -623,7 +624,8 @@ also returned after a reading error. In this case buffer[0] will be zero, and the error code will be in errno. Arguments: - inblock the SMTP input block (contains holding buffer, socket, etc.) + sx the SMTP connection (contains input block with holding buffer, + socket, etc.) buffer where to put the response size the size of the buffer okdigit the expected first digit of the response @@ -633,9 +635,10 @@ Returns: TRUE if a valid, non-error response was received; else FALSE */ BOOL -smtp_read_response(smtp_inblock *inblock, uschar *buffer, int size, int okdigit, +smtp_read_response(void * sx, uschar *buffer, int size, int okdigit, int timeout) { +smtp_inblock * inblock = &((smtp_context *)sx)->inblock; uschar *ptr = buffer; int count; diff --git a/src/src/structs.h b/src/src/structs.h index bec2b2aa0..b1df408be 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -420,8 +420,7 @@ typedef struct auth_info { uschar *); /* rest of AUTH command */ int (*clientcode)( /* client function */ struct auth_instance *, - struct smtp_inblock *, /* socket and input buffer */ - struct smtp_outblock *, /* socket and output buffer */ + void *, /* smtp conn, with socket, output and input buffers */ int, /* command timeout */ uschar *, /* buffer for reading response */ int); /* sizeof buffer */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index fb8e17ea8..076375158 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -797,7 +797,7 @@ 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"); @@ -813,7 +813,7 @@ if (sx->pending_MAIL) } 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; @@ -848,7 +848,7 @@ while (count-- > 0) addr->host_used = sx->host; DEBUG(D_transport) debug_printf("%s expect rcpt\n", __FUNCTION__); - 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)) { yield |= 1; @@ -968,7 +968,7 @@ previously or in this block, the response is ignored. */ if (pending_DATA != 0) { DEBUG(D_transport) debug_printf("%s expect data\n", __FUNCTION__); - if (!smtp_read_response(&sx->inblock, sx->buffer, sizeof(sx->buffer), + if (!smtp_read_response(sx, sx->buffer, sizeof(sx->buffer), '3', ob->command_timeout)) { int code; @@ -1001,11 +1001,8 @@ return yield; /* 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 @@ -1016,23 +1013,22 @@ Returns: 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"; 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(&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 */ @@ -1041,7 +1037,7 @@ if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1)) regex match above. */ if (require_auth == OK || - verify_check_given_host(&ob->hosts_try_auth, host) == OK) + verify_check_given_host(&ob->hosts_try_auth, sx->host) == OK) { auth_instance *au; fail_reason = US"no common mechanisms were found"; @@ -1089,10 +1085,10 @@ if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1)) 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); @@ -1120,7 +1116,7 @@ if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1)) 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 @@ -1132,14 +1128,14 @@ if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1)) 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; } @@ -1154,7 +1150,7 @@ if (is_esmtp && regex_match_and_setup(regex_AUTH, buffer, 0, -1)) 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; @@ -1436,7 +1432,7 @@ there may be more writes (like, the chunk data) done soon. */ 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; @@ -1479,7 +1475,7 @@ if (sx->pending_BDAT) { 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') @@ -1729,7 +1725,7 @@ if (!continue_hostname) #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); @@ -1819,11 +1815,11 @@ goto SEND_QUIT; 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) @@ -1852,10 +1848,9 @@ goto SEND_QUIT; 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 @@ -1955,7 +1950,7 @@ if ( smtp_peer_options & OPTION_TLS ) ) { 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 @@ -1965,7 +1960,7 @@ if ( smtp_peer_options & OPTION_TLS 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 @@ -2060,7 +2055,7 @@ if (tls_out.active.sock >= 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); @@ -2077,10 +2072,10 @@ if (tls_out.active.sock >= 0) 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); @@ -2209,8 +2204,7 @@ if (continue_hostname == NULL 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; @@ -2373,7 +2367,7 @@ FAILED: 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) @@ -2611,7 +2605,7 @@ sx->pending_MAIL = TRUE; /* The block starts with MAIL */ } #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); } @@ -2623,7 +2617,7 @@ switch(rc) 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') @@ -2695,7 +2689,7 @@ for (addr = sx->first_addr, address_count = 0; } #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; @@ -3033,7 +3027,7 @@ to send is. */ 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)) @@ -3196,7 +3190,7 @@ else * 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]) { @@ -3217,7 +3211,7 @@ else 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') { @@ -3281,7 +3275,7 @@ else 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; @@ -3363,7 +3357,7 @@ else /* 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) { @@ -3599,13 +3593,13 @@ if (sx.completed_addr && sx.ok && sx.send_quit) 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; @@ -3652,9 +3646,9 @@ if (sx.completed_addr && sx.ok && sx.send_quit) 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 && f.continue_more) @@ -3757,7 +3751,7 @@ This change is being made on 31-Jul-98. After over a year of trouble-free 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: @@ -3821,8 +3815,7 @@ smtp_transport_closedown(transport_instance *tblock) 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]; @@ -3831,22 +3824,21 @@ 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); } diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index 7127fe31f..3219b05a9 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -182,9 +182,6 @@ extern void smtp_transport_closedown(transport_instance *); -extern int smtp_auth(uschar *, unsigned, address_item *, host_item *, - smtp_transport_options_block *, BOOL, - smtp_inblock *, smtp_outblock *); extern BOOL smtp_mail_auth_str(uschar *, unsigned, address_item *, smtp_transport_options_block *); diff --git a/src/src/verify.c b/src/src/verify.c index 7d46c3590..8d31f5d8e 100644 --- a/src/src/verify.c +++ b/src/src/verify.c @@ -14,7 +14,7 @@ caching was contributed by Kevin Fleming (but I hacked it around a bit). */ #define CUTTHROUGH_CMD_TIMEOUT 30 /* timeout for cutthrough-routing calls */ #define CUTTHROUGH_DATA_TIMEOUT 60 /* timeout for cutthrough-routing calls */ -static smtp_outblock ctblock; +static smtp_context ctctx; uschar ctbuffer[8192]; @@ -409,7 +409,7 @@ if (addr->transport == cutthrough.addr.transport) /* Match! Send the RCPT TO, set done from the response */ done = - smtp_write_command(&ctblock, SCMD_FLUSH, "RCPT TO:<%.1000s>\r\n", + smtp_write_command(&ctctx, SCMD_FLUSH, "RCPT TO:<%.1000s>\r\n", transport_rcpt_address(addr, addr->transport->rcpt_include_affixes)) >= 0 && cutthrough_response(&cutthrough.cctx, '2', &resp, @@ -814,9 +814,8 @@ tls_retry_connection: XXX We don't care about that for postmaster_full. Should we? */ if ((done = - smtp_write_command(&sx.outblock, SCMD_FLUSH, "RSET\r\n") >= 0 && - smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer), - '2', callout))) + smtp_write_command(&sx, SCMD_FLUSH, "RSET\r\n") >= 0 && + smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2', callout))) break; HDEBUG(D_acl|D_v) @@ -911,9 +910,8 @@ tls_retry_connection: cancel_cutthrough_connection(TRUE, US"postmaster verify"); HDEBUG(D_acl|D_v) debug_printf_indent("Cutthrough cancelled by presence of postmaster verify\n"); - done = smtp_write_command(&sx.outblock, SCMD_FLUSH, "RSET\r\n") >= 0 - && smtp_read_response(&sx.inblock, sx.buffer, - sizeof(sx.buffer), '2', callout); + done = smtp_write_command(&sx, SCMD_FLUSH, "RSET\r\n") >= 0 + && smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2', callout); if (done) { @@ -936,9 +934,9 @@ tls_retry_connection: done = TRUE; else done = (options & vopt_callout_fullpm) != 0 - && smtp_write_command(&sx.outblock, SCMD_FLUSH, + && smtp_write_command(&sx, SCMD_FLUSH, "RCPT TO:\r\n") >= 0 - && smtp_read_response(&sx.inblock, sx.buffer, + && smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2', callout); /* Sort out the cache record */ @@ -1104,11 +1102,11 @@ no_conn: caddr = caddr->parent, parent = parent->parent) *(caddr->parent = store_get(sizeof(address_item))) = *parent; - ctblock.buffer = ctbuffer; - ctblock.buffersize = sizeof(ctbuffer); - ctblock.ptr = ctbuffer; - /* ctblock.cmd_count = 0; ctblock.authenticating = FALSE; */ - ctblock.cctx = &cutthrough.cctx; + ctctx.outblock.buffer = ctbuffer; + ctctx.outblock.buffersize = sizeof(ctbuffer); + ctctx.outblock.ptr = ctbuffer; + /* ctctx.outblock.cmd_count = 0; ctctx.outblock.authenticating = FALSE; */ + ctctx.outblock.cctx = &cutthrough.cctx; } else { @@ -1117,11 +1115,10 @@ no_conn: cancel_cutthrough_connection(TRUE, US"not usable for cutthrough"); 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"); /* Wait a short time for response, and discard it */ - smtp_read_response(&sx.inblock, sx.buffer, sizeof(sx.buffer), - '2', 1); + smtp_read_response(&sx, sx.buffer, sizeof(sx.buffer), '2', 1); } if (sx.cctx.sock >= 0) @@ -1234,14 +1231,14 @@ if(cutthrough.cctx.sock < 0) if( #ifdef SUPPORT_TLS cutthrough.is_tls - ? tls_write(cutthrough.cctx.tls_ctx, ctblock.buffer, n, FALSE) + ? tls_write(cutthrough.cctx.tls_ctx, ctctx.outblock.buffer, n, FALSE) : #endif - send(cutthrough.cctx.sock, ctblock.buffer, n, 0) > 0 + send(cutthrough.cctx.sock, ctctx.outblock.buffer, n, 0) > 0 ) { transport_count += n; - ctblock.ptr= ctblock.buffer; + ctctx.outblock.ptr= ctctx.outblock.buffer; return TRUE; } @@ -1256,11 +1253,11 @@ _cutthrough_puts(uschar * cp, int n) { while(n--) { - if(ctblock.ptr >= ctblock.buffer+ctblock.buffersize) - if(!cutthrough_send(ctblock.buffersize)) + if(ctctx.outblock.ptr >= ctctx.outblock.buffer+ctctx.outblock.buffersize) + if(!cutthrough_send(ctctx.outblock.buffersize)) return FALSE; - *ctblock.ptr++ = *cp++; + *ctctx.outblock.ptr++ = *cp++; } return TRUE; } @@ -1286,7 +1283,7 @@ return; static BOOL _cutthrough_flush_send(void) { -int n = ctblock.ptr - ctblock.buffer; +int n = ctctx.outblock.ptr - ctctx.outblock.buffer; if(n>0) if(!cutthrough_send(n)) @@ -1323,16 +1320,16 @@ cutthrough_data_puts(US"\r\n", 2); static uschar cutthrough_response(client_conn_ctx * cctx, char expect, uschar ** copy, int timeout) { -smtp_inblock inblock; +smtp_context sx; uschar inbuffer[4096]; uschar responsebuffer[4096]; -inblock.buffer = inbuffer; -inblock.buffersize = sizeof(inbuffer); -inblock.ptr = inbuffer; -inblock.ptrend = inbuffer; -inblock.cctx = cctx; -if(!smtp_read_response(&inblock, responsebuffer, sizeof(responsebuffer), expect, timeout)) +sx.inblock.buffer = inbuffer; +sx.inblock.buffersize = sizeof(inbuffer); +sx.inblock.ptr = inbuffer; +sx.inblock.ptrend = inbuffer; +sx.inblock.cctx = cctx; +if(!smtp_read_response(&sx, responsebuffer, sizeof(responsebuffer), expect, timeout)) cancel_cutthrough_connection(TRUE, US"target timeout on read"); if(copy) @@ -1423,7 +1420,7 @@ if(fd >= 0) conn before the final dot. */ client_conn_ctx tmp_ctx = cutthrough.cctx; - ctblock.ptr = ctbuffer; + ctctx.outblock.ptr = ctbuffer; HDEBUG(D_transport|D_acl|D_v) debug_printf_indent(" SMTP>> QUIT\n"); _cutthrough_puts(US"QUIT\r\n", 6); /* avoid recursion */ _cutthrough_flush_send(); @@ -1445,7 +1442,7 @@ if(fd >= 0) (void)close(fd); HDEBUG(D_acl) debug_printf_indent("----------- cutthrough shutdown (%s) ------------\n", why); } -ctblock.ptr = ctbuffer; +ctctx.outblock.ptr = ctbuffer; } void