Navigation Menu

Skip to content

Commit

Permalink
GP auth: give challenge/2FA forms a constant auth_id/name of "_challe…
Browse files Browse the repository at this point in the history
…nge"

Until now, we've been using the `inputStr` value (hex token that has to
accompany challenge form submission) as the `auth_id` for challenge forms,
but it appears these values aren't fixed from run-to-run, which makes it
impossible to use `--form-entry` to fill them out.

This patch makes all challenge forms have `auth_id=_challenge`, so they can
be filled with `--form-entry=_challenge:passwd=VALUE`. The `inputStr` value
will now be shoehorned into `form->action`.

Unless we find a GP VPN that uses multiple independent challenges (3FA?),
this should work better.

ping #112

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
  • Loading branch information
dlenski committed Apr 9, 2020
1 parent 9ec9c86 commit 593df6b
Showing 1 changed file with 18 additions and 16 deletions.
34 changes: 18 additions & 16 deletions auth-globalprotect.c
Expand Up @@ -60,13 +60,14 @@ const char *gpst_os_name(struct openconnect_info *vpninfo)
/* Parse pre-login response ({POST,GET} /{global-protect,ssl-vpn}/pre-login.esp)
*
* Extracts the relevant arguments from the XML (username-label, password-label)
* and uses them to build an auth form, which always has two visible fields:
* and uses them to build an auth form, which always has 2-3 fields:
*
* 1) username
* 1) username (hidden in challenge forms, since it's simply repeated)
* 2) one secret value:
* - normal account password
* - "challenge" (2FA) password, along with form name in auth_id
* - "challenge" (2FA) password
* - cookie from external authentication flow ("alternative secret" INSTEAD OF password)
* 3) inputStr for challenge form (shoehorned into form->action)
*
*/
static int parse_prelogin_xml(struct openconnect_info *vpninfo, xmlNode *xml_node, void *cb_data)
Expand Down Expand Up @@ -173,11 +174,10 @@ static int parse_prelogin_xml(struct openconnect_info *vpninfo, xmlNode *xml_nod
else
opt2->type = OC_FORM_OPT_PASSWORD;

vpn_progress(vpninfo, PRG_TRACE, "%s%s: \"%s\" %s(%s)=%s, \"%s\" %s(%s)\n",
form->auth_id[0] == '_' ? "Login form" : "Challenge form ",
form->auth_id[0] != '_' ? form->auth_id : "",
opt->label, opt->name, opt->type == OC_FORM_OPT_TEXT ? "TEXT" : "HIDDEN", opt->_value,
opt2->label, opt2->name, opt2->type == OC_FORM_OPT_PASSWORD ? "PASSWORD" : "TOKEN");
vpn_progress(vpninfo, PRG_TRACE, "Prelogin form %s: \"%s\" %s(%s)=%s, \"%s\" %s(%s)\n",
form->auth_id,
opt->label, opt->name, opt->type == OC_FORM_OPT_TEXT ? "TEXT" : "HIDDEN", opt->_value,
opt2->label, opt2->name, opt2->type == OC_FORM_OPT_PASSWORD ? "PASSWORD" : "TOKEN");

out:
free(prompt);
Expand All @@ -202,21 +202,23 @@ static int challenge_cb(struct openconnect_info *vpninfo, char *prompt, char *in
*/
free(form->message);
free(form->auth_id);
free(form->action);
free(opt2->label);
free(opt2->_value);
opt2->_value = NULL;
opt->type = OC_FORM_OPT_HIDDEN;

if ( !(form->message = strdup(prompt))
|| !(form->auth_id = strdup(inputStr))
|| !(form->action = strdup(inputStr))
|| !(form->auth_id = strdup("_challenge"))
|| !(opt2->label = strdup(_("Challenge: "))) )
return -ENOMEM;

vpn_progress(vpninfo, PRG_TRACE, "%s%s: \"%s\" %s(%s)=%s, \"%s\" %s(%s)\n",
form->auth_id[0] == '_' ? "Login form" : "Challenge form ",
form->auth_id[0] != '_' ? form->auth_id : "",
opt->label, opt->name, opt->type == OC_FORM_OPT_TEXT ? "TEXT" : "HIDDEN", opt->_value,
opt2->label, opt2->name, opt2->type == OC_FORM_OPT_PASSWORD ? "PASSWORD" : "TOKEN");
vpn_progress(vpninfo, PRG_TRACE, "Challenge form %s: \"%s\" %s(%s)=%s, \"%s\" %s(%s), inputStr=%s\n",
form->auth_id,
opt->label, opt->name, opt->type == OC_FORM_OPT_TEXT ? "TEXT" : "HIDDEN", opt->_value,
opt2->label, opt2->name, opt2->type == OC_FORM_OPT_PASSWORD ? "PASSWORD" : "TOKEN",
inputStr);

return -EAGAIN;
}
Expand Down Expand Up @@ -571,8 +573,8 @@ static int gpst_login(struct openconnect_info *vpninfo, int portal, struct login
append_opt(request_body, "computer", vpninfo->localname);
if (vpninfo->ip_info.addr)
append_opt(request_body, "preferred-ip", vpninfo->ip_info.addr);
if (ctx->form->auth_id && ctx->form->auth_id[0]!='_')
append_opt(request_body, "inputStr", ctx->form->auth_id);
if (ctx->form->action)
append_opt(request_body, "inputStr", ctx->form->action);
append_form_opts(vpninfo, ctx->form, request_body);
if ((result = buf_error(request_body)))
goto out;
Expand Down

0 comments on commit 593df6b

Please sign in to comment.