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

This commit is contained in:
Paul Howarth 2012-03-16 19:24:44 +00:00
parent d2c802f8e0
commit 12e9f5a79f
2 changed files with 68 additions and 4 deletions

View File

@ -0,0 +1,58 @@
commit cc4f9d5679278ce41cd5480fab3f5e71dba163ed
Author: Matthew Booth <mbooth@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);

View File

@ -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@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@city-fan.org> 1.4.0-1
- update to 1.4.0
- added libssh2_session_supported_algs()