No more packet_read2() !
Этот коммит содержится в:
родитель
74009e2be5
Коммит
40bcc0bed8
@ -31,7 +31,10 @@ typedef struct packet_struct {
|
|||||||
|
|
||||||
int packet_send(ssh_session session);
|
int packet_send(ssh_session session);
|
||||||
|
|
||||||
|
#ifdef WITH_SSH1
|
||||||
int packet_read(ssh_session session);
|
int packet_read(ssh_session session);
|
||||||
|
#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
|
||||||
|
201
libssh/packet.c
201
libssh/packet.c
@ -353,194 +353,11 @@ error:
|
|||||||
leave_function();
|
leave_function();
|
||||||
}
|
}
|
||||||
|
|
||||||
static int packet_read2(ssh_session session) {
|
|
||||||
unsigned int blocksize = (session->current_crypto ?
|
|
||||||
session->current_crypto->in_cipher->blocksize : 8);
|
|
||||||
int current_macsize = session->current_crypto ? macsize : 0;
|
|
||||||
unsigned char mac[30] = {0};
|
|
||||||
char buffer[16] = {0};
|
|
||||||
void *packet=NULL;
|
|
||||||
int to_be_read;
|
|
||||||
int rc = SSH_ERROR;
|
|
||||||
|
|
||||||
uint32_t len;
|
|
||||||
uint8_t padding;
|
|
||||||
|
|
||||||
enter_function();
|
|
||||||
|
|
||||||
if (session->alive == 0) {
|
|
||||||
/* The error message was already set into this session */
|
|
||||||
leave_function();
|
|
||||||
return SSH_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(session->packet_state) {
|
|
||||||
case PACKET_STATE_INIT:
|
|
||||||
memset(&session->in_packet, 0, sizeof(PACKET));
|
|
||||||
|
|
||||||
if (session->in_buffer) {
|
|
||||||
if (buffer_reinit(session->in_buffer) < 0) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
session->in_buffer = buffer_new();
|
|
||||||
if (session->in_buffer == NULL) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = ssh_socket_wait_for_data(session->socket, session, blocksize);
|
|
||||||
if (rc != SSH_OK) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
rc = SSH_ERROR;
|
|
||||||
/* can't fail since we're sure there is enough data in socket buffer */
|
|
||||||
ssh_socket_read(session->socket, buffer, blocksize);
|
|
||||||
len = packet_decrypt_len(session, buffer);
|
|
||||||
|
|
||||||
if (buffer_add_data(session->in_buffer, buffer, blocksize) < 0) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(len > MAX_PACKET_LEN) {
|
|
||||||
ssh_set_error(session, SSH_FATAL,
|
|
||||||
"read_packet(): Packet len too high(%u %.4x)", len, len);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
to_be_read = len - blocksize + sizeof(uint32_t);
|
|
||||||
if (to_be_read < 0) {
|
|
||||||
/* remote sshd sends invalid sizes? */
|
|
||||||
ssh_set_error(session, SSH_FATAL,
|
|
||||||
"given numbers of bytes left to be read < 0 (%d)!", to_be_read);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* saves the status of the current operations */
|
|
||||||
session->in_packet.len = len;
|
|
||||||
session->packet_state = PACKET_STATE_SIZEREAD;
|
|
||||||
case PACKET_STATE_SIZEREAD:
|
|
||||||
len = session->in_packet.len;
|
|
||||||
to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize;
|
|
||||||
/* if to_be_read is zero, the whole packet was blocksize bytes. */
|
|
||||||
if (to_be_read != 0) {
|
|
||||||
rc = ssh_socket_wait_for_data(session->socket,session,to_be_read);
|
|
||||||
if (rc != SSH_OK) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
rc = SSH_ERROR;
|
|
||||||
|
|
||||||
packet = malloc(to_be_read);
|
|
||||||
if (packet == NULL) {
|
|
||||||
ssh_set_error(session, SSH_FATAL, "No space left");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
ssh_socket_read(session->socket,packet,to_be_read-current_macsize);
|
|
||||||
|
|
||||||
ssh_log(session,SSH_LOG_PACKET,"Read a %d bytes packet",len);
|
|
||||||
|
|
||||||
if (buffer_add_data(session->in_buffer, packet,
|
|
||||||
to_be_read - current_macsize) < 0) {
|
|
||||||
SAFE_FREE(packet);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
SAFE_FREE(packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (session->current_crypto) {
|
|
||||||
/*
|
|
||||||
* decrypt the rest of the packet (blocksize bytes already
|
|
||||||
* have been decrypted)
|
|
||||||
*/
|
|
||||||
if (packet_decrypt(session,
|
|
||||||
((uint8_t*)buffer_get(session->in_buffer) + blocksize),
|
|
||||||
buffer_get_len(session->in_buffer) - blocksize) < 0) {
|
|
||||||
ssh_set_error(session, SSH_FATAL, "Decrypt error");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
#ifdef WITH_PCAP
|
|
||||||
if(session->pcap_ctx){
|
|
||||||
ssh_pcap_context_write(session->pcap_ctx,
|
|
||||||
SSH_PCAP_DIR_IN, buffer_get(session->in_buffer),
|
|
||||||
buffer_get_len(session->in_buffer),
|
|
||||||
buffer_get_len(session->in_buffer));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
ssh_socket_read(session->socket, mac, macsize);
|
|
||||||
|
|
||||||
if (packet_hmac_verify(session, session->in_buffer, mac) < 0) {
|
|
||||||
ssh_set_error(session, SSH_FATAL, "HMAC error");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#ifdef WITH_PCAP
|
|
||||||
else {
|
|
||||||
/* No crypto */
|
|
||||||
if(session->pcap_ctx){
|
|
||||||
ssh_pcap_context_write(session->pcap_ctx,
|
|
||||||
SSH_PCAP_DIR_IN, buffer_get(session->in_buffer),
|
|
||||||
buffer_get_len(session->in_buffer),
|
|
||||||
buffer_get_len(session->in_buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
buffer_pass_bytes(session->in_buffer, sizeof(uint32_t));
|
|
||||||
|
|
||||||
/* pass the size which has been processed before */
|
|
||||||
if (buffer_get_u8(session->in_buffer, &padding) == 0) {
|
|
||||||
ssh_set_error(session, SSH_FATAL, "Packet too short to read padding");
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssh_log(session, SSH_LOG_PACKET,
|
|
||||||
"%hhd bytes padding, %d bytes left in buffer",
|
|
||||||
padding, buffer_get_rest_len(session->in_buffer));
|
|
||||||
|
|
||||||
if (padding > buffer_get_rest_len(session->in_buffer)) {
|
|
||||||
ssh_set_error(session, SSH_FATAL,
|
|
||||||
"Invalid padding: %d (%d resting)",
|
|
||||||
padding,
|
|
||||||
buffer_get_rest_len(session->in_buffer));
|
|
||||||
#ifdef DEBUG_CRYPTO
|
|
||||||
ssh_print_hexa("incrimined packet",
|
|
||||||
buffer_get(session->in_buffer),
|
|
||||||
buffer_get_len(session->in_buffer));
|
|
||||||
#endif
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
buffer_pass_bytes_end(session->in_buffer, padding);
|
|
||||||
|
|
||||||
ssh_log(session, SSH_LOG_PACKET,
|
|
||||||
"After padding, %d bytes left in buffer",
|
|
||||||
buffer_get_rest_len(session->in_buffer));
|
|
||||||
#if defined(HAVE_LIBZ) && defined(WITH_LIBZ)
|
|
||||||
if (session->current_crypto && session->current_crypto->do_compress_in) {
|
|
||||||
ssh_log(session, SSH_LOG_PACKET, "Decompressing in_buffer ...");
|
|
||||||
if (decompress_buffer(session, session->in_buffer, MAX_PACKET_LEN) < 0) {
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
session->recv_seq++;
|
|
||||||
session->packet_state = PACKET_STATE_INIT;
|
|
||||||
|
|
||||||
leave_function();
|
|
||||||
return SSH_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ssh_set_error(session, SSH_FATAL,
|
|
||||||
"Invalid state into packet_read2(): %d",
|
|
||||||
session->packet_state);
|
|
||||||
|
|
||||||
error:
|
|
||||||
leave_function();
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef WITH_SSH1
|
#ifdef WITH_SSH1
|
||||||
/* a slighty modified packet_read2() for SSH-1 protocol */
|
/* a slighty modified packet_read2() for SSH-1 protocol
|
||||||
static int packet_read1(ssh_session session) {
|
* TODO: should be transformed in an asynchronous socket callback
|
||||||
|
*/
|
||||||
|
int packet_read(ssh_session session) {
|
||||||
void *packet = NULL;
|
void *packet = NULL;
|
||||||
int rc = SSH_ERROR;
|
int rc = SSH_ERROR;
|
||||||
int to_be_read;
|
int to_be_read;
|
||||||
@ -689,16 +506,6 @@ error:
|
|||||||
|
|
||||||
#endif /* WITH_SSH1 */
|
#endif /* WITH_SSH1 */
|
||||||
|
|
||||||
/* that's where i'd like C to be object ... */
|
|
||||||
int packet_read(ssh_session session) {
|
|
||||||
#ifdef WITH_SSH1
|
|
||||||
if (session->version == 1) {
|
|
||||||
return packet_read1(session);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return packet_read2(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
int packet_translate(ssh_session session) {
|
int packet_translate(ssh_session session) {
|
||||||
enter_function();
|
enter_function();
|
||||||
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user