From 47ae8457f9e9c2bb0f5c1e8f28822e1bbc16c196 Mon Sep 17 00:00:00 2001 From: james Date: Wed, 4 Jun 2008 05:16:44 +0000 Subject: 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 --- plugin/defer/simple.c | 162 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 131 insertions(+), 31 deletions(-) (limited to 'plugin/defer') diff --git a/plugin/defer/simple.c b/plugin/defer/simple.c index 2dcf9f2..8be9300 100644 --- a/plugin/defer/simple.c +++ b/plugin/defer/simple.c @@ -24,7 +24,30 @@ /* * This file implements a simple OpenVPN plugin module which - * will test deferred authentication. Will run on Windows or *nix. + * will test deferred authentication and packet filtering. + * + * Will run on Windows or *nix. + * + * Sample usage: + * + * setenv test_deferred_auth 20 + * setenv test_packet_filter 10 + * plugin plugin/defer/simple.so + * + * This will enable deferred authentication to occur 20 + * seconds after the normal TLS authentication process, + * and will cause a packet filter file to be generated 10 + * seconds after the initial TLS negotiation, using + * {common-name}.pf as the source. + * + * Sample packet filter configuration: + * + * [CLIENTS DROP] + * +otherclient + * [SUBNETS DROP] + * +10.0.0.0/8 + * -10.10.0.8 + * [END] * * See the README file for build instructions. */ @@ -35,11 +58,23 @@ #include "openvpn-plugin.h" +/* bool definitions */ +#define bool int +#define true 1 +#define false 0 + /* * Our context, where we keep our state. */ + struct plugin_context { - int dummy; + int test_deferred_auth; + int test_packet_filter; +}; + +struct plugin_per_client_context { + int n_calls; + bool generated_pf_file; }; /* @@ -77,6 +112,15 @@ np (const char *str) return "[NULL]"; } +static int +atoi_null0 (const char *str) +{ + if (str) + return atoi (str); + else + return 0; +} + OPENVPN_EXPORT openvpn_plugin_handle_t openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char *envp[]) { @@ -89,11 +133,14 @@ openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char */ context = (struct plugin_context *) calloc (1, sizeof (struct plugin_context)); + context->test_deferred_auth = atoi_null0 (get_env ("test_deferred_auth", envp)); + printf ("TEST_DEFERRED_AUTH %d\n", context->test_deferred_auth); + + context->test_packet_filter = atoi_null0 (get_env ("test_packet_filter", envp)); + printf ("TEST_PACKET_FILTER %d\n", context->test_packet_filter); + /* - * Which callbacks to intercept. We are only interested in - * OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY, but we intercept all - * the callbacks for illustration purposes, so we can show - * the calling sequence via debug output. + * Which callbacks to intercept. */ *type_mask = OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_UP) | @@ -105,45 +152,92 @@ openvpn_plugin_open_v1 (unsigned int *type_mask, const char *argv[], const char OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_CONNECT_V2) | OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_CLIENT_DISCONNECT) | OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_LEARN_ADDRESS) | - OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL); + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_TLS_FINAL) | + OPENVPN_PLUGIN_MASK (OPENVPN_PLUGIN_ENABLE_PF); return (openvpn_plugin_handle_t) context; } static int -auth_user_pass_verify (struct plugin_context *context, const char *argv[], const char *envp[]) +auth_user_pass_verify (struct plugin_context *context, struct plugin_per_client_context *pcc, const char *argv[], const char *envp[]) { - /* get username/password from envp string array */ - const char *username = get_env ("username", envp); - const char *password = get_env ("password", envp); + if (context->test_deferred_auth) + { + /* get username/password from envp string array */ + const char *username = get_env ("username", envp); + const char *password = get_env ("password", envp); - /* get auth_control_file filename from envp string array*/ - const char *auth_control_file = get_env ("auth_control_file", envp); + /* get auth_control_file filename from envp string array*/ + const char *auth_control_file = get_env ("auth_control_file", envp); - printf ("DEFER u='%s' p='%s' acf='%s'\n", - np(username), - np(password), - np(auth_control_file)); + printf ("DEFER u='%s' p='%s' acf='%s'\n", + np(username), + np(password), + np(auth_control_file)); + + /* Authenticate asynchronously in n seconds */ + if (auth_control_file) + { + char buf[256]; + int auth = 2; + sscanf (username, "%d", &auth); + snprintf (buf, sizeof(buf), "( sleep %d ; echo AUTH %s %d ; echo %d >%s ) &", + context->test_deferred_auth, + auth_control_file, + auth, + pcc->n_calls < auth, + auth_control_file); + printf ("%s\n", buf); + system (buf); + pcc->n_calls++; + return OPENVPN_PLUGIN_FUNC_DEFERRED; + } + else + return OPENVPN_PLUGIN_FUNC_ERROR; + } + else + return OPENVPN_PLUGIN_FUNC_SUCCESS; +} - /* Authenticate asynchronously in 10 seconds */ - if (auth_control_file) +static int +tls_final (struct plugin_context *context, struct plugin_per_client_context *pcc, const char *argv[], const char *envp[]) +{ + if (context->test_packet_filter) { - char buf[256]; - snprintf (buf, sizeof(buf), "( sleep 10 ; echo AUTH %s ; echo 1 >%s ) &", - auth_control_file, - auth_control_file); - printf ("%s\n", buf); - system (buf); - return OPENVPN_PLUGIN_FUNC_DEFERRED; + if (!pcc->generated_pf_file) + { + const char *pff = get_env ("pf_file", envp); + const char *cn = get_env ("username", envp); + if (pff && cn) + { + char buf[256]; + snprintf (buf, sizeof(buf), "( sleep %d ; echo PF %s/%s ; cp \"%s.pf\" \"%s\" ) &", + context->test_packet_filter, cn, pff, cn, pff); + printf ("%s\n", buf); + system (buf); + pcc->generated_pf_file = true; + return OPENVPN_PLUGIN_FUNC_SUCCESS; + } + else + return OPENVPN_PLUGIN_FUNC_ERROR; + } + else + return OPENVPN_PLUGIN_FUNC_ERROR; } else - return OPENVPN_PLUGIN_FUNC_ERROR; + return OPENVPN_PLUGIN_FUNC_SUCCESS; } OPENVPN_EXPORT int -openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const char *argv[], const char *envp[]) +openvpn_plugin_func_v2 (openvpn_plugin_handle_t handle, + const int type, + const char *argv[], + const char *envp[], + void *per_client_context, + struct openvpn_plugin_string_list **return_list) { struct plugin_context *context = (struct plugin_context *) handle; + struct plugin_per_client_context *pcc = (struct plugin_per_client_context *) per_client_context; switch (type) { case OPENVPN_PLUGIN_UP: @@ -163,7 +257,7 @@ openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const ch return OPENVPN_PLUGIN_FUNC_SUCCESS; case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY: printf ("OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY\n"); - return auth_user_pass_verify (context, argv, envp); + return auth_user_pass_verify (context, pcc, argv, envp); case OPENVPN_PLUGIN_CLIENT_CONNECT_V2: printf ("OPENVPN_PLUGIN_CLIENT_CONNECT_V2\n"); return OPENVPN_PLUGIN_FUNC_SUCCESS; @@ -175,7 +269,13 @@ openvpn_plugin_func_v1 (openvpn_plugin_handle_t handle, const int type, const ch return OPENVPN_PLUGIN_FUNC_SUCCESS; case OPENVPN_PLUGIN_TLS_FINAL: printf ("OPENVPN_PLUGIN_TLS_FINAL\n"); - return OPENVPN_PLUGIN_FUNC_SUCCESS; + return tls_final (context, pcc, argv, envp); + case OPENVPN_PLUGIN_ENABLE_PF: + printf ("OPENVPN_PLUGIN_ENABLE_PF\n"); + if (context->test_packet_filter) + return OPENVPN_PLUGIN_FUNC_SUCCESS; + else + return OPENVPN_PLUGIN_FUNC_ERROR; default: printf ("OPENVPN_PLUGIN_?\n"); return OPENVPN_PLUGIN_FUNC_ERROR; @@ -186,7 +286,7 @@ OPENVPN_EXPORT void * openvpn_plugin_client_constructor_v1 (openvpn_plugin_handle_t handle) { printf ("FUNC: openvpn_plugin_client_constructor_v1\n"); - return malloc(1); + return calloc (1, sizeof (struct plugin_per_client_context)); } OPENVPN_EXPORT void -- cgit v1.2.3