Skip to content

Commit

Permalink
Fortinet requires us to check for an HTTP error response only over TLS
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
dlenski committed Jun 17, 2021
1 parent f5a4fb0 commit 5cb9914
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 2 deletions.
3 changes: 2 additions & 1 deletion fortinet.c
Expand Up @@ -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.
Expand Down Expand Up @@ -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. */
Expand Down
2 changes: 1 addition & 1 deletion ppp.c
Expand Up @@ -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:
Expand All @@ -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:
Expand Down

0 comments on commit 5cb9914

Please sign in to comment.