]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
http: Allow passing header_cb to do_https_request
authorAndreas Gnau <rondom@rondom.de>
Sat, 29 May 2021 11:58:50 +0000 (13:58 +0200)
committerAndreas Gnau <rondom@rondom.de>
Tue, 15 Jun 2021 11:58:58 +0000 (13:58 +0200)
Enable passing a header callback to do_https_request in order to be able
to process response headers.

Signed-off-by: Andreas Gnau <rondom@rondom.de>
array.c
auth-globalprotect.c
auth-juniper.c
auth.c
f5.c
fortinet.c
gpst.c
http.c
oncp.c
openconnect-internal.h

diff --git a/array.c b/array.c
index 736e0f8ce192f8e0325c4f8adfce1ff1fc2d3a75..1800cfd1bd247dbd5b00bf96dfd02dce5243ed22 100644 (file)
--- a/array.c
+++ b/array.c
@@ -113,7 +113,7 @@ int array_obtain_cookie(struct openconnect_info *vpninfo)
        char *resp_buf = NULL;
        ret = do_https_request(vpninfo, "POST",
                               "application/x-www-form-urlencoded",
-                              req_buf, &resp_buf, 2);
+                              req_buf, &resp_buf, NULL, 2);
        free(resp_buf);
        if (ret <= 0)
                goto out;
@@ -1296,7 +1296,7 @@ int array_bye(struct openconnect_info *vpninfo, const char *reason)
 
        orig_path = vpninfo->urlpath;
        vpninfo->urlpath = strdup("prx/000/http/localhost/logout"); /* redirect segfaults without strdup */
-       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, 0);
        free(vpninfo->urlpath);
        vpninfo->urlpath = orig_path;
 
index a698cb436680e46ebfc662a0aed27e56cbaf7484..320a563ccba31102a266f7b40d150b37071b6493 100644 (file)
@@ -575,7 +575,7 @@ static int gpst_login(struct openconnect_info *vpninfo, int portal, struct login
                        }
                }
                /* submit prelogin request to get form */
