[PATCH/RFC V3 12/13] auth: Hide unused form fields based on the selected authgroup
Kevin Cernekee
cernekee at gmail.com
Sun Dec 15 01:43:03 EST 2013
Non-aggregate-auth servers have limited support for customizing the login
form based on which authgroup is currently selected. Selectively convert
text/password fields to hidden fields, based on the following attributes:
<input second-auth="1"> (for text/password fields)
<option (for authgroup options)
second-auth="1"
secondary_username="foo"
secondary_username_editable="true"
noaaa="1" >
Note that implementing secondary_username_editable can cause
libopenconnect to prepopulate the opt->value field, which may be blindly
overwritten (without freeing) by legacy clients. The other changes
should be backward-compatible, although they are not fully functional
on clients that do not implement OC_FORM_RESULT_NEWGROUP.
Signed-off-by: Kevin Cernekee <cernekee at gmail.com>
---
auth.c | 36 +++++++++++++++++++++++++++++++++---
1 file changed, 33 insertions(+), 3 deletions(-)
diff --git a/auth.c b/auth.c
index 6ff0b01..4f94df4 100644
--- a/auth.c
+++ b/auth.c
@@ -626,6 +626,8 @@ int process_auth_form(struct openconnect_info *vpninfo, struct __oc_auth_form *f
int ret;
struct __oc_form_opt *opt;
struct oc_form_opt **last;
+ struct __oc_form_opt_select *grp = form->authgroup_opt;
+ struct __oc_choice *auth_choice;
if (!vpninfo->process_auth_form) {
vpn_progress(vpninfo, PRG_ERR, _("No form handler; cannot authenticate.\n"));
@@ -633,6 +635,18 @@ int process_auth_form(struct openconnect_info *vpninfo, struct __oc_auth_form *f
}
retry:
+ auth_choice = NULL;
+ if (grp && grp->nr_choices && !vpninfo->xmlpost) {
+ if (vpninfo->authgroup) {
+ /* For non-XML-POST, the server doesn't tell us which group is selected */
+ int i;
+ for (i = 0; i < grp->nr_choices; i++)
+ if (!strcmp(grp->choices[i].u.name, vpninfo->authgroup))
+ form->u.authgroup_selection = i;
+ }
+ auth_choice = &grp->choices[form->u.authgroup_selection];
+ }
+
/* We have two parallel linked lists of form fields here:
form->u.opts is a linked list of user-visible oc_form_opt's
form->opts is a linked list of internally-visible __oc_form_opt's
@@ -647,10 +661,26 @@ retry:
continue;
*last = (struct oc_form_opt *)sopt->u;
last = &sopt->u->form.next;
- } else {
- *last = &opt->u;
- last = &opt->u.next;
+ continue;
+ } else if (!auth_choice) {
+ /* nothing left to check */
+ } else if (auth_choice->noaaa &&
+ (opt->u.type == OC_FORM_OPT_TEXT || opt->u.type == OC_FORM_OPT_PASSWORD)) {
+ /* nuke all text fields for noaaa groups */
+ continue;
+ } else if (!auth_choice->second_auth && opt->second_auth) {
+ /* hide second-auth fields if a non-second-auth group is selected */
+ continue;
+ } else if (!strcmp(opt->u.name, "secondary_username") && opt->second_auth) {
+ if (auth_choice->secondary_username) {
+ free(opt->u.value);
+ opt->u.value = strdup(auth_choice->secondary_username);
+ }
+ if (!auth_choice->secondary_username_editable)
+ continue;
}
+ *last = &opt->u;
+ last = &opt->u.next;
}
*last = NULL;
ret = vpninfo->process_auth_form(vpninfo->cbdata, &form->u);
--
1.7.9.5
More information about the openconnect-devel
mailing list