1
1

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
Этот коммит содержится в:
Aris Adamantiadis 2010-01-06 22:49:40 +01:00
родитель ef5dc6cd2b
Коммит 84ec17964e
4 изменённых файлов: 91 добавлений и 69 удалений

Просмотреть файл

@ -245,6 +245,9 @@ int gettimeofday(struct timeval *__p, void *__t);
char *dir_expand_dup(ssh_session session, const char *value, int allowsshdir);
int ssh_options_set_algo(ssh_session session, int algo, const char *list);
/* server.c */
SSH_PACKET_CALLBACK(ssh_packet_kexdh_init);
/** Free memory space */
#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0)

Просмотреть файл

@ -43,6 +43,12 @@ enum ssh_session_state_e {
SSH_SESSION_STATE_ERROR
};
enum ssh_dh_state_e {
DH_STATE_INIT,
DH_STATE_INIT_SENT,
DH_STATE_NEWKEYS_SENT,
DH_STATE_FINISHED
};
struct ssh_session_struct {
struct error_struct error;

Просмотреть файл

@ -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,6 +320,11 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
session->session_state,session->dh_handshake_state);
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;
@ -370,7 +370,7 @@ SSH_PACKET_CALLBACK(ssh_packet_newkeys){
ssh_set_error_oom(session);
goto error;
}
}
session->dh_handshake_state = DH_STATE_FINISHED;
ssh_connection_callback(session);
return SSH_PACKET_USED;

Просмотреть файл

@ -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;