-               result = do_https_request(vpninfo, "POST", NULL, NULL, &xml_buf, 1);
+               result = do_https_request(vpninfo, "POST", NULL, NULL, &xml_buf, NULL, 1);
                if (!keep_urlpath) {
                        free(vpninfo->urlpath);
                        vpninfo->urlpath = orig_path;
@@ -621,8 +621,7 @@ static int gpst_login(struct openconnect_info *vpninfo, int portal, struct login
 
                orig_path = vpninfo->urlpath;
                vpninfo->urlpath = strdup(portal ? "global-protect/getconfig.esp" : "ssl-vpn/login.esp");
-               result = do_https_request(vpninfo, "POST", request_body_type, request_body,
-                                         &xml_buf, 0);
+               result = do_https_request(vpninfo, "POST", request_body_type, request_body, &xml_buf, NULL, 0);
                free(vpninfo->urlpath);
                vpninfo->urlpath = orig_path;
 
@@ -734,8 +733,7 @@ int gpst_bye(struct openconnect_info *vpninfo, const char *reason)
        orig_path = vpninfo->urlpath;
        vpninfo->urlpath = strdup("ssl-vpn/logout.esp");
        openconnect_close_https(vpninfo, 0);
-       result = do_https_request(vpninfo, method, request_body_type, request_body,
-                                 &xml_buf, 0);
+       result = do_https_request(vpninfo, method, request_body_type, request_body, &xml_buf, NULL, 0);
        free(vpninfo->urlpath);
        vpninfo->urlpath = orig_path;
 
index 0d2e6ba9f6143cd7d5ca67b96514b416c85d242c..a535604505481ae8fcbbb035e8f5978ed7cf43f9 100644 (file)
@@ -466,12 +466,10 @@ int oncp_obtain_cookie(struct openconnect_info *vpninfo)
                char *url;
 
                if (resp_buf && resp_buf->pos)
-                       ret = do_https_request(vpninfo, "POST",
-                                              "application/x-www-form-urlencoded",
-                                              resp_buf, &form_buf, 2);
+                       ret = do_https_request(vpninfo, "POST", "application/x-www-form-urlencoded", resp_buf,
+                                              &form_buf, NULL, 2);
                else
-                       ret = do_https_request(vpninfo, "GET", NULL, NULL,
-                                              &form_buf, 2);
+                       ret = do_https_request(vpninfo, "GET", NULL, NULL, &form_buf, NULL, 2);
 
                /* After login, the server will redirect the "browser" to a landing page.
                 * https://kb.pulsesecure.net/articles/Pulse_Security_Advisories/SA44784
diff --git a/auth.c b/auth.c
index f074783079d62ba37e26d6416b958e5221a48f11..ba956eed84bab16ff86289f837b7b0960092df85 100644 (file)
--- a/auth.c
+++ b/auth.c
@@ -1362,8 +1362,7 @@ newgroup:
                }
 
                request_body_type = vpninfo->xmlpost ? "application/xml; charset=utf-8" : "application/x-www-form-urlencoded";
-               result = do_https_request(vpninfo, method, request_body_type, request_body,
-                                         &form_buf, 0);
+               result = do_https_request(vpninfo, method, request_body_type, request_body, &form_buf, NULL, 0);
                if (vpninfo->got_cancel_cmd) {
                        result = 1;
                        goto out;
@@ -1442,7 +1441,7 @@ newgroup:
                        vpninfo->csd_stuburl = NULL;
                        handle_redirect(vpninfo);
 
-                       buflen = do_https_request(vpninfo, "GET", NULL, NULL, &form_buf, 0);
+                       buflen = do_https_request(vpninfo, "GET", NULL, NULL, &form_buf, NULL, 0);
                        if (buflen <= 0) {
                                if (vpninfo->csd_wrapper) {
                                        vpn_progress(vpninfo, PRG_ERR,
@@ -1465,7 +1464,7 @@ newgroup:
 
                /* vpninfo->urlpath now points to the wait page */
                while (1) {
-                       result = do_https_request(vpninfo, "GET", NULL, NULL, &form_buf, 0);
+                       result = do_https_request(vpninfo, "GET", NULL, NULL, &form_buf, NULL, 0);
                        if (result <= 0)
                                break;
 
@@ -1488,7 +1487,7 @@ newgroup:
 
                result = do_https_request(vpninfo,
                                          vpninfo->xmlpost ? "POST" : "GET",
-                                         request_body_type, request_body, &form_buf, 1);
+                                         request_body_type, request_body, &form_buf, NULL, 1);
                if (result < 0)
                        goto out;
 
@@ -1514,8 +1513,7 @@ newgroup:
                        goto newgroup;
                }
 
-               result = do_https_request(vpninfo, method, request_body_type, request_body,
-                                         &form_buf, 1);
+               result = do_https_request(vpninfo, method, request_body_type, request_body, &form_buf, NULL, 1);
                if (result < 0)
                        goto out;
 
diff --git a/f5.c b/f5.c
index df26d2f8f20889cde2832e87bee64290a987d540..58f03a1fbaa74191d0b9bcc13ed0c352c1961fb9 100644 (file)
--- a/f5.c
+++ b/f5.c
@@ -111,10 +111,9 @@ int f5_obtain_cookie(struct openconnect_info *vpninfo)
                if (req_buf && req_buf->pos)
                        ret = do_https_request(vpninfo, "POST",
                                               "application/x-www-form-urlencoded",
-                                              req_buf, &resp_buf, 2);
+                                              req_buf, &resp_buf, NULL, 2);
                else
-                       ret = do_https_request(vpninfo, "GET", NULL, NULL,
-                                              &resp_buf, 2);
+                       ret = do_https_request(vpninfo, "GET", NULL, NULL, &resp_buf, NULL, 2);
 
                if (!check_cookie_success(vpninfo)) {
                        free(resp_buf);
@@ -538,7 +537,7 @@ static int f5_configure(struct openconnect_info *vpninfo)
 
        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);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, 0);
        if (ret < 0)
                goto out;
 
