[libssh2] Fix libssh2 failing key re-exchange when write channel is saturated (#804156)

Paul Howarth pghmcfc at fedoraproject.org
Fri Mar 16 21:53:25 UTC 2012


commit 12e9f5a79fe1ca6076ecb48196c8ee6e60a7b4c7
Author: Paul Howarth <paul at city-fan.org>
Date:   Fri Mar 16 19:24:44 2012 +0000

    Fix libssh2 failing key re-exchange when write channel is saturated (#804156)

 libssh2-1.4.0-cc4f9d.patch |   58 ++++++++++++++++++++++++++++++++++++++++++++
 libssh2.spec               |   14 +++++++---
 2 files changed, 68 insertions(+), 4 deletions(-)
---
diff --git a/libssh2-1.4.0-cc4f9d.patch b/libssh2-1.4.0-cc4f9d.patch
new file mode 100644
index 0000000..33e5e4d
--- /dev/null
+++ b/libssh2-1.4.0-cc4f9d.patch
@@ -0,0 +1,58 @@
+commit cc4f9d5679278ce41cd5480fab3f5e71dba163ed
+Author: Matthew Booth <mbooth at redhat.com>
+Date:   Fri Mar 16 16:29:00 2012 +0100
+
+    transport_send: Finish in-progress key exchange before sending data
+    
+    _libssh2_channel_write() first reads outstanding packets before writing
+    new data. If it reads a key exchange request, it will immediately start
+    key re-exchange, which will require sending a response. If the output
+    socket is full, this will result in a return from
+    _libssh2_transport_read() of LIBSSH2_ERROR_EAGAIN. In order not to block
+    a write because there is no data to read, this error is explicitly
+    ignored and the code continues marshalling a packet for sending. When it
+    is sent, the remote end immediately drops the connection because it was
+    expecting a continuation of the key exchange, but got a data packet.
+    
+    This change adds the same check for key exchange to
+    _libssh2_transport_send() that is in _libssh2_transport_read(). This
+    ensures that key exchange is completed before any data packet is sent.
+
+diff --git a/src/transport.c b/src/transport.c
+index 057dcf5..95b9a3a 100644
+--- a/src/transport.c
++++ b/src/transport.c
+@@ -296,7 +296,7 @@ int _libssh2_transport_read(LIBSSH2_SESSION * session)
+          * is done!
+          */
+         _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
+-                       " key re-exchange");
++                       " key re-exchange from _libssh2_transport_read");
+         rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
+         if (rc)
+             return rc;
+@@ -687,6 +687,24 @@ int _libssh2_transport_send(LIBSSH2_SESSION *session,
+     const unsigned char *orgdata = data;
+     size_t orgdata_len = data_len;
+ 
++    /*
++     * If the last read operation was interrupted in the middle of a key
++     * exchange, we must complete that key exchange before continuing to write
++     * further data.
++     *
++     * See the similar block in _libssh2_transport_read for more details.
++     */
++    if (session->state & LIBSSH2_STATE_EXCHANGING_KEYS &&
++        !(session->state & LIBSSH2_STATE_KEX_ACTIVE)) {
++        /* Don't write any new packets if we're still in the middle of a key
++         * exchange. */
++        _libssh2_debug(session, LIBSSH2_TRACE_TRANS, "Redirecting into the"
++                       " key re-exchange from _libssh2_transport_send");
++        rc = _libssh2_kex_exchange(session, 1, &session->startup_key_state);
++        if (rc)
++            return rc;
++    }
++
+     debugdump(session, "libssh2_transport_write plain", data, data_len);
+     if(data2)
+         debugdump(session, "libssh2_transport_write plain2", data2, data2_len);
diff --git a/libssh2.spec b/libssh2.spec
index 791b37e..7627806 100644
--- a/libssh2.spec
+++ b/libssh2.spec
@@ -9,7 +9,7 @@
 
 Name:		libssh2
 Version:	1.4.0
-Release:	1%{?dist}
+Release:	2%{?dist}
 Summary:	A library implementing the SSH2 protocol
 Group:		System Environment/Libraries
 License:	BSD
@@ -17,6 +17,7 @@ URL:		http://www.libssh2.org/
 Source0:	http://libssh2.org/download/libssh2-%{version}.tar.gz
 Patch0:		libssh2-1.2.9-utf8.patch
 Patch1:		libssh2-1.4.0-c4a0e0.patch
+Patch2:		libssh2-1.4.0-cc4f9d.patch
 BuildRoot:	%{_tmppath}/%{name}-%{version}-%{release}-root-%(id -nu)
 BuildRequires:	openssl-devel
 BuildRequires:	zlib-devel
@@ -69,6 +70,10 @@ developing applications that use libssh2.
 # Fix undefined reference to _libssh_error in libgcrypt (upstream patch)
 %patch1 -p1
 
+# Fix libssh2 failing key re-exchange when write channel is saturated
+# (upstream patch, #804156)
+%patch2 -p1
+
 # Make sshd transition appropriately if building in an SELinux environment
 chcon $(/usr/sbin/matchpathcon -n /etc/rc.d/init.d/sshd) tests/ssh2.sh || :
 chcon -R $(/usr/sbin/matchpathcon -n /etc) tests/etc || :
@@ -113,18 +118,15 @@ rm -rf %{buildroot}
 %postun -p /sbin/ldconfig
 
 %files
-%defattr(-,root,root,-)
 %doc AUTHORS ChangeLog COPYING README NEWS
 %{_libdir}/libssh2.so.1
 %{_libdir}/libssh2.so.1.*
 
 %files docs
-%defattr(-,root,root,-)
 %doc HACKING
 %{_mandir}/man3/libssh2_*.3*
 
 %files devel
-%defattr(-,root,root,-)
 %doc example/
 %{_includedir}/libssh2.h
 %{_includedir}/libssh2_publickey.h
@@ -133,6 +135,10 @@ rm -rf %{buildroot}
 %{_libdir}/pkgconfig/libssh2.pc
 
 %changelog
+* Fri Mar 16 2012 Paul Howarth <paul at city-fan.org> 1.4.0-2
+- fix libssh2 failing key re-exchange when write channel is saturated (#804156)
+- drop %%defattr, redundant since rpm 4.4
+
 * Wed Feb  1 2012 Paul Howarth <paul at city-fan.org> 1.4.0-1
 - update to 1.4.0
   - added libssh2_session_supported_algs()


More information about the scm-commits mailing list