From: Daniel Lenski Date: Tue, 9 Jan 2018 08:01:17 +0000 (-0800) Subject: Clean up dodgy query-string building in gpst.c X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=625165cf0b1669ed2135bdd010f7dbe973d6f815;p=users%2Fdwmw2%2Fopenconnect.git Clean up dodgy query-string building in gpst.c This function helps a lot: static int filter_opts(struct oc_text_buf *buf, const char *query, const char *incexc, int include) It takes a URL query string and a comma-separated list of fields to include or exclude, and copies fields into the buffer, e.g. /* include=1: copy only the named fields into the buffer */ filter_opts(buf, vpninfo->cookie, "user,authcookie", 1); /* include=0: copy all fields except the named ones into the buffer */ filter_opts(buf, vpninfo->cookie, "authcookie,junk", 0); Signed-off-by: Daniel Lenski Signed-off-by: David Woodhouse --- diff --git a/gpst.c b/gpst.c index ba1131c6..f4ddbfaa 100644 --- a/gpst.c +++ b/gpst.c @@ -107,6 +107,32 @@ static const char *add_option(struct openconnect_info *vpninfo, const char *opt, return new->value; } +static int filter_opts(struct oc_text_buf *buf, const char *query, const char *incexc, int include) +{ + const char *f, *endf, *eq; + const char *found, *comma; + + for (f = query; *f; f=(*endf) ? endf+1 : endf) { + endf = strchr(f, '&') ? : f+strlen(f); + eq = strchr(f, '='); + if (!eq || eq > endf) + eq = endf; + + for (found = incexc; *found; found=(*comma) ? comma+1 : comma) { + comma = strchr(found, ',') ? : found+strlen(found); + if (!strncmp(found, f, MAX(comma-found, eq-f))) + break; + } + + if ((include && *found) || (!include && !*found)) { + if (buf->pos && buf->data[buf->pos-1] != '?' && buf->data[buf->pos-1] != '&') + buf_append(buf, "&"); + buf_append_bytes(buf, f, (int)(endf-f)); + } + } + return buf_error(buf); +} + /* Parse this JavaScript-y mess: "var respStatus = \"Challenge|Error\";\n" @@ -511,9 +537,11 @@ static int gpst_get_config(struct openconnect_info *vpninfo) append_opt(request_body, "clientos", vpninfo->platname); append_opt(request_body, "hmac-algo", "sha1,md5"); append_opt(request_body, "enc-algo", "aes-128-cbc,aes-256-cbc"); - if (old_addr) + if (old_addr) { append_opt(request_body, "preferred-ip", old_addr); - buf_append(request_body, "&%s", vpninfo->cookie); + filter_opts(request_body, vpninfo->cookie, "preferred-ip", 0); + } else + buf_append(request_body, "&%s", vpninfo->cookie); orig_path = vpninfo->urlpath; vpninfo->urlpath = strdup("ssl-vpn/getconfig.esp"); @@ -584,7 +612,9 @@ static int gpst_connect(struct openconnect_info *vpninfo) return ret; reqbuf = buf_alloc(); - buf_append(reqbuf, "GET /ssl-tunnel-connect.sslvpn?%s HTTP/1.1\r\n\r\n", vpninfo->cookie); + buf_append(reqbuf, "GET /ssl-tunnel-connect.sslvpn?"); + filter_opts(reqbuf, vpninfo->cookie, "user,authcookie", 1); + buf_append(reqbuf, " HTTP/1.1\r\n\r\n"); if (vpninfo->dump_http_traffic) dump_buf(vpninfo, '>', reqbuf->data);