Commit 50b6c522 authored by David Woodhouse's avatar David Woodhouse

Allow automatic OATH for Juniper

Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent bf937a6a
......@@ -133,3 +133,66 @@ void free_auth_form(struct oc_auth_form *form)
free(form->action);
free(form);
}
/* Return value:
* < 0, if unable to generate a tokencode
* = 0, on success
*/
int do_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form)
{
struct oc_form_opt *opt;
for (opt = form->opts; ; opt = opt->next) {
/* this form might not have anything for us to do */
if (!opt)
return 0;
if (opt->type == OC_FORM_OPT_TOKEN)
break;
}
switch (vpninfo->token_mode) {
#ifdef HAVE_LIBSTOKEN
case OC_TOKEN_MODE_STOKEN:
return do_gen_stoken_code(vpninfo, form, opt);
#endif
#ifdef HAVE_LIBOATH
case OC_TOKEN_MODE_TOTP:
return do_gen_totp_code(vpninfo, form, opt);
case OC_TOKEN_MODE_HOTP:
return do_gen_hotp_code(vpninfo, form, opt);
#endif
#ifdef HAVE_LIBPCSCLITE
case OC_TOKEN_MODE_YUBIOATH:
return do_gen_yubikey_code(vpninfo, form, opt);
#endif
default:
return -EINVAL;
}
}
int can_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form,
struct oc_form_opt *opt)
{
switch (vpninfo->token_mode) {
#ifdef HAVE_LIBSTOKEN
case OC_TOKEN_MODE_STOKEN:
return can_gen_stoken_code(vpninfo, form, opt);
#endif
#ifdef HAVE_LIBOATH
case OC_TOKEN_MODE_TOTP:
return can_gen_totp_code(vpninfo, form, opt);
case OC_TOKEN_MODE_HOTP:
return can_gen_hotp_code(vpninfo, form, opt);
#endif
#ifdef HAVE_LIBPCSCLITE
case OC_TOKEN_MODE_YUBIOATH:
return can_gen_yubikey_code(vpninfo, form, opt);
#endif
default:
return -EINVAL;
}
}
......@@ -42,9 +42,9 @@
static int xmlpost_append_form_opts(struct openconnect_info *vpninfo,
struct oc_auth_form *form, struct oc_text_buf *body);
static int can_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form, struct oc_form_opt *opt);
static int do_gen_tokencode(struct openconnect_info *vpninfo, struct oc_auth_form *form);
static int cstp_can_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form,
struct oc_form_opt *opt);
int openconnect_set_option_value(struct oc_form_opt *opt, const char *value)
{
......@@ -223,7 +223,7 @@ static int parse_form(struct openconnect_info *vpninfo, struct oc_auth_form *for
} else if (!strcmp(input_type, "text")) {
opt->type = OC_FORM_OPT_TEXT;
} else if (!strcmp(input_type, "password")) {
if (!can_gen_tokencode(vpninfo, form, opt))
if (!cstp_can_gen_tokencode(vpninfo, form, opt))
opt->type = OC_FORM_OPT_TOKEN;
else
opt->type = OC_FORM_OPT_PASSWORD;
......@@ -873,9 +873,9 @@ bad:
* < 0, if unable to generate a tokencode
* = 0, on success
*/
static int can_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form,
struct oc_form_opt *opt)
static int cstp_can_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form,
struct oc_form_opt *opt)
{
if (vpninfo->token_mode == OC_TOKEN_MODE_NONE ||
vpninfo->token_bypassed)
......@@ -892,59 +892,8 @@ static int can_gen_tokencode(struct openconnect_info *vpninfo,
/* Otherwise it's an OATH token of some kind. */
if (strcmp(opt->name, "secondary_password"))
return -EINVAL;
switch (vpninfo->token_mode) {
#ifdef HAVE_LIBOATH
case OC_TOKEN_MODE_TOTP:
return can_gen_totp_code(vpninfo, form, opt);
case OC_TOKEN_MODE_HOTP:
return can_gen_hotp_code(vpninfo, form, opt);
#endif
#ifdef HAVE_LIBPCSCLITE
case OC_TOKEN_MODE_YUBIOATH:
return can_gen_yubikey_code(vpninfo, form, opt);
#endif
default:
return -EINVAL;
}
}
/* Return value:
* < 0, if unable to generate a tokencode
* = 0, on success
*/
static int do_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form)
{
struct oc_form_opt *opt;
for (opt = form->opts; ; opt = opt->next) {
/* this form might not have anything for us to do */
if (!opt)
return 0;
if (opt->type == OC_FORM_OPT_TOKEN)
break;
}
switch (vpninfo->token_mode) {
#ifdef HAVE_LIBSTOKEN
case OC_TOKEN_MODE_STOKEN:
return do_gen_stoken_code(vpninfo, form, opt);
#endif
#ifdef HAVE_LIBOATH
case OC_TOKEN_MODE_TOTP:
return do_gen_totp_code(vpninfo, form, opt);
case OC_TOKEN_MODE_HOTP:
return do_gen_hotp_code(vpninfo, form, opt);
#endif
#ifdef HAVE_LIBPCSCLITE
case OC_TOKEN_MODE_YUBIOATH:
return do_gen_yubikey_code(vpninfo, form, opt);
#endif
default:
return -EINVAL;
}
return can_gen_tokencode(vpninfo, form, opt);
}
static int fetch_config(struct openconnect_info *vpninfo)
......
......@@ -66,6 +66,35 @@ static xmlNodePtr htmlnode_next(xmlNodePtr top, xmlNodePtr node)
return node->next;
}
static int oncp_can_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form,
struct oc_form_opt *opt)
{
if (vpninfo->token_mode == OC_TOKEN_MODE_NONE ||
vpninfo->token_bypassed)
return -EINVAL;
if (strcmp(form->auth_id, "frmDefender") &&
strcmp(form->auth_id, "frmNextToken"))
return -EINVAL;
switch (vpninfo->token_mode) {
#ifdef HAVE_LIBOATH
case OC_TOKEN_MODE_TOTP:
return can_gen_totp_code(vpninfo, form, opt);
case OC_TOKEN_MODE_HOTP:
return can_gen_hotp_code(vpninfo, form, opt);
#endif
#ifdef HAVE_LIBPCSCLITE
case OC_TOKEN_MODE_YUBIOATH:
return can_gen_yubikey_code(vpninfo, form, opt);
#endif
default:
return -EINVAL;
}
}
static int parse_input_node(struct openconnect_info *vpninfo, struct oc_auth_form *form,
xmlNodePtr node, const char *submit_button)
{
......@@ -89,6 +118,8 @@ static int parse_input_node(struct openconnect_info *vpninfo, struct oc_auth_for
opt->type = OC_FORM_OPT_PASSWORD;
xmlnode_get_prop(node, "name", &opt->name);
asprintf(&opt->label, "%s:", opt->name);
if (!oncp_can_gen_tokencode(vpninfo, form, opt))
opt->type = OC_FORM_OPT_TOKEN;
} else if (!strcasecmp(type, "text")) {
opt->type = OC_FORM_OPT_TEXT;
xmlnode_get_prop(node, "name", &opt->name);
......@@ -508,6 +539,13 @@ int oncp_obtain_cookie(struct openconnect_info *vpninfo)
if (ret)
goto out;
ret = do_gen_tokencode(vpninfo, form);
if (ret) {
vpn_progress(vpninfo, PRG_ERR, _("Failed to generate OTP tokencode; disabling token\n"));
vpninfo->token_bypassed = 1;
goto out;
}
form_done:
append_form_opts(vpninfo, form, resp_buf);
ret = buf_error(resp_buf);
......
......@@ -896,6 +896,11 @@ int append_form_opts(struct openconnect_info *vpninfo,
struct oc_auth_form *form, struct oc_text_buf *body);
void free_opt(struct oc_form_opt *opt);
void free_auth_form(struct oc_auth_form *form);
int do_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form);
int can_gen_tokencode(struct openconnect_info *vpninfo,
struct oc_auth_form *form,
struct oc_form_opt *opt);
/* http.c */
struct oc_text_buf *buf_alloc(void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment