No more packet_read2() !
Этот коммит содержится в:
родитель
74009e2be5
Коммит
40bcc0bed8
@ -31,7 +31,10 @@ typedef struct packet_struct {
|
||||
|
||||
int packet_send(ssh_session session);
|
||||
|
||||
#ifdef WITH_SSH1
|
||||
int packet_read(ssh_session session);
|
||||
#endif
|
||||
|
||||
int packet_translate(ssh_session session);
|
||||
/* TODO: remove it when packet_wait is stripped out from libssh */
|
||||
#ifdef WITH_SSH1
|
||||
|
201
libssh/packet.c
201
libssh/packet.c
@ -353,194 +353,11 @@ error:
|
||||
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
|
||||
/* a slighty modified packet_read2() for SSH-1 protocol */
|
||||
static int packet_read1(ssh_session session) {
|
||||
/* a slighty modified packet_read2() for SSH-1 protocol
|
||||
* TODO: should be transformed in an asynchronous socket callback
|
||||
*/
|
||||
int packet_read(ssh_session session) {
|
||||
void *packet = NULL;
|
||||
int rc = SSH_ERROR;
|
||||
int to_be_read;
|
||||
@ -689,16 +506,6 @@ error:
|
||||
|
||||
#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) {
|
||||
enter_function();
|
||||
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user