From 83e7d008503efaaf4b727224b71a0fd828960c81 Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 23 Dec 2004 02:24:07 +0000 Subject: [PATCH] Add a preference list for SSH-2 key exchange algorithms, on a new "Kex" panel (which will gain more content anon). Retire BUG_SSH2_DH_GEX and add a backwards-compatibility wart, since we never did find a way of automatically detecting this alleged server bug, and in any case there was only ever one report (<3D91F3B5.7030309@inwind.it>, FWIW). Also generalise askcipher() to a new askalg() (thus touching all the front-ends). I've made some attempt to document what SSH key exchange is and why you care, but it could use some review for clarity (and outright lies). git-svn-id: svn://svn.tartarus.org/sgt/putty@5022 cda61777-01e9-0310-a592-d414129be87e --- config.c | 64 ++++++++++++++++++++++++++++++-- doc/config.but | 88 +++++++++++++++++++++++++++++++++++--------- mac/mac.c | 4 +- putty.h | 16 +++++++- settings.c | 25 ++++++++++++- ssh.c | 107 +++++++++++++++++++++++++++++++++++------------------- unix/gtkdlg.c | 11 ++---- unix/uxcons.c | 19 +++------- windows/wincons.c | 19 +++------- windows/windlg.c | 11 ++---- windows/winhelp.h | 2 +- 11 files changed, 262 insertions(+), 104 deletions(-) diff --git a/config.c b/config.c index 08ad4900..51d0f735 100644 --- a/config.c +++ b/config.c @@ -124,6 +124,48 @@ static void cipherlist_handler(union control *ctrl, void *dlg, } } +static void kexlist_handler(union control *ctrl, void *dlg, + void *data, int event) +{ + Config *cfg = (Config *)data; + if (event == EVENT_REFRESH) { + int i; + + static const struct { char *s; int k; } kexes[] = { + { "Diffie-Hellman group 1", KEX_DHGROUP1 }, + { "Diffie-Hellman group 14", KEX_DHGROUP14 }, + { "Diffie-Hellman group exchange", KEX_DHGEX }, + { "-- warn below here --", KEX_WARN } + }; + + /* Set up the "kex preference" box. */ + /* (kexlist assumed to contain all algorithms) */ + dlg_update_start(ctrl, dlg); + dlg_listbox_clear(ctrl, dlg); + for (i = 0; i < KEX_MAX; i++) { + int k = cfg->ssh_kexlist[i]; + int j; + char *kstr = NULL; + for (j = 0; j < (sizeof kexes) / (sizeof kexes[0]); j++) { + if (kexes[j].k == k) { + kstr = kexes[j].s; + break; + } + } + dlg_listbox_addwithid(ctrl, dlg, kstr, k); + } + dlg_update_done(ctrl, dlg); + + } else if (event == EVENT_VALCHANGE) { + int i; + + /* Update array to match the list box. */ + for (i=0; i < KEX_MAX; i++) + cfg->ssh_kexlist[i] = dlg_listbox_getid(ctrl, dlg, i); + + } +} + static void printerbox_handler(union control *ctrl, void *dlg, void *data, int event) { @@ -1526,6 +1568,25 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, I(offsetof(Config,ssh2_des_cbc))); /* + * The Connection/SSH/Kex panel. + */ + ctrl_settitle(b, "Connection/SSH/Kex", + "Options controlling SSH key exchange"); + + s = ctrl_getset(b, "Connection/SSH/Kex", "main", + "Key exchange algorithm options"); + c = ctrl_draglist(s, "Algorithm selection policy", 's', + HELPCTX(ssh_kexlist), + kexlist_handler, P(NULL)); + c->listbox.height = 5; + +#if 0 + s = ctrl_getset(b, "Connection/SSH/Kex", "repeat", + "Options controlling key re-exchange"); + /* FIXME: at least time and data size */ +#endif + + /* * The Connection/SSH/Auth panel. */ ctrl_settitle(b, "Connection/SSH/Auth", @@ -1659,9 +1720,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, ctrl_droplist(s, "Requires padding on SSH2 RSA signatures", 'p', 20, HELPCTX(ssh_bugs_rsapad2), sshbug_handler, I(offsetof(Config,sshbug_rsapad2))); - ctrl_droplist(s, "Chokes on Diffie-Hellman group exchange", 'd', 20, - HELPCTX(ssh_bugs_dhgex2), - sshbug_handler, I(offsetof(Config,sshbug_dhgex2))); ctrl_droplist(s, "Misuses the session ID in PK auth", 'n', 20, HELPCTX(ssh_bugs_pksessid2), sshbug_handler, I(offsetof(Config,sshbug_pksessid2))); diff --git a/doc/config.but b/doc/config.but index 07c35289..badb0d99 100644 --- a/doc/config.but +++ b/doc/config.but @@ -2098,6 +2098,77 @@ these servers if you enable the \q{Enable legacy use of single-DES in SSH 2} option; by default this is disabled and PuTTY will stick to recommended ciphers. +\H{config-ssh-kex} The Kex panel + +\# FIXME: This whole section is draft. Feel free to revise. + +The Kex panel (short for \q{key exchange}) allows you to configure +options related to SSH-2 key exchange. + +Key exchange occurs at the start of an SSH connection (and +occasionally thereafter); it establishes a shared secret that is used +as the basis for all of SSH's security features. It is therefore very +important for the security of the connection that the key exchange is +secure. + +Key exchange is a cryptographically intensive process; if either the +client or the server is a relatively slow machine, the slower methods +may take several tens of seconds to complete. + +If connection startup is too slow, or the connection hangs +periodically, you may want to try changing these settings. + +If you don't understand what any of this means, it's safe to leave +these settings alone. + +This entire panel is only relevant to SSH protocol version 2; none of +these settings affect SSH-1 at all. + +\S{config-ssh-kex-order} Key exchange algorithm selection + +\cfg{winhelp-topic}{ssh.kex.order} + +PuTTY supports a variety of SSH-2 key exchange methods, and allows you +to choose which one you prefer to use; configuration is similar to +cipher selection (see \k{config-ssh-encryption}). + +PuTTY currently supports the following varieties of Diffie-Hellman key +exchange: + +\b \q{Group 14}: a well-known 2048-bit group. + +\b \q{Group 1}: a well-known 1024-bit group. This is less secure +\#{FIXME better words} than group 14, but may be faster with slow +client or server machines, and may be the only method supported by +older server software. + +\b \q{Group exchange}: with this method, instead of using a fixed +group, PuTTY requests that the server suggest a group to use for key +exchange; the server can avoid groups known to be weak, and possibly +invent new ones over time, without any changes required to PuTTY's +configuration. We recommend use of this method, if possible. + +If the first algorithm PuTTY finds is below the \q{warn below here} +line, you will see a warning box when you make the connection, similar +to that for cipher selection (see \k{config-ssh-encryption}). + +\# [Repeat key exchange bumph when config is added:] If the session +key negotiated at connection startup is used too much or for too long, +it may become feasible to mount attacks against the SSH connection. +Therefore, the SSH protocol specifies that a new key exchange should +take place every so often. + +\# While this renegotiation is taking place, no data can pass through +the SSH connection, so it may appear to \q{freeze}. (The occurrence of +repeat key exchange is noted in the Event Log; see +\k{using-eventlog}.) Usually the same algorithm is used as at the +start of the connection, with a similar overhead. + +\# [When options are added to frob how often this happens, we should +hardcode the values recommended by the drafts -- 1 hour, 1GB -- in +this documentation, in case PuTTY's defaults are obscured by Default +Settings etc. Assuming we think they're good advice, that is.] + \H{config-ssh-auth} The Auth panel The Auth panel allows you to configure authentication options for @@ -2455,23 +2526,6 @@ to talking to OpenSSH. This is an SSH2-specific bug. -\S{config-ssh-bug-dhgex} \q{Chokes on Diffie-Hellman group exchange} - -\cfg{winhelp-topic}{ssh.bugs.dhgex2} - -We have anecdotal evidence that some SSH servers claim to be able to -perform Diffie-Hellman group exchange, but fail to actually do so -when PuTTY tries to. If your SSH2 sessions spontaneously close -immediately after opening the PuTTY window, it might be worth -enabling the workaround for this bug to see if it helps. - -We have no hard evidence that any specific version of specific -server software reliably demonstrates this bug. Therefore, PuTTY -will never \e{assume} a server has this bug; if you want the -workaround, you need to enable it manually. - -This is an SSH2-specific bug. - \S{config-ssh-bug-pksessid2} \q{Misuses the session ID in PK auth} \cfg{winhelp-topic}{ssh.bugs.pksessid2} diff --git a/mac/mac.c b/mac/mac.c index 4f7c2fcf..8dde3e12 100644 --- a/mac/mac.c +++ b/mac/mac.c @@ -1,4 +1,4 @@ -/* $Id: mac.c,v 1.59 2003/05/10 12:27:38 ben Exp $ */ +/* $Id$ */ /* * Copyright (c) 1999, 2003 Ben Harris * All rights reserved. @@ -704,7 +704,7 @@ void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, } } -void askcipher(void *frontend, char *ciphername, int cs) +void askalg(void *frontend, const char *algtype, const char *algname) { } diff --git a/putty.h b/putty.h index b6aace7f..5ffd73ce 100644 --- a/putty.h +++ b/putty.h @@ -234,6 +234,17 @@ enum { enum { /* + * SSH-2 key exchange algorithms + */ + KEX_WARN, + KEX_DHGROUP1, + KEX_DHGROUP14, + KEX_DHGEX, + KEX_MAX +}; + +enum { + /* * SSH ciphers (both SSH1 and SSH2) */ CIPHER_WARN, /* pseudo 'cipher' */ @@ -388,6 +399,7 @@ struct config_tag { * but never for loading/saving */ int nopty; int compression; + int ssh_kexlist[KEX_MAX]; int agentfwd; int change_username; /* allow username switching in SSH2 */ int ssh_cipherlist[CIPHER_MAX]; @@ -514,7 +526,7 @@ struct config_tag { /* SSH bug compatibility modes */ int sshbug_ignore1, sshbug_plainpw1, sshbug_rsa1, sshbug_hmac2, sshbug_derivekey2, sshbug_rsapad2, - sshbug_dhgex2, sshbug_pksessid2; + sshbug_pksessid2; /* Options for pterm. Should split out into platform-dependent part. */ int stamp_utmp; int login_shell; @@ -862,7 +874,7 @@ int wc_unescape(char *output, const char *wildcard); void logevent(void *frontend, const char *); void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, char *keystr, char *fingerprint); -void askcipher(void *frontend, char *ciphername, int cs); +void askalg(void *frontend, const char *algtype, const char *algname); int askappend(void *frontend, Filename filename); /* diff --git a/settings.c b/settings.c index 4377bfe3..711ef88f 100644 --- a/settings.c +++ b/settings.c @@ -12,6 +12,7 @@ */ struct keyval { char *s; int v; }; +/* The cipher order given here is the default order. */ static const struct keyval ciphernames[] = { { "aes", CIPHER_AES }, { "blowfish", CIPHER_BLOWFISH }, @@ -20,6 +21,13 @@ static const struct keyval ciphernames[] = { { "des", CIPHER_DES } }; +static const struct keyval kexnames[] = { + { "dh-gex-sha1", KEX_DHGEX }, + { "dh-group14-sha1", KEX_DHGROUP14 }, + { "dh-group1-sha1", KEX_DHGROUP1 }, + { "WARN", KEX_WARN } +}; + static void gpps(void *handle, const char *name, const char *def, char *val, int len) { @@ -227,6 +235,7 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_i(sesskey, "ChangeUsername", cfg->change_username); wprefs(sesskey, "Cipher", ciphernames, CIPHER_MAX, cfg->ssh_cipherlist); + wprefs(sesskey, "KEX", kexnames, KEX_MAX, cfg->ssh_kexlist); write_setting_i(sesskey, "AuthTIS", cfg->try_tis_auth); write_setting_i(sesskey, "AuthKI", cfg->try_ki_auth); write_setting_i(sesskey, "SshNoShell", cfg->ssh_no_shell); @@ -358,7 +367,6 @@ void save_open_settings(void *sesskey, int do_host, Config *cfg) write_setting_i(sesskey, "BugHMAC2", 2-cfg->sshbug_hmac2); write_setting_i(sesskey, "BugDeriveKey2", 2-cfg->sshbug_derivekey2); write_setting_i(sesskey, "BugRSAPad2", 2-cfg->sshbug_rsapad2); - write_setting_i(sesskey, "BugDHGEx2", 2-cfg->sshbug_dhgex2); write_setting_i(sesskey, "BugPKSessID2", 2-cfg->sshbug_pksessid2); write_setting_i(sesskey, "StampUtmp", cfg->stamp_utmp); write_setting_i(sesskey, "LoginShell", cfg->login_shell); @@ -492,6 +500,20 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg) gppi(sesskey, "ChangeUsername", 0, &cfg->change_username); gprefs(sesskey, "Cipher", "\0", ciphernames, CIPHER_MAX, cfg->ssh_cipherlist); + { + /* Backward-compatibility: we used to have an option to + * disable gex under the "bugs" panel after one report of + * a server which offered it then choked, but we never got + * a server version string or any other reports. */ + char *default_kexes; + gppi(sesskey, "BugDHGEx2", 0, &i); i = 2-i; + if (i == FORCE_ON) + default_kexes = "dh-group14-sha1,dh-group1-sha1,WARN,dh-gex-sha1"; + else + default_kexes = "dh-gex-sha1,dh-group14-sha1,dh-group1-sha1,WARN"; + gprefs(sesskey, "KEX", default_kexes, + kexnames, KEX_MAX, cfg->ssh_kexlist); + } gppi(sesskey, "SshProt", 2, &cfg->sshprot); gppi(sesskey, "SSH2DES", 0, &cfg->ssh2_des_cbc); gppi(sesskey, "AuthTIS", 0, &cfg->try_tis_auth); @@ -667,7 +689,6 @@ void load_open_settings(void *sesskey, int do_host, Config *cfg) } gppi(sesskey, "BugDeriveKey2", 0, &i); cfg->sshbug_derivekey2 = 2-i; gppi(sesskey, "BugRSAPad2", 0, &i); cfg->sshbug_rsapad2 = 2-i; - gppi(sesskey, "BugDHGEx2", 0, &i); cfg->sshbug_dhgex2 = 2-i; gppi(sesskey, "BugPKSessID2", 0, &i); cfg->sshbug_pksessid2 = 2-i; gppi(sesskey, "StampUtmp", 1, &cfg->stamp_utmp); gppi(sesskey, "LoginShell", 1, &cfg->login_shell); diff --git a/ssh.c b/ssh.c index a6fba8b8..126e6ff1 100644 --- a/ssh.c +++ b/ssh.c @@ -162,7 +162,7 @@ static const char *const ssh2_disconnect_reasons[] = { #define BUG_CHOKES_ON_RSA 8 #define BUG_SSH2_RSA_PADDING 16 #define BUG_SSH2_DERIVEKEY 32 -#define BUG_SSH2_DH_GEX 64 +/* 64 was BUG_SSH2_DH_GEX, now spare */ #define BUG_SSH2_PK_SESSIONID 128 #define translate(x) if (type == x) return #x @@ -360,12 +360,6 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, #define SSH_MAX_BACKLOG 32768 #define OUR_V2_WINSIZE 16384 -const static struct ssh_kex *kex_algs[] = { - &ssh_diffiehellman_gex, - &ssh_diffiehellman_group14, - &ssh_diffiehellman_group1, -}; - const static struct ssh_signkey *hostkey_algs[] = { &ssh_rsa, &ssh_dss }; static void *nullmac_make_context(void) @@ -2058,14 +2052,6 @@ static void ssh_detect_bugs(Ssh ssh, char *vstring) ssh->remote_bugs |= BUG_SSH2_PK_SESSIONID; logevent("We believe remote version has SSH2 public-key-session-ID bug"); } - - if (ssh->cfg.sshbug_dhgex2 == FORCE_ON) { - /* - * User specified the SSH2 DH GEX bug. - */ - ssh->remote_bugs |= BUG_SSH2_DH_GEX; - logevent("We believe remote version has SSH2 DH group exchange bug"); - } } /* @@ -2761,7 +2747,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, /* Warn about chosen cipher if necessary. */ if (warn) - askcipher(ssh->frontend, cipher_string, 0); + askalg(ssh->frontend, "cipher", cipher_string); } switch (s->cipher_type) { @@ -4321,6 +4307,8 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, int hostkeylen, siglen; void *hkey; /* actual host key */ unsigned char exchange_hash[20]; + int n_preferred_kex; + const struct ssh_kex *preferred_kex[KEX_MAX]; int n_preferred_ciphers; const struct ssh2_ciphers *preferred_ciphers[CIPHER_MAX]; const struct ssh_compress *preferred_comp; @@ -4340,6 +4328,37 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, { int i; /* + * Set up the preferred key exchange. (NULL => warn below here) + */ + s->n_preferred_kex = 0; + for (i = 0; i < KEX_MAX; i++) { + switch (ssh->cfg.ssh_kexlist[i]) { + case KEX_DHGEX: + s->preferred_kex[s->n_preferred_kex++] = + &ssh_diffiehellman_gex; + break; + case KEX_DHGROUP14: + s->preferred_kex[s->n_preferred_kex++] = + &ssh_diffiehellman_group14; + break; + case KEX_DHGROUP1: + s->preferred_kex[s->n_preferred_kex++] = + &ssh_diffiehellman_group1; + break; + case CIPHER_WARN: + /* Flag for later. Don't bother if it's the last in + * the list. */ + if (i < KEX_MAX - 1) { + s->preferred_kex[s->n_preferred_kex++] = NULL; + } + break; + } + } + } + + { + int i; + /* * Set up the preferred ciphers. (NULL => warn below here) */ s->n_preferred_ciphers = 0; @@ -4388,7 +4407,7 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, begin_key_exchange: { - int i, j, cipherstr_started; + int i, j, commalist_started; /* * Enable queueing of outgoing auth- or connection-layer @@ -4409,13 +4428,14 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, ssh2_pkt_addbyte(s->pktout, (unsigned char) random_byte()); /* List key exchange algorithms. */ ssh2_pkt_addstring_start(s->pktout); - for (i = 0; i < lenof(kex_algs); i++) { - if (kex_algs[i] == &ssh_diffiehellman_gex && - (ssh->remote_bugs & BUG_SSH2_DH_GEX)) - continue; - ssh2_pkt_addstring_str(s->pktout, kex_algs[i]->name); - if (i < lenof(kex_algs) - 1) + commalist_started = 0; + for (i = 0; i < s->n_preferred_kex; i++) { + const struct ssh_kex *k = s->preferred_kex[i]; + if (!k) continue; /* warning flag */ + if (commalist_started) ssh2_pkt_addstring_str(s->pktout, ","); + ssh2_pkt_addstring_str(s->pktout, s->preferred_kex[i]->name); + commalist_started = 1; } /* List server host key algorithms. */ ssh2_pkt_addstring_start(s->pktout); @@ -4426,28 +4446,28 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, } /* List client->server encryption algorithms. */ ssh2_pkt_addstring_start(s->pktout); - cipherstr_started = 0; + commalist_started = 0; for (i = 0; i < s->n_preferred_ciphers; i++) { const struct ssh2_ciphers *c = s->preferred_ciphers[i]; if (!c) continue; /* warning flag */ for (j = 0; j < c->nciphers; j++) { - if (cipherstr_started) + if (commalist_started) ssh2_pkt_addstring_str(s->pktout, ","); ssh2_pkt_addstring_str(s->pktout, c->list[j]->name); - cipherstr_started = 1; + commalist_started = 1; } } /* List server->client encryption algorithms. */ ssh2_pkt_addstring_start(s->pktout); - cipherstr_started = 0; + commalist_started = 0; for (i = 0; i < s->n_preferred_ciphers; i++) { const struct ssh2_ciphers *c = s->preferred_ciphers[i]; if (!c) continue; /* warning flag */ for (j = 0; j < c->nciphers; j++) { - if (cipherstr_started) + if (commalist_started) ssh2_pkt_addstring_str(s->pktout, ","); ssh2_pkt_addstring_str(s->pktout, c->list[j]->name); - cipherstr_started = 1; + commalist_started = 1; } } /* List client->server MAC algorithms. */ @@ -4528,15 +4548,26 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, s->sccomp_tobe = NULL; pktin->savedpos += 16; /* skip garbage cookie */ ssh_pkt_getstring(pktin, &str, &len); /* key exchange algorithms */ - for (i = 0; i < lenof(kex_algs); i++) { - if (kex_algs[i] == &ssh_diffiehellman_gex && - (ssh->remote_bugs & BUG_SSH2_DH_GEX)) - continue; - if (in_commasep_string(kex_algs[i]->name, str, len)) { - ssh->kex = kex_algs[i]; + s->warn = 0; + for (i = 0; i < s->n_preferred_kex; i++) { + const struct ssh_kex *k = s->preferred_kex[i]; + if (!k) { + s->warn = 1; + } else if (in_commasep_string(k->name, str, len)) { + ssh->kex = k; + } + if (ssh->kex) { + if (s->warn) + askalg(ssh->frontend, "key-exchange algorithm", + ssh->kex->name); break; } } + if (!ssh->kex) { + bombout(("Couldn't agree a key exchange algorithm (available: %s)", + str ? str : "(null)")); + crStop(0); + } ssh_pkt_getstring(pktin, &str, &len); /* host key algorithms */ for (i = 0; i < lenof(hostkey_algs); i++) { if (in_commasep_string(hostkey_algs[i]->name, str, len)) { @@ -4560,7 +4591,8 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, } if (s->cscipher_tobe) { if (s->warn) - askcipher(ssh->frontend, s->cscipher_tobe->name, 1); + askalg(ssh->frontend, "client-to-server cipher", + s->cscipher_tobe->name); break; } } @@ -4586,7 +4618,8 @@ static int do_ssh2_transport(Ssh ssh, unsigned char *in, int inlen, } if (s->sccipher_tobe) { if (s->warn) - askcipher(ssh->frontend, s->sccipher_tobe->name, 2); + askalg(ssh->frontend, "server-to-client cipher", + s->sccipher_tobe->name); break; } } diff --git a/unix/gtkdlg.c b/unix/gtkdlg.c index 2a2b3ab7..6b5659c2 100644 --- a/unix/gtkdlg.c +++ b/unix/gtkdlg.c @@ -2351,22 +2351,19 @@ void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, } /* - * Ask whether the selected cipher is acceptable (since it was + * Ask whether the selected algorithm is acceptable (since it was * below the configured 'warn' threshold). - * cs: 0 = both ways, 1 = client->server, 2 = server->client */ -void askcipher(void *frontend, char *ciphername, int cs) +void askalg(void *frontend, const char *algtype, const char *algname) { static const char msg[] = - "The first %scipher supported by the server is " + "The first %s supported by the server is " "%s, which is below the configured warning threshold.\n" "Continue with connection?"; char *text; int ret; - text = dupprintf(msg, (cs == 0) ? "" : - (cs == 1) ? "client-to-server " : "server-to-client ", - ciphername); + text = dupprintf(msg, algtype, algname); ret = messagebox(GTK_WIDGET(get_window(frontend)), "PuTTY Security Alert", text, string_width("Continue with connection?"), diff --git a/unix/uxcons.c b/unix/uxcons.c index a8effe90..b5bf840b 100644 --- a/unix/uxcons.c +++ b/unix/uxcons.c @@ -143,18 +143,17 @@ void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, } /* - * Ask whether the selected cipher is acceptable (since it was + * Ask whether the selected algorithm is acceptable (since it was * below the configured 'warn' threshold). - * cs: 0 = both ways, 1 = client->server, 2 = server->client */ -void askcipher(void *frontend, char *ciphername, int cs) +void askalg(void *frontend, const char *algtype, const char *algname) { static const char msg[] = - "The first %scipher supported by the server is\n" + "The first %s supported by the server is\n" "%s, which is below the configured warning threshold.\n" "Continue with connection? (y/n) "; static const char msg_batch[] = - "The first %scipher supported by the server is\n" + "The first %s supported by the server is\n" "%s, which is below the configured warning threshold.\n" "Connection abandoned.\n"; static const char abandoned[] = "Connection abandoned.\n"; @@ -162,17 +161,11 @@ void askcipher(void *frontend, char *ciphername, int cs) char line[32]; if (console_batch_mode) { - fprintf(stderr, msg_batch, - (cs == 0) ? "" : - (cs == 1) ? "client-to-server " : "server-to-client ", - ciphername); + fprintf(stderr, msg_batch, algtype, algname); cleanup_exit(1); } - fprintf(stderr, msg, - (cs == 0) ? "" : - (cs == 1) ? "client-to-server " : "server-to-client ", - ciphername); + fprintf(stderr, msg, algtype, algname); fflush(stderr); { diff --git a/windows/wincons.c b/windows/wincons.c index 347f99f1..38b46fad 100644 --- a/windows/wincons.c +++ b/windows/wincons.c @@ -147,21 +147,20 @@ void update_specials_menu(void *frontend) } /* - * Ask whether the selected cipher is acceptable (since it was + * Ask whether the selected algorithm is acceptable (since it was * below the configured 'warn' threshold). - * cs: 0 = both ways, 1 = client->server, 2 = server->client */ -void askcipher(void *frontend, char *ciphername, int cs) +void askalg(void *frontend, const char *algtype, const char *algname) { HANDLE hin; DWORD savemode, i; static const char msg[] = - "The first %scipher supported by the server is\n" + "The first %s supported by the server is\n" "%s, which is below the configured warning threshold.\n" "Continue with connection? (y/n) "; static const char msg_batch[] = - "The first %scipher supported by the server is\n" + "The first %s supported by the server is\n" "%s, which is below the configured warning threshold.\n" "Connection abandoned.\n"; static const char abandoned[] = "Connection abandoned.\n"; @@ -169,17 +168,11 @@ void askcipher(void *frontend, char *ciphername, int cs) char line[32]; if (console_batch_mode) { - fprintf(stderr, msg_batch, - (cs == 0) ? "" : - (cs == 1) ? "client-to-server " : "server-to-client ", - ciphername); + fprintf(stderr, msg_batch, algtype, algname); cleanup_exit(1); } - fprintf(stderr, msg, - (cs == 0) ? "" : - (cs == 1) ? "client-to-server " : "server-to-client ", - ciphername); + fprintf(stderr, msg, algtype, algname); fflush(stderr); hin = GetStdHandle(STD_INPUT_HANDLE); diff --git a/windows/windlg.c b/windows/windlg.c index 272196df..65018b12 100644 --- a/windows/windlg.c +++ b/windows/windlg.c @@ -777,24 +777,21 @@ void verify_ssh_host_key(void *frontend, char *host, int port, char *keytype, } /* - * Ask whether the selected cipher is acceptable (since it was + * Ask whether the selected algorithm is acceptable (since it was * below the configured 'warn' threshold). - * cs: 0 = both ways, 1 = client->server, 2 = server->client */ -void askcipher(void *frontend, char *ciphername, int cs) +void askalg(void *frontend, const char *algtype, const char *algname) { static const char mbtitle[] = "%s Security Alert"; static const char msg[] = - "The first %.35scipher supported by the server\n" + "The first %s supported by the server\n" "is %.64s, which is below the configured\n" "warning threshold.\n" "Do you want to continue with this connection?\n"; char *message, *title; int mbret; - message = dupprintf(msg, ((cs == 0) ? "" : - (cs == 1) ? "client-to-server " : - "server-to-client "), ciphername); + message = dupprintf(msg, algtype, algname); title = dupprintf(mbtitle, appname); mbret = MessageBox(NULL, message, title, MB_ICONWARNING | MB_YESNO); diff --git a/windows/winhelp.h b/windows/winhelp.h index 88338d3a..63f25adf 100644 --- a/windows/winhelp.h +++ b/windows/winhelp.h @@ -86,6 +86,7 @@ #define WINHELP_CTX_ssh_protocol "ssh.protocol" #define WINHELP_CTX_ssh_command "ssh.command" #define WINHELP_CTX_ssh_compress "ssh.compress" +#define WINHELP_CTX_ssh_kexlist "ssh.kex.order" #define WINHELP_CTX_ssh_auth_privkey "ssh.auth.privkey" #define WINHELP_CTX_ssh_auth_agentfwd "ssh.auth.agentfwd" #define WINHELP_CTX_ssh_auth_changeuser "ssh.auth.changeuser" @@ -116,5 +117,4 @@ #define WINHELP_CTX_ssh_bugs_hmac2 "ssh.bugs.hmac2" #define WINHELP_CTX_ssh_bugs_derivekey2 "ssh.bugs.derivekey2" #define WINHELP_CTX_ssh_bugs_rsapad2 "ssh.bugs.rsapad2" -#define WINHELP_CTX_ssh_bugs_dhgex2 "ssh.bugs.dhgex2" #define WINHELP_CTX_ssh_bugs_pksessid2 "ssh.bugs.pksessid2" -- 2.11.0