summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-04-19 13:46:00 +0200
committerThomas Haller <thaller@redhat.com>2016-04-19 13:47:42 +0200
commit7652e9ebe0c0a52139af763f007a61fd8f694f83 (patch)
treeb413b7c3922eef8d1de9acf2aa0a5b098216fbb5
parent03584e420f58aafaa2d71408deb2b4603dcc3103 (diff)
parente00eac298118b2016da4db78f88a74bb8c0eb4a4 (diff)
downloadNetworkManager-7652e9ebe0c0a52139af763f007a61fd8f694f83.tar.gz
libnm/vpn: merge branch 'th/vpn-load-plugin-bgo765225'
https://bugzilla.gnome.org/show_bug.cgi?id=765225
-rw-r--r--libnm-core/nm-core-internal.h9
-rw-r--r--libnm-core/nm-vpn-editor-plugin.c148
-rw-r--r--libnm-core/nm-vpn-editor-plugin.h5
-rw-r--r--libnm-core/nm-vpn-plugin-info.c31
-rw-r--r--libnm/libnm.ver5
-rw-r--r--shared/nm-shared-utils.c34
-rw-r--r--shared/nm-shared-utils.h3
-rw-r--r--src/nm-config.c2
-rw-r--r--src/nm-core-utils.c34
-rw-r--r--src/nm-core-utils.h5
10 files changed, 185 insertions, 91 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 082ebc9e28..8d97b066ee 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -72,6 +72,7 @@
#include "nm-utils.h"
#include "nm-vpn-dbus-interface.h"
#include "nm-core-types-internal.h"
+#include "nm-vpn-editor-plugin.h"
/* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated
* connection can be replaced by a already-defined connection. This flag only
@@ -245,6 +246,14 @@ GSList *_nm_vpn_plugin_info_list_load_dir (const char *dirname,
NMUtilsCheckFilePredicate check_file,
gpointer user_data);
+NMVpnEditorPlugin * _nm_vpn_editor_plugin_load (const char *plugin_filename,
+ gboolean force_absolute_path,
+ const char *check_service,
+ int check_owner,
+ NMUtilsCheckFilePredicate check_file,
+ gpointer user_data,
+ GError **error);
+
/***********************************************************/
typedef struct {
diff --git a/libnm-core/nm-vpn-editor-plugin.c b/libnm-core/nm-vpn-editor-plugin.c
index 5a1eed88dd..84297a82b7 100644
--- a/libnm-core/nm-vpn-editor-plugin.c
+++ b/libnm-core/nm-vpn-editor-plugin.c
@@ -71,60 +71,55 @@ nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface)
/*********************************************************************/
-/**
- * nm_vpn_editor_plugin_load_from_file:
- * @plugin_filename: The path to the share library to load.
- * Apply some common heuristics to find the library, such as
- * appending "so" file ending.
- * If the path is not an absolute path or no matching module
- * can be found, lookup inside a directory defined at compile time.
- * Due to this, @check_file might be called for two different paths.
- * @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 libary @plugin_filename and create a new
- * #NMVpnEditorPlugin instace via the #NMVpnEditorPluginFactory
- * function.
- *
- * 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_filename,
- const char *check_service,
- int check_owner,
- NMUtilsCheckFilePredicate check_file,
- gpointer user_data,
- GError **error)
+_nm_vpn_editor_plugin_load (const char *plugin_filename,
+ gboolean force_absolute_filename,
+ const char *check_service,
+ int check_owner,
+ NMUtilsCheckFilePredicate check_file,
+ gpointer user_data,
+ GError **error)
{
GModule *module = NULL;
gs_free_error GError *local = NULL;
NMVpnEditorPluginFactory factory = NULL;
NMVpnEditorPlugin *editor_plugin = NULL;
+ gboolean search_lib = FALSE;
g_return_val_if_fail (plugin_filename && *plugin_filename, NULL);
+ if ( !force_absolute_filename
+ && !strchr (plugin_filename, '/')
+ && !g_str_has_suffix (plugin_filename, ".la")) {
+ /* we allow omitting the (absolute) path.
+ *
+ * If the @plugin_filename contains no '/', we skip any checks
+ * for the file and pass it directly to g_module_open()/dlopen().
+ * 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. */
+ search_lib = TRUE;
+ }
+
/* _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,
- &local))
+ if ( search_lib
+ || _nm_utils_check_module_file (plugin_filename,
+ check_owner,
+ check_file,
+ user_data,
+ &local))
module = g_module_open (plugin_filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
if (!module) {
if (local) {
g_propagate_error (error, local);
local = NULL;
+ } else if (search_lib) {
+ g_set_error (error,
+ G_FILE_ERROR,
+ G_FILE_ERROR_NOENT,
+ _("Plugin does not exist (%s)"), plugin_filename);
} else {
g_set_error (error,
NM_VPN_PLUGIN_ERROR,
@@ -201,6 +196,85 @@ nm_vpn_editor_plugin_load_from_file (const char *plugin_filename,
return editor_plugin;
}
+/**
+ * nm_vpn_editor_plugin_load_from_file:
+ * @plugin_filename: The path to the shared library to load.
+ * The path must be an absolute filename to an existing file.
+ * @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 libary @plugin_filename and create a new
+ * #NMVpnEditorPlugin instace via the #NMVpnEditorPluginFactory
+ * function.
+ *
+ * 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_filename,
+ const char *check_service,
+ int check_owner,
+ NMUtilsCheckFilePredicate check_file,
+ gpointer user_data,
+ GError **error)
+{
+ return _nm_vpn_editor_plugin_load (plugin_filename,
+ 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.
+ * If it is an absolute path, for further checks will be
+ * performed on the file (aside from being a regular file
+ * and existing).
+ * The @plugin_name can also be a library name only. In this
+ * case, system dependent directories will be searched for a
+ * matching library.
+ * @check_service: if not-null, check that the loaded plugin advertises
+ * the given service.
+ * @error: on failure the error reason.
+ *
+ * Load the shared libary @plugin_filename and create a new
+ * #NMVpnEditorPlugin instace via the #NMVpnEditorPluginFactory
+ * function.
+ *
+ * This is similar to nm_vpn_editor_plugin_load_from_file(), but
+ * also allows searching for a matching library and not perform
+ * any checks on the file. 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);
+}
+
/*********************************************************************/
/**
diff --git a/libnm-core/nm-vpn-editor-plugin.h b/libnm-core/nm-vpn-editor-plugin.h
index 16e9533d23..7f70a40c2a 100644
--- a/libnm-core/nm-vpn-editor-plugin.h
+++ b/libnm-core/nm-vpn-editor-plugin.h
@@ -147,6 +147,11 @@ NMVpnEditorPlugin *nm_vpn_editor_plugin_load_from_file (const char *plugin_file
gpointer user_data,
GError **error);
+NM_AVAILABLE_IN_1_4
+NMVpnEditorPlugin *nm_vpn_editor_plugin_load (const char *plugin_name,
+ const char *check_service,
+ GError **error);
+
G_END_DECLS
#endif /* __NM_VPN_EDITOR_PLUGIN_H__ */
diff --git a/libnm-core/nm-vpn-plugin-info.c b/libnm-core/nm-vpn-plugin-info.c
index 53278fcac8..6c77f3c142 100644
--- a/libnm-core/nm-vpn-plugin-info.c
+++ b/libnm-core/nm-vpn-plugin-info.c
@@ -620,12 +620,12 @@ nm_vpn_plugin_info_get_program (NMVpnPluginInfo *self)
gboolean
nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self)
{
+ const char *s;
+
g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), FALSE);
- return g_key_file_get_boolean (NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->keyfile,
- NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION,
- "supports-multiple-connections",
- NULL);
+ s = nm_vpn_plugin_info_lookup_property (self, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "supports-multiple-connections");
+ return _nm_utils_ascii_str_to_bool (s, FALSE);
}
@@ -752,12 +752,13 @@ nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *self, GError **error)
}
priv->editor_plugin_loaded = TRUE;
- priv->editor_plugin = nm_vpn_editor_plugin_load_from_file (plugin_filename,
- priv->service,
- getuid (),
- NULL,
- NULL,
- error);
+ priv->editor_plugin = _nm_vpn_editor_plugin_load (plugin_filename,
+ FALSE,
+ priv->service,
+ getuid (),
+ NULL,
+ NULL,
+ error);
return priv->editor_plugin;
}
@@ -877,15 +878,16 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
for (j = 0; keys && keys[j]; j++) {
char *s;
- /* Lookup the value via get_string(). We want that behavior.
- * You could still lookup the original values via g_key_file_get_value()
- * based on priv->keyfile. */
+ /* Lookup the value via get_string(). We want that behavior for all our
+ * values. */
s = g_key_file_get_string (priv->keyfile, groups[i], keys[j], NULL);
if (s)
g_hash_table_insert (priv->keys, _nm_utils_strstrdictkey_create (groups[i], keys[j]), s);
}
}
+ g_clear_pointer (&priv->keyfile, g_key_file_unref);
+
return TRUE;
}
@@ -948,9 +950,10 @@ finalize (GObject *object)
g_free (priv->service);
g_strfreev (priv->aliases);
g_free (priv->filename);
- g_key_file_unref (priv->keyfile);
g_hash_table_unref (priv->keys);
+ g_clear_pointer (&priv->keyfile, g_key_file_unref);
+
G_OBJECT_CLASS (nm_vpn_plugin_info_parent_class)->finalize (object);
}
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 7ece1b2fef..7faac666d0 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1058,3 +1058,8 @@ global:
nm_vpn_service_plugin_set_ip6_config;
nm_vpn_service_plugin_set_login_banner;
} libnm_1_0_0;
+
+libnm_1_4_0 {
+global:
+ nm_vpn_editor_plugin_load;
+} libnm_1_2_0;
diff --git a/shared/nm-shared-utils.c b/shared/nm-shared-utils.c
index 0ae54bdcf0..932b7432c3 100644
--- a/shared/nm-shared-utils.c
+++ b/shared/nm-shared-utils.c
@@ -102,6 +102,40 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma
/*****************************************************************************/
+gint
+_nm_utils_ascii_str_to_bool (const char *str,
+ gint default_value)
+{
+ gsize len;
+ char *s = NULL;
+
+ if (!str)
+ return default_value;
+
+ while (str[0] && g_ascii_isspace (str[0]))
+ str++;
+
+ if (!str[0])
+ return default_value;
+
+ len = strlen (str);
+ if (g_ascii_isspace (str[len - 1])) {
+ s = g_strdup (str);
+ g_strchomp (s);
+ str = s;
+ }
+
+ if (!g_ascii_strcasecmp (str, "true") || !g_ascii_strcasecmp (str, "yes") || !g_ascii_strcasecmp (str, "on") || !g_ascii_strcasecmp (str, "1"))
+ default_value = TRUE;
+ else if (!g_ascii_strcasecmp (str, "false") || !g_ascii_strcasecmp (str, "no") || !g_ascii_strcasecmp (str, "off") || !g_ascii_strcasecmp (str, "0"))
+ default_value = FALSE;
+ if (s)
+ g_free (s);
+ return default_value;
+}
+
+/*****************************************************************************/
+
G_DEFINE_QUARK (nm-utils-error-quark, nm_utils_error)
void
diff --git a/shared/nm-shared-utils.h b/shared/nm-shared-utils.h
index f80c850c69..cfa8f994f7 100644
--- a/shared/nm-shared-utils.h
+++ b/shared/nm-shared-utils.h
@@ -26,6 +26,9 @@
gint64 _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 max, gint64 fallback);
+gint _nm_utils_ascii_str_to_bool (const char *str,
+ gint default_value);
+
/******************************************************************************/
/**
diff --git a/src/nm-config.c b/src/nm-config.c
index 669812c40a..f7c47497a7 100644
--- a/src/nm-config.c
+++ b/src/nm-config.c
@@ -157,7 +157,7 @@ gint
nm_config_parse_boolean (const char *str,
gint default_value)
{
- return nm_utils_ascii_str_to_bool (str, default_value);
+ return _nm_utils_ascii_str_to_bool (str, default_value);
}
gint
diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c
index 714aaa9279..bbe466545d 100644
--- a/src/nm-core-utils.c
+++ b/src/nm-core-utils.c
@@ -154,40 +154,6 @@ _nm_singleton_instance_register_destruction (GObject *instance)
/*****************************************************************************/
-gint
-nm_utils_ascii_str_to_bool (const char *str,
- gint default_value)
-{
- gsize len;
- char *s = NULL;
-
- if (!str)
- return default_value;
-
- while (str[0] && g_ascii_isspace (str[0]))
- str++;
-
- if (!str[0])
- return default_value;
-
- len = strlen (str);
- if (g_ascii_isspace (str[len - 1])) {
- s = g_strdup (str);
- g_strchomp (s);
- str = s;
- }
-
- if (!g_ascii_strcasecmp (str, "true") || !g_ascii_strcasecmp (str, "yes") || !g_ascii_strcasecmp (str, "on") || !g_ascii_strcasecmp (str, "1"))
- default_value = TRUE;
- else if (!g_ascii_strcasecmp (str, "false") || !g_ascii_strcasecmp (str, "no") || !g_ascii_strcasecmp (str, "off") || !g_ascii_strcasecmp (str, "0"))
- default_value = FALSE;
- if (s)
- g_free (s);
- return default_value;
-}
-
-/*****************************************************************************/
-
/*
* nm_ethernet_address_is_valid:
* @addr: pointer to a binary or ASCII Ethernet address
diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h
index 280be04736..528288c34c 100644
--- a/src/nm-core-utils.h
+++ b/src/nm-core-utils.h
@@ -91,11 +91,6 @@ GETTER (void) \
/*****************************************************************************/
-gint nm_utils_ascii_str_to_bool (const char *str,
- gint default_value);
-
-/*****************************************************************************/
-
gboolean nm_ethernet_address_is_valid (gconstpointer addr, gssize len);
in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen);