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:
parent
8d84272d80
commit
b494ecfcfc
7
ssh.h
7
ssh.h
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
};
|
||||
|
@ -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) ||
|
||||
|
Loading…
Reference in New Issue
Block a user