From 0303569d286d360da905b3c014daa99c65075524 Mon Sep 17 00:00:00 2001 From: Daniel Lenski Date: Wed, 8 Apr 2020 17:57:26 -0700 Subject: [PATCH] better heuristic for determining where to fill in a token in GP forms MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit GlobalProtect's prelogin doesn't give us much information to determine where a token code might be filled in. Current behavior: 1. Use the password file in the first form as a token field. 2. Ignores the fact that a second "challenge" form might be coming. New heuristic: 1. If the label for the password field in the first form has a non-default value (not empty or “Password”), then treat that as the token field. 2. Otherwise, assume a second form ("challenge") is coming, and treat the password field in the first form as a normal password, then treat the password field in the second form as the token field. Signed-off-by: Daniel Lenski --- auth-globalprotect.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/auth-globalprotect.c b/auth-globalprotect.c index a4a9b584..2843b1e0 100644 --- a/auth-globalprotect.c +++ b/auth-globalprotect.c @@ -168,8 +168,14 @@ static int parse_prelogin_xml(struct openconnect_info *vpninfo, xmlNode *xml_nod /* XX: Some VPNs use a password in the first form, followed by a * a token in the second ("challenge") form. Others use only a - * token. How can we distinguish these? */ - if (!can_gen_tokencode(vpninfo, form, opt2)) + * token. How can we distinguish these? + * + * Currently using the heuristic that a non-default label for the + * password in the first form means we should treat the first + * form's password as a token field. + */ + if (!can_gen_tokencode(vpninfo, form, opt2) && !ctx->alt_secret + && password_label && strcmp(password_label, "Password")) opt2->type = OC_FORM_OPT_TOKEN; else opt2->type = OC_FORM_OPT_PASSWORD; @@ -208,6 +214,19 @@ static int challenge_cb(struct openconnect_info *vpninfo, char *prompt, char *in opt2->_value = NULL; opt->type = OC_FORM_OPT_HIDDEN; + /* XX: Some VPNs use a password in the first form, followed by a + * a token in the second ("challenge") form. Others use only a + * token. How can we distinguish these? + * + * Currently using the heuristic that if the password field in + * the preceding form wasn't treated as a token field, treat this + * as a token field. + */ + if (!can_gen_tokencode(vpninfo, form, opt2) && opt2->type == OC_FORM_OPT_PASSWORD) + opt2->type = OC_FORM_OPT_TOKEN; + else + opt2->type = OC_FORM_OPT_PASSWORD; + if ( !(form->message = strdup(prompt)) || !(form->action = strdup(inputStr)) || !(form->auth_id = strdup("_challenge")) -- 2.50.1