Hello, If built against GnuTLS with TLS 1.3 support (i.e. >= 3.6.5) lynx 2.8.9rel.1 will fail to work with hosts offering TLS 1.3, e.g. gmail.com:
--------------------------------- (sid)ametzler@argenau:/tmp/LXYNX/lynx-2.8.9rel.1$ SSL_CERT_FILE=/etc/ssl/certs/c a-certificates.crt lynx -cfg=/dev/null -lss=/dev/null -dump https://gmail.com/ Looking up gmail.com Making HTTPS connection to gmail.com Verified connection to gmail.com (cert=gmail.com) Certificate issued by: /C=US/O=Google Trust Services/CN=Google Internet Authority G3 Secure 256-bit TLS1.3 (ECDHE_RSA_AES_256_GCM_SHA384) HTTP connection Sending HTTP request. HTTP request sent; waiting for response. Alert!: Unexpected network read error; connection aborted. Can't Access `https://gmail.com/' Alert!: Unable to access document. lynx: Can't access startfile --------------------------------- This sems to be an instance of https://gitlab.com/gnutls/gnutls/issues/644#note_123363338 <quote> Sam Varshavchik: | With TLS 1.3, gnutls will return GNUTLS_E_AGAIN even if the underlying | transport socket is a blocking socket. I'm pretty sure that previously | GNUTLS_E_AGAIN was getting returned only with non-blocking sockets as | the underlying transport, when reading or writing to the socket came | back with EAGAIN. GNUTLS_E_AGAIN was, basically, a passthrough for | EAGAIN on the underlying socket. | | All existing code that uses blocking sockets most likely handles any -1 | return from gnutls_record_send(), gnutls_record_recv(), and | gnutls_handshake() as a fatal transport error. It doesn't know about | special meaning of GNUTLS_E_AGAIN, because it was only seen, up until | now, with non-blocking sockets. | | Existing code that uses non-blocking sockets is unlikely to be affected, | as it already understands GNUTLS_E_AGAIN. <unquote> https://www.gnutls.org/manual/html_node/Data-transfer-and-termination.html Attached patch seems to work in quick test. cu Andreas -- `What a good friend you are to him, Dr. Maturin. His other friends are so grateful to you.' `I sew his ears on from time to time, sure'
--- lynx-2.8.9rel.1.orig/src/tidy_tls.c +++ lynx-2.8.9rel.1/src/tidy_tls.c @@ -462,13 +462,25 @@ int SSL_read(SSL * ssl, void *buffer, in { int rc; - rc = (int) gnutls_record_recv(ssl->gnutls_state, buffer, (size_t) length); + do + { + rc = (int) gnutls_record_recv(ssl->gnutls_state, buffer, (size_t) length); + } + while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)); if (rc < 0 && gnutls_error_is_fatal(rc) == 0) { if (rc == GNUTLS_E_REHANDSHAKE) { (void) gnutls_handshake(ssl->gnutls_state); - gnutls_record_send(ssl->gnutls_state, ssl->sendbuffer, (size_t) ssl->bytes_sent); - rc = (int) gnutls_record_recv(ssl->gnutls_state, buffer, (size_t) length); + do + { + rc = (int) gnutls_record_send(ssl->gnutls_state, ssl->sendbuffer, (size_t) ssl->bytes_sent); + } + while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)); + do + { + rc = (int) gnutls_record_recv(ssl->gnutls_state, buffer, (size_t) length); + } + while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)); } } @@ -500,7 +512,11 @@ int SSL_write(SSL * ssl, const void *buf { int rc; - rc = (int) gnutls_record_send(ssl->gnutls_state, buffer, (size_t) length); + do + { + rc = (int) gnutls_record_send(ssl->gnutls_state, buffer, (size_t) length); + } + while ((rc == GNUTLS_E_AGAIN) || (rc == GNUTLS_E_INTERRUPTED)); ssl->last_error = rc; if (rc < 0) {
signature.asc
Description: PGP signature
_______________________________________________ Lynx-dev mailing list Lynx-dev@nongnu.org https://lists.nongnu.org/mailman/listinfo/lynx-dev