Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Tatham <anakin@pobox.com>2022-04-28 15:02:00 +0300
committerSimon Tatham <anakin@pobox.com>2022-04-28 15:11:51 +0300
commit42dcd465ab19d0dab1cc081b5f7b35c60be2577b (patch)
tree7bffc1a531422eacdd77c8207d145cfc94ab095a /ssh/transport2.c
parent7b0292b2c359ab37811d658c4afe49d721b6253d (diff)
ssh2_scan_kexinits: dynamically allocate server_hostkeys[].
In commit 7d44e35bb3780c0 I introduced a bug: we were providing an array of MAXKEXLIST ints to ssh2_scan_kexinits() to write a list of server-supplied host keys into, and when MAXKEXLIST stopped being a thing, I mindlessly replaced it with an array dynamically allocated to the number of host key types we'd offered the server. But we return a list of host key types the _server_ offered _us_ (and that we can speak at all), which isn't necessarily the same thing. In particular, if you deliberately ask to cache a new host key type from the specials menu, we send a KEXINIT offering just _one_ host key type, namely the one you've asked for. But that loop still writes down all the key types it gets back from the server, which is (almost certainly) more than one. So the array overflows. In that situation we don't really need the returned array of key types at all, but it's easier to just make it work than to add conditionals. Replaced it with a dynamically grown array in the usual sort of way.
Diffstat (limited to 'ssh/transport2.c')
-rw-r--r--ssh/transport2.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/ssh/transport2.c b/ssh/transport2.c
index ebb76be1..7265444f 100644
--- a/ssh/transport2.c
+++ b/ssh/transport2.c
@@ -931,6 +931,11 @@ static void ssh2_write_kexinit_lists(
put_stringz(pktout, "");
}
+struct server_hostkeys {
+ int *indices;
+ size_t n, size;
+};
+
static bool ssh2_scan_kexinits(
ptrlen client_kexinit, ptrlen server_kexinit,
struct kexinit_algorithm_list kexlists[NKEXLIST],
@@ -938,7 +943,7 @@ static bool ssh2_scan_kexinits(
transport_direction *cs, transport_direction *sc,
bool *warn_kex, bool *warn_hk, bool *warn_cscipher, bool *warn_sccipher,
Ssh *ssh, bool *ignore_guess_cs_packet, bool *ignore_guess_sc_packet,
- int *n_server_hostkeys, int *server_hostkeys, unsigned *hkflags,
+ struct server_hostkeys *server_hostkeys, unsigned *hkflags,
bool *can_send_ext_info)
{
BinarySource client[1], server[1];
@@ -1160,13 +1165,13 @@ static bool ssh2_scan_kexinits(
* one or not. We return these as a list of indices into the
* constant ssh2_hostkey_algs[] array.
*/
- *n_server_hostkeys = 0;
-
ptrlen list = slists[KEXLIST_HOSTKEY];
for (ptrlen word; get_commasep_word(&list, &word) ;) {
for (i = 0; i < lenof(ssh2_hostkey_algs); i++)
if (ptrlen_eq_string(word, ssh2_hostkey_algs[i].alg->ssh_id)) {
- server_hostkeys[(*n_server_hostkeys)++] = i;
+ sgrowarray(server_hostkeys->indices, server_hostkeys->size,
+ server_hostkeys->n);
+ server_hostkeys->indices[server_hostkeys->n++] = i;
break;
}
}
@@ -1315,17 +1320,16 @@ static void ssh2_transport_process_queue(PacketProtocolLayer *ppl)
* selected algorithm identifiers.
*/
{
- int nhk, i, j;
- int *hks = snewn(s->kexlists[KEXLIST_HOSTKEY].nalgs, int);
+ struct server_hostkeys hks = { NULL, 0, 0 };
if (!ssh2_scan_kexinits(
ptrlen_from_strbuf(s->client_kexinit),
ptrlen_from_strbuf(s->server_kexinit),
s->kexlists, &s->kex_alg, &s->hostkey_alg, s->cstrans,
s->sctrans, &s->warn_kex, &s->warn_hk, &s->warn_cscipher,
- &s->warn_sccipher, s->ppl.ssh, NULL, &s->ignorepkt, &nhk, hks,
+ &s->warn_sccipher, s->ppl.ssh, NULL, &s->ignorepkt, &hks,
&s->hkflags, &s->can_send_ext_info)) {
- sfree(hks);
+ sfree(hks.indices);
return; /* false means a fatal error function was called */
}
@@ -1341,8 +1345,8 @@ static void ssh2_transport_process_queue(PacketProtocolLayer *ppl)
*/
s->n_uncert_hostkeys = 0;
- for (i = 0; i < nhk; i++) {
- j = hks[i];
+ for (int i = 0; i < hks.n; i++) {
+ int j = hks.indices[i];
if (ssh2_hostkey_algs[j].alg != s->hostkey_alg &&
ssh2_hostkey_algs[j].alg->cache_id &&
!have_ssh_host_key(s->savedhost, s->savedport,
@@ -1351,7 +1355,7 @@ static void ssh2_transport_process_queue(PacketProtocolLayer *ppl)
}
}
- sfree(hks);
+ sfree(hks.indices);
}
if (s->warn_kex) {