1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

Uppity: allow CLI override of the KEXINIT strings.

This is an obviously useful test feature, since if nothing else it
will let me exercise every individual crypto primitive, even the ones
that the client-side configuration is too coarse-grained to describe
in detail (such as the difference between CBC and CTR mode versions of
the same cipher).
This commit is contained in:
Simon Tatham 2019-03-31 08:35:31 +01:00
parent 8d84272d80
commit b494ecfcfc
5 changed files with 55 additions and 13 deletions

7
ssh.h
View File

@ -742,6 +742,13 @@ struct ssh_kexes {
const ssh_kex *const *list;
};
/* Indices of the negotiation strings in the KEXINIT packet */
enum kexlist {
KEXLIST_KEX, KEXLIST_HOSTKEY, KEXLIST_CSCIPHER, KEXLIST_SCCIPHER,
KEXLIST_CSMAC, KEXLIST_SCMAC, KEXLIST_CSCOMP, KEXLIST_SCCOMP,
NKEXLIST
};
struct ssh_keyalg {
/* Constructors that create an ssh_key */
ssh_key *(*new_pub) (const ssh_keyalg *self, ptrlen pub);

View File

@ -9,6 +9,7 @@
#include "sshbpp.h"
#include "sshppl.h"
#include "sshcr.h"
#include "sshserver.h"
#include "storage.h"
#include "ssh2transport.h"
#include "mpint.h"
@ -417,7 +418,7 @@ PktIn *ssh2_transport_pop(struct ssh2_transport_state *s)
static void ssh2_write_kexinit_lists(
BinarySink *pktout,
struct kexinit_algorithm kexlists[NKEXLIST][MAXKEXLIST],
Conf *conf, int remote_bugs,
Conf *conf, const SshServerConfig *ssc, int remote_bugs,
const char *hk_host, int hk_port, const ssh_keyalg *hk_prev,
ssh_transient_hostkey_cache *thc,
ssh_key *const *our_hostkeys, int our_nhostkeys,
@ -738,9 +739,13 @@ static void ssh2_write_kexinit_lists(
*/
for (i = 0; i < NKEXLIST; i++) {
strbuf *list = strbuf_new();
for (j = 0; j < MAXKEXLIST; j++) {
if (kexlists[i][j].name == NULL) break;
add_to_commasep(list, kexlists[i][j].name);
if (ssc && ssc->kex_override[i].ptr) {
put_datapl(list, ssc->kex_override[i]);
} else {
for (j = 0; j < MAXKEXLIST; j++) {
if (kexlists[i][j].name == NULL) break;
add_to_commasep(list, kexlists[i][j].name);
}
}
put_stringsb(pktout, list);
}
@ -822,12 +827,26 @@ static bool ssh2_scan_kexinits(
selected[i] = NULL;
for (j = 0; j < MAXKEXLIST; j++) {
if (ptrlen_eq_string(found, kexlists[i][j].name)) {
if (kexlists[i][j].name &&
ptrlen_eq_string(found, kexlists[i][j].name)) {
selected[i] = &kexlists[i][j];
break;
}
}
assert(selected[i]); /* kexlists[] must cover one of the inputs */
if (!selected[i]) {
/*
* In the client, this should never happen! But in the
* server, where we allow manual override on the command
* line of the exact KEXINIT strings, it can happen
* because the command line contained a typo. So we
* produce a reasonably useful message instead of an
* assertion failure.
*/
ssh_sw_abort(ssh, "Selected %s \"%.*s\" does not correspond to "
"any supported algorithm",
kexlist_descr[i], PTRLEN_PRINTF(found));
return false;
}
/*
* If the kex or host key algorithm is not the first one in
@ -1063,7 +1082,7 @@ static void ssh2_transport_process_queue(PacketProtocolLayer *ppl)
random_read(strbuf_append(s->outgoing_kexinit, 16), 16);
ssh2_write_kexinit_lists(
BinarySink_UPCAST(s->outgoing_kexinit), s->kexlists,
s->conf, s->ppl.remote_bugs,
s->conf, s->ssc, s->ppl.remote_bugs,
s->savedhost, s->savedport, s->hostkey_alg, s->thc,
s->hostkeys, s->nhostkeys,
!s->got_session_id, s->can_gssapi_keyex,

View File

@ -18,11 +18,6 @@
#define DH_MIN_SIZE 1024
#define DH_MAX_SIZE 8192
enum kexlist {
KEXLIST_KEX, KEXLIST_HOSTKEY, KEXLIST_CSCIPHER, KEXLIST_SCCIPHER,
KEXLIST_CSMAC, KEXLIST_SCMAC, KEXLIST_CSCOMP, KEXLIST_SCCOMP,
NKEXLIST
};
#define MAXKEXLIST 16
struct kexinit_algorithm {
const char *name;

View File

@ -1,7 +1,12 @@
typedef struct AuthPolicy AuthPolicy;
struct SshServerConfig {
ptrlen banner; /* banner.ptr == NULL indicates no banner */
/*
* In all of these ptrlens, setting the 'ptr' member to NULL means
* that we're not overriding the default configuration.
*/
ptrlen banner; /* default here is 'no banner' */
ptrlen kex_override[NKEXLIST];
bool exit_signal_numeric; /* mimic an old server bug */
};

View File

@ -542,6 +542,22 @@ int main(int argc, char **argv)
ssc.banner = ptrlen_from_strbuf(sb);
} else if (longoptarg(arg, "--bannertext", &val, &argc, &argv)) {
ssc.banner = ptrlen_from_asciz(val);
} else if (longoptarg(arg, "--kexinit-kex", &val, &argc, &argv)) {
ssc.kex_override[KEXLIST_KEX] = ptrlen_from_asciz(val);
} else if (longoptarg(arg, "--kexinit-hostkey", &val, &argc, &argv)) {
ssc.kex_override[KEXLIST_HOSTKEY] = ptrlen_from_asciz(val);
} else if (longoptarg(arg, "--kexinit-cscipher", &val, &argc, &argv)) {
ssc.kex_override[KEXLIST_CSCIPHER] = ptrlen_from_asciz(val);
} else if (longoptarg(arg, "--kexinit-csmac", &val, &argc, &argv)) {
ssc.kex_override[KEXLIST_CSMAC] = ptrlen_from_asciz(val);
} else if (longoptarg(arg, "--kexinit-cscomp", &val, &argc, &argv)) {
ssc.kex_override[KEXLIST_CSCOMP] = ptrlen_from_asciz(val);
} else if (longoptarg(arg, "--kexinit-sccipher", &val, &argc, &argv)) {
ssc.kex_override[KEXLIST_SCCIPHER] = ptrlen_from_asciz(val);
} else if (longoptarg(arg, "--kexinit-scmac", &val, &argc, &argv)) {
ssc.kex_override[KEXLIST_SCMAC] = ptrlen_from_asciz(val);
} else if (longoptarg(arg, "--kexinit-sccomp", &val, &argc, &argv)) {
ssc.kex_override[KEXLIST_SCCOMP] = ptrlen_from_asciz(val);
} else if (longoptnoarg(arg, "--exitsignum")) {
ssc.exit_signal_numeric = true;
} else if (longoptarg(arg, "--sshlog", &val, &argc, &argv) ||