]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Clean up dodgy query-string building in gpst.c
authorDaniel Lenski <dlenski@gmail.com>
Tue, 9 Jan 2018 08:01:17 +0000 (00:01 -0800)
committerDavid Woodhouse <dwmw2@infradead.org>
Tue, 27 Feb 2018 15:28:32 +0000 (16:28 +0100)
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 <dlenski@gmail.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
gpst.c

diff --git a/gpst.c b/gpst.c
index ba1131c675adc3af546390f272052c2fb2feef14..f4ddbfaabcaa8ba6f1a7fe9c5dab8d896a5f7708 100644 (file)
--- 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);