[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