diff options
author | Thomas Haller <thaller@redhat.com> | 2016-04-19 13:46:00 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2016-04-19 13:47:42 +0200 |
commit | 7652e9ebe0c0a52139af763f007a61fd8f694f83 (patch) | |
tree | b413b7c3922eef8d1de9acf2aa0a5b098216fbb5 | |
parent | 03584e420f58aafaa2d71408deb2b4603dcc3103 (diff) | |
parent | e00eac298118b2016da4db78f88a74bb8c0eb4a4 (diff) | |
download | NetworkManager-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.h | 9 | ||||
-rw-r--r-- | libnm-core/nm-vpn-editor-plugin.c | 148 | ||||
-rw-r--r-- | libnm-core/nm-vpn-editor-plugin.h | 5 | ||||
-rw-r--r-- | libnm-core/nm-vpn-plugin-info.c | 31 | ||||
-rw-r--r-- | libnm/libnm.ver | 5 | ||||
-rw-r--r-- | shared/nm-shared-utils.c | 34 | ||||
-rw-r--r-- | shared/nm-shared-utils.h | 3 | ||||
-rw-r--r-- | src/nm-config.c | 2 | ||||
-rw-r--r-- | src/nm-core-utils.c | 34 | ||||
-rw-r--r-- | src/nm-core-utils.h | 5 |
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); |