1
1

Made parts of SSH asynchronous (inc kex1)

Этот коммит содержится в:
Aris Adamantiadis 2010-01-24 21:03:03 +01:00
родитель 6ae558b541
Коммит 758df26582
9 изменённых файлов: 201 добавлений и 210 удалений

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

@ -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); ssh_channel ssh_channel_from_local(ssh_session session, uint32_t id);
int channel_write_common(ssh_channel channel, const void *data, int channel_write_common(ssh_channel channel, const void *data,
uint32_t len, int is_stderr); 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_ */ #endif /* CHANNELS_H_ */

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

@ -26,5 +26,8 @@
#include "libssh/callbacks.h" #include "libssh/callbacks.h"
SSH_PACKET_CALLBACK(ssh_packet_kexinit); SSH_PACKET_CALLBACK(ssh_packet_kexinit);
#ifdef WITH_SSH1
SSH_PACKET_CALLBACK(ssh_packet_publickey1);
#endif
#endif /* KEX_H_ */ #endif /* KEX_H_ */

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

@ -47,12 +47,16 @@ int packet_read(ssh_session session);
int packet_send1(ssh_session session) ; int packet_send1(ssh_session session) ;
void ssh_packet_set_default_callbacks1(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 #endif
int packet_translate(ssh_session session); int packet_translate(ssh_session session);
/* TODO: remove it when packet_wait is stripped out from libssh */ /* TODO: remove it when packet_wait is stripped out from libssh */
#ifdef WITH_SSH1 #ifdef WITH_SSH1
int packet_wait(ssh_session session,int type,int blocking); //int packet_wait(ssh_session session,int type,int blocking);
#endif #endif
int packet_flush(ssh_session session, int enforce_blocking); int packet_flush(ssh_session session, int enforce_blocking);

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

@ -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, int ssh_userauth1_password(ssh_session session, const char *username,
const char *password); const char *password);
#ifdef WITH_SSH1
/* channels1.c */ /* channels1.c */
int channel_open_session1(ssh_channel channel); int channel_open_session1(ssh_channel channel);
int channel_request_pty_size1(ssh_channel channel, const char *terminal, 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_change_pty_size1(ssh_channel channel, int cols, int rows);
int channel_request_shell1(ssh_channel channel); int channel_request_shell1(ssh_channel channel);
int channel_request_exec1(ssh_channel channel, const char *cmd); 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); int channel_write1(ssh_channel channel, const void *data, int len);
#endif
/* match.c */ /* match.c */
int match_hostname(const char *host, const char *pattern, unsigned int len); int match_hostname(const char *host, const char *pattern, unsigned int len);

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

@ -329,7 +329,8 @@ error:
} }
/** @internal /** @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 session current SSH session.
* @param packet buffer to parse packet from. The read pointer will be moved after * @param packet buffer to parse packet from. The read pointer will be moved after
* the call. * the call.
@ -339,7 +340,11 @@ error:
static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) { static ssh_channel channel_from_msg(ssh_session session, ssh_buffer packet) {
ssh_channel channel; ssh_channel channel;
uint32_t chan; 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)) { if (buffer_get_u32(packet, &chan) != sizeof(uint32_t)) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,
"Getting channel from message: short read"); "Getting channel from message: short read");
@ -1052,7 +1057,7 @@ void channel_set_blocking(ssh_channel channel, int blocking) {
/** @internal /** @internal
* @brief handle a SSH_CHANNEL_SUCCESS packet and set the channel * @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_PACKET_CALLBACK(ssh_packet_channel_success){
ssh_channel channel; ssh_channel channel;
@ -1083,7 +1088,7 @@ SSH_PACKET_CALLBACK(ssh_packet_channel_success){
/** @internal /** @internal
* @brief handle a SSH_CHANNEL_FAILURE packet and set the channel * @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_PACKET_CALLBACK(ssh_packet_channel_failure){
ssh_channel channel; ssh_channel channel;

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

@ -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) { int channel_change_pty_size1(ssh_channel channel, int cols, int rows) {
ssh_session session = channel->session; 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 || 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(rows)) < 0 ||
buffer_add_u32(session->out_buffer, ntohl(cols)) < 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 ||
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)) { if (packet_send(session)) {
return -1; return SSH_ERROR;
} }
ssh_log(session, SSH_LOG_RARE, "Change pty size send"); ssh_log(session, SSH_LOG_PROTOCOL, "Change pty size send");
while(channel->request_state==SSH_CHANNEL_REQ_STATE_PENDING){
if (packet_wait(session, SSH_SMSG_SUCCESS, 1) != SSH_OK) { ssh_handle_packets(session,-1);
return -1;
} }
switch(channel->request_state){
switch (session->in_packet.type) { case SSH_CHANNEL_REQ_STATE_ERROR:
case SSH_SMSG_SUCCESS: case SSH_CHANNEL_REQ_STATE_PENDING:
ssh_log(session, SSH_LOG_RARE, "pty size changed"); case SSH_CHANNEL_REQ_STATE_NONE:
return 0; channel->request_state=SSH_CHANNEL_REQ_STATE_NONE;
case SSH_SMSG_FAILURE: 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_log(session, SSH_LOG_RARE, "pty size change denied");
ssh_set_error(session, SSH_REQUEST_DENIED, "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) { int channel_request_shell1(ssh_channel channel) {
@ -208,35 +214,37 @@ int channel_request_exec1(ssh_channel channel, const char *cmd) {
return 0; 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_channel channel = session->channels;
ssh_string str = NULL; ssh_string str = NULL;
int is_stderr=(type==SSH_SMSG_STDOUT_DATA ? 0 : 1);
str = buffer_get_ssh_string(session->in_buffer); (void)user;
str = buffer_get_ssh_string(packet);
if (str == NULL) { if (str == NULL) {
ssh_log(session, SSH_LOG_FUNCTIONS, "Invalid data packet !\n"); 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", "Adding %zu bytes data in %d",
string_len(str), is_stderr); string_len(str), is_stderr);
if (channel_default_bufferize(channel, string_data(str), string_len(str), if (channel_default_bufferize(channel, string_data(str), string_len(str),
is_stderr) < 0) { is_stderr) < 0) {
string_free(str); string_free(str);
return -1; return SSH_PACKET_USED;
} }
string_free(str); 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; ssh_channel channel = session->channels;
uint32_t status; uint32_t status;
(void)type;
buffer_get_u32(session->in_buffer, &status); (void)user;
buffer_get_u32(packet, &status);
/* /*
* It's much more than a channel closing. spec says it's the last * It's much more than a channel closing. spec says it's the last
* message sent by server (strange) * message sent by server (strange)
@ -246,41 +254,12 @@ static int channel_rcv_close1(ssh_session session) {
channel->open = 0; channel->open = 0;
channel->remote_eof = 1; channel->remote_eof = 1;
if (buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION) < 0) { buffer_add_u8(session->out_buffer, SSH_CMSG_EXIT_CONFIRMATION);
return -1; packet_send(session);
}
if (packet_send(session) != SSH_OK) { return SSH_PACKET_USED;
return -1;
}
return 0;
} }
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) { int channel_write1(ssh_channel channel, const void *data, int len) {
ssh_session session = channel->session; ssh_session session = channel->session;

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

@ -601,7 +601,6 @@ void ssh_connection_callback(ssh_session session){
goto error; goto error;
set_status(session,0.6); set_status(session,0.6);
session->connected = 1; session->connected = 1;
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
break; break;
} }
#endif #endif

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

@ -597,7 +597,6 @@ static ssh_string encrypt_session_key(ssh_session session, ssh_public_key srvkey
return data1; return data1;
} }
/* SSH-1 functions */ /* SSH-1 functions */
/* 2 SSH_SMSG_PUBLIC_KEY /* 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_ciphers_mask
* 32-bit int supported_authentications_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_exp = NULL;
ssh_string server_mod = NULL; ssh_string server_mod = NULL;
ssh_string host_exp = NULL; ssh_string host_exp = NULL;
ssh_string host_mod = NULL; ssh_string host_mod = NULL;
ssh_string serverkey = NULL; ssh_string serverkey = NULL;
ssh_string hostkey = NULL; ssh_string hostkey = NULL;
ssh_string enc_session = NULL;
ssh_public_key srv = NULL; ssh_public_key srv = NULL;
ssh_public_key host = NULL; ssh_public_key host = NULL;
uint32_t server_bits; uint32_t server_bits;
@ -628,45 +628,43 @@ int ssh_get_kex1(ssh_session session) {
uint32_t protocol_flags; uint32_t protocol_flags;
uint32_t supported_ciphers_mask; uint32_t supported_ciphers_mask;
uint32_t supported_authentications_mask; uint32_t supported_authentications_mask;
ssh_string enc_session = NULL;
uint16_t bits; uint16_t bits;
int rc = -1;
int ko; int ko;
enter_function(); enter_function();
ssh_log(session, SSH_LOG_PROTOCOL, "Waiting for a SSH_SMSG_PUBLIC_KEY"); (void)type;
if (packet_wait(session, SSH_SMSG_PUBLIC_KEY, 1) != SSH_OK) { (void)user;
leave_function();
return -1;
}
ssh_log(session, SSH_LOG_PROTOCOL, "Got a SSH_SMSG_PUBLIC_KEY"); 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"); ssh_set_error(session, SSH_FATAL, "Can't get cookie in buffer");
leave_function(); goto error;
return -1;
} }
buffer_get_u32(session->in_buffer, &server_bits); buffer_get_u32(packet, &server_bits);
server_exp = buffer_get_mpint(session->in_buffer); server_exp = buffer_get_mpint(packet);
if (server_exp == NULL) { if (server_exp == NULL) {
goto error; goto error;
} }
server_mod = buffer_get_mpint(session->in_buffer); server_mod = buffer_get_mpint(packet);
if (server_mod == NULL) { if (server_mod == NULL) {
goto error; goto error;
} }
buffer_get_u32(session->in_buffer, &host_bits); buffer_get_u32(packet, &host_bits);
host_exp = buffer_get_mpint(session->in_buffer); host_exp = buffer_get_mpint(packet);
if (host_exp == NULL) { if (host_exp == NULL) {
goto error; goto error;
} }
host_mod = buffer_get_mpint(session->in_buffer); host_mod = buffer_get_mpint(packet);
if (host_mod == NULL) { if (host_mod == NULL) {
goto error; goto error;
} }
buffer_get_u32(session->in_buffer, &protocol_flags); buffer_get_u32(packet, &protocol_flags);
buffer_get_u32(session->in_buffer, &supported_ciphers_mask); buffer_get_u32(packet, &supported_ciphers_mask);
ko = buffer_get_u32(session->in_buffer, &supported_authentications_mask); ko = buffer_get_u32(packet, &supported_authentications_mask);
if ((ko != sizeof(uint32_t)) || !host_mod || !host_exp if ((ko != sizeof(uint32_t)) || !host_mod || !host_exp
|| !server_mod || !server_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"); ssh_set_error(session, SSH_FATAL, "Remote server doesn't accept 3DES");
goto error; goto error;
} }
ssh_log(session, SSH_LOG_PROTOCOL, "Sending SSH_CMSG_SESSION_KEY"); ssh_log(session, SSH_LOG_PROTOCOL, "Sending SSH_CMSG_SESSION_KEY");
if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) { if (buffer_add_u8(session->out_buffer, SSH_CMSG_SESSION_KEY) < 0) {
goto error; goto error;
} }
if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) { if (buffer_add_u8(session->out_buffer, SSH_CIPHER_3DES) < 0) {
goto error; goto error;
} }
if (buffer_add_data(session->out_buffer, session->server_kex.cookie, 8) < 0) { if (buffer_add_data(session->out_buffer, session->server_kex.cookie, 8) < 0) {
goto error; goto error;
} }
enc_session = encrypt_session_key(session, srv, host, server_bits, host_bits); enc_session = encrypt_session_key(session, srv, host, server_bits, host_bits);
if (enc_session == NULL) { if (enc_session == NULL) {
goto error; goto error;
} }
bits = string_len(enc_session) * 8 - 7; bits = string_len(enc_session) * 8 - 7;
ssh_log(session, SSH_LOG_PROTOCOL, "%d bits, %zu bytes encrypted session", ssh_log(session, SSH_LOG_PROTOCOL, "%d bits, %zu bytes encrypted session",
bits, string_len(enc_session)); bits, string_len(enc_session));
bits = htons(bits); bits = htons(bits);
/* the encrypted mpint */ /* the encrypted mpint */
if (buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) { if (buffer_add_data(session->out_buffer, &bits, sizeof(uint16_t)) < 0) {
goto error; goto error;
} }
if (buffer_add_data(session->out_buffer, string_data(enc_session), if (buffer_add_data(session->out_buffer, string_data(enc_session),
string_len(enc_session)) < 0) { string_len(enc_session)) < 0) {
goto error; goto error;
} }
/* the protocol flags */ /* the protocol flags */
if (buffer_add_u32(session->out_buffer, 0) < 0) { if (buffer_add_u32(session->out_buffer, 0) < 0) {
goto error; goto error;
} }
session->session_state=SSH_SESSION_STATE_KEXINIT_RECEIVED;
if (packet_send(session) != SSH_OK) {
goto error;
}
if (packet_send(session) != SSH_OK) { /* we can set encryption */
goto error; if (crypt_set_algorithms(session)) {
} goto error;
}
/* we can set encryption */ session->current_crypto = session->next_crypto;
if (crypt_set_algorithms(session)) { session->next_crypto = NULL;
goto error; goto end;
}
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);
goto error;
}
ssh_log(session, SSH_LOG_PROTOCOL, "received SSH_SMSG_SUCCESS\n");
rc = 0;
error: error:
string_free(host_mod); session->session_state=SSH_SESSION_STATE_ERROR;
string_free(host_exp); end:
string_free(server_mod);
string_free(server_exp);
string_free(serverkey);
string_free(hostkey);
publickey_free(srv); string_free(host_mod);
publickey_free(host); 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 SSH_PACKET_USED;
}
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);
}
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");
ret=SSH_OK;
error:
leave_function(); leave_function();
return rc; return ret;
} }
#endif /* WITH_SSH1 */ #endif /* WITH_SSH1 */

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

