aboutsummaryrefslogtreecommitdiff
path: root/libssh/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'libssh/packet.c')
-rw-r--r--libssh/packet.c201
1 files changed, 4 insertions, 197 deletions
diff --git a/libssh/packet.c b/libssh/packet.c
index 15f4ddfd..c9d2e5a9 100644
--- a/libssh/packet.c
+++ b/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();