diff options
author | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2008-06-04 05:16:44 +0000 |
---|---|---|
committer | james <james@e7ae566f-a301-0410-adde-c780ea21d3b5> | 2008-06-04 05:16:44 +0000 |
commit | 47ae8457f9e9c2bb0f5c1e8f28822e1bbc16c196 (patch) | |
tree | 0f47ea714dda8312ee85fe7530ee231c59b91221 /ssl.c | |
parent | 7c51fe16b435712423dd00145008ab58a95fdc5e (diff) | |
download | openvpn-47ae8457f9e9c2bb0f5c1e8f28822e1bbc16c196.tar.gz openvpn-47ae8457f9e9c2bb0f5c1e8f28822e1bbc16c196.tar.xz openvpn-47ae8457f9e9c2bb0f5c1e8f28822e1bbc16c196.zip |
Incremented version to 2.1_rc7d.
Support asynchronous authentication by plugins by allowing
OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY to return
OPENVPN_PLUGIN_FUNC_DEFERRED. See comments in
openvpn-plugin.h for documentation. Enabled by ENABLE_DEF_AUTH.
Added a simple packet filter functionality that can be driven by
a plugin. See comments in openvpn-plugin.h for documentation.
Enabled by ENABLE_PF.
See openvpn/plugin/defer/simple.c for examples of ENABLE_DEF_AUTH
and ENABLE_PF.
"TLS Error: local/remote TLS keys are out of sync" is no longer a
fatal error for TCP-based sessions, since the error can arise
normally in the course of deferred authentication. In a related
change, allow packet-id sequence to begin at some number n > 0 for
TCP sessions, rather than strictly requiring sequence to begin
at 1.
Added a test to configure.ac for LoadLibrary function on Windows.
Modified "make dist" function to include all files from
install-win32 so that ./domake-win can be run from a
tarball-expanded directory.
setenv and setenv-safe directives may now omit a value argument
which defaults to "".
git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@2978 e7ae566f-a301-0410-adde-c780ea21d3b5
Diffstat (limited to 'ssl.c')
-rw-r--r-- | ssl.c | 102 |
1 files changed, 70 insertions, 32 deletions
@@ -47,6 +47,7 @@ #include "status.h" #include "gremlin.h" #include "pkcs11.h" +#include "list.h" #ifdef WIN32 #include "cryptoapi.h" @@ -436,10 +437,22 @@ set_common_name (struct tls_session *session, const char *common_name) { free (session->common_name); session->common_name = NULL; +#ifdef ENABLE_PF + session->common_name_hashval = 0; +#endif } if (common_name) { session->common_name = string_alloc (common_name, NULL); +#ifdef ENABLE_PF + { + const uint32_t len = (uint32_t) strlen (common_name); + if (len) + session->common_name_hashval = hash_func ((const uint8_t*)common_name, len+1, 0); + else + session->common_name_hashval = 0; + } +#endif } } @@ -825,7 +838,7 @@ tls_set_common_name (struct tls_multi *multi, const char *common_name) } const char * -tls_common_name (struct tls_multi *multi, bool null) +tls_common_name (const struct tls_multi *multi, const bool null) { const char *ret = NULL; if (multi) @@ -846,6 +859,8 @@ tls_lock_common_name (struct tls_multi *multi) multi->locked_cn = string_alloc (cn, NULL); } +#ifdef ENABLE_DEF_AUTH + /* * auth_control_file functions */ @@ -876,34 +891,37 @@ key_state_gen_auth_control_file (struct key_state *ks, const struct tls_options } /* key_state_test_auth_control_file return values */ -#define ACF_SUCCEEDED 0 -#define ACF_FAILED 1 -#define ACF_KILL 2 -#define ACF_UNDEFINED 3 -#define ACF_DISABLED 4 +#define ACF_UNDEFINED 0 +#define ACF_SUCCEEDED 1 +#define ACF_DISABLED 2 +#define ACF_FAILED 3 static int -key_state_test_auth_control_file (const struct key_state *ks) +key_state_test_auth_control_file (struct key_state *ks) { - int ret = ACF_DISABLED; if (ks && ks->auth_control_file) { - ret = ACF_UNDEFINED; - FILE *fp = fopen (ks->auth_control_file, "r"); - if (fp) + int ret = ks->auth_control_status; + if (ret == ACF_UNDEFINED) { - int c = fgetc (fp); - if (c == '1') - ret = ACF_SUCCEEDED; - else if (c == '0') - ret = ACF_FAILED; - else if (c == '2') - ret = ACF_KILL; - fclose (fp); + FILE *fp = fopen (ks->auth_control_file, "r"); + if (fp) + { + const int c = fgetc (fp); + if (c == '1') + ret = ACF_SUCCEEDED; + else if (c == '0') + ret = ACF_FAILED; + fclose (fp); + ks->auth_control_status = ret; + } } + return ret; } - return ret; + return ACF_DISABLED; } +#endif + /* * Return current session authentication state. Return * value is TLS_AUTHENTICATION_x. @@ -914,12 +932,13 @@ tls_authentication_status (struct tls_multi *multi, const int latency) { bool deferred = false; bool success = false; - bool kill = false; bool active = false; +#ifdef ENABLE_DEF_AUTH if (latency && multi->tas_last && multi->tas_last + latency >= now) return TLS_AUTHENTICATION_UNDEFINED; multi->tas_last = now; +#endif if (multi) { @@ -932,6 +951,7 @@ tls_authentication_status (struct tls_multi *multi, const int latency) active = true; if (ks->authenticated) { +#ifdef ENABLE_DEF_AUTH switch (key_state_test_auth_control_file (ks)) { case ACF_SUCCEEDED: @@ -946,25 +966,22 @@ tls_authentication_status (struct tls_multi *multi, const int latency) case ACF_FAILED: ks->authenticated = false; break; - case ACF_KILL: - kill = true; - ks->authenticated = false; - break; default: ASSERT (0); } +#else + success = true; +#endif } } } } #if 0 - dmsg (D_TLS_ERRORS, "TAS: a=%d k=%d s=%d d=%d", active, kill, success, deferred); + dmsg (D_TLS_ERRORS, "TAS: a=%d s=%d d=%d", active, success, deferred); #endif - if (kill) - return TLS_AUTHENTICATION_FAILED; - else if (success) + if (success) return TLS_AUTHENTICATION_SUCCEEDED; else if (!active || deferred) return TLS_AUTHENTICATION_DEFERRED; @@ -2001,7 +2018,9 @@ key_state_free (struct key_state *ks, bool clear) packet_id_free (&ks->packet_id); +#ifdef ENABLE_DEF_AUTH key_state_rm_auth_control_file (ks); +#endif if (clear) CLEAR (*ks); @@ -2914,15 +2933,19 @@ verify_user_pass_plugin (struct tls_session *session, const struct user_pass *up /* setenv client real IP address */ setenv_untrusted (session); +#ifdef ENABLE_DEF_AUTH /* generate filename for deferred auth control file */ key_state_gen_auth_control_file (ks, session->opt); +#endif /* call command */ retval = plugin_call (session->opt->plugins, OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, NULL, NULL, session->opt->es); +#ifdef ENABLE_DEF_AUTH /* purge auth control filename (and file itself) for non-deferred returns */ if (retval != OPENVPN_PLUGIN_FUNC_DEFERRED) key_state_rm_auth_control_file (ks); +#endif setenv_del (session->opt->es, "password"); setenv_str (session->opt->es, "username", up->username); @@ -3178,11 +3201,17 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi s2 = verify_user_pass_script (session, up); /* auth succeeded? */ - if ((s1 == OPENVPN_PLUGIN_FUNC_SUCCESS || s1 == OPENVPN_PLUGIN_FUNC_DEFERRED) && s2) + if ((s1 == OPENVPN_PLUGIN_FUNC_SUCCESS +#ifdef ENABLE_DEF_AUTH + || s1 == OPENVPN_PLUGIN_FUNC_DEFERRED +#endif + ) && s2) { ks->authenticated = true; +#ifdef ENABLE_DEF_AUTH if (s1 == OPENVPN_PLUGIN_FUNC_DEFERRED) ks->auth_deferred = true; +#endif if (session->opt->username_as_common_name) set_common_name (session, up->username); msg (D_HANDSHAKE, "TLS: Username/Password authentication %s for username '%s' %s", @@ -3923,7 +3952,9 @@ tls_pre_decrypt (struct tls_multi *multi, if (DECRYPT_KEY_ENABLED (multi, ks) && key_id == ks->key_id && ks->authenticated +#ifdef ENABLE_DEF_AUTH && !ks->auth_deferred +#endif && link_socket_actual_match (from, &ks->remote_addr)) { /* return appropriate data channel decrypt key in opt */ @@ -3950,7 +3981,11 @@ tls_pre_decrypt (struct tls_multi *multi, key_id, ks->key_id, ks->authenticated, +#ifdef ENABLE_DEF_AUTH ks->auth_deferred, +#else + -1, +#endif link_socket_actual_match (from, &ks->remote_addr)); } #endif @@ -3959,7 +3994,7 @@ tls_pre_decrypt (struct tls_multi *multi, msg (D_TLS_ERRORS, "TLS Error: local/remote TLS keys are out of sync: %s [%d]", print_link_socket_actual (from, &gc), key_id); - goto error; + goto error_lite; } else /* control channel packet */ { @@ -4312,8 +4347,9 @@ tls_pre_decrypt (struct tls_multi *multi, return ret; error: - ERR_clear_error (); ++multi->n_soft_errors; + error_lite: + ERR_clear_error (); goto done; } @@ -4443,7 +4479,9 @@ tls_pre_encrypt (struct tls_multi *multi, struct key_state *ks = multi->key_scan[i]; if (ks->state >= S_ACTIVE && ks->authenticated +#ifdef ENABLE_DEF_AUTH && !ks->auth_deferred +#endif && (!ks->key_id || now >= ks->auth_deferred_expire)) { opt->key_ctx_bi = &ks->key; |