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 <[email protected]>
---
 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

Reply via email to