Blame libnm-core/nm-vpn-plugin-info.c

Packit Service b23acc
// SPDX-License-Identifier: LGPL-2.1+
Packit Service b23acc
/*
Packit Service b23acc
 * Copyright (C) 2015 Red Hat, Inc.
Packit Service b23acc
 */
Packit Service b23acc
Packit Service b23acc
#include "nm-default.h"
Packit Service b23acc
Packit Service b23acc
#include "nm-vpn-plugin-info.h"
Packit Service b23acc
Packit Service b23acc
#include <sys/stat.h>
Packit Service b23acc
Packit Service b23acc
#include "nm-errors.h"
Packit Service b23acc
#include "nm-core-internal.h"
Packit Service b23acc
Packit Service b23acc
#define DEFAULT_DIR_ETC     NMCONFDIR"/VPN"
Packit Service b23acc
#define DEFAULT_DIR_LIB     NMLIBDIR"/VPN"
Packit Service b23acc
Packit Service b23acc
enum {
Packit Service b23acc
	PROP_0,
Packit Service b23acc
	PROP_NAME,
Packit Service b23acc
	PROP_FILENAME,
Packit Service b23acc
	PROP_KEYFILE,
Packit Service b23acc
Packit Service b23acc
	LAST_PROP,
Packit Service b23acc
};
Packit Service b23acc
Packit Service b23acc
typedef struct {
Packit Service b23acc
	char *filename;
Packit Service b23acc
	char *name;
Packit Service b23acc
	char *service;
Packit Service b23acc
	char *auth_dialog;
Packit Service b23acc
	char **aliases;
Packit Service b23acc
	GKeyFile *keyfile;
Packit Service b23acc
Packit Service b23acc
	/* It is convenient for nm_vpn_plugin_info_lookup_property() to return a const char *,
Packit Service b23acc
	 * contrary to what g_key_file_get_string() does. Hence we must cache the returned
Packit Service b23acc
	 * value somewhere... let's put it in an internal hash table.
Packit Service b23acc
	 * This contains a clone of all the strings in keyfile. */
Packit Service b23acc
	GHashTable *keys;
Packit Service b23acc
Packit Service b23acc
	gboolean editor_plugin_loaded;
Packit Service b23acc
	NMVpnEditorPlugin *editor_plugin;
Packit Service b23acc
} NMVpnPluginInfoPrivate;
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * NMVpnPluginInfo:
Packit Service b23acc
 */
Packit Service b23acc
struct _NMVpnPluginInfo {
Packit Service b23acc
	GObject parent;
Packit Service b23acc
	NMVpnPluginInfoPrivate _priv;
Packit Service b23acc
};
Packit Service b23acc
Packit Service b23acc
struct _NMVpnPluginInfoClass {
Packit Service b23acc
	GObjectClass parent;
Packit Service b23acc
};
Packit Service b23acc
Packit Service b23acc
#define NM_VPN_PLUGIN_INFO_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMVpnPluginInfo, NM_IS_VPN_PLUGIN_INFO)
Packit Service b23acc
Packit Service b23acc
static void nm_vpn_plugin_info_initable_iface_init (GInitableIface *iface);
Packit Service b23acc
Packit Service b23acc
G_DEFINE_TYPE_WITH_CODE (NMVpnPluginInfo, nm_vpn_plugin_info, G_TYPE_OBJECT,
Packit Service b23acc
                         G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, nm_vpn_plugin_info_initable_iface_init);
Packit Service b23acc
                         )
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static NMVpnPluginInfo *_list_find_by_service (GSList *list,
Packit Service b23acc
                                               const char *name,
Packit Service b23acc
                                               const char *service);
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_validate_filename:
Packit Service b23acc
 * @filename: the filename to check
Packit Service b23acc
 *
Packit Service b23acc
 * Regular name files have a certain pattern. That basically means
Packit Service b23acc
 * they have the file extension "name". Check if @filename
Packit Service b23acc
 * is valid according to that pattern.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_vpn_plugin_info_validate_filename (const char *filename)
