]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Fortinet requires us to check for an HTTP error response only over TLS
authorDaniel Lenski <dlenski@gmail.com>
Thu, 17 Jun 2021 20:23:18 +0000 (13:23 -0700)
committerDaniel Lenski <dlenski@gmail.com>
Thu, 17 Jun 2021 21:01:21 +0000 (14:01 -0700)
If the Fortinet PPP connection request *succeeds* over TLS, there is no HTTP
response before we start exchanging PPP packets.  If it *fails*, there is an
HTTP response.

If the Fortinet PPP connection request is over DTLS, a 'svrhello' response
is expected regardless of whether it succeeded or failed. This is handled
by fortinet_dtls_catch_svrhello()

Let's only check for that HTTP response in Fortinet if we're definitely
connecting over TLS.  The "proceeding to tunnel stage" test in
'fortinet-auth-config-tests' verifies the correctness of the HTTP response
parsing behavior.

Fortinet connection response matrix ("Don't blame me, I didn't design this."):

           \ TRANSPORT
    STATUS  \             TLS               DTLS
             +            ---------------   -------------------
    Success  |            immediate → PPP   SVRHELLO 'ok' → PPP
    Failure  |            HTTP response     SVRHELLO 'fail'

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

index 0b220b7a5197af6e92f8f19bf58df86adf1e200d..668af9c4caf356af5ebdeefcb516e434f4d7e69a 100644 (file)
@@ -541,7 +541,7 @@ static int fortinet_configure(struct openconnect_info *vpninfo)
         * FortiOS 4 was the last version to send the legacy HTTP configuration.
         * FortiOS 5 and later send the current XML configuration.
         * We clearly do not need to support FortiOS 4 anymore.
-        * 
+        *
         * Yet we keep this code around in order to get a sanity check about
         * whether the SVPNCOOKIE is still valid/alive, until we are sure we've
         * worked out the weirdness with reconnects.
@@ -665,6 +665,7 @@ int fortinet_connect(struct openconnect_info *vpninfo)
         *
         * Don't blame me. I didn't design this.
         */
+       vpninfo->ppp->check_http_response = 1;
 
        /* Trigger the first PPP negotiations and ensure the PPP state
         * is PPPS_ESTABLISH so that ppp_tcp_mainloop() knows we've started. */
diff --git a/ppp.c b/ppp.c
index 3e61b742c3bf30c2f7fe697d8209271235bf75fe..042bf939a7b79d2739fd2f6f70bf512634076989 100644 (file)
--- a/ppp.c
+++ b/ppp.c
@@ -258,6 +258,7 @@ int ppp_reset(struct openconnect_info *vpninfo)
        ppp->ppp_state = PPPS_DEAD;
        ppp->out_asyncmap = 0;
        ppp->out_lcp_opts = BIT_MRU | BIT_MAGIC | BIT_PFCOMP | BIT_ACCOMP | BIT_MRU_COAX;
+       ppp->check_http_response = 0;
 
        switch (ppp->encap) {
        case PPP_ENCAP_F5:
@@ -268,7 +269,6 @@ int ppp_reset(struct openconnect_info *vpninfo)
                /* XX: Fortinet server rejects asyncmap and header compression. Don't blame me. */
                ppp->out_lcp_opts &= ~(BIT_PFCOMP | BIT_ACCOMP);
                ppp->encap_len = 6;
-               ppp->check_http_response = 1;
                break;
 
        case PPP_ENCAP_F5_HDLC: