26#ifdef HAVE_CONFIG_VERSION_H
27#include "config-version.h"
47#define PLUGIN_SYMBOL_REQUIRED (1 << 0)
56 for (
i = 0; array[
i]; ++
i)
60 msg(msglevel,
"%s[%d] = '%s'", name,
i, array[
i]);
87 return "PLUGIN_ROUTE_UP";
90 return "PLUGIN_IPCHANGE";
93 return "PLUGIN_TLS_VERIFY";
96 return "PLUGIN_AUTH_USER_PASS_VERIFY";
99 return "PLUGIN_CLIENT_CONNECT";
102 return "PLUGIN_CLIENT_CONNECT_V2";
105 return "PLUGIN_CLIENT_CONNECT_DEFER";
108 return "PLUGIN_CLIENT_CONNECT_DEFER_V2";
111 return "PLUGIN_CLIENT_DISCONNECT";
114 return "PLUGIN_LEARN_ADDRESS";
117 return "PLUGIN_TLS_FINAL";
120 return "PLUGIN_ROUTE_PREDOWN";
122 case OPENVPN_PLUGIN_CLIENT_CRRESPONSE:
123 return "PLUGIN_CRRESPONSE";
152static inline unsigned int
206libdl_resolve_symbol(
void *handle,
void **dest,
const char *symbol,
const char *plugin_name,
207 const unsigned int flags)
209 *dest = dlsym(handle, symbol);
212 msg(
M_FATAL,
"PLUGIN: could not find required symbol '%s' in plugin shared object %s: %s",
213 symbol, plugin_name, dlerror());
221 const unsigned int flags)
223 *dest = GetProcAddress(module, symbol);
226 msg(
M_FATAL,
"PLUGIN: could not find required symbol '%s' in plugin DLL %s", symbol,
265 snprintf(full,
sizeof(full),
"%s/%s", PLUGIN_LIBDIR, p->
so_pathname);
266 p->handle = dlopen(full, RTLD_NOW);
279#define PLUGIN_SYM(var, name, flags) \
280 libdl_resolve_symbol(p->handle, (void *)&p->var, name, p->so_pathname, flags)
285 WCHAR normalized_plugin_path[MAX_PATH] = { 0 };
287 if (!GetFullPathNameW(wpath, MAX_PATH, normalized_plugin_path, NULL))
289 msg(
M_ERR,
"PLUGIN_INIT: could not load plugin DLL: %ls. Failed to normalize plugin path.",
296 "PLUGIN_INIT: could not load plugin DLL: %ls. The DLL is not in a trusted directory.",
297 normalized_plugin_path);
300 p->module = LoadLibraryW(normalized_plugin_path);
303 msg(
M_ERR,
"PLUGIN_INIT: could not load plugin DLL: %ls", normalized_plugin_path);
306#define PLUGIN_SYM(var, name, flags) \
307 dll_resolve_symbol(p->module, (void *)&p->var, name, p->so_pathname, flags)
311 PLUGIN_SYM(open1,
"openvpn_plugin_open_v1", 0);
312 PLUGIN_SYM(open2,
"openvpn_plugin_open_v2", 0);
313 PLUGIN_SYM(open3,
"openvpn_plugin_open_v3", 0);
314 PLUGIN_SYM(func1,
"openvpn_plugin_func_v1", 0);
315 PLUGIN_SYM(func2,
"openvpn_plugin_func_v2", 0);
316 PLUGIN_SYM(func3,
"openvpn_plugin_func_v3", 0);
318 PLUGIN_SYM(abort,
"openvpn_plugin_abort_v1", 0);
319 PLUGIN_SYM(client_constructor,
"openvpn_plugin_client_constructor_v1", 0);
320 PLUGIN_SYM(client_destructor,
"openvpn_plugin_client_destructor_v1", 0);
321 PLUGIN_SYM(min_version_required,
"openvpn_plugin_min_version_required_v1", 0);
322 PLUGIN_SYM(initialization_point,
"openvpn_plugin_select_initialization_point_v1", 0);
326 msg(
M_FATAL,
"PLUGIN: symbol openvpn_plugin_open_vX is undefined in plugin: %s",
332 msg(
M_FATAL,
"PLUGIN: symbol openvpn_plugin_func_vX is undefined in plugin: %s",
345 "PLUGIN_INIT: plugin needs interface version %d, but this version of OpenVPN only supports version %d: %s",
362 "WARNING: plugin '%s' specified by a relative pathname -- using an absolute pathname would be more secure",
374 unsigned int msg_flags = 0;
381 if (!name || name[0] ==
'\0')
383 msg(
D_PLUGIN_DEBUG,
"PLUGIN: suppressed log message from plugin with unknown name");
423 snprintf(msg_fmt,
ERR_BUF_SIZE,
"PLUGIN %s: %s", name, format);
424 x_msg_va(msg_flags, msg_fmt, arglist);
434 va_start(arglist, format);
452#ifndef CONFIGURE_GIT_REVISION
453#define _OPENVPN_PATCH_LEVEL OPENVPN_VERSION_PATCH
455#define _OPENVPN_PATCH_LEVEL "git:" CONFIGURE_GIT_REVISION CONFIGURE_GIT_FLAGS
461 const int init_point)
484 (
const char **
const)o->
argv,
485 (
const char **
const)
envp,
522 (retlist && *retlist) ?
"[RETLIST]" :
"");
527 "PLUGIN_INIT: plugin %s expressed interest in unsupported plugin types: [want=0x%08x, have=0x%08x]",
567 (
const char **
const)a.
argv,
568 (
const char **
const)
envp,
583 per_client_context, retlist);
599 msg(
M_WARN,
"PLUGIN_CALL: plugin function %s failed with status %d: %s",
625 if (dlclose(p->handle))
630 if (!FreeLibrary(p->module))
654 const int init_point)
659 for (
i = 0;
i < n; ++
i)
676 for (
i = 0;
i < n; ++
i)
708 for (
i = 0;
i < list->
n; ++
i)
733 for (
i = 0;
i < pc->
n; ++
i)
755 for (
i = 0;
i < pc->
n; ++
i)
798 bool deferred_auth_done =
false;
803 for (
i = 0;
i < n; ++
i)
807 type, av, pr ? &pr->
list[
i] : NULL, envp, certdepth, current_cert);
831 msg(
M_FATAL,
"Exiting due to multiple authentication plug-ins "
832 "performing deferred authentication. Only one "
833 "authentication plug-in doing deferred auth is "
834 "allowed. Ignoring the result and stopping now, "
835 "the current authentication result is not to be "
839 deferred_auth_done =
true;
859 else if (deferred_auth_done)
896 for (
i = 0;
i < pc->
n; ++
i)
916 for (
i = 0;
i < pc->
n; ++
i)
978 for (
i = 0;
i < src->
n; ++
i)
989 for (
i = 0;
i < pr->
n; ++
i)
1001 msg(msglevel,
"PLUGIN_RETURN_PRINT %s", prefix);
1002 for (
i = 0;
i < pr->
n; ++
i)
1007 msg(msglevel,
"PLUGIN #%d (%s)",
i, prefix);
1010 msg(msglevel,
"[%d] '%s' -> '%s'", ++count, l->
name, l->
value);
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
struct argv argv_insert_head(const struct argv *a, const char *head)
Inserts an argument string in front of all other argument slots.
bool buf_printf(struct buffer *buf, const char *format,...)
void string_clear(char *str)
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
static void gc_init(struct gc_arena *a)
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
static void gc_free(struct gc_arena *a)
#define ALLOC_OBJ_CLEAR(dptr, type)
static struct gc_arena gc_new(void)
#define OPENVPN_VERSION_MINOR
#define OPENVPN_VERSION_MAJOR
const char ** make_env_array(const struct env_set *es, const bool check_allowed, struct gc_arena *gc)
void setenv_del(struct env_set *es, const char *name)
static bool env_safe_to_print(const char *str)
static SERVICE_STATUS status
const char ** make_extended_arg_array(char **p, bool is_inline, struct gc_arena *gc)
#define OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER
openvpn_plugin_log_flags_t
Definitions needed for the plug-in callback functions.
#define OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER_V2
#define OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
#define OPENVPN_PLUGIN_CLIENT_CONNECT_V2
#define OPENVPN_PLUGIN_LEARN_ADDRESS
#define OPENVPN_PLUGIN_INIT_PRE_DAEMON
#define OPENVPN_PLUGIN_CLIENT_CONNECT
#define OPENVPN_PLUGIN_DOWN
#define OPENVPN_PLUGIN_ROUTE_PREDOWN
#define OPENVPN_PLUGIN_MASK(x)
#define OPENVPN_PLUGIN_TLS_FINAL
#define OPENVPN_PLUGIN_VERSION
#define OPENVPN_PLUGIN_TLS_VERIFY
#define OPENVPN_PLUGIN_IPCHANGE
#define OPENVPN_PLUGIN_FUNC_DEFERRED
#define OPENVPN_PLUGIN_FUNC_SUCCESS
#define OPENVPN_PLUGIN_UP
#define OPENVPN_PLUGIN_CLIENT_DISCONNECT
#define OPENVPN_PLUGIN_ROUTE_UP
#define OPENVPN_PLUGINv3_STRUCTVER
Defines version of the v3 plugin argument structs.
#define OPENVPN_PLUGIN_FUNC_ERROR
void x_msg_va(const msglvl_t flags, const char *format, va_list arglist)
static bool check_debug_level(msglvl_t level)
static bool msg_test(msglvl_t flags)
Return true if flags represent an enabled, not muted log level.
void plugin_list_close(struct plugin_list *pl)
static struct openvpn_plugin_string_list * openvpn_plugin_string_list_find(struct openvpn_plugin_string_list *l, const char *name)
static struct plugin_common * static_plugin_common
struct plugin_option_list * plugin_option_list_new(struct gc_arena *gc)
static void plugin_abort_item(const struct plugin *p)
bool plugin_option_list_add(struct plugin_option_list *list, char **p, struct gc_arena *gc)
static void plugin_per_client_destroy(const struct plugin_common *pc, struct plugin_per_client *cli)
static void plugin_show_args_env(msglvl_t msglevel, const char *argv[], const char *envp[])
#define PLUGIN_SYMBOL_REQUIRED
static void plugin_open_item(struct plugin *p, const struct plugin_option *o, struct openvpn_plugin_string_list **retlist, const char **envp, const int init_point)
void plugin_option_list_print(const struct plugin_option_list *list, msglvl_t msglevel)
void plugin_return_free(struct plugin_return *pr)
static void plugin_per_client_init(const struct plugin_common *pc, struct plugin_per_client *cli, const int init_point)
struct plugin_list * plugin_list_inherit(const struct plugin_list *src)
static unsigned int plugin_supported_types(void)
static void plugin_common_close(struct plugin_common *pc)
static const char * plugin_type_name(const int type)
static void openvpn_plugin_string_list_item_free(struct openvpn_plugin_string_list *l)
static void openvpn_plugin_string_list_free(struct openvpn_plugin_string_list *l)
static const char * plugin_mask_string(const unsigned int type_mask, struct gc_arena *gc)
static int plugin_call_item(const struct plugin *p, void *per_client_context, const int type, const struct argv *av, struct openvpn_plugin_string_list **retlist, const char **envp, int certdepth, openvpn_x509_cert_t *current_cert)
#define _OPENVPN_PATCH_LEVEL
static void plugin_init_item(struct plugin *p, const struct plugin_option *o)
static void plugin_show_string_array(msglvl_t msglevel, const char *name, const char *array[])
int plugin_call_ssl(const struct plugin_list *pl, const int type, const struct argv *av, struct plugin_return *pr, struct env_set *es, int certdepth, openvpn_x509_cert_t *current_cert)
struct plugin_list * plugin_list_init(const struct plugin_option_list *list)
static void plugin_vlog(openvpn_plugin_log_flags_t flags, const char *name, const char *format, va_list arglist)
#define PLUGIN_SYM(var, name, flags)
static void dll_resolve_symbol(HMODULE module, void **dest, const char *symbol, const char *plugin_name, const unsigned int flags)
static struct plugin_common * plugin_common_init(const struct plugin_option_list *list)
static void plugin_close_item(struct plugin *p)
void plugin_return_get_column(const struct plugin_return *src, struct plugin_return *dest, const char *colname)
static void plugin_common_open(struct plugin_common *pc, const struct plugin_option_list *list, struct plugin_return *pr, const struct env_set *es, const int init_point)
bool plugin_defined(const struct plugin_list *pl, const int type)
void plugin_list_open(struct plugin_list *pl, const struct plugin_option_list *list, struct plugin_return *pr, const struct env_set *es, const int init_point)
static struct openvpn_plugin_callbacks callbacks
static int plugin_n(const struct plugin_list *pl)
static void plugin_return_init(struct plugin_return *pr)
static plugin_log_t plugin_log
int openvpn_base64_decode(const char *str, void *data, int size)
int openvpn_base64_encode(const void *data, int size, char **str)
Control Channel SSL library backend module.
Wrapper structure for dynamically allocated memory.
int len
Length in bytes of the actual content within the allocated memory.
Garbage collection arena used to keep track of dynamically allocated memory.
struct gc_entry * list
First element of the linked list of gc_entry structures.
Arguments used to transport variables to and from the plug-in.
void * per_client_context
openvpn_x509_cert_t * current_cert
Arguments used to transport variables to and from the plug-in.
struct openvpn_plugin_string_list ** return_list
Arguments used to transport variables to the plug-in.
Arguments used to transport variables from the plug-in back to the OpenVPN process.
openvpn_plugin_handle_t handle
struct openvpn_plugin_string_list ** return_list
Used by the openvpn_plugin_open_v3() function to pass callback function pointers to the plug-in.
struct openvpn_plugin_string_list * next
struct plugin plugins[MAX_PLUGINS]
struct plugin_common * common
struct plugin_per_client per_client
struct plugin_option plugins[MAX_PLUGINS]
void * per_client_context[MAX_PLUGINS]
struct openvpn_plugin_string_list * list[MAX_PLUGINS]
openvpn_plugin_abort_v1 abort
HMODULE openvpn_plugin_open_v1 open1
openvpn_plugin_select_initialization_point_v1 initialization_point
openvpn_plugin_close_v1 close
openvpn_plugin_handle_t plugin_handle
int requested_initialization_point
openvpn_plugin_open_v3 open3
openvpn_plugin_open_v2 open2
openvpn_plugin_client_destructor_v1 client_destructor
unsigned int plugin_type_mask
openvpn_plugin_min_version_required_v1 min_version_required
openvpn_plugin_client_constructor_v1 client_constructor
openvpn_plugin_func_v1 func1
openvpn_plugin_func_v2 func2
openvpn_plugin_func_v3 func3
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
bool plugin_in_trusted_dir(const WCHAR *plugin_path)
Checks if a plugin is located in a trusted directory.