aboutsummaryrefslogtreecommitdiff
path: root/libssh
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2010-01-06 22:49:40 +0100
committerAris Adamantiadis <aris@0xbadc0de.be>2010-01-06 22:49:40 +0100
commit84ec17964ed52c23f80f94e0fe23f29948d7d0a6 (patch)
tree57cae3c316d54efe5a893f066478dee1bf83ceaa /libssh
parentef5dc6cd2bf5f27230c33dbdcdff3a5fc67ab688 (diff)
downloadlibssh-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.c90
-rw-r--r--libssh/server.c49
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;