Exemplo n.º 1
0
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)
{
  ASSERT (p->initialized);

  /* clear return list */
  if (retlist)
    *retlist = NULL;

  if (!p->plugin_handle && init_point == p->requested_initialization_point)
    {
      struct gc_arena gc = gc_new ();

      dmsg (D_PLUGIN_DEBUG, "PLUGIN_INIT: PRE");
      plugin_show_args_env (D_PLUGIN_DEBUG, o->argv, envp);

      /*
       * Call the plugin initialization
       */
      if (p->open2)
	p->plugin_handle = (*p->open2)(&p->plugin_type_mask, o->argv, envp, retlist);
      else if (p->open1)
	p->plugin_handle = (*p->open1)(&p->plugin_type_mask, o->argv, envp);
      else
	ASSERT (0);

      msg (D_PLUGIN, "PLUGIN_INIT: POST %s '%s' intercepted=%s %s",
	   p->so_pathname,
	   print_argv (o->argv, &gc, PA_BRACKET),
	   plugin_mask_string (p->plugin_type_mask, &gc),
	   (retlist && *retlist) ? "[RETLIST]" : "");
      
      if ((p->plugin_type_mask | plugin_supported_types()) != plugin_supported_types())
	msg (M_FATAL, "PLUGIN_INIT: plugin %s expressed interest in unsupported plugin types: [want=0x%08x, have=0x%08x]",
	     p->so_pathname,
	     p->plugin_type_mask,
	     plugin_supported_types());

      if (p->plugin_handle == NULL)
	msg (M_FATAL, "PLUGIN_INIT: plugin initialization function failed: %s",
	     p->so_pathname);

      gc_free (&gc);
    }
}
Exemplo n.º 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 ();

#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);
}
Exemplo n.º 3
0
static void
plugin_open_item (struct plugin *p,
		  const struct plugin_option *o,
		  struct vpnconnect_plugin_string_list **retlist,
		  const char **envp,
		  const int init_point)
{
  ASSERT (p->initialized);

  /* clear return list */
  if (retlist)
    *retlist = NULL;

  if (!p->plugin_handle && init_point == p->requested_initialization_point)
    {
      struct gc_arena gc = gc_new ();

      dmsg (D_PLUGIN_DEBUG, "PLUGIN_INIT: PRE");
      plugin_show_args_env (D_PLUGIN_DEBUG, o->argv, envp);

      /*
       * Call the plugin initialization
       */
      if (p->open3) {
        struct vpnconnect_plugin_args_open_in args = { p->plugin_type_mask,
                                                    (const char ** const) o->argv,
                                                    (const char ** const) envp,
                                                    &callbacks,
                                                    SSLAPI,
                                                    PACKAGE_VERSION,
                                                    VPNCONNECT_VERSION_MAJOR,
                                                    VPNCONNECT_VERSION_MINOR,
                                                    _VPNCONNECT_PATCH_LEVEL
        };
        struct vpnconnect_plugin_args_open_return retargs;

        CLEAR(retargs);
        retargs.return_list = retlist;
        if ((*p->open3)(VPNCONNECT_PLUGINv3_STRUCTVER, &args, &retargs) == VPNCONNECT_PLUGIN_FUNC_SUCCESS) {
          p->plugin_type_mask = retargs.type_mask;
          p->plugin_handle = retargs.handle;
        } else {
          p->plugin_handle = NULL;
        }
      } else if (p->open2)
	p->plugin_handle = (*p->open2)(&p->plugin_type_mask, o->argv, envp, retlist);
      else if (p->open1)
	p->plugin_handle = (*p->open1)(&p->plugin_type_mask, o->argv, envp);
      else
	ASSERT (0);

      msg (D_PLUGIN, "PLUGIN_INIT: POST %s '%s' intercepted=%s %s",
	   p->so_pathname,
	   print_argv (o->argv, &gc, PA_BRACKET),
	   plugin_mask_string (p->plugin_type_mask, &gc),
	   (retlist && *retlist) ? "[RETLIST]" : "");
      
      if ((p->plugin_type_mask | plugin_supported_types()) != plugin_supported_types())
	msg (M_FATAL, "PLUGIN_INIT: plugin %s expressed interest in unsupported plugin types: [want=0x%08x, have=0x%08x]",
	     p->so_pathname,
	     p->plugin_type_mask,
	     plugin_supported_types());

      if (p->plugin_handle == NULL)
	msg (M_FATAL, "PLUGIN_INIT: plugin initialization function failed: %s",
	     p->so_pathname);

      gc_free (&gc);
    }
}
Exemplo n.º 4
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);
}