Commit 8b2bc5f2 authored by Daniel Lenski's avatar Daniel Lenski Committed by David Woodhouse

Allow specification of an "alternative secret" field for GP login form(s), instead of 'passwd'.

The alternative field is specified by appending :FIELDNAME to the URL path, or --usergroup.

Known use cases:

	openconnect --protocol=gp vpn.bigcorp.com --usergroup=gateway:prelogin-cookie
	openconnect --protocol=gp vpn.bigcorp.com --usergroup=portal:portal-userauthcookie
Signed-off-by: default avatarDaniel Lenski <dlenski@gmail.com>
Signed-off-by: default avatarDavid Woodhouse <dwmw2@infradead.org>
parent 78091bbc
......@@ -40,12 +40,13 @@ void gpst_common_headers(struct openconnect_info *vpninfo,
* 2) one secret value:
* - normal account password
* - "challenge" (2FA) password, along with form name in auth_id
* - cookie from external authentication flow (INSTEAD OF password)
*
* This function steals the value of auth_id and prompt and username for
* use in the auth form.
* use in the auth form; pw_or_cookie_field is NOT stolen.
*/
static struct oc_auth_form *auth_form(struct openconnect_info *vpninfo,
char *prompt, char *auth_id, char *username)
char *prompt, char *auth_id, char *username, char *pw_or_cookie_field)
{
struct oc_auth_form *form;
struct oc_form_opt *opt, *opt2;
......@@ -70,8 +71,9 @@ static struct oc_auth_form *auth_form(struct openconnect_info *vpninfo,
opt2 = opt->next = calloc(1, sizeof(*opt));
if (!opt2)
goto nomem;
opt2->name = strdup("passwd");
opt2->label = auth_id ? strdup(_("Challenge: ")) : strdup(_("Password: "));
opt2->name = strdup(pw_or_cookie_field ? : "passwd");
if (asprintf(&opt2->label, "%s: ", auth_id ? _("Challenge") : (pw_or_cookie_field ? : _("Password"))) == 0)
return NULL;
/* XX: Some VPNs use a password in the first form, followed by a
* a token in the second ("challenge") form. Others use only a
......@@ -316,7 +318,7 @@ out:
return result;
}
static int gpst_login(struct openconnect_info *vpninfo, int portal)
static int gpst_login(struct openconnect_info *vpninfo, int portal, char *pw_or_cookie_field)
{
int result;
......@@ -335,7 +337,7 @@ static int gpst_login(struct openconnect_info *vpninfo, int portal)
}
#endif
form = auth_form(vpninfo, prompt, NULL, NULL);
form = auth_form(vpninfo, prompt, NULL, NULL, pw_or_cookie_field);
if (!form)
return -ENOMEM;
......@@ -389,7 +391,7 @@ static int gpst_login(struct openconnect_info *vpninfo, int portal)
char *username = form->opts ? form->opts->_value : NULL;
form->opts->_value = NULL;
free_auth_form(form);
form = auth_form(vpninfo, prompt, auth_id, username);
form = auth_form(vpninfo, prompt, auth_id, username, pw_or_cookie_field);
if (!form)
return -ENOMEM;
} else if (portal && result == 0) {
......@@ -412,21 +414,32 @@ out:
int gpst_obtain_cookie(struct openconnect_info *vpninfo)
{
char *pw_or_cookie_field = NULL;
int result;
/* An alternate password/secret field may be specified in the "URL path". Known possibilities:
* /portal:portal-userauthcookie
* /gateway:prelogin-cookie
*/
if (vpninfo->urlpath
&& (pw_or_cookie_field = strrchr(vpninfo->urlpath, ':'))!=NULL) {
*pw_or_cookie_field = '\0';
pw_or_cookie_field++;
}
if (vpninfo->urlpath && (!strcmp(vpninfo->urlpath, "portal") || !strncmp(vpninfo->urlpath, "global-protect", 14))) {
/* assume the server is a portal */
return gpst_login(vpninfo, 1);
return gpst_login(vpninfo, 1, pw_or_cookie_field);
} else if (vpninfo->urlpath && (!strcmp(vpninfo->urlpath, "gateway") || !strncmp(vpninfo->urlpath, "ssl-vpn", 7))) {
/* assume the server is a gateway */
return gpst_login(vpninfo, 0);
return gpst_login(vpninfo, 0, pw_or_cookie_field);
} else {
/* first try handling it as a gateway, then a portal */
result = gpst_login(vpninfo, 0);
result = gpst_login(vpninfo, 0, pw_or_cookie_field);
if (result == -EEXIST) {
/* XX: Don't we want to start by trying the same username/password the user just
entered for the 'gateway' attempt? */
result = gpst_login(vpninfo, 1);
result = gpst_login(vpninfo, 1, pw_or_cookie_field);
if (result == -EEXIST)
vpn_progress(vpninfo, PRG_ERR, _("Server is neither a GlobalProtect portal nor a gateway.\n"));
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment