* some popular mail services enforce SNI for TLSv1.3 clients, so send it * retry SSL_write on blocking socket if we're told to do so. Index: imap/src/osdep/unix/ssl_unix.c --- imap/src/osdep/unix/ssl_unix.c.orig +++ imap/src/osdep/unix/ssl_unix.c @@ -391,6 +391,7 @@ static char *ssl_start_work (SSLSTREAM *stream,char *h { BIO *bio; X509 *cert; + int ssl_err; unsigned long sl,tl; int minv, maxv; int masklow, maskhigh; @@ -465,7 +466,13 @@ static char *ssl_start_work (SSLSTREAM *stream,char *h SSL_set_connect_state (stream->con); if (SSL_in_init (stream->con)) SSL_total_renegotiations (stream->con); /* now negotiate SSL */ - if (SSL_write (stream->con,"",0) < 0) + do { + ssl_err = SSL_write (stream->con,"",0); + } while (ssl_err < 0 && + ((SSL_get_error(stream->con, ssl_err) == SSL_ERROR_SYSCALL && errno == EINTR) || + SSL_get_error(stream->con, ssl_err) == SSL_ERROR_WANT_READ || + SSL_get_error(stream->con, ssl_err) == SSL_ERROR_WANT_WRITE)); + if (ssl_err < 0) return ssl_last_error ? ssl_last_error : "SSL negotiation failed"; /* need to validate host names? */ cert = SSL_get_peer_certificate (stream->con); @@ -530,7 +537,7 @@ static char *ssl_validate_cert (X509 *cert,char *host) /* make sure have a certificate */ if (!cert) return "No certificate from server"; /* Method 1: locate CN */ -#ifndef OPENSSL_1_1_0 +#if !defined(OPENSSL_1_1_0) && !defined(LIBRESSL_VERSION_NUMBER) if (cert->name == NIL) ret = "No name in certificate"; else if ((s = strstr (cert->name,"/CN=")) != NIL) { @@ -579,7 +586,7 @@ static char *ssl_validate_cert (X509 *cert,char *host) } if (ret == NIL -#ifndef OPENSSL_1_1_0 +#if !defined(OPENSSL_1_1_0) && !defined(LIBRESSL_VERSION_NUMBER) && !cert->name #endif /* OPENSSL_1_1_0 */ && !X509_get_subject_name(cert))