aboutsummaryrefslogtreecommitdiff
path: root/src/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/packet.c')
-rw-r--r--src/packet.c43
1 files changed, 29 insertions, 14 deletions
diff --git a/src/packet.c b/src/packet.c
index b66e3d22..f6fb6bff 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -555,6 +555,8 @@ static int ssh_packet_write(ssh_session session) {
static int packet_send2(ssh_session session) {
unsigned int blocksize = (session->current_crypto ?
session->current_crypto->out_cipher->blocksize : 8);
+ unsigned int lenfield_blocksize = (session->current_crypto ?
+ session->current_crypto->out_cipher->lenfield_blocksize : 0);
enum ssh_hmac_e hmac_type = (session->current_crypto ?
session->current_crypto->out_hmac : session->next_crypto->out_hmac);
uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
@@ -563,8 +565,7 @@ static int packet_send2(ssh_session session) {
int rc = SSH_ERROR;
uint32_t finallen,payloadsize,compsize;
uint8_t padding;
-
- uint8_t header[sizeof(padding) + sizeof(finallen)] = { 0 };
+ ssh_buffer header_buffer = ssh_buffer_new();
payloadsize = currentlen;
#ifdef WITH_ZLIB
@@ -578,20 +579,30 @@ static int packet_send2(ssh_session session) {
}
#endif /* WITH_ZLIB */
compsize = currentlen;
- padding = (blocksize - ((currentlen +5) % blocksize));
+ /* compressed payload + packet len (4) + padding len (1) */
+ /* totallen - lenfield_blocksize must be equal to 0 (mod blocksize) */
+ padding = (blocksize - ((blocksize - lenfield_blocksize + currentlen + 5) % blocksize));
if(padding < 4) {
padding += blocksize;
}
- if (session->current_crypto) {
+ if (session->current_crypto != NULL) {
ssh_get_random(padstring, padding, 0);
}
- finallen = htonl(currentlen + padding + 1);
+ if (header_buffer == NULL){
+ ssh_set_error_oom(session);
+ goto error;
+ }
+ finallen = currentlen + padding + 1;
+ rc = ssh_buffer_pack(header_buffer, "db", finallen, padding);
+ if (rc == SSH_ERROR){
+ goto error;
+ }
- memcpy(&header[0], &finallen, sizeof(finallen));
- header[sizeof(finallen)] = padding;
- rc = ssh_buffer_prepend_data(session->out_buffer, &header, sizeof(header));
+ rc = ssh_buffer_prepend_data(session->out_buffer,
+ ssh_buffer_get(header_buffer),
+ ssh_buffer_get_len(header_buffer));
if (rc < 0) {
goto error;
}
@@ -600,10 +611,12 @@ static int packet_send2(ssh_session session) {
goto error;
}
#ifdef WITH_PCAP
- if(session->pcap_ctx){
- ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,
- ssh_buffer_get(session->out_buffer),ssh_buffer_get_len(session->out_buffer)
- ,ssh_buffer_get_len(session->out_buffer));
+ if (session->pcap_ctx) {
+ ssh_pcap_context_write(session->pcap_ctx,
+ SSH_PCAP_DIR_OUT,
+ ssh_buffer_get(session->out_buffer),
+ ssh_buffer_get_len(session->out_buffer),
+ ssh_buffer_get_len(session->out_buffer));
}
#endif
hmac = ssh_packet_encrypt(session, ssh_buffer_get(session->out_buffer),
@@ -624,12 +637,14 @@ static int packet_send2(ssh_session session) {
SSH_LOG(SSH_LOG_PACKET,
"packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
- ntohl(finallen), padding, compsize, payloadsize);
+ finallen, padding, compsize, payloadsize);
if (ssh_buffer_reinit(session->out_buffer) < 0) {
rc = SSH_ERROR;
}
error:
-
+ if (header_buffer != NULL) {
+ ssh_buffer_free(header_buffer);
+ }
return rc; /* SSH_OK, AGAIN or ERROR */
}