From 597cbddbb9248ece77032bc80bf3e828064416fd Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Thu, 22 Aug 2013 17:45:26 +0000 Subject: [PATCH] Fix handling of IPv6 dynamic forwardings. During the Conf revamp, I changed the internal representation of dynamic forwardings so that they were stored as the conceptually sensible L12345=D rather than the old D12345, and added compensation code to translate to the latter form for backwards-compatible data storage and for OpenSSH-harmonised GUI display. Unfortunately I forgot that keys in the forwarding data can also prefix the L/R with a character indicating IPv4/IPv6, and my translations didn't take account of that possibility. Fix them. [originally from svn r10031] --- config.c | 20 +++++++++++++++++--- settings.c | 13 +++++++++---- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/config.c b/config.c index 02da07da..9f32bc30 100644 --- a/config.c +++ b/config.c @@ -1083,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); diff --git a/settings.c b/settings.c index df24f53d..2aae3f1d 100644 --- a/settings.c +++ b/settings.c @@ -178,7 +178,7 @@ static int gppmap(void *handle, char *name, Conf *conf, int primary) val = q; *q = '\0'; - if (primary == CONF_portfwd && buf[0] == 'D') { + if (primary == CONF_portfwd && strchr(buf, 'D') != NULL) { /* * Backwards-compatibility hack: dynamic forwardings are * indexed in the data store as a third type letter in the @@ -188,9 +188,10 @@ static int gppmap(void *handle, char *name, Conf *conf, int primary) * _listening_ on a local port, and are hence mutually * exclusive on the same port number. So here we translate * the legacy storage format into the sensible internal - * form. + * form, by finding the D and turning it into a L. */ - char *newkey = dupcat("L", buf+1, NULL); + char *newkey = dupstr(buf); + *strchr(newkey, 'D') = 'L'; conf_set_str_str(conf, primary, newkey, "D"); sfree(newkey); } else { @@ -232,9 +233,13 @@ static void wmap(void *handle, char const *outkey, Conf *conf, int primary) * conceptually incoherent legacy storage format (key * "D", value empty). */ + char *L; + realkey = key; /* restore it at end of loop */ val = ""; - key = dupcat("D", key+1, NULL); + key = dupstr(key); + L = strchr(key, 'L'); + if (L) *L = 'D'; } else { realkey = NULL; } -- 2.45.2