]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Consolidate check_http_status from gpst.c and ppp.c
authorDaniel Lenski <dlenski@gmail.com>
Wed, 28 Apr 2021 17:41:40 +0000 (10:41 -0700)
committerDaniel Lenski <dlenski@gmail.com>
Mon, 3 May 2021 21:50:21 +0000 (14:50 -0700)
This function checks a buffer for an unexpected HTTP status line ("HTTP/xxx
nnn ...") and returns the numeric status value (nnn) if found.

Also fixes a crash when GP config request ("/ssl-vpn/getconfig.esp") returns
no body at all.

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
gpst.c
openconnect-internal.h
ppp.c

diff --git a/gpst.c b/gpst.c
index 86f357c65d17248d9498fd83a57040090b5b3420..9f424c670cc56f6a9ad2f3995ab39247450193e9 100644 (file)
--- a/gpst.c
+++ b/gpst.c
@@ -650,7 +650,7 @@ static int gpst_get_config(struct openconnect_info *vpninfo)
                /* XX: if our "cookie" is bogus (doesn't include at least 'user', 'authcookie',
                 * and 'portal' fields) the server will respond like this.
                 */
-               if (result == -EINVAL && !strcmp(xml_buf, "errors getting SSL/VPN config"))
+               if (result == -EINVAL && xml_buf && !strcmp(xml_buf, "errors getting SSL/VPN config"))
                        result = -EPERM;
                goto out;
        }
@@ -741,10 +741,15 @@ static int gpst_connect(struct openconnect_info *vpninfo)
                        ret = vpninfo->ssl_gets(vpninfo, buf+sizeof(start_tunnel), sizeof(buf)-sizeof(start_tunnel));
                        ret = (ret>0 ? ret : 0) + sizeof(start_tunnel);
                }
-               vpn_progress(vpninfo, PRG_ERR,
-                            _("Got inappropriate HTTP GET-tunnel response: %.*s\n"), ret, buf);
-               /* XX: this is what GP servers return when they don't like the cookie */
-               ret = !strncmp(buf, "HTTP/1.1 502 ", 13) ? -EPERM : -EINVAL;
+               int status = check_http_status(buf, ret);
+               /* XX: GP servers return 502 when they don't like the cookie */
+               if (status == 502)
+                       ret = -EPERM;
+               else {
+                       vpn_progress(vpninfo, PRG_ERR, _("Got unexpected HTTP response: %.*s\n"),
+                                    ret, buf);
+                       ret = -EINVAL;
+               }
        }
 
        if (ret < 0)
index 9552c18bfde20b9568268314647dc85a1d171f93..3e6a549e94d8216ec86ea97b199db1fd1464b891 100644 (file)
@@ -1062,6 +1062,7 @@ int ppp_tcp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readabl
 int ppp_udp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable);
 int openconnect_ppp_new(struct openconnect_info *vpninfo, int encap, int want_ipv4, int want_ipv6);
 int ppp_reset(struct openconnect_info *vpninfo);
+int check_http_status(const char *buf, int len);
 
 /* auth-globalprotect.c */
 int gpst_obtain_cookie(struct openconnect_info *vpninfo);
diff --git a/ppp.c b/ppp.c
index 753a3b22bb746e7ecb230b4f2d8e649d7675da16..a9d15ae1c0f015db225b2df79701ac9134456c39 100644 (file)
--- a/ppp.c
+++ b/ppp.c
@@ -1047,6 +1047,17 @@ static inline void add_ppp_header(struct pkt *p, struct oc_ppp *ppp, int proto)
        p->ppp.hlen = p->data - ph;
 }
 
+int check_http_status(const char *buf, int len)
+{
+       if (len >= 5 && !memcmp(buf, "HTTP/", 5)) {
+               const char *eol = memchr(buf, '\r', len) ?: memchr(buf, '\n', len);
+               const char *sp1 = memchr(buf, ' ', len);
+               const char *sp2 = sp1 ? memchr(sp1+1, ' ', len - (sp1-buf) + 1) : NULL;
+               return (sp1 && sp2 && (!eol || sp2<eol)) ? atoi(sp1+1) : 500;
+       }
+       return -EINVAL;
+}
+
 static int ppp_mainloop(struct openconnect_info *vpninfo, int dtls,
                        struct keepalive_info *kai, int *timeout, int readable)
 {
@@ -1101,17 +1112,11 @@ static int ppp_mainloop(struct openconnect_info *vpninfo, int dtls,
                 * of the first packet
                 */
                if (ppp->check_http_response) {
+                       int status = check_http_status((const char *)eh, len);
                        ppp->check_http_response = 0;
-                       if (!memcmp(eh, "HTTP/", 5)) {
-                               const char *sol = (const char *)eh;
-                               const char *eol = memchr(sol, '\r', len) ?: memchr(sol, '\n', len);
-                               const char *sp1 = memchr(sol, ' ', len);
-                               const char *sp2 = memchr(sp1+1, ' ', len - (sp1-sol) + 1);
-                               int status = sp1 && sp2 ? atoi(sp1+1) : -1;
-                               if (eol)
-                                       len = eol - sol;
-                               vpn_progress(vpninfo, PRG_ERR,
-                                            _("Got unexpected HTTP response: %.*s\n"), len, sol);
+                       if (status >= 0) {
+                               vpn_progress(vpninfo, PRG_ERR,_("Got unexpected HTTP response: %.*s\n"),
+                                            len, (const char *)eh);
                                vpninfo->quit_reason = "Received HTTP response (not a PPP packet)";
                                return (status >= 400 && status <= 499) ? -EPERM : -EINVAL;
                        }