Can't connect to Juniper VPN because: "Unknown form ID 'frmSelectRoles'"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2016-07-19 at 14:08 -0600, Benjamin Cardon wrote:
> Attached is a scrubbed for session values version of the select roles
> page.

Try this please. Should work both on the command line and from
NetworkManager. I'll clean it up a little if it's working. Mostly based
on?Hillel's original HTML parsing code.

diff --git a/auth-juniper.c b/auth-juniper.c
index a037ffa..6729807 100644
--- a/auth-juniper.c
+++ b/auth-juniper.c
@@ -456,6 +456,106 @@ static int tncc_preauth(struct openconnect_info *vpninfo)
?}
?#endif
?
+static struct oc_auth_form *parse_roles_table_node(xmlNodePtr node)
+{
+	struct oc_auth_form *form;
+	xmlNodePtr table_itr;
+	xmlNodePtr row_itr;
+	xmlNodePtr data_itr;
+	struct oc_form_opt_select *opt;
+	struct oc_choice *choice;
+
+
+	form = calloc(1, sizeof(*form));
+	if (!form)
+		return NULL;
+
+	opt = calloc(1, sizeof(*opt));
+	if (!opt) {
+		free(form);
+		return NULL;
+	}
+
+	form->opts = &opt->form;
+	opt->form.label = strdup("frmSelectRoles");
+	opt->form.name = strdup("frmSelectRoles");
+	opt->form.type = OC_FORM_OPT_SELECT;
+
+	for (table_itr = node->children; table_itr; table_itr = table_itr->next) {
+		if (!table_itr->name || strcasecmp((const char *)table_itr->name, "tr"))
+			continue;
+		for (row_itr = table_itr->children; row_itr; row_itr = row_itr->next) {
+			if (!row_itr->name || strcasecmp((const char *)row_itr->name, "td"))
+				continue;
+			for (data_itr = row_itr->children; data_itr; data_itr = data_itr->next) {
+				struct oc_choice **new_choices;
+				char *role_link = NULL;
+				char *role_name = NULL;
+
+				if (!data_itr->name || strcasecmp((const char *)data_itr->name, "a"))
+					continue;
+
+				// Discovered <a> tag with role selection.
+				role_link = (char *)xmlGetProp(data_itr, (unsigned char *)"href");
+				if (!role_link) continue;
+
+				role_name = (char *)xmlNodeGetContent(data_itr);
+				if (!role_name) {
+					// some weird case?
+					free(role_link);
+					continue;
+				}
+
+				choice = calloc(1, sizeof(*choice));
+				if (!choice) {
+					free_auth_form(form);
+					return NULL;
+				}
+
+				choice->label = role_name;
+				choice->name = role_link;
+				new_choices = realloc(opt->choices, sizeof(opt->choices[0]) * (opt->nr_choices+1));
+				if (!new_choices) {
+					free(choice);
+					free_auth_form(form);
+					return NULL;
+				}
+				opt->choices = new_choices;
+				opt->choices[opt->nr_choices++] = choice;
+			}
+		}
+	}
+
+	return form;
+}
+
+static struct oc_auth_form *parse_roles_form_node(xmlNodePtr node)
+{
+	struct oc_auth_form *form;
+	xmlNodePtr child;
+
+	// Set form->action here as a redirect url with keys and ids.
+	for (child = htmlnode_next(node, node); child && child != node; child = htmlnode_next(node, child)) {
+		if (!child->name)
+			continue;
+
+		if (!strcasecmp((char *)child->name, "table")) {
+			char *table_id = (char *)xmlGetProp(child, (unsigned char *)"id");
+
+			if (table_id) {
+				if (!strcmp(table_id, "TABLE_SelectRole_1"))
+					form = parse_roles_table_node(child);
+
+				free(table_id);
+
+				if (form) break; // Redirect URL was constructed
+			}
+		}
+	}
+
+	return form;
+}
+
?int oncp_obtain_cookie(struct openconnect_info *vpninfo)
?{
?	int ret;
@@ -472,6 +572,7 @@ int oncp_obtain_cookie(struct openconnect_info *vpninfo)
?
?	while (1) {
?		char *form_buf = NULL;
+		int role_select = 0;
?		struct oc_text_buf *url;
?
?		if (resp_buf && resp_buf->pos)
@@ -560,6 +661,13 @@ int oncp_obtain_cookie(struct openconnect_info *vpninfo)
?			}
?			/* XXX: Actually ask the user? */
?			goto form_done;
+		} else if (!strcmp(form_id, "frmSelectRoles")) {
+			form = parse_roles_form_node(node);
+			if (!form) {
+				ret = -EINVAL;
+				break;
+			}
+			role_select = 1;
?		} else {
?			vpn_progress(vpninfo, PRG_ERR,
?				?????_("Unknown form ID '%s'\n"),
@@ -584,6 +692,10 @@ int oncp_obtain_cookie(struct openconnect_info *vpninfo)
?			goto out;
?		}
?
+		if (role_select) {
+			vpninfo->redirect_url = strdup(form->opts[0]._value);
+			goto do_redirect;
+		}
?	form_done:
?		append_form_opts(vpninfo, form, resp_buf);
?		ret = buf_error(resp_buf);
@@ -592,6 +704,7 @@ int oncp_obtain_cookie(struct openconnect_info *vpninfo)
?
?		vpninfo->redirect_url = form->action;
?		form->action = NULL;
+	do_redirect:
?		free_auth_form(form);
?		form = NULL;
?		handle_redirect(vpninfo);
-- 
David Woodhouse                            Open Source Technology Centre
David.Woodhouse at intel.com                              Intel Corporation

-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5760 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/openconnect-devel/attachments/20160719/e3a0bb09/attachment.bin>


[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux