aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAris Adamantiadis <aris@0xbadc0de.be>2010-01-24 21:03:03 +0100
committerAris Adamantiadis <aris@0xbadc0de.be>2010-01-24 21:03:03 +0100
commit758df265822928744ab20cec8e4929236b6b41e9 (patch)
tree42e10f836c0fbc57fb771f765caf616a69967777
parent6ae558b5410c0ebec6d9e3147e3b6eb6f0430f72 (diff)
downloadlibssh-758df265822928744ab20cec8e4929236b6b41e9.tar.gz
libssh-758df265822928744ab20cec8e4929236b6b41e9.tar.xz
libssh-758df265822928744ab20cec8e4929236b6b41e9.zip
Made parts of SSH asynchronous (inc kex1)
-rw-r--r--include/libssh/channels.h4
-rw-r--r--include/libssh/kex.h3
-rw-r--r--include/libssh/packet.h6
-rw-r--r--include/libssh/priv.h3
-rw-r--r--libssh/channels.c13
-rw-r--r--libssh/channels1.c101
-rw-r--r--libssh/client.c1
-rw-r--r--libssh/kex.c179
-rw-r--r--libssh/packet1.c95
9 files changed, 198 insertions, 207 deletions
diff --git a/include/libssh/channels.h b/include/libssh/channels.h
index ae45f269..5e4901ba 100644
--- a/include/libssh/channels.h
+++ b/include/libssh/channels.h
@@ -78,5 +78,9 @@ uint32_t ssh_channel_new_id(ssh_session session);
ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
int channel_write_common(ssh_channel channel, const void *data,
uint32_t len, int is_stderr);
+#ifdef WITH_SSH1
+SSH_PACKET_CALLBACK(ssh_packet_data1);
+SSH_PACKET_CALLBACK(ssh_packet_close1);
+#endif
#endif /* CHANNELS_H_ */
diff --git a/include/libssh/kex.h b/include/libssh/kex.h
index 89030d95..ce2a102b 100644
--- a/include/libssh/kex.h
+++ b/include/libssh/kex.h
@@ -26,5 +26,8 @@
#include "libssh/callbacks.h"
SSH_PACKET_CALLBACK(ssh_packet_kexinit);
+#ifdef WITH_SSH1
+SSH_PACKET_CALLBACK(ssh_packet_publickey1);
+#endif
#endif /* KEX_H_ */
diff --git a/include/libssh/packet.h b/include/libssh/packet.h
index 29701334..73ad6820 100644
--- a/include/libssh/packet.h
+++ b/include/libssh/packet.h
@@ -47,12 +47,16 @@ int packet_read(ssh_session session);
int packet_send1(ssh_session session) ;
void ssh_packet_set_default_callbacks1(ssh_session session);
+SSH_PACKET_CALLBACK(ssh_packet_disconnect1);
+SSH_PACKET_CALLBACK(ssh_packet_smsg_success1);
+SSH_PACKET_CALLBACK(ssh_packet_smsg_failure1);
+
#endif
int packet_translate(ssh_session session);
/* TODO: remove it when packet_wait is stripped out from libssh */
#ifdef WITH_SSH1
-int packet_wait(ssh_session session,int type,int blocking);
+//int packet_wait(ssh_session session,int type,int blocking);
#endif
int packet_flush(ssh_session session, int enforce_blocking);
diff --git a/include/libssh/priv.h b/include/libssh/priv.h
index 4b4aeba7..122dc129 100644
--- a/include/libssh/priv.h
+++ b/include/libssh/priv.h
@@ -191,6 +191,7 @@ int ssh_userauth1_offer_pubkey(ssh_session session, const char *username,
int ssh_userauth1_password(ssh_session session, const char *username,
const char *password);
+#ifdef WITH_SSH1
/* channels1.c */
int channel_open_session1(ssh_channel channel);
int channel_request_pty_size1(ssh_channel channel, const char *terminal,
@@ -198,9 +199,9 @@ int channel_request_pty_size1(ssh_channel channel, const char *terminal,
int channel_change_pty_size1(ssh_channel channel, int cols, int rows);
int channel_request_shell1(ssh_channel channel);
int channel_request_exec1(ssh_channel channel, const char *cmd);
-int channel_handle1(ssh_session session, int type);
int channel_write1(ssh_channel channel, const void *data, int len);
+#endif
/* match.c */
int match_hostname(const char *host, const char *pattern, unsigned int len);
diff --git a/libssh/channels.c b/libssh/channels.c
index 0a7bf383..aa310095 100644
--- a/libssh/channels.c
+++ b/libssh/channels.c
@@ -329,7 +329,8 @@ error:
}
/** @internal
- * @brief parse a channel-related packet to resolve it to a ssh_channel.
+ * @brief parse a channel-related packet to resolve it to a ssh_channel. Works on SSH1
+ * sessions too.
* @param session current SSH session.
* @param packet buffer to parse packet from. The read pointer will be moved after
* the call.
@@ -339,7 +340,11 @@ error:
static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) {
ssh_channel channel;
uint32_t chan;
-
+#ifdef WITH_SSH1
+ /* With SSH1, the channel is always the first one */
+ if(session->version==1)
+ return session->channels;
+#endif
if (buffer_get_u32(packet, &chan) != sizeof(uint32_t)) {
ssh_set_error(session, SSH_FATAL,
"Getting channel from message: short read");
@@ -1052,7 +1057,7 @@ void channel_set_blocking(ssh_channel channel, int blocking) {
/** @internal
* @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel
- * state.
+ * state. Also works on SSH1 sessions.
*/
SSH_PACKET_CALLBACK(ssh_packet_channel_success){
ssh_channel channel;
@@ -1083,7 +1088,7 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_success){
/** @internal
* @brief handle a SSH_CHANNEL_FAILURE packet and set the channel
- * state.
+ * state. Also works on SSH1 sessions.
*/
SSH_PACKET_CALLBACK(ssh_packet_channel_failure){
ssh_channel channel;
diff --git a/libssh/channels1.c b/libssh/channels1.c
index 54dc5a36..1697754a 100644
--- a/libssh/channels1.c
+++ b/libssh/channels1.c
@@ -132,39 +132,45 @@ int channel_request_pty_size1(ssh_channel channel, const char *terminal, int col
int channel_change_pty_size1(ssh_channel channel, int cols, int rows) {
ssh_session session = channel->session;
-
+ if(channel->request_state != SSH_CHANNEL_REQ_STATE_NONE){
+ ssh_set_error(session,SSH_REQUEST_DENIED,"Wrong request state");
+ return SSH_ERROR;
+ }
if (buffer_add_u8(session->out_buffer, SSH_CMSG_WINDOW_SIZE) < 0 ||
buffer_add_u32(session->out_buffer, ntohl(rows)) < 0 ||
buffer_add_u32(session->out_buffer, ntohl(cols)) < 0 ||
buffer_add_u32(session->out_buffer, 0) < 0 ||
buffer_add_u32(session->out_buffer, 0) < 0) {
- return -1;
+ return SSH_ERROR;
}
-
+ channel->request_state=SSH_CHANNEL_REQ_STATE_PENDING;
if (packet_send(session)) {
- return -1;
+ return SSH_ERROR;
}
- ssh_log(session, SSH_LOG_RARE, "Change pty size send");
-
- if (packet_wait(session, SSH_SMSG_SUCCESS, 1) != SSH_OK) {
- return -1;
+ ssh_log(session, SSH_LOG_PROTOCOL, "Change pty size send");
+ while(channel->request_state==SSH_CHANNEL_REQ_STATE_PENDING){
+ ssh_handle_packets(session,-1);
}
-
- switch (session->in_packet.type) {
- case SSH_SMSG_SUCCESS:
- ssh_log(session, SSH_LOG_RARE, "pty size changed");
- return 0;
- case SSH_SMSG_FAILURE:
+ switch(channel->request_state){
+ case SSH_CHANNEL_REQ_STATE_ERROR:
+ case SSH_CHANNEL_REQ_STATE_PENDING:
+ case SSH_CHANNEL_REQ_STATE_NONE:
+ channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
+ return SSH_ERROR;
+ case SSH_CHANNEL_REQ_STATE_ACCEPTED:
+ channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
+ ssh_log(session, SSH_LOG_PROTOCOL, "pty size changed");
+ return SSH_OK;
+ case SSH_CHANNEL_REQ_STATE_DENIED:
+ channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
ssh_log(session, SSH_LOG_RARE, "pty size change denied");
ssh_set_error(session, SSH_REQUEST_DENIED, "pty size change denied");
- return -1;
+ return SSH_ERROR;
}
+ // Not reached
+ return SSH_ERROR;
- ssh_set_error(session, SSH_FATAL, "Received unexpected packet type %d",
- session->in_packet.type);
-
- return -1;
}
int channel_request_shell1(ssh_channel channel) {
@@ -208,35 +214,37 @@ int channel_request_exec1(ssh_channel channel, const char *cmd) {
return 0;
}
-static int channel_rcv_data1(ssh_session session, int is_stderr) {
+SSH_PACKET_CALLBACK(ssh_packet_data1){
ssh_channel channel = session->channels;
ssh_string str = NULL;
-
- str = buffer_get_ssh_string(session->in_buffer);
+ int is_stderr=(type==SSH_SMSG_STDOUT_DATA ? 0 : 1);
+ (void)user;
+ str = buffer_get_ssh_string(packet);
if (str == NULL) {
ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n");
- return -1;
+ return SSH_PACKET_USED;
}
- ssh_log(session, SSH_LOG_RARE,
+ ssh_log(session, SSH_LOG_PROTOCOL,
"Adding %zu bytes data in %d",
string_len(str), is_stderr);
if (channel_default_bufferize(channel, string_data(str), string_len(str),
is_stderr) < 0) {
string_free(str);
- return -1;
+ return SSH_PACKET_USED;
}
string_free(str);
- return 0;
+ return SSH_PACKET_USED;
}
-static int channel_rcv_close1(ssh_session session) {
+SSH_PACKET_CALLBACK(ssh_packet_close1){
ssh_channel channel = session->channels;
uint32_t status;
-
- buffer_get_u32(session->in_buffer, &status);
+ (void)type;
+ (void)user;
+ buffer_get_u32(packet, &status);
/*
* It's much more than a channel closing. spec says it's the last
* message sent by server (strange)
@@ -246,41 +254,12 @@ static int channel_rcv_close1(ssh_session session) {
channel->open = 0;
channel->remote_eof = 1;
- if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION) < 0) {
- return -1;
- }
+ buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION);
+ packet_send(session);
- if (packet_send(session) != SSH_OK) {
- return -1;
- }
-
- return 0;
+ return SSH_PACKET_USED;
}
-int channel_handle1(ssh_session session, int type) {
- ssh_log(session, SSH_LOG_RARE, "Channel_handle1(%d)", type);
- switch (type) {
- case SSH_SMSG_STDOUT_DATA:
- if (channel_rcv_data1(session,0) < 0) {
- return -1;
- }
- break;
- case SSH_SMSG_STDERR_DATA:
- if (channel_rcv_data1(session,1) < 0) {
- return -1;
- }
- break;
- case SSH_SMSG_EXITSTATUS:
- if (channel_rcv_close1(session) < 0) {
- return -1;
- }
- break;
- default:
- ssh_log(session, SSH_LOG_FUNCTIONS, "Unexpected message %d", type);
- }
-
- return 0;
-}
int channel_write1(ssh_channel channel, const void *data, int len) {
ssh_session session = channel->session;
diff --git a/libssh/client.c b/libssh/client.c
index 60ebcac3..70e60f27 100644
--- a/libssh/client.c
+++ b/libssh/client.c
@@ -601,7 +601,6 @@ void ssh_connection_callback(ssh_session session){
goto error;
set_status(session,0.6);
session->connected = 1;
- session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
break;
}
#endif
diff --git a/libssh/kex.c b/libssh/kex.c
index 176ef5bd..70b3e910 100644
--- a/libssh/kex.c
+++ b/libssh/kex.c
@@ -597,7 +597,6 @@ static ssh_string encrypt_session_key(ssh_session session, ssh_public_key srvkey
return data1;
}
-
/* SSH-1 functions */
/* 2 SSH_SMSG_PUBLIC_KEY
*
@@ -612,15 +611,16 @@ static ssh_string encrypt_session_key(ssh_session session, ssh_public_key srvkey
* 32-bit int supported_ciphers_mask
* 32-bit int supported_authentications_mask
*/
-
-int ssh_get_kex1(ssh_session session) {
+/**
+ * @brief Wait for a SSH_SMSG_PUBLIC_KEY and does the key exchange
+ */
+SSH_PACKET_CALLBACK(ssh_packet_publickey1){
ssh_string server_exp = NULL;
ssh_string server_mod = NULL;
ssh_string host_exp = NULL;
ssh_string host_mod = NULL;
ssh_string serverkey = NULL;
ssh_string hostkey = NULL;
- ssh_string enc_session = NULL;
ssh_public_key srv = NULL;
ssh_public_key host = NULL;
uint32_t server_bits;
@@ -628,45 +628,43 @@ int ssh_get_kex1(ssh_session session) {
uint32_t protocol_flags;
uint32_t supported_ciphers_mask;
uint32_t supported_authentications_mask;
+ ssh_string enc_session = NULL;
uint16_t bits;
- int rc = -1;
int ko;
-
enter_function();
- ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY");
- if (packet_wait(session, SSH_SMSG_PUBLIC_KEY, 1) != SSH_OK) {
- leave_function();
- return -1;
- }
-
+ (void)type;
+ (void)user;
ssh_log(session, SSH_LOG_PROTOCOL, "Got a SSH_SMSG_PUBLIC_KEY");
- if (buffer_get_data(session->in_buffer, session->server_kex.cookie, 8) != 8) {
+ if(session->session_state != SSH_SESSION_STATE_INITIAL_KEX){
+ ssh_set_error(session,SSH_FATAL,"SSH_KEXINIT received in wrong state");
+ goto error;
+ }
+ if (buffer_get_data(packet, session->server_kex.cookie, 8) != 8) {
ssh_set_error(session, SSH_FATAL, "Can't get cookie in buffer");
- leave_function();
- return -1;
+ goto error;
}
- buffer_get_u32(session->in_buffer, &server_bits);
- server_exp = buffer_get_mpint(session->in_buffer);
+ buffer_get_u32(packet, &server_bits);
+ server_exp = buffer_get_mpint(packet);
if (server_exp == NULL) {
goto error;
}
- server_mod = buffer_get_mpint(session->in_buffer);
+ server_mod = buffer_get_mpint(packet);
if (server_mod == NULL) {
goto error;
}
- buffer_get_u32(session->in_buffer, &host_bits);
- host_exp = buffer_get_mpint(session->in_buffer);
+ buffer_get_u32(packet, &host_bits);
+ host_exp = buffer_get_mpint(packet);
if (host_exp == NULL) {
goto error;
}
- host_mod = buffer_get_mpint(session->in_buffer);
+ host_mod = buffer_get_mpint(packet);
if (host_mod == NULL) {
goto error;
}
- buffer_get_u32(session->in_buffer, &protocol_flags);
- buffer_get_u32(session->in_buffer, &supported_ciphers_mask);
- ko = buffer_get_u32(session->in_buffer, &supported_authentications_mask);
+ buffer_get_u32(packet, &protocol_flags);
+ buffer_get_u32(packet, &supported_ciphers_mask);
+ ko = buffer_get_u32(packet, &supported_authentications_mask);
if ((ko != sizeof(uint32_t)) || !host_mod || !host_exp
|| !server_mod || !server_exp) {
@@ -722,77 +720,92 @@ int ssh_get_kex1(ssh_session session) {
ssh_set_error(session, SSH_FATAL, "Remote server doesn't accept 3DES");
goto error;
}
-
ssh_log(session, SSH_LOG_PROTOCOL, "Sending SSH_CMSG_SESSION_KEY");
- if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) {
- goto error;
- }
- if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) {
- goto error;
- }
- if (buffer_add_data(session->out_buffer, session->server_kex.cookie, 8) < 0) {
- goto error;
- }
+ if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) {
+ goto error;
+ }
+ if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) {
+ goto error;
+ }
+ if (buffer_add_data(session->out_buffer, session->server_kex.cookie, 8) < 0) {
+ goto error;
+ }
+
+ enc_session = encrypt_session_key(session, srv, host, server_bits, host_bits);
+ if (enc_session == NULL) {
+ goto error;
+ }
+
+ bits = string_len(enc_session) * 8 - 7;
+ ssh_log(session, SSH_LOG_PROTOCOL, "%d bits, %zu bytes encrypted session",
+ bits, string_len(enc_session));
+ bits = htons(bits);
+ /* the encrypted mpint */
+ if (buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
+ goto error;
+ }
+ if (buffer_add_data(session->out_buffer, string_data(enc_session),
+ string_len(enc_session)) < 0) {
+ goto error;
+ }
+ /* the protocol flags */
+ if (buffer_add_u32(session->out_buffer, 0) < 0) {
+ goto error;
+ }
+ session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED;
+ if (packet_send(session) != SSH_OK) {
+ goto error;
+ }
+
+ /* we can set encryption */
+ if (crypt_set_algorithms(session)) {
+ goto error;
+ }
+
+ session->current_crypto = session->next_crypto;
+ session->next_crypto = NULL;
+ goto end;
+error:
+ session->session_state=SSH_SESSION_STATE_ERROR;
+end:
- enc_session = encrypt_session_key(session, srv, host, server_bits, host_bits);
- if (enc_session == NULL) {
- goto error;
- }
+ string_free(host_mod);
+ string_free(host_exp);
+ string_free(server_mod);
+ string_free(server_exp);
+ string_free(serverkey);
+ string_free(hostkey);
- bits = string_len(enc_session) * 8 - 7;
- ssh_log(session, SSH_LOG_PROTOCOL, "%d bits, %zu bytes encrypted session",
- bits, string_len(enc_session));
- bits = htons(bits);
- /* the encrypted mpint */
- if (buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
- goto error;
- }
- if (buffer_add_data(session->out_buffer, string_data(enc_session),
- string_len(enc_session)) < 0) {
- goto error;
- }
- /* the protocol flags */
- if (buffer_add_u32(session->out_buffer, 0) < 0) {
- goto error;
- }
+ publickey_free(srv);
+ publickey_free(host);
- if (packet_send(session) != SSH_OK) {
- goto error;
- }
+ leave_function();
+ return SSH_PACKET_USED;
+}
- /* we can set encryption */
- if (crypt_set_algorithms(session)) {
- goto error;
+int ssh_get_kex1(ssh_session session) {
+ int ret=SSH_ERROR;
+ enter_function();
+ ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY");
+ /* Here the callback is called */
+ while(session->session_state==SSH_SESSION_STATE_INITIAL_KEX){
+ ssh_handle_packets(session,-1);
}
-
- session->current_crypto = session->next_crypto;
- session->next_crypto = NULL;
-
- ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS");
- if (packet_wait(session,SSH_SMSG_SUCCESS,1) != SSH_OK) {
- char buffer[1024] = {0};
- snprintf(buffer, sizeof(buffer),
- "Key exchange failed: %s", ssh_get_error(session));
- ssh_set_error(session, SSH_FATAL, "%s",buffer);
+ if(session->session_state==SSH_SESSION_STATE_ERROR)
goto error;
+ ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_SUCCESS");
+ /* Waiting for SSH_SMSG_SUCCESS */
+ while(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
+ ssh_handle_packets(session,-1);
}
+ if(session->session_state==SSH_SESSION_STATE_ERROR)
+ goto error;
ssh_log(session, SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n");
-
- rc = 0;
+ ret=SSH_OK;
error:
- string_free(host_mod);
- string_free(host_exp);
- string_free(server_mod);
- string_free(server_exp);
- string_free(serverkey);
- string_free(hostkey);
-
- publickey_free(srv);
- publickey_free(host);
-
leave_function();
- return rc;
+ return ret;
}
#endif /* WITH_SSH1 */
diff --git a/libssh/packet1.c b/libssh/packet1.c
index 5c404378..7afab191 100644
--- a/libssh/packet1.c
+++ b/libssh/packet1.c
@@ -26,13 +26,13 @@
#include "libssh/session.h"
#include "libssh/buffer.h"
#include "libssh/socket.h"
-
+#include "libssh/kex.h"
#ifdef WITH_SSH1
ssh_packet_callback default_packet_handlers1[]= {
NULL, //SSH_MSG_NONE 0
- NULL, //SSH_MSG_DISCONNECT 1
- NULL, //SSH_SMSG_PUBLIC_KEY 2
+ ssh_packet_disconnect1, //SSH_MSG_DISCONNECT 1
+ ssh_packet_publickey1, //SSH_SMSG_PUBLIC_KEY 2
NULL, //SSH_CMSG_SESSION_KEY 3
NULL, //SSH_CMSG_USER 4
NULL, //SSH_CMSG_AUTH_RHOSTS 5
@@ -44,17 +44,17 @@ ssh_packet_callback default_packet_handlers1[]= {
NULL, //SSH_CMSG_WINDOW_SIZE 11
NULL, //SSH_CMSG_EXEC_SHELL 12
NULL, //SSH_CMSG_EXEC_CMD 13
- NULL, //SSH_SMSG_SUCCESS 14
- NULL, //SSH_SMSG_FAILURE 15
+ ssh_packet_smsg_success1, //SSH_SMSG_SUCCESS 14
+ ssh_packet_smsg_failure1, //SSH_SMSG_FAILURE 15
NULL, //SSH_CMSG_STDIN_DATA 16
- NULL, //SSH_SMSG_STDOUT_DATA 17
- NULL, //SSH_SMSG_STDERR_DATA 18
+ ssh_packet_data1, //SSH_SMSG_STDOUT_DATA 17
+ ssh_packet_data1, //SSH_SMSG_STDERR_DATA 18
NULL, //SSH_CMSG_EOF 19
NULL, //SSH_SMSG_EXITSTATUS 20
NULL, //SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21
NULL, //SSH_MSG_CHANNEL_OPEN_FAILURE 22
NULL, //SSH_MSG_CHANNEL_DATA 23
- NULL, //SSH_MSG_CHANNEL_CLOSE 24
+ ssh_packet_close1, //SSH_MSG_CHANNEL_CLOSE 24
NULL, //SSH_MSG_CHANNEL_CLOSE_CONFIRMATION 25
NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 26
NULL, //SSH_SMSG_X11_OPEN 27
@@ -62,19 +62,11 @@ ssh_packet_callback default_packet_handlers1[]= {
NULL, //SSH_MSG_PORT_OPEN 29
NULL, //SSH_CMSG_AGENT_REQUEST_FORWARDING 30
NULL, //SSH_SMSG_AGENT_OPEN 31
- NULL, //SSH_MSG_IGNORE 32
+ ssh_packet_ignore_callback, //SSH_MSG_IGNORE 32
NULL, //SSH_CMSG_EXIT_CONFIRMATION 33
NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 34
NULL, //SSH_CMSG_AUTH_RHOSTS_RSA 35
- NULL, //SSH_MSG_DEBUG 36
- NULL, //SSH_CMSG_REQUEST_COMPRESSION 37
- NULL, //SSH_CMSG_MAX_PACKET_SIZE 38
- NULL, //SSH_CMSG_AUTH_TIS 39
- NULL, //SSH_SMSG_AUTH_TIS_CHALLENGE 40
- NULL, //SSH_CMSG_AUTH_TIS_RESPONSE 41
- NULL, //SSH_CMSG_AUTH_KERBEROS 42
- NULL, //SSH_SMSG_AUTH_KERBEROS_RESPONSE 43
- NULL, //SSH_CMSG_HAVE_KERBEROS_TGT 44
+ ssh_packet_ignore_callback, //SSH_MSG_DEBUG 36
};
/** @internal
@@ -316,37 +308,37 @@ error:
return rc; /* SSH_OK, AGAIN or ERROR */
}
+SSH_PACKET_CALLBACK(ssh_packet_disconnect1){
+ (void)packet;
+ (void)user;
+ (void)type;
+ ssh_log(session, SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT");
+ ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_DISCONNECT");
+ ssh_socket_close(session->socket);
+ session->alive = 0;
+ return SSH_PACKET_USED;
+}
-static void packet_parse(ssh_session session) {
- uint8_t type = session->in_packet.type;
-
- if (session->version == 1) {
- /* SSH-1 */
- switch(type) {
- case SSH_MSG_DISCONNECT:
- ssh_log(session, SSH_LOG_PACKET, "Received SSH_MSG_DISCONNECT");
- ssh_set_error(session, SSH_FATAL, "Received SSH_MSG_DISCONNECT");
+SSH_PACKET_CALLBACK(ssh_packet_smsg_success1){
+ if(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
+ session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
+ return SSH_PACKET_USED;
+ } else {
+ return ssh_packet_channel_success(session,type,packet,user);
+ }
+}
- ssh_socket_close(session->socket);
- session->alive = 0;
- return;
- case SSH_SMSG_STDOUT_DATA:
- case SSH_SMSG_STDERR_DATA:
- case SSH_SMSG_EXITSTATUS:
- channel_handle1(session,type);
- return;
- case SSH_MSG_DEBUG:
- case SSH_MSG_IGNORE:
- break;
- default:
- ssh_log(session, SSH_LOG_PACKET,
- "Unexpected message code %d", type);
- }
- return;
+SSH_PACKET_CALLBACK(ssh_packet_smsg_failure1){
+ if(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
+ session->session_state=SSH_SESSION_STATE_ERROR;
+ ssh_set_error(session,SSH_FATAL,"Key exchange failed: received SSH_SMSG_FAILURE");
+ return SSH_PACKET_USED;
} else {
+ return ssh_packet_channel_failure(session,type,packet,user);
}
}
+
int packet_wait(ssh_session session, int type, int blocking) {
enter_function();
@@ -363,24 +355,15 @@ int packet_wait(ssh_session session, int type, int blocking) {
session->in_packet.type);
switch (session->in_packet.type) {
case SSH_MSG_DISCONNECT:
- packet_parse(session);
- leave_function();
- return SSH_ERROR;
case SSH_SMSG_STDOUT_DATA:
case SSH_SMSG_STDERR_DATA:
- case SSH_SMSG_EXITSTATUS:
- if (channel_handle1(session,type) < 0) {
- leave_function();
- return SSH_ERROR;
- }
- break;
case SSH_MSG_DEBUG:
case SSH_MSG_IGNORE:
+ ssh_packet_process(session,type);
+ break;
+ case SSH_SMSG_EXITSTATUS:
+ //This packet must be parsed too
break;
- /* case SSH2_MSG_CHANNEL_CLOSE:
- packet_parse(session);
- break;;
- */
default:
if (type && (type != session->in_packet.type)) {
ssh_set_error(session, SSH_FATAL,