]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Use do_https_request()
authorDavid Woodhouse <dwmw2@infradead.org>
Wed, 13 May 2020 15:44:54 +0000 (16:44 +0100)
committerDavid Woodhouse <dwmw2@infradead.org>
Wed, 13 May 2020 16:01:28 +0000 (17:01 +0100)
That's a lot simpler than open-coding it.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
f5.c
fortinet.c

diff --git a/f5.c b/f5.c
index a4dd348f99648f44717892f305eca8764939a90f..29a3b6edc28b4583bf4bd6a9314f0335fa1d79dc 100644 (file)
--- a/f5.c
+++ b/f5.c
@@ -55,7 +55,7 @@ int f5_obtain_cookie(struct openconnect_info *vpninfo)
  * Extract the content of the "params" node which is needed for the
  * next request.
  */
-static int parse_profile(struct openconnect_info *vpninfo, struct oc_text_buf *buf,
+static int parse_profile(struct openconnect_info *vpninfo, char *buf, int len,
                         char **params)
 {
        xmlDocPtr xml_doc;
@@ -63,16 +63,16 @@ static int parse_profile(struct openconnect_info *vpninfo, struct oc_text_buf *b
        char *type = NULL;
        int ret;
 
-       if (buf_error(buf))
-               return buf_error(buf);
+       if (!buf || !len)
+               return -EINVAL;
 
-       xml_doc = xmlReadMemory(buf->data, buf->pos, "noname.xml", NULL,
+       xml_doc = xmlReadMemory(buf, len, "noname.xml", NULL,
                                XML_PARSE_NOERROR|XML_PARSE_RECOVER);
        if (!xml_doc) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to parse F5 profile response\n"));
                vpn_progress(vpninfo, PRG_DEBUG,
-                            _("Response was:%s\n"), buf->data);
+                            _("Response was:%s\n"), buf);
                return -EINVAL;
        }
        xml_node = xmlDocGetRootElement(xml_doc);
@@ -114,7 +114,7 @@ static int parse_profile(struct openconnect_info *vpninfo, struct oc_text_buf *b
        vpn_progress(vpninfo, PRG_ERR,
                     _("Failed to find VPN profile parameters\n"));
        vpn_progress(vpninfo, PRG_DEBUG,
-                    _("Response was:%s\n"), buf->data);
+                    _("Response was:%s\n"), buf);
        ret = -EINVAL;
  out:
        xmlFreeDoc(xml_doc);
@@ -164,7 +164,7 @@ static const char *add_option(struct openconnect_info *vpninfo, const char *opt,
        return new->value;
 }
 
-static int parse_options(struct openconnect_info *vpninfo, struct oc_text_buf *buf,
+static int parse_options(struct openconnect_info *vpninfo, char *buf, int len,
                         char **session_id, char **ur_z, int *ipv4, int *ipv6, int *hdlc)
 {
        xmlNode *fav_node, *obj_node, *xml_node;
@@ -173,16 +173,16 @@ static int parse_options(struct openconnect_info *vpninfo, struct oc_text_buf *b
        char *s = NULL;
        struct oc_text_buf *domains = NULL;
 
-       if (buf_error(buf))
-               return buf_error(buf);
+       if (!buf || !len)
+               return -EINVAL;
 
-       xml_doc = xmlReadMemory(buf->data, buf->pos, "noname.xml", NULL,
+       xml_doc = xmlReadMemory(buf, len, "noname.xml", NULL,
                                XML_PARSE_NOERROR|XML_PARSE_RECOVER);
        if (!xml_doc) {
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to parse F5 options response\n"));
                vpn_progress(vpninfo, PRG_DEBUG,
-                            _("Response was:%s\n"), buf->data);
+                            _("Response was:%s\n"), buf);
                return -EINVAL;
        }
        fav_node = xmlDocGetRootElement(xml_doc);
@@ -294,7 +294,7 @@ static int parse_options(struct openconnect_info *vpninfo, struct oc_text_buf *b
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to find VPN options\n"));
                vpn_progress(vpninfo, PRG_DEBUG,
-                            _("Response was:%s\n"), buf->data);
+                            _("Response was:%s\n"), buf);
                ret = -EINVAL;
        }
        xmlFreeDoc(xml_doc);
@@ -323,10 +323,11 @@ static int get_ip_address(struct openconnect_info *vpninfo, char *header, char *
 int f5_connect(struct openconnect_info *vpninfo)
 {
        int ret;
-       struct oc_text_buf *reqbuf;
+       struct oc_text_buf *reqbuf = NULL;
        char *profile_params = NULL;
        char *sid = NULL, *ur_z = NULL;
        int ipv4 = -1, ipv6 = -1, hdlc = -1;
+       char *res_buf = NULL;
 
        /* XXX: We should do what cstp_connect() does to check that configuration
           hasn't changed on a reconnect. */
@@ -334,103 +335,50 @@ int f5_connect(struct openconnect_info *vpninfo)
        if (!vpninfo->cookies && vpninfo->cookie)
                http_add_cookie(vpninfo, "MRHSession", vpninfo->cookie, 1);
 
-       ret = openconnect_open_https(vpninfo);
-       if (ret)
-               return ret;
-
-       reqbuf = buf_alloc();
-
-       buf_append(reqbuf, "GET /vdesk/vpn/index.php3?outform=xml&client_version=2.0 HTTP/1.1\r\n");
-       http_common_headers(vpninfo, reqbuf);
-       buf_append(reqbuf, "\r\n");
-
-       if (buf_error(reqbuf)) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Error creating f5 profile request\n"));
-               ret = buf_error(reqbuf);
-               goto out;
-       }
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '>', reqbuf->data);
-
-       ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
-       if (ret < 0)
-               goto out;
-
-       ret = process_http_response(vpninfo, 0, NULL, reqbuf);
+       free(vpninfo->urlpath);
+       vpninfo->urlpath = strdup("vdesk/vpn/index.php3?outform=xml&client_version=2.0");
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
        if (ret < 0)
                goto out;
 
-       if (ret != 201 && ret != 200) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Unexpected %d result from server\n"),
-                            ret);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '<', reqbuf->data);
-       ret = parse_profile(vpninfo, reqbuf, &profile_params);
+       ret = parse_profile(vpninfo, res_buf, ret, &profile_params);
        if (ret)
                goto out;
 
        vpn_progress(vpninfo, PRG_DEBUG,
                     _("Got profile parameters '%s'\n"), profile_params);
-       buf_truncate(reqbuf);
 
-       /* Now fetch the connection options */
-       ret = openconnect_open_https(vpninfo);
-       if (ret)
-               goto out;
-       buf_append(reqbuf, "GET /vdesk/vpn/connect.php3?%s&outform=xml&client_version=2.0 HTTP/1.1\r\n",
-                  profile_params);
-       http_common_headers(vpninfo, reqbuf);
-       buf_append(reqbuf, "\r\n");
+       free(res_buf);
+       res_buf = NULL;
 
-       if (buf_error(reqbuf)) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Error creating f5 options request\n"));
-               ret = buf_error(reqbuf);
+       free(vpninfo->urlpath);
+       if (asprintf(&vpninfo->urlpath, "vdesk/vpn/connect.php3?%s&outform=xml&client_version=2.0",
+                    profile_params) == -1) {
+               ret = -ENOMEM;
                goto out;
        }
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '>', reqbuf->data);
-       ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
-       if (ret < 0)
-               goto out;
-
-       ret = process_http_response(vpninfo, 0, NULL, reqbuf);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
        if (ret < 0)
                goto out;
 
-       if (ret != 201 && ret != 200) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Unexpected %d result from server\n"),
-                            ret);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '<', reqbuf->data);
-       ret = parse_options(vpninfo, reqbuf, &sid, &ur_z, &ipv4, &ipv6, &hdlc);
+       ret = parse_options(vpninfo, res_buf, ret, &sid, &ur_z, &ipv4, &ipv6, &hdlc);
        if (ret)
                goto out;
 
        vpn_progress(vpninfo, PRG_DEBUG,
                     _("Got ipv4 %d ipv6 %d hdlc %d ur_Z '%s'\n"), ipv4, ipv6, hdlc, ur_z);
