]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - config.c
Merge branch 'pre-0.64'
[PuTTY.git] / config.c
index 5d0193440fd31aadc58bac1d9832c2b7a88085e1..0d292b8af4ff64c6606de8639b768b869fba9858 100644 (file)
--- a/config.c
+++ b/config.c
@@ -433,6 +433,7 @@ static void kexlist_handler(union control *ctrl, void *dlg,
            { "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 }
        };
 
@@ -1127,8 +1128,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)
@@ -1146,7 +1147,7 @@ static void portfwd_handler(union control *ctrl, void *dlg,
            }
            if (*type != 'D') {
                val = dlg_editbox_get(pfd->destbox, dlg);
-               if (!*val || !strchr(val, ':')) {
+               if (!*val || !host_strchr(val, ':')) {
                    dlg_error_msg(dlg,
                                  "You need to specify a destination address\n"
                                  "in the form \"host.name:port\"");
@@ -1225,6 +1226,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 +1303,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;
 
@@ -2068,7 +2137,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 +2160,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 +2169,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',
@@ -2134,10 +2204,11 @@ void setup_config_box(struct controlbox *b, int midsession,
 
        /*
         * 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 +2236,50 @@ void setup_config_box(struct controlbox *b, int midsession,
                      HELPCTX(ssh_kex_repeat));
        }
 
-       if (!midsession || protcfginfo != 1) {
+       /*
+        * 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/Kex", "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.
             */
@@ -2490,6 +2604,9 @@ void setup_config_box(struct controlbox *b, int midsession,
            ctrl_droplist(s, "Ignores SSH-2 maximum packet size", 'x', 20,
                          HELPCTX(ssh_bugs_maxpkt2),
                          sshbug_handler, I(CONF_sshbug_maxpkt2));
+           ctrl_droplist(s, "Replies to requests on closed channels", 'q', 20,
+                         HELPCTX(ssh_bugs_chanreq),
+                         sshbug_handler, I(CONF_sshbug_chanreq));
        }
     }
 }