On 2020/04/30 16:43, Theo Buehler wrote: > procter reported to me yesterday that the last time that he could use > his GMail account with alpine was before the Hobart hackathon, i.e., > before the TLSv1.3 client was enabled. > > There are two problems: > > First, if you establish a TLSv1.3 connection to imap.gmail.com:993 > without SNI, it answers with a self-signed cert containing > > subject=/OU=No SNI provided; please fix your client./CN=invalid2.invalid > issuer=/OU=No SNI provided; please fix your client./CN=invalid2.invalid > > Unless you turn off certificate validation in the alpine config, the > connection will fail. The SNI hunk is taken from alpine 2.22 [1].
Yep we've seen that one with a few ports already :-) > Second, our TLSv1.3 stack tends to want more retries. alpine already > retries reads, but doesn't do it for writes. We verified that SSL_write > returns SSL_ERROR_WANT_WRITE. I did essentially the same thing we did > (and shortly after undid) for wget. > > > procter verified that the combination of these two fixes allows him to > use alpine with GMail imap and smtp again. > > I'm both surprised and a bit worried that it took so long for somebody > to report this. I'm not entirely surprised, console-based mail clients are often run directly on mail servers which tend to not get updated all that often. > An alternative would be to update to alpine 2.22, but I suspect that the > SSL_write issue is still present there, so the patch below would seem to > be the safer option. > > [1]: > https://repo.or.cz/alpine.git/blob/99948a254e2c2352547b962cbd1c23738e7af6b3:/imap/src/osdep/unix/ssl_unix.c#l446 OK. > Index: Makefile > =================================================================== > RCS file: /var/cvs/ports/mail/alpine/Makefile,v > retrieving revision 1.46 > diff -u -p -r1.46 Makefile > --- Makefile 20 Mar 2020 16:44:24 -0000 1.46 > +++ Makefile 29 Apr 2020 13:29:40 -0000 > @@ -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 > > Index: patches/patch-imap_src_osdep_unix_ssl_unix_c > =================================================================== > RCS file: patches/patch-imap_src_osdep_unix_ssl_unix_c > diff -N patches/patch-imap_src_osdep_unix_ssl_unix_c > --- /dev/null 1 Jan 1970 00:00:00 -0000 > +++ patches/patch-imap_src_osdep_unix_ssl_unix_c 30 Apr 2020 10:49:20 > -0000 > @@ -0,0 +1,57 @@ > +$OpenBSD$ > + > +Workarounds for GMail: > +* imap.gmail.com requires SNI for TLSv1.3 clients > +* retry the writes 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", >