Skip to content

Commit

Permalink
auth: Split auth form prompt logic from parsing logic
Browse files Browse the repository at this point in the history
Provide separate calls for parse_xml_response() and handle_auth_form(),
so that the ordering of events in openconnect_obtain_cookie() can be
modified.

Signed-off-by: Kevin Cernekee <cernekee@gmail.com>
  • Loading branch information
cernekee committed Oct 28, 2012
1 parent dbc605c commit b4e67f4
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 34 deletions.
75 changes: 46 additions & 29 deletions auth.c
Expand Up @@ -396,19 +396,18 @@ static int parse_auth_node(struct openconnect_info *vpninfo, xmlNode *xml_node,

/* Return value:
* < 0, on error
* = 0, when form parsed and POST required
* = 1, when response was cancelled by user
* = 2, when form indicates that login was already successful
* = 0, on success; *form is populated
*/
int parse_xml_response(struct openconnect_info *vpninfo, char *response,
char *request_body, int req_len, const char **method,
const char **request_body_type)
int parse_xml_response(struct openconnect_info *vpninfo, char *response, struct oc_auth_form **formp)
{
struct oc_auth_form *form;
xmlDocPtr xml_doc;
xmlNode *xml_node;
int ret;
struct vpn_option *opt, *next;

if (*formp) {
free_auth_form(*formp);
*formp = NULL;
}

form = calloc(1, sizeof(*form));
if (!form)
Expand All @@ -428,27 +427,44 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response,
if (xml_node->type != XML_ELEMENT_NODE || strcmp((char *)xml_node->name, "auth")) {
vpn_progress(vpninfo, PRG_ERR,
_("XML response has no \"auth\" root node\n"));
ret = -EINVAL;
goto out;
}

form->auth_id = (char *)xmlGetProp(xml_node, (unsigned char *)"id");
if (!strcmp(form->auth_id, "success")) {
ret = 2;
goto out;

if (parse_auth_node(vpninfo, xml_node, form) == 0) {
xmlFreeDoc(xml_doc);
*formp = form;
return 0;
}

out:
xmlFreeDoc(xml_doc);
free_auth_form(form);
return -EINVAL;
}

/* Return value:
* < 0, on error
* = 0, when form parsed and POST required
* = 1, when response was cancelled by user
* = 2, when form indicates that login was already successful
*/
int handle_auth_form(struct openconnect_info *vpninfo, struct oc_auth_form *form,
char *request_body, int req_len, const char **method,
const char **request_body_type)
{
int ret;
struct vpn_option *opt, *next;

if (!strcmp(form->auth_id, "success"))
return 2;

if (vpninfo->nopasswd) {
vpn_progress(vpninfo, PRG_ERR,
_("Asked for password but '--no-passwd' set\n"));
ret = -EPERM;
goto out;
return -EPERM;
}

ret = parse_auth_node(vpninfo, xml_node, form);
if (ret)
goto out;

if (vpninfo->csd_token && vpninfo->csd_ticket && vpninfo->csd_starturl && vpninfo->csd_waiturl) {
/* First, redirect to the stuburl -- we'll need to fetch and run that */
vpninfo->redirect_url = strdup(vpninfo->csd_stuburl);
Expand All @@ -462,17 +478,14 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response,
free(opt);
}
vpninfo->cookies = NULL;

ret = 0;
goto out;
return 0;
}
if (!form->opts) {
if (form->message)
vpn_progress(vpninfo, PRG_INFO, "%s\n", form->message);
if (form->error)
vpn_progress(vpninfo, PRG_ERR, "%s\n", form->error);
ret = -EPERM;
goto out;
return -EPERM;
}

if (vpninfo->process_auth_form)
Expand All @@ -482,20 +495,25 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response,
ret = 1;
}
if (ret)
goto out;
return ret;

/* tokencode generation is deferred until after username prompts and CSD */
ret = do_gen_tokencode(vpninfo, form);
if (ret)
goto out;
return ret;

ret = append_form_opts(vpninfo, form, request_body, req_len);
if (!ret) {
*method = "POST";
*request_body_type = "application/x-www-form-urlencoded";
}
out:
xmlFreeDoc(xml_doc);
return ret;
}

void free_auth_form(struct oc_auth_form *form)
{
if (!form)
return;
while (form->opts) {
struct oc_form_opt *tmp = form->opts->next;
if (form->opts->type == OC_FORM_OPT_TEXT ||
Expand Down Expand Up @@ -527,7 +545,6 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response,
free(form->method);
free(form->action);
free(form);
return ret;
}

#ifdef LIBSTOKEN_HDR
Expand Down
11 changes: 9 additions & 2 deletions http.c
Expand Up @@ -792,6 +792,7 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
struct vpn_option *opt;
struct oc_text_buf *buf;
char *form_buf = NULL;
struct oc_auth_form *form = NULL;
int result, buflen;
char request_body[2048];
const char *request_body_type = NULL;
Expand Down Expand Up @@ -900,9 +901,15 @@ int openconnect_obtain_cookie(struct openconnect_info *vpninfo)
free(form_buf);
return -EINVAL;
}
result = parse_xml_response(vpninfo, form_buf, &form);
if (result) {
free(form_buf);
return -ENOMEM;
}
request_body[0] = 0;
result = parse_xml_response(vpninfo, form_buf, request_body, sizeof(request_body),
&method, &request_body_type);
result = handle_auth_form(vpninfo, form, request_body, sizeof(request_body),
&method, &request_body_type);
free_auth_form(form);

if (!result)
goto redirect;
Expand Down
8 changes: 5 additions & 3 deletions openconnect-internal.h
Expand Up @@ -402,9 +402,11 @@ extern int killed;
int config_lookup_host(struct openconnect_info *vpninfo, const char *host);

/* auth.c */
int parse_xml_response(struct openconnect_info *vpninfo, char *response,
char *request_body, int req_len, const char **method,
const char **request_body_type);
int parse_xml_response(struct openconnect_info *vpninfo, char *response, struct oc_auth_form **form);
int handle_auth_form(struct openconnect_info *vpninfo, struct oc_auth_form *form,
char *request_body, int req_len, const char **method,
const char **request_body_type);
void free_auth_form(struct oc_auth_form *form);
int prepare_stoken(struct openconnect_info *vpninfo);

/* http.c */
Expand Down

0 comments on commit b4e67f4

Please sign in to comment.