mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-08 15:00:35 +01:00
libnm: merge branch 'th/libnm-vpn-plugin-bgo749877'
- add new NMVpnPluginInfo class with new API to load VPN name files. - move NMVpnEditorPlugin to libnm-core, including code to load the client plugin from the shared library. - deprecate NMVpnPluginOld and add NMVpnServicePlugin. The latter is identical to NMVpnPluginOld but renamed and introduced as new API for 1.2. https://bugzilla.gnome.org/show_bug.cgi?id=749877
This commit is contained in:
commit
3e39e5b4f0
28 changed files with 3613 additions and 582 deletions
|
|
@ -34,142 +34,41 @@
|
|||
#include <gmodule.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include <nm-connection.h>
|
||||
#include <nm-setting-connection.h>
|
||||
#include <nm-setting-vpn.h>
|
||||
|
||||
#include "nm-glib.h"
|
||||
#include "vpn-helpers.h"
|
||||
|
||||
#define NM_VPN_API_SUBJECT_TO_CHANGE
|
||||
#include "nm-vpn-plugin-ui-interface.h"
|
||||
#include "nm-macros-internal.h"
|
||||
|
||||
#define VPN_NAME_FILES_DIR SYSCONFDIR"/NetworkManager/VPN"
|
||||
static gboolean plugins_loaded;
|
||||
static GSList *plugins = NULL;
|
||||
|
||||
static GHashTable *plugins = NULL;
|
||||
|
||||
G_DEFINE_QUARK (NMA_ERROR, nma_error)
|
||||
#define NMA_ERROR nma_error_quark ()
|
||||
#define NMA_ERROR_GENERIC 0
|
||||
|
||||
NMVpnPluginUiInterface *
|
||||
NMVpnEditorPlugin *
|
||||
vpn_get_plugin_by_service (const char *service)
|
||||
{
|
||||
NMVpnEditorPlugin *plugin = NULL;
|
||||
NMVpnPluginInfo *plugin_info;
|
||||
|
||||
g_return_val_if_fail (service != NULL, NULL);
|
||||
|
||||
return g_hash_table_lookup (plugins, service);
|
||||
if (G_UNLIKELY (!plugins_loaded))
|
||||
vpn_get_plugins ();
|
||||
|
||||
plugin_info = nm_vpn_plugin_info_list_find_by_service (plugins, service);
|
||||
if (plugin_info) {
|
||||
plugin = nm_vpn_plugin_info_get_editor_plugin (plugin_info);
|
||||
if (!plugin)
|
||||
plugin = nm_vpn_plugin_info_load_editor_plugin (plugin_info, NULL);
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
GHashTable *
|
||||
vpn_get_plugins (GError **error)
|
||||
GSList *
|
||||
vpn_get_plugins ()
|
||||
{
|
||||
GDir *dir;
|
||||
const char *f;
|
||||
|
||||
if (error)
|
||||
g_return_val_if_fail (*error == NULL, NULL);
|
||||
|
||||
if (plugins)
|
||||
if (G_LIKELY (plugins_loaded))
|
||||
return plugins;
|
||||
|
||||
dir = g_dir_open (VPN_NAME_FILES_DIR, 0, NULL);
|
||||
if (!dir) {
|
||||
g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, "Couldn't read VPN .name files directory " VPN_NAME_FILES_DIR ".");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
plugins = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
(GDestroyNotify) g_free, (GDestroyNotify) g_object_unref);
|
||||
|
||||
while ((f = g_dir_read_name (dir))) {
|
||||
char *path = NULL, *service = NULL;
|
||||
char *so_path = NULL, *so_name = NULL;
|
||||
GKeyFile *keyfile = NULL;
|
||||
GModule *module;
|
||||
NMVpnPluginUiFactory factory = NULL;
|
||||
|
||||
if (!g_str_has_suffix (f, ".name"))
|
||||
continue;
|
||||
|
||||
path = g_strdup_printf ("%s/%s", VPN_NAME_FILES_DIR, f);
|
||||
|
||||
keyfile = g_key_file_new ();
|
||||
if (!g_key_file_load_from_file (keyfile, path, 0, NULL))
|
||||
goto next;
|
||||
|
||||
service = g_key_file_get_string (keyfile, "VPN Connection", "service", NULL);
|
||||
if (!service)
|
||||
goto next;
|
||||
|
||||
so_path = g_key_file_get_string (keyfile, "GNOME", "properties", NULL);
|
||||
if (!so_path)
|
||||
goto next;
|
||||
|
||||
/* Remove any path and extension components, then reconstruct path
|
||||
* to the SO in LIBDIR
|
||||
*/
|
||||
so_name = g_path_get_basename (so_path);
|
||||
g_free (so_path);
|
||||
so_path = g_strdup_printf ("%s/NetworkManager/%s", LIBDIR, so_name);
|
||||
g_free (so_name);
|
||||
|
||||
module = g_module_open (so_path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
if (!module) {
|
||||
g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, "Cannot load the VPN plugin which provides the "
|
||||
"service '%s'.", service);
|
||||
goto next;
|
||||
}
|
||||
|
||||
if (g_module_symbol (module, "nm_vpn_plugin_ui_factory", (gpointer) &factory)) {
|
||||
NMVpnPluginUiInterface *plugin;
|
||||
GError *factory_error = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
plugin = factory (&factory_error);
|
||||
if (plugin) {
|
||||
char *plug_name = NULL, *plug_service = NULL;
|
||||
|
||||
/* Validate plugin properties */
|
||||
g_object_get (G_OBJECT (plugin),
|
||||
NM_VPN_PLUGIN_UI_INTERFACE_NAME, &plug_name,
|
||||
NM_VPN_PLUGIN_UI_INTERFACE_SERVICE, &plug_service,
|
||||
NULL);
|
||||
if (!plug_name || !strlen (plug_name)) {
|
||||
g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, "cannot load VPN plugin in '%s': missing plugin name",
|
||||
g_module_name (module));
|
||||
} else if (!plug_service || strcmp (plug_service, service)) {
|
||||
g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, "cannot load VPN plugin in '%s': invalid service name",
|
||||
g_module_name (module));
|
||||
} else {
|
||||
/* Success! */
|
||||
g_object_set_data_full (G_OBJECT (plugin), "gmodule", module,
|
||||
(GDestroyNotify) g_module_close);
|
||||
g_hash_table_insert (plugins, g_strdup (service), plugin);
|
||||
success = TRUE;
|
||||
}
|
||||
g_free (plug_name);
|
||||
g_free (plug_service);
|
||||
} else {
|
||||
g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, "cannot load VPN plugin in '%s': %s",
|
||||
g_module_name (module), g_module_error ());
|
||||
}
|
||||
|
||||
if (!success)
|
||||
g_module_close (module);
|
||||
} else {
|
||||
g_set_error (error, NMA_ERROR, NMA_ERROR_GENERIC, "cannot locate nm_vpn_plugin_ui_factory() in '%s': %s",
|
||||
g_module_name (module), g_module_error ());
|
||||
g_module_close (module);
|
||||
}
|
||||
|
||||
next:
|
||||
g_free (so_path);
|
||||
g_free (service);
|
||||
g_key_file_free (keyfile);
|
||||
g_free (path);
|
||||
}
|
||||
g_dir_close (dir);
|
||||
|
||||
plugins_loaded = TRUE;
|
||||
plugins = nm_vpn_plugin_info_list_load ();
|
||||
return plugins;
|
||||
}
|
||||
|
||||
|
|
@ -409,7 +308,7 @@ vpn_supports_ipv6 (NMConnection *connection)
|
|||
{
|
||||
NMSettingVpn *s_vpn;
|
||||
const char *service_type;
|
||||
NMVpnPluginUiInterface *plugin;
|
||||
NMVpnEditorPlugin *plugin;
|
||||
guint32 capabilities;
|
||||
|
||||
s_vpn = nm_connection_get_setting_vpn (connection);
|
||||
|
|
@ -421,6 +320,6 @@ vpn_supports_ipv6 (NMConnection *connection)
|
|||
plugin = vpn_get_plugin_by_service (service_type);
|
||||
g_return_val_if_fail (plugin != NULL, FALSE);
|
||||
|
||||
capabilities = nm_vpn_plugin_ui_interface_get_capabilities (plugin);
|
||||
return (capabilities & NM_VPN_PLUGIN_UI_CAPABILITY_IPV6) != 0;
|
||||
capabilities = nm_vpn_editor_plugin_get_capabilities (plugin);
|
||||
return NM_FLAGS_HAS (capabilities, NM_VPN_EDITOR_PLUGIN_CAPABILITY_IPV6);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,16 +19,13 @@
|
|||
#ifndef _VPN_HELPERS_H_
|
||||
#define _VPN_HELPERS_H_
|
||||
|
||||
#include <nm-connection.h>
|
||||
|
||||
#define NM_VPN_API_SUBJECT_TO_CHANGE
|
||||
#include <nm-vpn-plugin-ui-interface.h>
|
||||
#include <NetworkManager.h>
|
||||
|
||||
#include "nm-glib.h"
|
||||
|
||||
GHashTable *vpn_get_plugins (GError **error);
|
||||
GSList *vpn_get_plugins (void);
|
||||
|
||||
NMVpnPluginUiInterface *vpn_get_plugin_by_service (const char *service);
|
||||
NMVpnEditorPlugin *vpn_get_plugin_by_service (const char *service);
|
||||
|
||||
typedef void (*VpnImportSuccessCallback) (NMConnection *connection, gpointer user_data);
|
||||
void vpn_import (VpnImportSuccessCallback callback, gpointer user_data);
|
||||
|
|
|
|||
|
|
@ -440,6 +440,7 @@ make install DESTDIR=$RPM_BUILD_ROOT
|
|||
|
||||
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/%{name}/conf.d
|
||||
mkdir -p $RPM_BUILD_ROOT%{nmlibdir}/conf.d
|
||||
mkdir -p $RPM_BUILD_ROOT%{nmlibdir}/VPN
|
||||
%{__cp} %{SOURCE2} $RPM_BUILD_ROOT%{nmlibdir}/conf.d/
|
||||
%{__cp} %{SOURCE3} $RPM_BUILD_ROOT%{nmlibdir}/conf.d/
|
||||
|
||||
|
|
@ -541,6 +542,7 @@ fi
|
|||
%dir %{_sysconfdir}/%{name}/conf.d
|
||||
%dir %{nmlibdir}
|
||||
%dir %{nmlibdir}/conf.d
|
||||
%dir %{nmlibdir}/VPN
|
||||
%{_mandir}/man1/*
|
||||
%{_mandir}/man5/*
|
||||
%{_mandir}/man8/*
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ IGNORE_HFILES= \
|
|||
nm-types.h \
|
||||
nm-utils-private.h \
|
||||
nm-vpn-plugin-old.h \
|
||||
nm-vpn-service-plugin.h \
|
||||
nm-core-tests-enum-types.h
|
||||
|
||||
# Images to copy into HTML directory.
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ AM_CPPFLAGS = \
|
|||
-I${top_srcdir}/include \
|
||||
-DG_LOG_DOMAIN=\""libnm"\" \
|
||||
-DLOCALEDIR=\"$(datadir)/locale\" \
|
||||
-DNMCONFDIR=\"$(nmconfdir)\" \
|
||||
-DNMLIBDIR=\"$(nmlibdir)\" \
|
||||
-DNETWORKMANAGER_COMPILATION \
|
||||
-DNM_VERSION_MAX_ALLOWED=NM_VERSION_NEXT_STABLE \
|
||||
$(GLIB_CFLAGS)
|
||||
|
|
|
|||
|
|
@ -42,7 +42,9 @@ libnm_core_headers = \
|
|||
$(core)/nm-setting.h \
|
||||
$(core)/nm-simple-connection.h \
|
||||
$(core)/nm-utils.h \
|
||||
$(core)/nm-vpn-dbus-interface.h
|
||||
$(core)/nm-vpn-dbus-interface.h \
|
||||
$(core)/nm-vpn-editor-plugin.h \
|
||||
$(core)/nm-vpn-plugin-info.h
|
||||
|
||||
libnm_core_private_headers = \
|
||||
$(core)/crypto.h \
|
||||
|
|
@ -93,5 +95,7 @@ libnm_core_sources = \
|
|||
$(core)/nm-setting-wireless.c \
|
||||
$(core)/nm-setting.c \
|
||||
$(core)/nm-simple-connection.c \
|
||||
$(core)/nm-utils.c
|
||||
$(core)/nm-utils.c \
|
||||
$(core)/nm-vpn-editor-plugin.c \
|
||||
$(core)/nm-vpn-plugin-info.c
|
||||
|
||||
|
|
|
|||
|
|
@ -136,6 +136,19 @@ char ** _nm_utils_slist_to_strv (GSList *slist, gboolean deep_copy);
|
|||
GPtrArray * _nm_utils_strv_to_ptrarray (char **strv);
|
||||
char ** _nm_utils_ptrarray_to_strv (GPtrArray *ptrarray);
|
||||
|
||||
gboolean _nm_utils_check_file (const char *filename,
|
||||
gint64 check_owner,
|
||||
NMUtilsCheckFilePredicate check_file,
|
||||
gpointer user_data,
|
||||
struct stat *out_st,
|
||||
GError **error);
|
||||
|
||||
char *_nm_utils_check_module_file (const char *name,
|
||||
int check_owner,
|
||||
NMUtilsCheckFilePredicate check_file,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
#define NM_UTILS_UUID_TYPE_LEGACY 0
|
||||
#define NM_UTILS_UUID_TYPE_VARIANT3 1
|
||||
|
||||
|
|
@ -187,6 +200,26 @@ gboolean _nm_dbus_error_has_name (GError *error,
|
|||
|
||||
/***********************************************************/
|
||||
|
||||
gboolean _nm_vpn_plugin_info_check_file (const char *filename,
|
||||
gboolean check_absolute,
|
||||
gboolean do_validate_filename,
|
||||
gint64 check_owner,
|
||||
NMUtilsCheckFilePredicate check_file,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
const char *_nm_vpn_plugin_info_get_default_dir_etc (void);
|
||||
const char *_nm_vpn_plugin_info_get_default_dir_lib (void);
|
||||
const char *_nm_vpn_plugin_info_get_default_dir_user (void);
|
||||
|
||||
GSList *_nm_vpn_plugin_info_list_load_dir (const char *dirname,
|
||||
gboolean do_validate_filename,
|
||||
gint64 check_owner,
|
||||
NMUtilsCheckFilePredicate check_file,
|
||||
gpointer user_data);
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
gboolean numeric;
|
||||
|
|
@ -202,4 +235,14 @@ int _nm_utils_dns_option_find_idx (GPtrArray *array, const char *option)
|
|||
|
||||
/***********************************************************/
|
||||
|
||||
typedef struct _NMUtilsStrStrDictKey NMUtilsStrStrDictKey;
|
||||
guint _nm_utils_strstrdictkey_hash (gconstpointer a);
|
||||
gboolean _nm_utils_strstrdictkey_equal (gconstpointer a, gconstpointer b);
|
||||
NMUtilsStrStrDictKey *_nm_utils_strstrdictkey_create (const char *v1, const char *v2);
|
||||
|
||||
#define _nm_utils_strstrdictkey_static(v1, v2) \
|
||||
( (NMUtilsStrStrDictKey *) ("\03" v1 "\0" v2 "") )
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <libintl.h>
|
||||
#include <gmodule.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "nm-glib.h"
|
||||
#include "nm-utils.h"
|
||||
|
|
@ -2409,6 +2410,160 @@ nm_utils_file_is_pkcs12 (const char *filename)
|
|||
|
||||
/**********************************************************************************************/
|
||||
|
||||
gboolean
|
||||
_nm_utils_check_file (const char *filename,
|
||||
gint64 check_owner,
|
||||
NMUtilsCheckFilePredicate check_file,
|
||||
gpointer user_data,
|
||||
struct stat *out_st,
|
||||
GError **error)
|
||||
{
|
||||
struct stat st_backup;
|
||||
|
||||
if (!out_st)
|
||||
out_st = &st_backup;
|
||||
|
||||
if (stat (filename, out_st) != 0) {
|
||||
int errsv = errno;
|
||||
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("failed stat file %s: %s"), filename, strerror (errsv));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ignore non-files. */
|
||||
if (!S_ISREG (out_st->st_mode)) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("not a file (%s)"), filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* with check_owner enabled, check that the file belongs to the
|
||||
* owner or root. */
|
||||
if ( check_owner >= 0
|
||||
&& (out_st->st_uid != 0 && (gint64) out_st->st_uid != check_owner)) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("invalid file owner %d for %s"), out_st->st_uid, filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* with check_owner enabled, check that the file cannot be modified
|
||||
* by other users (except root). */
|
||||
if ( check_owner >= 0
|
||||
&& NM_FLAGS_ANY (out_st->st_mode, S_IWGRP | S_IWOTH | S_ISUID)) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("file permissions for %s"), filename);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( check_file
|
||||
&& !check_file (filename, out_st, user_data, error)) {
|
||||
if (error && !*error) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("reject %s"), filename);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static char *
|
||||
_resolve_module_file_name (const char *file_name)
|
||||
{
|
||||
char *name = NULL;
|
||||
|
||||
/* g_module_open() is searching for the exact file to load,
|
||||
* but it doesn't give us a hook to check file permissions
|
||||
* and ownership. Reimplement the file name resolution.
|
||||
*
|
||||
* Copied from g_module_open(). */
|
||||
|
||||
/* check whether we have a readable file right away */
|
||||
if (g_file_test (file_name, G_FILE_TEST_IS_REGULAR))
|
||||
name = g_strdup (file_name);
|
||||
|
||||
/* try completing file name with standard library suffix */
|
||||
if ( !name
|
||||
&& !g_str_has_suffix (file_name, "." G_MODULE_SUFFIX)) {
|
||||
name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL);
|
||||
if (!g_file_test (name, G_FILE_TEST_IS_REGULAR)) {
|
||||
g_free (name);
|
||||
name = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* g_module_open() would also try appending ".la". We don't do that
|
||||
* because we require the user to specify a shared library (directly). */
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
char *
|
||||
_nm_utils_check_module_file (const char *name,
|
||||
int check_owner,
|
||||
NMUtilsCheckFilePredicate check_file,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
gs_free char *name_resolved = NULL;
|
||||
char *s;
|
||||
|
||||
if (!g_path_is_absolute (name)) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("path is not absolute (%s)"), name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
name_resolved = _resolve_module_file_name (name);
|
||||
|
||||
if (!name_resolved) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("could not resolve plugin path (%s)"), name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (g_str_has_suffix (name_resolved, ".la")) {
|
||||
/* g_module_open() treats files that end with .la special.
|
||||
* We don't want to parse the libtool archive. Just error out. */
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("libtool archives are not supported (%s)"), name_resolved);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!_nm_utils_check_file (name_resolved,
|
||||
check_owner,
|
||||
check_file,
|
||||
user_data,
|
||||
NULL,
|
||||
error)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = name_resolved;
|
||||
name_resolved = NULL;
|
||||
return s;
|
||||
}
|
||||
|
||||
/**********************************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_utils_file_search_in_paths:
|
||||
* @progname: the helper program name, like "iptables"
|
||||
|
|
@ -3488,6 +3643,105 @@ nm_utils_bond_mode_string_to_int (const char *mode)
|
|||
|
||||
/**********************************************************************************************/
|
||||
|
||||
#define STRSTRDICTKEY_V1_SET 0x01
|
||||
#define STRSTRDICTKEY_V2_SET 0x02
|
||||
#define STRSTRDICTKEY_ALL_SET 0x03
|
||||
|
||||
struct _NMUtilsStrStrDictKey {
|
||||
char type;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
guint
|
||||
_nm_utils_strstrdictkey_hash (gconstpointer a)
|
||||
{
|
||||
const NMUtilsStrStrDictKey *k = a;
|
||||
const signed char *p;
|
||||
guint32 h = 5381;
|
||||
|
||||
if (k) {
|
||||
if (((int) k->type) & ~STRSTRDICTKEY_ALL_SET)
|
||||
g_return_val_if_reached (0);
|
||||
|
||||
h = (h << 5) + h + k->type;
|
||||
if (k->type & STRSTRDICTKEY_ALL_SET) {
|
||||
p = (void *) k->data;
|
||||
for (; *p != '\0'; p++)
|
||||
h = (h << 5) + h + *p;
|
||||
if (k->type == STRSTRDICTKEY_ALL_SET) {
|
||||
/* the key contains two strings. Continue... */
|
||||
h = (h << 5) + h + '\0';
|
||||
for (p++; *p != '\0'; p++)
|
||||
h = (h << 5) + h + *p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_utils_strstrdictkey_equal (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const NMUtilsStrStrDictKey *k1 = a;
|
||||
const NMUtilsStrStrDictKey *k2 = b;
|
||||
|
||||
if (k1 == k2)
|
||||
return TRUE;
|
||||
if (!k1 || !k2)
|
||||
return FALSE;
|
||||
|
||||
if (k1->type != k2->type)
|
||||
return FALSE;
|
||||
|
||||
if (k1->type & STRSTRDICTKEY_ALL_SET) {
|
||||
if (strcmp (k1->data, k2->data) != 0)
|
||||
return FALSE;
|
||||
|
||||
if (k1->type == STRSTRDICTKEY_ALL_SET) {
|
||||
gsize l = strlen (k1->data) + 1;
|
||||
|
||||
return strcmp (&k1->data[l], &k2->data[l]) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NMUtilsStrStrDictKey *
|
||||
_nm_utils_strstrdictkey_create (const char *v1, const char *v2)
|
||||
{
|
||||
char type = 0;
|
||||
gsize l1 = 0, l2 = 0;
|
||||
NMUtilsStrStrDictKey *k;
|
||||
|
||||
if (!v1 && !v2)
|
||||
return g_malloc0 (1);
|
||||
|
||||
/* we need to distinguish between ("",NULL) and (NULL,"").
|
||||
* Thus, in @type we encode which strings we have present
|
||||
* as not-NULL. */
|
||||
if (v1) {
|
||||
type |= STRSTRDICTKEY_V1_SET;
|
||||
l1 = strlen (v1) + 1;
|
||||
}
|
||||
if (v2) {
|
||||
type |= STRSTRDICTKEY_V2_SET;
|
||||
l2 = strlen (v2) + 1;
|
||||
}
|
||||
|
||||
k = g_malloc (G_STRUCT_OFFSET (NMUtilsStrStrDictKey, data) + l1 + l2);
|
||||
k->type = type;
|
||||
if (v1)
|
||||
memcpy (&k->data[0], v1, l1);
|
||||
if (v2)
|
||||
memcpy (&k->data[l1], v2, l2);
|
||||
|
||||
return k;
|
||||
}
|
||||
|
||||
/**********************************************************************************************/
|
||||
|
||||
/* _nm_utils_ascii_str_to_int64:
|
||||
*
|
||||
* A wrapper for g_ascii_strtoll, that checks whether the whole string
|
||||
|
|
|
|||
|
|
@ -128,6 +128,10 @@ gboolean nm_utils_file_is_pkcs12 (const char *filename);
|
|||
|
||||
typedef gboolean (*NMUtilsFileSearchInPathsPredicate) (const char *filename, gpointer user_data);
|
||||
|
||||
struct stat;
|
||||
|
||||
typedef gboolean (*NMUtilsCheckFilePredicate) (const char *filename, const struct stat *stat, gpointer user_data, GError **error);
|
||||
|
||||
const char *nm_utils_file_search_in_paths (const char *progname,
|
||||
const char *try_first,
|
||||
const char *const *paths,
|
||||
|
|
|
|||
284
libnm-core/nm-vpn-editor-plugin.c
Normal file
284
libnm-core/nm-vpn-editor-plugin.c
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2008 Novell, Inc.
|
||||
* Copyright 2008 - 2010 Red Hat, Inc.
|
||||
* Copyright 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "nm-vpn-editor-plugin.h"
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <glib/gi18n-lib.h>
|
||||
|
||||
#include "nm-macros-internal.h"
|
||||
#include "gsystem-local-alloc.h"
|
||||
#include "nm-core-internal.h"
|
||||
|
||||
static void nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface);
|
||||
|
||||
G_DEFINE_INTERFACE (NMVpnEditorPlugin, nm_vpn_editor_plugin, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface)
|
||||
{
|
||||
/* Properties */
|
||||
|
||||
/**
|
||||
* NMVpnEditorPlugin:name:
|
||||
*
|
||||
* Short display name of the VPN plugin.
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_string (NM_VPN_EDITOR_PLUGIN_NAME, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMVpnEditorPlugin:description:
|
||||
*
|
||||
* Longer description of the VPN plugin.
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_string (NM_VPN_EDITOR_PLUGIN_DESCRIPTION, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMVpnEditorPlugin:service:
|
||||
*
|
||||
* D-Bus service name of the plugin's VPN service.
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_string (NM_VPN_EDITOR_PLUGIN_SERVICE, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
/**
|
||||
* nm_vpn_editor_plugin_load_from_file:
|
||||
* @plugin_filename: The path to the share library to load.
|
||||
* Apply some common heuristics to find the library, such as
|
||||
* appending "so" file ending.
|
||||
* If the path is not an absolute path or no matching module
|
||||
* can be found, lookup inside a directory defined at compile time.
|
||||
* Due to this, @check_file might be called for two different paths.
|
||||
* @check_name: if not-null, check that the loaded plugin has
|
||||
* the given name.
|
||||
* @check_service: if not-null, check that the loaded plugin advertises
|
||||
* the given service.
|
||||
* @check_owner: if non-negative, check whether the file is owned
|
||||
* by UID @check_owner or by root. In this case also check that
|
||||
* the file is not writable by anybody else.
|
||||
* @check_file: optional callback to validate the file prior to
|
||||
* loading the shared library.
|
||||
* @user_data: user data for @check_file
|
||||
* @error: on failure the error reason.
|
||||
*
|
||||
* Load the shared libary @plugin_filename and create a new
|
||||
* #NMVpnEditorPlugin instace via the #NMVpnEditorPluginFactory
|
||||
* function.
|
||||
*
|
||||
* Returns: (transfer-full): a new plugin instance or %NULL on error.
|
||||
*
|
||||
* Since: 1.2
|
||||
*/
|
||||
NMVpnEditorPlugin *
|
||||
nm_vpn_editor_plugin_load_from_file (const char *plugin_filename,
|
||||
const char *check_name,
|
||||
const char *check_service,
|
||||
int check_owner,
|
||||
NMUtilsCheckFilePredicate check_file,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
GModule *module = NULL;
|
||||
gs_free_error GError *local = NULL;
|
||||
NMVpnEditorPluginFactory factory = NULL;
|
||||
NMVpnEditorPlugin *editor_plugin = NULL;
|
||||
|
||||
g_return_val_if_fail (plugin_filename && *plugin_filename, NULL);
|
||||
|
||||
if (g_path_is_absolute (plugin_filename)) {
|
||||
gs_free char *module_filename = NULL;
|
||||
|
||||
module_filename = _nm_utils_check_module_file (plugin_filename,
|
||||
check_owner,
|
||||
check_file,
|
||||
user_data,
|
||||
&local);
|
||||
if (module_filename)
|
||||
module = g_module_open (module_filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
|
||||
}
|
||||
|
||||
if (!module) {
|
||||
if (local) {
|
||||
g_propagate_error (error, local);
|
||||
local = NULL;
|
||||
} else {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("cannot load plugin %s"), plugin_filename);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
g_clear_error (&local);
|
||||
|
||||
if (g_module_symbol (module, "nm_vpn_editor_plugin_factory", (gpointer) &factory)) {
|
||||
gs_free_error GError *factory_error = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
editor_plugin = factory (&factory_error);
|
||||
|
||||
g_assert (!editor_plugin || G_IS_OBJECT (editor_plugin));
|
||||
|
||||
if (editor_plugin) {
|
||||
gs_free char *plug_name = NULL, *plug_service = NULL;
|
||||
|
||||
/* Validate plugin properties */
|
||||
|
||||
g_object_get (G_OBJECT (editor_plugin),
|
||||
NM_VPN_EDITOR_PLUGIN_NAME, &plug_name,
|
||||
NM_VPN_EDITOR_PLUGIN_SERVICE, &plug_service,
|
||||
NULL);
|
||||
|
||||
if (check_name && g_strcmp0 (plug_name, check_name) != 0) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("cannot load VPN plugin in '%s': invalid plugin name"),
|
||||
g_module_name (module));
|
||||
} else if ( check_service
|
||||
&& g_strcmp0 (plug_service, check_service) != 0) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("cannot load VPN plugin in '%s': invalid service name"),
|
||||
g_module_name (module));
|
||||
} else {
|
||||
/* Success! */
|
||||
g_object_set_data_full (G_OBJECT (editor_plugin), "gmodule", module,
|
||||
(GDestroyNotify) g_module_close);
|
||||
success = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (factory_error) {
|
||||
g_propagate_error (error, factory_error);
|
||||
factory_error = NULL;
|
||||
} else {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("unknown error initializing plugin %s"), plugin_filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (!success) {
|
||||
g_module_close (module);
|
||||
editor_plugin = NULL;
|
||||
}
|
||||
} else {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
_("failed to load nm_vpn_editor_plugin_factory() from %s (%s)"),
|
||||
g_module_name (module), g_module_error ());
|
||||
g_module_close (module);
|
||||
editor_plugin = NULL;
|
||||
}
|
||||
|
||||
return editor_plugin;
|
||||
}
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
/**
|
||||
* nm_vpn_editor_plugin_get_editor:
|
||||
*
|
||||
* Returns: (transfer full):
|
||||
*/
|
||||
NMVpnEditor *
|
||||
nm_vpn_editor_plugin_get_editor (NMVpnEditorPlugin *plugin,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL);
|
||||
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_editor (plugin, connection, error);
|
||||
}
|
||||
|
||||
NMVpnEditorPluginCapability
|
||||
nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), 0);
|
||||
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_capabilities (plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_vpn_editor_plugin_import:
|
||||
*
|
||||
* Returns: (transfer full):
|
||||
*/
|
||||
NMConnection *
|
||||
nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin,
|
||||
const char *path,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL);
|
||||
|
||||
if (nm_vpn_editor_plugin_get_capabilities (plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT) {
|
||||
g_return_val_if_fail (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->import_from_file != NULL, NULL);
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->import_from_file (plugin, path, error);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_editor_plugin_export (NMVpnEditorPlugin *plugin,
|
||||
const char *path,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), FALSE);
|
||||
|
||||
if (nm_vpn_editor_plugin_get_capabilities (plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT) {
|
||||
g_return_val_if_fail (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->export_to_file != NULL, FALSE);
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->export_to_file (plugin, path, connection, error);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char *
|
||||
nm_vpn_editor_plugin_get_suggested_filename (NMVpnEditorPlugin *plugin,
|
||||
NMConnection *connection)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL);
|
||||
|
||||
if (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_suggested_filename)
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_suggested_filename (plugin, connection);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -15,8 +15,8 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2008 - 2014 Red Hat, Inc.
|
||||
* Copyright 2008 Novell, Inc.
|
||||
* Copyright 2008 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_VPN_EDITOR_PLUGIN_H__
|
||||
|
|
@ -28,7 +28,9 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <nm-types.h>
|
||||
|
||||
#include "nm-connection.h"
|
||||
#include "nm-utils.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
|
@ -137,53 +139,15 @@ gboolean nm_vpn_editor_plugin_export (NMVpnEditorPlugin *pl
|
|||
char *nm_vpn_editor_plugin_get_suggested_filename (NMVpnEditorPlugin *plugin,
|
||||
NMConnection *connection);
|
||||
|
||||
/**************************************************/
|
||||
/* Editor interface */
|
||||
/**************************************************/
|
||||
|
||||
#define NM_TYPE_VPN_EDITOR (nm_vpn_editor_get_type ())
|
||||
#define NM_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditor))
|
||||
#define NM_IS_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_EDITOR))
|
||||
#define NM_VPN_EDITOR_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditorInterface))
|
||||
|
||||
/**
|
||||
* NMVpnEditorInterface:
|
||||
* @g_iface: the parent interface
|
||||
* @get_widget: return the #GtkWidget for the VPN editor's UI
|
||||
* @placeholder: not currently used
|
||||
* @update_connection: called to save the user-entered options to the connection
|
||||
* object. Should return %FALSE and set @error if the current options are
|
||||
* invalid. @error should contain enough information for the plugin to
|
||||
* determine which UI widget is invalid at a later point in time. For
|
||||
* example, creating unique error codes for what error occurred and populating
|
||||
* the message field of @error with the name of the invalid property.
|
||||
* @changed: emitted when the value of a UI widget changes. May trigger a
|
||||
* validity check via @update_connection to write values to the connection.
|
||||
*
|
||||
* Interface for editing a specific #NMConnection
|
||||
*/
|
||||
typedef struct {
|
||||
GTypeInterface g_iface;
|
||||
|
||||
GObject * (*get_widget) (NMVpnEditor *editor);
|
||||
|
||||
void (*placeholder) (void);
|
||||
|
||||
gboolean (*update_connection) (NMVpnEditor *editor,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
|
||||
void (*changed) (NMVpnEditor *editor);
|
||||
} NMVpnEditorInterface;
|
||||
|
||||
GType nm_vpn_editor_get_type (void);
|
||||
|
||||
GObject * nm_vpn_editor_get_widget (NMVpnEditor *editor);
|
||||
|
||||
gboolean nm_vpn_editor_update_connection (NMVpnEditor *editor,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnEditorPlugin *nm_vpn_editor_plugin_load_from_file (const char *plugin_filename,
|
||||
const char *check_name,
|
||||
const char *check_service,
|
||||
int check_owner,
|
||||
NMUtilsCheckFilePredicate check_file,
|
||||
gpointer user_data,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_VPN_EDITOR_PLUGIN_H */
|
||||
#endif /* __NM_VPN_EDITOR_PLUGIN_H__ */
|
||||
1016
libnm-core/nm-vpn-plugin-info.c
Normal file
1016
libnm-core/nm-vpn-plugin-info.c
Normal file
File diff suppressed because it is too large
Load diff
114
libnm-core/nm-vpn-plugin-info.h
Normal file
114
libnm-core/nm-vpn-plugin-info.h
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_VPN_PLUGIN_INFO_H__
|
||||
#define __NM_VPN_PLUGIN_INFO_H__
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-utils.h"
|
||||
#include "nm-vpn-editor-plugin.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_VPN_PLUGIN_INFO (nm_vpn_plugin_info_get_type ())
|
||||
#define NM_VPN_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfo))
|
||||
#define NM_VPN_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfoClass))
|
||||
#define NM_IS_VPN_PLUGIN_INFO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_PLUGIN_INFO))
|
||||
#define NM_IS_VPN_PLUGIN_INFO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_PLUGIN_INFO))
|
||||
#define NM_VPN_PLUGIN_INFO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_PLUGIN_INFO, NMVpnPluginInfoClass))
|
||||
|
||||
#define NM_VPN_PLUGIN_INFO_NAME "name"
|
||||
#define NM_VPN_PLUGIN_INFO_FILENAME "filename"
|
||||
#define NM_VPN_PLUGIN_INFO_KEYFILE "keyfile"
|
||||
|
||||
#define NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION "VPN Connection"
|
||||
#define NM_VPN_PLUGIN_INFO_KF_GROUP_LIBNM "libnm"
|
||||
#define NM_VPN_PLUGIN_INFO_KF_GROUP_GNOME "GNOME"
|
||||
|
||||
typedef struct {
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GObject parent;
|
||||
} NMVpnPluginInfo NM_AVAILABLE_IN_1_2;
|
||||
|
||||
typedef struct {
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GObjectClass parent;
|
||||
|
||||
/*< private >*/
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gpointer padding[8];
|
||||
} NMVpnPluginInfoClass NM_AVAILABLE_IN_1_2;
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GType nm_vpn_plugin_info_get_type (void);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnPluginInfo *nm_vpn_plugin_info_new_from_file (const char *filename,
|
||||
GError **error);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnPluginInfo *nm_vpn_plugin_info_new_with_data (const char *filename,
|
||||
GKeyFile *keyfile,
|
||||
GError **error);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char *nm_vpn_plugin_info_get_name (NMVpnPluginInfo *self);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char *nm_vpn_plugin_info_get_filename (NMVpnPluginInfo *self);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char *nm_vpn_plugin_info_get_service (NMVpnPluginInfo *self);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char *nm_vpn_plugin_info_get_plugin (NMVpnPluginInfo *self);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char *nm_vpn_plugin_info_get_program (NMVpnPluginInfo *self);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const char *nm_vpn_plugin_info_lookup_property (NMVpnPluginInfo *self, const char *group, const char *key);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_vpn_plugin_info_validate_filename (const char *filename);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GSList *nm_vpn_plugin_info_list_load (void);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_vpn_plugin_info_list_add (GSList **list, NMVpnPluginInfo *plugin_info, GError **error);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_vpn_plugin_info_list_remove (GSList **list, NMVpnPluginInfo *plugin_info);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_name (GSList *list, const char *name);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_filename (GSList *list, const char *filename);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnPluginInfo *nm_vpn_plugin_info_list_find_by_service (GSList *list, const char *service);
|
||||
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnEditorPlugin *nm_vpn_plugin_info_get_editor_plugin (NMVpnPluginInfo *plugin_info);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_vpn_plugin_info_set_editor_plugin (NMVpnPluginInfo *self,
|
||||
NMVpnEditorPlugin *plugin);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnEditorPlugin *nm_vpn_plugin_info_load_editor_plugin (NMVpnPluginInfo *plugin_info,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_VPN_PLUGIN_INFO_H__ */
|
||||
|
|
@ -4281,6 +4281,54 @@ test_nm_utils_ascii_str_to_int64 (void)
|
|||
|
||||
/******************************************************************************/
|
||||
|
||||
static void
|
||||
test_nm_utils_strstrdictkey ()
|
||||
{
|
||||
#define _VALUES_STATIC(_v1, _v2) { .v1 = _v1, .v2 = _v2, .v_static = _nm_utils_strstrdictkey_static (_v1, _v2), }
|
||||
const struct {
|
||||
const char *v1;
|
||||
const char *v2;
|
||||
NMUtilsStrStrDictKey *v_static;
|
||||
} *val1, *val2, values[] = {
|
||||
{ NULL, NULL },
|
||||
{ "", NULL },
|
||||
{ NULL, "" },
|
||||
{ "a", NULL },
|
||||
{ NULL, "a" },
|
||||
_VALUES_STATIC ("", ""),
|
||||
_VALUES_STATIC ("a", ""),
|
||||
_VALUES_STATIC ("", "a"),
|
||||
_VALUES_STATIC ("a", "b"),
|
||||
};
|
||||
guint i, j;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (values); i++) {
|
||||
gs_free NMUtilsStrStrDictKey *key1 = NULL;
|
||||
|
||||
val1 = &values[i];
|
||||
|
||||
key1 = _nm_utils_strstrdictkey_create (val1->v1, val1->v2);
|
||||
if (val1->v_static) {
|
||||
g_assert (_nm_utils_strstrdictkey_equal (key1, val1->v_static));
|
||||
g_assert (_nm_utils_strstrdictkey_equal (val1->v_static, key1));
|
||||
g_assert_cmpint (_nm_utils_strstrdictkey_hash (key1), ==, _nm_utils_strstrdictkey_hash (val1->v_static));
|
||||
}
|
||||
|
||||
for (j = 0; j < G_N_ELEMENTS (values); j++) {
|
||||
gs_free NMUtilsStrStrDictKey *key2 = NULL;
|
||||
|
||||
val2 = &values[j];
|
||||
key2 = _nm_utils_strstrdictkey_create (val2->v1, val2->v2);
|
||||
if (i != j) {
|
||||
g_assert (!_nm_utils_strstrdictkey_equal (key1, key2));
|
||||
g_assert (!_nm_utils_strstrdictkey_equal (key2, key1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void
|
||||
test_nm_utils_dns_option_validate_do (char *option, gboolean ipv6, const NMUtilsDNSOptionDesc *descs,
|
||||
gboolean exp_result, char *exp_name, gboolean exp_value)
|
||||
|
|
@ -4764,6 +4812,7 @@ int main (int argc, char **argv)
|
|||
g_test_add_func ("/core/general/nm_utils_is_power_of_two", test_nm_utils_is_power_of_two);
|
||||
g_test_add_func ("/core/general/_glib_compat_g_ptr_array_insert", test_g_ptr_array_insert);
|
||||
g_test_add_func ("/core/general/_nm_utils_ptrarray_find_binary_search", test_nm_utils_ptrarray_find_binary_search);
|
||||
g_test_add_func ("/core/general/_nm_utils_strstrdictkey", test_nm_utils_strstrdictkey);
|
||||
|
||||
g_test_add_func ("/core/general/_nm_utils_dns_option_validate", test_nm_utils_dns_option_validate);
|
||||
g_test_add_func ("/core/general/_nm_utils_dns_option_find_idx", test_nm_utils_dns_option_find_idx);
|
||||
|
|
|
|||
|
|
@ -50,12 +50,13 @@ libnminclude_hfiles = \
|
|||
nm-remote-connection.h \
|
||||
nm-types.h \
|
||||
nm-vpn-connection.h \
|
||||
nm-vpn-editor-plugin.h \
|
||||
nm-vpn-editor.h \
|
||||
nm-wimax-nsp.h
|
||||
|
||||
libnminclude_nointrospect_hfiles = \
|
||||
nm-secret-agent-old.h \
|
||||
nm-vpn-plugin-old.h
|
||||
nm-vpn-plugin-old.h \
|
||||
nm-vpn-service-plugin.h
|
||||
|
||||
libnminclude_HEADERS = \
|
||||
$(libnminclude_hfiles) \
|
||||
|
|
@ -108,7 +109,8 @@ libnm_la_csources = \
|
|||
nm-secret-agent-old.c \
|
||||
nm-vpn-connection.c \
|
||||
nm-vpn-plugin-old.c \
|
||||
nm-vpn-editor-plugin.c \
|
||||
nm-vpn-editor.c \
|
||||
nm-vpn-service-plugin.c \
|
||||
nm-wimax-nsp.c
|
||||
|
||||
libnm_la_SOURCES = \
|
||||
|
|
|
|||
|
|
@ -81,7 +81,9 @@
|
|||
#include <nm-version.h>
|
||||
#include <nm-vpn-connection.h>
|
||||
#include <nm-vpn-dbus-interface.h>
|
||||
#include <nm-vpn-editor.h>
|
||||
#include <nm-vpn-editor-plugin.h>
|
||||
#include <nm-vpn-plugin-info.h>
|
||||
#include <nm-wimax-nsp.h>
|
||||
|
||||
#undef __NETWORKMANAGER_H_INSIDE__
|
||||
|
|
|
|||
|
|
@ -821,17 +821,6 @@ global:
|
|||
nm_vpn_plugin_error_get_type;
|
||||
nm_vpn_plugin_error_quark;
|
||||
nm_vpn_plugin_failure_get_type;
|
||||
nm_vpn_plugin_old_disconnect;
|
||||
nm_vpn_plugin_old_failure;
|
||||
nm_vpn_plugin_old_get_connection;
|
||||
nm_vpn_plugin_old_get_secret_flags;
|
||||
nm_vpn_plugin_old_get_state;
|
||||
nm_vpn_plugin_old_get_type;
|
||||
nm_vpn_plugin_old_read_vpn_details;
|
||||
nm_vpn_plugin_old_secrets_required;
|
||||
nm_vpn_plugin_old_set_ip4_config;
|
||||
nm_vpn_plugin_old_set_login_banner;
|
||||
nm_vpn_plugin_old_set_state;
|
||||
nm_vpn_service_state_get_type;
|
||||
nm_wep_key_type_get_type;
|
||||
nm_wimax_nsp_connection_valid;
|
||||
|
|
@ -882,4 +871,35 @@ global:
|
|||
nm_utils_bond_mode_string_to_int;
|
||||
nm_utils_enum_from_str;
|
||||
nm_utils_enum_to_str;
|
||||
nm_vpn_editor_plugin_load_from_file;
|
||||
nm_vpn_plugin_info_get_filename;
|
||||
nm_vpn_plugin_info_get_editor_plugin;
|
||||
nm_vpn_plugin_info_get_name;
|
||||
nm_vpn_plugin_info_get_plugin;
|
||||
nm_vpn_plugin_info_get_program;
|
||||
nm_vpn_plugin_info_get_service;
|
||||
nm_vpn_plugin_info_get_type;
|
||||
nm_vpn_plugin_info_load_editor_plugin;
|
||||
nm_vpn_plugin_info_lookup_property;
|
||||
nm_vpn_plugin_info_new_from_file;
|
||||
nm_vpn_plugin_info_new_with_data;
|
||||
nm_vpn_plugin_info_set_editor_plugin;
|
||||
nm_vpn_plugin_info_validate_filename;
|
||||
nm_vpn_plugin_info_list_add;
|
||||
nm_vpn_plugin_info_list_find_by_filename;
|
||||
nm_vpn_plugin_info_list_find_by_name;
|
||||
nm_vpn_plugin_info_list_find_by_service;
|
||||
nm_vpn_plugin_info_list_load;
|
||||
nm_vpn_plugin_info_list_remove;
|
||||
nm_vpn_service_plugin_disconnect;
|
||||
nm_vpn_service_plugin_failure;
|
||||
nm_vpn_service_plugin_get_connection;
|
||||
nm_vpn_service_plugin_get_secret_flags;
|
||||
nm_vpn_service_plugin_get_state;
|
||||
nm_vpn_service_plugin_get_type;
|
||||
nm_vpn_service_plugin_read_vpn_details;
|
||||
nm_vpn_service_plugin_secrets_required;
|
||||
nm_vpn_service_plugin_set_ip4_config;
|
||||
nm_vpn_service_plugin_set_login_banner;
|
||||
nm_vpn_service_plugin_set_state;
|
||||
} libnm_1_0_0;
|
||||
|
|
|
|||
|
|
@ -1,181 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2008 - 2010 Red Hat, Inc.
|
||||
* Copyright 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "nm-vpn-editor-plugin.h"
|
||||
|
||||
static void nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface);
|
||||
|
||||
G_DEFINE_INTERFACE (NMVpnEditorPlugin, nm_vpn_editor_plugin, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
nm_vpn_editor_plugin_default_init (NMVpnEditorPluginInterface *iface)
|
||||
{
|
||||
/* Properties */
|
||||
|
||||
/**
|
||||
* NMVpnEditorPlugin:name:
|
||||
*
|
||||
* Short display name of the VPN plugin.
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_string (NM_VPN_EDITOR_PLUGIN_NAME, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMVpnEditorPlugin:description:
|
||||
*
|
||||
* Longer description of the VPN plugin.
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_string (NM_VPN_EDITOR_PLUGIN_DESCRIPTION, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMVpnEditorPlugin:service:
|
||||
*
|
||||
* D-Bus service name of the plugin's VPN service.
|
||||
*/
|
||||
g_object_interface_install_property (iface,
|
||||
g_param_spec_string (NM_VPN_EDITOR_PLUGIN_SERVICE, "", "",
|
||||
NULL,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_vpn_editor_plugin_get_editor:
|
||||
*
|
||||
* Returns: (transfer full):
|
||||
*/
|
||||
NMVpnEditor *
|
||||
nm_vpn_editor_plugin_get_editor (NMVpnEditorPlugin *plugin,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL);
|
||||
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_editor (plugin, connection, error);
|
||||
}
|
||||
|
||||
NMVpnEditorPluginCapability
|
||||
nm_vpn_editor_plugin_get_capabilities (NMVpnEditorPlugin *plugin)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), 0);
|
||||
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_capabilities (plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_vpn_editor_plugin_import:
|
||||
*
|
||||
* Returns: (transfer full):
|
||||
*/
|
||||
NMConnection *
|
||||
nm_vpn_editor_plugin_import (NMVpnEditorPlugin *plugin,
|
||||
const char *path,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL);
|
||||
|
||||
if (nm_vpn_editor_plugin_get_capabilities (plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_IMPORT) {
|
||||
g_return_val_if_fail (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->import_from_file != NULL, NULL);
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->import_from_file (plugin, path, error);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_editor_plugin_export (NMVpnEditorPlugin *plugin,
|
||||
const char *path,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), FALSE);
|
||||
|
||||
if (nm_vpn_editor_plugin_get_capabilities (plugin) & NM_VPN_EDITOR_PLUGIN_CAPABILITY_EXPORT) {
|
||||
g_return_val_if_fail (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->export_to_file != NULL, FALSE);
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->export_to_file (plugin, path, connection, error);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
char *
|
||||
nm_vpn_editor_plugin_get_suggested_filename (NMVpnEditorPlugin *plugin,
|
||||
NMConnection *connection)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR_PLUGIN (plugin), NULL);
|
||||
|
||||
if (NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_suggested_filename)
|
||||
return NM_VPN_EDITOR_PLUGIN_GET_INTERFACE (plugin)->get_suggested_filename (plugin, connection);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void nm_vpn_editor_default_init (NMVpnEditorInterface *iface);
|
||||
|
||||
G_DEFINE_INTERFACE (NMVpnEditor, nm_vpn_editor, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
nm_vpn_editor_default_init (NMVpnEditorInterface *iface)
|
||||
{
|
||||
GType iface_type = G_TYPE_FROM_INTERFACE (iface);
|
||||
|
||||
/* Signals */
|
||||
g_signal_new ("changed",
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMVpnEditorInterface, changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_vpn_editor_get_widget:
|
||||
*
|
||||
* Returns: (transfer none):
|
||||
*/
|
||||
GObject *
|
||||
nm_vpn_editor_get_widget (NMVpnEditor *editor)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), NULL);
|
||||
|
||||
return NM_VPN_EDITOR_GET_INTERFACE (editor)->get_widget (editor);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_editor_update_connection (NMVpnEditor *editor,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), FALSE);
|
||||
|
||||
if (error)
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
return NM_VPN_EDITOR_GET_INTERFACE (editor)->update_connection (editor, connection, error);
|
||||
}
|
||||
69
libnm/nm-vpn-editor.c
Normal file
69
libnm/nm-vpn-editor.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2008 - 2010 Red Hat, Inc.
|
||||
* Copyright 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "nm-vpn-editor.h"
|
||||
|
||||
static void nm_vpn_editor_default_init (NMVpnEditorInterface *iface);
|
||||
|
||||
G_DEFINE_INTERFACE (NMVpnEditor, nm_vpn_editor, G_TYPE_OBJECT)
|
||||
|
||||
static void
|
||||
nm_vpn_editor_default_init (NMVpnEditorInterface *iface)
|
||||
{
|
||||
GType iface_type = G_TYPE_FROM_INTERFACE (iface);
|
||||
|
||||
/* Signals */
|
||||
g_signal_new ("changed",
|
||||
iface_type,
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMVpnEditorInterface, changed),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_vpn_editor_get_widget:
|
||||
*
|
||||
* Returns: (transfer none):
|
||||
*/
|
||||
GObject *
|
||||
nm_vpn_editor_get_widget (NMVpnEditor *editor)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), NULL);
|
||||
|
||||
return NM_VPN_EDITOR_GET_INTERFACE (editor)->get_widget (editor);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_editor_update_connection (NMVpnEditor *editor,
|
||||
NMConnection *connection,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_EDITOR (editor), FALSE);
|
||||
|
||||
if (error)
|
||||
g_return_val_if_fail (*error == NULL, FALSE);
|
||||
|
||||
return NM_VPN_EDITOR_GET_INTERFACE (editor)->update_connection (editor, connection, error);
|
||||
}
|
||||
86
libnm/nm-vpn-editor.h
Normal file
86
libnm/nm-vpn-editor.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2008 Novell, Inc.
|
||||
* Copyright 2008 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_VPN_EDITOR_H__
|
||||
#define __NM_VPN_EDITOR_H__
|
||||
|
||||
#if !defined (__NETWORKMANAGER_H_INSIDE__) && !defined (NETWORKMANAGER_COMPILATION)
|
||||
#error "Only <NetworkManager.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <nm-types.h>
|
||||
|
||||
#include "nm-vpn-editor-plugin.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/**************************************************/
|
||||
/* Editor interface */
|
||||
/**************************************************/
|
||||
|
||||
#define NM_TYPE_VPN_EDITOR (nm_vpn_editor_get_type ())
|
||||
#define NM_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditor))
|
||||
#define NM_IS_VPN_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_EDITOR))
|
||||
#define NM_VPN_EDITOR_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), NM_TYPE_VPN_EDITOR, NMVpnEditorInterface))
|
||||
|
||||
/**
|
||||
* NMVpnEditorInterface:
|
||||
* @g_iface: the parent interface
|
||||
* @get_widget: return the #GtkWidget for the VPN editor's UI
|
||||
* @placeholder: not currently used
|
||||
* @update_connection: called to save the user-entered options to the connection
|
||||
* object. Should return %FALSE and set @error if the current options are
|
||||
* invalid. @error should contain enough information for the plugin to
|
||||
* determine which UI widget is invalid at a later point in time. For
|
||||
* example, creating unique error codes for what error occurred and populating
|
||||
* the message field of @error with the name of the invalid property.
|
||||
* @changed: emitted when the value of a UI widget changes. May trigger a
|
||||
* validity check via @update_connection to write values to the connection.
|
||||
*
|
||||
* Interface for editing a specific #NMConnection
|
||||
*/
|
||||
typedef struct {
|
||||
GTypeInterface g_iface;
|
||||
|
||||
GObject * (*get_widget) (NMVpnEditor *editor);
|
||||
|
||||
void (*placeholder) (void);
|
||||
|
||||
gboolean (*update_connection) (NMVpnEditor *editor,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
|
||||
void (*changed) (NMVpnEditor *editor);
|
||||
} NMVpnEditorInterface;
|
||||
|
||||
GType nm_vpn_editor_get_type (void);
|
||||
|
||||
GObject * nm_vpn_editor_get_widget (NMVpnEditor *editor);
|
||||
|
||||
gboolean nm_vpn_editor_update_connection (NMVpnEditor *editor,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_VPN_EDITOR_H__ */
|
||||
|
|
@ -19,10 +19,6 @@
|
|||
* Copyright 2007 - 2008 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
/* This interface is expected to be deprecated in NM 1.2, at which point there
|
||||
* will be a new "NMVpnPlugin" class to replace it.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
|
|
@ -70,7 +66,7 @@ typedef struct {
|
|||
gboolean has_ip6, got_ip6;
|
||||
|
||||
/* Config stuff copied from config to ip4config */
|
||||
char *banner, *tundev, *gateway, *mtu;
|
||||
GVariant *banner, *tundev, *gateway, *mtu;
|
||||
} NMVpnPluginOldPrivate;
|
||||
|
||||
#define NM_VPN_PLUGIN_OLD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN_OLD, NMVpnPluginOldPrivate))
|
||||
|
|
@ -117,6 +113,8 @@ nm_vpn_plugin_old_set_connection (NMVpnPluginOld *plugin,
|
|||
* nm_vpn_plugin_old_get_connection:
|
||||
*
|
||||
* Returns: (transfer full):
|
||||
*
|
||||
* Deprecated: 1.2: replaced by NMVpnServicePlugin
|
||||
*/
|
||||
GDBusConnection *
|
||||
nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin)
|
||||
|
|
@ -300,14 +298,22 @@ nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin,
|
|||
/* Record the items that need to also be inserted into the
|
||||
* ip4config, for compatibility with older daemons.
|
||||
*/
|
||||
g_clear_pointer (&priv->banner, g_free);
|
||||
(void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_BANNER, "&s", &priv->banner);
|
||||
g_clear_pointer (&priv->tundev, g_free);
|
||||
(void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_TUNDEV, "&s", &priv->tundev);
|
||||
g_clear_pointer (&priv->gateway, g_free);
|
||||
(void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY, "&s", &priv->gateway);
|
||||
g_clear_pointer (&priv->mtu, g_free);
|
||||
(void) g_variant_lookup (config, NM_VPN_PLUGIN_CONFIG_MTU, "&s", &priv->mtu);
|
||||
if (priv->banner)
|
||||
g_variant_unref (priv->banner);
|
||||
priv->banner = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_BANNER,
|
||||
G_VARIANT_TYPE ("s"));
|
||||
if (priv->tundev)
|
||||
g_variant_unref (priv->tundev);
|
||||
priv->tundev = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_TUNDEV,
|
||||
G_VARIANT_TYPE ("s"));
|
||||
if (priv->gateway)
|
||||
g_variant_unref (priv->gateway);
|
||||
priv->gateway = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_EXT_GATEWAY,
|
||||
G_VARIANT_TYPE ("u"));
|
||||
if (priv->mtu)
|
||||
g_variant_unref (priv->mtu);
|
||||
priv->mtu = g_variant_lookup_value (config, NM_VPN_PLUGIN_CONFIG_MTU,
|
||||
G_VARIANT_TYPE ("u"));
|
||||
|
||||
g_signal_emit (plugin, signals[CONFIG], 0, config);
|
||||
}
|
||||
|
|
@ -320,7 +326,8 @@ nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin,
|
|||
GVariant *combined_config;
|
||||
GVariantBuilder builder;
|
||||
GVariantIter iter;
|
||||
const char *key, *value;
|
||||
const char *key;
|
||||
GVariant *value;
|
||||
|
||||
g_return_if_fail (NM_IS_VPN_PLUGIN_OLD (plugin));
|
||||
g_return_if_fail (ip4_config != NULL);
|
||||
|
|
@ -340,19 +347,21 @@ nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin,
|
|||
* being emitted. So just copy all of that data into the ip4
|
||||
* config too.
|
||||
*/
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{ss}"));
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
|
||||
g_variant_iter_init (&iter, ip4_config);
|
||||
while (g_variant_iter_next (&iter, "{&s&s}", &key, &value))
|
||||
g_variant_builder_add (&builder, "{ss}", key, value);
|
||||
while (g_variant_iter_next (&iter, "{&sv}", &key, &value)) {
|
||||
g_variant_builder_add (&builder, "{sv}", key, value);
|
||||
g_variant_unref (value);
|
||||
}
|
||||
|
||||
if (priv->banner)
|
||||
g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner);
|
||||
g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_BANNER, &priv->banner);
|
||||
if (priv->tundev)
|
||||
g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev);
|
||||
g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV, &priv->tundev);
|
||||
if (priv->gateway)
|
||||
g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway);
|
||||
g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_EXT_GATEWAY, &priv->gateway);
|
||||
if (priv->mtu)
|
||||
g_variant_builder_add (&builder, "{ss}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu);
|
||||
g_variant_builder_add (&builder, "{sv}", NM_VPN_PLUGIN_IP4_CONFIG_MTU, &priv->mtu);
|
||||
|
||||
combined_config = g_variant_builder_end (&builder);
|
||||
g_variant_ref_sink (combined_config);
|
||||
|
|
@ -595,6 +604,8 @@ impl_vpn_plugin_old_new_secrets (NMVpnPluginOld *plugin,
|
|||
* request new secrets when the secrets originally provided by NetworkManager
|
||||
* are insufficient, or the VPN process indicates that it needs additional
|
||||
* information to complete the request.
|
||||
*
|
||||
* Deprecated: 1.2: replaced by NMVpnServicePlugin
|
||||
*/
|
||||
void
|
||||
nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin,
|
||||
|
|
@ -647,6 +658,8 @@ free_secret (gpointer data)
|
|||
* an applet when the applet calls the authentication dialog of the VPN plugin.
|
||||
*
|
||||
* Returns: %TRUE if reading values was successful, %FALSE if not
|
||||
*
|
||||
* Deprecated: 1.2: replaced by NMVpnServicePlugin
|
||||
**/
|
||||
gboolean
|
||||
nm_vpn_plugin_old_read_vpn_details (int fd,
|
||||
|
|
@ -748,6 +761,8 @@ nm_vpn_plugin_old_read_vpn_details (int fd,
|
|||
*
|
||||
* Returns: %TRUE if the flag data item was found and successfully converted
|
||||
* to flags, %FALSE if not
|
||||
*
|
||||
* Deprecated: 1.2: replaced by NMVpnServicePlugin
|
||||
**/
|
||||
gboolean
|
||||
nm_vpn_plugin_old_get_secret_flags (GHashTable *data,
|
||||
|
|
@ -1026,10 +1041,10 @@ finalize (GObject *object)
|
|||
nm_vpn_plugin_old_set_connection (plugin, NULL);
|
||||
g_free (priv->dbus_service_name);
|
||||
|
||||
g_clear_pointer (&priv->banner, g_free);
|
||||
g_clear_pointer (&priv->tundev, g_free);
|
||||
g_clear_pointer (&priv->gateway, g_free);
|
||||
g_clear_pointer (&priv->mtu, g_free);
|
||||
g_clear_pointer (&priv->banner, g_variant_unref);
|
||||
g_clear_pointer (&priv->tundev, g_variant_unref);
|
||||
g_clear_pointer (&priv->gateway, g_variant_unref);
|
||||
g_clear_pointer (&priv->mtu, g_variant_unref);
|
||||
|
||||
G_OBJECT_CLASS (nm_vpn_plugin_old_parent_class)->finalize (object);
|
||||
}
|
||||
|
|
@ -1077,6 +1092,8 @@ nm_vpn_plugin_old_class_init (NMVpnPluginOldClass *plugin_class)
|
|||
* NMVpnPluginOld:service-name:
|
||||
*
|
||||
* The D-Bus service name of this plugin.
|
||||
*
|
||||
* Deprecated: 1.2: replaced by NMVpnServicePlugin
|
||||
*/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DBUS_SERVICE_NAME,
|
||||
|
|
@ -1090,6 +1107,8 @@ nm_vpn_plugin_old_class_init (NMVpnPluginOldClass *plugin_class)
|
|||
* NMVpnPluginOld:state:
|
||||
*
|
||||
* The state of the plugin.
|
||||
*
|
||||
* Deprecated: 1.2: replaced by NMVpnServicePlugin
|
||||
*/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_STATE,
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2007 - 2008 Novell, Inc.
|
||||
* Copyright 2007 - 2013 Red Hat, Inc.
|
||||
* Copyright 2007 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_VPN_PLUGIN_OLD_H__
|
||||
|
|
@ -39,94 +39,122 @@ G_BEGIN_DECLS
|
|||
#define NM_VPN_PLUGIN_OLD_STATE "state"
|
||||
|
||||
typedef struct {
|
||||
NM_DEPRECATED_IN_1_2
|
||||
GObject parent;
|
||||
} NMVpnPluginOld;
|
||||
} NMVpnPluginOld NM_DEPRECATED_IN_1_2;
|
||||
|
||||
typedef struct {
|
||||
NM_DEPRECATED_IN_1_2
|
||||
GObjectClass parent;
|
||||
|
||||
/* Signals */
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void (*state_changed) (NMVpnPluginOld *plugin,
|
||||
NMVpnServiceState state);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void (*ip4_config) (NMVpnPluginOld *plugin,
|
||||
GVariant *ip4_config);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void (*login_banner) (NMVpnPluginOld *plugin,
|
||||
const char *banner);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void (*failure) (NMVpnPluginOld *plugin,
|
||||
NMVpnPluginFailure reason);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void (*quit) (NMVpnPluginOld *plugin);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void (*config) (NMVpnPluginOld *plugin,
|
||||
GVariant *config);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void (*ip6_config) (NMVpnPluginOld *plugin,
|
||||
GVariant *config);
|
||||
|
||||
/* virtual methods */
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gboolean (*connect) (NMVpnPluginOld *plugin,
|
||||
NMConnection *connection,
|
||||
GError **err);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gboolean (*need_secrets) (NMVpnPluginOld *plugin,
|
||||
NMConnection *connection,
|
||||
const char **setting_name,
|
||||
GError **error);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gboolean (*disconnect) (NMVpnPluginOld *plugin,
|
||||
GError **err);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gboolean (*new_secrets) (NMVpnPluginOld *plugin,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gboolean (*connect_interactive) (NMVpnPluginOld *plugin,
|
||||
NMConnection *connection,
|
||||
GVariant *details,
|
||||
GError **error);
|
||||
|
||||
/*< private >*/
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gpointer padding[8];
|
||||
} NMVpnPluginOldClass;
|
||||
} NMVpnPluginOldClass NM_DEPRECATED_IN_1_2;
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
GType nm_vpn_plugin_old_get_type (void);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
GDBusConnection *nm_vpn_plugin_old_get_connection (NMVpnPluginOld *plugin);
|
||||
NM_DEPRECATED_IN_1_2
|
||||
NMVpnServiceState nm_vpn_plugin_old_get_state (NMVpnPluginOld *plugin);
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void nm_vpn_plugin_old_set_state (NMVpnPluginOld *plugin,
|
||||
NMVpnServiceState state);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void nm_vpn_plugin_old_secrets_required (NMVpnPluginOld *plugin,
|
||||
const char *message,
|
||||
const char **hints);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void nm_vpn_plugin_old_set_login_banner (NMVpnPluginOld *plugin,
|
||||
const char *banner);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void nm_vpn_plugin_old_failure (NMVpnPluginOld *plugin,
|
||||
NMVpnPluginFailure reason);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void nm_vpn_plugin_old_set_config (NMVpnPluginOld *plugin,
|
||||
GVariant *config);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void nm_vpn_plugin_old_set_ip4_config (NMVpnPluginOld *plugin,
|
||||
GVariant *ip4_config);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
void nm_vpn_plugin_old_set_ip6_config (NMVpnPluginOld *plugin,
|
||||
GVariant *ip6_config);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gboolean nm_vpn_plugin_old_disconnect (NMVpnPluginOld *plugin,
|
||||
GError **err);
|
||||
|
||||
/* Utility functions */
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gboolean nm_vpn_plugin_old_read_vpn_details (int fd,
|
||||
GHashTable **out_data,
|
||||
GHashTable **out_secrets);
|
||||
|
||||
NM_DEPRECATED_IN_1_2
|
||||
gboolean nm_vpn_plugin_old_get_secret_flags (GHashTable *data,
|
||||
const char *secret_name,
|
||||
NMSettingSecretFlags *out_flags);
|
||||
|
|
|
|||
1208
libnm/nm-vpn-service-plugin.c
Normal file
1208
libnm/nm-vpn-service-plugin.c
Normal file
File diff suppressed because it is too large
Load diff
164
libnm/nm-vpn-service-plugin.h
Normal file
164
libnm/nm-vpn-service-plugin.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright 2007 - 2008 Novell, Inc.
|
||||
* Copyright 2007 - 2015 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __NM_VPN_SERVICE_PLUGIN_H__
|
||||
#define __NM_VPN_SERVICE_PLUGIN_H__
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <nm-vpn-dbus-interface.h>
|
||||
#include <nm-connection.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_VPN_SERVICE_PLUGIN (nm_vpn_service_plugin_get_type ())
|
||||
#define NM_VPN_SERVICE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePlugin))
|
||||
#define NM_VPN_SERVICE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginClass))
|
||||
#define NM_IS_VPN_SERVICE_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_SERVICE_PLUGIN))
|
||||
#define NM_IS_VPN_SERVICE_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_VPN_SERVICE_PLUGIN))
|
||||
#define NM_VPN_SERVICE_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE_PLUGIN, NMVpnServicePluginClass))
|
||||
|
||||
#define NM_VPN_SERVICE_PLUGIN_DBUS_SERVICE_NAME "service-name"
|
||||
#define NM_VPN_SERVICE_PLUGIN_STATE "state"
|
||||
|
||||
typedef struct {
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GObject parent;
|
||||
} NMVpnServicePlugin NM_AVAILABLE_IN_1_2;
|
||||
|
||||
typedef struct {
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GObjectClass parent;
|
||||
|
||||
/* Signals */
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void (*state_changed) (NMVpnServicePlugin *plugin,
|
||||
NMVpnServiceState state);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void (*ip4_config) (NMVpnServicePlugin *plugin,
|
||||
GVariant *ip4_config);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void (*login_banner) (NMVpnServicePlugin *plugin,
|
||||
const char *banner);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void (*failure) (NMVpnServicePlugin *plugin,
|
||||
NMVpnPluginFailure reason);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void (*quit) (NMVpnServicePlugin *plugin);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void (*config) (NMVpnServicePlugin *plugin,
|
||||
GVariant *config);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void (*ip6_config) (NMVpnServicePlugin *plugin,
|
||||
GVariant *config);
|
||||
|
||||
/* virtual methods */
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean (*connect) (NMVpnServicePlugin *plugin,
|
||||
NMConnection *connection,
|
||||
GError **err);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean (*need_secrets) (NMVpnServicePlugin *plugin,
|
||||
NMConnection *connection,
|
||||
const char **setting_name,
|
||||
GError **error);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean (*disconnect) (NMVpnServicePlugin *plugin,
|
||||
GError **err);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean (*new_secrets) (NMVpnServicePlugin *plugin,
|
||||
NMConnection *connection,
|
||||
GError **error);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean (*connect_interactive) (NMVpnServicePlugin *plugin,
|
||||
NMConnection *connection,
|
||||
GVariant *details,
|
||||
GError **error);
|
||||
|
||||
/*< private >*/
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gpointer padding[8];
|
||||
} NMVpnServicePluginClass NM_AVAILABLE_IN_1_2;
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GType nm_vpn_service_plugin_get_type (void);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GDBusConnection *nm_vpn_service_plugin_get_connection (NMVpnServicePlugin *plugin);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMVpnServiceState nm_vpn_service_plugin_get_state (NMVpnServicePlugin *plugin);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_vpn_service_plugin_set_state (NMVpnServicePlugin *plugin,
|
||||
NMVpnServiceState state);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_vpn_service_plugin_secrets_required (NMVpnServicePlugin *plugin,
|
||||
const char *message,
|
||||
const char **hints);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_vpn_service_plugin_set_login_banner (NMVpnServicePlugin *plugin,
|
||||
const char *banner);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_vpn_service_plugin_failure (NMVpnServicePlugin *plugin,
|
||||
NMVpnPluginFailure reason);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_vpn_service_plugin_set_config (NMVpnServicePlugin *plugin,
|
||||
GVariant *config);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_vpn_service_plugin_set_ip4_config (NMVpnServicePlugin *plugin,
|
||||
GVariant *ip4_config);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_vpn_service_plugin_set_ip6_config (NMVpnServicePlugin *plugin,
|
||||
GVariant *ip6_config);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_vpn_service_plugin_disconnect (NMVpnServicePlugin *plugin,
|
||||
GError **err);
|
||||
|
||||
/* Utility functions */
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_vpn_service_plugin_read_vpn_details (int fd,
|
||||
GHashTable **out_data,
|
||||
GHashTable **out_secrets);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_vpn_service_plugin_get_secret_flags (GHashTable *data,
|
||||
const char *secret_name,
|
||||
NMSettingSecretFlags *out_flags);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_VPN_SERVICE_PLUGIN_H__ */
|
||||
|
|
@ -77,6 +77,8 @@ libnm-core/nm-setting-wireless-security.c
|
|||
libnm-core/nm-setting-wireless.c
|
||||
libnm-core/nm-setting.c
|
||||
libnm-core/nm-utils.c
|
||||
libnm-core/nm-vpn-editor-plugin.c
|
||||
libnm-core/nm-vpn-plugin-info.c
|
||||
libnm-glib/nm-device.c
|
||||
libnm-glib/nm-remote-connection.c
|
||||
libnm-util/crypto.c
|
||||
|
|
@ -127,6 +129,7 @@ libnm/nm-object.c
|
|||
libnm/nm-remote-connection.c
|
||||
libnm/nm-remote-settings.c
|
||||
libnm/nm-vpn-plugin-old.c
|
||||
libnm/nm-vpn-service-plugin.c
|
||||
policy/org.freedesktop.NetworkManager.policy.in.in
|
||||
src/NetworkManagerUtils.c
|
||||
src/main.c
|
||||
|
|
|
|||
|
|
@ -29,44 +29,38 @@
|
|||
#include "nm-vpn-connection.h"
|
||||
#include "nm-setting-vpn.h"
|
||||
#include "nm-vpn-dbus-interface.h"
|
||||
#include "nm-core-internal.h"
|
||||
#include "nm-enum-types.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
#define VPN_NAME_FILES_DIR NMCONFDIR "/VPN"
|
||||
#include "gsystem-local-alloc.h"
|
||||
|
||||
G_DEFINE_TYPE (NMVpnManager, nm_vpn_manager, G_TYPE_OBJECT)
|
||||
|
||||
#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVpnManagerPrivate))
|
||||
|
||||
typedef struct {
|
||||
GHashTable *services;
|
||||
GFileMonitor *monitor;
|
||||
guint monitor_id;
|
||||
GSList *services;
|
||||
GFileMonitor *monitor_etc;
|
||||
GFileMonitor *monitor_lib;
|
||||
guint monitor_id_etc;
|
||||
guint monitor_id_lib;
|
||||
} NMVpnManagerPrivate;
|
||||
|
||||
|
||||
static NMVpnService *
|
||||
get_service_by_namefile (NMVpnManager *self, const char *namefile)
|
||||
_plugin_info_get_service (NMVpnPluginInfo *plugin_info)
|
||||
{
|
||||
NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
|
||||
GHashTableIter iter;
|
||||
gpointer data;
|
||||
|
||||
g_return_val_if_fail (namefile, NULL);
|
||||
g_return_val_if_fail (g_path_is_absolute (namefile), NULL);
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->services);
|
||||
while (g_hash_table_iter_next (&iter, NULL, &data)) {
|
||||
NMVpnService *candidate = NM_VPN_SERVICE (data);
|
||||
const char *service_namefile;
|
||||
|
||||
service_namefile = nm_vpn_service_get_name_file (candidate);
|
||||
if (!strcmp (namefile, service_namefile))
|
||||
return candidate;
|
||||
}
|
||||
if (plugin_info)
|
||||
return NM_VPN_SERVICE (g_object_get_data (G_OBJECT (plugin_info), "service-instance"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
_plugin_info_set_service (NMVpnPluginInfo *plugin_info, NMVpnService *service)
|
||||
{
|
||||
g_object_set_data_full (G_OBJECT (plugin_info), "service-instance", service,
|
||||
(GDestroyNotify) g_object_unref);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_manager_activate_connection (NMVpnManager *manager,
|
||||
NMVpnConnection *vpn,
|
||||
|
|
@ -75,6 +69,7 @@ nm_vpn_manager_activate_connection (NMVpnManager *manager,
|
|||
NMConnection *connection;
|
||||
NMSettingVpn *s_vpn;
|
||||
NMVpnService *service;
|
||||
NMVpnPluginInfo *plugin_info;
|
||||
const char *service_name;
|
||||
NMDevice *device;
|
||||
|
||||
|
|
@ -98,8 +93,8 @@ nm_vpn_manager_activate_connection (NMVpnManager *manager,
|
|||
g_assert (s_vpn);
|
||||
|
||||
service_name = nm_setting_vpn_get_service_type (s_vpn);
|
||||
g_assert (service_name);
|
||||
service = g_hash_table_lookup (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, service_name);
|
||||
plugin_info = nm_vpn_plugin_info_list_find_by_service (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, service_name);
|
||||
service = _plugin_info_get_service (plugin_info);
|
||||
if (!service) {
|
||||
g_set_error (error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
|
||||
"The VPN service '%s' was not installed.",
|
||||
|
|
@ -119,33 +114,31 @@ nm_vpn_manager_deactivate_connection (NMVpnManager *self,
|
|||
}
|
||||
|
||||
static void
|
||||
try_add_service (NMVpnManager *self, const char *namefile)
|
||||
try_add_service (NMVpnManager *self, NMVpnPluginInfo *plugin_info)
|
||||
{
|
||||
NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
|
||||
NMVpnService *service = NULL;
|
||||
GHashTableIter iter;
|
||||
GError *error = NULL;
|
||||
const char *service_name;
|
||||
|
||||
g_return_if_fail (g_path_is_absolute (namefile));
|
||||
|
||||
/* Make sure we don't add dupes */
|
||||
g_hash_table_iter_init (&iter, priv->services);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &service)) {
|
||||
if (g_strcmp0 (namefile, nm_vpn_service_get_name_file (service)) == 0)
|
||||
return;
|
||||
}
|
||||
/* Make sure we don't add dupes.
|
||||
* We don't really allow reload of the same file. What we do allow is however to
|
||||
* delete a file and re-add it. */
|
||||
if (nm_vpn_plugin_info_list_find_by_filename (priv->services,
|
||||
nm_vpn_plugin_info_get_filename (plugin_info)))
|
||||
return;
|
||||
if (!nm_vpn_plugin_info_list_add (&priv->services, plugin_info, NULL))
|
||||
return;
|
||||
|
||||
/* New service */
|
||||
service = nm_vpn_service_new (namefile, &error);
|
||||
service = nm_vpn_service_new (plugin_info, &error);
|
||||
if (service) {
|
||||
service_name = nm_vpn_service_get_dbus_service (service);
|
||||
g_hash_table_insert (priv->services, (char *) service_name, service);
|
||||
nm_log_info (LOGD_VPN, "VPN: loaded %s", service_name);
|
||||
_plugin_info_set_service (plugin_info, service);
|
||||
nm_log_info (LOGD_VPN, "VPN: loaded %s - %s",
|
||||
nm_vpn_plugin_info_get_name (plugin_info),
|
||||
nm_vpn_service_get_dbus_service (service));
|
||||
} else {
|
||||
nm_log_warn (LOGD_VPN, "failed to load VPN service file %s: (%d) %s",
|
||||
namefile,
|
||||
error ? error->code : -1,
|
||||
nm_log_warn (LOGD_VPN, "failed to load VPN service file %s: %s",
|
||||
nm_vpn_plugin_info_get_filename (plugin_info),
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
|
@ -160,41 +153,65 @@ vpn_dir_changed (GFileMonitor *monitor,
|
|||
{
|
||||
NMVpnManager *self = NM_VPN_MANAGER (user_data);
|
||||
NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
|
||||
NMVpnPluginInfo *plugin_info;
|
||||
NMVpnService *service;
|
||||
char *path;
|
||||
gs_free char *path = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
path = g_file_get_path (file);
|
||||
if (!g_str_has_suffix (path, ".name")) {
|
||||
g_free (path);
|
||||
if (!nm_vpn_plugin_info_validate_filename (path))
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event_type) {
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
nm_log_dbg (LOGD_VPN, "service file %s deleted", path);
|
||||
plugin_info = nm_vpn_plugin_info_list_find_by_filename (priv->services, path);
|
||||
if (!plugin_info)
|
||||
break;
|
||||
|
||||
service = get_service_by_namefile (self, path);
|
||||
nm_log_dbg (LOGD_VPN, "vpn: service file %s deleted", path);
|
||||
service = _plugin_info_get_service (plugin_info);
|
||||
if (service) {
|
||||
const char *service_name = nm_vpn_service_get_dbus_service (service);
|
||||
|
||||
/* Stop active VPN connections and destroy the service */
|
||||
nm_vpn_service_stop_connections (service, FALSE,
|
||||
NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
|
||||
nm_log_info (LOGD_VPN, "VPN: unloaded %s", service_name);
|
||||
g_hash_table_remove (priv->services, service_name);
|
||||
nm_log_info (LOGD_VPN, "VPN: unloaded %s", nm_vpn_service_get_dbus_service (service));
|
||||
|
||||
_plugin_info_set_service (plugin_info, NULL);
|
||||
}
|
||||
nm_vpn_plugin_info_list_remove (&priv->services, plugin_info);
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
||||
nm_log_dbg (LOGD_VPN, "service file %s created or modified", path);
|
||||
try_add_service (self, path);
|
||||
plugin_info = nm_vpn_plugin_info_list_find_by_filename (priv->services, path);
|
||||
if (plugin_info) {
|
||||
/* we don't support reloading an existing plugin. You can only remove the file
|
||||
* and re-add it. By reloading we want to support the use case of installing
|
||||
* a VPN plugin after NM started. No need to burden ourself with a complete
|
||||
* reload. */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_nm_vpn_plugin_info_check_file (path, TRUE, TRUE, 0,
|
||||
NULL, NULL, &error)) {
|
||||
nm_log_dbg (LOGD_VPN, "vpn: ignore changed service file %s (%s)", path, error->message);
|
||||
g_clear_error (&error);
|
||||
break;
|
||||
}
|
||||
plugin_info = nm_vpn_plugin_info_new_from_file (path, &error);
|
||||
if (!plugin_info) {
|
||||
nm_log_dbg (LOGD_VPN, "vpn: ignore changed service file %s due to invalid content (%s)", path, error->message);
|
||||
g_clear_error (&error);
|
||||
break;
|
||||
}
|
||||
|
||||
nm_log_dbg (LOGD_VPN, "vpn: service file %s created or modified", path);
|
||||
try_add_service (self, plugin_info);
|
||||
g_object_unref (plugin_info);
|
||||
break;
|
||||
default:
|
||||
nm_log_dbg (LOGD_VPN, "service file %s change event %d", path, event_type);
|
||||
nm_log_dbg (LOGD_VPN, "vpn: service file %s change event %d", path, event_type);
|
||||
break;
|
||||
}
|
||||
|
||||
g_free (path);
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
|
@ -206,50 +223,40 @@ nm_vpn_manager_init (NMVpnManager *self)
|
|||
{
|
||||
NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
|
||||
GFile *file;
|
||||
GDir *dir;
|
||||
const char *fn;
|
||||
char *path;
|
||||
|
||||
priv->services = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL, g_object_unref);
|
||||
GSList *infos, *info;
|
||||
const char *conf_dir_etc = _nm_vpn_plugin_info_get_default_dir_etc ();
|
||||
const char *conf_dir_lib = _nm_vpn_plugin_info_get_default_dir_lib ();
|
||||
|
||||
/* Watch the VPN directory for changes */
|
||||
file = g_file_new_for_path (VPN_NAME_FILES_DIR "/");
|
||||
priv->monitor = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
file = g_file_new_for_path (conf_dir_lib);
|
||||
priv->monitor_lib = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
g_object_unref (file);
|
||||
if (priv->monitor) {
|
||||
priv->monitor_id = g_signal_connect (priv->monitor, "changed",
|
||||
G_CALLBACK (vpn_dir_changed), self);
|
||||
if (priv->monitor_lib) {
|
||||
priv->monitor_id_lib = g_signal_connect (priv->monitor_lib, "changed",
|
||||
G_CALLBACK (vpn_dir_changed), self);
|
||||
}
|
||||
|
||||
/* Load VPN service files */
|
||||
dir = g_dir_open (VPN_NAME_FILES_DIR, 0, NULL);
|
||||
if (dir) {
|
||||
while ((fn = g_dir_read_name (dir))) {
|
||||
/* only parse filenames that end with .name */
|
||||
if (g_str_has_suffix (fn, ".name")) {
|
||||
path = g_build_filename (VPN_NAME_FILES_DIR, fn, NULL);
|
||||
try_add_service (self, path);
|
||||
g_free (path);
|
||||
}
|
||||
}
|
||||
g_dir_close (dir);
|
||||
file = g_file_new_for_path (conf_dir_etc);
|
||||
priv->monitor_etc = g_file_monitor_directory (file, G_FILE_MONITOR_NONE, NULL, NULL);
|
||||
g_object_unref (file);
|
||||
if (priv->monitor_etc) {
|
||||
priv->monitor_id_etc = g_signal_connect (priv->monitor_etc, "changed",
|
||||
G_CALLBACK (vpn_dir_changed), self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
stop_all_services (NMVpnManager *self)
|
||||
{
|
||||
NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (self);
|
||||
GHashTableIter iter;
|
||||
NMVpnService *service;
|
||||
/* first read conf_dir_lib. The name files are not really user configuration, but
|
||||
* plugin configuration. Hence we expect ~newer~ plugins to install their files
|
||||
* in /usr/lib/NetworkManager. We want to prefer those files.
|
||||
* In case of no-conflict, the order doesn't matter. */
|
||||
infos = _nm_vpn_plugin_info_list_load_dir (conf_dir_lib, TRUE, 0, NULL, NULL);
|
||||
for (info = infos; info; info = info->next)
|
||||
try_add_service (self, info->data);
|
||||
g_slist_free_full (infos, g_object_unref);
|
||||
|
||||
g_hash_table_iter_init (&iter, priv->services);
|
||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer) &service)) {
|
||||
nm_vpn_service_stop_connections (service,
|
||||
TRUE,
|
||||
NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
|
||||
}
|
||||
infos = _nm_vpn_plugin_info_list_load_dir (conf_dir_etc, TRUE, 0, NULL, NULL);
|
||||
for (info = infos; info; info = info->next)
|
||||
try_add_service (self, info->data);
|
||||
g_slist_free_full (infos, g_object_unref);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -257,17 +264,29 @@ dispose (GObject *object)
|
|||
{
|
||||
NMVpnManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
|
||||
|
||||
if (priv->monitor) {
|
||||
if (priv->monitor_id)
|
||||
g_signal_handler_disconnect (priv->monitor, priv->monitor_id);
|
||||
g_file_monitor_cancel (priv->monitor);
|
||||
g_clear_object (&priv->monitor);
|
||||
if (priv->monitor_etc) {
|
||||
if (priv->monitor_id_etc)
|
||||
g_signal_handler_disconnect (priv->monitor_etc, priv->monitor_id_etc);
|
||||
g_file_monitor_cancel (priv->monitor_etc);
|
||||
g_clear_object (&priv->monitor_etc);
|
||||
}
|
||||
|
||||
if (priv->services) {
|
||||
stop_all_services (NM_VPN_MANAGER (object));
|
||||
g_hash_table_destroy (priv->services);
|
||||
priv->services = NULL;
|
||||
if (priv->monitor_lib) {
|
||||
if (priv->monitor_id_lib)
|
||||
g_signal_handler_disconnect (priv->monitor_lib, priv->monitor_id_lib);
|
||||
g_file_monitor_cancel (priv->monitor_lib);
|
||||
g_clear_object (&priv->monitor_lib);
|
||||
}
|
||||
|
||||
while (priv->services) {
|
||||
NMVpnPluginInfo *plugin_info = priv->services->data;
|
||||
NMVpnService *service = _plugin_info_get_service (plugin_info);
|
||||
|
||||
if (service) {
|
||||
nm_vpn_service_stop_connections (service, TRUE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
|
||||
_plugin_info_set_service (plugin_info, NULL);
|
||||
}
|
||||
nm_vpn_plugin_info_list_remove (&priv->services, plugin_info);
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (nm_vpn_manager_parent_class)->dispose (object);
|
||||
|
|
|
|||
|
|
@ -35,10 +35,7 @@
|
|||
G_DEFINE_TYPE (NMVpnService, nm_vpn_service, G_TYPE_OBJECT)
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *dbus_service;
|
||||
char *program;
|
||||
char *namefile;
|
||||
NMVpnPluginInfo *plugin_info;
|
||||
|
||||
NMVpnConnection *active;
|
||||
GSList *pending;
|
||||
|
|
@ -50,67 +47,50 @@ typedef struct {
|
|||
|
||||
#define NM_VPN_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_SERVICE, NMVpnServicePrivate))
|
||||
|
||||
#define VPN_CONNECTION_GROUP "VPN Connection"
|
||||
|
||||
static gboolean start_pending_vpn (NMVpnService *self, GError **error);
|
||||
|
||||
static void _name_owner_changed (GObject *object, GParamSpec *pspec, gpointer user_data);
|
||||
|
||||
NMVpnService *
|
||||
nm_vpn_service_new (const char *namefile, GError **error)
|
||||
nm_vpn_service_new (NMVpnPluginInfo *plugin_info, GError **error)
|
||||
{
|
||||
NMVpnService *self;
|
||||
NMVpnServicePrivate *priv;
|
||||
GKeyFile *kf;
|
||||
|
||||
g_return_val_if_fail (namefile != NULL, NULL);
|
||||
g_return_val_if_fail (g_path_is_absolute (namefile), NULL);
|
||||
g_return_val_if_fail (NM_IS_VPN_PLUGIN_INFO (plugin_info), NULL);
|
||||
g_return_val_if_fail (nm_vpn_plugin_info_get_filename (plugin_info), NULL);
|
||||
|
||||
kf = g_key_file_new ();
|
||||
if (!g_key_file_load_from_file (kf, namefile, G_KEY_FILE_NONE, error)) {
|
||||
g_key_file_free (kf);
|
||||
if (!nm_vpn_plugin_info_get_program (plugin_info)) {
|
||||
g_set_error (error,
|
||||
NM_VPN_PLUGIN_ERROR,
|
||||
NM_VPN_PLUGIN_ERROR_FAILED,
|
||||
"missing \"program\" entry");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self = (NMVpnService *) g_object_new (NM_TYPE_VPN_SERVICE, NULL);
|
||||
priv = NM_VPN_SERVICE_GET_PRIVATE (self);
|
||||
priv->namefile = g_strdup (namefile);
|
||||
|
||||
priv->dbus_service = g_key_file_get_string (kf, VPN_CONNECTION_GROUP, "service", error);
|
||||
if (!priv->dbus_service)
|
||||
goto error;
|
||||
|
||||
priv->program = g_key_file_get_string (kf, VPN_CONNECTION_GROUP, "program", error);
|
||||
if (!priv->program)
|
||||
goto error;
|
||||
|
||||
priv->name = g_key_file_get_string (kf, VPN_CONNECTION_GROUP, "name", error);
|
||||
if (!priv->name)
|
||||
goto error;
|
||||
priv->plugin_info = g_object_ref (plugin_info);
|
||||
|
||||
priv->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
|
||||
NULL,
|
||||
priv->dbus_service,
|
||||
nm_vpn_plugin_info_get_service (plugin_info),
|
||||
NM_VPN_DBUS_PLUGIN_PATH,
|
||||
NM_VPN_DBUS_PLUGIN_INTERFACE,
|
||||
NULL, error);
|
||||
if (!priv->proxy)
|
||||
goto error;
|
||||
if (!priv->proxy) {
|
||||
g_object_unref (self);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
g_signal_connect (priv->proxy, "notify::g-name-owner",
|
||||
G_CALLBACK (_name_owner_changed), self);
|
||||
_name_owner_changed (G_OBJECT (priv->proxy), NULL, self);
|
||||
|
||||
g_key_file_free (kf);
|
||||
return self;
|
||||
|
||||
error:
|
||||
g_object_unref (self);
|
||||
g_key_file_free (kf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *
|
||||
|
|
@ -118,15 +98,7 @@ nm_vpn_service_get_dbus_service (NMVpnService *service)
|
|||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
|
||||
|
||||
return NM_VPN_SERVICE_GET_PRIVATE (service)->dbus_service;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_vpn_service_get_name_file (NMVpnService *service)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
|
||||
|
||||
return NM_VPN_SERVICE_GET_PRIVATE (service)->namefile;
|
||||
return nm_vpn_plugin_info_get_service (NM_VPN_SERVICE_GET_PRIVATE (service)->plugin_info);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -187,7 +159,7 @@ _daemon_exec_timeout (gpointer data)
|
|||
NMVpnService *self = NM_VPN_SERVICE (data);
|
||||
NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
|
||||
|
||||
nm_log_warn (LOGD_VPN, "VPN service '%s' start timed out", priv->name);
|
||||
nm_log_warn (LOGD_VPN, "VPN service '%s' start timed out", nm_vpn_plugin_info_get_name (priv->plugin_info));
|
||||
priv->start_timeout = 0;
|
||||
nm_vpn_service_stop_connections (self, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_START_TIMEOUT);
|
||||
return G_SOURCE_REMOVE;
|
||||
|
|
@ -204,17 +176,21 @@ nm_vpn_service_daemon_exec (NMVpnService *service, GError **error)
|
|||
|
||||
g_return_val_if_fail (NM_IS_VPN_SERVICE (service), FALSE);
|
||||
|
||||
vpn_argv[0] = priv->program;
|
||||
vpn_argv[0] = (char *) nm_vpn_plugin_info_get_program (priv->plugin_info);
|
||||
vpn_argv[1] = NULL;
|
||||
|
||||
g_assert (vpn_argv[0]);
|
||||
|
||||
success = g_spawn_async (NULL, vpn_argv, NULL, 0, nm_utils_setpgid, NULL, &pid, &spawn_error);
|
||||
if (success) {
|
||||
nm_log_info (LOGD_VPN, "VPN service '%s' started (%s), PID %ld",
|
||||
priv->name, priv->dbus_service, (long int) pid);
|
||||
nm_vpn_plugin_info_get_name (priv->plugin_info),
|
||||
nm_vpn_service_get_dbus_service (service),
|
||||
(long int) pid);
|
||||
priv->start_timeout = g_timeout_add_seconds (5, _daemon_exec_timeout, service);
|
||||
} else {
|
||||
nm_log_warn (LOGD_VPN, "VPN service '%s': could not launch the VPN service. error: (%d) %s.",
|
||||
priv->name,
|
||||
nm_vpn_plugin_info_get_name (priv->plugin_info),
|
||||
spawn_error ? spawn_error->code : -1,
|
||||
spawn_error && spawn_error->message ? spawn_error->message : "(unknown)");
|
||||
|
||||
|
|
@ -244,7 +220,7 @@ start_active_vpn (NMVpnService *self, GError **error)
|
|||
return TRUE;
|
||||
} else if (priv->start_timeout == 0) {
|
||||
/* VPN service not running, start it */
|
||||
nm_log_info (LOGD_VPN, "Starting VPN service '%s'...", priv->name);
|
||||
nm_log_info (LOGD_VPN, "Starting VPN service '%s'...", nm_vpn_plugin_info_get_name (priv->plugin_info));
|
||||
return nm_vpn_service_daemon_exec (self, error);
|
||||
}
|
||||
|
||||
|
|
@ -324,14 +300,14 @@ _name_owner_changed (GObject *object,
|
|||
if (owner && !priv->service_running) {
|
||||
/* service appeared */
|
||||
priv->service_running = TRUE;
|
||||
nm_log_info (LOGD_VPN, "VPN service '%s' appeared; activating connections", priv->name);
|
||||
nm_log_info (LOGD_VPN, "VPN service '%s' appeared; activating connections", nm_vpn_plugin_info_get_name (priv->plugin_info));
|
||||
/* Expect success because the VPN service has already appeared */
|
||||
success = start_active_vpn (service, NULL);
|
||||
g_warn_if_fail (success);
|
||||
} else if (!owner && priv->service_running) {
|
||||
/* service went away */
|
||||
priv->service_running = FALSE;
|
||||
nm_log_info (LOGD_VPN, "VPN service '%s' disappeared", priv->name);
|
||||
nm_log_info (LOGD_VPN, "VPN service '%s' disappeared", nm_vpn_plugin_info_get_name (priv->plugin_info));
|
||||
nm_vpn_service_stop_connections (service, FALSE, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
|
||||
}
|
||||
|
||||
|
|
@ -351,10 +327,9 @@ dispose (GObject *object)
|
|||
NMVpnService *self = NM_VPN_SERVICE (object);
|
||||
NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (self);
|
||||
|
||||
if (priv->start_timeout) {
|
||||
g_source_remove (priv->start_timeout);
|
||||
priv->start_timeout = 0;
|
||||
}
|
||||
nm_clear_g_source (&priv->start_timeout);
|
||||
|
||||
g_clear_object (&priv->plugin_info);
|
||||
|
||||
/* VPNService owner is required to stop connections before releasing */
|
||||
g_assert (priv->active == NULL);
|
||||
|
|
@ -370,19 +345,6 @@ dispose (GObject *object)
|
|||
G_OBJECT_CLASS (nm_vpn_service_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMVpnServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (object);
|
||||
|
||||
g_free (priv->name);
|
||||
g_free (priv->dbus_service);
|
||||
g_free (priv->program);
|
||||
g_free (priv->namefile);
|
||||
|
||||
G_OBJECT_CLASS (nm_vpn_service_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_vpn_service_class_init (NMVpnServiceClass *service_class)
|
||||
{
|
||||
|
|
@ -392,5 +354,4 @@ nm_vpn_service_class_init (NMVpnServiceClass *service_class)
|
|||
|
||||
/* virtual methods */
|
||||
object_class->dispose = dispose;
|
||||
object_class->finalize = finalize;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "nm-glib.h"
|
||||
#include "nm-device.h"
|
||||
#include "nm-vpn-connection.h"
|
||||
#include "nm-vpn-plugin-info.h"
|
||||
|
||||
#define NM_TYPE_VPN_SERVICE (nm_vpn_service_get_type ())
|
||||
#define NM_VPN_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE, NMVpnService))
|
||||
|
|
@ -43,14 +44,11 @@ typedef struct {
|
|||
|
||||
GType nm_vpn_service_get_type (void);
|
||||
|
||||
NMVpnService * nm_vpn_service_new (const char *namefile, GError **error);
|
||||
NMVpnService * nm_vpn_service_new (NMVpnPluginInfo *plugin_info, GError **error);
|
||||
|
||||
/* Returns the VPN service's D-Bus service name */
|
||||
const char *nm_vpn_service_get_dbus_service (NMVpnService *service);
|
||||
|
||||
/* Returns the path of the VPN service's .name file */
|
||||
const char *nm_vpn_service_get_name_file (NMVpnService *service);
|
||||
|
||||
gboolean nm_vpn_service_activate (NMVpnService *service,
|
||||
NMVpnConnection *vpn,
|
||||
GError **error);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue