diff --git a/ssh.h b/ssh.h index b7bf8711..15542f59 100644 --- a/ssh.h +++ b/ssh.h @@ -415,6 +415,17 @@ void ssh_user_close(Ssh *ssh, const char *fmt, ...); #define SSH1_CIPHER_3DES 3 #define SSH1_CIPHER_BLOWFISH 6 +/* The subset of those that we support, with names for selecting them + * on Uppity's command line */ +#define SSH1_SUPPORTED_CIPHER_LIST(X) \ + X(SSH1_CIPHER_3DES, "3des") \ + X(SSH1_CIPHER_BLOWFISH, "blowfish") \ + X(SSH1_CIPHER_DES, "des") \ + /* end of list */ +#define SSH1_CIPHER_LIST_MAKE_MASK(bitpos, name) | (1U << bitpos) +#define SSH1_SUPPORTED_CIPHER_MASK \ + (0 SSH1_SUPPORTED_CIPHER_LIST(SSH1_CIPHER_LIST_MAKE_MASK)) + struct ssh_key { const ssh_keyalg *vt; }; diff --git a/ssh1login-server.c b/ssh1login-server.c index 1551c5a2..10d9a37b 100644 --- a/ssh1login-server.c +++ b/ssh1login-server.c @@ -146,10 +146,7 @@ static void ssh1_login_server_process_queue(PacketProtocolLayer *ppl) } s->local_protoflags = SSH1_PROTOFLAGS_SUPPORTED; - /* FIXME: ability to configure this to a subset */ - s->supported_ciphers_mask = ((1U << SSH1_CIPHER_3DES) | - (1U << SSH1_CIPHER_BLOWFISH) | - (1U << SSH1_CIPHER_DES)); + s->supported_ciphers_mask = s->ssc->ssh1_cipher_mask; s->supported_auths_mask = 0; s->ap_methods = auth_methods(s->authpolicy); if (s->ap_methods & AUTHMETHOD_PASSWORD) diff --git a/sshserver.h b/sshserver.h index bbdb8765..5afa4b14 100644 --- a/sshserver.h +++ b/sshserver.h @@ -13,6 +13,8 @@ struct SshServerConfig { ptrlen kex_override[NKEXLIST]; bool exit_signal_numeric; /* mimic an old server bug */ + + unsigned long ssh1_cipher_mask; }; Plug *ssh_server_plug( diff --git a/unix/uxserver.c b/unix/uxserver.c index 5706e029..5698152b 100644 --- a/unix/uxserver.c +++ b/unix/uxserver.c @@ -337,6 +337,7 @@ static void show_help(FILE *fp) "c->s compression types\n" " --kexinit-sccomp STR override list of SSH-2 " "s->c compression types\n" + " --ssh1-ciphers STR override list of SSH-1 ciphers\n" " --exitsignum send buggy numeric \"exit-signal\" " "message\n" " --verbose print event log messages to standard " @@ -537,6 +538,7 @@ int main(int argc, char **argv) memset(&ssc, 0, sizeof(ssc)); ssc.session_starting_dir = getenv("HOME"); + ssc.ssh1_cipher_mask = SSH1_SUPPORTED_CIPHER_MASK; if (argc <= 1) { /* @@ -739,6 +741,25 @@ int main(int argc, char **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 (longoptarg(arg, "--ssh1-ciphers", &val, &argc, &argv)) { + ptrlen list = ptrlen_from_asciz(val); + ptrlen word; + unsigned long mask = 0; + while (word = ptrlen_get_word(&list, ","), word.len != 0) { + +#define SSH1_CIPHER_CASE(bitpos, name) \ + if (ptrlen_eq_string(word, name)) { \ + mask |= 1U << bitpos; \ + continue; \ + } + SSH1_SUPPORTED_CIPHER_LIST(SSH1_CIPHER_CASE); +#undef SSH1_CIPHER_CASE + + fprintf(stderr, "%s: unrecognised SSH-1 cipher '%.*s'\n", + appname, PTRLEN_PRINTF(word)); + exit(1); + } + ssc.ssh1_cipher_mask = mask; } else if (longoptnoarg(arg, "--exitsignum")) { ssc.exit_signal_numeric = true; } else if (longoptarg(arg, "--sshlog", &val, &argc, &argv) ||