diff --git a/lftp-4.9.2-tls-close.patch b/lftp-4.9.2-tls-close.patch new file mode 100644 index 0000000..6ae7fab --- /dev/null +++ b/lftp-4.9.2-tls-close.patch @@ -0,0 +1,204 @@ +commit 841fb0abfa8b84af5cb817a7b77006253e239aec +Author: Tomas Korbar +Date: Mon May 5 13:08:54 2025 +0200 + + Ensure proper closing of TLS connection + +diff --git a/src/buffer.cc b/src/buffer.cc +index 9ee6580..e54e20e 100644 +--- a/src/buffer.cc ++++ b/src/buffer.cc +@@ -491,23 +491,31 @@ int IOBuffer::Do() + if(Done() || Error()) + return STALL; + int res=0; ++ int remaining_size; + switch(mode) + { + case PUT: +- if(Size()==0) +- return STALL; +- res=Put_LL(buffer+buffer_ptr,Size()); +- if(res>0) +- { +- RateAdd(res); +- buffer_ptr+=res; +- event_time=now; +- if(eof) +- PutEOF_LL(); +- return MOVED; ++ remaining_size = Size(); ++ if (remaining_size > 0) { ++ res=Put_LL(buffer+buffer_ptr, remaining_size); ++ if (res <= 0) { ++ return STALL; ++ } ++ RateAdd(res); ++ buffer_ptr+=res; ++ event_time=now; ++ if (eof) { ++ /* We do not have to check for return value of PutEOF_LL here as ++ * We MOVED anyway and find out whether it was a success in next Do */ ++ PutEOF_LL(); ++ } ++ return MOVED; ++ } ++ if (eof && PutEOF_LL()) { ++ event_time=now; ++ return MOVED; + } + break; +- + case GET: + if(eof) + return STALL; +diff --git a/src/buffer_ssl.cc b/src/buffer_ssl.cc +index 9e701c2..6dd8680 100644 +--- a/src/buffer_ssl.cc ++++ b/src/buffer_ssl.cc +@@ -39,10 +39,11 @@ int IOBufferSSL::Do() + // nothing to write, but may need to do handshake + if(!ssl->handshake_done) + { +- if(Put_LL("",0)<0) +- return MOVED; +- if(ssl->handshake_done && eof) +- ssl->shutdown(); ++ if(Put_LL("",0)<0) ++ return MOVED; ++ } ++ if(ssl->handshake_done && eof && IOBufferSSL::PutEOF_LL()) { ++ return MOVED; + } + if(ssl->handshake_done && !eof) + return m; +@@ -103,8 +104,17 @@ int IOBufferSSL::Put_LL(const char *buf,int size) + + int IOBufferSSL::PutEOF_LL() + { +- if(Size()==0) +- ssl->shutdown(); ++ int res; ++ if(Size()==0) { ++ res = ssl->shutdown(); ++ if (res == ssl->RETRY) { ++ SetNotReady(ssl->fd,want_mask()); ++ return 1; ++ } else if (res == ssl->ERROR) { ++ SetError(ssl->error,ssl->fatal); ++ return -1; ++ } ++ } + return 0; + } + +diff --git a/src/buffer_ssl.h b/src/buffer_ssl.h +index d3cf7f0..8915066 100644 +--- a/src/buffer_ssl.h ++++ b/src/buffer_ssl.h +@@ -42,7 +42,7 @@ public: + IOBufferSSL(const Ref& s,dir_t m) : IOBuffer(m), ssl(s) {} + ~IOBufferSSL(); + int Do(); +- bool Done() { return IOBuffer::Done() && ssl->handshake_done; } ++ bool Done() { return IOBuffer::Done() && ssl->handshake_done && ssl->goodbye_done; } + }; + #endif + +diff --git a/src/lftp_ssl.cc b/src/lftp_ssl.cc +index 89421ee..2d8ef3d 100644 +--- a/src/lftp_ssl.cc ++++ b/src/lftp_ssl.cc +@@ -48,6 +48,7 @@ lftp_ssl_base::lftp_ssl_base(int fd1,handshake_mode_t m,const char *h) + { + fd=fd1; + handshake_done=false; ++ goodbye_done=false; + handshake_mode=m; + fatal=false; + cert_error=false; +@@ -350,10 +351,24 @@ void lftp_ssl_gnutls::load_keys() + Log::global->Format(9, "Loaded %d CRLs\n", res); + gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred); + } +-void lftp_ssl_gnutls::shutdown() ++/* Try to shutdown the tls connection, return 1 if needed to call again otherwise 0*/ ++int lftp_ssl_gnutls::shutdown() + { +- if(handshake_done) +- gnutls_bye(session,GNUTLS_SHUT_RDWR); // FIXME - E_AGAIN ++ int res; ++ if(handshake_done) { ++ res = gnutls_bye(session,GNUTLS_SHUT_RDWR); ++ if (res == GNUTLS_E_SUCCESS) { ++ goodbye_done = true; ++ return DONE; ++ } else if (res == GNUTLS_E_AGAIN || res == GNUTLS_E_INTERRUPTED) { ++ return RETRY; ++ } ++ fatal=check_fatal(res); ++ set_error("gnutls_bye",gnutls_strerror(res)); ++ return ERROR; ++ } ++ goodbye_done = true; ++ return DONE; + } + lftp_ssl_gnutls::~lftp_ssl_gnutls() + { +@@ -854,10 +869,23 @@ void lftp_ssl_openssl::load_keys() + } + } + } +-void lftp_ssl_openssl::shutdown() ++int lftp_ssl_openssl::shutdown() + { +- if(handshake_done) +- SSL_shutdown(ssl); ++ int res; ++ if(handshake_done) { ++ res = SSL_shutdown(ssl); ++ if (res == 1) { ++ goodbye_done = true; ++ return DONE; ++ } else if (res == 0) { ++ return RETRY; ++ } ++ fatal=check_fatal(res); ++ set_error("SSL_shutdown",strerror()); ++ return ERROR; ++ } ++ goodbye_done = true; ++ return DONE; + } + lftp_ssl_openssl::~lftp_ssl_openssl() + { +diff --git a/src/lftp_ssl.h b/src/lftp_ssl.h +index 87b92d4..9b2a615 100644 +--- a/src/lftp_ssl.h ++++ b/src/lftp_ssl.h +@@ -38,6 +38,7 @@ class lftp_ssl_base + { + public: + bool handshake_done; ++ bool goodbye_done; + int fd; + xstring_c hostname; + enum handshake_mode_t { CLIENT, SERVER } handshake_mode; +@@ -108,7 +109,7 @@ public: + bool want_out(); + void copy_sid(const lftp_ssl_gnutls *); + void load_keys(); +- void shutdown(); ++ int shutdown(); + }; + typedef lftp_ssl_gnutls lftp_ssl; + #elif USE_OPENSSL +@@ -144,7 +145,7 @@ public: + bool want_out(); + void copy_sid(const lftp_ssl_openssl *); + void load_keys(); +- void shutdown(); ++ int shutdown(); + }; + typedef lftp_ssl_openssl lftp_ssl; + #endif diff --git a/lftp.spec b/lftp.spec index 00068ee..83c6e9f 100644 --- a/lftp.spec +++ b/lftp.spec @@ -1,7 +1,7 @@ Summary: A sophisticated file transfer program Name: lftp Version: 4.9.2 -Release: 16%{?dist} +Release: 17%{?dist} License: GPL-3.0-or-later Source0: http://lftp.yar.ru/ftp/%{name}-%{version}.tar.xz URL: http://lftp.yar.ru/ @@ -19,6 +19,7 @@ Patch1: lftp-4.0.9-date_fmt.patch Patch2: lftp-4.9.2-cdefs.patch Patch3: lftp-4.9.2-gnutls-peers2.patch Patch4: lftp-4.9.2-fedora-c99.patch +Patch5: lftp-4.9.2-tls-close.patch %description LFTP is a sophisticated ftp/http file transfer program. Like bash, it has job @@ -36,6 +37,8 @@ reliability in mind. %patch 3 -p1 -b .gnutls-peers2 %patch 4 -p1 -b .fedora-c99 +%patch 5 -p1 -b .tls-close + # Avoid trying to re-run autoconf touch -r aclocal.m4 configure m4/needtrio.m4 @@ -97,6 +100,10 @@ rm -r $RPM_BUILD_ROOT%{_datadir}/lftp %{_datadir}/icons/hicolor/*/apps/* %changelog +* Tue May 06 2025 Tomas Korbar - 4.9.2-17 +- Ensure proper closing of TLS connection +- Resolves: RHEL-91005 + * Tue Oct 29 2024 Troy Dawson - 4.9.2-16 - Bump release for October 2024 mass rebuild: Resolves: RHEL-64018