mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-09 09:54:25 +09:00
packet: Reformat packet_send2()
Signed-off-by: Andreas Schneider <asn@cryptomilk.org> Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
199
src/packet.c
199
src/packet.c
@@ -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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user