Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitrij <kvarkas@gmail.com>2022-10-31 00:45:23 +0300
committerDimitrij <kvarkas@gmail.com>2022-10-31 00:45:23 +0300
commit302fb2e8ddea1c993552c9a30c02f41d01ca54a9 (patch)
treed6cf1b32664296ef2cecda33caeafbe39e6695c1 /config.c
parent59105d9b26363e47f00676bd365b2ac8d4cb536a (diff)
parent4ff82ab29a22936b78510c68f544a99e677efed3 (diff)
Merge tag 'tags/0.78'HEADmaster
Diffstat (limited to 'config.c')
-rw-r--r--config.c605
1 files changed, 369 insertions, 236 deletions
diff --git a/config.c b/config.c
index b8348530..8cdeee24 100644
--- a/config.c
+++ b/config.c
@@ -9,13 +9,14 @@
#include "putty.h"
#include "dialog.h"
#include "storage.h"
+#include "tree234.h"
#define PRINTER_DISABLED_STRING "None (printing disabled)"
#define HOST_BOX_TITLE "Host Name (or IP address)"
#define PORT_BOX_TITLE "Port"
-void conf_radiobutton_handler(union control *ctrl, dlgparam *dlg,
+void conf_radiobutton_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
int button;
@@ -28,7 +29,7 @@ void conf_radiobutton_handler(union control *ctrl, dlgparam *dlg,
* is the one selected.
*/
if (event == EVENT_REFRESH) {
- int val = conf_get_int(conf, ctrl->radio.context.i);
+ int val = conf_get_int(conf, ctrl->context.i);
for (button = 0; button < ctrl->radio.nbuttons; button++)
if (val == ctrl->radio.buttondata[button].i)
break;
@@ -38,12 +39,12 @@ void conf_radiobutton_handler(union control *ctrl, dlgparam *dlg,
} else if (event == EVENT_VALCHANGE) {
button = dlg_radiobutton_get(ctrl, dlg);
assert(button >= 0 && button < ctrl->radio.nbuttons);
- conf_set_int(conf, ctrl->radio.context.i,
+ conf_set_int(conf, ctrl->context.i,
ctrl->radio.buttondata[button].i);
}
}
-void conf_radiobutton_bool_handler(union control *ctrl, dlgparam *dlg,
+void conf_radiobutton_bool_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
int button;
@@ -55,7 +56,7 @@ void conf_radiobutton_bool_handler(union control *ctrl, dlgparam *dlg,
* config option.
*/
if (event == EVENT_REFRESH) {
- int val = conf_get_bool(conf, ctrl->radio.context.i);
+ int val = conf_get_bool(conf, ctrl->context.i);
for (button = 0; button < ctrl->radio.nbuttons; button++)
if (val == ctrl->radio.buttondata[button].i)
break;
@@ -65,13 +66,13 @@ void conf_radiobutton_bool_handler(union control *ctrl, dlgparam *dlg,
} else if (event == EVENT_VALCHANGE) {
button = dlg_radiobutton_get(ctrl, dlg);
assert(button >= 0 && button < ctrl->radio.nbuttons);
- conf_set_bool(conf, ctrl->radio.context.i,
+ conf_set_bool(conf, ctrl->context.i,
ctrl->radio.buttondata[button].i);
}
}
#define CHECKBOX_INVERT (1<<30)
-void conf_checkbox_handler(union control *ctrl, dlgparam *dlg,
+void conf_checkbox_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
int key;
@@ -82,7 +83,7 @@ void conf_checkbox_handler(union control *ctrl, dlgparam *dlg,
* For a standard checkbox, the context parameter gives the
* primary key (CONF_foo), optionally ORed with CHECKBOX_INVERT.
*/
- key = ctrl->checkbox.context.i;
+ key = ctrl->context.i;
if (key & CHECKBOX_INVERT) {
key &= ~CHECKBOX_INVERT;
invert = true;
@@ -103,27 +104,23 @@ void conf_checkbox_handler(union control *ctrl, dlgparam *dlg,
}
}
-void conf_editbox_handler(union control *ctrl, dlgparam *dlg,
+const struct conf_editbox_handler_type conf_editbox_str = {.type = EDIT_STR};
+const struct conf_editbox_handler_type conf_editbox_int = {.type = EDIT_INT};
+
+void conf_editbox_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
/*
- * The standard edit-box handler expects the main `context'
- * field to contain the primary key. The secondary `context2'
- * field indicates the type of this field:
- *
- * - if context2 > 0, the field is a string.
- * - if context2 == -1, the field is an int and the edit box
- * is numeric.
- * - if context2 < -1, the field is an int and the edit box is
- * _floating_, and (-context2) gives the scale. (E.g. if
- * context2 == -1000, then typing 1.2 into the box will set
- * the field to 1200.)
+ * The standard edit-box handler expects the main `context' field
+ * to contain the primary key. The secondary `context2' field is a
+ * pointer to the struct conf_editbox_handler_type defined in
+ * putty.h.
*/
- int key = ctrl->editbox.context.i;
- int length = ctrl->editbox.context2.i;
+ int key = ctrl->context.i;
+ const struct conf_editbox_handler_type *type = ctrl->context2.cp;
Conf *conf = (Conf *)data;
- if (length > 0) {
+ if (type->type == EDIT_STR) {
if (event == EVENT_REFRESH) {
char *field = conf_get_str(conf, key);
dlg_editbox_set(ctrl, dlg, field);
@@ -132,30 +129,30 @@ void conf_editbox_handler(union control *ctrl, dlgparam *dlg,
conf_set_str(conf, key, field);
sfree(field);
}
- } else if (length < 0) {
+ } else {
if (event == EVENT_REFRESH) {
char str[80];
int value = conf_get_int(conf, key);
- if (length == -1)
+ if (type->type == EDIT_INT)
sprintf(str, "%d", value);
else
- sprintf(str, "%g", (double)value / (double)(-length));
+ sprintf(str, "%g", (double)value / type->denominator);
dlg_editbox_set(ctrl, dlg, str);
} else if (event == EVENT_VALCHANGE) {
char *str = dlg_editbox_get(ctrl, dlg);
- if (length == -1)
+ if (type->type == EDIT_INT)
conf_set_int(conf, key, atoi(str));
else
- conf_set_int(conf, key, (int)((-length) * atof(str)));
+ conf_set_int(conf, key, (int)(type->denominator * atof(str)));
sfree(str);
}
}
}
-void conf_filesel_handler(union control *ctrl, dlgparam *dlg,
+void conf_filesel_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
- int key = ctrl->fileselect.context.i;
+ int key = ctrl->context.i;
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
@@ -168,10 +165,10 @@ void conf_filesel_handler(union control *ctrl, dlgparam *dlg,
}
}
-void conf_fontsel_handler(union control *ctrl, dlgparam *dlg,
+void conf_fontsel_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
- int key = ctrl->fontselect.context.i;
+ int key = ctrl->context.i;
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
@@ -184,7 +181,7 @@ void conf_fontsel_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void config_host_handler(union control *ctrl, dlgparam *dlg,
+static void config_host_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
@@ -216,7 +213,7 @@ static void config_host_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void config_port_handler(union control *ctrl, dlgparam *dlg,
+static void config_port_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
@@ -257,7 +254,7 @@ static void config_port_handler(union control *ctrl, dlgparam *dlg,
}
struct hostport {
- union control *host, *port, *protradio, *protlist;
+ dlgcontrol *host, *port, *protradio, *protlist;
bool mid_refresh;
};
@@ -268,12 +265,12 @@ struct hostport {
* and refreshes both host and port boxes when switching to/from the
* serial backend.
*/
-static void config_protocols_handler(union control *ctrl, dlgparam *dlg,
+static void config_protocols_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
int curproto = conf_get_int(conf, CONF_protocol);
- struct hostport *hp = (struct hostport *)ctrl->generic.context.p;
+ struct hostport *hp = (struct hostport *)ctrl->context.p;
if (event == EVENT_REFRESH) {
/*
@@ -312,7 +309,7 @@ static void config_protocols_handler(union control *ctrl, dlgparam *dlg,
for (size_t i = n_ui_backends;
i < PROTOCOL_LIMIT && backends[i]; i++) {
dlg_listbox_addwithid(ctrl, dlg,
- backends[i]->displayname,
+ backends[i]->displayname_tc,
backends[i]->protocol);
if (backends[i]->protocol == curproto)
curentry = i - n_ui_backends;
@@ -421,7 +418,7 @@ static void config_protocols_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void loggingbuttons_handler(union control *ctrl, dlgparam *dlg,
+static void loggingbuttons_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
int button;
@@ -450,7 +447,7 @@ static void loggingbuttons_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void numeric_keypad_handler(union control *ctrl, dlgparam *dlg,
+static void numeric_keypad_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
int button;
@@ -481,7 +478,7 @@ static void numeric_keypad_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void cipherlist_handler(union control *ctrl, dlgparam *dlg,
+static void cipherlist_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
@@ -490,6 +487,7 @@ static void cipherlist_handler(union control *ctrl, dlgparam *dlg,
static const struct { const char *s; int c; } ciphers[] = {
{ "ChaCha20 (SSH-2 only)", CIPHER_CHACHA20 },
+ { "AES-GCM (SSH-2 only)", CIPHER_AESGCM },
{ "3DES", CIPHER_3DES },
{ "Blowfish", CIPHER_BLOWFISH },
{ "DES", CIPHER_DES },
@@ -527,7 +525,7 @@ static void cipherlist_handler(union control *ctrl, dlgparam *dlg,
}
#ifndef NO_GSSAPI
-static void gsslist_handler(union control *ctrl, dlgparam *dlg,
+static void gsslist_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
@@ -554,7 +552,7 @@ static void gsslist_handler(union control *ctrl, dlgparam *dlg,
}
#endif
-static void kexlist_handler(union control *ctrl, dlgparam *dlg,
+static void kexlist_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
@@ -562,12 +560,17 @@ static void kexlist_handler(union control *ctrl, dlgparam *dlg,
int i;
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 }
+ { "Diffie-Hellman group 1 (1024-bit)", KEX_DHGROUP1 },
+ { "Diffie-Hellman group 14 (2048-bit)", KEX_DHGROUP14 },
+ { "Diffie-Hellman group 15 (3072-bit)", KEX_DHGROUP15 },
+ { "Diffie-Hellman group 16 (4096-bit)", KEX_DHGROUP16 },
+ { "Diffie-Hellman group 17 (6144-bit)", KEX_DHGROUP17 },
+ { "Diffie-Hellman group 18 (8192-bit)", KEX_DHGROUP18 },
+ { "Diffie-Hellman group exchange", KEX_DHGEX },
+ { "RSA-based key exchange", KEX_RSA },
+ { "ECDH key exchange", KEX_ECDH },
+ { "NTRU Prime / Curve25519 hybrid kex", KEX_NTRU_HYBRID },
+ { "-- warn below here --", KEX_WARN }
};
/* Set up the "kex preference" box. */
@@ -598,8 +601,8 @@ static void kexlist_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void hklist_handler(union control *ctrl, dlgparam *dlg,
- void *data, int event)
+static void hklist_handler(dlgcontrol *ctrl, dlgparam *dlg,
+ void *data, int event)
{
Conf *conf = (Conf *)data;
if (event == EVENT_REFRESH) {
@@ -642,7 +645,7 @@ static void hklist_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void printerbox_handler(union control *ctrl, dlgparam *dlg,
+static void printerbox_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
@@ -678,7 +681,7 @@ static void printerbox_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void codepage_handler(union control *ctrl, dlgparam *dlg,
+static void codepage_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
@@ -702,7 +705,7 @@ static void codepage_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void sshbug_handler(union control *ctrl, dlgparam *dlg,
+static void sshbug_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
@@ -713,7 +716,7 @@ static void sshbug_handler(union control *ctrl, dlgparam *dlg,
* spurious SELCHANGE we trigger in the process will overwrite
* the value we wanted to keep.
*/
- int oldconf = conf_get_int(conf, ctrl->listbox.context.i);
+ int oldconf = conf_get_int(conf, ctrl->context.i);
dlg_update_start(ctrl, dlg);
dlg_listbox_clear(ctrl, dlg);
dlg_listbox_addwithid(ctrl, dlg, "Auto", AUTO);
@@ -731,13 +734,44 @@ static void sshbug_handler(union control *ctrl, dlgparam *dlg,
i = AUTO;
else
i = dlg_listbox_getid(ctrl, dlg, i);
- conf_set_int(conf, ctrl->listbox.context.i, i);
+ conf_set_int(conf, ctrl->context.i, i);
+ }
+}
+
+static void sshbug_handler_manual_only(dlgcontrol *ctrl, dlgparam *dlg,
+ void *data, int event)
+{
+ /*
+ * This is just like sshbug_handler, except that there's no 'Auto'
+ * option. Used for bug workaround flags that can't be
+ * autodetected, and have to be manually enabled if they're to be
+ * used at all.
+ */
+ Conf *conf = (Conf *)data;
+ if (event == EVENT_REFRESH) {
+ int oldconf = conf_get_int(conf, ctrl->context.i);
+ dlg_update_start(ctrl, dlg);
+ dlg_listbox_clear(ctrl, dlg);
+ dlg_listbox_addwithid(ctrl, dlg, "Off", FORCE_OFF);
+ dlg_listbox_addwithid(ctrl, dlg, "On", FORCE_ON);
+ switch (oldconf) {
+ case FORCE_OFF: dlg_listbox_select(ctrl, dlg, 0); break;
+ case FORCE_ON: dlg_listbox_select(ctrl, dlg, 1); break;
+ }
+ dlg_update_done(ctrl, dlg);
+ } else if (event == EVENT_SELCHANGE) {
+ int i = dlg_listbox_index(ctrl, dlg);
+ if (i < 0)
+ i = FORCE_OFF;
+ else
+ i = dlg_listbox_getid(ctrl, dlg, i);
+ conf_set_int(conf, ctrl->context.i, i);
}
}
struct sessionsaver_data {
- union control *editbox, *listbox, *loadbutton, *savebutton, *delbutton;
- union control *okbutton, *cancelbutton;
+ dlgcontrol *editbox, *listbox, *loadbutton, *savebutton, *delbutton;
+ dlgcontrol *okbutton, *cancelbutton;
struct sesslist sesslist;
bool midsession;
char *savedsession; /* the current contents of ssd->editbox */
@@ -779,12 +813,12 @@ static bool load_selected_session(
return true;
}
-static void sessionsaver_handler(union control *ctrl, dlgparam *dlg,
+static void sessionsaver_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
struct sessionsaver_data *ssd =
- (struct sessionsaver_data *)ctrl->generic.context.p;
+ (struct sessionsaver_data *)ctrl->context.p;
if (event == EVENT_REFRESH) {
if (ctrl == ssd->editbox) {
@@ -917,15 +951,15 @@ static void sessionsaver_handler(union control *ctrl, dlgparam *dlg,
}
struct charclass_data {
- union control *listbox, *editbox, *button;
+ dlgcontrol *listbox, *editbox, *button;
};
-static void charclass_handler(union control *ctrl, dlgparam *dlg,
+static void charclass_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
struct charclass_data *ccd =
- (struct charclass_data *)ctrl->generic.context.p;
+ (struct charclass_data *)ctrl->context.p;
if (event == EVENT_REFRESH) {
if (ctrl == ccd->listbox) {
@@ -958,7 +992,7 @@ static void charclass_handler(union control *ctrl, dlgparam *dlg,
}
struct colour_data {
- union control *listbox, *redit, *gedit, *bedit, *button;
+ dlgcontrol *listbox, *redit, *gedit, *bedit, *button;
};
/* Array of the user-visible colour names defined in the list macro in
@@ -969,12 +1003,12 @@ static const char *const colours[] = {
#undef CONF_COLOUR_NAME_DECL
};
-static void colour_handler(union control *ctrl, dlgparam *dlg,
+static void colour_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
struct colour_data *cd =
- (struct colour_data *)ctrl->generic.context.p;
+ (struct colour_data *)ctrl->context.p;
bool update = false, clear = false;
int r, g, b;
@@ -1075,15 +1109,15 @@ static void colour_handler(union control *ctrl, dlgparam *dlg,
}
struct ttymodes_data {
- union control *valradio, *valbox, *setbutton, *listbox;
+ dlgcontrol *valradio, *valbox, *setbutton, *listbox;
};
-static void ttymodes_handler(union control *ctrl, dlgparam *dlg,
+static void ttymodes_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
struct ttymodes_data *td =
- (struct ttymodes_data *)ctrl->generic.context.p;
+ (struct ttymodes_data *)ctrl->context.p;
if (event == EVENT_REFRESH) {
if (ctrl == td->listbox) {
@@ -1160,15 +1194,15 @@ static void ttymodes_handler(union control *ctrl, dlgparam *dlg,
}
struct environ_data {
- union control *varbox, *valbox, *addbutton, *rembutton, *listbox;
+ dlgcontrol *varbox, *valbox, *addbutton, *rembutton, *listbox;
};
-static void environ_handler(union control *ctrl, dlgparam *dlg,
+static void environ_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
struct environ_data *ed =
- (struct environ_data *)ctrl->generic.context.p;
+ (struct environ_data *)ctrl->context.p;
if (event == EVENT_REFRESH) {
if (ctrl == ed->listbox) {
@@ -1232,19 +1266,19 @@ static void environ_handler(union control *ctrl, dlgparam *dlg,
}
struct portfwd_data {
- union control *addbutton, *rembutton, *listbox;
- union control *sourcebox, *destbox, *direction;
+ dlgcontrol *addbutton, *rembutton, *listbox;
+ dlgcontrol *sourcebox, *destbox, *direction;
#ifndef NO_IPV6
- union control *addressfamily;
+ dlgcontrol *addressfamily;
#endif
};
-static void portfwd_handler(union control *ctrl, dlgparam *dlg,
+static void portfwd_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
struct portfwd_data *pfd =
- (struct portfwd_data *)ctrl->generic.context.p;
+ (struct portfwd_data *)ctrl->context.p;
if (event == EVENT_REFRESH) {
if (ctrl == pfd->listbox) {
@@ -1400,15 +1434,15 @@ static void portfwd_handler(union control *ctrl, dlgparam *dlg,
}
struct manual_hostkey_data {
- union control *addbutton, *rembutton, *listbox, *keybox;
+ dlgcontrol *addbutton, *rembutton, *listbox, *keybox;
};
-static void manual_hostkey_handler(union control *ctrl, dlgparam *dlg,
+static void manual_hostkey_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
struct manual_hostkey_data *mh =
- (struct manual_hostkey_data *)ctrl->generic.context.p;
+ (struct manual_hostkey_data *)ctrl->context.p;
if (event == EVENT_REFRESH) {
if (ctrl == mh->listbox) {
@@ -1466,13 +1500,13 @@ static void manual_hostkey_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void clipboard_selector_handler(union control *ctrl, dlgparam *dlg,
+static void clipboard_selector_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
Conf *conf = (Conf *)data;
- int setting = ctrl->generic.context.i;
+ int setting = ctrl->context.i;
#ifdef NAMED_CLIPBOARDS
- int strsetting = ctrl->editbox.context2.i;
+ int strsetting = ctrl->context2.i;
#endif
static const struct {
@@ -1554,7 +1588,7 @@ static void clipboard_selector_handler(union control *ctrl, dlgparam *dlg,
}
static void clipboard_control(struct controlset *s, const char *label,
- char shortcut, int percentage, intorptr helpctx,
+ char shortcut, int percentage, HelpCtx helpctx,
int setting, int strsetting)
{
#ifdef NAMED_CLIPBOARDS
@@ -1567,7 +1601,7 @@ static void clipboard_control(struct controlset *s, const char *label,
#endif
}
-static void serial_parity_handler(union control *ctrl, dlgparam *dlg,
+static void serial_parity_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
static const struct {
@@ -1580,7 +1614,7 @@ static void serial_parity_handler(union control *ctrl, dlgparam *dlg,
{"Mark", SER_PAR_MARK},
{"Space", SER_PAR_SPACE},
};
- int mask = ctrl->listbox.context.i;
+ int mask = ctrl->context.i;
int i, j;
Conf *conf = (Conf *)data;
@@ -1622,7 +1656,7 @@ static void serial_parity_handler(union control *ctrl, dlgparam *dlg,
}
}
-static void serial_flow_handler(union control *ctrl, dlgparam *dlg,
+static void serial_flow_handler(dlgcontrol *ctrl, dlgparam *dlg,
void *data, int event)
{
static const struct {
@@ -1634,7 +1668,7 @@ static void serial_flow_handler(union control *ctrl, dlgparam *dlg,
{"RTS/CTS", SER_FLOW_RTSCTS},
{"DSR/DTR", SER_FLOW_DSRDTR},
};
- int mask = ctrl->listbox.context.i;
+ int mask = ctrl->context.i;
int i, j;
Conf *conf = (Conf *)data;
@@ -1675,6 +1709,67 @@ static void serial_flow_handler(union control *ctrl, dlgparam *dlg,
}
}
+void proxy_type_handler(dlgcontrol *ctrl, dlgparam *dlg,
+ void *data, int event)
+{
+ Conf *conf = (Conf *)data;
+ if (event == EVENT_REFRESH) {
+ /*
+ * We must fetch the previously configured value from the Conf
+ * before we start modifying the drop-down list, otherwise the
+ * spurious SELCHANGE we trigger in the process will overwrite
+ * the value we wanted to keep.
+ */
+ int proxy_type = conf_get_int(conf, CONF_proxy_type);
+
+ dlg_update_start(ctrl, dlg);
+ dlg_listbox_clear(ctrl, dlg);
+
+ int index_to_select = 0, current_index = 0;
+
+#define ADD(id, title) do { \
+ dlg_listbox_addwithid(ctrl, dlg, title, id); \
+ if (id == proxy_type) \
+ index_to_select = current_index; \
+ current_index++; \
+ } while (0)
+
+ ADD(PROXY_NONE, "None");
+ ADD(PROXY_SOCKS5, "SOCKS 5");
+ ADD(PROXY_SOCKS4, "SOCKS 4");
+ ADD(PROXY_HTTP, "HTTP CONNECT");
+ if (ssh_proxy_supported) {
+ ADD(PROXY_SSH_TCPIP, "SSH to proxy and use port forwarding");
+ ADD(PROXY_SSH_EXEC, "SSH to proxy and execute a command");
+ ADD(PROXY_SSH_SUBSYSTEM, "SSH to proxy and invoke a subsystem");
+ }
+ if (ctrl->context.i & PROXY_UI_FLAG_LOCAL) {
+ ADD(PROXY_CMD, "Local (run a subprogram to connect)");
+ }
+ ADD(PROXY_TELNET, "'Telnet' (send an ad-hoc command)");
+
+#undef ADD
+
+ dlg_listbox_select(ctrl, dlg, index_to_select);
+
+ dlg_update_done(ctrl, dlg);
+ } else if (event == EVENT_SELCHANGE) {
+ int i = dlg_listbox_index(ctrl, dlg);
+ if (i < 0)
+ i = AUTO;
+ else
+ i = dlg_listbox_getid(ctrl, dlg, i);
+ conf_set_int(conf, CONF_proxy_type, i);
+ }
+}
+
+static void host_ca_button_handler(dlgcontrol *ctrl, dlgparam *dp,
+ void *data, int event)
+{
+ if (event == EVENT_ACTION)
+ show_ca_config_box(dp);
+}
+
void setup_config_box(struct controlbox *b, bool midsession,
int protocol, int protcfginfo)
{
@@ -1687,7 +1782,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
struct environ_data *ed;
struct portfwd_data *pfd;
struct manual_hostkey_data *mh;
- union control *c;
+ dlgcontrol *c;
bool resize_forbidden = false;
char *str;
@@ -1710,11 +1805,11 @@ void setup_config_box(struct controlbox *b, bool midsession,
HELPCTX(no_help),
sessionsaver_handler, P(ssd));
ssd->okbutton->button.isdefault = true;
- ssd->okbutton->generic.column = 3;
+ ssd->okbutton->column = 3;
ssd->cancelbutton = ctrl_pushbutton(s, "Cancel", 'c', HELPCTX(no_help),
sessionsaver_handler, P(ssd));
ssd->cancelbutton->button.iscancel = true;
- ssd->cancelbutton->generic.column = 4;
+ ssd->cancelbutton->column = 4;
/* We carefully don't close the 5-column part, so that platform-
* specific add-ons can put extra buttons alongside Open and Cancel. */
@@ -1736,12 +1831,12 @@ void setup_config_box(struct controlbox *b, bool midsession,
c = ctrl_editbox(s, HOST_BOX_TITLE, 'n', 100,
HELPCTX(session_hostname),
config_host_handler, I(0), I(0));
- c->generic.column = 0;
+ c->column = 0;
hp->host = c;
c = ctrl_editbox(s, PORT_BOX_TITLE, 'p', 100,
HELPCTX(session_hostname),
config_port_handler, I(0), I(0));
- c->generic.column = 1;
+ c->column = 1;
hp->port = c;
ctrl_columns(s, 1, 100);
@@ -1749,8 +1844,8 @@ void setup_config_box(struct controlbox *b, bool midsession,
ctrl_columns(s, 2, 62, 38);
c = ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 3,
HELPCTX(session_hostname),
- config_protocols_handler, P(hp), NULL);
- c->generic.column = 0;
+ config_protocols_handler, P(hp));
+ c->column = 0;
hp->protradio = c;
c->radio.buttons = sresize(c->radio.buttons, PROTOCOL_LIMIT, char *);
c->radio.shortcuts = sresize(c->radio.shortcuts, PROTOCOL_LIMIT, char);
@@ -1762,7 +1857,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
for (size_t i = 0; i < n_ui_backends; i++) {
assert(backends[i]);
c->radio.buttons[c->radio.nbuttons] =
- dupstr(backends[i]->displayname);
+ dupstr(backends[i]->displayname_tc);
c->radio.shortcuts[c->radio.nbuttons] =
(backends[i]->protocol == PROT_SSH ? 's' :
backends[i]->protocol == PROT_SERIAL ? 'r' :
@@ -1785,10 +1880,10 @@ void setup_config_box(struct controlbox *b, bool midsession,
config_protocols_handler, P(hp));
hp->protlist = c;
/* droplist is populated in config_protocols_handler */
- c->generic.column = 1;
+ c->column = 1;
/* Vertically centre the two protocol controls w.r.t. each other */
- hp->protlist->generic.align_next_to = hp->protradio;
+ hp->protlist->align_next_to = hp->protradio;
ctrl_columns(s, 1, 100);
}
@@ -1804,7 +1899,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
ssd->editbox = ctrl_editbox(s, "Saved Sessions", 'e', 100,
HELPCTX(session_saved),
sessionsaver_handler, P(ssd), P(NULL));
- ssd->editbox->generic.column = 0;
+ ssd->editbox->column = 0;
/* Reset columns so that the buttons are alongside the list, rather
* than alongside that edit box. */
ctrl_columns(s, 1, 100);
@@ -1812,13 +1907,13 @@ void setup_config_box(struct controlbox *b, bool midsession,
ssd->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(session_saved),
sessionsaver_handler, P(ssd));
- ssd->listbox->generic.column = 0;
+ ssd->listbox->column = 0;
ssd->listbox->listbox.height = 7;
if (!midsession) {
ssd->loadbutton = ctrl_pushbutton(s, "Load", 'l',
HELPCTX(session_saved),
sessionsaver_handler, P(ssd));
- ssd->loadbutton->generic.column = 1;
+ ssd->loadbutton->column = 1;
} else {
/* We can't offer the Load button mid-session, as it would allow the
* user to load and subsequently save settings they can't see. (And
@@ -1830,12 +1925,12 @@ void setup_config_box(struct controlbox *b, bool midsession,
ssd->savebutton = ctrl_pushbutton(s, "Save", 'v',
HELPCTX(session_saved),
sessionsaver_handler, P(ssd));
- ssd->savebutton->generic.column = 1;
+ ssd->savebutton->column = 1;
if (!midsession) {
ssd->delbutton = ctrl_pushbutton(s, "Delete", 'd',
HELPCTX(session_saved),
sessionsaver_handler, P(ssd));
- ssd->delbutton->generic.column = 1;
+ ssd->delbutton->column = 1;
} else {
/* Disable the Delete button mid-session too, for UI consistency. */
ssd->delbutton = NULL;
@@ -1849,7 +1944,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
I(CONF_close_on_exit),
"Always", I(FORCE_ON),
"Never", I(FORCE_OFF),
- "Only on clean exit", I(AUTO), NULL);
+ "Only on clean exit", I(AUTO));
/*
* The Session/Logging panel.
@@ -1879,8 +1974,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Printable output", 'p', I(LGTYP_ASCII),
"All session output", 'l', I(LGTYP_DEBUG),
sshlogname, 's', I(LGTYP_PACKETS),
- sshrawlogname, 'r', I(LGTYP_SSHRAW),
- NULL);
+ sshrawlogname, 'r', I(LGTYP_SSHRAW));
}
ctrl_filesel(s, "Log file name:", 'f',
NULL, true, "Select session log file name",
@@ -1894,13 +1988,13 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_radiobutton_handler, I(CONF_logxfovr),
"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);
+ "Ask the user every time", I(LGXF_ASK));
ctrl_checkbox(s, "Flush log file frequently", 'u',
- HELPCTX(logging_flush),
- conf_checkbox_handler, I(CONF_logflush));
+ HELPCTX(logging_flush),
+ conf_checkbox_handler, I(CONF_logflush));
ctrl_checkbox(s, "Include header", 'i',
- HELPCTX(logging_header),
- conf_checkbox_handler, I(CONF_logheader));
+ HELPCTX(logging_header),
+ conf_checkbox_handler, I(CONF_logheader));
if ((midsession && protocol == PROT_SSH) ||
(!midsession && backend_vt_from_proto(PROT_SSH))) {
@@ -1940,7 +2034,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_checkbox_handler, I(CONF_blinktext));
ctrl_editbox(s, "Answerback to ^E:", 's', 100,
HELPCTX(terminal_answerback),
- conf_editbox_handler, I(CONF_answerback), I(1));
+ conf_editbox_handler, I(CONF_answerback), ED_STR);
s = ctrl_getset(b, "Terminal", "ldisc", "Line discipline options");
ctrl_radiobuttons(s, "Local echo:", 'l', 3,
@@ -1948,13 +2042,13 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_radiobutton_handler,I(CONF_localecho),
"Auto", I(AUTO),
"Force on", I(FORCE_ON),
- "Force off", I(FORCE_OFF), NULL);
+ "Force off", I(FORCE_OFF));
ctrl_radiobuttons(s, "Local line editing:", 't', 3,
HELPCTX(terminal_localedit),
conf_radiobutton_handler,I(CONF_localedit),
"Auto", I(AUTO),
"Force on", I(FORCE_ON),
- "Force off", I(FORCE_OFF), NULL);
+ "Force off", I(FORCE_OFF));
s = ctrl_getset(b, "Terminal", "printing", "Remote-controlled printing");
ctrl_combobox(s, "Printer to send ANSI printer output to:", 'p', 100,
@@ -1973,18 +2067,29 @@ void setup_config_box(struct controlbox *b, bool midsession,
HELPCTX(keyboard_backspace),
conf_radiobutton_bool_handler,
I(CONF_bksp_is_delete),
- "Control-H", I(0), "Control-? (127)", I(1), NULL);
+ "Control-H", I(0), "Control-? (127)", I(1));
ctrl_radiobuttons(s, "The Home and End keys", 'e', 2,
HELPCTX(keyboard_homeend),
conf_radiobutton_bool_handler,
I(CONF_rxvt_homeend),
- "Standard", I(false), "rxvt", I(true), NULL);
- ctrl_radiobuttons(s, "The Function keys and keypad", 'f', 3,
+ "Standard", I(false), "rxvt", I(true));
+ ctrl_radiobuttons(s, "The Function keys and keypad", 'f', 4,
HELPCTX(keyboard_funkeys),
conf_radiobutton_handler,
I(CONF_funky_type),
- "ESC[n~", I(0), "Linux", I(1), "Xterm R6", I(2),
- "VT400", I(3), "VT100+", I(4), "SCO", I(5), NULL);
+ "ESC[n~", I(FUNKY_TILDE),
+ "Linux", I(FUNKY_LINUX),
+ "Xterm R6", I(FUNKY_XTERM),
+ "VT400", I(FUNKY_VT400),
+ "VT100+", I(FUNKY_VT100P),
+ "SCO", I(FUNKY_SCO),
+ "Xterm 216+", I(FUNKY_XTERM_216));
+ ctrl_radiobuttons(s, "Shift/Ctrl/Alt with the arrow keys", 'w', 2,
+ HELPCTX(keyboard_sharrow),
+ conf_radiobutton_handler,
+ I(CONF_sharrow_type),
+ "Ctrl toggles app mode", I(SHARROW_APPLICATION),
+ "xterm-style bitmap", I(SHARROW_BITMAP));
s = ctrl_getset(b, "Terminal/Keyboard", "appkeypad",
"Application keypad settings:");
@@ -1992,12 +2097,11 @@ void setup_config_box(struct controlbox *b, bool midsession,
HELPCTX(keyboard_appcursor),
conf_radiobutton_bool_handler,
I(CONF_app_cursor),
- "Normal", I(0), "Application", I(1), NULL);
+ "Normal", I(0), "Application", I(1));
ctrl_radiobuttons(s, "Initial state of numeric keypad:", 'n', 3,
HELPCTX(keyboard_appkeypad),
numeric_keypad_handler, P(NULL),
- "Normal", I(0), "Application", I(1), "NetHack", I(2),
- NULL);
+ "Normal", I(0), "Application", I(1), "NetHack", I(2));
/*
* The Terminal/Bell panel.
@@ -2011,7 +2115,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_radiobutton_handler, I(CONF_beep),
"None (bell disabled)", I(BELL_DISABLED),
"Make default system alert sound", I(BELL_DEFAULT),
- "Visual bell (flash window)", I(BELL_VISUAL), NULL);
+ "Visual bell (flash window)", I(BELL_VISUAL));
s = ctrl_getset(b, "Terminal/Bell", "overload",
"Control the bell overload behaviour");
@@ -2020,17 +2124,21 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_checkbox_handler, I(CONF_bellovl));
ctrl_editbox(s, "Over-use means this many bells...", 'm', 20,
HELPCTX(bell_overload),
- conf_editbox_handler, I(CONF_bellovl_n), I(-1));
+ conf_editbox_handler, I(CONF_bellovl_n), ED_INT);
+
+ static const struct conf_editbox_handler_type conf_editbox_tickspersec = {
+ .type = EDIT_FIXEDPOINT, .denominator = TICKSPERSEC};
+
ctrl_editbox(s, "... in this many seconds", 't', 20,
HELPCTX(bell_overload),
conf_editbox_handler, I(CONF_bellovl_t),
- I(-TICKSPERSEC));
+ CP(&conf_editbox_tickspersec));
ctrl_text(s, "The bell is re-enabled after a few seconds of silence.",
HELPCTX(bell_overload));
ctrl_editbox(s, "Seconds of silence required", 's', 20,
HELPCTX(bell_overload),
conf_editbox_handler, I(CONF_bellovl_s),
- I(-TICKSPERSEC));
+ CP(&conf_editbox_tickspersec));
/*
* The Terminal/Features panel.
@@ -2065,7 +2173,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
I(CONF_remote_qtitle_action),
"None", I(TITLE_NONE),
"Empty string", I(TITLE_EMPTY),
- "Window title", I(TITLE_REAL), NULL);
+ "Window title", I(TITLE_REAL));
ctrl_checkbox(s, "Disable remote-controlled clearing of scrollback", 'e',
HELPCTX(features_clearscroll),
conf_checkbox_handler,
@@ -2099,12 +2207,12 @@ void setup_config_box(struct controlbox *b, bool midsession,
ctrl_columns(s, 2, 50, 50);
c = ctrl_editbox(s, "Columns", 'm', 100,
HELPCTX(window_size),
- conf_editbox_handler, I(CONF_width), I(-1));
- c->generic.column = 0;
+ conf_editbox_handler, I(CONF_width), ED_INT);
+ c->column = 0;
c = ctrl_editbox(s, "Rows", 'r', 100,
HELPCTX(window_size),
- conf_editbox_handler, I(CONF_height),I(-1));
- c->generic.column = 1;
+ conf_editbox_handler, I(CONF_height),ED_INT);
+ c->column = 1;
ctrl_columns(s, 1, 100);
}
@@ -2112,7 +2220,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Control the scrollback in the window");
ctrl_editbox(s, "Lines of scrollback", 's', 50,
HELPCTX(window_scrollback),
- conf_editbox_handler, I(CONF_savelines), I(-1));
+ conf_editbox_handler, I(CONF_savelines), ED_INT);
ctrl_checkbox(s, "Display scrollbar", 'd',
HELPCTX(window_scrollback),
conf_checkbox_handler, I(CONF_scrollbar));
@@ -2142,7 +2250,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
I(CONF_cursor_type),
"Block", 'l', I(0),
"Underline", 'u', I(1),
- "Vertical line", 'v', I(2), NULL);
+ "Vertical line", 'v', I(2));
ctrl_checkbox(s, "Cursor blinks", 'b',
HELPCTX(appearance_cursor),
conf_checkbox_handler, I(CONF_blink_cur));
@@ -2164,7 +2272,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
ctrl_editbox(s, "Gap between text and window edge:", 'e', 20,
HELPCTX(appearance_border),
conf_editbox_handler,
- I(CONF_window_border), I(-1));
+ I(CONF_window_border), ED_INT);
/*
* The Window/Behaviour panel.
@@ -2177,7 +2285,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Adjust the behaviour of the window title");
ctrl_editbox(s, "Window title:", 't', 100,
HELPCTX(appearance_title),
- conf_editbox_handler, I(CONF_wintitle), I(1));
+ conf_editbox_handler, I(CONF_wintitle), ED_STR);
ctrl_checkbox(s, "Separate window and icon titles", 'i',
HELPCTX(appearance_title),
conf_checkbox_handler,
@@ -2208,13 +2316,12 @@ void setup_config_box(struct controlbox *b, bool midsession,
str = dupprintf("Adjust how %s handles line drawing characters", appname);
s = ctrl_getset(b, "Window/Translation", "linedraw", str);
sfree(str);
- ctrl_radiobuttons(s, "Handling of line drawing characters:", NO_SHORTCUT,1,
- HELPCTX(translation_linedraw),
- conf_radiobutton_handler,
- I(CONF_vtmode),
- "Use Unicode line drawing code points",'u',I(VT_UNICODE),
- "Poor man's line drawing (+, - and |)",'p',I(VT_POORMAN),
- NULL);
+ ctrl_radiobuttons(
+ s, "Handling of line drawing characters:", NO_SHORTCUT,1,
+ HELPCTX(translation_linedraw),
+ conf_radiobutton_handler, I(CONF_vtmode),
+ "Use Unicode line drawing code points",'u',I(VT_UNICODE),
+ "Poor man's line drawing (+, - and |)",'p',I(VT_POORMAN));
ctrl_checkbox(s, "Copy and paste line drawing characters as lqqqk",'d',
HELPCTX(selection_linedraw),
conf_checkbox_handler, I(CONF_rawcnp));
@@ -2239,7 +2346,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_radiobutton_bool_handler,
I(CONF_rect_select),
"Normal", 'n', I(false),
- "Rectangular block", 'r', I(true), NULL);
+ "Rectangular block", 'r', I(true));
s = ctrl_getset(b, "Window/Selection", "clipboards",
"Assign copy/paste actions to clipboards");
@@ -2287,11 +2394,11 @@ void setup_config_box(struct controlbox *b, bool midsession,
ccd->editbox = ctrl_editbox(s, "Set to class", 't', 50,
HELPCTX(copy_charclasses),
charclass_handler, P(ccd), P(NULL));
- ccd->editbox->generic.column = 0;
+ ccd->editbox->column = 0;
ccd->button = ctrl_pushbutton(s, "Set", 's',
HELPCTX(copy_charclasses),
charclass_handler, P(ccd));
- ccd->button->generic.column = 1;
+ ccd->button->column = 1;
ctrl_columns(s, 1, 100);
/*
@@ -2315,8 +2422,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_radiobutton_handler, I(CONF_bold_style),
"The font", I(1),
"The colour", I(2),
- "Both", I(3),
- NULL);
+ "Both", I(3));
str = dupprintf("Adjust the precise colours %s displays", appname);
s = ctrl_getset(b, "Window/Colours", "adjust", str);
@@ -2328,22 +2434,22 @@ void setup_config_box(struct controlbox *b, bool midsession,
cd = (struct colour_data *)ctrl_alloc(b, sizeof(struct colour_data));
cd->listbox = ctrl_listbox(s, "Select a colour to adjust:", 'u',
HELPCTX(colours_config), colour_handler, P(cd));
- cd->listbox->generic.column = 0;
+ cd->listbox->column = 0;
cd->listbox->listbox.height = 7;
c = ctrl_text(s, "RGB value:", HELPCTX(colours_config));
- c->generic.column = 1;
+ c->column = 1;
cd->redit = ctrl_editbox(s, "Red", 'r', 50, HELPCTX(colours_config),
colour_handler, P(cd), P(NULL));
- cd->redit->generic.column = 1;
+ cd->redit->column = 1;
cd->gedit = ctrl_editbox(s, "Green", 'n', 50, HELPCTX(colours_config),
colour_handler, P(cd), P(NULL));
- cd->gedit->generic.column = 1;
+ cd->gedit->column = 1;
cd->bedit = ctrl_editbox(s, "Blue", 'e', 50, HELPCTX(colours_config),
colour_handler, P(cd), P(NULL));
- cd->bedit->generic.column = 1;
+ cd->bedit->column = 1;
cd->button = ctrl_pushbutton(s, "Modify", 'm', HELPCTX(colours_config),
colour_handler, P(cd));
- cd->button->generic.column = 1;
+ cd->button->column = 1;
ctrl_columns(s, 1, 100);
/*
@@ -2358,8 +2464,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Sending of null packets to keep session active");
ctrl_editbox(s, "Seconds between keepalives (0 to turn off)", 'k', 20,
HELPCTX(connection_keepalive),
- conf_editbox_handler, I(CONF_ping_interval),
- I(-1));
+ conf_editbox_handler, I(CONF_ping_interval), ED_INT);
if (!midsession) {
s = ctrl_getset(b, "Connection", "tcp",
@@ -2374,15 +2479,14 @@ void setup_config_box(struct controlbox *b, bool midsession,
I(CONF_tcp_keepalives));
#ifndef NO_IPV6
s = ctrl_getset(b, "Connection", "ipversion",
- "Internet protocol version");
+ "Internet protocol version");
ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 3,
- HELPCTX(connection_ipversion),
- conf_radiobutton_handler,
- I(CONF_addressfamily),
- "Auto", 'u', I(ADDRTYPE_UNSPEC),
- "IPv4", '4', I(ADDRTYPE_IPV4),
- "IPv6", '6', I(ADDRTYPE_IPV6),
- NULL);
+ HELPCTX(connection_ipversion),
+ conf_radiobutton_handler,
+ I(CONF_addressfamily),
+ "Auto", 'u', I(ADDRTYPE_UNSPEC),
+ "IPv4", '4', I(ADDRTYPE_IPV4),
+ "IPv6", '6', I(ADDRTYPE_IPV6));
#endif
{
@@ -2393,7 +2497,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Logical name of remote host");
ctrl_editbox(s, label, 'm', 100,
HELPCTX(connection_loghost),
- conf_editbox_handler, I(CONF_loghost), I(1));
+ conf_editbox_handler, I(CONF_loghost), ED_STR);
}
}
@@ -2408,7 +2512,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Login details");
ctrl_editbox(s, "Auto-login username", 'u', 50,
HELPCTX(connection_username),
- conf_editbox_handler, I(CONF_username), I(1));
+ conf_editbox_handler, I(CONF_username), ED_STR);
{
/* We assume the local username is sufficiently stable
* to include on the dialog box. */
@@ -2421,8 +2525,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_radiobutton_bool_handler,
I(CONF_username_from_env),
"Prompt", I(false),
- userlabel, I(true),
- NULL);
+ userlabel, I(true));
sfree(userlabel);
}
@@ -2430,10 +2533,10 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Terminal details");
ctrl_editbox(s, "Terminal-type string", 't', 50,
HELPCTX(connection_termtype),
- conf_editbox_handler, I(CONF_termtype), I(1));
+ conf_editbox_handler, I(CONF_termtype), ED_STR);
ctrl_editbox(s, "Terminal speeds", 's', 50,
HELPCTX(connection_termspeed),
- conf_editbox_handler, I(CONF_termspeed), I(1));
+ conf_editbox_handler, I(CONF_termspeed), ED_STR);
s = ctrl_getset(b, "Connection/Data", "env",
"Environment variables");
@@ -2443,19 +2546,19 @@ void setup_config_box(struct controlbox *b, bool midsession,
ed->varbox = ctrl_editbox(s, "Variable", 'v', 60,
HELPCTX(telnet_environ),
environ_handler, P(ed), P(NULL));
- ed->varbox->generic.column = 0;
+ ed->varbox->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->valbox->column = 0;
ed->addbutton = ctrl_pushbutton(s, "Add", 'd',
HELPCTX(telnet_environ),
environ_handler, P(ed));
- ed->addbutton->generic.column = 1;
+ ed->addbutton->column = 1;
ed->rembutton = ctrl_pushbutton(s, "Remove", 'r',
HELPCTX(telnet_environ),
environ_handler, P(ed));
- ed->rembutton->generic.column = 1;
+ ed->rembutton->column = 1;
ctrl_columns(s, 1, 100);
ed->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(telnet_environ),
@@ -2477,33 +2580,25 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Options controlling proxy usage");
s = ctrl_getset(b, "Connection/Proxy", "basics", NULL);
- ctrl_radiobuttons(s, "Proxy type:", 't', 3,
- HELPCTX(proxy_type),
- conf_radiobutton_handler,
- I(CONF_proxy_type),
- "None", I(PROXY_NONE),
- "SOCKS 4", I(PROXY_SOCKS4),
- "SOCKS 5", I(PROXY_SOCKS5),
- "HTTP", I(PROXY_HTTP),
- "Telnet", I(PROXY_TELNET),
- NULL);
+ c = ctrl_droplist(s, "Proxy type:", 't', 70,
+ HELPCTX(proxy_type), proxy_type_handler, I(0));
ctrl_columns(s, 2, 80, 20);
c = ctrl_editbox(s, "Proxy hostname", 'y', 100,
HELPCTX(proxy_main),
conf_editbox_handler,
- I(CONF_proxy_host), I(1));
- c->generic.column = 0;
+ I(CONF_proxy_host), ED_STR);
+ c->column = 0;
c = ctrl_editbox(s, "Port", 'p', 100,
HELPCTX(proxy_main),
conf_editbox_handler,
I(CONF_proxy_port),
- I(-1));
- c->generic.column = 1;
+ ED_INT);
+ c->column = 1;
ctrl_columns(s, 1, 100);
ctrl_editbox(s, "Exclude Hosts/IPs", 'e', 100,
HELPCTX(proxy_exclude),
conf_editbox_handler,
- I(CONF_proxy_exclude_list), I(1));
+ I(CONF_proxy_exclude_list), ED_STR);
ctrl_checkbox(s, "Consider proxying local host connections", 'x',
HELPCTX(proxy_exclude),
conf_checkbox_handler,
@@ -2514,20 +2609,20 @@ void setup_config_box(struct controlbox *b, bool midsession,
I(CONF_proxy_dns),
"No", I(FORCE_OFF),
"Auto", I(AUTO),
- "Yes", I(FORCE_ON), NULL);
+ "Yes", I(FORCE_ON));
ctrl_editbox(s, "Username", 'u', 60,
HELPCTX(proxy_auth),
conf_editbox_handler,
- I(CONF_proxy_username), I(1));
+ I(CONF_proxy_username), ED_STR);
c = ctrl_editbox(s, "Password", 'w', 60,
HELPCTX(proxy_auth),
conf_editbox_handler,
- I(CONF_proxy_password), I(1));
+ I(CONF_proxy_password), ED_STR);
c->editbox.password = true;
- ctrl_editbox(s, "Telnet command", 'm', 100,
+ ctrl_editbox(s, "Command to send to proxy (for some types)", 'm', 100,
HELPCTX(proxy_command),
conf_editbox_handler,
- I(CONF_proxy_telnet_command), I(1));
+ I(CONF_proxy_telnet_command), ED_STR);
ctrl_radiobuttons(s, "Print proxy diagnostics "
"in the terminal window", 'r', 5,
@@ -2536,7 +2631,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
I(CONF_proxy_log_to_term),
"No", I(FORCE_OFF),
"Yes", I(FORCE_ON),
- "Only until session starts", I(AUTO), NULL);
+ "Only until session starts", I(AUTO));
}
/*
@@ -2577,7 +2672,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Data to send to the server");
ctrl_editbox(s, "Remote command:", 'r', 100,
HELPCTX(ssh_command),
- conf_editbox_handler, I(CONF_remote_cmd), I(1));
+ conf_editbox_handler, I(CONF_remote_cmd), ED_STR);
s = ctrl_getset(b, "Connection/SSH", "protocol", "Protocol options");
ctrl_checkbox(s, "Don't start a shell or command at all", 'n',
@@ -2623,7 +2718,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_radiobutton_handler,
I(CONF_sshprot),
"2", '2', I(3),
- "1 (INSECURE)", '1', I(0), NULL);
+ "1 (INSECURE)", '1', I(0));
}
/*
@@ -2656,19 +2751,19 @@ void setup_config_box(struct controlbox *b, bool midsession,
HELPCTX(ssh_kex_repeat),
conf_editbox_handler,
I(CONF_ssh_rekey_time),
- I(-1));
+ ED_INT);
#ifndef NO_GSSAPI
ctrl_editbox(s, "Minutes between GSS checks (0 for never)", NO_SHORTCUT, 20,
HELPCTX(ssh_kex_repeat),
conf_editbox_handler,
I(CONF_gssapirekey),
- I(-1));
+ ED_INT);
#endif
ctrl_editbox(s, "Max data before rekey (0 for no limit)", 'x', 20,
HELPCTX(ssh_kex_repeat),
conf_editbox_handler,
I(CONF_ssh_rekey_data),
- I(16));
+ ED_STR);
ctrl_text(s, "(Use 1M for 1 megabyte, 1G for 1 gigabyte etc)",
HELPCTX(ssh_kex_repeat));
}
@@ -2704,7 +2799,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
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;
+ c->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 *)
@@ -2712,8 +2807,8 @@ void setup_config_box(struct controlbox *b, bool midsession,
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 = true;
+ mh->rembutton->column = 1;
+ mh->rembutton->delay_taborder = true;
mh->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(ssh_kex_manual_hostkeys),
manual_hostkey_handler, P(mh));
@@ -2727,14 +2822,25 @@ void setup_config_box(struct controlbox *b, bool midsession,
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->keybox->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;
+ mh->addbutton->column = 1;
ctrl_columns(s, 1, 100);
}
+ /*
+ * But there's no reason not to forbid access to the host CA
+ * configuration box, which is common across sessions in any
+ * case.
+ */
+ s = ctrl_getset(b, "Connection/SSH/Host keys", "ca",
+ "Configure trusted certification authorities");
+ c = ctrl_pushbutton(s, "Configure host CAs", NO_SHORTCUT,
+ HELPCTX(ssh_kex_cert),
+ host_ca_button_handler, I(0));
+
if (!midsession || !(protcfginfo == 1 || protcfginfo == -1)) {
/*
* The Connection/SSH/Cipher panel.
@@ -2792,8 +2898,8 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_checkbox_handler,
I(CONF_try_ki_auth));
- s = ctrl_getset(b, "Connection/SSH/Auth", "params",
- "Authentication parameters");
+ s = ctrl_getset(b, "Connection/SSH/Auth", "aux",
+ "Other authentication-related options");
ctrl_checkbox(s, "Allow agent forwarding", 'f',
HELPCTX(ssh_auth_agentfwd),
conf_checkbox_handler, I(CONF_agentfwd));
@@ -2801,11 +2907,26 @@ void setup_config_box(struct controlbox *b, bool midsession,
HELPCTX(ssh_auth_changeuser),
conf_checkbox_handler,
I(CONF_change_username));
+
+ ctrl_settitle(b, "Connection/SSH/Auth/Credentials",
+ "Credentials to authenticate with");
+
+ s = ctrl_getset(b, "Connection/SSH/Auth/Credentials", "publickey",
+ "Public-key authentication");
ctrl_filesel(s, "Private key file for authentication:", 'k',
FILTER_KEY_FILES, false, "Select private key file",
HELPCTX(ssh_auth_privkey),
conf_filesel_handler, I(CONF_keyfile));
-
+ ctrl_filesel(s, "Certificate to use with the private key:", 'e',
+ NULL, false, "Select certificate file",
+ HELPCTX(ssh_auth_cert),
+ conf_filesel_handler, I(CONF_detached_cert));
+
+ s = ctrl_getset(b, "Connection/SSH/Auth/Credentials", "plugin",
+ "Plugin to provide authentication responses");
+ ctrl_editbox(s, "Plugin command to run", NO_SHORTCUT, 100,
+ HELPCTX(ssh_auth_plugin),
+ conf_editbox_handler, I(CONF_auth_plugin), ED_STR);
#ifndef NO_GSSAPI
/*
* Connection/SSH/Auth/GSSAPI, which sadly won't fit on
@@ -2894,12 +3015,12 @@ void setup_config_box(struct controlbox *b, bool midsession,
td->listbox->listbox.percentages[1] = 60;
ctrl_columns(s, 2, 75, 25);
c = ctrl_text(s, "For selected mode, send:", HELPCTX(ssh_ttymodes));
- c->generic.column = 0;
+ c->column = 0;
td->setbutton = ctrl_pushbutton(s, "Set", 's',
HELPCTX(ssh_ttymodes),
ttymodes_handler, P(td));
- td->setbutton->generic.column = 1;
- td->setbutton->generic.tabdelay = true;
+ td->setbutton->column = 1;
+ td->setbutton->delay_taborder = true;
ctrl_columns(s, 1, 100); /* column break */
/* Bit of a hack to get the value radio buttons and
* edit-box on the same row. */
@@ -2909,14 +3030,13 @@ void setup_config_box(struct controlbox *b, bool midsession,
ttymodes_handler, P(td),
"Auto", NO_SHORTCUT, P(NULL),
"Nothing", NO_SHORTCUT, P(NULL),
- "This:", NO_SHORTCUT, P(NULL),
- NULL);
- td->valradio->generic.column = 0;
+ "This:", NO_SHORTCUT, P(NULL));
+ td->valradio->column = 0;
td->valbox = ctrl_editbox(s, NULL, NO_SHORTCUT, 100,
HELPCTX(ssh_ttymodes),
ttymodes_handler, P(td), P(NULL));
- td->valbox->generic.column = 1;
- td->valbox->generic.align_next_to = td->valradio;
+ td->valbox->column = 1;
+ td->valbox->align_next_to = td->valradio;
ctrl_tabdelay(s, td->setbutton);
}
@@ -2933,13 +3053,13 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_checkbox_handler,I(CONF_x11_forward));
ctrl_editbox(s, "X display location", 'x', 50,
HELPCTX(ssh_tunnels_x11),
- conf_editbox_handler, I(CONF_x11_display), I(1));
+ conf_editbox_handler, I(CONF_x11_display), ED_STR);
ctrl_radiobuttons(s, "Remote X11 authentication protocol", 'u', 2,
HELPCTX(ssh_tunnels_x11auth),
conf_radiobutton_handler,
I(CONF_x11_auth),
"MIT-Magic-Cookie-1", I(X11_MIT),
- "XDM-Authorization-1", I(X11_XDM), NULL);
+ "XDM-Authorization-1", I(X11_XDM));
}
/*
@@ -2961,15 +3081,15 @@ void setup_config_box(struct controlbox *b, bool midsession,
ctrl_columns(s, 3, 55, 20, 25);
c = ctrl_text(s, "Forwarded ports:", HELPCTX(ssh_tunnels_portfwd));
- c->generic.column = COLUMN_FIELD(0,2);
+ c->column = COLUMN_FIELD(0,2);
/* You want to select from the list, _then_ hit Remove. So tab order
* should be that way round. */
pfd = (struct portfwd_data *)ctrl_alloc(b,sizeof(struct portfwd_data));
pfd->rembutton = ctrl_pushbutton(s, "Remove", 'r',
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd));
- pfd->rembutton->generic.column = 2;
- pfd->rembutton->generic.tabdelay = true;
+ pfd->rembutton->column = 2;
+ pfd->rembutton->delay_taborder = true;
pfd->listbox = ctrl_listbox(s, NULL, NO_SHORTCUT,
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd));
@@ -2985,12 +3105,12 @@ void setup_config_box(struct controlbox *b, bool midsession,
pfd->addbutton = ctrl_pushbutton(s, "Add", 'd',
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd));
- pfd->addbutton->generic.column = 2;
- pfd->addbutton->generic.tabdelay = true;
+ pfd->addbutton->column = 2;
+ pfd->addbutton->delay_taborder = true;
pfd->sourcebox = ctrl_editbox(s, "Source port", 's', 40,
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd), P(NULL));
- pfd->sourcebox->generic.column = 0;
+ pfd->sourcebox->column = 0;
pfd->destbox = ctrl_editbox(s, "Destination", 'i', 67,
HELPCTX(ssh_tunnels_portfwd),
portfwd_handler, P(pfd), P(NULL));
@@ -2999,8 +3119,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
portfwd_handler, P(pfd),
"Local", 'l', P(NULL),
"Remote", 'm', P(NULL),
- "Dynamic", 'y', P(NULL),
- NULL);
+ "Dynamic", 'y', P(NULL));
#ifndef NO_IPV6
pfd->addressfamily =
ctrl_radiobuttons(s, NULL, NO_SHORTCUT, 3,
@@ -3008,8 +3127,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
portfwd_handler, P(pfd),
"Auto", 'u', I(ADDRTYPE_UNSPEC),
"IPv4", '4', I(ADDRTYPE_IPV4),
- "IPv6", '6', I(ADDRTYPE_IPV6),
- NULL);
+ "IPv6", '6', I(ADDRTYPE_IPV6));
#endif
ctrl_tabdelay(s, pfd->addbutton);
ctrl_columns(s, 1, 100);
@@ -3039,6 +3157,17 @@ void setup_config_box(struct controlbox *b, bool midsession,
HELPCTX(ssh_bugs_maxpkt2),
sshbug_handler, I(CONF_sshbug_maxpkt2));
+ s = ctrl_getset(b, "Connection/SSH/Bugs", "manual",
+ "Manually enabled workarounds");
+ ctrl_droplist(s, "Discards data sent before its greeting", 'd', 20,
+ HELPCTX(ssh_bugs_dropstart),
+ sshbug_handler_manual_only,
+ I(CONF_sshbug_dropstart));
+ ctrl_droplist(s, "Chokes on PuTTY's full KEXINIT", 'p', 20,
+ HELPCTX(ssh_bugs_filter_kexinit),
+ sshbug_handler_manual_only,
+ I(CONF_sshbug_filter_kexinit));
+
ctrl_settitle(b, "Connection/SSH/More bugs",
"Further workarounds for SSH server bugs");
@@ -3090,22 +3219,26 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Select a serial line");
ctrl_editbox(s, "Serial line to connect to", 'l', 40,
HELPCTX(serial_line),
- conf_editbox_handler, I(CONF_serline), I(1));
+ conf_editbox_handler, I(CONF_serline), ED_STR);
}
s = ctrl_getset(b, "Connection/Serial", "sercfg", "Configure the serial line");
ctrl_editbox(s, "Speed (baud)", 's', 40,
HELPCTX(serial_speed),
- conf_editbox_handler, I(CONF_serspeed), I(-1));
+ conf_editbox_handler, I(CONF_serspeed), ED_INT);
ctrl_editbox(s, "Data bits", 'b', 40,
HELPCTX(serial_databits),
- conf_editbox_handler, I(CONF_serdatabits), I(-1));
+ conf_editbox_handler, I(CONF_serdatabits), ED_INT);
/*
* Stop bits come in units of one half.
*/
+ static const struct conf_editbox_handler_type conf_editbox_stopbits = {
+ .type = EDIT_FIXEDPOINT, .denominator = 2};
+
ctrl_editbox(s, "Stop bits", 't', 40,
HELPCTX(serial_stopbits),
- conf_editbox_handler, I(CONF_serstopbits), I(-2));
+ conf_editbox_handler, I(CONF_serstopbits),
+ CP(&conf_editbox_stopbits));
ctrl_droplist(s, "Parity", 'p', 40,
HELPCTX(serial_parity), serial_parity_handler,
I(ser_vt->serial_parity_mask));
@@ -3131,12 +3264,12 @@ void setup_config_box(struct controlbox *b, bool midsession,
conf_radiobutton_bool_handler,
I(CONF_rfc_environ),
"BSD (commonplace)", 'b', I(false),
- "RFC 1408 (unusual)", 'f', I(true), NULL);
+ "RFC 1408 (unusual)", 'f', I(true));
ctrl_radiobuttons(s, "Telnet negotiation mode:", 't', 2,
HELPCTX(telnet_passive),
conf_radiobutton_bool_handler,
I(CONF_passive_telnet),
- "Passive", I(true), "Active", I(false), NULL);
+ "Passive", I(true), "Active", I(false));
}
ctrl_checkbox(s, "Keyboard sends Telnet special commands", 'k',
HELPCTX(telnet_specialkeys),
@@ -3159,7 +3292,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
"Data to send to the server");
ctrl_editbox(s, "Local username:", 'l', 50,
HELPCTX(rlogin_localuser),
- conf_editbox_handler, I(CONF_localusername), I(1));
+ conf_editbox_handler, I(CONF_localusername), ED_STR);
}
@@ -3175,7 +3308,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
ctrl_editbox(s, "Location string", 'l', 70,
HELPCTX(supdup_location),
conf_editbox_handler, I(CONF_supdup_location),
- I(1));
+ ED_STR);
ctrl_radiobuttons(s, "Extended ASCII Character set:", 'e', 4,
HELPCTX(supdup_ascii),
@@ -3183,7 +3316,7 @@ void setup_config_box(struct controlbox *b, bool midsession,
I(CONF_supdup_ascii_set),
"None", I(SUPDUP_CHARSET_ASCII),
"ITS", I(SUPDUP_CHARSET_ITS),
- "WAITS", I(SUPDUP_CHARSET_WAITS), NULL);
+ "WAITS", I(SUPDUP_CHARSET_WAITS));
ctrl_checkbox(s, "**MORE** processing", 'm',
HELPCTX(supdup_more),