27#ifdef HAVE_CONFIG_VERSION_H
28#include "config-version.h"
48#define PLUGIN_SYMBOL_REQUIRED (1<<0)
57 for (i = 0; array[i]; ++i)
61 msg(msglevel,
"%s[%d] = '%s'", name, i, array[i]);
81 case OPENVPN_PLUGIN_UP:
84 case OPENVPN_PLUGIN_DOWN:
87 case OPENVPN_PLUGIN_ROUTE_UP:
88 return "PLUGIN_ROUTE_UP";
90 case OPENVPN_PLUGIN_IPCHANGE:
91 return "PLUGIN_IPCHANGE";
93 case OPENVPN_PLUGIN_TLS_VERIFY:
94 return "PLUGIN_TLS_VERIFY";
96 case OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY:
97 return "PLUGIN_AUTH_USER_PASS_VERIFY";
99 case OPENVPN_PLUGIN_CLIENT_CONNECT:
100 return "PLUGIN_CLIENT_CONNECT";
102 case OPENVPN_PLUGIN_CLIENT_CONNECT_V2:
103 return "PLUGIN_CLIENT_CONNECT_V2";
105 case OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER:
106 return "PLUGIN_CLIENT_CONNECT_DEFER";
108 case OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER_V2:
109 return "PLUGIN_CLIENT_CONNECT_DEFER_V2";
111 case OPENVPN_PLUGIN_CLIENT_DISCONNECT:
112 return "PLUGIN_CLIENT_DISCONNECT";
114 case OPENVPN_PLUGIN_LEARN_ADDRESS:
115 return "PLUGIN_LEARN_ADDRESS";
117 case OPENVPN_PLUGIN_TLS_FINAL:
118 return "PLUGIN_TLS_FINAL";
120 case OPENVPN_PLUGIN_ROUTE_PREDOWN:
121 return "PLUGIN_ROUTE_PREDOWN";
123 case OPENVPN_PLUGIN_CLIENT_CRRESPONSE:
124 return "PLUGIN_CRRESPONSE";
153static inline unsigned int
194 for (i = 0; i <
list->n; ++i)
207libdl_resolve_symbol(
void *handle,
void **dest,
const char *symbol,
const char *plugin_name,
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", symbol, plugin_name, dlerror());
219dll_resolve_symbol(HMODULE module,
void **dest,
const char *symbol,
const char *plugin_name,
const unsigned int flags)
221 *dest = GetProcAddress(module, symbol);
224 msg(
M_FATAL,
"PLUGIN: could not find required symbol '%s' in plugin DLL %s", symbol, plugin_name);
263 snprintf(full,
sizeof(full),
"%s/%s", PLUGIN_LIBDIR, p->
so_pathname);
264 p->handle = dlopen(full, RTLD_NOW);
273 msg(
M_ERR,
"PLUGIN_INIT: could not load plugin shared object %s: %s", p->
so_pathname, dlerror());
276#define PLUGIN_SYM(var, name, flags) libdl_resolve_symbol(p->handle, (void *)&p->var, name, p->so_pathname, flags)
281 WCHAR normalized_plugin_path[MAX_PATH] = {0};
283 if (!GetFullPathNameW(wpath, MAX_PATH, normalized_plugin_path, NULL))
285 msg(
M_ERR,
"PLUGIN_INIT: could not load plugin DLL: %ls. Failed to normalize plugin path.", wpath);
290 msg(
M_FATAL,
"PLUGIN_INIT: could not load plugin DLL: %ls. The DLL is not in a trusted directory.", normalized_plugin_path);
293 p->module = LoadLibraryW(normalized_plugin_path);
296 msg(
M_ERR,
"PLUGIN_INIT: could not load plugin DLL: %ls", normalized_plugin_path);
299#define PLUGIN_SYM(var, name, flags) dll_resolve_symbol(p->module, (void *)&p->var, name, p->so_pathname, flags)
303 PLUGIN_SYM(open1,
"openvpn_plugin_open_v1", 0);
304 PLUGIN_SYM(open2,
"openvpn_plugin_open_v2", 0);
305 PLUGIN_SYM(open3,
"openvpn_plugin_open_v3", 0);
306 PLUGIN_SYM(func1,
"openvpn_plugin_func_v1", 0);
307 PLUGIN_SYM(func2,
"openvpn_plugin_func_v2", 0);
308 PLUGIN_SYM(func3,
"openvpn_plugin_func_v3", 0);
310 PLUGIN_SYM(abort,
"openvpn_plugin_abort_v1", 0);
311 PLUGIN_SYM(client_constructor,
"openvpn_plugin_client_constructor_v1", 0);
312 PLUGIN_SYM(client_destructor,
"openvpn_plugin_client_destructor_v1", 0);
313 PLUGIN_SYM(min_version_required,
"openvpn_plugin_min_version_required_v1", 0);
314 PLUGIN_SYM(initialization_point,
"openvpn_plugin_select_initialization_point_v1", 0);
332 if (plugin_needs_version > OPENVPN_PLUGIN_VERSION)
334 msg(
M_FATAL,
"PLUGIN_INIT: plugin needs interface version %d, but this version of OpenVPN only supports version %d: %s",
335 plugin_needs_version,
336 OPENVPN_PLUGIN_VERSION,
352 msg(
M_WARN,
"WARNING: plugin '%s' specified by a relative pathname -- using an absolute pathname would be more secure", p->
so_pathname);
361plugin_vlog(openvpn_plugin_log_flags_t flags,
const char *name,
const char *format, va_list arglist)
363 unsigned int msg_flags = 0;
370 if (!name || name[0] ==
'\0')
372 msg(
D_PLUGIN_DEBUG,
"PLUGIN: suppressed log message from plugin with unknown name");
376 if (flags & PLOG_ERR)
380 else if (flags & PLOG_WARN)
384 else if (flags & PLOG_NOTE)
388 else if (flags & PLOG_DEBUG)
393 if (flags & PLOG_ERRNO)
397 if (flags & PLOG_NOMUTE)
412 snprintf(msg_fmt,
ERR_BUF_SIZE,
"PLUGIN %s: %s", name, format);
413 x_msg_va(msg_flags, msg_fmt, arglist);
420plugin_log(openvpn_plugin_log_flags_t flags,
const char *name,
const char *format, ...)
423 va_start(arglist, format);
441#ifndef CONFIGURE_GIT_REVISION
442#define _OPENVPN_PATCH_LEVEL OPENVPN_VERSION_PATCH
444#define _OPENVPN_PATCH_LEVEL "git:" CONFIGURE_GIT_REVISION CONFIGURE_GIT_FLAGS
450 struct openvpn_plugin_string_list **retlist,
452 const int init_point)
475 (
const char **
const) o->
argv,
476 (
const char **
const) envp,
480 OPENVPN_VERSION_MAJOR,
481 OPENVPN_VERSION_MINOR,
483 struct openvpn_plugin_args_open_return retargs;
486 retargs.return_list = retlist;
487 if ((*p->
open3)(OPENVPN_PLUGINv3_STRUCTVER, &args, &retargs) == OPENVPN_PLUGIN_FUNC_SUCCESS)
510 msg(
D_PLUGIN,
"PLUGIN_INIT: POST %s '%s' intercepted=%s %s",
514 (retlist && *retlist) ?
"[RETLIST]" :
"");
518 msg(
M_FATAL,
"PLUGIN_INIT: plugin %s expressed interest in unsupported plugin types: [want=0x%08x, have=0x%08x]",
526 msg(
M_FATAL,
"PLUGIN_INIT: plugin initialization function failed: %s",
536 void *per_client_context,
538 const struct argv *av,
539 struct openvpn_plugin_string_list **retlist,
545 int status = OPENVPN_PLUGIN_FUNC_SUCCESS;
566 struct openvpn_plugin_args_func_in args = { type,
567 (
const char **
const) a.
argv,
568 (
const char **
const) envp,
571 (current_cert ? certdepth : -1),
574 struct openvpn_plugin_args_func_return retargs;
577 retargs.return_list = retlist;
578 status = (*p->
func3)(OPENVPN_PLUGINv3_STRUCTVER, &args, &retargs);
598 if (
status == OPENVPN_PLUGIN_FUNC_ERROR)
600 msg(
M_WARN,
"PLUGIN_CALL: plugin function %s failed with status %d: %s",
628 if (dlclose(p->handle))
633 if (!FreeLibrary(p->module))
658 const int init_point)
663 for (i = 0; i < n; ++i)
681 for (i = 0; i < n; ++i)
713 for (i = 0; i < list->
n; ++i)
729 const int init_point)
742 for (i = 0; i < pc->
n; ++i)
746 pr ? &pr->
list[i] : NULL,
767 for (i = 0; i < pc->
n; ++i)
790 const int init_point)
799 const struct argv *av,
818 bool deferred_auth_done =
false;
823 for (i = 0; i < n; ++i)
829 pr ? &pr->
list[i] : NULL,
836 case OPENVPN_PLUGIN_FUNC_SUCCESS:
839 case OPENVPN_PLUGIN_FUNC_DEFERRED:
840 if ((type == OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY)
841 && deferred_auth_done)
859 "Exiting due to multiple authentication plug-ins "
860 "performing deferred authentication. Only one "
861 "authentication plug-in doing deferred auth is "
862 "allowed. Ignoring the result and stopping now, "
863 "the current authentication result is not to be "
867 deferred_auth_done =
true;
885 return OPENVPN_PLUGIN_FUNC_ERROR;
887 else if (deferred_auth_done)
889 return OPENVPN_PLUGIN_FUNC_DEFERRED;
893 return OPENVPN_PLUGIN_FUNC_SUCCESS;
924 for (i = 0; i < pc->
n; ++i)
943 const unsigned int mask = OPENVPN_PLUGIN_MASK(type);
944 for (i = 0; i < pc->
n; ++i)
976 struct openvpn_plugin_string_list *next;
985static struct openvpn_plugin_string_list *
990 if (!strcmp(l->name, name))
1002 const char *colname)
1007 for (i = 0; i < src->
n; ++i)
1018 for (i = 0; i < pr->
n; ++i)
1027plugin_return_print(
const int msglevel,
const char *prefix,
const struct plugin_return *pr)
1030 msg(msglevel,
"PLUGIN_RETURN_PRINT %s", prefix);
1031 for (i = 0; i < pr->
n; ++i)
1033 struct openvpn_plugin_string_list *l = pr->
list[i];
1036 msg(msglevel,
"PLUGIN #%d (%s)", i, prefix);
1039 msg(msglevel,
"[%d] '%s' -> '%s'\n",
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)
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)
void x_msg_va(const unsigned int flags, const char *format, va_list arglist)
static bool msg_test(unsigned int flags)
Return true if flags represent an enabled, not muted log level.
static bool check_debug_level(unsigned int level)
void plugin_list_close(struct plugin_list *pl)
static void plugin_show_string_array(int msglevel, const char *name, const char *array[])
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(int 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_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)
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)
void plugin_option_list_print(const struct plugin_option_list *list, int msglevel)
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.
mbedtls_x509_crt openvpn_x509_cert_t
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.
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.