1
1
Этот коммит содержится в:
Aris Adamantiadis 2010-01-08 22:33:58 +01:00
родитель 74009e2be5
Коммит 40bcc0bed8
2 изменённых файлов: 7 добавлений и 197 удалений

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

@ -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

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

@ -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();