libnm/vpn,cli: merge branch 'th/vpn-service-info-bgo767197'
https://bugzilla.gnome.org/show_bug.cgi?id=767197
This commit is contained in:
@@ -5886,16 +5886,13 @@ cleanup_bridge_slave:
|
|||||||
/* Build up the settings required for 'vpn' */
|
/* Build up the settings required for 'vpn' */
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
const char *vpn_type = NULL;
|
const char *vpn_type = NULL;
|
||||||
char *vpn_type_ask = NULL;
|
gs_free char *vpn_type_ask = NULL;
|
||||||
const char *user_c = NULL;
|
const char *user_c = NULL;
|
||||||
char *user = NULL;
|
char *user = NULL;
|
||||||
const char *st;
|
|
||||||
gs_free char *service_type_free = NULL;
|
gs_free char *service_type_free = NULL;
|
||||||
const char *service_type = NULL;
|
|
||||||
nmc_arg_t exp_args[] = { {"vpn-type", TRUE, &vpn_type, !ask},
|
nmc_arg_t exp_args[] = { {"vpn-type", TRUE, &vpn_type, !ask},
|
||||||
{"user", TRUE, &user_c, FALSE},
|
{"user", TRUE, &user_c, FALSE},
|
||||||
{NULL} };
|
{NULL} };
|
||||||
gs_free const char **plugin_names = NULL;
|
|
||||||
|
|
||||||
if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error))
|
if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -5910,15 +5907,11 @@ cleanup_bridge_slave:
|
|||||||
if (vpn_type_ask)
|
if (vpn_type_ask)
|
||||||
vpn_type = g_strstrip (vpn_type_ask);
|
vpn_type = g_strstrip (vpn_type_ask);
|
||||||
|
|
||||||
plugin_names = nm_vpn_get_plugin_names (FALSE);
|
service_type_free = nm_vpn_plugin_info_list_find_service_type (nm_vpn_get_plugin_infos (), vpn_type);
|
||||||
if (!(st = nmc_string_is_valid (vpn_type, plugin_names, NULL))) {
|
if (!service_type_free)
|
||||||
g_print (_("Warning: 'vpn-type': %s not known.\n"), vpn_type);
|
g_print (_("Warning: 'vpn-type': %s not known.\n"), vpn_type);
|
||||||
st = vpn_type;
|
else
|
||||||
}
|
vpn_type = service_type_free;
|
||||||
|
|
||||||
service_type = nm_vpn_get_service_for_name (st);
|
|
||||||
if (!service_type)
|
|
||||||
service_type = service_type_free = nm_vpn_get_service_for_name_default (st);
|
|
||||||
|
|
||||||
/* Also ask for all optional arguments if '--ask' is specified. */
|
/* Also ask for all optional arguments if '--ask' is specified. */
|
||||||
user = g_strdup (user_c);
|
user = g_strdup (user_c);
|
||||||
@@ -5929,12 +5922,11 @@ cleanup_bridge_slave:
|
|||||||
s_vpn = (NMSettingVpn *) nm_setting_vpn_new ();
|
s_vpn = (NMSettingVpn *) nm_setting_vpn_new ();
|
||||||
nm_connection_add_setting (connection, NM_SETTING (s_vpn));
|
nm_connection_add_setting (connection, NM_SETTING (s_vpn));
|
||||||
|
|
||||||
g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, service_type, NULL);
|
g_object_set (s_vpn, NM_SETTING_VPN_SERVICE_TYPE, vpn_type, NULL);
|
||||||
g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, user, NULL);
|
g_object_set (s_vpn, NM_SETTING_VPN_USER_NAME, user, NULL);
|
||||||
|
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
cleanup_vpn:
|
cleanup_vpn:
|
||||||
g_free (vpn_type_ask);
|
|
||||||
g_free (user);
|
g_free (user);
|
||||||
if (!success)
|
if (!success)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@@ -6702,10 +6694,10 @@ update_connection (gboolean persistent,
|
|||||||
static char *
|
static char *
|
||||||
gen_func_vpn_types (const char *text, int state)
|
gen_func_vpn_types (const char *text, int state)
|
||||||
{
|
{
|
||||||
gs_free const char **plugin_names = NULL;
|
gs_strfreev char **plugin_names = NULL;
|
||||||
|
|
||||||
plugin_names = nm_vpn_get_plugin_names (FALSE);
|
plugin_names = nm_vpn_plugin_info_list_get_service_types (nm_vpn_get_plugin_infos (), FALSE, TRUE);
|
||||||
return nmc_rl_gen_func_basic (text, state, plugin_names);
|
return nmc_rl_gen_func_basic (text, state, (const char **) plugin_names);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@@ -10625,6 +10617,7 @@ do_connection_import (NmCli *nmc, gboolean temporary, int argc, char **argv)
|
|||||||
AddConnectionInfo *info;
|
AddConnectionInfo *info;
|
||||||
NMConnection *connection = NULL;
|
NMConnection *connection = NULL;
|
||||||
NMVpnEditorPlugin *plugin;
|
NMVpnEditorPlugin *plugin;
|
||||||
|
gs_free char *service_type = NULL;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
if (nmc->ask) {
|
if (nmc->ask) {
|
||||||
@@ -10682,8 +10675,15 @@ do_connection_import (NmCli *nmc, gboolean temporary, int argc, char **argv)
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
service_type = nm_vpn_plugin_info_list_find_service_type (nm_vpn_get_plugin_infos (), type);
|
||||||
|
if (!service_type) {
|
||||||
|
g_string_printf (nmc->return_text, _("Error: failed to find VPN plugin for %s."), type);
|
||||||
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
/* Import VPN configuration */
|
/* Import VPN configuration */
|
||||||
plugin = nm_vpn_lookup_plugin (type, NULL, &error);
|
plugin = nm_vpn_get_editor_plugin (service_type, &error);
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
g_string_printf (nmc->return_text, _("Error: failed to load VPN plugin: %s."),
|
g_string_printf (nmc->return_text, _("Error: failed to load VPN plugin: %s."),
|
||||||
error->message);
|
error->message);
|
||||||
@@ -10790,7 +10790,7 @@ do_connection_export (NmCli *nmc, int argc, char **argv)
|
|||||||
type = nm_setting_vpn_get_service_type (nm_connection_get_setting_vpn (connection));
|
type = nm_setting_vpn_get_service_type (nm_connection_get_setting_vpn (connection));
|
||||||
|
|
||||||
/* Export VPN configuration */
|
/* Export VPN configuration */
|
||||||
plugin = nm_vpn_lookup_plugin (type, NULL, &error);
|
plugin = nm_vpn_get_editor_plugin (type, &error);
|
||||||
if (!plugin) {
|
if (!plugin) {
|
||||||
g_string_printf (nmc->return_text, _("Error: failed to load VPN plugin: %s."),
|
g_string_printf (nmc->return_text, _("Error: failed to load VPN plugin: %s."),
|
||||||
error->message);
|
error->message);
|
||||||
|
@@ -19,8 +19,6 @@
|
|||||||
/**
|
/**
|
||||||
* SECTION:nm-vpn-helpers
|
* SECTION:nm-vpn-helpers
|
||||||
* @short_description: VPN-related utilities
|
* @short_description: VPN-related utilities
|
||||||
*
|
|
||||||
* Some functions should probably eventually move into libnm.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "nm-default.h"
|
#include "nm-default.h"
|
||||||
@@ -31,30 +29,23 @@
|
|||||||
|
|
||||||
#include "nm-utils.h"
|
#include "nm-utils.h"
|
||||||
|
|
||||||
static gboolean plugins_loaded;
|
/*****************************************************************************/
|
||||||
static GSList *plugins = NULL;
|
|
||||||
|
|
||||||
NMVpnEditorPlugin *
|
NMVpnEditorPlugin *
|
||||||
nm_vpn_lookup_plugin (const char *name, const char *service, GError **error)
|
nm_vpn_get_editor_plugin (const char *service_type, GError **error)
|
||||||
{
|
{
|
||||||
NMVpnEditorPlugin *plugin = NULL;
|
NMVpnEditorPlugin *plugin = NULL;
|
||||||
NMVpnPluginInfo *plugin_info;
|
NMVpnPluginInfo *plugin_info;
|
||||||
gs_free_error GError *local = NULL;
|
gs_free_error GError *local = NULL;
|
||||||
|
|
||||||
g_return_val_if_fail (!service ^ !name, NULL);
|
g_return_val_if_fail (service_type, NULL);
|
||||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||||
|
|
||||||
if (G_UNLIKELY (!plugins_loaded))
|
plugin_info = nm_vpn_plugin_info_list_find_by_service (nm_vpn_get_plugin_infos (), service_type);
|
||||||
nm_vpn_get_plugins ();
|
|
||||||
|
|
||||||
if (service)
|
|
||||||
plugin_info = nm_vpn_plugin_info_list_find_by_service (plugins, service);
|
|
||||||
else
|
|
||||||
plugin_info = nm_vpn_plugin_info_list_find_by_name (plugins, name);
|
|
||||||
|
|
||||||
if (!plugin_info) {
|
if (!plugin_info) {
|
||||||
g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
|
g_set_error (error, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_FAILED,
|
||||||
_("unknown VPN plugin \"%s\""), service ?: name);
|
_("unknown VPN plugin \"%s\""), service_type);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
plugin = nm_vpn_plugin_info_get_editor_plugin (plugin_info);
|
plugin = nm_vpn_plugin_info_get_editor_plugin (plugin_info);
|
||||||
@@ -86,8 +77,11 @@ nm_vpn_lookup_plugin (const char *name, const char *service, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GSList *
|
GSList *
|
||||||
nm_vpn_get_plugins (void)
|
nm_vpn_get_plugin_infos (void)
|
||||||
{
|
{
|
||||||
|
static bool plugins_loaded;
|
||||||
|
static GSList *plugins = NULL;
|
||||||
|
|
||||||
if (G_LIKELY (plugins_loaded))
|
if (G_LIKELY (plugins_loaded))
|
||||||
return plugins;
|
return plugins;
|
||||||
plugins_loaded = TRUE;
|
plugins_loaded = TRUE;
|
||||||
@@ -95,78 +89,6 @@ nm_vpn_get_plugins (void)
|
|||||||
return plugins;
|
return plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
_strcmp_data (gconstpointer a, gconstpointer b, gpointer unused)
|
|
||||||
{
|
|
||||||
return strcmp (a, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
const char **
|
|
||||||
nm_vpn_get_plugin_names (gboolean only_available_plugins)
|
|
||||||
{
|
|
||||||
GSList *p;
|
|
||||||
const char **list;
|
|
||||||
const char *known_names[] = {
|
|
||||||
"openvpn",
|
|
||||||
"vpnc",
|
|
||||||
"pptp",
|
|
||||||
"openconnect",
|
|
||||||
"openswan",
|
|
||||||
"libreswan",
|
|
||||||
"strongswan",
|
|
||||||
"ssh",
|
|
||||||
"l2tp",
|
|
||||||
"iodine",
|
|
||||||
"fortisslvpn",
|
|
||||||
};
|
|
||||||
guint i, j, k;
|
|
||||||
|
|
||||||
p = nm_vpn_get_plugins ();
|
|
||||||
list = g_new0 (const char *, g_slist_length (p) + G_N_ELEMENTS (known_names) + 1);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
for (i = 0; p; p = p->next)
|
|
||||||
list[i++] = nm_vpn_plugin_info_get_name (p->data);
|
|
||||||
if (!only_available_plugins) {
|
|
||||||
for (j = 0; j < G_N_ELEMENTS (known_names); j++)
|
|
||||||
list[i++] = known_names[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
g_qsort_with_data (list, i, sizeof (gpointer), _strcmp_data, NULL);
|
|
||||||
|
|
||||||
/* remove duplicates */
|
|
||||||
for (k = 0, j = 1; j < i; j++) {
|
|
||||||
if (nm_streq (list[k], list[j]))
|
|
||||||
continue;
|
|
||||||
list[k++] = list[j];
|
|
||||||
}
|
|
||||||
list[k++] = NULL;
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *
|
|
||||||
nm_vpn_get_service_for_name (const char *name)
|
|
||||||
{
|
|
||||||
NMVpnPluginInfo *plugin_info;
|
|
||||||
|
|
||||||
g_return_val_if_fail (name, NULL);
|
|
||||||
|
|
||||||
plugin_info = nm_vpn_plugin_info_list_find_by_name (nm_vpn_get_plugins (), name);
|
|
||||||
if (plugin_info) {
|
|
||||||
/* this only means we have a .name file (NMVpnPluginInfo). Possibly the
|
|
||||||
* NMVpnEditorPlugin is not loadable. */
|
|
||||||
return nm_vpn_plugin_info_get_service (plugin_info);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
nm_vpn_get_service_for_name_default (const char *name)
|
|
||||||
{
|
|
||||||
return g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
nm_vpn_supports_ipv6 (NMConnection *connection)
|
nm_vpn_supports_ipv6 (NMConnection *connection)
|
||||||
{
|
{
|
||||||
@@ -182,7 +104,7 @@ nm_vpn_supports_ipv6 (NMConnection *connection)
|
|||||||
if (!service_type)
|
if (!service_type)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
plugin = nm_vpn_lookup_plugin (NULL, service_type, NULL);
|
plugin = nm_vpn_get_editor_plugin (service_type, NULL);
|
||||||
if (!plugin)
|
if (!plugin)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@@ -28,14 +28,9 @@ struct {
|
|||||||
const char *ui_name;
|
const char *ui_name;
|
||||||
} typedef VpnPasswordName;
|
} typedef VpnPasswordName;
|
||||||
|
|
||||||
GSList *nm_vpn_get_plugins (void);
|
GSList *nm_vpn_get_plugin_infos (void);
|
||||||
|
|
||||||
const char **nm_vpn_get_plugin_names (gboolean only_available_plugins);
|
NMVpnEditorPlugin *nm_vpn_get_editor_plugin (const char *service_type, GError **error);
|
||||||
|
|
||||||
const char *nm_vpn_get_service_for_name (const char *name);
|
|
||||||
char * nm_vpn_get_service_for_name_default (const char *name);
|
|
||||||
|
|
||||||
NMVpnEditorPlugin *nm_vpn_lookup_plugin (const char *name, const char *service, GError **error);
|
|
||||||
|
|
||||||
gboolean nm_vpn_supports_ipv6 (NMConnection *connection);
|
gboolean nm_vpn_supports_ipv6 (NMConnection *connection);
|
||||||
|
|
||||||
|
@@ -223,7 +223,7 @@ nm_editor_utils_get_connection_type_list (void)
|
|||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
/* Add "VPN" only if there are plugins */
|
/* Add "VPN" only if there are plugins */
|
||||||
vpn_plugins_hash = nm_vpn_get_plugins ();
|
vpn_plugins_hash = nm_vpn_get_plugin_infos ();
|
||||||
have_vpn_plugins = vpn_plugins_hash && g_hash_table_size (vpn_plugins_hash);
|
have_vpn_plugins = vpn_plugins_hash && g_hash_table_size (vpn_plugins_hash);
|
||||||
if (have_vpn_plugins) {
|
if (have_vpn_plugins) {
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
|
@@ -233,12 +233,6 @@ route_writer (KeyfileWriterInfo *info,
|
|||||||
write_ip_values (info->keyfile, setting_name, array, NULL, TRUE);
|
write_ip_values (info->keyfile, setting_name, array, NULL, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
sort_hash_keys (gconstpointer a, gconstpointer b, gpointer user_data)
|
|
||||||
{
|
|
||||||
return g_strcmp0 (*((const char **) a), *((const char **) b));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write_hash_of_string (GKeyFile *file,
|
write_hash_of_string (GKeyFile *file,
|
||||||
NMSetting *setting,
|
NMSetting *setting,
|
||||||
@@ -262,7 +256,7 @@ write_hash_of_string (GKeyFile *file,
|
|||||||
if (!keys)
|
if (!keys)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
g_qsort_with_data (keys, l, sizeof (const char *), sort_hash_keys, NULL);
|
g_qsort_with_data (keys, l, sizeof (const char *), nm_strcmp_p_with_data, NULL);
|
||||||
|
|
||||||
for (i = 0; keys[i]; i++) {
|
for (i = 0; keys[i]; i++) {
|
||||||
const char *property, *data;
|
const char *property, *data;
|
||||||
|
@@ -74,6 +74,159 @@ nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface)
|
|||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
NMVpnPluginInfo *plugin_info;
|
||||||
|
} NMVpnEditorPluginPrivate;
|
||||||
|
|
||||||
|
static void
|
||||||
|
_private_destroy (gpointer data)
|
||||||
|
{
|
||||||
|
NMVpnEditorPluginPrivate *priv = data;
|
||||||
|
|
||||||
|
if (priv->plugin_info)
|
||||||
|
g_object_remove_weak_pointer ((GObject *) priv->plugin_info, (gpointer *) &priv->plugin_info);
|
||||||
|
|
||||||
|
g_slice_free (NMVpnEditorPluginPrivate, priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NMVpnEditorPluginPrivate *
|
||||||
|
_private_get (NMVpnEditorPlugin *plugin, gboolean create)
|
||||||
|
{
|
||||||
|
static GQuark quark = 0;
|
||||||
|
NMVpnEditorPluginPrivate *priv;
|
||||||
|
|
||||||
|
nm_assert (NM_IS_VPN_EDITOR_PLUGIN (plugin));
|
||||||
|
|
||||||
|
if (G_UNLIKELY (quark == 0))
|
||||||
|
quark = g_quark_from_string ("nm-vpn-editor-plugin-private");
|
||||||
|
|
||||||
|
priv = g_object_get_qdata ((GObject *) plugin, quark);
|
||||||
|
if (G_LIKELY (priv))
|
||||||
|
return priv;
|
||||||
|
if (!create)
|
||||||
|
return NULL;
|
||||||
|
priv = g_slice_new0 (NMVpnEditorPluginPrivate);
|
||||||
|
g_object_set_qdata_full ((GObject *) plugin, quark, priv, _private_destroy);
|
||||||
|
return priv;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NM_VPN_EDITOR_PLUGIN_GET_PRIVATE(plugin) _private_get (plugin, TRUE)
|
||||||
|
#define NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE(plugin) _private_get (plugin, FALSE)
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_vpn_editor_plugin_get_plugin_info:
|
||||||
|
* @plugin: the #NMVpnEditorPlugin instance
|
||||||
|
*
|
||||||
|
* Returns: (transfer-none): if set, return the #NMVpnPluginInfo instance.
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
*/
|
||||||
|
NMVpnPluginInfo *
|
||||||
|
nm_vpn_editor_plugin_get_plugin_info (NMVpnEditorPlugin *plugin)
|
||||||
|
{
|
||||||
|
NMVpnEditorPluginPrivate *priv;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL);
|
||||||
|
|
||||||
|
priv = NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE (plugin);
|
||||||
|
return priv ? priv->plugin_info : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_vpn_editor_plugin_set_plugin_info:
|
||||||
|
* @plugin: the #NMVpnEditorPlugin instance
|
||||||
|
* @plugin_info: (allow-none): a #NMVpnPluginInfo instance or %NULL
|
||||||
|
*
|
||||||
|
* Returns: (transfer-none): set or clear the plugin-info instance.
|
||||||
|
* This takes a weak reference on @plugin_info, to avoid circular
|
||||||
|
* reference as the plugin-info might also reference the editor-plugin.
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nm_vpn_editor_plugin_set_plugin_info (NMVpnEditorPlugin *plugin, NMVpnPluginInfo *plugin_info)
|
||||||
|
{
|
||||||
|
NMVpnEditorPluginInterface *interface;
|
||||||
|
NMVpnEditorPluginPrivate *priv;
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin));
|
||||||
|
|
||||||
|
if (!plugin_info) {
|
||||||
|
priv = NM_VPN_EDITOR_PLUGIN_TRY_GET_PRIVATE (plugin);
|
||||||
|
if (!priv)
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
g_return_if_fail (NM_IS_VPN_PLUGIN_INFO (plugin_info));
|
||||||
|
priv = NM_VPN_EDITOR_PLUGIN_GET_PRIVATE (plugin);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (priv->plugin_info == plugin_info)
|
||||||
|
return;
|
||||||
|
if (priv->plugin_info)
|
||||||
|
g_object_remove_weak_pointer ((GObject *) priv->plugin_info, (gpointer *) &priv->plugin_info);
|
||||||
|
priv->plugin_info = plugin_info;
|
||||||
|
if (priv->plugin_info)
|
||||||
|
g_object_add_weak_pointer ((GObject *) priv->plugin_info, (gpointer *) &priv->plugin_info);
|
||||||
|
|
||||||
|
if (plugin_info) {
|
||||||
|
interface = NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin);
|
||||||
|
if (interface->notify_plugin_info_set)
|
||||||
|
interface->notify_plugin_info_set (plugin, plugin_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_vpn_editor_plugin_get_vt:
|
||||||
|
* @plugin: the #NMVpnEditorPlugin
|
||||||
|
* @vt: (out): buffer to be filled with the VT table of the plugin
|
||||||
|
* @vt_size: the size of the buffer. Can be 0 to only query the
|
||||||
|
* size of plugin's VT.
|
||||||
|
*
|
||||||
|
* Returns an opaque VT function table for the plugin to extend
|
||||||
|
* functionality. The actual meaning of NMVpnEditorPluginVT is not
|
||||||
|
* defined in public API of libnm, instead it must be agreed by
|
||||||
|
* both the plugin and the caller. See the header-only file
|
||||||
|
* 'nm-vpn-editor-plugin-call.h' which defines the meaning.
|
||||||
|
*
|
||||||
|
* Returns: the actual size of the @plugin's virtual function table.
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
**/
|
||||||
|
gsize
|
||||||
|
nm_vpn_editor_plugin_get_vt (NMVpnEditorPlugin *plugin,
|
||||||
|
NMVpnEditorPluginVT *vt,
|
||||||
|
gsize vt_size)
|
||||||
|
{
|
||||||
|
const NMVpnEditorPluginVT *p_vt = NULL;
|
||||||
|
gsize p_vt_size = 0;
|
||||||
|
NMVpnEditorPluginInterface *interface;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), 0);
|
||||||
|
|
||||||
|
if (vt_size) {
|
||||||
|
g_return_val_if_fail (vt, 0);
|
||||||
|
memset (vt, 0, vt_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
interface = NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin);
|
||||||
|
if (interface->get_vt) {
|
||||||
|
p_vt = interface->get_vt (plugin, &p_vt_size);
|
||||||
|
if (!p_vt)
|
||||||
|
p_vt_size = 0;
|
||||||
|
g_return_val_if_fail (p_vt_size, 0);
|
||||||
|
memcpy (vt, p_vt, MIN (vt_size, p_vt_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
return p_vt_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*********************************************************************/
|
||||||
|
|
||||||
static NMVpnEditorPlugin *
|
static NMVpnEditorPlugin *
|
||||||
_nm_vpn_editor_plugin_load (const char *plugin_name,
|
_nm_vpn_editor_plugin_load (const char *plugin_name,
|
||||||
gboolean do_file_checks,
|
gboolean do_file_checks,
|
||||||
|
@@ -34,6 +34,8 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
struct _NMVpnPluginInfo;
|
||||||
|
|
||||||
typedef struct _NMVpnEditorPlugin NMVpnEditorPlugin;
|
typedef struct _NMVpnEditorPlugin NMVpnEditorPlugin;
|
||||||
typedef struct _NMVpnEditor NMVpnEditor;
|
typedef struct _NMVpnEditor NMVpnEditor;
|
||||||
|
|
||||||
@@ -80,6 +82,8 @@ typedef enum /*< flags >*/ {
|
|||||||
/* D-Bus service name of the plugin's VPN service */
|
/* D-Bus service name of the plugin's VPN service */
|
||||||
#define NM_VPN_EDITOR_PLUGIN_SERVICE "service"
|
#define NM_VPN_EDITOR_PLUGIN_SERVICE "service"
|
||||||
|
|
||||||
|
typedef struct _NMVpnEditorPluginVT NMVpnEditorPluginVT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMVpnEditorPluginInterface:
|
* NMVpnEditorPluginInterface:
|
||||||
* @g_iface: the parent interface
|
* @g_iface: the parent interface
|
||||||
@@ -97,6 +101,8 @@ typedef enum /*< flags >*/ {
|
|||||||
* @get_suggested_filename: For a given connection, return a suggested file
|
* @get_suggested_filename: For a given connection, return a suggested file
|
||||||
* name. Returned value will be %NULL or a suggested file name to be freed by
|
* name. Returned value will be %NULL or a suggested file name to be freed by
|
||||||
* the caller.
|
* the caller.
|
||||||
|
* @get_vt: return a virtual function table to implement further functions in
|
||||||
|
* the plugin, without requiring to update libnm. Used by nm_vpn_editor_plugin_get_vt().
|
||||||
*
|
*
|
||||||
* Interface for VPN editor plugins.
|
* Interface for VPN editor plugins.
|
||||||
*/
|
*/
|
||||||
@@ -119,6 +125,12 @@ typedef struct {
|
|||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
char * (*get_suggested_filename) (NMVpnEditorPlugin *plugin, NMConnection *connection);
|
char * (*get_suggested_filename) (NMVpnEditorPlugin *plugin, NMConnection *connection);
|
||||||
|
|
||||||
|
void (*notify_plugin_info_set) (NMVpnEditorPlugin *plugin,
|
||||||
|
struct _NMVpnPluginInfo *plugin_info);
|
||||||
|
|
||||||
|
const NMVpnEditorPluginVT *(*get_vt) (NMVpnEditorPlugin *plugin,
|
||||||
|
gsize *out_vt_size);
|
||||||
} NMVpnEditorPluginInterface;
|
} NMVpnEditorPluginInterface;
|
||||||
|
|
||||||
GType nm_vpn_editor_plugin_get_type (void);
|
GType nm_vpn_editor_plugin_get_type (void);
|
||||||
@@ -129,6 +141,11 @@ NMVpnEditor *nm_vpn_editor_plugin_get_editor (NMVpnEditorPlugin *plugin,
|
|||||||
|
|
||||||
NMVpnEditorPluginCapability nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin);
|
NMVpnEditorPluginCapability nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin);
|
||||||
|
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
gsize nm_vpn_editor_plugin_get_vt (NMVpnEditorPlugin *plugin,
|
||||||
|
NMVpnEditorPluginVT *vt,
|
||||||
|
gsize vt_size);
|
||||||
|
|
||||||
NMConnection *nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin,
|
NMConnection *nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin,
|
||||||
const char *path,
|
const char *path,
|
||||||
GError **error);
|
GError **error);
|
||||||
@@ -152,6 +169,13 @@ NMVpnEditorPlugin *nm_vpn_editor_plugin_load (const char *plugin_name,
|
|||||||
const char *check_service,
|
const char *check_service,
|
||||||
GError **error);
|
GError **error);
|
||||||
|
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
struct _NMVpnPluginInfo *nm_vpn_editor_plugin_get_plugin_info (NMVpnEditorPlugin *plugin);
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
void nm_vpn_editor_plugin_set_plugin_info (NMVpnEditorPlugin *plugin, struct _NMVpnPluginInfo *plugin_info);
|
||||||
|
|
||||||
|
#include "nm-vpn-plugin-info.h"
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __NM_VPN_EDITOR_PLUGIN_H__ */
|
#endif /* __NM_VPN_EDITOR_PLUGIN_H__ */
|
||||||
|
@@ -491,7 +491,7 @@ nm_vpn_plugin_info_list_add (GSList **list, NMVpnPluginInfo *plugin_info, GError
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* the plugin must have unique values for certain properties. E.g. two different
|
/* the plugin must have unique values for certain properties. E.g. two different
|
||||||
* plugins cannot share the same service name. */
|
* plugins cannot share the same service type. */
|
||||||
if (!_check_no_conflict (plugin_info, iter->data, error))
|
if (!_check_no_conflict (plugin_info, iter->data, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@@ -573,10 +573,24 @@ nm_vpn_plugin_info_list_find_by_filename (GSList *list, const char *filename)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NMVpnPluginInfo *
|
||||||
|
_list_find_by_service (GSList *list, const char *service)
|
||||||
|
{
|
||||||
|
for (; list; list = list->next) {
|
||||||
|
NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (list->data);
|
||||||
|
|
||||||
|
if ( nm_streq (priv->service, service)
|
||||||
|
|| _nm_utils_strv_find_first (priv->aliases, -1, service) >= 0)
|
||||||
|
return list->data;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_vpn_plugin_info_list_find_by_service:
|
* nm_vpn_plugin_info_list_find_by_service:
|
||||||
* @list: (element-type NMVpnPluginInfo): list of plugins
|
* @list: (element-type NMVpnPluginInfo): list of plugins
|
||||||
* @service: service to search
|
* @service: service to search. This can be the main service-type
|
||||||
|
* or one of the provided aliases.
|
||||||
*
|
*
|
||||||
* Returns: (transfer none): the first plugin with a matching @service (or %NULL).
|
* Returns: (transfer none): the first plugin with a matching @service (or %NULL).
|
||||||
*
|
*
|
||||||
@@ -585,29 +599,182 @@ nm_vpn_plugin_info_list_find_by_filename (GSList *list, const char *filename)
|
|||||||
NMVpnPluginInfo *
|
NMVpnPluginInfo *
|
||||||
nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service)
|
nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service)
|
||||||
{
|
{
|
||||||
GSList *iter;
|
|
||||||
|
|
||||||
if (!service)
|
if (!service)
|
||||||
g_return_val_if_reached (NULL);
|
g_return_val_if_reached (NULL);
|
||||||
|
return _list_find_by_service (list, service);
|
||||||
|
}
|
||||||
|
|
||||||
/* First, consider the primary service name. */
|
/* known_names are well known short names for the service-type. They all implicitly
|
||||||
|
* have a prefix "org.freedesktop.NetworkManager." + known_name. */
|
||||||
|
static const char *known_names[] = {
|
||||||
|
"openvpn",
|
||||||
|
"vpnc",
|
||||||
|
"pptp",
|
||||||
|
"openconnect",
|
||||||
|
"openswan",
|
||||||
|
"libreswan",
|
||||||
|
"strongswan",
|
||||||
|
"ssh",
|
||||||
|
"l2tp",
|
||||||
|
"iodine",
|
||||||
|
"fortisslvpn",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_vpn_plugin_info_list_find_service_type:
|
||||||
|
* @list: a possibly empty #GSList of #NMVpnPluginInfo instances
|
||||||
|
* @name: a name to lookup the service-type.
|
||||||
|
*
|
||||||
|
* A VPN plugin provides one or several service-types, like org.freedesktop.NetworkManager.libreswan
|
||||||
|
* Certain plugins provide more then one service type, via aliases (org.freedesktop.NetworkManager.openswan).
|
||||||
|
* This function looks up a service-type (or an alias) based on a name.
|
||||||
|
*
|
||||||
|
* Preferably, the name can be a full service-type/alias of an installed
|
||||||
|
* plugin. Otherwise, it can be the name of a VPN plugin (in which case, the
|
||||||
|
* primary, non-aliased service-type is returned). Otherwise, it can be
|
||||||
|
* one of several well known short-names (which is a hard-coded list of
|
||||||
|
* types in libnm). On success, this returns a full qualified service-type
|
||||||
|
* (or an alias). It doesn't say, that such an plugin is actually available,
|
||||||
|
* but it could be retrieved via nm_vpn_plugin_info_list_find_by_service().
|
||||||
|
*
|
||||||
|
* Returns: (transfer-full): the resolved service-type or %NULL on failure.
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
nm_vpn_plugin_info_list_find_service_type (GSList *list, const char *name)
|
||||||
|
{
|
||||||
|
GSList *iter;
|
||||||
|
char *n;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
g_return_val_if_reached (NULL);
|
||||||
|
if (!*name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* First, try to interpret @name as a full service-type (or alias). */
|
||||||
|
if (_list_find_by_service (list, name))
|
||||||
|
return g_strdup (name);
|
||||||
|
|
||||||
|
/* try to interpret @name as plugin name, in which case we return
|
||||||
|
* the main service-type (not an alias). */
|
||||||
for (iter = list; iter; iter = iter->next) {
|
for (iter = list; iter; iter = iter->next) {
|
||||||
if (strcmp (nm_vpn_plugin_info_get_service (iter->data), service) == 0)
|
NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (iter->data);
|
||||||
return iter->data;
|
|
||||||
|
if (nm_streq (priv->name, name))
|
||||||
|
return g_strdup (priv->service);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Then look into the aliases. */
|
/* check the hard-coded list of short-names. They all have have the same
|
||||||
for (iter = list; iter; iter = iter->next) {
|
* well-known prefix org.freedesktop.NetworkManager and the name. */
|
||||||
char **aliases = (NM_VPN_PLUGIN_INFO_GET_PRIVATE (iter->data))->aliases;
|
if (_nm_utils_strv_find_first ((char **) known_names, G_N_ELEMENTS (known_names), name) >= 0)
|
||||||
|
return g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, name);
|
||||||
|
|
||||||
|
/* try, if there exists a plugin with @name under org.freedesktop.NetworkManager.
|
||||||
|
* Allow this to be a valid abbreviation. */
|
||||||
|
n = g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, name);
|
||||||
|
if (_list_find_by_service (list, n))
|
||||||
|
return n;
|
||||||
|
g_free (n);
|
||||||
|
|
||||||
|
/* currently, VPN plugins have no way to define a short-name for their
|
||||||
|
* alias name, unless the alias name is prefixed by org.freedesktop.NetworkManager. */
|
||||||
|
|
||||||
if (!aliases)
|
|
||||||
continue;
|
|
||||||
if (_nm_utils_strv_find_first (aliases, -1, service) >= 0)
|
|
||||||
return iter->data;
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_service_type_get_default_abbreviation (const char *service_type)
|
||||||
|
{
|
||||||
|
if (!g_str_has_prefix (service_type, NM_DBUS_INTERFACE))
|
||||||
|
return NULL;
|
||||||
|
service_type += NM_STRLEN (NM_DBUS_INTERFACE);
|
||||||
|
if (service_type[0] != '.')
|
||||||
|
return NULL;
|
||||||
|
service_type++;
|
||||||
|
if (!service_type[0])
|
||||||
|
return NULL;
|
||||||
|
return service_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_vpn_plugin_info_list_get_service_types:
|
||||||
|
* @list: a possibly empty #GSList of #NMVpnPluginInfo
|
||||||
|
* @only_existing: only include results that are actually in @list.
|
||||||
|
* Otherwise, the result is extended with a hard-code list or
|
||||||
|
* well-known plugins
|
||||||
|
* @with_abbreviations: if %FALSE, only full service types are returned.
|
||||||
|
* Otherwise, this also includes abbreviated names that can be used
|
||||||
|
* with nm_vpn_plugin_info_list_find_service_type().
|
||||||
|
*
|
||||||
|
* Returns: (transfer-full): a %NULL terminated strv list of strings.
|
||||||
|
* The list itself and the values must be freed with g_strfreev().
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
*/
|
||||||
|
char **
|
||||||
|
nm_vpn_plugin_info_list_get_service_types (GSList *list,
|
||||||
|
gboolean only_existing,
|
||||||
|
gboolean with_abbreviations)
|
||||||
|
{
|
||||||
|
GSList *iter;
|
||||||
|
GPtrArray *l;
|
||||||
|
guint i, j;
|
||||||
|
const char *n;
|
||||||
|
|
||||||
|
l = g_ptr_array_sized_new (20);
|
||||||
|
|
||||||
|
for (iter = list; iter; iter = iter->next) {
|
||||||
|
NMVpnPluginInfoPrivate *priv = NM_VPN_PLUGIN_INFO_GET_PRIVATE (iter->data);
|
||||||
|
|
||||||
|
g_ptr_array_add (l, g_strdup (priv->service));
|
||||||
|
if (priv->aliases) {
|
||||||
|
for (i = 0; priv->aliases[i]; i++)
|
||||||
|
g_ptr_array_add (l, g_strdup (priv->aliases[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (with_abbreviations) {
|
||||||
|
g_ptr_array_add (l, g_strdup (priv->name));
|
||||||
|
n = _service_type_get_default_abbreviation (priv->service);
|
||||||
|
if (n)
|
||||||
|
g_ptr_array_add (l, g_strdup (n));
|
||||||
|
for (i = 0; priv->aliases[i]; i++) {
|
||||||
|
n = _service_type_get_default_abbreviation (priv->aliases[i]);
|
||||||
|
if (n)
|
||||||
|
g_ptr_array_add (l, g_strdup (n));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!only_existing) {
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (known_names); i++) {
|
||||||
|
g_ptr_array_add (l, g_strdup_printf ("%s.%s", NM_DBUS_INTERFACE, known_names[i]));
|
||||||
|
if (with_abbreviations)
|
||||||
|
g_ptr_array_add (l, g_strdup (known_names[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->len <= 0) {
|
||||||
|
g_ptr_array_free (l, TRUE);
|
||||||
|
return g_new0 (char *, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sort the result and remove duplicates. */
|
||||||
|
g_ptr_array_sort (l, nm_strcmp_p);
|
||||||
|
for (i = 1, j = 1; i < l->len; i++) {
|
||||||
|
if (nm_streq (l->pdata[j-1], l->pdata[i]))
|
||||||
|
g_free (l->pdata[i]);
|
||||||
|
else
|
||||||
|
l->pdata[j++] = l->pdata[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j == l->len)
|
||||||
|
g_ptr_array_add (l, NULL);
|
||||||
|
else
|
||||||
|
l->pdata[j] = NULL;
|
||||||
|
return (char **) g_ptr_array_free (l, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************************************/
|
/*********************************************************************/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -767,6 +934,32 @@ nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_vpn_plugin_info_get_aliases:
|
||||||
|
* @self: plugin info instance
|
||||||
|
*
|
||||||
|
* Returns: (array zero-terminated=1) (element-type utf8) (transfer none):
|
||||||
|
* the aliases from the name-file.
|
||||||
|
*
|
||||||
|
* Since: 1.4
|
||||||
|
*/
|
||||||
|
const char *const*
|
||||||
|
nm_vpn_plugin_info_get_aliases (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 (priv->aliases)
|
||||||
|
return (const char *const*) priv->aliases;
|
||||||
|
|
||||||
|
/* For convenience, we always want to return non-NULL, even for empty
|
||||||
|
* aliases. Hack around that, by making a NULL terminated array using
|
||||||
|
* the NULL of priv->aliases. */
|
||||||
|
return (const char *const*) &priv->aliases;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nm_vpn_plugin_info_lookup_property:
|
* nm_vpn_plugin_info_lookup_property:
|
||||||
* @self: plugin info instance
|
* @self: plugin info instance
|
||||||
@@ -896,6 +1089,8 @@ nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *self, GError **error)
|
|||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
error);
|
error);
|
||||||
|
if (priv->editor_plugin)
|
||||||
|
nm_vpn_editor_plugin_set_plugin_info (priv->editor_plugin, self);
|
||||||
return priv->editor_plugin;
|
return priv->editor_plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1003,6 +1198,8 @@ init_sync (GInitable *initable, GCancellable *cancellable, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
priv->aliases = g_key_file_get_string_list (priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "aliases", NULL, NULL);
|
priv->aliases = g_key_file_get_string_list (priv->keyfile, NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION, "aliases", NULL, NULL);
|
||||||
|
if (priv->aliases && !priv->aliases[0])
|
||||||
|
g_clear_pointer (&priv->aliases, g_free);
|
||||||
|
|
||||||
priv->keys = g_hash_table_new_full (_nm_utils_strstrdictkey_hash,
|
priv->keys = g_hash_table_new_full (_nm_utils_strstrdictkey_hash,
|
||||||
_nm_utils_strstrdictkey_equal,
|
_nm_utils_strstrdictkey_equal,
|
||||||
|
@@ -44,10 +44,12 @@ G_BEGIN_DECLS
|
|||||||
#define NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM "libnm"
|
#define NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM "libnm"
|
||||||
#define NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME "GNOME"
|
#define NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME "GNOME"
|
||||||
|
|
||||||
|
struct _NMVpnPluginInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NMVpnPluginInfo:
|
* NMVpnPluginInfo:
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct _NMVpnPluginInfo {
|
||||||
NM_AVAILABLE_IN_1_2
|
NM_AVAILABLE_IN_1_2
|
||||||
GObject parent;
|
GObject parent;
|
||||||
} NMVpnPluginInfo;
|
} NMVpnPluginInfo;
|
||||||
@@ -93,6 +95,8 @@ NM_AVAILABLE_IN_1_4
|
|||||||
gboolean nm_vpn_plugin_info_supports_hints (NMVpnPluginInfo *self);
|
gboolean nm_vpn_plugin_info_supports_hints (NMVpnPluginInfo *self);
|
||||||
NM_AVAILABLE_IN_1_2
|
NM_AVAILABLE_IN_1_2
|
||||||
gboolean nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self);
|
gboolean nm_vpn_plugin_info_supports_multiple (NMVpnPluginInfo *self);
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
const char *const*nm_vpn_plugin_info_get_aliases (NMVpnPluginInfo *self);
|
||||||
NM_AVAILABLE_IN_1_2
|
NM_AVAILABLE_IN_1_2
|
||||||
const char *nm_vpn_plugin_info_lookup_property (NMVpnPluginInfo *self, const char *group, const char *key);
|
const char *nm_vpn_plugin_info_lookup_property (NMVpnPluginInfo *self, const char *group, const char *key);
|
||||||
|
|
||||||
@@ -112,6 +116,12 @@ NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_filename (GSList *list, const c
|
|||||||
NM_AVAILABLE_IN_1_2
|
NM_AVAILABLE_IN_1_2
|
||||||
NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service);
|
NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service);
|
||||||
|
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
char *nm_vpn_plugin_info_list_find_service_type (GSList *list, const char *name);
|
||||||
|
NM_AVAILABLE_IN_1_4
|
||||||
|
char **nm_vpn_plugin_info_list_get_service_types (GSList *list,
|
||||||
|
gboolean only_existing,
|
||||||
|
gboolean with_abbreviations);
|
||||||
|
|
||||||
NM_AVAILABLE_IN_1_2
|
NM_AVAILABLE_IN_1_2
|
||||||
NMVpnEditorPlugin *nm_vpn_plugin_info_get_editor_plugin (NMVpnPluginInfo *self);
|
NMVpnEditorPlugin *nm_vpn_plugin_info_get_editor_plugin (NMVpnPluginInfo *self);
|
||||||
|
@@ -1068,9 +1068,15 @@ global:
|
|||||||
nm_device_team_get_config;
|
nm_device_team_get_config;
|
||||||
nm_setting_ip6_config_get_token;
|
nm_setting_ip6_config_get_token;
|
||||||
nm_setting_ip_config_get_dns_priority;
|
nm_setting_ip_config_get_dns_priority;
|
||||||
|
nm_vpn_editor_plugin_get_plugin_info;
|
||||||
|
nm_vpn_editor_plugin_get_vt;
|
||||||
nm_vpn_editor_plugin_load;
|
nm_vpn_editor_plugin_load;
|
||||||
|
nm_vpn_editor_plugin_set_plugin_info;
|
||||||
|
nm_vpn_plugin_info_get_aliases;
|
||||||
nm_vpn_plugin_info_get_auth_dialog;
|
nm_vpn_plugin_info_get_auth_dialog;
|
||||||
nm_vpn_plugin_info_get_service;
|
nm_vpn_plugin_info_get_service;
|
||||||
|
nm_vpn_plugin_info_list_get_service_types;
|
||||||
|
nm_vpn_plugin_info_list_find_service_type;
|
||||||
nm_vpn_plugin_info_new_search_file;
|
nm_vpn_plugin_info_new_search_file;
|
||||||
nm_vpn_plugin_info_supports_hints;
|
nm_vpn_plugin_info_supports_hints;
|
||||||
} libnm_1_2_0;
|
} libnm_1_2_0;
|
||||||
|
@@ -1306,3 +1306,11 @@ nm_vpn_service_plugin_initable_iface_init (GInitableIface *iface)
|
|||||||
{
|
{
|
||||||
iface->init = init_sync;
|
iface->init = init_sync;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* this header is intended to be copied to users of nm_vpn_editor_plugin_call(),
|
||||||
|
* to simplify invocation of generic functions. Include it here, to complile
|
||||||
|
* the code. */
|
||||||
|
#include "nm-vpn-editor-plugin-call.h"
|
||||||
|
|
||||||
|
@@ -6,5 +6,6 @@ vpn-daemons/openvpn
|
|||||||
vpn-daemons/pptp
|
vpn-daemons/pptp
|
||||||
vpn-daemons/vpnc
|
vpn-daemons/vpnc
|
||||||
contrib/fedora/rpm/
|
contrib/fedora/rpm/
|
||||||
|
shared/nm-vpn-editor-plugin-call.h
|
||||||
# https://bugs.launchpad.net/intltool/+bug/1117944
|
# https://bugs.launchpad.net/intltool/+bug/1117944
|
||||||
sub/policy/org.freedesktop.NetworkManager.policy.in
|
sub/policy/org.freedesktop.NetworkManager.policy.in
|
||||||
|
@@ -10,6 +10,7 @@ EXTRA_DIST = \
|
|||||||
nm-test-libnm-utils.h \
|
nm-test-libnm-utils.h \
|
||||||
nm-test-utils.h \
|
nm-test-utils.h \
|
||||||
nm-test-utils-impl.c \
|
nm-test-utils-impl.c \
|
||||||
nm-version-macros.h.in
|
nm-version-macros.h.in \
|
||||||
|
nm-vpn-editor-plugin-call.h
|
||||||
|
|
||||||
CLEANFILES=nm-version.h
|
CLEANFILES=nm-version.h
|
||||||
|
@@ -484,6 +484,36 @@ nm_strstrip (char *str)
|
|||||||
return str ? g_strstrip (str) : NULL;
|
return str ? g_strstrip (str) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* g_ptr_array_sort()'s compare function takes pointers to the
|
||||||
|
* value. Thus, you cannot use strcmp directly. You can use
|
||||||
|
* nm_strcmp_p().
|
||||||
|
*
|
||||||
|
* Like strcmp(), this function is not forgiving to accept %NULL. */
|
||||||
|
static inline int
|
||||||
|
nm_strcmp_p (gconstpointer a, gconstpointer b)
|
||||||
|
{
|
||||||
|
const char *s1 = *((const char **) a);
|
||||||
|
const char *s2 = *((const char **) b);
|
||||||
|
|
||||||
|
return strcmp (s1, s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* like nm_strcmp_p(), suitable for g_ptr_array_sort_with_data().
|
||||||
|
* g_ptr_array_sort() just casts nm_strcmp_p() to a function of different
|
||||||
|
* signature. I guess, in glib there are knowledgeable people that ensure
|
||||||
|
* that this additional argument doesn't cause problems due to different ABI
|
||||||
|
* for every architecture that glib supports.
|
||||||
|
* For NetworkManager, we'd rather avoid such stunts.
|
||||||
|
**/
|
||||||
|
static inline int
|
||||||
|
nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data)
|
||||||
|
{
|
||||||
|
const char *s1 = *((const char **) a);
|
||||||
|
const char *s2 = *((const char **) b);
|
||||||
|
|
||||||
|
return strcmp (s1, s2);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static inline guint
|
static inline guint
|
||||||
|
189
shared/nm-vpn-editor-plugin-call.h
Normal file
189
shared/nm-vpn-editor-plugin-call.h
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||||
|
/* NetworkManager -- Network link manager
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Red Hat, Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __NM_VPN_EDITOR_PLUGIN_CALL_H__
|
||||||
|
#define __NM_VPN_EDITOR_PLUGIN_CALL_H__
|
||||||
|
|
||||||
|
/* This header is an internal, header-only file that can be copied to
|
||||||
|
* other projects to call well-known service functions on VPN plugins.
|
||||||
|
*
|
||||||
|
* This uses the NMVpnEditorPluginVT and allows a user (nm-applet)
|
||||||
|
* to directly communicate with a VPN plugin using API that is newer
|
||||||
|
* then the current libnm version. That is, it allows to call to a VPN
|
||||||
|
* plugin bypassing libnm. */
|
||||||
|
|
||||||
|
#include <NetworkManager.h>
|
||||||
|
|
||||||
|
/* we make use of other internal header files, you need those too. */
|
||||||
|
#include "gsystem-local-alloc.h"
|
||||||
|
#include "nm-macros-internal.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NMVpnEditorPluginServiceFlags:
|
||||||
|
* @NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_NONE: no flags
|
||||||
|
* @NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_CAN_ADD: whether the plugin can
|
||||||
|
* add a new connection for the given service-type.
|
||||||
|
**/
|
||||||
|
typedef enum { /*< skip >*/
|
||||||
|
NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_NONE = 0x00,
|
||||||
|
NM_VPN_EDITOR_PLUGIN_SERVICE_FLAGS_CAN_ADD = 0x01,
|
||||||
|
} NMVpnEditorPluginServiceFlags;
|
||||||
|
|
||||||
|
struct _NMVpnEditorPluginVT {
|
||||||
|
gboolean (*fcn_get_service_info) (NMVpnEditorPlugin *plugin,
|
||||||
|
const char *service_type,
|
||||||
|
char **out_short_name,
|
||||||
|
char **out_pretty_name,
|
||||||
|
char **out_description,
|
||||||
|
NMVpnEditorPluginServiceFlags *out_flags);
|
||||||
|
char **(*fcn_get_service_add_details) (NMVpnEditorPlugin *plugin,
|
||||||
|
const char *service_name);
|
||||||
|
gboolean (*fcn_get_service_add_detail) (NMVpnEditorPlugin *plugin,
|
||||||
|
const char *service_type,
|
||||||
|
const char *add_detail,
|
||||||
|
char **out_pretty_name,
|
||||||
|
char **out_description,
|
||||||
|
char **out_add_detail_key,
|
||||||
|
char **out_add_detail_val,
|
||||||
|
guint *out_flags);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Call
|
||||||
|
*
|
||||||
|
* The following wrap the calling of generic functions for a VPN plugin.
|
||||||
|
* They are used by callers (for example nm-connection-editor).
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
nm_vpn_editor_plugin_get_service_info (NMVpnEditorPlugin *plugin,
|
||||||
|
const char *service_type,
|
||||||
|
char **out_short_name,
|
||||||
|
char **out_pretty_name,
|
||||||
|
char **out_description,
|
||||||
|
NMVpnEditorPluginServiceFlags *out_flags)
|
||||||
|
{
|
||||||
|
NMVpnEditorPluginVT vt;
|
||||||
|
gs_free char *short_name_local = NULL;
|
||||||
|
gs_free char *pretty_name_local = NULL;
|
||||||
|
gs_free char *description_local = NULL;
|
||||||
|
guint flags_local = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), FALSE);
|
||||||
|
g_return_val_if_fail (service_type, FALSE);
|
||||||
|
|
||||||
|
nm_vpn_editor_plugin_get_vt (plugin, &vt, sizeof (vt));
|
||||||
|
if ( !vt.fcn_get_service_info
|
||||||
|
|| !vt.fcn_get_service_info (plugin,
|
||||||
|
service_type,
|
||||||
|
out_short_name ? &short_name_local : NULL,
|
||||||
|
out_pretty_name ? &pretty_name_local : NULL,
|
||||||
|
out_description ? &description_local : NULL,
|
||||||
|
out_flags ? &flags_local : NULL))
|
||||||
|
return FALSE;
|
||||||
|
NM_SET_OUT (out_short_name, g_steal_pointer (&short_name_local));
|
||||||
|
NM_SET_OUT (out_pretty_name, g_steal_pointer (&pretty_name_local));
|
||||||
|
NM_SET_OUT (out_description, g_steal_pointer (&description_local));
|
||||||
|
NM_SET_OUT (out_flags, flags_local);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char **
|
||||||
|
nm_vpn_editor_plugin_get_service_add_details (NMVpnEditorPlugin *plugin,
|
||||||
|
const char *service_name)
|
||||||
|
{
|
||||||
|
NMVpnEditorPluginVT vt;
|
||||||
|
char **details = NULL;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL);
|
||||||
|
g_return_val_if_fail (service_name, NULL);
|
||||||
|
|
||||||
|
nm_vpn_editor_plugin_get_vt (plugin, &vt, sizeof (vt));
|
||||||
|
if (vt.fcn_get_service_add_details)
|
||||||
|
details = vt.fcn_get_service_add_details (plugin, service_name);
|
||||||
|
if (!details)
|
||||||
|
return g_new0 (char *, 1);
|
||||||
|
return details;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
nm_vpn_editor_plugin_get_service_add_detail (NMVpnEditorPlugin *plugin,
|
||||||
|
const char *service_type,
|
||||||
|
const char *add_detail,
|
||||||
|
char **out_pretty_name,
|
||||||
|
char **out_description,
|
||||||
|
char **out_add_detail_key,
|
||||||
|
char **out_add_detail_val,
|
||||||
|
guint *out_flags)
|
||||||
|
{
|
||||||
|
NMVpnEditorPluginVT vt;
|
||||||
|
gs_free char *pretty_name_local = NULL;
|
||||||
|
gs_free char *description_local = NULL;
|
||||||
|
gs_free char *add_detail_key_local = NULL;
|
||||||
|
gs_free char *add_detail_val_local = NULL;
|
||||||
|
guint flags_local = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), FALSE);
|
||||||
|
g_return_val_if_fail (service_type, FALSE);
|
||||||
|
g_return_val_if_fail (add_detail, FALSE);
|
||||||
|
|
||||||
|
nm_vpn_editor_plugin_get_vt (plugin, &vt, sizeof (vt));
|
||||||
|
if ( !vt.fcn_get_service_add_detail
|
||||||
|
|| !vt.fcn_get_service_add_detail (plugin,
|
||||||
|
service_type,
|
||||||
|
add_detail,
|
||||||
|
out_pretty_name ? &pretty_name_local : NULL,
|
||||||
|
out_description ? &description_local : NULL,
|
||||||
|
out_add_detail_key ? &add_detail_key_local : NULL,
|
||||||
|
out_add_detail_val ? &add_detail_val_local : NULL,
|
||||||
|
out_flags ? &flags_local : NULL))
|
||||||
|
return FALSE;
|
||||||
|
NM_SET_OUT (out_pretty_name, g_steal_pointer (&pretty_name_local));
|
||||||
|
NM_SET_OUT (out_description, g_steal_pointer (&description_local));
|
||||||
|
NM_SET_OUT (out_add_detail_key, g_steal_pointer (&add_detail_key_local));
|
||||||
|
NM_SET_OUT (out_add_detail_val, g_steal_pointer (&add_detail_val_local));
|
||||||
|
NM_SET_OUT (out_flags, flags_local);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************
|
||||||
|
* Implementation
|
||||||
|
*
|
||||||
|
* The following glue code can be used to implement calls in a VPN plugin.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#define NM_VPN_EDITOR_PLUGIN_VT_DEFINE(vt_name, get_vt, ...) \
|
||||||
|
static const NMVpnEditorPluginVT vt_name = { \
|
||||||
|
__VA_ARGS__ \
|
||||||
|
}; \
|
||||||
|
static const NMVpnEditorPluginVT * \
|
||||||
|
get_vt (NMVpnEditorPlugin *plugin, \
|
||||||
|
gsize *out_vt_size) \
|
||||||
|
{ \
|
||||||
|
nm_assert (NM_IS_VPN_EDITOR_PLUGIN (plugin)); \
|
||||||
|
nm_assert (out_vt_size); \
|
||||||
|
\
|
||||||
|
*out_vt_size = sizeof (vt_name); \
|
||||||
|
return &vt_name; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __NM_VPN_EDITOR_PLUGIN_CALL_H__ */
|
@@ -880,15 +880,6 @@ read_base_config (GKeyFile *keyfile,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
sort_asciibetically (gconstpointer a, gconstpointer b)
|
|
||||||
{
|
|
||||||
const char *s1 = *(const char **)a;
|
|
||||||
const char *s2 = *(const char **)b;
|
|
||||||
|
|
||||||
return strcmp (s1, s2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static GPtrArray *
|
static GPtrArray *
|
||||||
_get_config_dir_files (const char *config_dir)
|
_get_config_dir_files (const char *config_dir)
|
||||||
{
|
{
|
||||||
@@ -917,7 +908,7 @@ _get_config_dir_files (const char *config_dir)
|
|||||||
}
|
}
|
||||||
g_object_unref (dir);
|
g_object_unref (dir);
|
||||||
|
|
||||||
g_ptr_array_sort (confs, sort_asciibetically);
|
g_ptr_array_sort (confs, nm_strcmp_p);
|
||||||
return confs;
|
return confs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user