]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Fortinet: socket switches abruptly from HTTP request to encapsulated PPP, with no...
authorDaniel Lenski <dlenski@gmail.com>
Thu, 4 Feb 2021 23:38:20 +0000 (15:38 -0800)
committerDaniel Lenski <dlenski@gmail.com>
Mon, 29 Mar 2021 03:13:30 +0000 (20:13 -0700)
However, in the case of *failure* to start the PPP tunnel, an HTTP response
may be sent, and we'll need to detect that in the PPP mainloop.

Don't blame me. I didn't design this.

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

index b5aa42fee5960e89b3f29db1748899fc79b8e520..f5e1e0c884842fdb043d06e0baad745bd9639dac 100644 (file)
@@ -331,17 +331,13 @@ int fortinet_connect(struct openconnect_info *vpninfo)
        if (ret < 0)
                goto out;
 
-       ret = process_http_response(vpninfo, 1, 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;
-       }
+       /* XX: If this connection request succeeds, no HTTP response appears.
+        * We just start sending our encapsulated PPP configuration packets.
+        * However, if the request FAILS, it WILL send an HTTP response.
+        * We handle that in the PPP mainloop.
+        *
+        * Don't blame me. I didn't design this.
+        */
 
        ret = openconnect_ppp_new(vpninfo, PPP_ENCAP_FORTINET_HDLC, ipv4, ipv6);
 
diff --git a/ppp.c b/ppp.c
index 3115092761073b32aeb661dadb96710baec4bd3e..e452caee2c1af52d1b3746c406da0e0308127ebe 100644 (file)
--- a/ppp.c
+++ b/ppp.c
@@ -248,13 +248,16 @@ int openconnect_ppp_new(struct openconnect_info *vpninfo,
                ppp->encap_len = 4;
                break;
 
+       case PPP_ENCAP_FORTINET_HDLC:
+               ppp->check_http_response = 1;
+               /* fall through */
+
        case PPP_ENCAP_F5_HDLC:
                /* XX: F5 server cancels our IP address allocation if we PPP-terminate */
                ppp->no_terminate_on_pause = 1;
                /* fall through */
 
        case PPP_ENCAP_RFC1662_HDLC:
-       case PPP_ENCAP_FORTINET_HDLC:
                ppp->encap_len = 0;
                ppp->hdlc = 1;
                break;
@@ -1019,6 +1022,23 @@ int ppp_mainloop(struct openconnect_info *vpninfo, int *timeout, int readable)
                if (len < 0)
                        goto do_reconnect;
 
+               /* XX: Some protocols require us to check for an HTTP response in place
+                * of the first packet
+                */
+               if (ppp->check_http_response) {
+                       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);
+                               if (eol)
+                                       len = eol - sol;
+                               vpn_progress(vpninfo, PRG_ERR,
+                                            _("Got unexpected HTTP response: %.*s\n"), len, sol);
+                               vpninfo->quit_reason = "Received HTTP response (not a PPP packet)";
+                               return -EINVAL;
+                       }
+               }
+
        next_pkt:
                /* At this point:
                 *   eh: pointer to start of bytes-from-the-wire
diff --git a/ppp.h b/ppp.h
index 2b9d1c3e2937a0ffbcd9734ae316f5b3964f855d..fe00f0db9ff9bb0dabecd36165b0fe311f49734c 100644 (file)
--- a/ppp.h
+++ b/ppp.h
@@ -104,6 +104,7 @@ struct oc_ppp {
        int hdlc;
        int want_ipv4;
        int want_ipv6;
+       int check_http_response;
        int no_terminate_on_pause;
 
        int ppp_state;