packet: Reformat packet_send2()

Signed-off-by: Andreas Schneider <asn@cryptomilk.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Andreas Schneider
2018-10-07 14:23:57 +02:00
parent 3245b50795
commit 422376efd4

View File

@@ -551,106 +551,121 @@ static int ssh_packet_write(ssh_session session) {
return rc; return rc;
} }
static int packet_send2(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 blocksize =
unsigned int lenfield_blocksize = (session->current_crypto ? (session->current_crypto ?
session->current_crypto->out_cipher->lenfield_blocksize : 0); session->current_crypto->out_cipher->blocksize : 8);
enum ssh_hmac_e hmac_type = (session->current_crypto ? unsigned int lenfield_blocksize =
session->current_crypto->out_hmac : session->next_crypto->out_hmac); (session->current_crypto ?
uint32_t currentlen = ssh_buffer_get_len(session->out_buffer); session->current_crypto->out_cipher->lenfield_blocksize : 0);
unsigned char *hmac = NULL; enum ssh_hmac_e hmac_type =
char padstring[32] = { 0 }; (session->current_crypto ?
int rc = SSH_ERROR; session->current_crypto->out_hmac : session->next_crypto->out_hmac);
uint32_t finallen,payloadsize,compsize; uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
uint8_t padding; unsigned char *hmac = NULL;
ssh_buffer header_buffer = ssh_buffer_new(); uint8_t padstring[32] = { 0 };
uint8_t padding;
uint32_t finallen, payloadsize, compsize;
ssh_buffer header_buffer = ssh_buffer_new();
int rc = SSH_ERROR;
payloadsize = currentlen; payloadsize = currentlen;
#ifdef WITH_ZLIB #ifdef WITH_ZLIB
if (session->current_crypto if (session->current_crypto != NULL &&
&& session->current_crypto->do_compress_out session->current_crypto->do_compress_out &&
&& ssh_buffer_get_len(session->out_buffer)) { ssh_buffer_get_len(session->out_buffer) > 0) {
if (compress_buffer(session,session->out_buffer) < 0) { rc = compress_buffer(session,session->out_buffer);
goto error; if (rc < 0) {
goto error;
}
currentlen = ssh_buffer_get_len(session->out_buffer);
} }
currentlen = ssh_buffer_get_len(session->out_buffer);
}
#endif /* WITH_ZLIB */ #endif /* WITH_ZLIB */
compsize = currentlen; compsize = currentlen;
/* compressed payload + packet len (4) + padding len (1) */ /* compressed payload + packet len (4) + padding len (1) */
/* totallen - lenfield_blocksize must be equal to 0 (mod blocksize) */ /* totallen - lenfield_blocksize must be equal to 0 (mod blocksize) */
padding = (blocksize - ((blocksize - lenfield_blocksize + currentlen + 5) % blocksize)); padding = (blocksize - ((blocksize - lenfield_blocksize + currentlen + 5) % blocksize));
if(padding < 4) { if (padding < 4) {
padding += blocksize; padding += blocksize;
}
if (session->current_crypto != NULL) {
int ok;
ok = ssh_get_random(padstring, padding, 0);
if (!ok) {
ssh_set_error(session, SSH_FATAL, "PRNG error");
goto error;
}
}
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;
}
rc = ssh_buffer_prepend_data(session->out_buffer,
ssh_buffer_get(header_buffer),
ssh_buffer_get_len(header_buffer));
if (rc < 0) {
goto error;
}
rc = ssh_buffer_add_data(session->out_buffer, padstring, padding);
if (rc < 0) {
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));
}
#endif
hmac = ssh_packet_encrypt(session, ssh_buffer_get(session->out_buffer),
ssh_buffer_get_len(session->out_buffer));
if (hmac) {
rc = ssh_buffer_add_data(session->out_buffer, hmac, hmac_digest_len(hmac_type));
if (rc < 0) {
goto error;
} }
}
rc = ssh_packet_write(session); if (session->current_crypto != NULL) {
session->send_seq++; int ok;
if (session->raw_counter != NULL) {
session->raw_counter->out_bytes += payloadsize; ok = ssh_get_random(padstring, padding, 0);
session->raw_counter->out_packets++; if (!ok) {
} ssh_set_error(session, SSH_FATAL, "PRNG error");
goto error;
}
}
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;
}
rc = ssh_buffer_prepend_data(session->out_buffer,
ssh_buffer_get(header_buffer),
ssh_buffer_get_len(header_buffer));
if (rc < 0) {
goto error;
}
rc = ssh_buffer_add_data(session->out_buffer, padstring, padding);
if (rc < 0) {
goto error;
}
#ifdef WITH_PCAP
if (session->pcap_ctx != NULL) {
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),
ssh_buffer_get_len(session->out_buffer));
if (hmac != NULL) {
rc = ssh_buffer_add_data(session->out_buffer,
hmac,
hmac_digest_len(hmac_type));
if (rc < 0) {
goto error;
}
}
rc = ssh_packet_write(session);
session->send_seq++;
if (session->raw_counter != NULL) {
session->raw_counter->out_bytes += payloadsize;
session->raw_counter->out_packets++;
}
SSH_LOG(SSH_LOG_PACKET,
"packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
finallen, padding, compsize, payloadsize);
rc = ssh_buffer_reinit(session->out_buffer);
if (rc < 0) {
rc = SSH_ERROR;
}
SSH_LOG(SSH_LOG_PACKET,
"packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
finallen, padding, compsize, payloadsize);
if (ssh_buffer_reinit(session->out_buffer) < 0) {
rc = SSH_ERROR;
}
error: error:
if (header_buffer != NULL) { if (header_buffer != NULL) {
ssh_buffer_free(header_buffer); ssh_buffer_free(header_buffer);
} }
return rc; /* SSH_OK, AGAIN or ERROR */ return rc; /* SSH_OK, AGAIN or ERROR */
} }