]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
Fortinet's realm parameter comes from the URL-path
authorDaniel Lenski <dlenski@gmail.com>
Fri, 19 Feb 2021 05:14:03 +0000 (21:14 -0800)
committerDaniel Lenski <dlenski@gmail.com>
Mon, 29 Mar 2021 03:13:31 +0000 (20:13 -0700)
See an example at https://github.com/adrienverge/openfortivpn/issues/827

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

index 237d244951109d0bd79121272155876bcf2f4730..b551465cbdec32c2b2916d230ef4956520557fa7 100644 (file)
@@ -93,7 +93,7 @@ int fortinet_obtain_cookie(struct openconnect_info *vpninfo)
        struct oc_text_buf *resp_buf = NULL;
        struct oc_auth_form *form = NULL;
        struct oc_form_opt *opt, *opt2;
-       char *form_buf = NULL;
+       char *form_buf = NULL, *realm = NULL;
 
        resp_buf = buf_alloc();
        if (buf_error(resp_buf)) {
@@ -107,6 +107,21 @@ int fortinet_obtain_cookie(struct openconnect_info *vpninfo)
        if (ret < 0)
                goto out;
 
+       /* XX: Fortinet's initial 'GET /' normally redirects to /remote/login.
+        * If a valid, non-default "realm" is specified (~= usergroup or authgroup),
+        * it will appear as a query parameter of the resulting URL, and we need to
+        * capture and save it. That is, for example:
+        *   'GET /MyRealmName' will redirect to '/remote/login?realm=MyRealmName'
+        */
+       for (realm = strchr(vpninfo->urlpath, '?'); realm && *++realm; realm=strchr(realm, '&')) {
+               if (!strncmp(realm, "realm=", 6)) {
+                       const char *end = strchr(realm+1, '&');
+                       realm = end ? strndup(realm+6, end-realm) : strdup(realm+6);
+                       vpn_progress(vpninfo, PRG_INFO, _("Got login realm '%s'\n"), realm);
+                       break;
+               }
+       }
+
        /* XX: Fortinet HTML forms *seem* like they should be about as easy to follow
         * as Juniper HTML forms, but some redirects use Javascript EXCLUSIVELY (no
         * 'Location' header). Also, a failed login returns the misleading HTTP status
@@ -145,7 +160,7 @@ int fortinet_obtain_cookie(struct openconnect_info *vpninfo)
 
                buf_truncate(resp_buf);
                append_form_opts(vpninfo, form, resp_buf);
-               append_opt(resp_buf, "realm", vpninfo->authgroup ?: "");
+               buf_append(resp_buf, "&realm=%s", realm ?: ""); /* XX: already URL-escaped */
 
                if (!form->action) {
                        /* "normal" form (fields 'username', 'credential') */
@@ -218,6 +233,7 @@ int fortinet_obtain_cookie(struct openconnect_info *vpninfo)
        }
 
  out:
+       free(realm);
        free(form_buf);
        if (form)
                free_auth_form(form);