diff options
Diffstat (limited to 'libnm-core/nm-vpn-editor-plugin.c')
| -rw-r--r-- | libnm-core/nm-vpn-editor-plugin.c | 518 |
1 files changed, 0 insertions, 518 deletions
diff --git a/libnm-core/nm-vpn-editor-plugin.c b/libnm-core/nm-vpn-editor-plugin.c deleted file mode 100644 index e68bdc24..00000000 --- a/libnm-core/nm-vpn-editor-plugin.c +++ /dev/null @@ -1,518 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -/* - * Copyright (C) 2008 Novell, Inc. - * Copyright (C) 2008 - 2010 Red Hat, Inc. - * Copyright (C) 2015 Red Hat, Inc. - */ - -#include "libnm-core/nm-default-libnm-core.h" - -#include "nm-vpn-editor-plugin.h" - -#include <dlfcn.h> -#include <gmodule.h> - -#include "nm-core-internal.h" - -/*****************************************************************************/ - -static void nm_vpn_editor_plugin_default_init(NMVpnEditorPluginInterface *iface); - -G_DEFINE_INTERFACE(NMVpnEditorPlugin, nm_vpn_editor_plugin, G_TYPE_OBJECT) - -static void -nm_vpn_editor_plugin_default_init(NMVpnEditorPluginInterface *iface) -{ - /** - * NMVpnEditorPlugin:name: - * - * Short display name of the VPN plugin. - */ - g_object_interface_install_property( - iface, - g_param_spec_string(NM_VPN_EDITOR_PLUGIN_NAME, - "", - "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - /** - * NMVpnEditorPlugin:description: - * - * Longer description of the VPN plugin. - */ - g_object_interface_install_property( - iface, - g_param_spec_string(NM_VPN_EDITOR_PLUGIN_DESCRIPTION, - "", - "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); - - /** - * NMVpnEditorPlugin:service: - * - * D-Bus service name of the plugin's VPN service. - */ - g_object_interface_install_property( - iface, - g_param_spec_string(NM_VPN_EDITOR_PLUGIN_SERVICE, - "", - "", - NULL, - G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); -} - -/*****************************************************************************/ - -typedef struct { - NMVpnPluginInfo *plugin_info; -} NMVpnEditorPluginPrivate; - -static void -_private_destroy(gpointer data) -{ - NMVpnEditorPluginPrivate *priv = data; - - if (priv->plugin_info) - g_object_remove_weak_pointer((GObject *) priv->plugin_info, - (gpointer *) &priv->plugin_info); - - g_slice_free(NMVpnEditorPluginPrivate, priv); -} - -static NMVpnEditorPluginPrivate * -_private_get(NMVpnEditorPlugin *plugin, gboolean create) -{ - static GQuark quark = 0; - NMVpnEditorPluginPrivate *priv; - - nm_assert(NM_IS_VPN_EDITOR_PLUGIN(plugin)); - - if (G_UNLIKELY(quark == 0)) - quark = g_quark_from_string("nm-vpn-editor-plugin-private"); - - priv = g_object_get_qdata((GObject *) plugin, quark); - if (G_LIKELY(priv)) - return priv; - if (!create) - return NULL; - priv = g_slice_new0(NMVpnEditorPluginPrivate); - g_object_set_qdata_full((GObject *) plugin, quark, priv, _private_destroy); - return priv; -} - -#define NM_VPN_EDITOR_PLUGIN_GET_PRIVATE(plugin) _private_get(plugin, TRUE) -#define NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE(plugin) _private_get(plugin, FALSE) - -/*****************************************************************************/ - -/** - * nm_vpn_editor_plugin_get_plugin_info: - * @plugin: the #NMVpnEditorPlugin instance - * - * Returns: (transfer none): if set, return the #NMVpnPluginInfo instance. - * - * Since: 1.4 - */ -NMVpnPluginInfo * -nm_vpn_editor_plugin_get_plugin_info(NMVpnEditorPlugin *plugin) -{ - NMVpnEditorPluginPrivate *priv; - - g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); - - priv = NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE(plugin); - return priv ? priv->plugin_info : NULL; -} - -/** - * nm_vpn_editor_plugin_set_plugin_info: - * @plugin: the #NMVpnEditorPlugin instance - * @plugin_info: (allow-none): a #NMVpnPluginInfo instance or %NULL - * - * Set or clear the plugin-info instance. - * This takes a weak reference on @plugin_info, to avoid circular - * reference as the plugin-info might also reference the editor-plugin. - * - * Since: 1.4 - */ -void -nm_vpn_editor_plugin_set_plugin_info(NMVpnEditorPlugin *plugin, NMVpnPluginInfo *plugin_info) -{ - NMVpnEditorPluginInterface *interface; - NMVpnEditorPluginPrivate * priv; - - g_return_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin)); - - if (!plugin_info) { - priv = NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE(plugin); - if (!priv) - return; - } else { - g_return_if_fail(NM_IS_VPN_PLUGIN_INFO(plugin_info)); - priv = NM_VPN_EDITOR_PLUGIN_GET_PRIVATE(plugin); - } - - if (priv->plugin_info == plugin_info) - return; - if (priv->plugin_info) - g_object_remove_weak_pointer((GObject *) priv->plugin_info, - (gpointer *) &priv->plugin_info); - priv->plugin_info = plugin_info; - if (priv->plugin_info) - g_object_add_weak_pointer((GObject *) priv->plugin_info, (gpointer *) &priv->plugin_info); - - if (plugin_info) { - interface = NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin); - if (interface->notify_plugin_info_set) - interface->notify_plugin_info_set(plugin, plugin_info); - } -} - -/*****************************************************************************/ - -/** - * nm_vpn_editor_plugin_get_vt: - * @plugin: the #NMVpnEditorPlugin - * @vt: (out): buffer to be filled with the VT table of the plugin - * @vt_size: the size of the buffer. Can be 0 to only query the - * size of plugin's VT. - * - * Returns an opaque VT function table for the plugin to extend - * functionality. The actual meaning of NMVpnEditorPluginVT is not - * defined in public API of libnm, instead it must be agreed by - * both the plugin and the caller. See the header-only file - * 'nm-vpn-editor-plugin-call.h' which defines the meaning. - * - * Returns: the actual size of the @plugin's virtual function table. - * - * Since: 1.4 - **/ -gsize -nm_vpn_editor_plugin_get_vt(NMVpnEditorPlugin *plugin, NMVpnEditorPluginVT *vt, gsize vt_size) -{ - const NMVpnEditorPluginVT * p_vt = NULL; - gsize p_vt_size = 0; - NMVpnEditorPluginInterface *interface; - - g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), 0); - - if (vt_size) { - g_return_val_if_fail(vt, 0); - memset(vt, 0, vt_size); - } - - interface = NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin); - if (interface->get_vt) { - p_vt = interface->get_vt(plugin, &p_vt_size); - if (!p_vt) - p_vt_size = 0; - g_return_val_if_fail(p_vt_size, 0); - memcpy(vt, p_vt, MIN(vt_size, p_vt_size)); - } - - return p_vt_size; -} - -/*****************************************************************************/ - -static NMVpnEditorPlugin * -_nm_vpn_editor_plugin_load(const char * plugin_name, - gboolean do_file_checks, - const char * check_service, - int check_owner, - NMUtilsCheckFilePredicate check_file, - gpointer user_data, - GError ** error) -{ - void * dl_module = NULL; - gboolean loaded_before; - NMVpnEditorPluginFactory factory = NULL; - gs_unref_object NMVpnEditorPlugin *editor_plugin = NULL; - gs_free char * plugin_filename_free = NULL; - const char * plugin_filename; - gs_free_error GError *factory_error = NULL; - gs_free char * plug_name = NULL; - gs_free char * plug_service = NULL; - - g_return_val_if_fail(plugin_name && *plugin_name, NULL); - - /* if @do_file_checks is FALSE, we pass plugin_name directly to - * g_module_open(). - * - * Otherwise, we allow for library names without path component. - * In which case, we prepend the plugin directory and form an - * absolute path. In that case, we perform checks on the file. - * - * One exception is that we don't allow for the "la" suffix. The - * reason is that g_module_open() interprets files with this extension - * special and we don't want that. */ - plugin_filename = plugin_name; - if (do_file_checks) { - if (!strchr(plugin_name, '/') && !g_str_has_suffix(plugin_name, ".la")) { - plugin_filename_free = g_module_build_path(NMVPNDIR, plugin_name); - plugin_filename = plugin_filename_free; - } - } - - dl_module = dlopen(plugin_filename, RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD); - if (!dl_module && do_file_checks) { - /* If the module is already loaded, we skip the file checks. - * - * _nm_utils_check_module_file() fails with ENOENT if the plugin file - * does not exist. That is relevant, because nm-applet checks for that. */ - if (!_nm_utils_check_module_file(plugin_filename, - check_owner, - check_file, - user_data, - error)) - return NULL; - } - - if (dl_module) { - loaded_before = TRUE; - } else { - loaded_before = FALSE; - dl_module = dlopen(plugin_filename, RTLD_LAZY | RTLD_LOCAL); - } - - if (!dl_module) { - g_set_error(error, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_FAILED, - _("cannot load plugin \"%s\": %s"), - plugin_name, - dlerror() ?: "unknown reason"); - return NULL; - } - - factory = dlsym(dl_module, "nm_vpn_editor_plugin_factory"); - if (!factory) { - g_set_error(error, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_FAILED, - _("failed to load nm_vpn_editor_plugin_factory() from %s (%s)"), - plugin_name, - dlerror()); - dlclose(dl_module); - return NULL; - } - - editor_plugin = factory(&factory_error); - - if (loaded_before) { - /* we want to leak the library, because the factory will register glib - * types, which cannot be unregistered. - * - * However, if the library was already loaded before, we want to return - * our part of the reference count. */ - dlclose(dl_module); - } - - if (!editor_plugin) { - if (factory_error) { - g_propagate_error(error, factory_error); - factory_error = NULL; - } else { - g_set_error(error, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_FAILED, - _("unknown error initializing plugin %s"), - plugin_name); - } - return NULL; - } - - g_return_val_if_fail(G_IS_OBJECT(editor_plugin), NULL); - - /* Validate plugin properties */ - g_object_get(G_OBJECT(editor_plugin), - NM_VPN_EDITOR_PLUGIN_NAME, - &plug_name, - NM_VPN_EDITOR_PLUGIN_SERVICE, - &plug_service, - NULL); - - if (!plug_name || !*plug_name) { - g_set_error(error, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_FAILED, - _("cannot load VPN plugin in '%s': missing plugin name"), - plugin_name); - return NULL; - } - if (check_service && g_strcmp0(plug_service, check_service) != 0) { - g_set_error(error, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_FAILED, - _("cannot load VPN plugin in '%s': invalid service name"), - plugin_name); - return NULL; - } - - return g_steal_pointer(&editor_plugin); -} - -/** - * nm_vpn_editor_plugin_load_from_file: - * @plugin_name: The path or name of the shared library to load. - * The path must either be an absolute filename to an existing file. - * Alternatively, it can be the name (without path) of a library in the - * plugin directory of NetworkManager. - * @check_service: if not-null, check that the loaded plugin advertises - * the given service. - * @check_owner: if non-negative, check whether the file is owned - * by UID @check_owner or by root. In this case also check that - * the file is not writable by anybody else. - * @check_file: (scope call): optional callback to validate the file prior to - * loading the shared library. - * @user_data: user data for @check_file - * @error: on failure the error reason. - * - * Load the shared library @plugin_name and create a new - * #NMVpnEditorPlugin instance via the #NMVpnEditorPluginFactory - * function. - * - * If @plugin_name is not an absolute path name, it assumes the file - * is in the plugin directory of NetworkManager. In any case, the call - * will do certain checks on the file before passing it to dlopen. - * A consequence for that is, that you cannot omit the ".so" suffix - * as you could for nm_vpn_editor_plugin_load(). - * - * Returns: (transfer full): a new plugin instance or %NULL on error. - * - * Since: 1.2 - */ -NMVpnEditorPlugin * -nm_vpn_editor_plugin_load_from_file(const char * plugin_name, - const char * check_service, - int check_owner, - NMUtilsCheckFilePredicate check_file, - gpointer user_data, - GError ** error) -{ - return _nm_vpn_editor_plugin_load(plugin_name, - TRUE, - check_service, - check_owner, - check_file, - user_data, - error); -} - -/** - * nm_vpn_editor_plugin_load: - * @plugin_name: The name of the shared library to load. - * This path will be directly passed to dlopen() without - * further checks. - * @check_service: if not-null, check that the loaded plugin advertises - * the given service. - * @error: on failure the error reason. - * - * Load the shared library @plugin_name and create a new - * #NMVpnEditorPlugin instance via the #NMVpnEditorPluginFactory - * function. - * - * This is similar to nm_vpn_editor_plugin_load_from_file(), but - * it does no validation of the plugin name, instead passes it directly - * to dlopen(). If you have the full path to a plugin file, - * nm_vpn_editor_plugin_load_from_file() is preferred. - * - * Returns: (transfer full): a new plugin instance or %NULL on error. - * - * Since: 1.4 - */ -NMVpnEditorPlugin * -nm_vpn_editor_plugin_load(const char *plugin_name, const char *check_service, GError **error) -{ - return _nm_vpn_editor_plugin_load(plugin_name, FALSE, check_service, -1, NULL, NULL, error); -} - -/*****************************************************************************/ - -/** - * nm_vpn_editor_plugin_get_editor: - * @plugin: the #NMVpnEditorPlugin - * @connection: the #NMConnection to be edited - * @error: on return, an error or %NULL - * - * Returns: (transfer full): a new #NMVpnEditor or %NULL on error - */ -NMVpnEditor * -nm_vpn_editor_plugin_get_editor(NMVpnEditorPlugin *plugin, NMConnection *connection, GError **error) -{ - g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); - - return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->get_editor(plugin, connection, error); -} - -NMVpnEditorPluginCapability -nm_vpn_editor_plugin_get_capabilities(NMVpnEditorPlugin *plugin) -{ - g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), 0); - - return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->get_capabilities(plugin); -} - -/** - * nm_vpn_editor_plugin_import: - * @plugin: the #NMVpnEditorPlugin - * @path: full path to the file to attempt to read into a new #NMConnection - * @error: on return, an error or %NULL - * - * Returns: (transfer full): a new #NMConnection imported from @path, or %NULL - * on error or if the file at @path was not recognized by this plugin - */ -NMConnection * -nm_vpn_editor_plugin_import(NMVpnEditorPlugin *plugin, const char *path, GError **error) -{ - g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); - - if (nm_vpn_editor_plugin_get_capabilities(plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT) { - g_return_val_if_fail(NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->import_from_file != NULL, - NULL); - return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->import_from_file(plugin, path, error); - } - - g_set_error(error, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_FAILED, - _("the plugin does not support import capability")); - return NULL; -} - -gboolean -nm_vpn_editor_plugin_export(NMVpnEditorPlugin *plugin, - const char * path, - NMConnection * connection, - GError ** error) -{ - g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), FALSE); - - if (nm_vpn_editor_plugin_get_capabilities(plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT) { - g_return_val_if_fail(NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->export_to_file != NULL, - FALSE); - return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->export_to_file(plugin, - path, - connection, - error); - } - - g_set_error(error, - NM_VPN_PLUGIN_ERROR, - NM_VPN_PLUGIN_ERROR_FAILED, - _("the plugin does not support export capability")); - return FALSE; -} - -char * -nm_vpn_editor_plugin_get_suggested_filename(NMVpnEditorPlugin *plugin, NMConnection *connection) -{ - g_return_val_if_fail(NM_IS_VPN_EDITOR_PLUGIN(plugin), NULL); - - if (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->get_suggested_filename) - return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE(plugin)->get_suggested_filename(plugin, - connection); - return NULL; -} |