[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] client: send kex as soon as banners are exchanged


Some ssh servers, in cisco IOS, do not send kex if they send the banner last.
In this situation, both libssh client and the cisco IOS server hang.
Libssh client should send kex init as soon as banners are exchanged.

   Signed-off-by: Meng Tan <mtan@xxxxxxxxxx>
---
 src/client.c | 30 +++++++++++++++++++++---------
 1 file changed, 21 insertions(+), 9 deletions(-)

diff --git a/src/client.c b/src/client.c
index 11a0022..aa206fe 100644
--- a/src/client.c
+++ b/src/client.c
@@ -441,9 +441,17 @@ static void ssh_client_connection_callback(ssh_session session){
 #endif
 		  ssh_packet_set_default_callbacks(session);
 		  session->session_state=SSH_SESSION_STATE_INITIAL_KEX;
-          if (session->opts.ssh1 == 1) {
-              ssh_send_banner(session, 0);
-          }
+                  if (session->opts.ssh1 == 1) {
+                      ssh_send_banner(session, 0);
+                  } else {
+                      /* Banner already sent, we can send kexinit now */
+                      if (ssh_set_client_kex(session) < 0) {
+                          goto error;
+                      }
+                      if (ssh_send_kex(session, 0) < 0) {
+                          goto error;
+                      }
+                  }
 		  set_status(session, 0.5f);
 		  break;
 		case SSH_SESSION_STATE_INITIAL_KEX:
@@ -461,14 +469,18 @@ static void ssh_client_connection_callback(ssh_session session){
 		case SSH_SESSION_STATE_KEXINIT_RECEIVED:
 			set_status(session,0.6f);
 			ssh_list_kex(&session->next_crypto->server_kex);
-			if (ssh_set_client_kex(session) < 0) {
-				goto error;
-			}
+                        if (session->opts.ssh1 == 1
+                            || session->next_crypto->client_kex.methods[0] == NULL) {
+                            /* in rekeying state if next_crypto client_kex is empty */
+                            if (ssh_set_client_kex(session) < 0) {
+                                goto error;
+                            }
+                            if (ssh_send_kex(session, 0) < 0) {
+                                goto error;
+                            }
+                        }
 			if (ssh_kex_select_methods(session) == SSH_ERROR)
 			    goto error;
-			if (ssh_send_kex(session, 0) < 0) {
-				goto error;
-			}
 			set_status(session,0.8f);
 			session->session_state=SSH_SESSION_STATE_DH;
 			if (dh_handshake(session) == SSH_ERROR) {
-- 
2.1.4

Archive administrator: postmaster@lists.cynapses.org