@ -26,13 +26,13 @@
#include "libssh/session.h" #include "libssh/session.h"
#include "libssh/buffer.h" #include "libssh/buffer.h"
#include "libssh/socket.h" #include "libssh/socket.h"
#include "libssh/kex.h"
#ifdef WITH_SSH1 #ifdef WITH_SSH1
ssh_packet_callback default_packet_handlers1[]= { ssh_packet_callback default_packet_handlers1[]= {
NULL, //SSH_MSG_NONE 0 NULL, //SSH_MSG_NONE 0
NULL, //SSH_MSG_DISCONNECT 1 ssh_packet_disconnect1, //SSH_MSG_DISCONNECT 1
NULL, //SSH_SMSG_PUBLIC_KEY 2 ssh_packet_publickey1, //SSH_SMSG_PUBLIC_KEY 2
NULL, //SSH_CMSG_SESSION_KEY 3 NULL, //SSH_CMSG_SESSION_KEY 3
NULL, //SSH_CMSG_USER 4 NULL, //SSH_CMSG_USER 4
NULL, //SSH_CMSG_AUTH_RHOSTS 5 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_WINDOW_SIZE 11
NULL, //SSH_CMSG_EXEC_SHELL 12 NULL, //SSH_CMSG_EXEC_SHELL 12
NULL, //SSH_CMSG_EXEC_CMD 13 NULL, //SSH_CMSG_EXEC_CMD 13
NULL, //SSH_SMSG_SUCCESS 14 ssh_packet_smsg_success1, //SSH_SMSG_SUCCESS 14
NULL, //SSH_SMSG_FAILURE 15 ssh_packet_smsg_failure1, //SSH_SMSG_FAILURE 15
NULL, //SSH_CMSG_STDIN_DATA 16 NULL, //SSH_CMSG_STDIN_DATA 16
NULL, //SSH_SMSG_STDOUT_DATA 17 ssh_packet_data1, //SSH_SMSG_STDOUT_DATA 17
NULL, //SSH_SMSG_STDERR_DATA 18 ssh_packet_data1, //SSH_SMSG_STDERR_DATA 18
NULL, //SSH_CMSG_EOF 19 NULL, //SSH_CMSG_EOF 19
NULL, //SSH_SMSG_EXITSTATUS 20 NULL, //SSH_SMSG_EXITSTATUS 20
NULL, //SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21 NULL, //SSH_MSG_CHANNEL_OPEN_CONFIRMATION 21
NULL, //SSH_MSG_CHANNEL_OPEN_FAILURE 22 NULL, //SSH_MSG_CHANNEL_OPEN_FAILURE 22
NULL, //SSH_MSG_CHANNEL_DATA 23 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_MSG_CHANNEL_CLOSE_CONFIRMATION 25
NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 26 NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 26
NULL, //SSH_SMSG_X11_OPEN 27 NULL, //SSH_SMSG_X11_OPEN 27
@ -62,19 +62,11 @@ ssh_packet_callback default_packet_handlers1[]= {
NULL, //SSH_MSG_PORT_OPEN 29 NULL, //SSH_MSG_PORT_OPEN 29
NULL, //SSH_CMSG_AGENT_REQUEST_FORWARDING 30 NULL, //SSH_CMSG_AGENT_REQUEST_FORWARDING 30
NULL, //SSH_SMSG_AGENT_OPEN 31 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_EXIT_CONFIRMATION 33
NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 34 NULL, //SSH_CMSG_X11_REQUEST_FORWARDING 34
NULL, //SSH_CMSG_AUTH_RHOSTS_RSA 35 NULL, //SSH_CMSG_AUTH_RHOSTS_RSA 35
NULL, //SSH_MSG_DEBUG 36 ssh_packet_ignore_callback, //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
}; };
/** @internal /** @internal
@ -316,37 +308,37 @@ error:
return rc; /* SSH_OK, AGAIN or 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) { SSH_PACKET_CALLBACK(ssh_packet_smsg_success1){
uint8_t type = session->in_packet.type; if(session->session_state==SSH_SESSION_STATE_KEXINIT_RECEIVED){
session->session_state=SSH_SESSION_STATE_AUTHENTICATING;
if (session->version == 1) { return SSH_PACKET_USED;
/* 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_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;
} else { } else {
return ssh_packet_channel_success(session,type,packet,user);
} }
} }
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) { int packet_wait(ssh_session session, int type, int blocking) {
enter_function(); enter_function();
@ -363,24 +355,15 @@ int packet_wait(ssh_session session, int type, int blocking) {
session->in_packet.type); session->in_packet.type);
switch (session->in_packet.type) { switch (session->in_packet.type) {
case SSH_MSG_DISCONNECT: case SSH_MSG_DISCONNECT:
packet_parse(session);
leave_function();
return SSH_ERROR;
case SSH_SMSG_STDOUT_DATA: case SSH_SMSG_STDOUT_DATA:
case SSH_SMSG_STDERR_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_DEBUG:
case SSH_MSG_IGNORE: case SSH_MSG_IGNORE:
ssh_packet_process(session,type);
break;
case SSH_SMSG_EXITSTATUS:
//This packet must be parsed too
break; break;
/* case SSH2_MSG_CHANNEL_CLOSE:
packet_parse(session);
break;;
*/
default: default:
if (type && (type != session->in_packet.type)) { if (type && (type != session->in_packet.type)) {
ssh_set_error(session, SSH_FATAL, ssh_set_error(session, SSH_FATAL,