diff options
Diffstat (limited to 'src/client.c')
-rw-r--r-- | src/client.c | 202 |
1 files changed, 79 insertions, 123 deletions
diff --git a/src/client.c b/src/client.c index 6a5332d5..66aad23e 100644 --- a/src/client.c +++ b/src/client.c @@ -171,16 +171,13 @@ static int callback_receive_banner(const void *data, size_t len, void *user) */ int ssh_send_banner(ssh_session session, int server) { - const char *banner = NULL; - const char *terminator = NULL; + const char *banner = CLIENT_BANNER_SSH2; + const char *terminator = "\r\n"; /* The maximum banner length is 255 for SSH2 */ char buffer[256] = {0}; size_t len; int rc = SSH_ERROR; - banner = session->version == 1 ? CLIENTBANNER1 : CLIENTBANNER2; - terminator = session->version == 1 ? "\n" : "\r\n"; - if (server == 1) { if (session->opts.custombanner == NULL){ len = strlen(banner); @@ -211,11 +208,8 @@ int ssh_send_banner(ssh_session session, int server) goto end; } - /* SSH version 1 has a banner length of 128 only */ - len = session->version == 1 ? 128 : 0; - snprintf(buffer, - sizeof(buffer) - len, + sizeof(buffer), "%s%s", session->clientbanner, terminator); @@ -361,8 +355,6 @@ pending: rc=SSH_AGAIN; break; case SSH_AUTH_SERVICE_NONE: - case SSH_AUTH_SERVICE_USER_SENT: - /* Invalid state, SSH1 specific */ rc=SSH_ERROR; break; } @@ -382,122 +374,86 @@ pending: * @brief A function to be called each time a step has been done in the * connection. */ -static void ssh_client_connection_callback(ssh_session session){ - int ssh1,ssh2; - - switch(session->session_state){ - case SSH_SESSION_STATE_NONE: - case SSH_SESSION_STATE_CONNECTING: - break; - case SSH_SESSION_STATE_SOCKET_CONNECTED: - /* If SSHv1 is disabled, we can send the banner immedietly */ - if (session->opts.ssh1 == 0) { - ssh_set_fd_towrite(session); - ssh_send_banner(session, 0); +static void ssh_client_connection_callback(ssh_session session) +{ + int rc; + + switch(session->session_state) { + case SSH_SESSION_STATE_NONE: + case SSH_SESSION_STATE_CONNECTING: + break; + case SSH_SESSION_STATE_SOCKET_CONNECTED: + ssh_set_fd_towrite(session); + ssh_send_banner(session, 0); + + break; + case SSH_SESSION_STATE_BANNER_RECEIVED: + if (session->serverbanner == NULL) { + goto error; + } + set_status(session, 0.4f); + SSH_LOG(SSH_LOG_RARE, + "SSH server banner: %s", session->serverbanner); + + /* Here we analyze the different protocols the server allows. */ + rc = ssh_analyze_banner(session, 0); + if (rc < 0) { + ssh_set_error(session, SSH_FATAL, + "No version of SSH protocol usable (banner: %s)", + session->serverbanner); + goto error; + } + + ssh_packet_register_socket_callback(session, session->socket); + + ssh_packet_set_default_callbacks(session); + session->session_state = SSH_SESSION_STATE_INITIAL_KEX; + set_status(session, 0.5f); + + break; + case SSH_SESSION_STATE_INITIAL_KEX: + /* TODO: This state should disappear in favor of get_key handle */ + break; + 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 (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) { + goto error; } - break; - case SSH_SESSION_STATE_BANNER_RECEIVED: - if (session->serverbanner == NULL) { - goto error; - } - set_status(session, 0.4f); - SSH_LOG(SSH_LOG_RARE, - "SSH server banner: %s", session->serverbanner); - - /* Here we analyze the different protocols the server allows. */ - if (ssh_analyze_banner(session, 0, &ssh1, &ssh2) < 0) { - goto error; - } - /* Here we decide which version of the protocol to use. */ - if (ssh2 && session->opts.ssh2) { - session->version = 2; -#ifdef WITH_SSH1 - } else if(ssh1 && session->opts.ssh1) { - session->version = 1; -#endif - } else if(ssh1 && !session->opts.ssh1){ -#ifdef WITH_SSH1 - ssh_set_error(session, SSH_FATAL, - "SSH-1 protocol not available (configure session to allow SSH-1)"); - goto error; -#else - ssh_set_error(session, SSH_FATAL, - "SSH-1 protocol not available (libssh compiled without SSH-1 support)"); - goto error; -#endif - } else { - ssh_set_error(session, SSH_FATAL, - "No version of SSH protocol usable (banner: %s)", - session->serverbanner); - goto error; - } - /* from now, the packet layer is handling incoming packets */ - if (session->version == 2) { - ssh_packet_register_socket_callback(session, session->socket); - } -#ifdef WITH_SSH1 - else - session->socket_callbacks.data=ssh_packet_socket_callback1; -#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); - } - set_status(session, 0.5f); - break; - case SSH_SESSION_STATE_INITIAL_KEX: - /* TODO: This state should disappear in favor of get_key handle */ -#ifdef WITH_SSH1 - if(session->version==1){ - if (ssh_get_kex1(session) < 0) - goto error; - set_status(session,0.6f); - session->connected = 1; - break; - } -#endif - break; - 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 (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) { - goto error; - } /* FALL THROUGH */ - case SSH_SESSION_STATE_DH: - if(session->dh_handshake_state==DH_STATE_FINISHED){ - set_status(session,1.0f); - session->connected = 1; - if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) - session->session_state = SSH_SESSION_STATE_AUTHENTICATED; - else - session->session_state=SSH_SESSION_STATE_AUTHENTICATING; - } - break; - case SSH_SESSION_STATE_AUTHENTICATING: - break; - case SSH_SESSION_STATE_ERROR: - goto error; - default: - ssh_set_error(session,SSH_FATAL,"Invalid state %d",session->session_state); - } + case SSH_SESSION_STATE_DH: + if(session->dh_handshake_state==DH_STATE_FINISHED){ + set_status(session,1.0f); + session->connected = 1; + if (session->flags & SSH_SESSION_FLAG_AUTHENTICATED) + session->session_state = SSH_SESSION_STATE_AUTHENTICATED; + else + session->session_state=SSH_SESSION_STATE_AUTHENTICATING; + } + break; + case SSH_SESSION_STATE_AUTHENTICATING: + break; + case SSH_SESSION_STATE_ERROR: + goto error; + default: + ssh_set_error(session,SSH_FATAL,"Invalid state %d",session->session_state); + } - return; + return; error: - ssh_socket_close(session->socket); - session->alive = 0; - session->session_state=SSH_SESSION_STATE_ERROR; + ssh_socket_close(session->socket); + session->alive = 0; + session->session_state=SSH_SESSION_STATE_ERROR; } |