mirror of
https://github.com/openssh/libopenssh
synced 2026-04-23 05:06:33 +00:00
fix some kex-related leaks
This commit is contained in:
committed by
Markus Friedl
parent
06cbafed01
commit
4a3c3a7baf
40
ssh/kex.c
40
ssh/kex.c
@@ -310,9 +310,42 @@ kex_new(struct ssh *ssh, char *proposal[PROPOSAL_MAX], Kex **kexp)
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
kex_free_newkeys(Newkeys *newkeys)
|
||||
{
|
||||
if (newkeys == NULL)
|
||||
return;
|
||||
if (newkeys->enc.key) {
|
||||
bzero(newkeys->enc.key, newkeys->enc.key_len);
|
||||
free(newkeys->enc.key);
|
||||
newkeys->enc.key = NULL;
|
||||
}
|
||||
if (newkeys->enc.iv) {
|
||||
bzero(newkeys->enc.iv, newkeys->enc.block_size);
|
||||
free(newkeys->enc.iv);
|
||||
newkeys->enc.iv = NULL;
|
||||
}
|
||||
free(newkeys->enc.name);
|
||||
bzero(&newkeys->enc, sizeof(newkeys->enc));
|
||||
free(newkeys->comp.name);
|
||||
bzero(&newkeys->comp, sizeof(newkeys->comp));
|
||||
mac_clear(&newkeys->mac);
|
||||
if (newkeys->mac.key) {
|
||||
bzero(newkeys->mac.key, newkeys->mac.key_len);
|
||||
free(newkeys->mac.key);
|
||||
newkeys->mac.key = NULL;
|
||||
}
|
||||
free(newkeys->mac.name);
|
||||
bzero(&newkeys->mac, sizeof(newkeys->mac));
|
||||
bzero(newkeys, sizeof(*newkeys));
|
||||
free(newkeys);
|
||||
}
|
||||
|
||||
void
|
||||
kex_free(Kex *kex)
|
||||
{
|
||||
u_int mode;
|
||||
|
||||
if (kex->peer != NULL)
|
||||
sshbuf_free(kex->peer);
|
||||
if (kex->my != NULL)
|
||||
@@ -321,6 +354,10 @@ kex_free(Kex *kex)
|
||||
DH_free(kex->dh);
|
||||
if (kex->ec_client_key)
|
||||
EC_KEY_free(kex->ec_client_key);
|
||||
for (mode = 0; mode < MODE_MAX; mode++) {
|
||||
kex_free_newkeys(kex->newkeys[mode]);
|
||||
kex->newkeys[mode] = NULL;
|
||||
}
|
||||
free(kex);
|
||||
}
|
||||
|
||||
@@ -610,7 +647,7 @@ derive_key(struct ssh *ssh, int id, u_int need, u_char *hash, u_int hashlen,
|
||||
r = 0;
|
||||
out:
|
||||
if (digest)
|
||||
free (digest);
|
||||
free(digest);
|
||||
if (b)
|
||||
sshbuf_free(b);
|
||||
return r;
|
||||
@@ -635,6 +672,7 @@ kex_derive_keys(struct ssh *ssh, u_char *hash, u_int hashlen,
|
||||
}
|
||||
}
|
||||
for (mode = 0; mode < MODE_MAX; mode++) {
|
||||
kex_free_newkeys(ssh->current_keys[mode]);
|
||||
ssh->current_keys[mode] = kex->newkeys[mode];
|
||||
kex->newkeys[mode] = NULL;
|
||||
ctos = (!kex->server && mode == MODE_OUT) ||
|
||||
|
||||
@@ -137,6 +137,7 @@ int kex_names_valid(const char *);
|
||||
|
||||
int kex_new(struct ssh *, char *[PROPOSAL_MAX], Kex **);
|
||||
int kex_setup(struct ssh *, char *[PROPOSAL_MAX]);
|
||||
void kex_free_newkeys(Newkeys *);
|
||||
void kex_free(Kex *);
|
||||
|
||||
int kex_buf2prop(struct sshbuf *, int *, char ***);
|
||||
|
||||
@@ -530,6 +530,7 @@ ssh_packet_close(struct ssh *ssh)
|
||||
{
|
||||
struct session_state *state = ssh->state;
|
||||
int r;
|
||||
u_int mode;
|
||||
|
||||
if (!state->initialized)
|
||||
return;
|
||||
@@ -545,6 +546,8 @@ ssh_packet_close(struct ssh *ssh)
|
||||
sshbuf_free(state->output);
|
||||
sshbuf_free(state->outgoing_packet);
|
||||
sshbuf_free(state->incoming_packet);
|
||||
for (mode = 0; mode < MODE_MAX; mode++)
|
||||
kex_free_newkeys(state->newkeys[mode]);
|
||||
if (state->compression_buffer) {
|
||||
sshbuf_free(state->compression_buffer);
|
||||
if (ssh->state->compression_out_started) {
|
||||
|
||||
@@ -96,9 +96,15 @@ ssh_init(struct ssh **sshp, int is_server, struct kex_params *kex_params)
|
||||
void
|
||||
ssh_free(struct ssh *ssh)
|
||||
{
|
||||
u_int mode;
|
||||
|
||||
ssh_packet_close(ssh);
|
||||
if (ssh->kex);
|
||||
if (ssh->kex)
|
||||
kex_free(ssh->kex);
|
||||
for (mode = 0; mode < MODE_MAX; mode++) {
|
||||
kex_free_newkeys(ssh->current_keys[mode]);
|
||||
ssh->current_keys[mode] = NULL;
|
||||
}
|
||||
free(ssh);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ do_kex_with_key(char *kex, int key_type, int bits)
|
||||
ASSERT_INT_EQ(ssh_add_hostkey(client, public), 0);
|
||||
TEST_DONE();
|
||||
|
||||
TEST_START(kex);
|
||||
TEST_START("kex");
|
||||
run_kex(client, server);
|
||||
TEST_DONE();
|
||||
|
||||
@@ -148,6 +148,12 @@ do_kex_with_key(char *kex, int key_type, int bits)
|
||||
ASSERT_INT_EQ(kex_send_kexinit(client), 0);
|
||||
run_kex(client, server2);
|
||||
TEST_DONE();
|
||||
|
||||
TEST_START("cleanup");
|
||||
ssh_free(client);
|
||||
ssh_free(server);
|
||||
ssh_free(server2);
|
||||
TEST_DONE();
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
Reference in New Issue
Block a user