@@ -558,7 +557,7 @@ static int f5_configure(struct openconnect_info *vpninfo)
                ret = -ENOMEM;
                goto out;
        }
-       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, 0);
        if (ret < 0)
                goto out;
 
@@ -693,7 +692,7 @@ int f5_bye(struct openconnect_info *vpninfo, const char *reason)
 
        orig_path = vpninfo->urlpath;
        vpninfo->urlpath = strdup("vdesk/hangup.php3?hangup_error=1"); /* redirect segfaults without strdup */
-       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, 0);
        free(vpninfo->urlpath);
        vpninfo->urlpath = orig_path;
 
index 0b220b7a5197af6e92f8f19bf58df86adf1e200d..b57c9bc3fc6c5f60782e8467adb712da0dae6015 100644 (file)
@@ -108,7 +108,7 @@ int fortinet_obtain_cookie(struct openconnect_info *vpninfo)
                goto out;
        }
 
-       ret = do_https_request(vpninfo, "GET", NULL, NULL, &resp_buf, 1);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &resp_buf, NULL, 1);
        free(resp_buf);
        resp_buf = NULL;
        if (ret < 0)
@@ -195,7 +195,7 @@ int fortinet_obtain_cookie(struct openconnect_info *vpninfo)
                if ((ret = buf_error(req_buf)))
                        goto out;
                ret = do_https_request(vpninfo, "POST", "application/x-www-form-urlencoded",
-                                      req_buf, &resp_buf, 0);
+                                      req_buf, &resp_buf, NULL, 0);
 
                /* If we got SVPNCOOKIE, then we're done. */
                struct oc_vpn_option *cookie;
@@ -549,7 +549,7 @@ static int fortinet_configure(struct openconnect_info *vpninfo)
 #if 0 /* Nah... */
        free(vpninfo->urlpath);
        vpninfo->urlpath = strdup("remote/fortisslvpn");
-       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, 0);
        if (ret < 0)
                goto out;
        else if (ret == 0)
@@ -562,7 +562,7 @@ static int fortinet_configure(struct openconnect_info *vpninfo)
 
        /* Now fetch the connection options in XML format */
        vpninfo->urlpath = strdup("remote/fortisslvpn_xml");
