From 5cb99148a582f4953f8f884bc2c43187e7fa54b8 Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Thu, 17 Jun 2021 13:23:18 -0700 Subject: [PATCH] Fortinet requires us to check for an HTTP error response only over TLS MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 --- fortinet.c | 3 ++- ppp.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/fortinet.c b/fortinet.c index 0b220b7a..668af9c4 100644 --- a/fortinet.c +++ b/fortinet.c @@ -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 3e61b742..042bf939 100644 --- 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: -- 2.49.0