Basic configurability for client-initiated rekeys.
[u/mdw/putty] / config.c
index 8588b23..6511502 100644 (file)
--- 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)
 {
@@ -362,6 +404,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg,
                    dlg_end(dlg, 1);
                } else
                    dlg_beep(dlg);
+                return;
            }
 
            /*
@@ -884,6 +927,9 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
                      "Always overwrite it", I(LGXF_OVR),
                      "Always append to the end of it", I(LGXF_APN),
                      "Ask the user every time", I(LGXF_ASK), NULL);
+    ctrl_checkbox(s, "Flush log file frequently", 'u',
+                HELPCTX(logging_flush),
+                dlg_stdcheckbox_handler, I(offsetof(Config,logflush)));
 
     if ((midsession && protocol == PROT_SSH) ||
        (!midsession && backends[3].name != NULL)) {
@@ -1233,6 +1279,12 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
 
     s = ctrl_getset(b, "Window/Colours", "general",
                    "General options for colour usage");
+    ctrl_checkbox(s, "Allow terminal to specify ANSI colours", 'i',
+                 HELPCTX(colours_ansi),
+                 dlg_stdcheckbox_handler, I(offsetof(Config,ansi_colour)));
+    ctrl_checkbox(s, "Allow terminal to use xterm 256-colour mode", '2',
+                 HELPCTX(colours_xterm256), dlg_stdcheckbox_handler,
+                 I(offsetof(Config,xterm_256_colour)));
     ctrl_checkbox(s, "Bolded text is a different colour", 'b',
                  HELPCTX(colours_bold),
                  dlg_stdcheckbox_handler, I(offsetof(Config,bold_colour)));
@@ -1288,6 +1340,36 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
                         HELPCTX(connection_username),
                         dlg_stdeditbox_handler, I(offsetof(Config,username)),
                         I(sizeof(((Config *)0)->username)));
+
+           ctrl_text(s, "Environment variables:", HELPCTX(telnet_environ));
+           ctrl_columns(s, 2, 80, 20);
+           ed = (struct environ_data *)
+               ctrl_alloc(b, sizeof(struct environ_data));
+           ed->varbox = ctrl_editbox(s, "Variable", 'v', 60,
+                                     HELPCTX(telnet_environ),
+                                     environ_handler, P(ed), P(NULL));
+           ed->varbox->generic.column = 0;
+           ed->valbox = ctrl_editbox(s, "Value", 'l', 60,
+                                     HELPCTX(telnet_environ),
+                                     environ_handler, P(ed), P(NULL));
+           ed->valbox->generic.column = 0;
+           ed->addbutton = ctrl_pushbutton(s, "Add", 'd',
+                                           HELPCTX(telnet_environ),
+                                           environ_handler, P(ed));
+           ed->addbutton->generic.column = 1;
+           ed->rembutton = ctrl_pushbutton(s, "Remove", 'r',
+                                           HELPCTX(telnet_environ),
+                                           environ_handler, P(ed));
+           ed->rembutton->generic.column = 1;
+           ctrl_columns(s, 1, 100);
+           ed->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
+                                      HELPCTX(telnet_environ),
+                                      environ_handler, P(ed));
+           ed->listbox->listbox.height = 3;
+           ed->listbox->listbox.ncols = 2;
+           ed->listbox->listbox.percentages = snewn(2, int);
+           ed->listbox->listbox.percentages[0] = 30;
+           ed->listbox->listbox.percentages[1] = 70;
        }
 
        s = ctrl_getset(b, "Connection", "keepalive",
@@ -1389,40 +1471,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist,
        ctrl_settitle(b, "Connection/Telnet",
                      "Options controlling Telnet connections");
 
-       if (!midsession) {
-           s = ctrl_getset(b, "Connection/Telnet", "data",
-                           "Data to send to the server");
-           ctrl_text(s, "Environment variables:", HELPCTX(telnet_environ));
-           ctrl_columns(s, 2, 80, 20);
-           ed = (struct environ_data *)
-               ctrl_alloc(b, sizeof(struct environ_data));
-           ed->varbox = ctrl_editbox(s, "Variable", 'v', 60,
-                                     HELPCTX(telnet_environ),
-                                     environ_handler, P(ed), P(NULL));
-           ed->varbox->generic.column = 0;
-           ed->valbox = ctrl_editbox(s, "Value", 'l', 60,
-                                     HELPCTX(telnet_environ),
-                                     environ_handler, P(ed), P(NULL));
-           ed->valbox->generic.column = 0;
-           ed->addbutton = ctrl_pushbutton(s, "Add", 'd',
-                                           HELPCTX(telnet_environ),
-                                           environ_handler, P(ed));
-           ed->addbutton->generic.column = 1;
-           ed->rembutton = ctrl_pushbutton(s, "Remove", 'r',
-                                           HELPCTX(telnet_environ),
-                                           environ_handler, P(ed));
-           ed->rembutton->generic.column = 1;
-           ctrl_columns(s, 1, 100);
-           ed->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
-                                      HELPCTX(telnet_environ),
-                                      environ_handler, P(ed));
-           ed->listbox->listbox.height = 3;
-           ed->listbox->listbox.ncols = 2;
-           ed->listbox->listbox.percentages = snewn(2, int);
-           ed->listbox->listbox.percentages[0] = 30;
-           ed->listbox->listbox.percentages[1] = 70;
-       }
-
        s = ctrl_getset(b, "Connection/Telnet", "protocol",
                        "Telnet protocol adjustments");
 
@@ -1520,6 +1568,37 @@ 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;
+
+       s = ctrl_getset(b, "Connection/SSH/Kex", "repeat",
+                       "Options controlling key re-exchange");
+
+       /* FIXME: these could usefully be configured mid-session in SSH-2.
+        *        (So could cipher/compression/kex, now we have rekey.) */
+       ctrl_editbox(s, "Max minutes before rekey (0 for no limit)", 't', 20,
+                    HELPCTX(ssh_kex_repeat),
+                    dlg_stdeditbox_handler,
+                    I(offsetof(Config,ssh_rekey_time)),
+                    I(-1));
+       ctrl_editbox(s, "Max data before rekey (0 for no limit)", 'd', 20,
+                    HELPCTX(ssh_kex_repeat),
+                    dlg_stdeditbox_handler,
+                    I(offsetof(Config,ssh_rekey_data)),
+                    I(16));
+       ctrl_text(s, "(Use 1M for 1 megabyte, 1G for 1 gigabyte etc)",
+                 HELPCTX(ssh_kex_repeat));
+
+       /*
         * The Connection/SSH/Auth panel.
         */
        ctrl_settitle(b, "Connection/SSH/Auth",
@@ -1653,9 +1732,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)));