-       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, 0);
        if (ret < 0) {
                if (ret == -EPERM)
                        vpn_progress(vpninfo, PRG_ERR,
@@ -739,7 +739,7 @@ int fortinet_bye(struct openconnect_info *vpninfo, const char *reason)
 
        orig_path = vpninfo->urlpath;
        vpninfo->urlpath = strdup("remote/logout");
-       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, 0);
        free(vpninfo->urlpath);
        vpninfo->urlpath = orig_path;
 
diff --git a/gpst.c b/gpst.c
index 5fb1d41bb6b21a294945da91c58cbaeaad1a1038..99c4370aaeb9eab07646469231bf24654a7910b6 100644 (file)
--- a/gpst.c
+++ b/gpst.c
@@ -639,8 +639,7 @@ static int gpst_get_config(struct openconnect_info *vpninfo)
 
        orig_path = vpninfo->urlpath;
        vpninfo->urlpath = strdup("ssl-vpn/getconfig.esp");
-       result = do_https_request(vpninfo, method, request_body_type, request_body,
-                                 &xml_buf, 0);
+       result = do_https_request(vpninfo, method, request_body_type, request_body, &xml_buf, NULL, 0);
        free(vpninfo->urlpath);
        vpninfo->urlpath = orig_path;
 
@@ -870,8 +869,7 @@ static int check_or_submit_hip_report(struct openconnect_info *vpninfo, const ch
 
        orig_path = vpninfo->urlpath;
        vpninfo->urlpath = strdup(report ? "ssl-vpn/hipreport.esp" : "ssl-vpn/hipreportcheck.esp");
-       result = do_https_request(vpninfo, method, request_body_type, request_body,
-                                 &xml_buf, 0);
+       result = do_https_request(vpninfo, method, request_body_type, request_body, &xml_buf, NULL, 0);
        free(vpninfo->urlpath);
        vpninfo->urlpath = orig_path;
 
diff --git a/http.c b/http.c
index 790f2cd8bb7463d7743869badf4d520ea8ed49dc..aef75f04a5ca8c25e7f0fc72a4391077a61acf3e 100644 (file)
--- a/http.c
+++ b/http.c
@@ -778,14 +778,17 @@ static int https_socket_closed(struct openconnect_info *vpninfo)
  *  request_body_type:  Content type for a POST (e.g. text/html).  Can be NULL.
  *  request_body:       POST content
  *  form_buf:           Callee-allocated buffer for server content
+ *  header_cb:          Callback executed on every header line
+ *                      If HTTP authentication is needed, the callback specified needs to call http_auth_hdrs.
+ *  fetch_redirect:
  *
  * Return value:
  *  < 0, on error
  *  >=0, on success, indicating the length of the data in *form_buf
  */
-int do_https_request(struct openconnect_info *vpninfo, const char *method,
-                    const char *request_body_type, struct oc_text_buf *request_body,
-                    char **form_buf, int fetch_redirect)
+int do_https_request(struct openconnect_info *vpninfo, const char *method, const char *request_body_type,
+                    struct oc_text_buf *request_body, char **form_buf,
+                    int (*header_cb)(struct openconnect_info *, char *, char *), int fetch_redirect)
 {
        struct oc_text_buf *buf;
        int result;
@@ -794,6 +797,9 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
        int i, auth = 0;
        int max_redirects = 10;
 
+       if (!header_cb)
+               header_cb = http_auth_hdrs;
+
        if (request_body_type && buf_error(request_body))
                return buf_error(request_body);
 
@@ -902,7 +908,7 @@ int do_https_request(struct openconnect_info *vpninfo, const char *method,
                }
        }
 
-       result = process_http_response(vpninfo, 0, http_auth_hdrs, buf);
+       result = process_http_response(vpninfo, 0, header_cb, buf);
        if (result < 0) {
                if (rq_retry) {
                        openconnect_close_https(vpninfo, 0);
diff --git a/oncp.c b/oncp.c
index 1c90918dd3cb7b1a5d9ac2693cac59051ca2b2fe..66fec8f22a207def1887cdb0f7cd09c8fb11cd61 100644 (file)
--- a/oncp.c
+++ b/oncp.c
@@ -1214,7 +1214,7 @@ int oncp_bye(struct openconnect_info *vpninfo, const char *reason)
 
        orig_path = vpninfo->urlpath;
        vpninfo->urlpath = strdup("dana-na/auth/logout.cgi"); /* redirect segfaults without strdup */
-       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, 0);
+       ret = do_https_request(vpninfo, "GET", NULL, NULL, &res_buf, NULL, 0);
        free(vpninfo->urlpath);
        vpninfo->urlpath = orig_path;
 
index 97f0ba2411cbaaba1dc11176e08cadc2e6279b54..07c4581ddb77833e5f3678d46e7aca6d214aad8f 100644 (file)
@@ -1313,9 +1313,9 @@ int process_proxy(struct openconnect_info *vpninfo, int ssl_sock);
 int internal_parse_url(const char *url, char **res_proto, char **res_host,
                       int *res_port, char **res_path, int default_port);
 char *internal_get_url(struct openconnect_info *vpninfo);
-int do_https_request(struct openconnect_info *vpninfo, const char *method,
-                    const char *request_body_type, struct oc_text_buf *request_body,
-                    char **form_buf, int fetch_redirect);
+int do_https_request(struct openconnect_info *vpninfo, const char *method, const char *request_body_type,
+                    struct oc_text_buf *request_body, char **form_buf,
+                    int (*header_cb)(struct openconnect_info *, char *, char *), int fetch_redirect);
 int http_add_cookie(struct openconnect_info *vpninfo, const char *option,
                    const char *value, int replace);
 int internal_split_cookies(struct openconnect_info *vpninfo, int replace, const char *def_cookie);