Skip to content

Commit

Permalink
Backward compatibility for MFA authentication
Browse files Browse the repository at this point in the history
  • Loading branch information
harsh1618 authored and srijanshetty committed Oct 16, 2014
1 parent e0bfc77 commit 95ff0b5
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 24 deletions.
7 changes: 7 additions & 0 deletions src/openvpn/init.c
Expand Up @@ -2190,6 +2190,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
to.single_session = options->single_session;
#ifdef ENABLE_MFA
to.mfa_methods_list = options->mfa_methods_list;
to.mfa_backward_compat = options->mfa_backward_compat;
#endif
#ifdef ENABLE_PUSH_PEER_INFO
if (options->push_peer_info) /* all there is */
Expand Down Expand Up @@ -2514,6 +2515,12 @@ do_option_warnings (struct context *c)
#endif
#endif

#ifdef ENABLE_MFA
if (o->tls_server
&& o->mfa_backward_compat)
msg (M_WARN, "WARNING: using --mfa-backward-compat allows clients to bypass multi-factor authentication.");
#endif

#ifndef CONNECT_NONBLOCK
if (o->ce.connect_timeout_defined)
msg (M_WARN, "NOTE: --connect-timeout option is not supported on this OS");
Expand Down
10 changes: 8 additions & 2 deletions src/openvpn/options.c
Expand Up @@ -2123,8 +2123,10 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NO_NAME_REMAPPING))
msg (M_USAGE, "--compat-x509-names no-remapping requires --mode server");
#ifdef ENABLE_MFA
if(options->mfa_methods_list.len > 1)
if (options->mfa_methods_list.len > 1)
msg(M_USAGE, "--mfa-method cannot be used more than once with --mode client");
if (options->mfa_backward_compat)
msg(M_USAGE, "--mfa-backward-compat cannot be used with --mode client");
#endif
}
#endif /* P2MP_SERVER */
Expand Down Expand Up @@ -6970,7 +6972,11 @@ add_option (struct options *options,
{
msg(msglevel, "Missing arguments for --mfa-method option");
}
}
}
else if (streq (p[0], "mfa-backward-compat"))
{
options->mfa_backward_compat = true;
}
#endif
#ifdef ENABLE_X509ALTUSERNAME
else if (streq (p[0], "x509-username-field") && p[1])
Expand Down
1 change: 1 addition & 0 deletions src/openvpn/options.h
Expand Up @@ -574,6 +574,7 @@ struct options
int key_method;
#ifdef ENABLE_MFA
struct mfa_methods_list mfa_methods_list;
bool mfa_backward_compat;
#endif

/* Per-packet timeout on control channel */
Expand Down
67 changes: 45 additions & 22 deletions src/openvpn/ssl.c
Expand Up @@ -352,9 +352,9 @@ pem_password_callback (char *buf, int size, int rwflag, void *u)
*/

static bool auth_user_pass_enabled; /* GLOBAL */
static bool auth_mfa_enabled; /* GLOBAL */
static struct user_pass auth_user_pass; /* GLOBAL */
#ifdef ENABLE_MFA
static bool auth_mfa_enabled; /* GLOBAL */
static struct user_pass auth_mfa; /* GLOBAL */
#endif

Expand Down Expand Up @@ -1914,7 +1914,12 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
goto error;

/* write key_method + flags */
if (!buf_write_u8 (buf, (session->opt->key_method & KEY_METHOD_MASK)))
if (!buf_write_u8 (buf, ((session->opt->key_method & KEY_METHOD_MASK)
#ifdef ENABLE_MFA
| KEY_METHOD_MFA_ENABLED
#endif
)))

goto error;

/* write key source material */
Expand Down Expand Up @@ -1949,8 +1954,11 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
goto error;
}

if (!push_peer_info (buf, session))
goto error;

#ifdef ENABLE_MFA
if (auth_mfa_enabled)
if (auth_mfa_enabled) /* client only */
{
struct mfa_methods_list *m = &(session->opt->mfa_methods_list);
auth_mfa_setup (m);
Expand Down Expand Up @@ -1993,8 +2001,6 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
goto error;
}
#endif
if (!push_peer_info (buf, session))
goto error;

