diff options
author | Aris Adamantiadis <aris@0xbadc0de.be> | 2010-01-06 22:49:40 +0100 |
---|---|---|
committer | Aris Adamantiadis <aris@0xbadc0de.be> | 2010-01-06 22:49:40 +0100 |
commit | 84ec17964ed52c23f80f94e0fe23f29948d7d0a6 (patch) | |
tree | 57cae3c316d54efe5a893f066478dee1bf83ceaa /libssh | |
parent | ef5dc6cd2bf5f27230c33dbdcdff3a5fc67ab688 (diff) | |
download | libssh-84ec17964ed52c23f80f94e0fe23f29948d7d0a6.tar.gz libssh-84ec17964ed52c23f80f94e0fe23f29948d7d0a6.tar.xz libssh-84ec17964ed52c23f80f94e0fe23f29948d7d0a6.zip |
Made the server DH asynchronous.
It still needs testing and cleanup, it was done with less
care than the client-side.
The socket listening and connexion is still synchronous
Diffstat (limited to 'libssh')
-rw-r--r-- | libssh/client.c | 90 | ||||
-rw-r--r-- | libssh/server.c | 49 |
2 files changed, 76 insertions, 63 deletions
diff --git a/libssh/client.c b/libssh/client.c index f0621fab..c3a46689 100644 --- a/libssh/client.c +++ b/libssh/client.c @@ -246,12 +246,7 @@ int ssh_send_banner(ssh_session session, int server) { return 0; } -enum ssh_dh_state_e { - DH_STATE_INIT, - DH_STATE_INIT_SENT, - DH_STATE_NEWKEYS_SENT, - DH_STATE_FINISHED -}; + SSH_PACKET_CALLBACK(ssh_packet_dh_reply){ ssh_string f = NULL; @@ -325,52 +320,57 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){ session->session_state,session->dh_handshake_state); goto error; } - rc = make_sessionid(session); - if (rc != SSH_OK) { - goto error; - } + if(session->server){ + /* server things are done in server.c */ + session->dh_handshake_state=DH_STATE_FINISHED; + } else { + /* client */ + rc = make_sessionid(session); + if (rc != SSH_OK) { + goto error; + } - /* - * Set the cryptographic functions for the next crypto - * (it is needed for generate_session_keys for key lengths) - */ - if (crypt_set_algorithms(session)) { - goto error; - } + /* + * Set the cryptographic functions for the next crypto + * (it is needed for generate_session_keys for key lengths) + */ + if (crypt_set_algorithms(session)) { + goto error; + } - if (generate_session_keys(session) < 0) { - goto error; - } + if (generate_session_keys(session) < 0) { + goto error; + } - /* Verify the host's signature. FIXME do it sooner */ - signature = session->dh_server_signature; - session->dh_server_signature = NULL; - if (signature_verify(session, signature)) { - goto error; - } + /* Verify the host's signature. FIXME do it sooner */ + signature = session->dh_server_signature; + session->dh_server_signature = NULL; + if (signature_verify(session, signature)) { + goto error; + } - /* forget it for now ... */ - string_burn(signature); - string_free(signature); - signature=NULL; - /* - * Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and - * current_crypto - */ - if (session->current_crypto) { - crypto_free(session->current_crypto); - session->current_crypto=NULL; - } + /* forget it for now ... */ + string_burn(signature); + string_free(signature); + signature=NULL; + /* + * Once we got SSH2_MSG_NEWKEYS we can switch next_crypto and + * current_crypto + */ + if (session->current_crypto) { + crypto_free(session->current_crypto); + session->current_crypto=NULL; + } - /* FIXME later, include a function to change keys */ - session->current_crypto = session->next_crypto; + /* FIXME later, include a function to change keys */ + session->current_crypto = session->next_crypto; - session->next_crypto = crypto_new(); - if (session->next_crypto == NULL) { - ssh_set_error_oom(session); - goto error; + session->next_crypto = crypto_new(); + if (session->next_crypto == NULL) { + ssh_set_error_oom(session); + goto error; + } } - session->dh_handshake_state = DH_STATE_FINISHED; ssh_connection_callback(session); return SSH_PACKET_USED; diff --git a/libssh/server.c b/libssh/server.c index 9a9bdc4b..efb3220c 100644 --- a/libssh/server.c +++ b/libssh/server.c @@ -351,30 +351,45 @@ static int server_set_kex(ssh_session session) { return 0; } -static int dh_handshake_server(ssh_session session) { +SSH_PACKET_CALLBACK(ssh_packet_kexdh_init){ ssh_string e; - ssh_string f; - ssh_string pubkey; - ssh_string sign; - ssh_public_key pub; - ssh_private_key prv; - - if (packet_wait(session, SSH2_MSG_KEXDH_INIT, 1) != SSH_OK) { - return -1; + (void)type; + (void)user;enter_function(); + ssh_log(session,SSH_LOG_PACKET,"Received SSH_MSG_KEXDH_INIT"); + if(session->dh_handshake_state != DH_STATE_INIT){ + ssh_log(session,SSH_LOG_RARE,"Invalid state for SSH_MSG_KEXDH_INIT"); + goto error; } - - e = buffer_get_ssh_string(session->in_buffer); + e = buffer_get_ssh_string(packet); if (e == NULL) { ssh_set_error(session, SSH_FATAL, "No e number in client request"); return -1; } if (dh_import_e(session, e) < 0) { ssh_set_error(session, SSH_FATAL, "Cannot import e number"); - string_free(e); - return -1; + session->session_state=SSH_SESSION_STATE_ERROR; + } else { + session->dh_handshake_state=DH_STATE_INIT_SENT; } string_free(e); + error: + leave_function(); + return SSH_PACKET_USED; +} + +static int dh_handshake_server(ssh_session session) { + ssh_string f; + ssh_string pubkey; + ssh_string sign; + ssh_public_key pub; + ssh_private_key prv; + /* waiting for SSH_MSG_KEXDH_INIT */ + while(session->dh_handshake_state != DH_STATE_INIT_SENT){ + ssh_handle_packets(session); + } + /* received SSH_MSG_KEXDH_INIT */ + if (dh_generate_y(session) < 0) { ssh_set_error(session, SSH_FATAL, "Could not create y number"); return -1; @@ -458,7 +473,7 @@ static int dh_handshake_server(ssh_session session) { } string_free(f); string_free(sign); - + session->dh_handshake_state=DH_STATE_NEWKEYS_SENT; if (packet_send(session) != SSH_OK) { return -1; } @@ -473,10 +488,8 @@ static int dh_handshake_server(ssh_session session) { } ssh_log(session, SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent"); - if (packet_wait(session, SSH2_MSG_NEWKEYS, 1) != SSH_OK) { - return -1; - } - ssh_log(session, SSH_LOG_PACKET, "Got SSH_MSG_NEWKEYS"); + while(session->dh_handshake_state != DH_STATE_FINISHED) + ssh_handle_packets(session); if (generate_session_keys(session) < 0) { return -1; |