summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-04-22 14:17:21 +0200
committerThomas Haller <thaller@redhat.com>2016-04-22 14:17:21 +0200
commit2d59e70c6f8161bf2fe08a05351a7e3d826834ff (patch)
treec3565d7c4b9cc928ccd835b506e98eacb448af90
parentcf0c300058722a01898770f1e061ab2dfebf3b71 (diff)
parent4271c9650c1cfcbd487cc471099b1c0c9bbfa290 (diff)
downloadNetworkManager-2d59e70c6f8161bf2fe08a05351a7e3d826834ff.tar.gz
libnm/vpn: merge branch 'th/vpn-auth-dialog-bgo765329'
https://bugzilla.gnome.org/show_bug.cgi?id=765329
-rw-r--r--libnm-core/Makefile.am1
-rw-r--r--libnm-core/nm-vpn-plugin-info.c170
-rw-r--r--libnm-core/nm-vpn-plugin-info.h10
-rw-r--r--libnm/libnm.ver4
-rw-r--r--src/vpn-manager/nm-vpn-connection.c6
5 files changed, 169 insertions, 22 deletions
diff --git a/libnm-core/Makefile.am b/libnm-core/Makefile.am
index c4d348aa75..695b6a3a58 100644
--- a/libnm-core/Makefile.am
+++ b/libnm-core/Makefile.am
@@ -12,6 +12,7 @@ AM_CPPFLAGS = \
-DNMCONFDIR=\"$(nmconfdir)\" \
-DNMLIBDIR=\"$(nmlibdir)\" \
-DNMPLUGINDIR=\"$(pkglibdir)\" \
+ -DLIBEXECDIR=\"$(libexecdir)\" \
-DNETWORKMANAGER_COMPILATION=NM_NETWORKMANAGER_COMPILATION_LIB \
$(GLIB_CFLAGS) \
$(CODE_COVERAGE_CFLAGS) \
diff --git a/libnm-core/nm-vpn-plugin-info.c b/libnm-core/nm-vpn-plugin-info.c
index 2e6275e341..9ffa04706a 100644
--- a/libnm-core/nm-vpn-plugin-info.c
+++ b/libnm-core/nm-vpn-plugin-info.c
@@ -45,6 +45,7 @@ typedef struct {
char *filename;
char *name;
char *service;
+ char *auth_dialog;
char **aliases;
GKeyFile *keyfile;
@@ -188,6 +189,23 @@ _sort_files (LoadDirInfo *a, LoadDirInfo *b)
nm_vpn_plugin_info_get_filename (b->plugin_info));
}
+#define DEFINE_DEFAULT_DIR_LIST(dir) \
+ const char *dir[] = { \
+ /* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with
+ * preference to the former.
+ *
+ * load user directory with highest priority. */ \
+ _nm_vpn_plugin_info_get_default_dir_user (), \
+ \
+ /* lib directory has higher priority then etc. The reason is that
+ * etc is deprecated and used by old plugins. We expect newer plugins
+ * to install their file in lib, where they have higher priority.
+ *
+ * Optimally, there are no duplicates anyway, so it doesn't really matter. */ \
+ _nm_vpn_plugin_info_get_default_dir_lib (), \
+ _nm_vpn_plugin_info_get_default_dir_etc (), \
+ }
+
/**
* _nm_vpn_plugin_info_get_default_dir_etc:
*
@@ -253,7 +271,10 @@ _nm_vpn_plugin_info_list_load_dir (const char *dirname,
GSList *res = NULL;
guint i;
- g_return_val_if_fail (dirname && dirname[0], NULL);
+ g_return_val_if_fail (dirname, NULL);
+
+ if (!dirname[0])
+ return NULL;
dir = g_dir_open (dirname, 0, NULL);
if (!dir)
@@ -312,21 +333,7 @@ nm_vpn_plugin_info_list_load ()
gint64 uid;
GSList *list = NULL;
GSList *infos, *info;
- const char *dir[] = {
- /* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with
- * preference to the former.
- *
- * load user directory with highest priority. */
- _nm_vpn_plugin_info_get_default_dir_user (),
-
- /* lib directory has higher priority then etc. The reason is that
- * etc is deprecated and used by old plugins. We expect newer plugins
- * to install their file in lib, where they have higher priority.
- *
- * Optimally, there are no duplicates anyway, so it doesn't really matter. */
- _nm_vpn_plugin_info_get_default_dir_lib (),
- _nm_vpn_plugin_info_get_default_dir_etc (),
- };
+ DEFINE_DEFAULT_DIR_LIST (dir);
uid = getuid ();
@@ -345,6 +352,60 @@ nm_vpn_plugin_info_list_load ()
return list;
}
+/**
+ * nm_vpn_plugin_info_new_search_file:
+ * @name: (allow-none): the name to search for. Either @name or @service
+ * must be present.
+ * @service: (allow-none): the service to search for. Either @name or
+ * @service must be present.
+ *
+ * This has the same effect as doing a full nm_vpn_plugin_info_list_load()
+ * followed by a search for the first matching VPN plugin info that has the
+ * given @name and/or @service.
+ *
+ * Returns: (transfer full): a newly created instance of plugin info
+ * or %NULL if no matching value was found.
+ *
+ * Since: 1.4
+ */
+NMVpnPluginInfo *
+nm_vpn_plugin_info_new_search_file (const char *name, const char *service)
+{
+ int i;
+ gint64 uid;
+ NMVpnPluginInfo *plugin_info = NULL;
+ GSList *infos, *info;
+ DEFINE_DEFAULT_DIR_LIST (dir);
+
+ if (!name && !service)
+ g_return_val_if_reached (NULL);
+
+ uid = getuid ();
+
+ for (i = 0; !plugin_info && i < G_N_ELEMENTS (dir); i++) {
+ if ( !dir[i]
+ || _nm_utils_strv_find_first ((char **) dir, i, dir[i]) >= 0)
+ continue;
+
+ /* We still must load the entire directory while searching for the matching
+ * plugin-info. The reason is that reading the directory has no stable
+ * order and we can only sort them after reading the entire directory --
+ * which _nm_vpn_plugin_info_list_load_dir() does. */
+ infos = _nm_vpn_plugin_info_list_load_dir (dir[i], TRUE, uid, NULL, NULL);
+
+ for (info = infos; info; info = info->next) {
+ if ( (!name || nm_streq (nm_vpn_plugin_info_get_name (info->data), name))
+ && (!service || nm_streq (nm_vpn_plugin_info_get_service (info->data), service))) {
+ plugin_info = g_object_ref (info->data);
+ break;
+ }
+ }
+
+ g_slist_free_full (infos, g_object_unref);
+ }
+ return plugin_info;
+}
+
/*********************************************************************/
static gboolean
@@ -525,7 +586,7 @@ nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service)
/* First, consider the primary service name. */
for (iter = list; iter; iter = iter->next) {
- if (strcmp (NM_VPN_PLUGIN_INFO_GET_PRIVATE (iter->data)->service, service) == 0)
+ if (strcmp (nm_vpn_plugin_info_get_service (iter->data), service) == 0)
return iter->data;
}
@@ -576,6 +637,78 @@ nm_vpn_plugin_info_get_name (NMVpnPluginInfo *self)
}
/**
+ * nm_vpn_plugin_info_get_service:
+ * @self: plugin info instance
+ *
+ * Returns: (transfer none): the service. Cannot be %NULL.
+ *
+ * Since: 1.4
+ */
+const char *
+nm_vpn_plugin_info_get_service (NMVpnPluginInfo *self)
+{
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
+
+ return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->service;
+}
+
+/**
+ * nm_vpn_plugin_info_get_auth_dialog:
+ * @self: plugin info instance
+ *
+ * Returns: the absolute path to the auth-dialog helper or %NULL.
+ *
+ * Since: 1.4
+ **/
+const char *
+nm_vpn_plugin_info_get_auth_dialog (NMVpnPluginInfo *self)
+{
+ NMVpnPluginInfoPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
+
+ priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
+
+ if (G_UNLIKELY (priv->auth_dialog == NULL)) {
+ const char *s;
+
+ s = g_hash_table_lookup (priv->keys, _nm_utils_strstrdictkey_static (NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "auth-dialog"));
+ if (!s || !s[0])
+ priv->auth_dialog = g_strdup ("");
+ else if (g_path_is_absolute (s))
+ priv->auth_dialog = g_strdup (s);
+ else {
+ gs_free char *prog_basename;
+
+ /* for relative paths, we take the basename and assume it's in LIBEXECDIR. */
+ prog_basename = g_path_get_basename (s);
+ priv->auth_dialog = g_build_filename (LIBEXECDIR, prog_basename, NULL);
+ }
+ }
+
+ return priv->auth_dialog[0] ? priv->auth_dialog : NULL;
+}
+
+/**
+ * nm_vpn_plugin_info_supports_hints:
+ * @self: plugin info instance
+ *
+ * Returns: %TRUE if the supports hints for secret requests, otherwise %FALSE
+ *
+ * Since: 1.4
+ */
+gboolean
+nm_vpn_plugin_info_supports_hints (NMVpnPluginInfo *self)
+{
+ const char *s;
+
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), FALSE);
+
+ s = nm_vpn_plugin_info_lookup_property (self, NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "supports-hints");
+ return _nm_utils_ascii_str_to_bool (s, FALSE);
+}
+
+/**
* nm_vpn_plugin_info_get_plugin:
* @self: plugin info instance
*
@@ -753,7 +886,7 @@ 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,
+ nm_vpn_plugin_info_get_service (self),
getuid (),
NULL,
NULL,
@@ -947,6 +1080,7 @@ finalize (GObject *object)
g_free (priv->name);
g_free (priv->service);
+ g_free (priv->auth_dialog);
g_strfreev (priv->aliases);
g_free (priv->filename);
g_hash_table_unref (priv->keys);
diff --git a/libnm-core/nm-vpn-plugin-info.h b/libnm-core/nm-vpn-plugin-info.h
index 667a4fe2d9..9844625cfc 100644
--- a/libnm-core/nm-vpn-plugin-info.h
+++ b/libnm-core/nm-vpn-plugin-info.h
@@ -70,14 +70,24 @@ NMVpnPluginInfo *nm_vpn_plugin_info_new_with_data (const char *filename,
GKeyFile *keyfile,
GError **error);
+NM_AVAILABLE_IN_1_4
+NMVpnPluginInfo *nm_vpn_plugin_info_new_search_file (const char *name,
+ const char *service);
+
NM_AVAILABLE_IN_1_2
const char *nm_vpn_plugin_info_get_name (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
const char *nm_vpn_plugin_info_get_filename (NMVpnPluginInfo *self);
+NM_AVAILABLE_IN_1_4
+const char *nm_vpn_plugin_info_get_service (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
const char *nm_vpn_plugin_info_get_plugin (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
const char *nm_vpn_plugin_info_get_program (NMVpnPluginInfo *self);
+NM_AVAILABLE_IN_1_4
+const char *nm_vpn_plugin_info_get_auth_dialog (NMVpnPluginInfo *self);
+NM_AVAILABLE_IN_1_4
+gboolean nm_vpn_plugin_info_supports_hints (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
gboolean nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self);
NM_AVAILABLE_IN_1_2
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 7faac666d0..e40a8d8e2e 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -1062,4 +1062,8 @@ global:
libnm_1_4_0 {
global:
nm_vpn_editor_plugin_load;
+ nm_vpn_plugin_info_get_auth_dialog;
+ nm_vpn_plugin_info_get_service;
+ nm_vpn_plugin_info_new_search_file;
+ nm_vpn_plugin_info_supports_hints;
} libnm_1_2_0;
diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c
index a1cd0c3289..32f6a79756 100644
--- a/src/vpn-manager/nm-vpn-connection.c
+++ b/src/vpn-manager/nm-vpn-connection.c
@@ -2019,10 +2019,8 @@ nm_vpn_connection_activate (NMVpnConnection *self,
s_vpn = nm_connection_get_setting_vpn (_get_applied_connection (self));
g_return_if_fail (s_vpn);
- service = nm_vpn_plugin_info_lookup_property (plugin_info,
- NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION,
- "service");
- g_return_if_fail (service);
+ service = nm_vpn_plugin_info_get_service (plugin_info);
+ nm_assert (service);
if (nm_vpn_plugin_info_supports_multiple (plugin_info)) {
const char *path;