From: Ken Hornstein Date: Tue, 3 Jan 2012 20:17:54 +0000 (-0500) Subject: Switch to using buffered I/O when doing TLS (but only for output). X-Git-Url: http://git.marmaro.de/?a=commitdiff_plain;h=096c67eb7451cd78ed1e74c5b2a0c07ceb5c69d9;p=mmh Switch to using buffered I/O when doing TLS (but only for output). --- diff --git a/mts/smtp/smtp.c b/mts/smtp/smtp.c index e7a64a0..8d3a233 100644 --- a/mts/smtp/smtp.c +++ b/mts/smtp/smtp.c @@ -116,6 +116,7 @@ static SSL_CTX *sslctx = NULL; static SSL *ssl = NULL; static BIO *sbior = NULL; static BIO *sbiow = NULL; +static BIO *io = NULL; #endif /* TLS_SUPPORT */ #if defined(CYRUS_SASL) || defined(TLS_SUPPORT) @@ -286,6 +287,8 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, */ if (tls) { + BIO *ssl_bio; + if (! EHLOset("STARTTLS")) { sm_end(NOTOK); return sm_ierror("SMTP server does not support TLS"); @@ -338,8 +341,36 @@ smtp_init (char *client, char *server, char *port, int watch, int verbose, } SSL_set_bio(ssl, sbior, sbiow); + SSL_set_connect_state(ssl); + + /* + * Set up a BIO to handle buffering for us + */ + + io = BIO_new(BIO_f_buffer()); + + if (! io) { + sm_end(NOTOK); + return sm_ierror("Unable to create a buffer BIO: %s", + ERR_error_string(ERR_get_error(), NULL)); + } - if (SSL_connect(ssl) < 1) { + ssl_bio = BIO_new(BIO_f_ssl()); + + if (! ssl_bio) { + sm_end(NOTOK); + return sm_ierror("Unable to create a SSL BIO: %s", + ERR_error_string(ERR_get_error(), NULL)); + } + + BIO_set_ssl(ssl_bio, ssl, BIO_CLOSE); + BIO_push(io, ssl_bio); + + /* + * Try doing the handshake now + */ + + if (BIO_do_handshake(io) < 1) { sm_end(NOTOK); return sm_ierror("Unable to negotiate SSL connection: %s", ERR_error_string(ERR_get_error(), NULL)); @@ -787,8 +818,8 @@ sm_end (int type) #ifdef TLS_SUPPORT if (tls_active) { - SSL_shutdown(ssl); - SSL_free(ssl); + BIO_ssl_shutdown(io); + BIO_free_all(io); } #endif /* TLS_SUPPORT */ @@ -1235,9 +1266,9 @@ sm_fwrite(char *buffer, int len) if (tls_active) { int ret; - ret = SSL_write(ssl, buffer, len); + ret = BIO_write(io, buffer, len); - if (SSL_get_error(ssl, ret) != SSL_ERROR_NONE) { + if (ret <= 0) { sm_ierror("TLS error during write: %s", ERR_error_string(ERR_get_error(), NULL)); return NOTOK; @@ -1316,6 +1347,12 @@ sm_fflush(void) } #endif /* CYRUS_SASL */ +#ifdef TLS_SUPPORT + if (tls_active) { + (void) BIO_flush(io); + } +#endif /* TLS_SUPPORT */ + fflush(sm_wfp); }