X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=config.c;h=59d01e7479cded42d6e0384b7f1bac8b6c306d85;hb=510f49e405e71ba5c97875e7a019364e1ef5fac9;hp=1596c2f1d97d3ccbde0acdd37c7a6e1c5cfcd944;hpb=8da4fa506389910599c59b87ba1b799efd6d3ae1;p=PuTTY.git diff --git a/config.c b/config.c index 1596c2f1..59d01e74 100644 --- a/config.c +++ b/config.c @@ -356,7 +356,8 @@ static void cipherlist_handler(union control *ctrl, void *dlg, if (event == EVENT_REFRESH) { int i; - static const struct { char *s; int c; } ciphers[] = { + static const struct { const char *s; int c; } ciphers[] = { + { "ChaCha20 (SSH-2 only)", CIPHER_CHACHA20 }, { "3DES", CIPHER_3DES }, { "Blowfish", CIPHER_BLOWFISH }, { "DES", CIPHER_DES }, @@ -372,7 +373,7 @@ static void cipherlist_handler(union control *ctrl, void *dlg, for (i = 0; i < CIPHER_MAX; i++) { int c = conf_get_int_int(conf, CONF_ssh_cipherlist, i); int j; - char *cstr = NULL; + const char *cstr = NULL; for (j = 0; j < (sizeof ciphers) / (sizeof ciphers[0]); j++) { if (ciphers[j].c == c) { cstr = ciphers[j].s; @@ -428,11 +429,12 @@ static void kexlist_handler(union control *ctrl, void *dlg, if (event == EVENT_REFRESH) { int i; - static const struct { char *s; int k; } kexes[] = { + static const struct { const char *s; int k; } kexes[] = { { "Diffie-Hellman group 1", KEX_DHGROUP1 }, { "Diffie-Hellman group 14", KEX_DHGROUP14 }, { "Diffie-Hellman group exchange", KEX_DHGEX }, { "RSA-based key exchange", KEX_RSA }, + { "ECDH key exchange", KEX_ECDH }, { "-- warn below here --", KEX_WARN } }; @@ -443,7 +445,7 @@ static void kexlist_handler(union control *ctrl, void *dlg, for (i = 0; i < KEX_MAX; i++) { int k = conf_get_int_int(conf, CONF_ssh_kexlist, i); int j; - char *kstr = NULL; + const char *kstr = NULL; for (j = 0; j < (sizeof kexes) / (sizeof kexes[0]); j++) { if (kexes[j].k == k) { kstr = kexes[j].s; @@ -464,6 +466,49 @@ static void kexlist_handler(union control *ctrl, void *dlg, } } +static void hklist_handler(union control *ctrl, void *dlg, + void *data, int event) +{ + Conf *conf = (Conf *)data; + if (event == EVENT_REFRESH) { + int i; + + static const struct { const char *s; int k; } hks[] = { + { "Ed25519", HK_ED25519 }, + { "ECDSA", HK_ECDSA }, + { "DSA", HK_DSA }, + { "RSA", HK_RSA }, + { "-- warn below here --", HK_WARN } + }; + + /* Set up the "host key preference" box. */ + /* (hklist assumed to contain all algorithms) */ + dlg_update_start(ctrl, dlg); + dlg_listbox_clear(ctrl, dlg); + for (i = 0; i < HK_MAX; i++) { + int k = conf_get_int_int(conf, CONF_ssh_hklist, i); + int j; + const char *kstr = NULL; + for (j = 0; j < lenof(hks); j++) { + if (hks[j].k == k) { + kstr = hks[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 < HK_MAX; i++) + conf_set_int_int(conf, CONF_ssh_hklist, i, + dlg_listbox_getid(ctrl, dlg, i)); + } +} + static void printerbox_handler(union control *ctrl, void *dlg, void *data, int event) { @@ -471,7 +516,7 @@ static void printerbox_handler(union control *ctrl, void *dlg, if (event == EVENT_REFRESH) { int nprinters, i; printer_enum *pe; - char *printer; + const char *printer; dlg_update_start(ctrl, dlg); /* @@ -568,6 +613,7 @@ struct sessionsaver_data { static void sessionsaver_data_free(void *ssdv) { struct sessionsaver_data *ssd = (struct sessionsaver_data *)ssdv; + get_sesslist(&ssd->sesslist, FALSE); sfree(ssd->savedsession); sfree(ssd); } @@ -1117,7 +1163,8 @@ static void portfwd_handler(union control *ctrl, void *dlg, } } else if (event == EVENT_ACTION) { if (ctrl == pfd->addbutton) { - char *family, *type, *src, *key, *val; + const char *family, *type; + char *src, *key, *val; int whichbutton; #ifndef NO_IPV6 @@ -1127,8 +1174,8 @@ static void portfwd_handler(union control *ctrl, void *dlg, else if (whichbutton == 2) family = "6"; else - family = ""; #endif + family = ""; whichbutton = dlg_radiobutton_get(pfd->direction, dlg); if (whichbutton == 0) @@ -1176,7 +1223,8 @@ static void portfwd_handler(union control *ctrl, void *dlg, if (i < 0) { dlg_beep(dlg); } else { - char *key, *val, *p; + char *key, *p; + const char *val; key = conf_get_str_nthstrkey(conf, CONF_portfwd, i); if (key) { @@ -1225,6 +1273,73 @@ static void portfwd_handler(union control *ctrl, void *dlg, } } +struct manual_hostkey_data { + union control *addbutton, *rembutton, *listbox, *keybox; +}; + +static void manual_hostkey_handler(union control *ctrl, void *dlg, + void *data, int event) +{ + Conf *conf = (Conf *)data; + struct manual_hostkey_data *mh = + (struct manual_hostkey_data *)ctrl->generic.context.p; + + if (event == EVENT_REFRESH) { + if (ctrl == mh->listbox) { + char *key, *val; + dlg_update_start(ctrl, dlg); + dlg_listbox_clear(ctrl, dlg); + for (val = conf_get_str_strs(conf, CONF_ssh_manual_hostkeys, + NULL, &key); + val != NULL; + val = conf_get_str_strs(conf, CONF_ssh_manual_hostkeys, + key, &key)) { + dlg_listbox_add(ctrl, dlg, key); + } + dlg_update_done(ctrl, dlg); + } + } else if (event == EVENT_ACTION) { + if (ctrl == mh->addbutton) { + char *key; + + key = dlg_editbox_get(mh->keybox, dlg); + if (!*key) { + dlg_error_msg(dlg, "You need to specify a host key or " + "fingerprint"); + sfree(key); + return; + } + + if (!validate_manual_hostkey(key)) { + dlg_error_msg(dlg, "Host key is not in a valid format"); + } else if (conf_get_str_str_opt(conf, CONF_ssh_manual_hostkeys, + key)) { + dlg_error_msg(dlg, "Specified host key is already listed"); + } else { + conf_set_str_str(conf, CONF_ssh_manual_hostkeys, key, ""); + } + + sfree(key); + dlg_refresh(mh->listbox, dlg); + } else if (ctrl == mh->rembutton) { + int i = dlg_listbox_index(mh->listbox, dlg); + if (i < 0) { + dlg_beep(dlg); + } else { + char *key; + + key = conf_get_str_nthstrkey(conf, CONF_ssh_manual_hostkeys, i); + if (key) { + dlg_editbox_set(mh->keybox, dlg, key); + /* And delete it */ + conf_del_str_str(conf, CONF_ssh_manual_hostkeys, key); + } + } + dlg_refresh(mh->listbox, dlg); + } + } +} + void setup_config_box(struct controlbox *b, int midsession, int protocol, int protcfginfo) { @@ -1235,6 +1350,7 @@ void setup_config_box(struct controlbox *b, int midsession, struct ttymodes_data *td; struct environ_data *ed; struct portfwd_data *pfd; + struct manual_hostkey_data *mh; union control *c; char *str; @@ -1380,7 +1496,7 @@ void setup_config_box(struct controlbox *b, int midsession, * logging can sensibly be available. */ { - char *sshlogname, *sshrawlogname; + const char *sshlogname, *sshrawlogname; if ((midsession && protocol == PROT_SSH) || (!midsession && backend_from_proto(PROT_SSH))) { sshlogname = "SSH packets"; @@ -1405,7 +1521,7 @@ void setup_config_box(struct controlbox *b, int midsession, HELPCTX(logging_filename), conf_filesel_handler, I(CONF_logfilename)); ctrl_text(s, "(Log file name can contain &Y, &M, &D for date," - " &T for time, and &H for host name)", + " &T for time, &H for host name, and &P for port number)", HELPCTX(logging_filename)); ctrl_radiobuttons(s, "What to do if the log file already exists:", 'e', 1, HELPCTX(logging_exists), @@ -1574,6 +1690,10 @@ void setup_config_box(struct controlbox *b, int midsession, HELPCTX(features_retitle), conf_checkbox_handler, I(CONF_no_remote_wintitle)); + ctrl_checkbox(s, "Disable remote-controlled clearing of scrollback", 'e', + HELPCTX(features_clearscroll), + conf_checkbox_handler, + I(CONF_no_remote_clearscroll)); ctrl_radiobuttons(s, "Response to remote title query (SECURITY):", 'q', 3, HELPCTX(features_qtitle), conf_radiobutton_handler, @@ -1857,7 +1977,7 @@ void setup_config_box(struct controlbox *b, int midsession, #endif { - char *label = backend_from_proto(PROT_SSH) ? + const char *label = backend_from_proto(PROT_SSH) ? "Logical name of remote host (e.g. for SSH key lookup):" : "Logical name of remote host:"; s = ctrl_getset(b, "Connection", "identity", @@ -1999,6 +2119,15 @@ void setup_config_box(struct controlbox *b, int midsession, HELPCTX(proxy_command), conf_editbox_handler, I(CONF_proxy_telnet_command), I(1)); + + ctrl_radiobuttons(s, "Print proxy diagnostics " + "in the terminal window", 'r', 5, + HELPCTX(proxy_logging), + conf_radiobutton_handler, + I(CONF_proxy_log_to_term), + "No", I(FORCE_OFF), + "Yes", I(FORCE_ON), + "Only until session starts", I(AUTO), NULL); } /* @@ -2068,7 +2197,8 @@ void setup_config_box(struct controlbox *b, int midsession, ctrl_settitle(b, "Connection/SSH", "Options controlling SSH connections"); - if (midsession && protcfginfo == 1) { + /* SSH-1 or connection-sharing downstream */ + if (midsession && (protcfginfo == 1 || protcfginfo == -1)) { s = ctrl_getset(b, "Connection/SSH", "disclaimer", NULL); ctrl_text(s, "Nothing on this panel may be reconfigured in mid-" "session; it is only here so that sub-panels of it can " @@ -2090,7 +2220,7 @@ void setup_config_box(struct controlbox *b, int midsession, I(CONF_ssh_no_shell)); } - if (!midsession || protcfginfo != 1) { + if (!midsession || !(protcfginfo == 1 || protcfginfo == -1)) { s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options"); ctrl_checkbox(s, "Enable compression", 'e', @@ -2099,7 +2229,7 @@ void setup_config_box(struct controlbox *b, int midsession, I(CONF_compression)); } - if (!midsession || protcfginfo != 1) { + if (!midsession) { s = ctrl_getset(b, "Connection/SSH", "sharing", "Sharing an SSH connection between PuTTY tools"); ctrl_checkbox(s, "Share SSH connections if possible", 's', @@ -2122,22 +2252,21 @@ void setup_config_box(struct controlbox *b, int midsession, if (!midsession) { s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options"); - ctrl_radiobuttons(s, "Preferred SSH protocol version:", NO_SHORTCUT, 4, + ctrl_radiobuttons(s, "SSH protocol version:", NO_SHORTCUT, 2, HELPCTX(ssh_protocol), conf_radiobutton_handler, I(CONF_sshprot), - "1 only", 'l', I(0), - "1", '1', I(1), - "2", '2', I(2), - "2 only", 'y', I(3), NULL); + "2", '2', I(3), + "1 (INSECURE)", '1', I(0), NULL); } /* * The Connection/SSH/Kex panel. (Owing to repeat key - * exchange, this is all meaningful in mid-session _if_ - * we're using SSH-2 or haven't decided yet.) + * exchange, much of this is meaningful in mid-session _if_ + * we're using SSH-2 and are not a connection-sharing + * downstream, or haven't decided yet.) */ - if (protcfginfo != 1) { + if (protcfginfo != 1 && protcfginfo != -1) { ctrl_settitle(b, "Connection/SSH/Kex", "Options controlling SSH key exchange"); @@ -2165,7 +2294,65 @@ void setup_config_box(struct controlbox *b, int midsession, HELPCTX(ssh_kex_repeat)); } - if (!midsession || protcfginfo != 1) { + /* + * The 'Connection/SSH/Host keys' panel. + */ + if (protcfginfo != 1 && protcfginfo != -1) { + ctrl_settitle(b, "Connection/SSH/Host keys", + "Options controlling SSH host keys"); + + s = ctrl_getset(b, "Connection/SSH/Host keys", "main", + "Host key algorithm preference"); + c = ctrl_draglist(s, "Algorithm selection policy:", 's', + HELPCTX(ssh_hklist), + hklist_handler, P(NULL)); + c->listbox.height = 5; + } + + /* + * Manual host key configuration is irrelevant mid-session, + * as we enforce that the host key for rekeys is the + * same as that used at the start of the session. + */ + if (!midsession) { + s = ctrl_getset(b, "Connection/SSH/Host keys", "hostkeys", + "Manually configure host keys for this connection"); + + ctrl_columns(s, 2, 75, 25); + c = ctrl_text(s, "Host keys or fingerprints to accept:", + HELPCTX(ssh_kex_manual_hostkeys)); + c->generic.column = 0; + /* You want to select from the list, _then_ hit Remove. So + * tab order should be that way round. */ + mh = (struct manual_hostkey_data *) + ctrl_alloc(b,sizeof(struct manual_hostkey_data)); + mh->rembutton = ctrl_pushbutton(s, "Remove", 'r', + HELPCTX(ssh_kex_manual_hostkeys), + manual_hostkey_handler, P(mh)); + mh->rembutton->generic.column = 1; + mh->rembutton->generic.tabdelay = 1; + mh->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT, + HELPCTX(ssh_kex_manual_hostkeys), + manual_hostkey_handler, P(mh)); + /* This list box can't be very tall, because there's not + * much room in the pane on Windows at least. This makes + * it become really unhelpful if a horizontal scrollbar + * appears, so we suppress that. */ + mh->listbox->listbox.height = 2; + mh->listbox->listbox.hscroll = FALSE; + ctrl_tabdelay(s, mh->rembutton); + mh->keybox = ctrl_editbox(s, "Key", 'k', 80, + HELPCTX(ssh_kex_manual_hostkeys), + manual_hostkey_handler, P(mh), P(NULL)); + mh->keybox->generic.column = 0; + mh->addbutton = ctrl_pushbutton(s, "Add key", 'y', + HELPCTX(ssh_kex_manual_hostkeys), + manual_hostkey_handler, P(mh)); + mh->addbutton->generic.column = 1; + ctrl_columns(s, 1, 100); + } + + if (!midsession || !(protcfginfo == 1 || protcfginfo == -1)) { /* * The Connection/SSH/Cipher panel. */ @@ -2194,14 +2381,14 @@ void setup_config_box(struct controlbox *b, int midsession, "Options controlling SSH authentication"); s = ctrl_getset(b, "Connection/SSH/Auth", "main", NULL); - ctrl_checkbox(s, "Bypass authentication entirely (SSH-2 only)", 'b', - HELPCTX(ssh_auth_bypass), - conf_checkbox_handler, - I(CONF_ssh_no_userauth)); ctrl_checkbox(s, "Display pre-authentication banner (SSH-2 only)", 'd', HELPCTX(ssh_auth_banner), conf_checkbox_handler, I(CONF_ssh_show_banner)); + ctrl_checkbox(s, "Bypass authentication entirely (SSH-2 only)", 'b', + HELPCTX(ssh_auth_bypass), + conf_checkbox_handler, + I(CONF_ssh_no_userauth)); s = ctrl_getset(b, "Connection/SSH/Auth", "methods", "Authentication methods"); @@ -2450,46 +2637,58 @@ void setup_config_box(struct controlbox *b, int midsession, if (!midsession) { /* - * The Connection/SSH/Bugs panel. + * The Connection/SSH/Bugs panels. */ ctrl_settitle(b, "Connection/SSH/Bugs", "Workarounds for SSH server bugs"); s = ctrl_getset(b, "Connection/SSH/Bugs", "main", "Detection of known bugs in SSH servers"); - ctrl_droplist(s, "Chokes on SSH-1 ignore messages", 'i', 20, - HELPCTX(ssh_bugs_ignore1), - sshbug_handler, I(CONF_sshbug_ignore1)); - ctrl_droplist(s, "Refuses all SSH-1 password camouflage", 's', 20, - HELPCTX(ssh_bugs_plainpw1), - sshbug_handler, I(CONF_sshbug_plainpw1)); - ctrl_droplist(s, "Chokes on SSH-1 RSA authentication", 'r', 20, - HELPCTX(ssh_bugs_rsa1), - sshbug_handler, I(CONF_sshbug_rsa1)); ctrl_droplist(s, "Chokes on SSH-2 ignore messages", '2', 20, HELPCTX(ssh_bugs_ignore2), sshbug_handler, I(CONF_sshbug_ignore2)); + ctrl_droplist(s, "Handles SSH-2 key re-exchange badly", 'k', 20, + HELPCTX(ssh_bugs_rekey2), + sshbug_handler, I(CONF_sshbug_rekey2)); ctrl_droplist(s, "Chokes on PuTTY's SSH-2 'winadj' requests", 'j', 20, HELPCTX(ssh_bugs_winadj), sshbug_handler, I(CONF_sshbug_winadj)); - ctrl_droplist(s, "Miscomputes SSH-2 HMAC keys", 'm', 20, - HELPCTX(ssh_bugs_hmac2), - sshbug_handler, I(CONF_sshbug_hmac2)); - ctrl_droplist(s, "Miscomputes SSH-2 encryption keys", 'e', 20, - HELPCTX(ssh_bugs_derivekey2), - sshbug_handler, I(CONF_sshbug_derivekey2)); + ctrl_droplist(s, "Replies to requests on closed channels", 'q', 20, + HELPCTX(ssh_bugs_chanreq), + sshbug_handler, I(CONF_sshbug_chanreq)); + ctrl_droplist(s, "Ignores SSH-2 maximum packet size", 'x', 20, + HELPCTX(ssh_bugs_maxpkt2), + sshbug_handler, I(CONF_sshbug_maxpkt2)); + + ctrl_settitle(b, "Connection/SSH/More bugs", + "Further workarounds for SSH server bugs"); + + s = ctrl_getset(b, "Connection/SSH/More bugs", "main", + "Detection of known bugs in SSH servers"); ctrl_droplist(s, "Requires padding on SSH-2 RSA signatures", 'p', 20, HELPCTX(ssh_bugs_rsapad2), sshbug_handler, I(CONF_sshbug_rsapad2)); + ctrl_droplist(s, "Only supports pre-RFC4419 SSH-2 DH GEX", 'd', 20, + HELPCTX(ssh_bugs_oldgex2), + sshbug_handler, I(CONF_sshbug_oldgex2)); + ctrl_droplist(s, "Miscomputes SSH-2 HMAC keys", 'm', 20, + HELPCTX(ssh_bugs_hmac2), + sshbug_handler, I(CONF_sshbug_hmac2)); ctrl_droplist(s, "Misuses the session ID in SSH-2 PK auth", 'n', 20, HELPCTX(ssh_bugs_pksessid2), sshbug_handler, I(CONF_sshbug_pksessid2)); - ctrl_droplist(s, "Handles SSH-2 key re-exchange badly", 'k', 20, - HELPCTX(ssh_bugs_rekey2), - sshbug_handler, I(CONF_sshbug_rekey2)); - ctrl_droplist(s, "Ignores SSH-2 maximum packet size", 'x', 20, - HELPCTX(ssh_bugs_maxpkt2), - sshbug_handler, I(CONF_sshbug_maxpkt2)); + ctrl_droplist(s, "Miscomputes SSH-2 encryption keys", 'e', 20, + HELPCTX(ssh_bugs_derivekey2), + sshbug_handler, I(CONF_sshbug_derivekey2)); + ctrl_droplist(s, "Chokes on SSH-1 ignore messages", 'i', 20, + HELPCTX(ssh_bugs_ignore1), + sshbug_handler, I(CONF_sshbug_ignore1)); + ctrl_droplist(s, "Refuses all SSH-1 password camouflage", 's', 20, + HELPCTX(ssh_bugs_plainpw1), + sshbug_handler, I(CONF_sshbug_plainpw1)); + ctrl_droplist(s, "Chokes on SSH-1 RSA authentication", 'r', 20, + HELPCTX(ssh_bugs_rsa1), + sshbug_handler, I(CONF_sshbug_rsa1)); } } }