/* * Test the behavior of buffer_prepend_data */ static void torture_buffer_prepend(void **state) { ssh_buffer buffer = *state; uint32_t v; buffer_add_data(buffer,"abcdef",6); buffer_prepend_data(buffer,"xyz",3); assert_int_equal(buffer_get_rest_len(buffer),9); assert_int_equal(memcmp(buffer_get_rest(buffer), "xyzabcdef", 9), 0); // Now remove 4 bytes and see if we can replace them buffer_get_u32(buffer,&v); assert_int_equal(buffer_get_rest_len(buffer),5); assert_int_equal(memcmp(buffer_get_rest(buffer), "bcdef", 5), 0); buffer_prepend_data(buffer,"aris",4); assert_int_equal(buffer_get_rest_len(buffer),9); assert_int_equal(memcmp(buffer_get_rest(buffer), "arisbcdef", 9), 0); /* same thing but we add 5 bytes now */ buffer_get_u32(buffer,&v); assert_int_equal(buffer_get_rest_len(buffer),5); assert_int_equal(memcmp(buffer_get_rest(buffer), "bcdef", 5), 0); buffer_prepend_data(buffer,"12345",5); assert_int_equal(buffer_get_rest_len(buffer),10); assert_int_equal(memcmp(buffer_get_rest(buffer), "12345bcdef", 10), 0); }
static int packet_send2(ssh_session session) { unsigned int blocksize = (session->current_crypto ? session->current_crypto->out_cipher->blocksize : 8); uint32_t currentlen = buffer_get_rest_len(session->out_buffer); unsigned char *hmac = NULL; char padstring[32] = {0}; int rc = SSH_ERROR; uint32_t finallen; uint8_t padding; enter_function(); ssh_log(session, SSH_LOG_PACKET, "Writing on the wire a packet having %u bytes before", currentlen); #if defined(HAVE_LIBZ) && defined(WITH_LIBZ) if (session->current_crypto && session->current_crypto->do_compress_out && buffer_get_rest_len(session->out_buffer)) { ssh_log(session, SSH_LOG_PACKET, "Compressing out_buffer ..."); if (compress_buffer(session,session->out_buffer) < 0) { goto error; } currentlen = buffer_get_rest_len(session->out_buffer); } #endif padding = (blocksize - ((currentlen +5) % blocksize)); if(padding < 4) { padding += blocksize; } if (session->current_crypto) { ssh_get_random(padstring, padding, 0); } else { memset(padstring,0,padding); } finallen = htonl(currentlen + padding + 1); ssh_log(session, SSH_LOG_PACKET, "%d bytes after comp + %d padding bytes = %lu bytes packet", currentlen, padding, (long unsigned int) ntohl(finallen)); if (buffer_prepend_data(session->out_buffer, &padding, sizeof(uint8_t)) < 0) { goto error; } if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) { goto error; } if (buffer_add_data(session->out_buffer, padstring, padding) < 0) { goto error; } #ifdef WITH_PCAP if(session->pcap_ctx){ ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT, buffer_get_rest(session->out_buffer),buffer_get_rest_len(session->out_buffer) ,buffer_get_rest_len(session->out_buffer)); } #endif hmac = packet_encrypt(session, buffer_get_rest(session->out_buffer), buffer_get_rest_len(session->out_buffer)); if (hmac) { if (buffer_add_data(session->out_buffer, hmac, 20) < 0) { goto error; } } rc = ssh_packet_write(session); session->send_seq++; if (buffer_reinit(session->out_buffer) < 0) { rc = SSH_ERROR; } error: leave_function(); return rc; /* SSH_OK, AGAIN or ERROR */ }
static int packet_send2(ssh_session session) { unsigned int blocksize = (session->current_crypto ? session->current_crypto->out_cipher->blocksize : 8); uint32_t currentlen = buffer_get_rest_len(session->out_buffer); unsigned char *hmac = NULL; char padstring[32] = {0}; int rc = SSH_ERROR; uint32_t finallen,payloadsize,compsize; uint8_t padding; payloadsize = currentlen; #ifdef WITH_ZLIB if (session->current_crypto && session->current_crypto->do_compress_out && buffer_get_rest_len(session->out_buffer)) { if (compress_buffer(session,session->out_buffer) < 0) { goto error; } currentlen = buffer_get_rest_len(session->out_buffer); } #endif /* WITH_ZLIB */ compsize = currentlen; padding = (blocksize - ((currentlen +5) % blocksize)); if(padding < 4) { padding += blocksize; } if (session->current_crypto) { ssh_get_random(padstring, padding, 0); } else { memset(padstring,0,padding); } finallen = htonl(currentlen + padding + 1); if (buffer_prepend_data(session->out_buffer, &padding, sizeof(uint8_t)) < 0) { goto error; } if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(uint32_t)) < 0) { goto error; } if (buffer_add_data(session->out_buffer, padstring, padding) < 0) { goto error; } #ifdef WITH_PCAP if(session->pcap_ctx){ ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT, buffer_get_rest(session->out_buffer),buffer_get_rest_len(session->out_buffer) ,buffer_get_rest_len(session->out_buffer)); } #endif hmac = packet_encrypt(session, buffer_get_rest(session->out_buffer), buffer_get_rest_len(session->out_buffer)); if (hmac) { if (buffer_add_data(session->out_buffer, hmac, 20) < 0) { goto error; } } rc = ssh_packet_write(session); session->send_seq++; SSH_LOG(SSH_LOG_PACKET, "packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]", ntohl(finallen), padding, compsize, payloadsize); if (buffer_reinit(session->out_buffer) < 0) { rc = SSH_ERROR; } error: return rc; /* SSH_OK, AGAIN or ERROR */ }
static int packet_send1(SSH_SESSION *session) { unsigned int blocksize = (session->current_crypto ? session->current_crypto->out_cipher->blocksize : 8); u32 currentlen = buffer_get_len(session->out_buffer) + sizeof(u32); char padstring[32] = {0}; int rc = SSH_ERROR; u32 finallen; u32 crc; u8 padding; enter_function(); ssh_log(session,SSH_LOG_PACKET,"Sending a %d bytes long packet",currentlen); /* TODO FIXME #if defined(HAVE_LIBZ) && defined(WITH_LIBZ) if (session->current_crypto && session->current_crypto->do_compress_out) { if (compress_buffer(session, session->out_buffer) < 0) { goto error; } currentlen = buffer_get_len(session->out_buffer); } #endif */ padding = blocksize - (currentlen % blocksize); if (session->current_crypto) { ssh_get_random(padstring, padding, 0); } else { memset(padstring, 0, padding); } finallen = htonl(currentlen); ssh_log(session, SSH_LOG_PACKET, "%d bytes after comp + %d padding bytes = %d bytes packet", currentlen, padding, ntohl(finallen)); if (buffer_prepend_data(session->out_buffer, &padstring, padding) < 0) { goto error; } if (buffer_prepend_data(session->out_buffer, &finallen, sizeof(u32)) < 0) { goto error; } crc = ssh_crc32(buffer_get(session->out_buffer) + sizeof(u32), buffer_get_len(session->out_buffer) - sizeof(u32)); if (buffer_add_u32(session->out_buffer, ntohl(crc)) < 0) { goto error; } #ifdef DEBUG_CRYPTO ssh_print_hexa("Clear packet", buffer_get(session->out_buffer), buffer_get_len(session->out_buffer)); #endif packet_encrypt(session, buffer_get(session->out_buffer) + sizeof(u32), buffer_get_len(session->out_buffer) - sizeof(u32)); #ifdef DEBUG_CRYPTO ssh_print_hexa("encrypted packet",buffer_get(session->out_buffer), buffer_get_len(session->out_buffer)); #endif if (ssh_socket_write(session->socket, buffer_get(session->out_buffer), buffer_get_len(session->out_buffer)) == SSH_ERROR) { goto error; } rc = packet_flush(session, 0); session->send_seq++; if (buffer_reinit(session->out_buffer) < 0) { rc = SSH_ERROR; } error: leave_function(); return rc; /* SSH_OK, AGAIN or ERROR */ }