X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=config.c;h=2960cab37a5bfebc2e13abbc9a594e61f56b7b36;hb=HEAD;hp=b0b0092c77f452972ec911f17fe109155da5859f;hpb=1ec1e33e8a1ee99181059c4929e0cbd254412211;p=PuTTY_svn.git diff --git a/config.c b/config.c index b0b0092c..2960cab3 100644 --- a/config.c +++ b/config.c @@ -557,22 +557,27 @@ static void sshbug_handler(union control *ctrl, void *dlg, } } -#define SAVEDSESSION_LEN 2048 - struct sessionsaver_data { union control *editbox, *listbox, *loadbutton, *savebutton, *delbutton; union control *okbutton, *cancelbutton; struct sesslist sesslist; int midsession; + char *savedsession; /* the current contents of ssd->editbox */ }; +static void sessionsaver_data_free(void *ssdv) +{ + struct sessionsaver_data *ssd = (struct sessionsaver_data *)ssdv; + sfree(ssd->savedsession); + sfree(ssd); +} + /* * Helper function to load the session selected in the list box, if * any, as this is done in more than one place below. Returns 0 for * failure. */ static int load_selected_session(struct sessionsaver_data *ssd, - char *savedsession, void *dlg, Conf *conf, int *maybe_launch) { int i = dlg_listbox_index(ssd->listbox, dlg); @@ -583,17 +588,10 @@ static int load_selected_session(struct sessionsaver_data *ssd, } isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings"); load_settings(ssd->sesslist.sessions[i], conf); - if (!isdef) { - strncpy(savedsession, ssd->sesslist.sessions[i], - SAVEDSESSION_LEN); - savedsession[SAVEDSESSION_LEN-1] = '\0'; - if (maybe_launch) - *maybe_launch = TRUE; - } else { - savedsession[0] = '\0'; - if (maybe_launch) - *maybe_launch = FALSE; - } + sfree(ssd->savedsession); + ssd->savedsession = dupstr(isdef ? "" : ssd->sesslist.sessions[i]); + if (maybe_launch) + *maybe_launch = !isdef; dlg_refresh(NULL, dlg); /* Restore the selection, which might have been clobbered by * changing the value of the edit box. */ @@ -607,33 +605,10 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, Conf *conf = (Conf *)data; struct sessionsaver_data *ssd = (struct sessionsaver_data *)ctrl->generic.context.p; - char *savedsession; - - /* - * The first time we're called in a new dialog, we must - * allocate space to store the current contents of the saved - * session edit box (since it must persist even when we switch - * panels, but is not part of the Conf). - * - * FIXME: this is disgusting, and we'd do much better to have - * the persistent storage be dynamically allocated and get rid - * of the arbitrary limit SAVEDSESSION_LEN. To do that would - * require a means of making sure the memory gets freed at the - * appropriate moment. - */ - if (!ssd->editbox) { - savedsession = NULL; - } else if (!dlg_get_privdata(ssd->editbox, dlg)) { - savedsession = (char *) - dlg_alloc_privdata(ssd->editbox, dlg, SAVEDSESSION_LEN); - savedsession[0] = '\0'; - } else { - savedsession = dlg_get_privdata(ssd->editbox, dlg); - } if (event == EVENT_REFRESH) { if (ctrl == ssd->editbox) { - dlg_editbox_set(ctrl, dlg, savedsession); + dlg_editbox_set(ctrl, dlg, ssd->savedsession); } else if (ctrl == ssd->listbox) { int i; dlg_update_start(ctrl, dlg); @@ -645,14 +620,13 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, } else if (event == EVENT_VALCHANGE) { int top, bottom, halfway, i; if (ctrl == ssd->editbox) { - char *tmp = dlg_editbox_get(ctrl, dlg); - strncpy(savedsession, tmp, SAVEDSESSION_LEN); - sfree(tmp); + sfree(ssd->savedsession); + ssd->savedsession = dlg_editbox_get(ctrl, dlg); top = ssd->sesslist.nsessions; bottom = -1; while (top-bottom > 1) { halfway = (top+bottom)/2; - i = strcmp(savedsession, ssd->sesslist.sessions[halfway]); + i = strcmp(ssd->savedsession, ssd->sesslist.sessions[halfway]); if (i <= 0 ) { top = halfway; } else { @@ -676,29 +650,25 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, * double-click on the list box _and_ that session * contains a hostname. */ - if (load_selected_session(ssd, savedsession, dlg, conf, &mbl) && + if (load_selected_session(ssd, dlg, conf, &mbl) && (mbl && ctrl == ssd->listbox && conf_launchable(conf))) { dlg_end(dlg, 1); /* it's all over, and succeeded */ } } else if (ctrl == ssd->savebutton) { - int isdef = !strcmp(savedsession, "Default Settings"); - if (!savedsession[0]) { + int isdef = !strcmp(ssd->savedsession, "Default Settings"); + if (!ssd->savedsession[0]) { int i = dlg_listbox_index(ssd->listbox, dlg); if (i < 0) { dlg_beep(dlg); return; } isdef = !strcmp(ssd->sesslist.sessions[i], "Default Settings"); - if (!isdef) { - strncpy(savedsession, ssd->sesslist.sessions[i], - SAVEDSESSION_LEN); - savedsession[SAVEDSESSION_LEN-1] = '\0'; - } else { - savedsession[0] = '\0'; - } + sfree(ssd->savedsession); + ssd->savedsession = dupstr(isdef ? "" : + ssd->sesslist.sessions[i]); } { - char *errmsg = save_settings(savedsession, conf); + char *errmsg = save_settings(ssd->savedsession, conf); if (errmsg) { dlg_error_msg(dlg, errmsg); sfree(errmsg); @@ -736,8 +706,7 @@ static void sessionsaver_handler(union control *ctrl, void *dlg, !conf_launchable(conf)) { Conf *conf2 = conf_new(); int mbl = FALSE; - if (!load_selected_session(ssd, savedsession, dlg, - conf2, &mbl)) { + if (!load_selected_session(ssd, dlg, conf2, &mbl)) { dlg_beep(dlg); conf_free(conf2); return; @@ -1114,9 +1083,23 @@ static void portfwd_handler(union control *ctrl, void *dlg, val != NULL; val = conf_get_str_strs(conf, CONF_portfwd, key, &key)) { char *p; - if (!strcmp(val, "D")) - p = dupprintf("D%s\t", key+1); - else + if (!strcmp(val, "D")) { + char *L; + /* + * A dynamic forwarding is stored as L12345=D or + * 6L12345=D (since it's mutually exclusive with + * L12345=anything else), but displayed as D12345 + * to match the fiction that 'Local', 'Remote' and + * 'Dynamic' are three distinct modes and also to + * align with OpenSSH's command line option syntax + * that people will already be used to. So, for + * display purposes, find the L in the key string + * and turn it into a D. + */ + p = dupprintf("%s\t", key); + L = strchr(p, 'L'); + if (L) *L = 'D'; + } else p = dupprintf("%s\t%s", key, val); dlg_listbox_add(ctrl, dlg, p); sfree(p); @@ -1144,8 +1127,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) @@ -1163,7 +1146,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\""); @@ -1256,8 +1239,10 @@ void setup_config_box(struct controlbox *b, int midsession, char *str; ssd = (struct sessionsaver_data *) - ctrl_alloc(b, sizeof(struct sessionsaver_data)); + ctrl_alloc_with_free(b, sizeof(struct sessionsaver_data), + sessionsaver_data_free); memset(ssd, 0, sizeof(*ssd)); + ssd->savedsession = dupstr(""); ssd->midsession = midsession; /* @@ -1376,13 +1361,13 @@ void setup_config_box(struct controlbox *b, int midsession, ctrl_columns(s, 1, 100); s = ctrl_getset(b, "Session", "otheropts", NULL); - c = ctrl_radiobuttons(s, "Close window on exit:", 'x', 4, - HELPCTX(session_coe), - conf_radiobutton_handler, - I(CONF_close_on_exit), - "Always", I(FORCE_ON), - "Never", I(FORCE_OFF), - "Only on clean exit", I(AUTO), NULL); + ctrl_radiobuttons(s, "Close window on exit:", 'x', 4, + HELPCTX(session_coe), + conf_radiobutton_handler, + I(CONF_close_on_exit), + "Always", I(FORCE_ON), + "Never", I(FORCE_OFF), + "Only on clean exit", I(AUTO), NULL); /* * The Session/Logging panel. @@ -2114,6 +2099,26 @@ void setup_config_box(struct controlbox *b, int midsession, I(CONF_compression)); } + if (!midsession || protcfginfo != 1) { + 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"); @@ -2127,19 +2132,6 @@ void setup_config_box(struct controlbox *b, int midsession, "2 only", 'y', I(3), NULL); } - if (!midsession || protcfginfo != 1) { - s = ctrl_getset(b, "Connection/SSH", "encryption", "Encryption options"); - c = ctrl_draglist(s, "Encryption cipher selection policy:", 's', - HELPCTX(ssh_ciphers), - cipherlist_handler, P(NULL)); - c->listbox.height = 6; - - ctrl_checkbox(s, "Enable legacy use of single-DES in SSH-2", 'i', - HELPCTX(ssh_ciphers), - conf_checkbox_handler, - I(CONF_ssh2_des_cbc)); - } - /* * The Connection/SSH/Kex panel. (Owing to repeat key * exchange, this is all meaningful in mid-session _if_ @@ -2173,6 +2165,26 @@ void setup_config_box(struct controlbox *b, int midsession, HELPCTX(ssh_kex_repeat)); } + if (!midsession || protcfginfo != 1) { + /* + * The Connection/SSH/Cipher panel. + */ + ctrl_settitle(b, "Connection/SSH/Cipher", + "Options controlling SSH encryption"); + + s = ctrl_getset(b, "Connection/SSH/Cipher", + "encryption", "Encryption options"); + c = ctrl_draglist(s, "Encryption cipher selection policy:", 's', + HELPCTX(ssh_ciphers), + cipherlist_handler, P(NULL)); + c->listbox.height = 6; + + ctrl_checkbox(s, "Enable legacy use of single-DES in SSH-2", 'i', + HELPCTX(ssh_ciphers), + conf_checkbox_handler, + I(CONF_ssh2_des_cbc)); + } + if (!midsession) { /*