diff --git a/.lftp.metadata b/.lftp.metadata new file mode 100644 index 0000000..88a2d64 --- /dev/null +++ b/.lftp.metadata @@ -0,0 +1 @@ +fa97429d4376c87dd0b6a9b27ed89184fb2a9149 SOURCES/lftp-4.8.4.tar.xz diff --git a/SOURCES/lftp-4.8.4-tls-close.patch b/SOURCES/lftp-4.8.4-tls-close.patch new file mode 100644 index 0000000..986b2ff --- /dev/null +++ b/SOURCES/lftp-4.8.4-tls-close.patch @@ -0,0 +1,204 @@ +commit 299a194cc86ea81c40d2146dd095dda3954efc81 +Author: Tomas Korbar +Date: Tue May 6 12:01:10 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 0a0078a..8820b6f 100644 +--- a/src/lftp_ssl.cc ++++ b/src/lftp_ssl.cc +@@ -45,6 +45,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; +@@ -347,10 +348,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() + { +@@ -849,10 +864,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 17a91b0..8e0cc85 100644 +--- a/src/lftp_ssl.h ++++ b/src/lftp_ssl.h +@@ -37,6 +37,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; +@@ -107,7 +108,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 +@@ -143,7 +144,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/SPECS/lftp.spec b/SPECS/lftp.spec index 1882f3e..42642e5 100644 --- a/SPECS/lftp.spec +++ b/SPECS/lftp.spec @@ -1,7 +1,7 @@ Summary: A sophisticated file transfer program Name: lftp Version: 4.8.4 -Release: 3%{?dist} +Release: 4%{?dist} License: GPLv3+ Group: Applications/Internet Source0: http://lftp.yar.ru/ftp/%{name}-%{version}.tar.xz @@ -14,6 +14,7 @@ BuildRequires: desktop-file-utils Patch1: lftp-4.0.9-date_fmt.patch Patch2: lftp-4.8.4-ssh-prompt.patch Patch3: lftp-4.8.4-re-newed-cert.patch +Patch4: lftp-4.8.4-tls-close.patch %description LFTP is a sophisticated ftp/http file transfer program. Like bash, it has job @@ -36,6 +37,7 @@ Utility scripts for use with lftp. %patch1 -p1 -b .date_fmt %patch2 -p1 -b .ssh-prompt %patch3 -p1 -b .re-newed-cert +%patch4 -p1 -b .tls-close #sed -i.rpath -e '/lftp_cv_openssl/s|-R.*lib||' configure sed -i.norpath -e \ @@ -105,6 +107,10 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Tue May 06 2025 Tomas Korbar - 4.8.4-4 +- Ensure proper closing of TLS connection +- Resolves: RHEL-88955 + * Mon Jul 24 2023 Michal Ruprich - 4.8.4-3 - Resolves: #2182418 - Connection to site fails with certificate verification error