]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - config.c
Elliptic-curve cryptography support.
[PuTTY.git] / config.c
index 147f0c4e6efaca69a6631d6a953ea09e50881df7..c01c6812a90cdc7b41e9f63e389ddd248c9b9745 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;
 
@@ -2099,6 +2168,26 @@ void setup_config_box(struct controlbox *b, int midsession,
                          I(CONF_compression));
        }
 
+       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',
+                         HELPCTX(ssh_share),
+                         conf_checkbox_handler,
+                         I(CONF_ssh_connection_sharing));
+
+            ctrl_text(s, "Permitted roles in a shared connection:",
+                      HELPCTX(ssh_share));
+           ctrl_checkbox(s, "Upstream (connecting to the real server)", 'u',
+                         HELPCTX(ssh_share),
+                         conf_checkbox_handler,
+                         I(CONF_ssh_connection_sharing_upstream));
+           ctrl_checkbox(s, "Downstream (connecting to the upstream PuTTY)", 'd',
+                         HELPCTX(ssh_share),
+                         conf_checkbox_handler,
+                         I(CONF_ssh_connection_sharing_downstream));
+       }
+
        if (!midsession) {
            s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options");
 
@@ -2143,6 +2232,42 @@ void setup_config_box(struct controlbox *b, int midsession,
                         I(16));
            ctrl_text(s, "(Use 1M for 1 megabyte, 1G for 1 gigabyte etc)",
                      HELPCTX(ssh_kex_repeat));
+
+           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) {
@@ -2470,6 +2595,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 channel requests after channel close",
+                          'q', 20, HELPCTX(ssh_bugs_chanreq),
+                         sshbug_handler, I(CONF_sshbug_chanreq));
        }
     }
 }