[PATCH/RFC V3 09/13] process_auth_form: Add code to support NEWGROUP return status from UI
Kevin Cernekee
cernekee at gmail.com
Sun Dec 15 01:43:00 EST 2013
In order to support refreshing the <opaque> data (XML POST) or the
secondary_* fields (non XML POST) on the auth form, it is necessary for
the process_auth_form() callback to return to libopenconnect to refresh
the form fields whenever the user changes the value of a <select>
dropdown.
This change should not break existing implementations.
Signed-off-by: Kevin Cernekee <cernekee at gmail.com>
---
auth.c | 12 ++++++++++++
http.c | 8 ++++++++
library.c | 1 +
main.c | 9 ++++++---
openconnect.h | 1 +
5 files changed, 28 insertions(+), 3 deletions(-)
diff --git a/auth.c b/auth.c
index 2b08403..7c95037 100644
--- a/auth.c
+++ b/auth.c
@@ -631,6 +631,7 @@ int process_auth_form(struct openconnect_info *vpninfo, struct __oc_auth_form *f
return OC_FORM_RESULT_ERR;
}
+retry:
/* 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
@@ -661,6 +662,17 @@ int process_auth_form(struct openconnect_info *vpninfo, struct __oc_auth_form *f
sopt->u = NULL;
}
}
+
+ if (ret == OC_FORM_RESULT_NEWGROUP &&
+ form->authgroup_opt &&
+ form->authgroup_opt->form.u.value) {
+ free(vpninfo->authgroup);
+ vpninfo->authgroup = strdup(form->authgroup_opt->form.u.value);
+
+ if (!vpninfo->xmlpost)
+ goto retry;
+ }
+
return ret;
}
diff --git a/http.c b/http.c
index 4f85f8a..f66acf5 100644
--- a/http.c
+++ b/http.c
@@ -1025,6 +1025,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
* b) Same-host redirect (e.g. Location: /foo/bar)
* c) Three redirects without seeing a plausible login form
*/
+newgroup:
result = xmlpost_initial_req(vpninfo, request_body, sizeof(request_body), 0);
if (result < 0)
return result;
@@ -1185,6 +1186,13 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
goto out;
if (result == __OC_FORM_RESULT_LOGGEDIN)
break;
+ if (result == OC_FORM_RESULT_NEWGROUP) {
+ free(form_buf);
+ form_buf = NULL;
+ free_auth_form(form);
+ form = NULL;
+ goto newgroup;
+ }
result = do_https_request(vpninfo, method, request_body_type, request_body,
&form_buf, 1);
diff --git a/library.c b/library.c
index 66bf89b..e1bd0f2 100644
--- a/library.c
+++ b/library.c
@@ -145,6 +145,7 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo)
vpninfo->peer_cert = NULL;
}
free(vpninfo->useragent);
+ free(vpninfo->authgroup);
#ifdef HAVE_LIBSTOKEN
if (vpninfo->stoken_pin)
free(vpninfo->stoken_pin);
diff --git a/main.c b/main.c
index b7ccb1f..c9a3fa4 100644
--- a/main.c
+++ b/main.c
@@ -1105,13 +1105,12 @@ static int process_auth_form_cb(void *_vpninfo,
if (opt->type == OC_FORM_OPT_SELECT) {
struct oc_form_opt_select *select_opt = (void *)opt;
struct oc_choice *choice = NULL;
- int i;
+ int i, is_group_list = form->authgroup_field && !strcmp(opt->name, form->authgroup_field);
if (!select_opt->nr_choices)
continue;
- if (authgroup &&
- !strcmp(opt->name, "group_list")) {
+ if (authgroup && is_group_list) {
for (i = 0; i < select_opt->nr_choices; i++) {
choice = &select_opt->choices[i];
@@ -1158,9 +1157,13 @@ static int process_auth_form_cb(void *_vpninfo,
for (i = 0; i < select_opt->nr_choices; i++) {
choice = &select_opt->choices[i];
+ select_opt->form.value = choice->name;
if (!strcmp(response, choice->label)) {
select_opt->form.value = choice->name;
+ authgroup = strdup(choice->label);
+ if (is_group_list)
+ return OC_FORM_RESULT_NEWGROUP;
break;
}
}
diff --git a/openconnect.h b/openconnect.h
index 18d31ae..97747ff 100644
--- a/openconnect.h
+++ b/openconnect.h
@@ -96,6 +96,7 @@
#define OC_FORM_RESULT_ERR -1
#define OC_FORM_RESULT_OK 0
#define OC_FORM_RESULT_CANCELLED 1
+#define OC_FORM_RESULT_NEWGROUP 2
#define __OC_FORM_RESULT_LOGGEDIN 255 /* internal library use only */
/* char * fields are static (owned by XML parser) and don't need to be
--
1.7.9.5
More information about the openconnect-devel
mailing list