From 33622138ada668c6b581496c330e928fcbd83f17 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Tue, 29 May 2012 15:01:02 +0100 Subject: [PATCH] Move basic process_auth_form() out to main.c There's no need for it to be in the library, and it uses OpenSSL UI. Signed-off-by: David Woodhouse --- auth.c | 186 ++-------------------------------------------------------- main.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ openconnect.h | 7 ++- 3 files changed, 193 insertions(+), 183 deletions(-) diff --git a/auth.c b/auth.c index 82974e8..d17a318 100644 --- a/auth.c +++ b/auth.c @@ -251,9 +251,6 @@ static int parse_form(struct openconnect_info *vpninfo, struct oc_auth_form *for return 0; } -static int process_auth_form(struct openconnect_info *vpninfo, - struct oc_auth_form *form); - static char *xmlnode_msg(xmlNode *xml_node) { char *fmt = (char *)xmlNodeGetContent(xml_node); @@ -437,8 +434,10 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response, if (vpninfo->process_auth_form) ret = vpninfo->process_auth_form(vpninfo->cbdata, form); - else - ret = process_auth_form(vpninfo, form); + else { + vpn_progress(vpninfo, PRG_ERR, _("No form handler; cannot authentiate.")); + ret = 1; + } if (ret) goto out; @@ -484,180 +483,3 @@ int parse_xml_response(struct openconnect_info *vpninfo, char *response, -/* Return value: - * < 0, on error - * = 0, when form was parsed and POST required - * = 1, when response was cancelled by user - */ -static int process_auth_form(struct openconnect_info *vpninfo, - struct oc_auth_form *form) -{ - UI *ui = UI_new(); - char banner_buf[1024], msg_buf[1024], err_buf[1024]; - char choice_prompt[1024], choice_resp[80]; - int ret = 0, input_count=0; - struct oc_form_opt *opt; - struct oc_form_opt_select *select_opt = NULL; - - choice_resp[0] = 0; - - if (!ui) { - vpn_progress(vpninfo, PRG_ERR, _("Failed to create UI\n")); - return -EINVAL; - } - if (form->banner) { - banner_buf[1023] = 0; - snprintf(banner_buf, 1023, "%s\n", form->banner); - UI_add_info_string(ui, banner_buf); - } - if (form->error) { - err_buf[1023] = 0; - snprintf(err_buf, 1023, "%s\n", form->error); - UI_add_error_string(ui, err_buf); - } - if (form->message) { - msg_buf[1023] = 0; - snprintf(msg_buf, 1023, "%s\n", form->message); - UI_add_info_string(ui, msg_buf); - } - - /* scan for select options first so they are displayed first */ - for (opt = form->opts; opt; opt = opt->next) { - if (opt->type == OC_FORM_OPT_SELECT) { - struct oc_choice *choice = NULL; - int i; - - select_opt = (void *)opt; - - if (!select_opt->nr_choices) - continue; - - if (vpninfo->authgroup && - !strcmp(opt->name, "group_list")) { - for (i = 0; i < select_opt->nr_choices; i++) { - choice = &select_opt->choices[i]; - - if (!strcmp(vpninfo->authgroup, - choice->label)) { - opt->value = choice->name; - break; - } - } - if (!opt->value) - vpn_progress(vpninfo, PRG_ERR, - _("Auth choice \"%s\" not available\n"), - vpninfo->authgroup); - } - if (!opt->value && select_opt->nr_choices == 1) { - choice = &select_opt->choices[0]; - opt->value = choice->name; - } - if (opt->value) { - select_opt = NULL; - continue; - } - snprintf(choice_prompt, 1023, "%s [", opt->label); - for (i = 0; i < select_opt->nr_choices; i++) { - choice = &select_opt->choices[i]; - if (i) - strncat(choice_prompt, "|", 1023 - strlen(choice_prompt)); - - strncat(choice_prompt, choice->label, 1023 - strlen(choice_prompt)); - } - strncat(choice_prompt, "]:", 1023 - strlen(choice_prompt)); - - UI_add_input_string(ui, choice_prompt, UI_INPUT_FLAG_ECHO, choice_resp, 1, 80); - input_count++; - } - } - - for (opt = form->opts; opt; opt = opt->next) { - - if (opt->type == OC_FORM_OPT_TEXT) { - if (vpninfo->username && - !strcmp(opt->name, "username")) { - opt->value = strdup(vpninfo->username); - if (!opt->value) { - ret = -ENOMEM; - goto out_ui; - } - } else { - opt->value=malloc(80); - if (!opt->value) { - ret = -ENOMEM; - goto out_ui; - } - UI_add_input_string(ui, opt->label, UI_INPUT_FLAG_ECHO, opt->value, 1, 80); - input_count++; - } - - } else if (opt->type == OC_FORM_OPT_PASSWORD) { - if (vpninfo->password && - !strcmp(opt->name, "password")) { - opt->value = strdup(vpninfo->password); - vpninfo->password = NULL; - if (!opt->value) { - ret = -ENOMEM; - goto out_ui; - } - } else { - opt->value=malloc(80); - if (!opt->value) { - ret = -ENOMEM; - goto out_ui; - } - UI_add_input_string(ui, opt->label, 0, opt->value, 1, 80); - input_count++; - } - - } - } - - if (!input_count) { - ret = 0; - goto out_ui; - } - - switch (UI_process(ui)) { - case -2: - /* cancelled */ - ret = 1; - goto out_ui; - case -1: - /* error */ - vpn_progress(vpninfo, PRG_ERR, _("Invalid inputs\n")); - ret = -EINVAL; - out_ui: - UI_free(ui); - return ret; - } - - UI_free(ui); - - if (select_opt) { - struct oc_choice *choice = NULL; - int i; - - for (i = 0; i < select_opt->nr_choices; i++) { - choice = &select_opt->choices[i]; - - if (!strcmp(choice_resp, choice->label)) { - select_opt->form.value = choice->name; - break; - } - } - if (!select_opt->form.value) { - vpn_progress(vpninfo, PRG_ERR, - _("Auth choice \"%s\" not valid\n"), - choice_resp); - return -EINVAL; - } - } - - if (vpninfo->password) { - free(vpninfo->password); - vpninfo->password = NULL; - } - - return 0; -} diff --git a/main.c b/main.c index 700bd8f..e0d2033 100644 --- a/main.c +++ b/main.c @@ -64,6 +64,8 @@ static void syslog_progress(void *_vpninfo, int level, const char *fmt, ...); static int validate_peer_cert(void *_vpninfo, X509 *peer_cert, const char *reason); +static int process_auth_form(void *_vpninfo, + struct oc_auth_form *form); /* A sanity check that the openconnect executable is running against a library of the same version */ @@ -421,6 +423,7 @@ int main(int argc, char **argv) vpninfo->uid_csd = 0; vpninfo->uid_csd_given = 0; vpninfo->validate_peer_cert = validate_peer_cert; + vpninfo->process_auth_form = process_auth_form; vpninfo->cbdata = vpninfo; vpninfo->cert_expire_warning = 60 * 86400; vpninfo->vpnc_script = DEFAULT_VPNCSCRIPT; @@ -948,3 +951,183 @@ static int validate_peer_cert(void *_vpninfo, X509 *peer_cert, } } + + +/* Return value: + * < 0, on error + * = 0, when form was parsed and POST required + * = 1, when response was cancelled by user + */ +static int process_auth_form(void *_vpninfo, + struct oc_auth_form *form) +{ + struct openconnect_info *vpninfo = _vpninfo; + UI *ui = UI_new(); + char banner_buf[1024], msg_buf[1024], err_buf[1024]; + char choice_prompt[1024], choice_resp[80]; + int ret = 0, input_count=0; + struct oc_form_opt *opt; + struct oc_form_opt_select *select_opt = NULL; + + choice_resp[0] = 0; + + if (!ui) { + vpn_progress(vpninfo, PRG_ERR, _("Failed to create UI\n")); + return -EINVAL; + } + if (form->banner) { + banner_buf[1023] = 0; + snprintf(banner_buf, 1023, "%s\n", form->banner); + UI_add_info_string(ui, banner_buf); + } + if (form->error) { + err_buf[1023] = 0; + snprintf(err_buf, 1023, "%s\n", form->error); + UI_add_error_string(ui, err_buf); + } + if (form->message) { + msg_buf[1023] = 0; + snprintf(msg_buf, 1023, "%s\n", form->message); + UI_add_info_string(ui, msg_buf); + } + + /* scan for select options first so they are displayed first */ + for (opt = form->opts; opt; opt = opt->next) { + if (opt->type == OC_FORM_OPT_SELECT) { + struct oc_choice *choice = NULL; + int i; + + select_opt = (void *)opt; + + if (!select_opt->nr_choices) + continue; + + if (vpninfo->authgroup && + !strcmp(opt->name, "group_list")) { + for (i = 0; i < select_opt->nr_choices; i++) { + choice = &select_opt->choices[i]; + + if (!strcmp(vpninfo->authgroup, + choice->label)) { + opt->value = choice->name; + break; + } + } + if (!opt->value) + vpn_progress(vpninfo, PRG_ERR, + _("Auth choice \"%s\" not available\n"), + vpninfo->authgroup); + } + if (!opt->value && select_opt->nr_choices == 1) { + choice = &select_opt->choices[0]; + opt->value = choice->name; + } + if (opt->value) { + select_opt = NULL; + continue; + } + snprintf(choice_prompt, 1023, "%s [", opt->label); + for (i = 0; i < select_opt->nr_choices; i++) { + choice = &select_opt->choices[i]; + if (i) + strncat(choice_prompt, "|", 1023 - strlen(choice_prompt)); + + strncat(choice_prompt, choice->label, 1023 - strlen(choice_prompt)); + } + strncat(choice_prompt, "]:", 1023 - strlen(choice_prompt)); + + UI_add_input_string(ui, choice_prompt, UI_INPUT_FLAG_ECHO, choice_resp, 1, 80); + input_count++; + } + } + + for (opt = form->opts; opt; opt = opt->next) { + + if (opt->type == OC_FORM_OPT_TEXT) { + if (vpninfo->username && + !strcmp(opt->name, "username")) { + opt->value = strdup(vpninfo->username); + if (!opt->value) { + ret = -ENOMEM; + goto out_ui; + } + } else { + opt->value=malloc(80); + if (!opt->value) { + ret = -ENOMEM; + goto out_ui; + } + UI_add_input_string(ui, opt->label, UI_INPUT_FLAG_ECHO, opt->value, 1, 80); + input_count++; + } + + } else if (opt->type == OC_FORM_OPT_PASSWORD) { + if (vpninfo->password && + !strcmp(opt->name, "password")) { + opt->value = strdup(vpninfo->password); + vpninfo->password = NULL; + if (!opt->value) { + ret = -ENOMEM; + goto out_ui; + } + } else { + opt->value=malloc(80); + if (!opt->value) { + ret = -ENOMEM; + goto out_ui; + } + UI_add_input_string(ui, opt->label, 0, opt->value, 1, 80); + input_count++; + } + + } + } + + if (!input_count) { + ret = 0; + goto out_ui; + } + + switch (UI_process(ui)) { + case -2: + /* cancelled */ + ret = 1; + goto out_ui; + case -1: + /* error */ + vpn_progress(vpninfo, PRG_ERR, _("Invalid inputs\n")); + ret = -EINVAL; + out_ui: + UI_free(ui); + return ret; + } + + UI_free(ui); + + if (select_opt) { + struct oc_choice *choice = NULL; + int i; + + for (i = 0; i < select_opt->nr_choices; i++) { + choice = &select_opt->choices[i]; + + if (!strcmp(choice_resp, choice->label)) { + select_opt->form.value = choice->name; + break; + } + } + if (!select_opt->form.value) { + vpn_progress(vpninfo, PRG_ERR, + _("Auth choice \"%s\" not valid\n"), + choice_resp); + return -EINVAL; + } + } + + if (vpninfo->password) { + free(vpninfo->password); + vpninfo->password = NULL; + } + + return 0; +} diff --git a/openconnect.h b/openconnect.h index 18274ff..1d4e723 100644 --- a/openconnect.h +++ b/openconnect.h @@ -201,7 +201,12 @@ typedef int (*openconnect_validate_peer_cert_vfn) (void *privdata, then the new XML is downloaded and this function is invoked. */ typedef int (*openconnect_write_new_config_vfn) (void *privdata, char *buf, int buflen); -/* Handle an authentication form, requesting input from the user. */ +/* Handle an authentication form, requesting input from the user. + * Return value: + * < 0, on error + * = 0, when form was parsed and POST required + * = 1, when response was cancelled by user + */ typedef int (*openconnect_process_auth_form_vfn) (void *privdata, struct oc_auth_form *form); /* Logging output which the user *may* want to see. */ -- 2.7.4