/*
* generate tunnel keys if server
Expand Down Expand Up @@ -2094,6 +2100,7 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
int key_method_flags;
bool username_status, password_status;
#ifdef ENABLE_MFA
bool peer_supports_mfa;
bool mfa_username_status, mfa_password_status, mfa_type_status;
int mfa_type;
struct user_pass *mfa;
Expand Down Expand Up @@ -2121,6 +2128,20 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
goto error;
}

#ifdef ENABLE_MFA
if (key_method_flags & KEY_METHOD_MFA_ENABLED)
peer_supports_mfa = true;
else
{
peer_supports_mfa = false;
if (tls_session_mfa_enabled(session) && !session->opt->mfa_backward_compat)
{
msg (D_TLS_ERRORS, "Client does not support multi-factor authentication");
goto error;
}
}
#endif

/* get key source material (not actual keys yet) */
if (!key_source2_read (ks->key_src, buf, session->opt->server))
{
Expand All @@ -2145,19 +2166,6 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
username_status = read_string (buf, up->username, USER_PASS_LEN);
password_status = read_string (buf, up->password, USER_PASS_LEN);

#ifdef ENABLE_MFA
/* get mfa method */
mfa_type = (int) buf_read_u32 (buf, &mfa_type_status);
if (!mfa_type_status)
{
msg(D_TLS_ERRORS, "Bad MFA-type received");
goto error;
}
ALLOC_OBJ_CLEAR_GC (mfa, struct user_pass, &gc);
mfa_username_status = read_string (buf, mfa->username, USER_PASS_LEN);
mfa_password_status = read_string (buf, mfa->password, USER_PASS_LEN);
#endif

#if P2MP_SERVER
/* get peer info from control channel */
free (multi->peer_info);
Expand All @@ -2166,6 +2174,22 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
output_peer_info_env (session->opt->es, multi->peer_info);
#endif

#ifdef ENABLE_MFA
if (peer_supports_mfa)
{
/* get mfa method */
mfa_type = (int) buf_read_u32 (buf, &mfa_type_status);
if (!mfa_type_status)
{
msg(D_TLS_ERRORS, "Bad MFA-type received");
goto error;
}
ALLOC_OBJ_CLEAR_GC (mfa, struct user_pass, &gc);
mfa_username_status = read_string (buf, mfa->username, USER_PASS_LEN);
mfa_password_status = read_string (buf, mfa->password, USER_PASS_LEN);
}
#endif

if (tls_session_user_pass_enabled(session))
{
/* Perform username/password authentication */
Expand Down Expand Up @@ -2204,7 +2228,7 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi

#ifdef ENABLE_MFA
/*check for MFA options */
if (tls_session_mfa_enabled(session))
if (tls_session_mfa_enabled(session) && peer_supports_mfa)
{
if (!process_mfa_options (mfa_type, session))
{
Expand All @@ -2217,20 +2241,19 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
* set username to common name in case of OTP and PUSH
*/
if (session->opt->client_mfa_type == MFA_TYPE_OTP
|| session->opt->client_mfa_type == MFA_TYPE_PUSH)
|| session->opt->client_mfa_type == MFA_TYPE_PUSH)
{
strncpynt(mfa->username, session->common_name, TLS_USERNAME_LEN);
}
verify_user_pass(mfa, multi, session, VERIFY_MFA_CREDENTIALS);
}

CLEAR (*mfa);
}
else
{
ks->authenticated = true;
}

CLEAR (*mfa);
#endif

/* Perform final authentication checks */
Expand Down
3 changes: 3 additions & 0 deletions src/openvpn/ssl.h
Expand Up @@ -123,6 +123,9 @@

/* key method taken from lower 4 bits */
#define KEY_METHOD_MASK 0x0F
#ifdef ENABLE_MFA
#define KEY_METHOD_MFA_ENABLED 0x10
#endif

/*
* Measure success rate of TLS handshakes, for debugging only
Expand Down
1 change: 1 addition & 0 deletions src/openvpn/ssl_common.h
Expand Up @@ -230,6 +230,7 @@ struct tls_options
#ifdef ENABLE_MFA
struct mfa_methods_list mfa_methods_list;
int client_mfa_type;
bool mfa_backward_compat;
#endif
bool replay;
bool single_session;
Expand Down

0 comments on commit 95ff0b5

Please sign in to comment.