Add workarounds to fix alpine with TLSv1.3
Servers enforcing that clients send an SNI become more common. Backport the mechanism for sending SNI from alpine 2.22. Our new TLSv1.3 stack requires more retries than the old one so retry SSL_write() if the API tells us to do so. Issue reported, fix tested and "ok" procter. ok jca sthen
This commit is contained in:
parent
63530a4cbf
commit
2776d09f08
@ -1,4 +1,4 @@
|
||||
# $OpenBSD: Makefile,v 1.46 2020/03/20 16:44:24 naddy Exp $
|
||||
# $OpenBSD: Makefile,v 1.47 2020/05/01 09:09:14 tb Exp $
|
||||
|
||||
# XXX consider moving to https://repo.or.cz/alpine.git
|
||||
|
||||
@ -28,7 +28,7 @@ PKGNAME-mailutil= mailutil-uw-${V}
|
||||
PKGNAME-pico= pico-${PICO_V}
|
||||
PKGNAME-pilot= pilot-${PILOT_V}
|
||||
|
||||
REVISION= 3
|
||||
REVISION= 4
|
||||
REVISION-pico= 20
|
||||
REVISION-pilot= 20
|
||||
|
||||
|
56
mail/alpine/patches/patch-imap_src_osdep_unix_ssl_unix_c
Normal file
56
mail/alpine/patches/patch-imap_src_osdep_unix_ssl_unix_c
Normal file
@ -0,0 +1,56 @@
|
||||
$OpenBSD: patch-imap_src_osdep_unix_ssl_unix_c,v 1.1 2020/05/01 09:09:14 tb Exp $
|
||||
|
||||
* some popular mail services enforce SNI for TLSv1.3 clients, so send it
|
||||
* retry SSL_write 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
|
||||
@@ -266,6 +266,7 @@ static char *ssl_start_work (SSLSTREAM *stream,char *h
|
||||
{
|
||||
BIO *bio;
|
||||
X509 *cert;
|
||||
+ int ssl_err;
|
||||
unsigned long sl,tl;
|
||||
char *s,*t,*err,tmp[MAILTMPLEN], buf[256];
|
||||
sslcertificatequery_t scq =
|
||||
@@ -313,12 +314,22 @@ static char *ssl_start_work (SSLSTREAM *stream,char *h
|
||||
/* create connection */
|
||||
if (!(stream->con = (SSL *) SSL_new (stream->context)))
|
||||
return "SSL connection failed";
|
||||
+ if (host && !SSL_set_tlsext_host_name(stream->con, host)) {
|
||||
+ return "Server Name Identification (SNI) failed";
|
||||
+ }
|
||||
bio = BIO_new_socket (stream->tcpstream->tcpsi,BIO_NOCLOSE);
|
||||
SSL_set_bio (stream->con,bio,bio);
|
||||
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 == -1 &&
|
||||
+ SSL_get_error(stream->con, ssl_err) == SSL_ERROR_SYSCALL && errno == EINTR) ||
|
||||
+ (ssl_err < 0 &&
|
||||
+ (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? */
|
||||
if (!(flags & NET_NOVALIDATECERT) &&
|
||||
@@ -626,7 +637,14 @@ long ssl_sout (SSLSTREAM *stream,char *string,unsigned
|
||||
/* until request satisfied */
|
||||
for (i = 0; size > 0; string += i,size -= i)
|
||||
/* write as much as we can */
|
||||
- if ((i = SSL_write (stream->con,string,(int) min (SSLBUFLEN,size))) < 0) {
|
||||
+ do {
|
||||
+ i = SSL_write (stream->con,string,(int) min (SSLBUFLEN,size));
|
||||
+ } while ((i == -1 &&
|
||||
+ SSL_get_error(stream->con, i) == SSL_ERROR_SYSCALL && errno == EINTR) ||
|
||||
+ (i < 0 &&
|
||||
+ (SSL_get_error(stream->con, i) == SSL_ERROR_WANT_READ ||
|
||||
+ SSL_get_error(stream->con, i) == SSL_ERROR_WANT_WRITE)));
|
||||
+ if (i < 0) {
|
||||
if (tcpdebug) {
|
||||
char tmp[MAILTMPLEN];
|
||||
sprintf (tmp,"SSL data write I/O error %d SSL error %d",
|
Loading…
Reference in New Issue
Block a user