1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-02-04 14:12:24 +00:00

Factor out code for constructing lists of algorithms for SSH-2 KEXINIT.

This commit is contained in:
Ben Harris 2014-11-03 00:55:21 +00:00
parent bb09a3936e
commit cdb80025b7

72
ssh.c
View File

@ -5926,7 +5926,8 @@ static void ssh1_protocol(Ssh ssh, void *vin, int inlen,
/* /*
* Utility routine for decoding comma-separated strings in KEXINIT. * Utility routine for decoding comma-separated strings in KEXINIT.
*/ */
static int in_commasep_string(char *needle, char *haystack, int haylen) static int in_commasep_string(char const *needle, char const *haystack,
int haylen)
{ {
int needlen; int needlen;
if (!needle || !haystack) /* protect against null pointers */ if (!needle || !haystack) /* protect against null pointers */
@ -5957,7 +5958,8 @@ static int in_commasep_string(char *needle, char *haystack, int haylen)
/* /*
* Similar routine for checking whether we have the first string in a list. * Similar routine for checking whether we have the first string in a list.
*/ */
static int first_in_commasep_string(char *needle, char *haystack, int haylen) static int first_in_commasep_string(char const *needle, char const *haystack,
int haylen)
{ {
int needlen; int needlen;
if (!needle || !haystack) /* protect against null pointers */ if (!needle || !haystack) /* protect against null pointers */
@ -5975,6 +5977,19 @@ static int first_in_commasep_string(char *needle, char *haystack, int haylen)
return 0; return 0;
} }
/*
* Add a value to the comma-separated string at the end of the packet.
* If the value is already in the string, don't bother adding it again.
*/
static void ssh2_pkt_addstring_commasep(struct Packet *pkt, const char *data)
{
if (in_commasep_string(data, (char *)pkt->data + pkt->savedpos,
pkt->length - pkt->savedpos)) return;
if (pkt->length - pkt->savedpos > 0)
ssh_pkt_addstring_str(pkt, ",");
ssh_pkt_addstring_str(pkt, data);
}
/* /*
* SSH-2 key creation method. * SSH-2 key creation method.
@ -6070,7 +6085,7 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
begin_key_exchange: begin_key_exchange:
ssh->pkt_kctx = SSH2_PKTCTX_NOKEX; ssh->pkt_kctx = SSH2_PKTCTX_NOKEX;
{ {
int i, j, k, commalist_started; int i, j, k;
/* /*
* Set up the preferred key exchange. (NULL => warn below here) * Set up the preferred key exchange. (NULL => warn below here)
@ -6168,16 +6183,11 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte()); ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte());
/* List key exchange algorithms. */ /* List key exchange algorithms. */
ssh2_pkt_addstring_start(s->pktout); ssh2_pkt_addstring_start(s->pktout);
commalist_started = 0;
for (i = 0; i < s->n_preferred_kex; i++) { for (i = 0; i < s->n_preferred_kex; i++) {
const struct ssh_kexes *k = s->preferred_kex[i]; const struct ssh_kexes *k = s->preferred_kex[i];
if (!k) continue; /* warning flag */ if (!k) continue; /* warning flag */
for (j = 0; j < k->nkexes; j++) { for (j = 0; j < k->nkexes; j++)
if (commalist_started) ssh2_pkt_addstring_commasep(s->pktout, k->list[j]->name);
ssh2_pkt_addstring_str(s->pktout, ",");
ssh2_pkt_addstring_str(s->pktout, k->list[j]->name);
commalist_started = 1;
}
} }
/* List server host key algorithms. */ /* List server host key algorithms. */
if (!s->got_session_id) { if (!s->got_session_id) {
@ -6186,11 +6196,8 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
* we're prepared to cope with. * we're prepared to cope with.
*/ */
ssh2_pkt_addstring_start(s->pktout); ssh2_pkt_addstring_start(s->pktout);
for (i = 0; i < lenof(hostkey_algs); i++) { for (i = 0; i < lenof(hostkey_algs); i++)
ssh2_pkt_addstring_str(s->pktout, hostkey_algs[i]->name); ssh2_pkt_addstring_commasep(s->pktout, hostkey_algs[i]->name);
if (i < lenof(hostkey_algs) - 1)
ssh2_pkt_addstring_str(s->pktout, ",");
}
} else { } else {
/* /*
* In subsequent key exchanges, we list only the kex * In subsequent key exchanges, we list only the kex
@ -6205,26 +6212,18 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
/* List encryption algorithms (client->server then server->client). */ /* List encryption algorithms (client->server then server->client). */
for (k = 0; k < 2; k++) { for (k = 0; k < 2; k++) {
ssh2_pkt_addstring_start(s->pktout); ssh2_pkt_addstring_start(s->pktout);
commalist_started = 0;
for (i = 0; i < s->n_preferred_ciphers; i++) { for (i = 0; i < s->n_preferred_ciphers; i++) {
const struct ssh2_ciphers *c = s->preferred_ciphers[i]; const struct ssh2_ciphers *c = s->preferred_ciphers[i];
if (!c) continue; /* warning flag */ if (!c) continue; /* warning flag */
for (j = 0; j < c->nciphers; j++) { for (j = 0; j < c->nciphers; j++)
if (commalist_started) ssh2_pkt_addstring_commasep(s->pktout, c->list[j]->name);
ssh2_pkt_addstring_str(s->pktout, ",");
ssh2_pkt_addstring_str(s->pktout, c->list[j]->name);
commalist_started = 1;
}
} }
} }
/* List MAC algorithms (client->server then server->client). */ /* List MAC algorithms (client->server then server->client). */
for (j = 0; j < 2; j++) { for (j = 0; j < 2; j++) {
ssh2_pkt_addstring_start(s->pktout); ssh2_pkt_addstring_start(s->pktout);
for (i = 0; i < s->nmacs; i++) { for (i = 0; i < s->nmacs; i++)
ssh2_pkt_addstring_str(s->pktout, s->maclist[i]->name); ssh2_pkt_addstring_commasep(s->pktout, s->maclist[i]->name);
if (i < s->nmacs - 1)
ssh2_pkt_addstring_str(s->pktout, ",");
}
} }
/* List client->server compression algorithms, /* List client->server compression algorithms,
* then server->client compression algorithms. (We use the * then server->client compression algorithms. (We use the
@ -6233,25 +6232,18 @@ static void do_ssh2_transport(Ssh ssh, void *vin, int inlen,
ssh2_pkt_addstring_start(s->pktout); ssh2_pkt_addstring_start(s->pktout);
assert(lenof(compressions) > 1); assert(lenof(compressions) > 1);
/* Prefer non-delayed versions */ /* Prefer non-delayed versions */
ssh2_pkt_addstring_str(s->pktout, s->preferred_comp->name); ssh2_pkt_addstring_commasep(s->pktout, s->preferred_comp->name);
/* We don't even list delayed versions of algorithms until /* We don't even list delayed versions of algorithms until
* they're allowed to be used, to avoid a race. See the end of * they're allowed to be used, to avoid a race. See the end of
* this function. */ * this function. */
if (s->userauth_succeeded && s->preferred_comp->delayed_name) { if (s->userauth_succeeded && s->preferred_comp->delayed_name)
ssh2_pkt_addstring_str(s->pktout, ","); ssh2_pkt_addstring_commasep(s->pktout,
ssh2_pkt_addstring_str(s->pktout,
s->preferred_comp->delayed_name); s->preferred_comp->delayed_name);
}
for (i = 0; i < lenof(compressions); i++) { for (i = 0; i < lenof(compressions); i++) {
const struct ssh_compress *c = compressions[i]; const struct ssh_compress *c = compressions[i];
if (c != s->preferred_comp) { ssh2_pkt_addstring_commasep(s->pktout, c->name);
ssh2_pkt_addstring_str(s->pktout, ","); if (s->userauth_succeeded && c->delayed_name)
ssh2_pkt_addstring_str(s->pktout, c->name); ssh2_pkt_addstring_commasep(s->pktout, c->delayed_name);
if (s->userauth_succeeded && c->delayed_name) {
ssh2_pkt_addstring_str(s->pktout, ",");
ssh2_pkt_addstring_str(s->pktout, c->delayed_name);
}
}
} }
} }
/* List client->server languages. Empty list. */ /* List client->server languages. Empty list. */