-       buf_truncate(reqbuf);
 
        if (ipv4 == -1)
                ipv4 = 0;
        if (ipv6 == -1)
                ipv6 = 0;
 
-       /* Now fetch the connection options */
+       /* Now establish the actual connection */
        ret = openconnect_open_https(vpninfo);
        if (ret)
                goto out;
+
+       reqbuf = buf_alloc();
        buf_append(reqbuf, "GET /myvpn?sess=%s&hdlc_framing=%s&ipv4=%s&ipv6=%s&Z=%s&hostname=",
                   sid, hdlc?"yes":"no", ipv4?"yes":"no", ipv6?"yes":"no", ur_z);
        buf_append_base64(reqbuf, vpninfo->localname, strlen(vpninfo->localname));
@@ -440,7 +388,7 @@ int f5_connect(struct openconnect_info *vpninfo)
 
        if (buf_error(reqbuf)) {
                vpn_progress(vpninfo, PRG_ERR,
-                            _("Error creating f5 options request\n"));
+                            _("Error establishing F5 connection\n"));
                ret = buf_error(reqbuf);
                goto out;
        }
@@ -494,7 +442,7 @@ int f5_connect(struct openconnect_info *vpninfo)
 int f5_bye(struct openconnect_info *vpninfo, const char *reason)
 {
        char *orig_path;
-       char *res_buf=NULL;
+       char *res_buf = NULL;
        int ret;
 
        /* XX: handle clean PPP termination?
index bd5667d0b13d3f6d507dfbf3935faf18be22feb8..cb5462a751bbf1d8c4caf3e934ddaa2218ee1799 100644 (file)
@@ -81,7 +81,7 @@ static const char *add_option(struct openconnect_info *vpninfo, const char *opt,
        return new->value;
 }
 
-static int parse_fortinet_xml_config(struct openconnect_info *vpninfo, struct oc_text_buf *buf,
+static int parse_fortinet_xml_config(struct openconnect_info *vpninfo, char *buf, int len,
                                     int *ipv4, int *ipv6)
 {
        xmlNode *fav_node, *obj_node, *xml_node;
@@ -90,16 +90,16 @@ static int parse_fortinet_xml_config(struct openconnect_info *vpninfo, struct oc
        char *s = NULL;
        struct oc_text_buf *domains = NULL;
 
-       if (buf_error(buf))
-               return buf_error(buf);
+       if (!buf || !len)
+               return -EINVAL;
 
-       xml_doc = xmlReadMemory(buf->data, buf->pos, "noname.xml", NULL,
+       xml_doc = xmlReadMemory(buf, len, "noname.xml", NULL,
                                XML_PARSE_NOERROR|XML_PARSE_RECOVER);
        if (!xml_doc) {
                vpn_progress(vpninfo, PRG_ERR,
-                            _("Failed to parse Fortinet options response\n"));
+                            _("Failed to parse Fortinet config XML\n"));
                vpn_progress(vpninfo, PRG_DEBUG,
-                            _("Response was:%s\n"), buf->data);
+                            _("Response was:%s\n"), buf);
                return -EINVAL;
        }
        fav_node = xmlDocGetRootElement(xml_doc);
@@ -205,7 +205,7 @@ static int parse_fortinet_xml_config(struct openconnect_info *vpninfo, struct oc
                vpn_progress(vpninfo, PRG_ERR,
                             _("Failed to find VPN options\n"));
                vpn_progress(vpninfo, PRG_DEBUG,
-                            _("Response was:%s\n"), buf->data);
+                            _("Response was:%s\n"), buf);
                ret = -EINVAL;
        }
        xmlFreeDoc(xml_doc);
@@ -215,7 +215,8 @@ static int parse_fortinet_xml_config(struct openconnect_info *vpninfo, struct oc
 
 int fortinet_connect(struct openconnect_info *vpninfo)
 {
-       struct oc_text_buf *reqbuf;
+       char *res_buf = NULL;
+       struct oc_text_buf *reqbuf = NULL;
        int ret, ipv4 = -1, ipv6 = -1;
 
        /* XXX: We should do what cstp_connect() does to check that configuration
@@ -237,122 +238,38 @@ int fortinet_connect(struct openconnect_info *vpninfo)
         * we're letting the auth happen externally for now, let's do it
         * here...
         */
-
-       buf_append(reqbuf, "GET /remote/index HTTP/1.1\r\n");
-       http_common_headers(vpninfo, reqbuf);
-       buf_append(reqbuf, "\r\n");
-
-       if (buf_error(reqbuf)) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Error creating Fortinet index request\n"));
-               ret = buf_error(reqbuf);
-               goto out;
-       }
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '>', reqbuf->data);
-
-       ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
-       if (ret < 0)
-               goto out;
-
-       ret = process_http_response(vpninfo, 0, NULL, reqbuf);
+       free(vpninfo->urlpath);
+       vpninfo->urlpath = strdup("remote/index");
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
        if (ret < 0)
                goto out;
