Go to the documentation of this file.
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]);
88 return "PLUGIN_ROUTE_UP";
91 return "PLUGIN_IPCHANGE";
94 return "PLUGIN_TLS_VERIFY";
97 return "PLUGIN_AUTH_USER_PASS_VERIFY";
100 return "PLUGIN_CLIENT_CONNECT";
103 return "PLUGIN_CLIENT_CONNECT_V2";
106 return "PLUGIN_CLIENT_CONNECT_DEFER";
109 return "PLUGIN_CLIENT_CONNECT_DEFER_V2";
112 return "PLUGIN_CLIENT_DISCONNECT";
115 return "PLUGIN_LEARN_ADDRESS";
118 return "PLUGIN_TLS_FINAL";
121 return "PLUGIN_ROUTE_PREDOWN";
123 case OPENVPN_PLUGIN_CLIENT_CRRESPONSE:
124 return "PLUGIN_CRRESPONSE";
153 static inline unsigned int
194 for (i = 0; i <
list->n; ++i)
207 libdl_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());
219 dll_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);
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,
352 msg(
M_WARN,
"WARNING: plugin '%s' specified by a relative pathname -- using an absolute pathname would be more secure", p->
so_pathname);
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");
412 snprintf(msg_fmt,
ERR_BUF_SIZE,
"PLUGIN %s: %s", name, format);
413 x_msg_va(msg_flags, msg_fmt, arglist);
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
452 const int init_point)
475 (
const char **
const) o->
argv,
476 (
const char **
const)
envp,
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,
567 (
const char **
const) a.
argv,
568 (
const char **
const)
envp,
600 msg(
M_WARN,
"PLUGIN_CALL: plugin function %s failed with status %d: %s",
628 if (dlclose(p->handle))
632 #elif defined(_WIN32)
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,
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;
887 else if (deferred_auth_done)
924 for (i = 0; i < pc->
n; ++i)
944 for (i = 0; i < pc->
n; ++i)
1002 const char *colname)
1007 for (i = 0; i < src->
n; ++i)
1018 for (i = 0; i < pr->
n; ++i)
1027 plugin_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)
1036 msg(msglevel,
"PLUGIN #%d (%s)", i, prefix);
1039 msg(msglevel,
"[%d] '%s' -> '%s'\n",
struct openvpn_plugin_string_list * list[MAX_PLUGINS]
struct gc_entry * list
First element of the linked list of gc_entry structures.
openvpn_plugin_open_v1 open1
struct plugin_list * plugin_list_init(const struct plugin_option_list *list)
int openvpn_base64_decode(const char *str, void *data, int size)
#define OPENVPN_PLUGIN_CLIENT_CONNECT_V2
#define OPENVPN_PLUGIN_LEARN_ADDRESS
#define OPENVPN_PLUGIN_UP
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)
static bool msg_test(unsigned int flags)
Return true if flags represent an enabled, not muted log level.
unsigned int plugin_type_mask
static void plugin_per_client_init(const struct plugin_common *pc, struct plugin_per_client *cli, const int init_point)
#define OPENVPN_PLUGIN_DOWN
static struct gc_arena gc_new(void)
static struct plugin_common * static_plugin_common
#define OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER
openvpn_plugin_abort_v1 abort
void x_msg_va(const unsigned int flags, const char *format, va_list arglist)
Arguments used to transport variables to the plug-in.
openvpn_plugin_handle_t plugin_handle
struct openvpn_plugin_string_list * next
#define OPENVPN_PLUGINv3_STRUCTVER
Defines version of the v3 plugin argument structs.
static void plugin_show_args_env(int msglevel, const char *argv[], const char *envp[])
bool plugin_in_trusted_dir(const WCHAR *plugin_path)
Checks if a plugin is located in a trusted directory.
static void plugin_return_init(struct plugin_return *pr)
const char ** make_extended_arg_array(char **p, bool is_inline, struct gc_arena *gc)
struct buffer alloc_buf_gc(size_t size, struct gc_arena *gc)
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
openvpn_plugin_open_v2 open2
#define OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY
openvpn_plugin_select_initialization_point_v1 initialization_point
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 plugin_common * plugin_common_init(const struct plugin_option_list *list)
int openvpn_base64_encode(const void *data, int size, char **str)
#define OPENVPN_VERSION_MINOR
static void plugin_log(openvpn_plugin_log_flags_t flags, const char *name, const char *format,...)
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)
openvpn_plugin_log_flags_t
Definitions needed for the plug-in callback functions.
#define OPENVPN_PLUGIN_MASK(x)
void plugin_option_list_print(const struct plugin_option_list *list, int msglevel)
openvpn_plugin_func_v2 func2
static struct openvpn_plugin_callbacks callbacks
void * per_client_context[MAX_PLUGINS]
static unsigned int plugin_supported_types(void)
static void secure_memzero(void *data, size_t len)
Securely zeroise memory.
static void plugin_abort_item(const struct plugin *p)
void string_clear(char *str)
#define OPENVPN_PLUGIN_FUNC_ERROR
struct plugin plugins[MAX_PLUGINS]
#define OPENVPN_PLUGIN_INIT_PRE_DAEMON
static void plugin_show_string_array(int msglevel, const char *name, const char *array[])
openvpn_plugin_close_v1 close
openvpn_x509_cert_t * current_cert
static struct openvpn_plugin_string_list * openvpn_plugin_string_list_find(struct openvpn_plugin_string_list *l, const char *name)
struct plugin_common * common
openvpn_plugin_client_destructor_v1 client_destructor
#define OPENVPN_PLUGIN_IPCHANGE
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)
void plugin_list_close(struct plugin_list *pl)
void plugin_return_free(struct plugin_return *pr)
#define OPENVPN_VERSION_MAJOR
#define OPENVPN_PLUGIN_FUNC_DEFERRED
struct plugin_list * plugin_list_inherit(const struct plugin_list *src)
#define ALLOC_OBJ_CLEAR_GC(dptr, type, gc)
struct openvpn_plugin_string_list ** return_list
WCHAR * wide_string(const char *utf8, struct gc_arena *gc)
#define OPENVPN_PLUGIN_ROUTE_UP
struct plugin_option_list * plugin_option_list_new(struct gc_arena *gc)
static void plugin_init_item(struct plugin *p, const struct plugin_option *o)
static void dll_resolve_symbol(HMODULE module, void **dest, const char *symbol, const char *plugin_name, const unsigned int flags)
void * per_client_context
#define OPENVPN_PLUGIN_TLS_VERIFY
struct argv argv_insert_head(const struct argv *a, const char *head)
Inserts an argument string in front of all other argument slots.
Wrapper structure for dynamically allocated memory.
openvpn_plugin_func_v1 func1
Garbage collection arena used to keep track of dynamically allocated memory.
Arguments used to transport variables to and from the plug-in.
static void plugin_common_close(struct plugin_common *pc)
bool plugin_option_list_add(struct plugin_option_list *list, char **p, struct gc_arena *gc)
#define PLUGIN_SYMBOL_REQUIRED
struct plugin_option plugins[MAX_PLUGINS]
static bool check_debug_level(unsigned int level)
void plugin_return_get_column(const struct plugin_return *src, struct plugin_return *dest, const char *colname)
int requested_initialization_point
static void openvpn_plugin_string_list_free(struct openvpn_plugin_string_list *l)
#define OPENVPN_PLUGIN_CLIENT_DISCONNECT
#define OPENVPN_PLUGIN_VERSION
void * gc_malloc(size_t size, bool clear, struct gc_arena *a)
static void openvpn_plugin_string_list_item_free(struct openvpn_plugin_string_list *l)
Arguments used to transport variables from the plug-in back to the OpenVPN process.
Arguments used to transport variables to and from the plug-in.
static void plugin_close_item(struct plugin *p)
openvpn_plugin_handle_t handle
static SERVICE_STATUS status
struct plugin_per_client per_client
static void gc_free(struct gc_arena *a)
openvpn_plugin_open_v3 open3
openvpn_plugin_client_constructor_v1 client_constructor
static int plugin_n(const struct plugin_list *pl)
#define ALLOC_OBJ_CLEAR(dptr, type)
#define _OPENVPN_PATCH_LEVEL
#define OPENVPN_PLUGIN_FUNC_SUCCESS
#define OPENVPN_PLUGIN_TLS_FINAL
static void gc_init(struct gc_arena *a)
openvpn_plugin_func_v3 func3
static void plugin_per_client_destroy(const struct plugin_common *pc, struct plugin_per_client *cli)
#define OPENVPN_PLUGIN_ROUTE_PREDOWN
bool plugin_defined(const struct plugin_list *pl, const int type)
struct openvpn_plugin_string_list ** return_list
char * print_argv(const char **p, struct gc_arena *gc, const unsigned int flags)
Used by the openvpn_plugin_open_v3() function to pass callback function pointers to the plug-in.
void setenv_del(struct env_set *es, const char *name)
static const char * plugin_mask_string(const unsigned int type_mask, struct gc_arena *gc)
#define OPENVPN_PLUGIN_CLIENT_CONNECT
openvpn_plugin_min_version_required_v1 min_version_required
static bool env_safe_to_print(const char *str)
const char ** make_env_array(const struct env_set *es, const bool check_allowed, struct gc_arena *gc)
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)
bool buf_printf(struct buffer *buf, const char *format,...)
static const char * plugin_type_name(const int type)
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)
#define OPENVPN_PLUGIN_CLIENT_CONNECT_DEFER_V2