Made parts of SSH asynchronous (inc kex1)
Этот коммит содержится в:
родитель
6ae558b541
Коммит
758df26582
@ -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_ */
|
||||
|
@ -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_ */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
183
libssh/kex.c
183
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if (packet_send(session) != SSH_OK) {
|
||||
goto error;
|
||||
}
|
||||
/* we can set encryption */
|
||||
if (crypt_set_algorithms(session)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* we can set encryption */
|
||||
if (crypt_set_algorithms(session)) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
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;
|
||||
session->current_crypto = session->next_crypto;
|
||||
session->next_crypto = NULL;
|
||||
goto end;
|
||||
error:
|
||||
string_free(host_mod);
|
||||
string_free(host_exp);
|
||||
string_free(server_mod);
|
||||
string_free(server_exp);
|
||||
string_free(serverkey);
|
||||
string_free(hostkey);
|
||||
session->session_state=SSH_SESSION_STATE_ERROR;
|
||||
end:
|
||||
|
||||
publickey_free(srv);
|
||||
publickey_free(host);
|
||||
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 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();
|
||||
return rc;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* WITH_SSH1 */
|
||||
|
@ -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_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_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_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,
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user