-
-       if (ret != 201 && ret != 200) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Unexpected %d result from server\n"),
-                            ret);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       /* We don't care about what it returns */
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '<', reqbuf->data);
-       buf_truncate(reqbuf);
+       /* We don't care what it returned as long as it was successful */
+       free(res_buf);
+       res_buf = NULL;
 
        /* XXX: Why was auth_request_vpn_allocation() doing this anyway?
         * It's fetching the legacy non-XML configuration, isn't it?
         * Do we *actually* have to do this, before fetching the XML config?
         */
-       buf_append(reqbuf, "GET /remote/fortisslvpn HTTP/1.1\r\n");
-       http_common_headers(vpninfo, reqbuf);
-       buf_append(reqbuf, "\r\n");
-
-       if (buf_error(reqbuf)) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Error creating Fortinet legacy config request\n"));
-               ret = buf_error(reqbuf);
-               goto out;
-       }
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '>', reqbuf->data);
-
-       ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
-       if (ret < 0)
-               goto out;
-
-       ret = process_http_response(vpninfo, 0, NULL, reqbuf);
-       if (ret < 0)
-               goto out;
-
-       if (ret != 201 && ret != 200) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Unexpected %d result from server\n"),
-                            ret);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       /* ... and auth_request_vpn_allocation() just throws it away,
-        * before fetching the XML version. Or refetching this and
-        * *actually* looking at it, if the legacy mode is enabled.
-        * WTF? */
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '<', reqbuf->data);
-       buf_truncate(reqbuf);
-
-       /* Now fetch the XML version of the config for real */
-       ret = openconnect_open_https(vpninfo);
-       if (ret)
-               goto out;
-       buf_append(reqbuf, "GET /remote/fortisslvpn_xml HTTP/1.1\r\n");
-       http_common_headers(vpninfo, reqbuf);
-       buf_append(reqbuf, "\r\n");
-
-       if (buf_error(reqbuf)) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Error creating fortinet options request\n"));
-               ret = buf_error(reqbuf);
-               goto out;
-       }
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '>', reqbuf->data);
-       ret = vpninfo->ssl_write(vpninfo, reqbuf->data, reqbuf->pos);
+       free(vpninfo->urlpath);
+       vpninfo->urlpath = strdup("remote/fortisslvpn");
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
        if (ret < 0)
                goto out;