Packit Service b23acc
{
Packit Service b23acc
	if (!filename || !g_str_has_suffix (filename, ".name"))
Packit Service b23acc
		return FALSE;
Packit Service b23acc
Packit Service b23acc
	/* originally, we didn't do further checks... but here we go. */
Packit Service b23acc
	if (filename[0] == '.') {
Packit Service b23acc
		/* this also rejects name ".name" alone. */
Packit Service b23acc
		return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
	return TRUE;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static gboolean
Packit Service b23acc
nm_vpn_plugin_info_check_file_full (const char *filename,
Packit Service b23acc
                                    gboolean check_absolute,
Packit Service b23acc
                                    gboolean do_validate_filename,
Packit Service b23acc
                                    gint64 check_owner,
Packit Service b23acc
                                    NMUtilsCheckFilePredicate check_file,
Packit Service b23acc
                                    gpointer user_data,
Packit Service b23acc
                                    struct stat *out_st,
Packit Service b23acc
                                    GError **error)
Packit Service b23acc
{
Packit Service b23acc
	if (!filename || !*filename) {
Packit Service b23acc
		g_set_error (error,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR_FAILED,
Packit Service b23acc
		             _("missing filename"));
Packit Service b23acc
		return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	if (check_absolute && !g_path_is_absolute (filename)) {
Packit Service b23acc
		g_set_error (error,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR_FAILED,
Packit Service b23acc
		             _("filename must be an absolute path (%s)"), filename);
Packit Service b23acc
		return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	if (   do_validate_filename
Packit Service b23acc
	    && !nm_vpn_plugin_info_validate_filename (filename)) {
Packit Service b23acc
		g_set_error (error,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR_FAILED,
Packit Service b23acc
		             _("filename has invalid format (%s)"), filename);
Packit Service b23acc
		return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	return _nm_utils_check_file (filename,
Packit Service b23acc
	                             check_owner,
Packit Service b23acc
	                             check_file,
Packit Service b23acc
	                             user_data,
Packit Service b23acc
	                             out_st,
Packit Service b23acc
	                             error);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * _nm_vpn_plugin_info_check_file:
Packit Service b23acc
 * @filename: the file to check
Packit Service b23acc
 * @check_absolute: if %TRUE, only allow absolute path names.
Packit Service b23acc
 * @do_validate_filename: if %TRUE, only accept the filename if
Packit Service b23acc
 *   nm_vpn_plugin_info_validate_filename() succeeds.
Packit Service b23acc
 * @check_owner: if non-negative, only accept the file if the
Packit Service b23acc
 *   owner UID is equal to @check_owner or if the owner is 0.
Packit Service b23acc
 *   In this case, also check that the file is not writable by
Packit Service b23acc
 *   other users.
Packit Service b23acc
 * @check_file: pass a callback to do your own validation.
Packit Service b23acc
 * @user_data: user data for @check_file.
Packit Service b23acc
 * @error: (allow-none) (out): the error reason if the check fails.
Packit Service b23acc
 *
Packit Service b23acc
 * Check whether the file exists and is a valid name file (in keyfile format).
Packit Service b23acc
 * Additionally, also check for file permissions.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if a file @filename exists and has valid permissions.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
_nm_vpn_plugin_info_check_file (const char *filename,
Packit Service b23acc
                                gboolean check_absolute,
Packit Service b23acc
                                gboolean do_validate_filename,
Packit Service b23acc
                                gint64 check_owner,
Packit Service b23acc
                                NMUtilsCheckFilePredicate check_file,
Packit Service b23acc
                                gpointer user_data,
Packit Service b23acc
                                GError **error)
Packit Service b23acc
{
Packit Service b23acc
	return nm_vpn_plugin_info_check_file_full (filename, check_absolute, do_validate_filename, check_owner, check_file, user_data, NULL, error);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
typedef struct {
Packit Service b23acc
	NMVpnPluginInfo *plugin_info;
Packit Service b23acc
	struct stat stat;
Packit Service b23acc
} LoadDirInfo;
Packit Service b23acc
Packit Service b23acc
static int
Packit Service b23acc
_sort_files (LoadDirInfo *a, LoadDirInfo *b)
Packit Service b23acc
{
Packit Service b23acc
	time_t ta, tb;
Packit Service b23acc
Packit Service b23acc
	ta = MAX (a->stat.st_mtime, a->stat.st_ctime);
Packit Service b23acc
	tb = MAX (b->stat.st_mtime, b->stat.st_ctime);
Packit Service b23acc
	if (ta < tb)
Packit Service b23acc
		return 1;
Packit Service b23acc
	if (ta > tb)
Packit Service b23acc
		return -1;
Packit Service b23acc
	return g_strcmp0 (nm_vpn_plugin_info_get_filename (a->plugin_info),
Packit Service b23acc
	                  nm_vpn_plugin_info_get_filename (b->plugin_info));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * _nm_vpn_plugin_info_get_default_dir_etc:
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): compile time constant of the default
Packit Service b23acc
 *   VPN plugin directory.
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
_nm_vpn_plugin_info_get_default_dir_etc ()
Packit Service b23acc
{
Packit Service b23acc
	return DEFAULT_DIR_ETC;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * _nm_vpn_plugin_info_get_default_dir_lib:
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): compile time constant of the default
Packit Service b23acc
 *   VPN plugin directory.
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
_nm_vpn_plugin_info_get_default_dir_lib ()
Packit Service b23acc
{
Packit Service b23acc
	return DEFAULT_DIR_LIB;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * _nm_vpn_plugin_info_get_default_dir_user:
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: The user can specify a different directory for VPN plugins
Packit Service b23acc
 * by setting NM_VPN_PLUGIN_DIR environment variable. Return
Packit Service b23acc
 * that directory.
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
_nm_vpn_plugin_info_get_default_dir_user ()
Packit Service b23acc
{
Packit Service b23acc
	return nm_str_not_empty (g_getenv ("NM_VPN_PLUGIN_DIR"));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * _nm_vpn_plugin_info_list_load_dir:
Packit Service b23acc
 * @dirname: the name of the directory to load.
Packit Service b23acc
 * @do_validate_filename: only consider filenames that have a certain
Packit Service b23acc
 *   pattern (i.e. end with ".name").
Packit Service b23acc
 * @check_owner: if set to a non-negative number, check that the file
Packit Service b23acc
 *   owner is either the same uid or 0. In that case, also check
Packit Service b23acc
 *   that the file is not writable by group or other.
Packit Service b23acc
 * @check_file: (allow-none): callback to check whether the file is valid.
Packit Service b23acc
 * @user_data: data for @check_file
Packit Service b23acc
 *
Packit Service b23acc
 * Iterate over the content of @dirname and load name files.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer full) (element-type NMVpnPluginInfo): list of loaded plugin infos.
Packit Service b23acc
 */
Packit Service b23acc
GSList *
Packit Service b23acc
_nm_vpn_plugin_info_list_load_dir (const char *dirname,
Packit Service b23acc
                                   gboolean do_validate_filename,
Packit Service b23acc
                                   gint64 check_owner,
Packit Service b23acc
                                   NMUtilsCheckFilePredicate check_file,
Packit Service b23acc
                                   gpointer user_data)
Packit Service b23acc
{
Packit Service b23acc
	GDir *dir;
Packit Service b23acc
	const char *fn;
Packit Service b23acc
	GArray *array;
Packit Service b23acc
	GSList *res = NULL;
Packit Service b23acc
	guint i;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (dirname, NULL);
Packit Service b23acc
Packit Service b23acc
	if (!dirname[0])
Packit Service b23acc
		return NULL;
Packit Service b23acc
Packit Service b23acc
	dir = g_dir_open (dirname, 0, NULL);
Packit Service b23acc
	if (!dir)
Packit Service b23acc
		return NULL;
Packit Service b23acc
Packit Service b23acc
	array = g_array_new (FALSE, FALSE, sizeof (LoadDirInfo));
Packit Service b23acc
Packit Service b23acc
	while ((fn = g_dir_read_name (dir))) {
Packit Service b23acc
		gs_free char *filename = NULL;
Packit Service b23acc
		LoadDirInfo info = { 0 };
Packit Service b23acc
Packit Service b23acc
		filename = g_build_filename (dirname, fn, NULL);
Packit Service b23acc
		if (nm_vpn_plugin_info_check_file_full (filename,
Packit Service b23acc
		                                        FALSE,
Packit Service b23acc
		                                        do_validate_filename,
Packit Service b23acc
		                                        check_owner,
Packit Service b23acc
		                                        check_file,
Packit Service b23acc
		                                        user_data,
Packit Service b23acc
		                                        &info.stat,
Packit Service b23acc
		                                        NULL)) {
Packit Service b23acc
			info.plugin_info = nm_vpn_plugin_info_new_from_file (filename, NULL);
Packit Service b23acc
			if (info.plugin_info) {
Packit Service b23acc
				g_array_append_val (array, info);
Packit Service b23acc
				continue;
Packit Service b23acc
			}
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
	g_dir_close (dir);
Packit Service b23acc
Packit Service b23acc
	/* sort the files so that we have a stable behavior. The directory might contain
Packit Service b23acc
	 * duplicate VPNs, so while nm_vpn_plugin_info_list_load() would load them all, the
Packit Service b23acc
	 * caller probably wants to reject duplicates. Having a stable order means we always
Packit Service b23acc
	 * reject the same files in face of duplicates. */
Packit Service b23acc
	g_array_sort (array, (GCompareFunc) _sort_files);
Packit Service b23acc
Packit Service b23acc
	for (i = 0; i < array->len; i++)
Packit Service b23acc
		res = g_slist_prepend (res, g_array_index (array, LoadDirInfo, i).plugin_info);
Packit Service b23acc
Packit Service b23acc
	g_array_unref (array);
Packit Service b23acc
Packit Service b23acc
	return g_slist_reverse (res);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_list_load:
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (element-type NMVpnPluginInfo) (transfer full): list of plugins
Packit Service b23acc
 * loaded from the default directories rejecting duplicates.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
GSList *
Packit Service b23acc
nm_vpn_plugin_info_list_load ()
Packit Service b23acc
{
Packit Service b23acc
	int i;
Packit Service b23acc
	gint64 uid;
Packit Service b23acc
	GSList *list = NULL;
Packit Service b23acc
	GSList *infos, *info;
Packit Service b23acc
	const char *const dir[] = {
Packit Service b23acc
		/* We load plugins from NM_VPN_PLUGIN_DIR *and* DEFAULT_DIR*, with
Packit Service b23acc
		 * preference to the former.
Packit Service b23acc
		 *
Packit Service b23acc
		 * load user directory with highest priority. */
Packit Service b23acc
		_nm_vpn_plugin_info_get_default_dir_user (),
Packit Service b23acc
Packit Service b23acc
		/* lib directory has higher priority then etc. The reason is that
Packit Service b23acc
		 * etc is deprecated and used by old plugins. We expect newer plugins
Packit Service b23acc
		 * to install their file in lib, where they have higher priority.
Packit Service b23acc
		 *
Packit Service b23acc
		 * Optimally, there are no duplicates anyway, so it doesn't really matter. */
Packit Service b23acc
		_nm_vpn_plugin_info_get_default_dir_lib (),
Packit Service b23acc
		_nm_vpn_plugin_info_get_default_dir_etc (),
Packit Service b23acc
	};
Packit Service b23acc
Packit Service b23acc
	uid = getuid ();
Packit Service b23acc
Packit Service b23acc
	for (i = 0; i < G_N_ELEMENTS (dir); i++) {
Packit Service b23acc
		if (   !dir[i]
Packit Service b23acc
		    || nm_utils_strv_find_first ((char **) dir, i, dir[i]) >= 0)
Packit Service b23acc
			continue;
Packit Service b23acc
Packit Service b23acc
		infos = _nm_vpn_plugin_info_list_load_dir (dir[i], TRUE, uid, NULL, NULL);
Packit Service b23acc
Packit Service b23acc
		for (info = infos; info; info = info->next)
Packit Service b23acc
			nm_vpn_plugin_info_list_add (&list, info->data, NULL);
Packit Service b23acc
Packit Service b23acc
		g_slist_free_full (infos, g_object_unref);
Packit Service b23acc
	}
Packit Service b23acc
	return list;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_new_search_file:
Packit Service b23acc
 * @name: (allow-none): the name to search for. Either @name or @service
Packit Service b23acc
 *   must be present.
Packit Service b23acc
 * @service: (allow-none): the service to search for. Either @name  or
Packit Service b23acc
 *   @service must be present.
Packit Service b23acc
 *
Packit Service b23acc
 * This has the same effect as doing a full nm_vpn_plugin_info_list_load()
Packit Service b23acc
 * followed by a search for the first matching VPN plugin info that has the
Packit Service b23acc
 * given @name and/or @service.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer full): a newly created instance of plugin info
Packit Service b23acc
 *   or %NULL if no matching value was found.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.4
Packit Service b23acc
 */
Packit Service b23acc
NMVpnPluginInfo *
Packit Service b23acc
nm_vpn_plugin_info_new_search_file (const char *name, const char *service)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfo *info;
Packit Service b23acc
	GSList *infos;
Packit Service b23acc
Packit Service b23acc
	if (!name && !service)
Packit Service b23acc
		g_return_val_if_reached (NULL);
Packit Service b23acc
Packit Service b23acc
	infos = nm_vpn_plugin_info_list_load ();
Packit Service b23acc
	info = nm_g_object_ref (_list_find_by_service (infos, name, service));
Packit Service b23acc
	g_slist_free_full (infos, g_object_unref);
Packit Service b23acc
	return info;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static gboolean
Packit Service b23acc
_check_no_conflict (NMVpnPluginInfo *i1, NMVpnPluginInfo *i2, GError **error)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv1, *priv2;
Packit Service b23acc
	uint i;
Packit Service b23acc
	struct {
Packit Service b23acc
		const char *group;
Packit Service b23acc
		const char *key;
Packit Service b23acc
	} check_list[] = {
Packit Service b23acc
		{ NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "service" },
Packit Service b23acc
		{ NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM,      "plugin" },
Packit Service b23acc
		{ NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME,      "properties" },
Packit Service b23acc
	};
Packit Service b23acc
Packit Service b23acc
	priv1 = NM_VPN_PLUGIN_INFO_GET_PRIVATE (i1);
Packit Service b23acc
	priv2 = NM_VPN_PLUGIN_INFO_GET_PRIVATE (i2);
Packit Service b23acc
Packit Service b23acc
	for (i = 0; i < G_N_ELEMENTS (check_list); i++) {
Packit Service b23acc
		gs_free NMUtilsStrStrDictKey *k = NULL;
Packit Service b23acc
		const char *s1, *s2;
Packit Service b23acc
Packit Service b23acc
		k = _nm_utils_strstrdictkey_create (check_list[i].group, check_list[i].key);
Packit Service b23acc
		s1 = g_hash_table_lookup (priv1->keys, k);
Packit Service b23acc
		if (!s1)
Packit Service b23acc
			continue;
Packit Service b23acc
		s2 = g_hash_table_lookup (priv2->keys, k);
Packit Service b23acc
		if (!s2)
Packit Service b23acc
			continue;
Packit Service b23acc
Packit Service b23acc
		if (strcmp (s1, s2) == 0) {
Packit Service b23acc
			g_set_error (error,
Packit Service b23acc
			             NM_VPN_PLUGIN_ERROR,
Packit Service b23acc
			             NM_VPN_PLUGIN_ERROR_FAILED,
Packit Service b23acc
			             _("there exists a conflicting plugin (%s) that has the same %s.%s value"),
Packit Service b23acc
			             priv2->name,
Packit Service b23acc
			             check_list[i].group, check_list[i].key);
Packit Service b23acc
			return FALSE;
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
	return TRUE;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_list_add:
Packit Service b23acc
 * @list: (element-type NMVpnPluginInfo): list of plugins
Packit Service b23acc
 * @plugin_info: instance to add
Packit Service b23acc
 * @error: failure reason
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the plugin was added to @list. This will fail
Packit Service b23acc
 * to add duplicate plugins.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_vpn_plugin_info_list_add (GSList **list, NMVpnPluginInfo *plugin_info, GError **error)
Packit Service b23acc
{
Packit Service b23acc
	GSList *iter;
Packit Service b23acc
	const char *name;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (list, FALSE);
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (plugin_info), FALSE);
Packit Service b23acc
Packit Service b23acc
	name = nm_vpn_plugin_info_get_name (plugin_info);
Packit Service b23acc
	for (iter = *list; iter; iter = iter->next) {
Packit Service b23acc
		if (iter->data == plugin_info)
Packit Service b23acc
			return TRUE;
Packit Service b23acc
Packit Service b23acc
		if (strcmp (nm_vpn_plugin_info_get_name (iter->data), name) == 0) {
Packit Service b23acc
			g_set_error (error,
Packit Service b23acc
			             NM_VPN_PLUGIN_ERROR,
Packit Service b23acc
			             NM_VPN_PLUGIN_ERROR_FAILED,
Packit Service b23acc
			             _("there exists a conflicting plugin with the same name (%s)"),
Packit Service b23acc
			             name);
Packit Service b23acc
			return FALSE;
Packit Service b23acc
		}
Packit Service b23acc
Packit Service b23acc
		/* the plugin must have unique values for certain properties. E.g. two different
Packit Service b23acc
		 * plugins cannot share the same service type. */
Packit Service b23acc
		if (!_check_no_conflict (plugin_info, iter->data, error))
Packit Service b23acc
			return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	*list = g_slist_append (*list, g_object_ref (plugin_info));
Packit Service b23acc
	return TRUE;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_list_remove:
Packit Service b23acc
 * @list: (element-type NMVpnPluginInfo): list of plugins
Packit Service b23acc
 * @plugin_info: instance
Packit Service b23acc
 *
Packit Service b23acc
 * Remove @plugin_info from @list.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if @plugin_info was in @list and successfully removed.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_vpn_plugin_info_list_remove (GSList **list, NMVpnPluginInfo *plugin_info)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (list, FALSE);
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (plugin_info), FALSE);
Packit Service b23acc
Packit Service b23acc
	if (!g_slist_find (*list, plugin_info))
Packit Service b23acc
		return FALSE;
Packit Service b23acc
Packit Service b23acc
	*list = g_slist_remove (*list, plugin_info);
Packit Service b23acc
	g_object_unref (plugin_info);
Packit Service b23acc
	return TRUE;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_list_find_by_name:
Packit Service b23acc
 * @list: (element-type NMVpnPluginInfo): list of plugins
Packit Service b23acc
 * @name: name to search
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the first plugin with a matching @name (or %NULL).
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
NMVpnPluginInfo *
Packit Service b23acc
nm_vpn_plugin_info_list_find_by_name (GSList *list, const char *name)
Packit Service b23acc
{
Packit Service b23acc
	GSList *iter;
Packit Service b23acc
Packit Service b23acc
	if (!name)
Packit Service b23acc
		g_return_val_if_reached (NULL);
Packit Service b23acc
Packit Service b23acc
	for (iter = list; iter; iter = iter->next) {
Packit Service b23acc
		if (strcmp (nm_vpn_plugin_info_get_name (iter->data), name) == 0)
Packit Service b23acc
			return iter->data;
Packit Service b23acc
	}
Packit Service b23acc
	return NULL;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_list_find_by_filename:
Packit Service b23acc
 * @list: (element-type NMVpnPluginInfo): list of plugins
Packit Service b23acc
 * @filename: filename to search
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the first plugin with a matching @filename (or %NULL).
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
NMVpnPluginInfo *
Packit Service b23acc
nm_vpn_plugin_info_list_find_by_filename (GSList *list, const char *filename)
Packit Service b23acc
{
Packit Service b23acc
	GSList *iter;
Packit Service b23acc
Packit Service b23acc
	if (!filename)
Packit Service b23acc
		g_return_val_if_reached (NULL);
Packit Service b23acc
Packit Service b23acc
	for (iter = list; iter; iter = iter->next) {
Packit Service b23acc
		if (g_strcmp0 (nm_vpn_plugin_info_get_filename (iter->data), filename) == 0)
Packit Service b23acc
			return iter->data;
Packit Service b23acc
	}
Packit Service b23acc
	return NULL;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static NMVpnPluginInfo *
Packit Service b23acc
_list_find_by_service (GSList *list,
Packit Service b23acc
                       const char *name,
Packit Service b23acc
                       const char *service)
Packit Service b23acc
{
Packit Service b23acc
	for (; list; list = list->next) {
Packit Service b23acc
		NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (list->data);
Packit Service b23acc
Packit Service b23acc
		if (   name
Packit Service b23acc
		    && !nm_streq (name, priv->name))
Packit Service b23acc
			continue;
Packit Service b23acc
		if (   service
Packit Service b23acc
		    && !nm_streq (priv->service, service)
Packit Service b23acc
		    && (nm_utils_strv_find_first (priv->aliases, -1, service) < 0))
Packit Service b23acc
			continue;
Packit Service b23acc
Packit Service b23acc
		return list->data;
Packit Service b23acc
	}
Packit Service b23acc
	return NULL;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_list_find_by_service:
Packit Service b23acc
 * @list: (element-type NMVpnPluginInfo): list of plugins
Packit Service b23acc
 * @service: service to search. This can be the main service-type
Packit Service b23acc
 *   or one of the provided aliases.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the first plugin with a matching @service (or %NULL).
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
NMVpnPluginInfo *
Packit Service b23acc
nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service)
Packit Service b23acc
{
Packit Service b23acc
	if (!service)
Packit Service b23acc
		g_return_val_if_reached (NULL);
Packit Service b23acc
	return _list_find_by_service (list, NULL, service);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/* known_names are well known short names for the service-type. They all implicitly
Packit Service b23acc
 * have a prefix "org.freedesktop.NetworkManager." + known_name. */
Packit Service b23acc
static const char *known_names[] = {
Packit Service b23acc
	"openvpn",
Packit Service b23acc
	"vpnc",
Packit Service b23acc
	"pptp",
Packit Service b23acc
	"openconnect",
Packit Service b23acc
	"openswan",
Packit Service b23acc
	"libreswan",
Packit Service b23acc
	"strongswan",
Packit Service b23acc
	"ssh",
Packit Service b23acc
	"l2tp",
Packit Service b23acc
	"iodine",
Packit Service b23acc
	"fortisslvpn",
Packit Service b23acc
};
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_list_find_service_type:
Packit Service b23acc
 * @list: (element-type NMVpnPluginInfo): a possibly empty #GSList of #NMVpnPluginInfo instances
Packit Service b23acc
 * @name: a name to lookup the service-type.
Packit Service b23acc
 *
Packit Service b23acc
 * A VPN plugin provides one or several service-types, like org.freedesktop.NetworkManager.libreswan
Packit Service b23acc
 * Certain plugins provide more then one service type, via aliases (org.freedesktop.NetworkManager.openswan).
Packit Service b23acc
 * This function looks up a service-type (or an alias) based on a name.
Packit Service b23acc
 *
Packit Service b23acc
 * Preferably, the name can be a full service-type/alias of an installed
Packit Service b23acc
 * plugin. Otherwise, it can be the name of a VPN plugin (in which case, the
Packit Service b23acc
 * primary, non-aliased service-type is returned). Otherwise, it can be
Packit Service b23acc
 * one of several well known short-names (which is a hard-coded list of
Packit Service b23acc
 * types in libnm). On success, this returns a full qualified service-type
Packit Service b23acc
 * (or an alias). It doesn't say, that such an plugin is actually available,
Packit Service b23acc
 * but it could be retrieved via nm_vpn_plugin_info_list_find_by_service().
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer full): the resolved service-type or %NULL on failure.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.4
Packit Service b23acc
 */
Packit Service b23acc
char *
Packit Service b23acc
nm_vpn_plugin_info_list_find_service_type (GSList *list, const char *name)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfo *info;
Packit Service b23acc
	char *n;
Packit Service b23acc
Packit Service b23acc
	if (!name)
Packit Service b23acc
		g_return_val_if_reached (NULL);
Packit Service b23acc
	if (!*name)
Packit Service b23acc
		return NULL;
Packit Service b23acc
Packit Service b23acc
	/* First, try to interpret @name as a full service-type (or alias). */
Packit Service b23acc
	info = _list_find_by_service (list, NULL, name);
Packit Service b23acc
	if (info)
Packit Service b23acc
		return g_strdup (name);
Packit Service b23acc
Packit Service b23acc
	/* try to interpret @name as plugin name, in which case we return
Packit Service b23acc
	 * the main service-type (not an alias). */
Packit Service b23acc
	info = _list_find_by_service (list, name, NULL);
Packit Service b23acc
	if (info)
Packit Service b23acc
		return g_strdup (NM_VPN_PLUGIN_INFO_GET_PRIVATE (info)->service);
Packit Service b23acc
Packit Service b23acc
	/* check the hard-coded list of short-names. They all have have the same
Packit Service b23acc
	 * well-known prefix org.freedesktop.NetworkManager and the name. */
Packit Service b23acc
	if (nm_utils_strv_find_first ((char **) known_names, G_N_ELEMENTS (known_names), name) >= 0)
Packit Service b23acc
		return g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, name);
Packit Service b23acc
Packit Service b23acc
	/* try, if there exists a plugin with @name under org.freedesktop.NetworkManager.
Packit Service b23acc
	 * Allow this to be a valid abbreviation. */
Packit Service b23acc
	n = g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, name);
Packit Service b23acc
	if (_list_find_by_service (list, NULL, n))
Packit Service b23acc
		return n;
Packit Service b23acc
	g_free (n);
Packit Service b23acc
Packit Service b23acc
	/* currently, VPN plugins have no way to define a short-name for their
Packit Service b23acc
	 * alias name, unless the alias name is prefixed by org.freedesktop.NetworkManager. */
Packit Service b23acc
Packit Service b23acc
	return NULL;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static const char *
Packit Service b23acc
_service_type_get_default_abbreviation (const char *service_type)
Packit Service b23acc
{
Packit Service b23acc
	if (!g_str_has_prefix (service_type, NM_DBUS_INTERFACE))
Packit Service b23acc
		return NULL;
Packit Service b23acc
	service_type += NM_STRLEN (NM_DBUS_INTERFACE);
Packit Service b23acc
	if (service_type[0] != '.')
Packit Service b23acc
		return NULL;
Packit Service b23acc
	service_type++;
Packit Service b23acc
	if (!service_type[0])
Packit Service b23acc
		return NULL;
Packit Service b23acc
	return service_type;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_list_get_service_types:
Packit Service b23acc
 * @list: (element-type NMVpnPluginInfo): a possibly empty #GSList of #NMVpnPluginInfo
Packit Service b23acc
 * @only_existing: only include results that are actually in @list.
Packit Service b23acc
 *   Otherwise, the result is extended with a hard-code list or
Packit Service b23acc
 *   well-known plugins
Packit Service b23acc
 * @with_abbreviations: if %FALSE, only full service types are returned.
Packit Service b23acc
 *   Otherwise, this also includes abbreviated names that can be used
Packit Service b23acc
 *   with nm_vpn_plugin_info_list_find_service_type().
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer full): a %NULL terminated strv list of strings.
Packit Service b23acc
 *   The list itself and the values must be freed with g_strfreev().
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.4
Packit Service b23acc
 */
Packit Service b23acc
char **
Packit Service b23acc
nm_vpn_plugin_info_list_get_service_types (GSList *list,
Packit Service b23acc
                                           gboolean only_existing,
Packit Service b23acc
                                           gboolean with_abbreviations)
Packit Service b23acc
{
Packit Service b23acc
	GSList *iter;
Packit Service b23acc
	GPtrArray *l;
Packit Service b23acc
	guint i, j;
Packit Service b23acc
	const char *n;
Packit Service b23acc
Packit Service b23acc
	l = g_ptr_array_sized_new (20);
Packit Service b23acc
Packit Service b23acc
	for (iter = list; iter; iter = iter->next) {
Packit Service b23acc
		NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (iter->data);
Packit Service b23acc
Packit Service b23acc
		g_ptr_array_add (l, g_strdup (priv->service));
Packit Service b23acc
		if (priv->aliases) {
Packit Service b23acc
			for (i = 0; priv->aliases[i]; i++)
Packit Service b23acc
				g_ptr_array_add (l, g_strdup (priv->aliases[i]));
Packit Service b23acc
		}
Packit Service b23acc
Packit Service b23acc
		if (with_abbreviations) {
Packit Service b23acc
			g_ptr_array_add (l, g_strdup (priv->name));
Packit Service b23acc
			n = _service_type_get_default_abbreviation (priv->service);
Packit Service b23acc
			if (n)
Packit Service b23acc
				g_ptr_array_add (l, g_strdup (n));
Packit Service b23acc
			for (i = 0; priv->aliases && priv->aliases[i]; i++) {
Packit Service b23acc
				n = _service_type_get_default_abbreviation (priv->aliases[i]);
Packit Service b23acc
				if (n)
Packit Service b23acc
					g_ptr_array_add (l, g_strdup (n));
Packit Service b23acc
			}
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	if (!only_existing) {
Packit Service b23acc
		for (i = 0; i < G_N_ELEMENTS (known_names); i++) {
Packit Service b23acc
			g_ptr_array_add (l, g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, known_names[i]));
Packit Service b23acc
			if (with_abbreviations)
Packit Service b23acc
				g_ptr_array_add (l, g_strdup (known_names[i]));
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	if (l->len <= 0) {
Packit Service b23acc
		g_ptr_array_free (l, TRUE);
Packit Service b23acc
		return g_new0 (char *, 1);
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	/* sort the result and remove duplicates. */
Packit Service b23acc
	g_ptr_array_sort (l, nm_strcmp_p);
Packit Service b23acc
	for (i = 1, j = 1; i < l->len; i++) {
Packit Service b23acc
		if (nm_streq (l->pdata[j-1], l->pdata[i]))
Packit Service b23acc
			g_free (l->pdata[i]);
Packit Service b23acc
		else
Packit Service b23acc
			l->pdata[j++] = l->pdata[i];
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	if (j == l->len)
Packit Service b23acc
		g_ptr_array_add (l, NULL);
Packit Service b23acc
	else
Packit Service b23acc
		l->pdata[j] = NULL;
Packit Service b23acc
	return (char **) g_ptr_array_free (l, FALSE);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_get_filename:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the filename. Can be %NULL.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
nm_vpn_plugin_info_get_filename (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->filename;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_get_name:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the name. Cannot be %NULL.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
nm_vpn_plugin_info_get_name (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->name;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_get_service:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the service. Cannot be %NULL.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.4
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
nm_vpn_plugin_info_get_service (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->service;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_get_auth_dialog:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: the absolute path to the auth-dialog helper or %NULL.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.4
Packit Service b23acc
 **/
Packit Service b23acc
const char *
Packit Service b23acc
nm_vpn_plugin_info_get_auth_dialog (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
Packit Service b23acc
Packit Service b23acc
	if (G_UNLIKELY (priv->auth_dialog == NULL)) {
Packit Service b23acc
		const char *s;
Packit Service b23acc
Packit Service b23acc
		s = g_hash_table_lookup (priv->keys, _nm_utils_strstrdictkey_static (NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "auth-dialog"));
Packit Service b23acc
		if (!s || !s[0])
Packit Service b23acc
			priv->auth_dialog = g_strdup ("");
Packit Service b23acc
		else if (g_path_is_absolute (s))
Packit Service b23acc
			priv->auth_dialog = g_strdup (s);
Packit Service b23acc
		else {
Packit Service b23acc
			/* for relative paths, we take the basename and assume it's in LIBEXECDIR. */
Packit Service b23acc
			gs_free char *prog_basename = g_path_get_basename (s);
Packit Service b23acc
Packit Service b23acc
			priv->auth_dialog = g_build_filename (LIBEXECDIR, prog_basename, NULL);
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	return priv->auth_dialog[0] ? priv->auth_dialog : NULL;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_supports_hints:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the supports hints for secret requests, otherwise %FALSE
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.4
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_vpn_plugin_info_supports_hints (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	const char *s;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), FALSE);
Packit Service b23acc
Packit Service b23acc
	s = nm_vpn_plugin_info_lookup_property (self, NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME, "supports-hints");
Packit Service b23acc
	return _nm_utils_ascii_str_to_bool (s, FALSE);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_get_plugin:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the plugin. Can be %NULL.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
nm_vpn_plugin_info_get_plugin (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	return g_hash_table_lookup (NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->keys,
Packit Service b23acc
	                            _nm_utils_strstrdictkey_static (NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM, "plugin"));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_get_program:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the program. Can be %NULL.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
nm_vpn_plugin_info_get_program (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	return g_hash_table_lookup (NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->keys,
Packit Service b23acc
	                            _nm_utils_strstrdictkey_static (NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "program"));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_supports_multiple:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %TRUE if the service supports multiple instances with different bus names, otherwise %FALSE
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
gboolean
Packit Service b23acc
nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	const char *s;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), FALSE);
Packit Service b23acc
Packit Service b23acc
	s = nm_vpn_plugin_info_lookup_property (self, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "supports-multiple-connections");
Packit Service b23acc
	return _nm_utils_ascii_str_to_bool (s, FALSE);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_get_aliases:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (array zero-terminated=1) (element-type utf8) (transfer none):
Packit Service b23acc
 *   the aliases from the name-file.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.4
Packit Service b23acc
 */
Packit Service b23acc
const char *const*
Packit Service b23acc
nm_vpn_plugin_info_get_aliases (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
Packit Service b23acc
	if (priv->aliases)
Packit Service b23acc
		return (const char *const*) priv->aliases;
Packit Service b23acc
Packit Service b23acc
	/* For convenience, we always want to return non-NULL, even for empty
Packit Service b23acc
	 * aliases. Hack around that, by making a NULL terminated array using
Packit Service b23acc
	 * the NULL of priv->aliases. */
Packit Service b23acc
	return (const char *const*) &priv->aliases;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_lookup_property:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 * @group: group name
Packit Service b23acc
 * @key: name of the property
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): #NMVpnPluginInfo is internally a #GKeyFile. Returns the matching
Packit Service b23acc
 * property.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
const char *
Packit Service b23acc
nm_vpn_plugin_info_lookup_property (NMVpnPluginInfo *self, const char *group, const char *key)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv;
Packit Service b23acc
	gs_free NMUtilsStrStrDictKey *k = NULL;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
	g_return_val_if_fail (group, NULL);
Packit Service b23acc
	g_return_val_if_fail (key, NULL);
Packit Service b23acc
Packit Service b23acc
	priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
Packit Service b23acc
Packit Service b23acc
	k = _nm_utils_strstrdictkey_create (group, key);
Packit Service b23acc
	return g_hash_table_lookup (priv->keys, k);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_get_editor_plugin:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): the cached #NMVpnEditorPlugin instance.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
NMVpnEditorPlugin *
Packit Service b23acc
nm_vpn_plugin_info_get_editor_plugin (NMVpnPluginInfo *self)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	return NM_VPN_PLUGIN_INFO_GET_PRIVATE (self)->editor_plugin;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_set_editor_plugin:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 * @plugin: (allow-none): plugin instance
Packit Service b23acc
 *
Packit Service b23acc
 * Set the internal plugin instance. If %NULL, only clear the previous instance.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
void
Packit Service b23acc
nm_vpn_plugin_info_set_editor_plugin (NMVpnPluginInfo *self, NMVpnEditorPlugin *plugin)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv;
Packit Service b23acc
	NMVpnEditorPlugin *old;
Packit Service b23acc
Packit Service b23acc
	g_return_if_fail (NM_IS_VPN_PLUGIN_INFO (self));
Packit Service b23acc
	g_return_if_fail (!plugin || G_IS_OBJECT (plugin));
Packit Service b23acc
Packit Service b23acc
	priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
Packit Service b23acc
Packit Service b23acc
	if (!plugin) {
Packit Service b23acc
		priv->editor_plugin_loaded = FALSE;
Packit Service b23acc
		g_clear_object (&priv->editor_plugin);
Packit Service b23acc
	} else {
Packit Service b23acc
		old = priv->editor_plugin;
Packit Service b23acc
		priv->editor_plugin = g_object_ref (plugin);
Packit Service b23acc
		priv->editor_plugin_loaded = TRUE;
Packit Service b23acc
		if (old)
Packit Service b23acc
			g_object_unref (old);
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_load_editor_plugin:
Packit Service b23acc
 * @self: plugin info instance
Packit Service b23acc
 * @error: error reason on failure
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: (transfer none): loads the plugin and returns the newly created
Packit Service b23acc
 *   instance. The plugin is owned by @self and can be later retrieved again
Packit Service b23acc
 *   via nm_vpn_plugin_info_get_editor_plugin(). You can load the
Packit Service b23acc
 *   plugin only once, unless you reset the state via
Packit Service b23acc
 *   nm_vpn_plugin_info_set_editor_plugin().
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
NMVpnEditorPlugin *
Packit Service b23acc
nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *self, GError **error)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv;
Packit Service b23acc
	const char *plugin_filename;
Packit Service b23acc
Packit Service b23acc
	g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (self), NULL);
Packit Service b23acc
Packit Service b23acc
	priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
Packit Service b23acc
Packit Service b23acc
	if (priv->editor_plugin)
Packit Service b23acc
		return priv->editor_plugin;
Packit Service b23acc
Packit Service b23acc
	plugin_filename = nm_vpn_plugin_info_get_plugin (self);
Packit Service b23acc
	if (!plugin_filename || !*plugin_filename) {
Packit Service b23acc
		g_set_error (error,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR_FAILED,
Packit Service b23acc
		             _("missing \"plugin\" setting"));
Packit Service b23acc
		return NULL;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	/* We only try once to load the plugin. If we previously tried and it was
Packit Service b23acc
	 * unsuccessful, error out immediately. */
Packit Service b23acc
	if (priv->editor_plugin_loaded) {
Packit Service b23acc
		g_set_error (error,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR,
Packit Service b23acc
		             NM_VPN_PLUGIN_ERROR_FAILED,
Packit Service b23acc
		             _("%s: don't retry loading plugin which already failed previously"), priv->name);
Packit Service b23acc
		return NULL;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	priv->editor_plugin_loaded = TRUE;
Packit Service b23acc
	priv->editor_plugin = nm_vpn_editor_plugin_load_from_file (plugin_filename,
Packit Service b23acc
	                                                           nm_vpn_plugin_info_get_service (self),
Packit Service b23acc
	                                                           getuid (),
Packit Service b23acc
	                                                           NULL,
Packit Service b23acc
	                                                           NULL,
Packit Service b23acc
	                                                           error);
Packit Service b23acc
	if (priv->editor_plugin)
Packit Service b23acc
		nm_vpn_editor_plugin_set_plugin_info (priv->editor_plugin, self);
Packit Service b23acc
	return priv->editor_plugin;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
get_property (GObject *object, guint prop_id,
Packit Service b23acc
              GValue *value, GParamSpec *pspec)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (object);
Packit Service b23acc
Packit Service b23acc
	switch (prop_id) {
Packit Service b23acc
	case PROP_NAME:
Packit Service b23acc
		g_value_set_string (value, priv->name);
Packit Service b23acc
		break;
Packit Service b23acc
	case PROP_FILENAME:
Packit Service b23acc
		g_value_set_string (value, priv->filename);
Packit Service b23acc
		break;
Packit Service b23acc
	default:
Packit Service b23acc
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
set_property (GObject *object, guint prop_id,
Packit Service b23acc
              const GValue *value, GParamSpec *pspec)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (object);
Packit Service b23acc
Packit Service b23acc
	switch (prop_id) {
Packit Service b23acc
	case PROP_FILENAME:
Packit Service b23acc
		priv->filename = g_value_dup_string (value);
Packit Service b23acc
		break;
Packit Service b23acc
	case PROP_KEYFILE:
Packit Service b23acc
		priv->keyfile = g_value_dup_boxed (value);
Packit Service b23acc
		break;
Packit Service b23acc
	default:
Packit Service b23acc
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service b23acc
		break;
Packit Service b23acc
	}
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/*****************************************************************************/
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
nm_vpn_plugin_info_init (NMVpnPluginInfo *plugin)
Packit Service b23acc
{
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static gboolean
Packit Service b23acc
init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfo *self = NM_VPN_PLUGIN_INFO (initable);
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
Packit Service b23acc
	gs_strfreev char **groups = NULL;
Packit Service b23acc
	guint i, j;
Packit Service b23acc
Packit Service b23acc
	if (!priv->keyfile) {
Packit Service b23acc
		if (!priv->filename) {
Packit Service b23acc
			g_set_error_literal (error,
Packit Service b23acc
			                     NM_VPN_PLUGIN_ERROR,
Packit Service b23acc
			                     NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
Packit Service b23acc
			                     _("missing filename to load VPN plugin info"));
Packit Service b23acc
			return FALSE;
Packit Service b23acc
		}
Packit Service b23acc
		priv->keyfile = g_key_file_new ();
Packit Service b23acc
		if (!g_key_file_load_from_file (priv->keyfile, priv->filename, G_KEY_FILE_NONE, error))
Packit Service b23acc
			return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	/* we reqire at least a "name" */
Packit Service b23acc
	priv->name = g_key_file_get_string (priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "name", NULL);
Packit Service b23acc
	if (!priv->name || !priv->name[0]) {
Packit Service b23acc
		g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
Packit Service b23acc
		                     _("missing name for VPN plugin info"));
Packit Service b23acc
		return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	/* we also require "service", because that how we associate NMSettingVpn:service-type with the
Packit Service b23acc
	 * NMVpnPluginInfo. */
Packit Service b23acc
	priv->service = g_key_file_get_string (priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "service", NULL);
Packit Service b23acc
	if (!priv->service || !*priv->service) {
Packit Service b23acc
		g_set_error_literal (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
Packit Service b23acc
		                     _("missing service for VPN plugin info"));
Packit Service b23acc
		return FALSE;
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	priv->aliases = g_key_file_get_string_list (priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "aliases", NULL, NULL);
Packit Service b23acc
	if (priv->aliases && !priv->aliases[0])
Packit Service b23acc
		nm_clear_g_free (&priv->aliases);
Packit Service b23acc
Packit Service b23acc
	priv->keys = g_hash_table_new_full (_nm_utils_strstrdictkey_hash,
Packit Service b23acc
	                                    _nm_utils_strstrdictkey_equal,
Packit Service b23acc
	                                    g_free, g_free);
Packit Service b23acc
	groups = g_key_file_get_groups (priv->keyfile, NULL);
Packit Service b23acc
	for (i = 0; groups && groups[i]; i++) {
Packit Service b23acc
		gs_strfreev char **keys = NULL;
Packit Service b23acc
Packit Service b23acc
		keys = g_key_file_get_keys (priv->keyfile, groups[i], NULL, NULL);
Packit Service b23acc
		for (j = 0; keys && keys[j]; j++) {
Packit Service b23acc
			char *s;
Packit Service b23acc
Packit Service b23acc
			/* Lookup the value via get_string(). We want that behavior for all our
Packit Service b23acc
			 * values. */
Packit Service b23acc
			s = g_key_file_get_string (priv->keyfile, groups[i], keys[j], NULL);
Packit Service b23acc
			if (s)
Packit Service b23acc
				g_hash_table_insert (priv->keys, _nm_utils_strstrdictkey_create (groups[i], keys[j]), s);
Packit Service b23acc
		}
Packit Service b23acc
	}
Packit Service b23acc
Packit Service b23acc
	nm_clear_pointer (&priv->keyfile, g_key_file_unref);
Packit Service b23acc
Packit Service b23acc
	return TRUE;
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_new_from_file:
Packit Service b23acc
 * @filename: filename to read.
Packit Service b23acc
 * @error: on failure, the error reason.
Packit Service b23acc
 *
Packit Service b23acc
 * Read the plugin info from file @filename. Does not do
Packit Service b23acc
 * any further verification on the file. You might want to check
Packit Service b23acc
 * file permissions and ownership of the file.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: %NULL if there is any error or a newly created
Packit Service b23acc
 * #NMVpnPluginInfo instance.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
NMVpnPluginInfo *
Packit Service b23acc
nm_vpn_plugin_info_new_from_file (const char *filename,
Packit Service b23acc
                                  GError **error)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (filename, NULL);
Packit Service b23acc
Packit Service b23acc
	return NM_VPN_PLUGIN_INFO (g_initable_new (NM_TYPE_VPN_PLUGIN_INFO,
Packit Service b23acc
	                                           NULL,
Packit Service b23acc
	                                           error,
Packit Service b23acc
	                                           NM_VPN_PLUGIN_INFO_FILENAME, filename,
Packit Service b23acc
	                                           NULL));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
/**
Packit Service b23acc
 * nm_vpn_plugin_info_new_with_data:
Packit Service b23acc
 * @filename: optional filename.
Packit Service b23acc
 * @keyfile: inject data for the plugin info instance.
Packit Service b23acc
 * @error: construction may fail if the keyfile lacks mandatory fields.
Packit Service b23acc
 *   In this case, return the error reason.
Packit Service b23acc
 *
Packit Service b23acc
 * This constructor does not read any data from file but
Packit Service b23acc
 * takes instead a @keyfile argument.
Packit Service b23acc
 *
Packit Service b23acc
 * Returns: new plugin info instance.
Packit Service b23acc
 *
Packit Service b23acc
 * Since: 1.2
Packit Service b23acc
 */
Packit Service b23acc
NMVpnPluginInfo *
Packit Service b23acc
nm_vpn_plugin_info_new_with_data (const char *filename,
Packit Service b23acc
                                  GKeyFile *keyfile,
Packit Service b23acc
                                  GError **error)
Packit Service b23acc
{
Packit Service b23acc
	g_return_val_if_fail (keyfile, NULL);
Packit Service b23acc
Packit Service b23acc
	return NM_VPN_PLUGIN_INFO (g_initable_new (NM_TYPE_VPN_PLUGIN_INFO,
Packit Service b23acc
	                                           NULL,
Packit Service b23acc
	                                           error,
Packit Service b23acc
	                                           NM_VPN_PLUGIN_INFO_FILENAME, filename,
Packit Service b23acc
	                                           NM_VPN_PLUGIN_INFO_KEYFILE, keyfile,
Packit Service b23acc
	                                           NULL));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
dispose (GObject *object)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfo *self = NM_VPN_PLUGIN_INFO (object);
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
Packit Service b23acc
Packit Service b23acc
	g_clear_object (&priv->editor_plugin);
Packit Service b23acc
Packit Service b23acc
	G_OBJECT_CLASS (nm_vpn_plugin_info_parent_class)->dispose (object);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
finalize (GObject *object)
Packit Service b23acc
{
Packit Service b23acc
	NMVpnPluginInfo *self = NM_VPN_PLUGIN_INFO (object);
Packit Service b23acc
	NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (self);
Packit Service b23acc
Packit Service b23acc
	g_free (priv->name);
Packit Service b23acc
	g_free (priv->service);
Packit Service b23acc
	g_free (priv->auth_dialog);
Packit Service b23acc
	g_strfreev (priv->aliases);
Packit Service b23acc
	g_free (priv->filename);
Packit Service b23acc
	g_hash_table_unref (priv->keys);
Packit Service b23acc
Packit Service b23acc
	nm_clear_pointer (&priv->keyfile, g_key_file_unref);
Packit Service b23acc
Packit Service b23acc
	G_OBJECT_CLASS (nm_vpn_plugin_info_parent_class)->finalize (object);
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
nm_vpn_plugin_info_class_init (NMVpnPluginInfoClass *plugin_class)
Packit Service b23acc
{
Packit Service b23acc
	GObjectClass *object_class = G_OBJECT_CLASS (plugin_class);
Packit Service b23acc
Packit Service b23acc
	object_class->set_property = set_property;
Packit Service b23acc
	object_class->get_property = get_property;
Packit Service b23acc
	object_class->dispose      = dispose;
Packit Service b23acc
	object_class->finalize     = finalize;
Packit Service b23acc
Packit Service b23acc
	/**
Packit Service b23acc
	 * NMVpnPluginInfo:name:
Packit Service b23acc
	 *
Packit Service b23acc
	 * The name of the VPN plugin.
Packit Service b23acc
	 *
Packit Service b23acc
	 * Since: 1.2
Packit Service b23acc
	 */
Packit Service b23acc
	g_object_class_install_property
Packit Service b23acc
	    (object_class, PROP_NAME,
Packit Service b23acc
	     g_param_spec_string (NM_VPN_PLUGIN_INFO_NAME, "", "",
Packit Service b23acc
	                          NULL,
Packit Service b23acc
	                          G_PARAM_READABLE |
Packit Service b23acc
	                          G_PARAM_STATIC_STRINGS));
Packit Service b23acc
Packit Service b23acc
	/**
Packit Service b23acc
	 * NMVpnPluginInfo:filename:
Packit Service b23acc
	 *
Packit Service b23acc
	 * The filename from which the info was loaded.
Packit Service b23acc
	 * Can be %NULL if the instance was not loaded from
Packit Service b23acc
	 * a file (i.e. the keyfile instance was passed to the
Packit Service b23acc
	 * constructor).
Packit Service b23acc
	 *
Packit Service b23acc
	 * Since: 1.2
Packit Service b23acc
	 */
Packit Service b23acc
	g_object_class_install_property
Packit Service b23acc
	    (object_class, PROP_FILENAME,
Packit Service b23acc
	     g_param_spec_string (NM_VPN_PLUGIN_INFO_FILENAME, "", "",
Packit Service b23acc
	                          NULL,
Packit Service b23acc
	                          G_PARAM_READWRITE |
Packit Service b23acc
	                          G_PARAM_CONSTRUCT_ONLY |
Packit Service b23acc
	                          G_PARAM_STATIC_STRINGS));
Packit Service b23acc
Packit Service b23acc
	/**
Packit Service b23acc
	 * NMVpnPluginInfo:keyfile:
Packit Service b23acc
	 *
Packit Service b23acc
	 * Initialize the instance with a different keyfile instance.
Packit Service b23acc
	 * When passing a keyfile instance, the constructor will not
Packit Service b23acc
	 * try to read from filename.
Packit Service b23acc
	 *
Packit Service b23acc
	 * Since: 1.2
Packit Service b23acc
	 */
Packit Service b23acc
	g_object_class_install_property
Packit Service b23acc
	    (object_class, PROP_KEYFILE,
Packit Service b23acc
	     g_param_spec_boxed (NM_VPN_PLUGIN_INFO_KEYFILE, "", "",
Packit Service b23acc
	                         G_TYPE_KEY_FILE,
Packit Service b23acc
	                         G_PARAM_WRITABLE |
Packit Service b23acc
	                         G_PARAM_CONSTRUCT_ONLY |
Packit Service b23acc
	                         G_PARAM_STATIC_STRINGS));
Packit Service b23acc
}
Packit Service b23acc
Packit Service b23acc
static void
Packit Service b23acc
nm_vpn_plugin_info_initable_iface_init (GInitableIface *iface)
Packit Service b23acc
{
Packit Service b23acc
	iface->init = init_sync;
Packit Service b23acc
}