From 71b557ba9d2f29f667bda60870993b83aa8d21a8 Mon Sep 17 00:00:00 2001 From: james Date: Sat, 24 Oct 2009 01:08:30 +0000 Subject: On server, lock session username against changes in mid-session TLS renegotiations -- this is similer to how the common name is also locked. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@5098 e7ae566f-a301-0410-adde-c780ea21d3b5 --- ssl.c | 31 +++++++++++++++++++++++++++++-- ssl.h | 3 ++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/ssl.c b/ssl.c index bc8b2da..847c5ec 100644 --- a/ssl.c +++ b/ssl.c @@ -898,6 +898,30 @@ tls_lock_common_name (struct tls_multi *multi) multi->locked_cn = string_alloc (cn, NULL); } +static bool +tls_lock_username (struct tls_multi *multi, const char *username) +{ + if (multi->locked_username) + { + if (!username || strcmp (username, multi->locked_username)) + { + msg (D_TLS_ERRORS, "TLS Auth Error: username attempted to change from '%s' to '%s' -- tunnel disabled", + multi->locked_username, + np(username)); + + /* disable the tunnel */ + tls_deauthenticate (multi); + return false; + } + } + else + { + if (username) + multi->locked_username = string_alloc (username, NULL); + } + return true; +} + #ifdef ENABLE_DEF_AUTH /* key_state_test_auth_control_file return values, NOTE: acf_merge indexing depends on these values */ @@ -2417,6 +2441,9 @@ tls_multi_free (struct tls_multi *multi, bool clear) if (multi->locked_cn) free (multi->locked_cn); + if (multi->locked_username) + free (multi->locked_username); + for (i = 0; i < TM_SIZE; ++i) tls_session_free (&multi->session[i], false); @@ -3401,7 +3428,8 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi #ifdef PLUGIN_DEF_AUTH || s1 == OPENVPN_PLUGIN_FUNC_DEFERRED #endif - ) && s2 && man_def_auth != KMDA_ERROR) + ) && s2 && man_def_auth != KMDA_ERROR + && tls_lock_username (multi, up->username)) { ks->authenticated = true; #ifdef PLUGIN_DEF_AUTH @@ -3412,7 +3440,6 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi if (man_def_auth != KMDA_UNDEF) ks->auth_deferred = true; #endif - if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME)) set_common_name (session, up->username); #ifdef ENABLE_DEF_AUTH diff --git a/ssl.h b/ssl.h index 06cd246..7e0bfb5 100644 --- a/ssl.h +++ b/ssl.h @@ -589,9 +589,10 @@ struct tls_multi int n_soft_errors; /* errors due to unrecognized or failed-to-authenticate incoming packets */ /* - * Our locked common name (cannot change during the life of this tls_multi object) + * Our locked common name and username (cannot change during the life of this tls_multi object) */ char *locked_cn; + char *locked_username; #ifdef ENABLE_DEF_AUTH /* -- cgit