+       /* We don't care what it returned as long as it was successful */
+       free(res_buf);
+       res_buf = NULL;
 
-       ret = process_http_response(vpninfo, 0, NULL, reqbuf);
+       free(vpninfo->urlpath);
+       vpninfo->urlpath = strdup("remote/fortisslvpn_xml");
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
        if (ret < 0)
                goto out;
 
-       if (ret != 201 && ret != 200) {
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Unexpected %d result from server\n"),
-                            ret);
-               ret = -EINVAL;
-               goto out;
-       }
-
-       if (vpninfo->dump_http_traffic)
-               dump_buf(vpninfo, '<', reqbuf->data);
-       ret = parse_fortinet_xml_config(vpninfo, reqbuf, &ipv4, &ipv6);
+       ret = parse_fortinet_xml_config(vpninfo, res_buf, ret, &ipv4, &ipv6);
        if (ret)
                goto out;
 
-       buf_truncate(reqbuf);
-
        if (ipv4 == -1)
                ipv4 = 0;
        if (ipv6 == -1)
@@ -362,7 +279,8 @@ int fortinet_connect(struct openconnect_info *vpninfo)
        ret = openconnect_open_https(vpninfo);
        if (ret)
                goto out;
-       buf_append(reqbuf, "GET /remopte/sslvpn-tunnel HTTP/1.1\r\n");
+       reqbuf = buf_alloc();
+       buf_append(reqbuf, "GET /remote/sslvpn-tunnel HTTP/1.1\r\n");
        http_common_headers(vpninfo, reqbuf);
        buf_append(reqbuf, "\r\n");
 
@@ -406,6 +324,7 @@ int fortinet_connect(struct openconnect_info *vpninfo)
                monitor_except_fd(vpninfo, ssl);
        }
        buf_free(reqbuf);
+       free(res_buf);
 
        free(vpninfo->cstp_pkt);
        vpninfo->cstp_pkt = NULL;
@@ -430,7 +349,7 @@ int fortinet_bye(struct openconnect_info *vpninfo, const char *reason)
        openconnect_close_https(vpninfo, 0);
 
        orig_path = vpninfo->urlpath;
-       vpninfo->urlpath = strdup("/remote/logout");
+       vpninfo->urlpath = strdup("remote/logout");
        ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
        free(vpninfo->urlpath);
        vpninfo->urlpath = orig_path;