Example #1
0
static void
plugin_init_item (struct plugin *p, const struct plugin_option *o)
{
  struct gc_arena gc = gc_new ();
  bool rel = false;

  p->so_pathname = o->so_pathname;
  p->plugin_type_mask = plugin_supported_types ();

#if defined(USE_LIBDL)

  p->handle = NULL;
#if defined(PLUGIN_LIBDIR)
  if (!absolute_pathname (p->so_pathname))
    {
      char full[PATH_MAX];

      openvpn_snprintf (full, sizeof(full), "%s/%s", PLUGIN_LIBDIR, p->so_pathname);
      p->handle = dlopen (full, RTLD_NOW);
#if defined(ENABLE_PLUGIN_SEARCH)
      if (!p->handle)
	{
	  rel = true;
	  p->handle = dlopen (p->so_pathname, RTLD_NOW);
	}
#endif
    }
  else
#endif
    {
      rel = !absolute_pathname (p->so_pathname);
      p->handle = dlopen (p->so_pathname, RTLD_NOW);
    }
  if (!p->handle)
    msg (M_ERR, "PLUGIN_INIT: could not load plugin shared object %s: %s", p->so_pathname, dlerror());

# define PLUGIN_SYM(var, name, flags) libdl_resolve_symbol (p->handle, (void*)&p->var, name, p->so_pathname, flags)

#elif defined(USE_LOAD_LIBRARY)

  rel = !absolute_pathname (p->so_pathname);
  p->module = LoadLibrary (p->so_pathname);
  if (!p->module)
    msg (M_ERR, "PLUGIN_INIT: could not load plugin DLL: %s", p->so_pathname);

# define PLUGIN_SYM(var, name, flags) dll_resolve_symbol (p->module, (void*)&p->var, name, p->so_pathname, flags)

#endif

  PLUGIN_SYM (open1, "openvpn_plugin_open_v1", 0);
  PLUGIN_SYM (open2, "openvpn_plugin_open_v2", 0);
  PLUGIN_SYM (open3, "openvpn_plugin_open_v3", 0);
  PLUGIN_SYM (func1, "openvpn_plugin_func_v1", 0);
  PLUGIN_SYM (func2, "openvpn_plugin_func_v2", 0);
  PLUGIN_SYM (func3, "openvpn_plugin_func_v3", 0);
  PLUGIN_SYM (close, "openvpn_plugin_close_v1", PLUGIN_SYMBOL_REQUIRED);
  PLUGIN_SYM (abort, "openvpn_plugin_abort_v1", 0);
  PLUGIN_SYM (client_constructor, "openvpn_plugin_client_constructor_v1", 0);
  PLUGIN_SYM (client_destructor, "openvpn_plugin_client_destructor_v1", 0);
  PLUGIN_SYM (min_version_required, "openvpn_plugin_min_version_required_v1", 0);
  PLUGIN_SYM (initialization_point, "openvpn_plugin_select_initialization_point_v1", 0);

  if (!p->open1 && !p->open2 && !p->open3)
    msg (M_FATAL, "PLUGIN: symbol openvpn_plugin_open_vX is undefined in plugin: %s", p->so_pathname);

  if (!p->func1 && !p->func2 && !p->func3)
    msg (M_FATAL, "PLUGIN: symbol openvpn_plugin_func_vX is undefined in plugin: %s", p->so_pathname);

  /*
   * Verify that we are sufficiently up-to-date to handle the plugin
   */
  if (p->min_version_required)
    {
      const int plugin_needs_version = (*p->min_version_required)();
      if (plugin_needs_version > OPENVPN_PLUGIN_VERSION)
	msg (M_FATAL, "PLUGIN_INIT: plugin needs interface version %d, but this version of OpenVPN only supports version %d: %s",
	     plugin_needs_version,
	     OPENVPN_PLUGIN_VERSION,
	     p->so_pathname);
    }

  if (p->initialization_point)
    p->requested_initialization_point = (*p->initialization_point)();
  else
    p->requested_initialization_point = OPENVPN_PLUGIN_INIT_PRE_DAEMON;

  if (rel)
    msg (M_WARN, "WARNING: plugin '%s' specified by a relative pathname -- using an absolute pathname would be more secure", p->so_pathname);

  p->initialized = true;

  gc_free (&gc);
}
Example #2
0
static void
plugin_init_item(struct plugin *p, const struct plugin_option *o)
{
    struct gc_arena gc = gc_new();
    bool rel = false;

    p->so_pathname = o->so_pathname;
    p->plugin_type_mask = plugin_supported_types();

#ifndef _WIN32

    p->handle = NULL;

    /* If the plug-in filename is not an absolute path,
     * or beginning with '.', it should use the PLUGIN_LIBDIR
     * as the base directory for loading the plug-in.
     *
     * This means the following scenarios are loaded from these places:
     *    --plugin fancyplug.so              -> $PLUGIN_LIBDIR/fancyplug.so
     *    --plugin my/fancyplug.so           -> $PLUGIN_LIBDIR/my/fancyplug.so
     *    --plugin ./fancyplug.so            -> $CWD/fancyplug.so
     *    --plugin /usr/lib/my/fancyplug.so  -> /usr/lib/my/fancyplug.so
     *
     * Please note that $CWD means the directory OpenVPN is either started from
     * or the directory OpenVPN have changed into using --cd before --plugin
     * was parsed.
     *
     */
    if (!platform_absolute_pathname(p->so_pathname)
        && p->so_pathname[0] != '.')
    {
        char full[PATH_MAX];

        openvpn_snprintf(full, sizeof(full), "%s/%s", PLUGIN_LIBDIR, p->so_pathname);
        p->handle = dlopen(full, RTLD_NOW);
    }
    else
    {
        rel = !platform_absolute_pathname(p->so_pathname);
        p->handle = dlopen(p->so_pathname, RTLD_NOW);
    }
    if (!p->handle)
    {
        msg(M_ERR, "PLUGIN_INIT: could not load plugin shared object %s: %s", p->so_pathname, dlerror());
    }

#define PLUGIN_SYM(var, name, flags) libdl_resolve_symbol(p->handle, (void *)&p->var, name, p->so_pathname, flags)

#else  /* ifndef _WIN32 */

    rel = !platform_absolute_pathname(p->so_pathname);
    p->module = LoadLibraryW(wide_string(p->so_pathname, &gc));
    if (!p->module)
    {
        msg(M_ERR, "PLUGIN_INIT: could not load plugin DLL: %s", p->so_pathname);
    }

#define PLUGIN_SYM(var, name, flags) dll_resolve_symbol(p->module, (void *)&p->var, name, p->so_pathname, flags)

#endif /* ifndef _WIN32 */

    PLUGIN_SYM(open1, "openvpn_plugin_open_v1", 0);
    PLUGIN_SYM(open2, "openvpn_plugin_open_v2", 0);
    PLUGIN_SYM(open3, "openvpn_plugin_open_v3", 0);
    PLUGIN_SYM(func1, "openvpn_plugin_func_v1", 0);
    PLUGIN_SYM(func2, "openvpn_plugin_func_v2", 0);
    PLUGIN_SYM(func3, "openvpn_plugin_func_v3", 0);
    PLUGIN_SYM(close, "openvpn_plugin_close_v1", PLUGIN_SYMBOL_REQUIRED);
    PLUGIN_SYM(abort, "openvpn_plugin_abort_v1", 0);
    PLUGIN_SYM(client_constructor, "openvpn_plugin_client_constructor_v1", 0);
    PLUGIN_SYM(client_destructor, "openvpn_plugin_client_destructor_v1", 0);
    PLUGIN_SYM(min_version_required, "openvpn_plugin_min_version_required_v1", 0);
    PLUGIN_SYM(initialization_point, "openvpn_plugin_select_initialization_point_v1", 0);

    if (!p->open1 && !p->open2 && !p->open3)
    {
        msg(M_FATAL, "PLUGIN: symbol openvpn_plugin_open_vX is undefined in plugin: %s", p->so_pathname);
    }

    if (!p->func1 && !p->func2 && !p->func3)
    {
        msg(M_FATAL, "PLUGIN: symbol openvpn_plugin_func_vX is undefined in plugin: %s", p->so_pathname);
    }

    /*
     * Verify that we are sufficiently up-to-date to handle the plugin
     */
    if (p->min_version_required)
    {
        const int plugin_needs_version = (*p->min_version_required)();
        if (plugin_needs_version > OPENVPN_PLUGIN_VERSION)
        {
            msg(M_FATAL, "PLUGIN_INIT: plugin needs interface version %d, but this version of OpenVPN only supports version %d: %s",
                plugin_needs_version,
                OPENVPN_PLUGIN_VERSION,
                p->so_pathname);
        }
    }

    if (p->initialization_point)
    {
        p->requested_initialization_point = (*p->initialization_point)();
    }
    else
    {
        p->requested_initialization_point = OPENVPN_PLUGIN_INIT_PRE_DAEMON;
    }

    if (rel)
    {
        msg(M_WARN, "WARNING: plugin '%s' specified by a relative pathname -- using an absolute pathname would be more secure", p->so_pathname);
    }

    p->initialized = true;

    gc_free(&gc);
}