]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Attempt to determine whether Fortinet server really supports reconnect-after-drop...
authorDaniel Lenski <dlenski@gmail.com>
Tue, 31 Aug 2021 01:55:37 +0000 (18:55 -0700)
committerDaniel Lenski <dlenski@gmail.com>
Sun, 17 Oct 2021 15:37:32 +0000 (08:37 -0700)
If the server doesn't actually support reconnection, then DPD is probably
useless or counterproductive, and we shouldn't enable it.

See discussion here: https://gitlab.com/openconnect/openconnect/-/issues/297#note_664686767

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

index 9135e03717e1e764969ef2d68bb397c8665a7311..6db86723c84f50b3273162fdb4025977a61ac4ff 100644 (file)
@@ -298,6 +298,7 @@ static int parse_fortinet_xml_config(struct openconnect_info *vpninfo, char *buf
        xmlDocPtr xml_doc;
        int ret = 0, n_dns = 0, default_route = 1;
        char *s = NULL, *s2 = NULL;
+       int heartbeat_interval = -1, reconnect_after_drop = -1;
        struct oc_text_buf *domains = NULL;
 
        if (!buf || !len)
@@ -337,10 +338,35 @@ static int parse_fortinet_xml_config(struct openconnect_info *vpninfo, char *buf
                else if (xmlnode_is_named(xml_node, "idle-timeout") && !xmlnode_get_prop(xml_node, "val", &s)) {
                        int sec = vpninfo->idle_timeout = atoi(s);
                        vpn_progress(vpninfo, PRG_INFO, _("Idle timeout is %d minutes.\n"), sec/60);
-               } else if (xmlnode_is_named(xml_node, "dtls-config") && !xmlnode_get_prop(xml_node, "heartbeat-interval", &s)) {
-                       int sec = atoi(s);
-                       if (sec && (!vpninfo->dtls_times.dpd || sec < vpninfo->dtls_times.dpd))
-                               vpninfo->dtls_times.dpd = vpninfo->ssl_times.dpd = sec;
+               } else if (xmlnode_is_named(xml_node, "dtls-config") && !xmlnode_get_prop(xml_node, "heartbeat-interval", &s))
+                       heartbeat_interval = atoi(s);
+               else if (xmlnode_is_named(xml_node, "auth-ses")) {
+                       /* These settings were apparently added in v6.2.1 of the Fortigate server,
+                        * (see https://docs.fortinet.com/document/fortigate/6.2.1/cli-reference/281620/vpn-ssl-settings)
+                        * and seem to control the possibility of reconnecting after a dropped connection.
+                        * See discussion at https://gitlab.com/openconnect/openconnect/-/issues/297#note_664686767
+                        */
+                       int check_ip_src = -1, dropped_session_cleanup = -1;
+                       if (!xmlnode_get_prop(xml_node, "tun-connect-without-reauth", &s)) {
+                               reconnect_after_drop = atoi(s);
+                               if (reconnect_after_drop) {
+                                       if (!xmlnode_get_prop(xml_node, "check-src-ip", &s))
+                                               check_ip_src = atoi(s);
+                                       if (!xmlnode_get_prop(xml_node, "tun-user-ses-timeout", &s))
+                                               dropped_session_cleanup = atoi(s);
+                                       vpn_progress(vpninfo, PRG_ERR,
+                                                    _("Server reports that reconnect-after-drop is allowed within %d seconds, %s\n"),
+                                                    dropped_session_cleanup,
+                                                    check_ip_src ? _("but only from the same source IP address") : _("even if source IP address changes"));
+                               } else if (reconnect_after_drop == 0) {
+                                       vpn_progress(vpninfo, PRG_ERR,
+                                                    _("Server reports that reconnect-after-drop is not allowed.\n"));
+                               }
+                       } else
+                               vpn_progress(vpninfo, PRG_ERR,
+                                            _("Contents of <auth-ses> tag are unexpected.\n"));
+                       vpn_progress(vpninfo, PRG_ERR,
+                                    _("Please report whether Fortinet reconnect-after-drop works to <openconnect-devel@lists.infradead.org>\n"));
                } else if (xmlnode_is_named(xml_node, "fos")) {
                        char platform[80], *p = platform, *e = platform + 80;
                        if (!xmlnode_get_prop(xml_node, "platform", &s)) {
@@ -481,6 +507,19 @@ static int parse_fortinet_xml_config(struct openconnect_info *vpninfo, char *buf
                }
        }
 
+       if (heartbeat_interval > 0) {
+               /* Ignore server's heartbeat/DPD interval unless server actually allows
+                * reconnect-after-drop (without reauthentication).
+                */
+               if (reconnect_after_drop > 0) {
+                       if (!vpninfo->dtls_times.dpd || heartbeat_interval < vpninfo->dtls_times.dpd)
+                               vpninfo->dtls_times.dpd = vpninfo->ssl_times.dpd = heartbeat_interval;
+               } else
+                       vpn_progress(vpninfo, PRG_ERR,
+                                    _("Ignoring server's heartbeat/DPD interval of %d seconds, because reconnect-after-drop is not allowed.\n"),
+                                    heartbeat_interval);
+       }
+
        if (default_route && new_ip_info.addr)
                new_ip_info.netmask = add_option_dup(&new_opts, "full-netmask", "0.0.0.0", -1);
        if (buf_error(domains) == 0 && domains->pos > 0) {