From ec89663e7da344f54e11dbd5848c2828fa258b92 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 26 Mar 2008 13:43:01 +0000 Subject: [PATCH] 2008-03-26 Dan Williams Rework VPN connection handling for a more consistent D-Bus API. The VPNManager object has been removed, and active VPN connections are now the same as any other active connection. The Manager object's ActivateConnection and DeactivateConnection methods are used to start and stop a VPN connection, and the VPNConnection objects are subclasses of the ActiveConnection objects. When activating a VPN connection, pass the path of the active connection to which the VPN connection is tied in the 'specific_object' argument. Consequently, the libnm-glib API has been reworked to match this arrangement, with the VPNManager object removed, and the NMVPNConnection objects now being subclasses of NMActiveConnection. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3504 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 14 ++ introspection/Makefile.am | 1 - introspection/all.xml | 1 - introspection/nm-vpn-connection.xml | 33 ++- introspection/nm-vpn-manager.xml | 46 ---- libnm-glib/Makefile.am | 6 - libnm-glib/nm-active-connection.c | 38 ++- libnm-glib/nm-active-connection.h | 2 + libnm-glib/nm-client.c | 43 +++- libnm-glib/nm-vpn-connection.c | 55 +---- libnm-glib/nm-vpn-connection.h | 13 +- libnm-glib/nm-vpn-manager.c | 136 ----------- libnm-glib/nm-vpn-manager.h | 46 ---- src/Makefile.am | 2 + src/NetworkManager.c | 18 +- src/NetworkManagerPolicy.c | 56 +++-- src/marshallers/nm-marshal.list | 2 + src/nm-activation-request.c | 57 ++--- src/nm-activation-request.h | 8 +- src/nm-active-connection.c | 63 +++++ src/nm-active-connection.h | 42 ++++ src/nm-manager.c | 347 +++++++++++++++++++--------- src/nm-manager.h | 19 +- src/vpn-manager/Makefile.am | 4 - src/vpn-manager/nm-vpn-connection.c | 212 ++++++++++++----- src/vpn-manager/nm-vpn-connection.h | 15 +- src/vpn-manager/nm-vpn-manager.c | 341 ++++++++++++++++----------- src/vpn-manager/nm-vpn-manager.h | 24 +- src/vpn-manager/nm-vpn-service.c | 28 ++- src/vpn-manager/nm-vpn-service.h | 16 +- 30 files changed, 973 insertions(+), 715 deletions(-) delete mode 100644 introspection/nm-vpn-manager.xml delete mode 100644 libnm-glib/nm-vpn-manager.c delete mode 100644 libnm-glib/nm-vpn-manager.h create mode 100644 src/nm-active-connection.c create mode 100644 src/nm-active-connection.h diff --git a/ChangeLog b/ChangeLog index b3ef434abb..05fcc39cea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2008-03-26 Dan Williams + + Rework VPN connection handling for a more consistent D-Bus API. The + VPNManager object has been removed, and active VPN connections are now the + same as any other active connection. The Manager object's ActivateConnection + and DeactivateConnection methods are used to start and stop a VPN connection, + and the VPNConnection objects are subclasses of the ActiveConnection objects. + When activating a VPN connection, pass the path of the active connection + to which the VPN connection is tied in the 'specific_object' argument. + + Consequently, the libnm-glib API has been reworked to match this arrangement, + with the VPNManager object removed, and the NMVPNConnection objects now + being subclasses of NMActiveConnection. + 2008-03-25 Dan Williams Patch from Björn Martensen diff --git a/introspection/Makefile.am b/introspection/Makefile.am index e8ca586d06..6b74577a83 100644 --- a/introspection/Makefile.am +++ b/introspection/Makefile.am @@ -10,7 +10,6 @@ EXTRA_DIST = \ nm-manager-client.xml \ nm-settings.xml \ nm-exported-connection.xml \ - nm-vpn-manager.xml \ nm-vpn-plugin.xml \ nm-vpn-connection.xml \ nm-ppp-manager.xml \ diff --git a/introspection/all.xml b/introspection/all.xml index 07f8dbed40..654f7cce99 100644 --- a/introspection/all.xml +++ b/introspection/all.xml @@ -36,7 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - diff --git a/introspection/nm-vpn-connection.xml b/introspection/nm-vpn-connection.xml index b899d95f13..757b8d22a0 100644 --- a/introspection/nm-vpn-connection.xml +++ b/introspection/nm-vpn-connection.xml @@ -1,20 +1,32 @@ + + + The D-Bus service name providing this connection. + + + The path of the connection. + + + A specific object associated with the active connection. + + + The D-Bus service name that provides a connection with which this active connection is shared. + + + The path of a connection provided by the D-Bus service SharedServiceName which which this connection is shared. + + + Array of object paths representing devices which are part of this active connection. + + + - Represents a connection to a Virtual Private Network. + Represents an active connection to a Virtual Private Network. - - - Disconnect the VPN connection. - - - - - The name of the VPN connection. - The state of the VPN connection. @@ -37,6 +49,7 @@ + diff --git a/introspection/nm-vpn-manager.xml b/introspection/nm-vpn-manager.xml deleted file mode 100644 index 57665f61a7..0000000000 --- a/introspection/nm-vpn-manager.xml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - Establish a VPN connection. - - - - - String describing the connection type. - - - - - Object path of the network connection to establish the VPN connection on. - - - - - Object path of the device to establish the VPN connection on. - - - - - Object path of the newly created VPN connection. - - - - - - - Get the list of active VPN connections. - - - - - List of object paths of active VPN connections. - - - - - - - diff --git a/libnm-glib/Makefile.am b/libnm-glib/Makefile.am index a88ca59e56..47d4f1e8e3 100644 --- a/libnm-glib/Makefile.am +++ b/libnm-glib/Makefile.am @@ -10,7 +10,6 @@ BUILT_SOURCES = \ nm-marshal.c \ nm-exported-connection-glue.h \ nm-settings-glue.h \ - nm-vpn-manager-bindings.h \ nm-vpn-connection-bindings.h \ nm-vpn-plugin-glue.h \ nm-active-connection-bindings.h @@ -39,7 +38,6 @@ libnminclude_HEADERS = \ nm-gsm-device.h \ nm-cdma-device.h \ nm-vpn-connection.h \ - nm-vpn-manager.h \ nm-vpn-plugin.h \ nm-types.h \ nm-active-connection.h @@ -61,7 +59,6 @@ libnm_glib_la_SOURCES = \ nm-gsm-device.c \ nm-cdma-device.c \ nm-vpn-connection.c \ - nm-vpn-manager.c \ nm-marshal-main.c \ nm-types.c \ nm-types-private.h \ @@ -123,9 +120,6 @@ nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml nm-exported-connection-glue.h: $(top_srcdir)/introspection/nm-exported-connection.xml dbus-binding-tool --prefix=nm_exported_connection --mode=glib-server --output=nm-exported-connection-glue.h $(top_srcdir)/introspection/nm-exported-connection.xml -nm-vpn-manager-bindings.h: $(top_srcdir)/introspection/nm-vpn-manager.xml - dbus-binding-tool --prefix=nm_vpn_manager --mode=glib-client --output=nm-vpn-manager-bindings.h $(top_srcdir)/introspection/nm-vpn-manager.xml - nm-vpn-connection-bindings.h: $(top_srcdir)/introspection/nm-vpn-connection.xml dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-client --output=nm-vpn-connection-bindings.h $(top_srcdir)/introspection/nm-vpn-connection.xml diff --git a/libnm-glib/nm-active-connection.c b/libnm-glib/nm-active-connection.c index d8d5dd0517..8ee8a8e3c0 100644 --- a/libnm-glib/nm-active-connection.c +++ b/libnm-glib/nm-active-connection.c @@ -7,6 +7,7 @@ #include "nm-object-private.h" #include "nm-types-private.h" #include "nm-device.h" +#include "nm-connection.h" #include "nm-active-connection-bindings.h" @@ -22,6 +23,7 @@ typedef struct { DBusGProxy *proxy; char *service_name; + NMConnectionScope scope; char *connection; char *specific_object; char *shared_service_name; @@ -60,6 +62,17 @@ nm_active_connection_new (DBusGConnection *connection, const char *path) NULL); } +static NMConnectionScope +get_scope_for_service_name (const char *service_name) +{ + if (service_name && !strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS)) + return NM_CONNECTION_SCOPE_USER; + else if (service_name && !strcmp (service_name, NM_DBUS_SERVICE_SYSTEM_SETTINGS)) + return NM_CONNECTION_SCOPE_SYSTEM; + + return NM_CONNECTION_SCOPE_UNKNOWN; +} + const char * nm_active_connection_get_service_name (NMActiveConnection *connection) { @@ -72,11 +85,22 @@ nm_active_connection_get_service_name (NMActiveConnection *connection) priv->service_name = nm_object_get_string_property (NM_OBJECT (connection), NM_DBUS_INTERFACE_ACTIVE_CONNECTION, DBUS_PROP_SERVICE_NAME); + priv->scope = get_scope_for_service_name (priv->service_name); } return priv->service_name; } +NMConnectionScope +nm_active_connection_get_scope (NMActiveConnection *connection) +{ + g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NM_CONNECTION_SCOPE_UNKNOWN); + + /* Make sure service_name and scope are up-to-date */ + nm_active_connection_get_service_name (connection); + return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->scope; +} + const char * nm_active_connection_get_connection (NMActiveConnection *connection) { @@ -256,12 +280,24 @@ demarshal_devices (NMObject *object, GParamSpec *pspec, GValue *value, gpointer return TRUE; } +static gboolean +demarshal_service (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field) +{ + NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object); + + if (nm_object_demarshal_generic (object, pspec, value, field)) { + priv->scope = get_scope_for_service_name (priv->service_name); + return TRUE; + } + return FALSE; +} + static void register_for_property_changed (NMActiveConnection *connection) { NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); const NMPropertiesChangedInfo property_changed_info[] = { - { NM_ACTIVE_CONNECTION_SERVICE_NAME, nm_object_demarshal_generic, &priv->service_name }, + { NM_ACTIVE_CONNECTION_SERVICE_NAME, demarshal_service, &priv->service_name }, { NM_ACTIVE_CONNECTION_CONNECTION, nm_object_demarshal_generic, &priv->connection }, { NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, nm_object_demarshal_generic, &priv->specific_object }, { NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME, nm_object_demarshal_generic, &priv->shared_service_name }, diff --git a/libnm-glib/nm-active-connection.h b/libnm-glib/nm-active-connection.h index b42aa51221..bf4129f7f5 100644 --- a/libnm-glib/nm-active-connection.h +++ b/libnm-glib/nm-active-connection.h @@ -4,6 +4,7 @@ #include #include #include "nm-object.h" +#include G_BEGIN_DECLS @@ -34,6 +35,7 @@ GType nm_active_connection_get_type (void); GObject *nm_active_connection_new (DBusGConnection *connection, const char *path); const char * nm_active_connection_get_service_name (NMActiveConnection *connection); +NMConnectionScope nm_active_connection_get_scope (NMActiveConnection *connection); const char * nm_active_connection_get_connection (NMActiveConnection *connection); const char * nm_active_connection_get_specific_object (NMActiveConnection *connection); const char * nm_active_connection_get_shared_service_name (NMActiveConnection *connection); diff --git a/libnm-glib/nm-client.c b/libnm-glib/nm-client.c index 1d028f4be8..126e658209 100644 --- a/libnm-glib/nm-client.c +++ b/libnm-glib/nm-client.c @@ -14,6 +14,7 @@ #include "nm-types-private.h" #include "nm-object-private.h" #include "nm-active-connection.h" +#include "nm-vpn-connection.h" #include "nm-object-cache.h" #include "nm-dbus-glib-types.h" @@ -131,6 +132,46 @@ wireless_enabled_cb (GObject *object, GParamSpec *pspec, gpointer user_data) poke_wireless_devices_with_rf_status (NM_CLIENT (object)); } +static GObject * +new_active_connection (DBusGConnection *connection, const char *path) +{ + DBusGProxy *proxy; + GError *error = NULL; + GValue value = {0,}; + GObject *object = NULL; + + proxy = dbus_g_proxy_new_for_name (connection, + NM_DBUS_SERVICE, + path, + "org.freedesktop.DBus.Properties"); + if (!proxy) { + g_warning ("%s: couldn't create D-Bus object proxy.", __func__); + return NULL; + } + + /* Have to create an NMVPNConnection if it's a VPN connection, otherwise + * a plain NMActiveConnection. + */ + if (dbus_g_proxy_call (proxy, + "Get", &error, + G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION, + G_TYPE_STRING, "Vpn", + G_TYPE_INVALID, + G_TYPE_VALUE, &value, G_TYPE_INVALID)) { + if (g_value_get_boolean (&value)) + object = nm_vpn_connection_new (connection, path); + else + object = nm_active_connection_new (connection, path); + } else { + g_warning ("Error in getting active connection 'Vpn' property: (%d) %s", + error->code, error->message); + g_error_free (error); + } + + g_object_unref (proxy); + return object; +} + static gboolean demarshal_active_connections (NMObject *object, GParamSpec *pspec, @@ -140,7 +181,7 @@ demarshal_active_connections (NMObject *object, DBusGConnection *connection; connection = nm_object_get_connection (object); - if (!nm_object_array_demarshal (value, (GPtrArray **) field, connection, nm_active_connection_new)) + if (!nm_object_array_demarshal (value, (GPtrArray **) field, connection, new_active_connection)) return FALSE; nm_object_queue_notify (object, NM_CLIENT_ACTIVE_CONNECTIONS); diff --git a/libnm-glib/nm-vpn-connection.c b/libnm-glib/nm-vpn-connection.c index ff18de924f..e256bef3af 100644 --- a/libnm-glib/nm-vpn-connection.c +++ b/libnm-glib/nm-vpn-connection.c @@ -27,14 +27,14 @@ #include "nm-vpn-connection-bindings.h" #include "nm-marshal.h" #include "nm-object-private.h" +#include "nm-active-connection.h" -G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_OBJECT) +G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION) #define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate)) typedef struct { DBusGProxy *proxy; - char *name; char *banner; NMVPNConnectionState state; } NMVPNConnectionPrivate; @@ -48,38 +48,16 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -NMVPNConnection * -nm_vpn_connection_new (DBusGConnection *dbus_connection, - const char *path) +GObject * +nm_vpn_connection_new (DBusGConnection *dbus_connection, const char *path) { - NMVPNConnection *connection; - g_return_val_if_fail (dbus_connection != NULL, NULL); g_return_val_if_fail (path != NULL, NULL); - connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, - NM_OBJECT_DBUS_CONNECTION, dbus_connection, - NM_OBJECT_DBUS_PATH, path, - NULL); - - nm_vpn_connection_get_name (connection); - - return connection; -} - -const char * -nm_vpn_connection_get_name (NMVPNConnection *vpn) -{ - NMVPNConnectionPrivate *priv; - - g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL); - - priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn); - if (!priv->name) - priv->name = nm_object_get_string_property (NM_OBJECT (vpn), - NM_DBUS_INTERFACE_VPN_CONNECTION, - "Name"); - return priv->name; + return g_object_new (NM_TYPE_VPN_CONNECTION, + NM_OBJECT_DBUS_CONNECTION, dbus_connection, + NM_OBJECT_DBUS_PATH, path, + NULL); } const char * @@ -136,20 +114,6 @@ state_changed_proxy (DBusGProxy *proxy, } } -void -nm_vpn_connection_disconnect (NMVPNConnection *vpn) -{ - GError *err = NULL; - - g_return_if_fail (NM_IS_VPN_CONNECTION (vpn)); - - org_freedesktop_NetworkManager_VPN_Connection_disconnect (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy, &err); - if (err) { - nm_warning ("Error in VPN disconnect: %s", err->message); - g_error_free (err); - } -} - /*****************************************************************************/ static void @@ -199,12 +163,11 @@ finalize (GObject *object) { NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); - if (priv->name) - g_free (priv->name); if (priv->banner) g_free (priv->banner); g_object_unref (priv->proxy); + G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object); } diff --git a/libnm-glib/nm-vpn-connection.h b/libnm-glib/nm-vpn-connection.h index a32cc66640..6b60988436 100644 --- a/libnm-glib/nm-vpn-connection.h +++ b/libnm-glib/nm-vpn-connection.h @@ -26,7 +26,7 @@ #include #include #include -#include "nm-object.h" +#include "nm-active-connection.h" #include "NetworkManagerVPN.h" G_BEGIN_DECLS @@ -39,11 +39,11 @@ G_BEGIN_DECLS #define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass)) typedef struct { - NMObject parent; + NMActiveConnection parent; } NMVPNConnection; typedef struct { - NMObjectClass parent; + NMActiveConnectionClass parent; /* Signals */ void (*state_changed) (NMVPNConnection *connection, @@ -53,16 +53,11 @@ typedef struct { GType nm_vpn_connection_get_type (void); +GObject * nm_vpn_connection_new (DBusGConnection *dbus_connection, const char *path); -NMVPNConnection * nm_vpn_connection_new (DBusGConnection *dbus_connection, - const char *path); - -const char * nm_vpn_connection_get_name (NMVPNConnection *vpn); NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *vpn); const char * nm_vpn_connection_get_banner (NMVPNConnection *vpn); -void nm_vpn_connection_disconnect (NMVPNConnection *vpn); - G_END_DECLS #endif /* NM_VPN_CONNECTION_H */ diff --git a/libnm-glib/nm-vpn-manager.c b/libnm-glib/nm-vpn-manager.c deleted file mode 100644 index 2c57687884..0000000000 --- a/libnm-glib/nm-vpn-manager.c +++ /dev/null @@ -1,136 +0,0 @@ -/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ - -#include -#include -#include "nm-vpn-manager.h" -#include "nm-marshal.h" - -#include "nm-vpn-manager-bindings.h" - -G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, NM_TYPE_OBJECT) - -#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate)) - -typedef struct { - DBusGProxy *manager_proxy; -} NMVPNManagerPrivate; - -NMVPNManager * -nm_vpn_manager_new (void) -{ - DBusGConnection *connection; - GError *err = NULL; - - connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err); - if (!connection) { - g_warning ("Couldn't connect to system bus: %s", err->message); - g_error_free (err); - return NULL; - } - - return (NMVPNManager *) g_object_new (NM_TYPE_VPN_MANAGER, - NM_OBJECT_DBUS_CONNECTION, connection, - NM_OBJECT_DBUS_PATH, NM_DBUS_PATH_VPN, - NULL); - -} - -NMVPNConnection * -nm_vpn_manager_connect (NMVPNManager *manager, - const char *connection_type, - const char *connection_path, - NMDevice *device) -{ - char *vpn_connection = NULL; - GError *err = NULL; - - g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); - g_return_val_if_fail (connection_type != NULL, NULL); - g_return_val_if_fail (connection_path, NULL); - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - - if (!org_freedesktop_NetworkManager_VPN_Manager_connect (NM_VPN_MANAGER_GET_PRIVATE (manager)->manager_proxy, - connection_type, - connection_path, - nm_object_get_path (NM_OBJECT (device)), - &vpn_connection, - &err)) { - g_warning ("Error in VPN Connect: %s", err->message); - g_error_free (err); - return NULL; - } - - return nm_vpn_connection_new (nm_object_get_connection (NM_OBJECT (manager)), vpn_connection); -} - -GSList * -nm_vpn_manager_get_connections (NMVPNManager *manager) -{ - GPtrArray *array = NULL; - GSList *list = NULL; - DBusGConnection *dbus_connection; - int i; - GError *err = NULL; - - g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); - - if (!org_freedesktop_NetworkManager_VPN_Manager_list_connections (NM_VPN_MANAGER_GET_PRIVATE (manager)->manager_proxy, - &array, &err)) { - g_warning ("Error in getting VPN connections: %s", err->message); - g_error_free (err); - return NULL; - } - - dbus_connection = nm_object_get_connection (NM_OBJECT (manager)); - - for (i = 0; i < array->len; i++) - list = g_slist_prepend (list, nm_vpn_connection_new (dbus_connection, (char *) g_ptr_array_index (array, i))); - - return list; -} - -/*****************************************************************************/ - -static void -nm_vpn_manager_init (NMVPNManager *manager) -{ -} - -static GObject* -constructor (GType type, - guint n_construct_params, - GObjectConstructParam *construct_params) -{ - NMObject *object; - - object = (NMObject *) G_OBJECT_CLASS (nm_vpn_manager_parent_class)->constructor (type, - n_construct_params, - construct_params); - if (!object) - return NULL; - - NM_VPN_MANAGER_GET_PRIVATE (object)->manager_proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object), - NM_DBUS_SERVICE, - nm_object_get_path (object), - NM_DBUS_INTERFACE_VPN); - return G_OBJECT (object); -} - -static void -finalize (GObject *object) -{ - g_object_unref (NM_VPN_MANAGER_GET_PRIVATE (object)->manager_proxy); - G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object); -} - -static void -nm_vpn_manager_class_init (NMVPNManagerClass *manager_class) -{ - GObjectClass *object_class = G_OBJECT_CLASS (manager_class); - - g_type_class_add_private (manager_class, sizeof (NMVPNManagerPrivate)); - - /* virtual methods */ - object_class->constructor = constructor; - object_class->finalize = finalize; -} diff --git a/libnm-glib/nm-vpn-manager.h b/libnm-glib/nm-vpn-manager.h deleted file mode 100644 index 50797b4c90..0000000000 --- a/libnm-glib/nm-vpn-manager.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */ - -#ifndef NM_VPN_MANAGER_H -#define NM_VPN_MANAGER_H 1 - -#include -#include -#include -#include -#include -#include "nm-object.h" -#include "nm-device.h" -#include "nm-connection.h" -#include "nm-vpn-connection.h" - -G_BEGIN_DECLS - -#define NM_TYPE_VPN_MANAGER (nm_vpn_manager_get_type ()) -#define NM_VPN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVPNManager)) -#define NM_VPN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_MANAGER, NMVPNManagerClass)) -#define NM_IS_VPN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_MANAGER)) -#define NM_IS_VPN_MANAGER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_MANAGER)) -#define NM_VPN_MANAGER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_MANAGER, NMVPNManagerClass)) - -typedef struct { - NMObject parent; -} NMVPNManager; - -typedef struct { - NMObjectClass parent; -} NMVPNManagerClass; - -GType nm_vpn_manager_get_type (void); - - -NMVPNManager *nm_vpn_manager_new (void); -NMVPNConnection *nm_vpn_manager_connect (NMVPNManager *manager, - const char *connection_type, - const char *connection_path, - NMDevice *device); - -GSList *nm_vpn_manager_get_connections (NMVPNManager *manager); - -G_END_DECLS - -#endif /* NM_MANAGER_H */ diff --git a/src/Makefile.am b/src/Makefile.am index f2eddd7008..cdda0feb6e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -38,6 +38,8 @@ NetworkManager_SOURCES = \ nm-hal-manager.h \ nm-ip4-config.c \ nm-ip4-config.h \ + nm-active-connection.h \ + nm-active-connection.c \ NetworkManager.c \ NetworkManagerPolicy.c \ NetworkManagerPolicy.h \ diff --git a/src/NetworkManager.c b/src/NetworkManager.c index 465d553066..7c46cdff6d 100644 --- a/src/NetworkManager.c +++ b/src/NetworkManager.c @@ -303,6 +303,12 @@ main (int argc, char *argv[]) /* Initialize our DBus service & connection */ dbus_mgr = nm_dbus_manager_get (); + vpn_manager = nm_vpn_manager_get (); + if (!vpn_manager) { + nm_warning ("Failed to start the VPN manager."); + goto done; + } + manager = nm_manager_new (); if (manager == NULL) { nm_error ("Failed to initialize the network manager."); @@ -322,12 +328,6 @@ main (int argc, char *argv[]) goto done; } - vpn_manager = nm_vpn_manager_new (manager); - if (!vpn_manager) { - nm_warning ("Failed to start the VPN manager."); - goto done; - } - named_mgr = nm_named_manager_get (); if (!named_mgr) { nm_warning ("Failed to start the named manager."); @@ -354,9 +354,6 @@ main (int argc, char *argv[]) g_main_loop_run (main_loop); done: - if (vpn_manager) - g_object_unref (vpn_manager); - if (hal_manager) nm_hal_manager_destroy (hal_manager); @@ -366,6 +363,9 @@ done: if (manager) g_object_unref (manager); + if (vpn_manager) + g_object_unref (vpn_manager); + if (sup_mgr) g_object_unref (sup_mgr); diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index 7e3171492b..22d3f3d2f6 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -214,17 +214,22 @@ auto_activate_device (gpointer user_data) best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object); if (best_connection) { GError *error = NULL; + const char *device_path; - if (!nm_manager_activate_device (policy->manager, - data->device, - best_connection, - specific_object, - FALSE, - &error)) { - nm_warning ("Failed to automatically activate device %s: (%d) %s", - nm_device_get_iface (data->device), - error->code, - error->message); + device_path = nm_device_get_udi (data->device); + if (!nm_manager_activate_connection (policy->manager, + best_connection, + specific_object, + device_path, + FALSE, + &error)) { + NMSettingConnection *s_con; + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (best_connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + nm_warning ("Connection '%s' auto-activation failed: (%d) %s", + s_con->id, error->code, error->message); g_error_free (error); } } @@ -476,23 +481,30 @@ connection_removed (NMManager *manager, NMConnectionScope scope, gpointer user_data) { - GSList *iter; + NMSettingConnection *s_con; + GPtrArray *list; + int i; - /* If the connection just removed was active, deactive it */ - for (iter = nm_manager_get_devices (manager); iter; iter = g_slist_next (iter)) { - NMDevice *device = NM_DEVICE (iter->data); - NMActRequest *req = nm_device_get_act_request (device); - NMConnection *dev_connection; + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + if (!s_con) + return; - if (!req) - continue; + list = nm_manager_get_active_connections_by_connection (manager, connection); + if (!list) + return; - dev_connection = nm_act_request_get_connection (req); - if (dev_connection == connection) { - nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); - schedule_activate_check ((NMPolicy *) user_data, device); + for (i = 0; i < list->len; i++) { + char *path = g_ptr_array_index (list, i); + GError *error = NULL; + + if (!nm_manager_deactivate_connection (manager, path, &error)) { + nm_warning ("Connection '%s' disappeared, but error deactivating it: (%d) %s", + s_con->id, error->code, error->message); + g_error_free (error); } + g_free (path); } + g_ptr_array_free (list, TRUE); } NMPolicy * diff --git a/src/marshallers/nm-marshal.list b/src/marshallers/nm-marshal.list index e6443022ba..8370d4dac4 100644 --- a/src/marshallers/nm-marshal.list +++ b/src/marshallers/nm-marshal.list @@ -8,3 +8,5 @@ VOID:UINT,UINT VOID:STRING,STRING VOID:STRING,UCHAR VOID:STRING,OBJECT +VOID:OBJECT,UINT,UINT + diff --git a/src/nm-activation-request.c b/src/nm-activation-request.c index 1d4d7259b7..02e9817f0e 100644 --- a/src/nm-activation-request.c +++ b/src/nm-activation-request.c @@ -30,7 +30,7 @@ #include "nm-dbus-manager.h" #include "nm-device.h" #include "nm-properties-changed-signal.h" -#include "nm-active-connection-glue.h" +#include "nm-active-connection.h" #include "nm-manager.h" /* FIXME! */ @@ -69,6 +69,7 @@ enum { PROP_SHARED_SERVICE_NAME, PROP_SHARED_CONNECTION, PROP_DEVICES, + PROP_VPN, LAST_PROP }; @@ -82,8 +83,6 @@ nm_act_request_new (NMConnection *connection, { GObject *object; NMActRequestPrivate *priv; - DBusGConnection *g_connection; - static guint32 counter = 0; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); g_return_val_if_fail (NM_DEVICE (device), NULL); @@ -100,16 +99,22 @@ nm_act_request_new (NMConnection *connection, priv->device = NM_DEVICE (device); priv->user_requested = user_requested; - g_connection = nm_dbus_manager_get_connection (nm_dbus_manager_get ()); - priv->ac_path = g_strdup_printf (NM_DBUS_PATH "/ActiveConnection/%d", counter++); - dbus_g_connection_register_g_object (g_connection, priv->ac_path, object); - return NM_ACT_REQUEST (object); } static void nm_act_request_init (NMActRequest *req) { + NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req); + NMDBusManager *dbus_mgr; + + priv->ac_path = nm_active_connection_get_next_object_path (); + + dbus_mgr = nm_dbus_manager_get (); + dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr), + priv->ac_path, + G_OBJECT (req)); + g_object_unref (dbus_mgr); } static void @@ -152,27 +157,6 @@ finalize (GObject *object) G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object); } -static void -scope_to_value (NMConnection *connection, GValue *value) -{ - if (!connection) { - g_value_set_string (value, ""); - return; - } - - switch (nm_connection_get_scope (connection)) { - case NM_CONNECTION_SCOPE_SYSTEM: - g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS); - break; - case NM_CONNECTION_SCOPE_USER: - g_value_set_string (value, NM_DBUS_SERVICE_USER_SETTINGS); - break; - default: - g_warning ("%s: unknown connection scope!", __func__); - break; - } -} - static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) @@ -182,7 +166,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_SERVICE_NAME: - scope_to_value (priv->connection, value); + nm_active_connection_scope_to_value (priv->connection, value); break; case PROP_CONNECTION: g_value_set_boxed (value, nm_connection_get_path (priv->connection)); @@ -194,7 +178,7 @@ get_property (GObject *object, guint prop_id, g_value_set_boxed (value, "/"); break; case PROP_SHARED_SERVICE_NAME: - scope_to_value (priv->shared, value); + nm_active_connection_scope_to_value (priv->shared, value); break; case PROP_SHARED_CONNECTION: if (!priv->shared) { @@ -208,6 +192,9 @@ get_property (GObject *object, guint prop_id, g_ptr_array_add (devices, g_strdup (nm_device_get_udi (priv->device))); g_value_take_boxed (value, devices); break; + case PROP_VPN: + g_value_set_boolean (value, FALSE); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -269,6 +256,13 @@ nm_act_request_class_init (NMActRequestClass *req_class) "Devices", dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_VPN, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, + "VPN", + "Is a VPN connection", + FALSE, + G_PARAM_READABLE)); /* Signals */ signals[CONNECTION_SECRETS_UPDATED] = @@ -295,8 +289,7 @@ nm_act_request_class_init (NMActRequestClass *req_class) nm_properties_changed_signal_new (object_class, G_STRUCT_OFFSET (NMActRequestClass, properties_changed)); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (req_class), - &dbus_glib_nm_active_connection_object_info); + nm_active_connection_install_type_info (object_class); } typedef struct GetSecretsInfo { diff --git a/src/nm-activation-request.h b/src/nm-activation-request.h index 2ed7427de0..b7f43e7073 100644 --- a/src/nm-activation-request.h +++ b/src/nm-activation-request.h @@ -25,6 +25,7 @@ #include #include #include "nm-connection.h" +#include "nm-active-connection.h" #define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ()) #define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest)) @@ -33,13 +34,6 @@ #define NM_IS_ACT_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ACT_REQUEST)) #define NM_ACT_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACT_REQUEST, NMActRequestClass)) -#define NM_ACTIVE_CONNECTION_SERVICE_NAME "service-name" -#define NM_ACTIVE_CONNECTION_CONNECTION "connection" -#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object" -#define NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME "shared-service-name" -#define NM_ACTIVE_CONNECTION_SHARED_CONNECTION "shared-connection" -#define NM_ACTIVE_CONNECTION_DEVICES "devices" - typedef struct { GObject parent; } NMActRequest; diff --git a/src/nm-active-connection.c b/src/nm-active-connection.c new file mode 100644 index 0000000000..dc63426751 --- /dev/null +++ b/src/nm-active-connection.c @@ -0,0 +1,63 @@ +/* NetworkManager -- Network link manager + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#include +#include "nm-active-connection.h" +#include "NetworkManager.h" +#include "nm-active-connection-glue.h" + +char * +nm_active_connection_get_next_object_path (void) +{ + static guint32 counter = 0; + + return g_strdup_printf (NM_DBUS_PATH "/ActiveConnection/%d", counter++); +} + +void +nm_active_connection_install_type_info (GObjectClass *klass) +{ + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), + &dbus_glib_nm_active_connection_object_info); +} + +void +nm_active_connection_scope_to_value (NMConnection *connection, GValue *value) +{ + if (!connection) { + g_value_set_string (value, ""); + return; + } + + switch (nm_connection_get_scope (connection)) { + case NM_CONNECTION_SCOPE_SYSTEM: + g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS); + break; + case NM_CONNECTION_SCOPE_USER: + g_value_set_string (value, NM_DBUS_SERVICE_USER_SETTINGS); + break; + default: + g_warning ("%s: unknown connection scope!", __func__); + break; + } +} + + diff --git a/src/nm-active-connection.h b/src/nm-active-connection.h new file mode 100644 index 0000000000..699836b434 --- /dev/null +++ b/src/nm-active-connection.h @@ -0,0 +1,42 @@ +/* NetworkManager -- Network link manager + * + * Dan Williams + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * (C) Copyright 2008 Red Hat, Inc. + */ + +#ifndef NM_ACTIVE_CONNECTION_H +#define NM_ACTIVE_CONNECTION_H + +#include +#include "nm-connection.h" + +#define NM_ACTIVE_CONNECTION_SERVICE_NAME "service-name" +#define NM_ACTIVE_CONNECTION_CONNECTION "connection" +#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object" +#define NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME "shared-service-name" +#define NM_ACTIVE_CONNECTION_SHARED_CONNECTION "shared-connection" +#define NM_ACTIVE_CONNECTION_DEVICES "devices" +#define NM_ACTIVE_CONNECTION_VPN "vpn" + +char *nm_active_connection_get_next_object_path (void); + +void nm_active_connection_install_type_info (GObjectClass *klass); + +void nm_active_connection_scope_to_value (NMConnection *connection, GValue *value); + +#endif /* NM_ACTIVE_CONNECTION_H */ diff --git a/src/nm-manager.c b/src/nm-manager.c index 9982f2f702..e1595ec161 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -6,12 +6,14 @@ #include "nm-manager.h" #include "nm-utils.h" #include "nm-dbus-manager.h" +#include "nm-vpn-manager.h" #include "nm-device-interface.h" #include "nm-device-802-11-wireless.h" #include "NetworkManagerSystem.h" #include "nm-properties-changed-signal.h" #include "nm-setting-connection.h" #include "nm-setting-wireless.h" +#include "nm-setting-vpn.h" #include "nm-marshal.h" static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err); @@ -49,10 +51,10 @@ static void connection_added_default_handler (NMManager *manager, typedef struct { DBusGMethodInvocation *context; - NMDevice *device; NMConnectionScope scope; char *connection_path; char *specific_object_path; + char *device_path; guint timeout_id; } PendingConnectionInfo; @@ -74,6 +76,11 @@ typedef struct { gboolean sleeping; guint poke_id; + + NMVPNManager *vpn_manager; + guint vpn_manager_id; + + gboolean disposed; } NMManagerPrivate; #define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, NMManagerPrivate)) @@ -159,10 +166,21 @@ nm_manager_error_get_type (void) return etype; } +static void +vpn_manager_connection_deactivated_cb (NMVPNManager *manager, + NMVPNConnection *vpn, + NMVPNConnectionState state, + NMVPNConnectionStateReason reason, + gpointer user_data) +{ + g_object_notify (G_OBJECT (user_data), NM_MANAGER_ACTIVE_CONNECTIONS); +} + static void nm_manager_init (NMManager *manager) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + guint id; priv->wireless_enabled = TRUE; priv->wireless_hw_enabled = TRUE; @@ -180,6 +198,11 @@ nm_manager_init (NMManager *manager) g_str_equal, g_free, g_object_unref); + + priv->vpn_manager = nm_vpn_manager_get (); + id = g_signal_connect (G_OBJECT (priv->vpn_manager), "connection-deactivated", + G_CALLBACK (vpn_manager_connection_deactivated_cb), manager); + priv->vpn_manager_id = id; } NMState @@ -239,17 +262,23 @@ pending_connection_info_destroy (PendingConnectionInfo *info) g_free (info->connection_path); g_free (info->specific_object_path); - g_object_unref (info->device); + g_free (info->device_path); g_slice_free (PendingConnectionInfo, info); } static void -finalize (GObject *object) +dispose (GObject *object) { NMManager *manager = NM_MANAGER (object); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + if (priv->disposed) { + G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object); + return; + } + priv->disposed = TRUE; + pending_connection_info_destroy (priv->pending_connection_info); priv->pending_connection_info = NULL; @@ -269,10 +298,15 @@ finalize (GObject *object) priv->poke_id = 0; } - if (priv->dbus_mgr) - g_object_unref (priv->dbus_mgr); + if (priv->vpn_manager_id) { + g_source_remove (priv->vpn_manager_id); + priv->vpn_manager_id = 0; + } + g_object_unref (priv->vpn_manager); - G_OBJECT_CLASS (nm_manager_parent_class)->finalize (object); + g_object_unref (priv->dbus_mgr); + + G_OBJECT_CLASS (nm_manager_parent_class)->dispose (object); } static void @@ -289,15 +323,49 @@ set_property (GObject *object, guint prop_id, } } +static GPtrArray * +get_active_connections (NMManager *manager, NMConnection *filter) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + NMVPNManager *vpn_manager; + GPtrArray *active; + GSList *iter; + + active = g_ptr_array_sized_new (3); + + /* Add active device connections */ + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMActRequest *req; + const char *path; + + req = nm_device_get_act_request (NM_DEVICE (iter->data)); + if (!req) + continue; + + if (!filter || (nm_act_request_get_connection (req) == filter)) { + path = nm_act_request_get_active_connection_path (req); + g_ptr_array_add (active, g_strdup (path)); + } + } + + /* Add active VPN connections */ + vpn_manager = nm_vpn_manager_get (); + nm_vpn_manager_add_active_connections (vpn_manager, filter, active); + g_object_unref (vpn_manager); + + return active; +} + static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (object); + NMManager *self = NM_MANAGER (object); + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self); switch (prop_id) { case PROP_STATE: - nm_manager_update_state (NM_MANAGER (object)); + nm_manager_update_state (self); g_value_set_uint (value, priv->state); break; case PROP_WIRELESS_ENABLED: @@ -306,25 +374,9 @@ get_property (GObject *object, guint prop_id, case PROP_WIRELESS_HARDWARE_ENABLED: g_value_set_boolean (value, priv->wireless_hw_enabled); break; - case PROP_ACTIVE_CONNECTIONS: { - GPtrArray *active; - GSList *iter; - - active = g_ptr_array_sized_new (2); - for (iter = priv->devices; iter; iter = g_slist_next (iter)) { - NMActRequest *req; - const char *path; - - req = nm_device_get_act_request (NM_DEVICE (iter->data)); - if (!req) - continue; - - path = nm_act_request_get_active_connection_path (req); - g_ptr_array_add (active, g_strdup (path)); - } - g_value_take_boxed (value, active); + case PROP_ACTIVE_CONNECTIONS: + g_value_take_boxed (value, get_active_connections (self, NULL)); break; - } default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -343,7 +395,7 @@ nm_manager_class_init (NMManagerClass *manager_class) object_class->set_property = set_property; object_class->get_property = get_property; - object_class->finalize = finalize; + object_class->dispose = dispose; /* properties */ g_object_class_install_property @@ -1261,6 +1313,37 @@ nm_manager_get_device_by_udi (NMManager *manager, const char *udi) return NULL; } +static NMActRequest * +nm_manager_get_act_request_by_path (NMManager *manager, + const char *path, + NMDevice **device) +{ + NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + GSList *iter; + + g_return_val_if_fail (manager != NULL, NULL); + g_return_val_if_fail (path != NULL, NULL); + g_return_val_if_fail (device != NULL, NULL); + g_return_val_if_fail (*device == NULL, NULL); + + for (iter = priv->devices; iter; iter = g_slist_next (iter)) { + NMActRequest *req; + const char *ac_path; + + req = nm_device_get_act_request (NM_DEVICE (iter->data)); + if (!req) + continue; + + ac_path = nm_act_request_get_active_connection_path (req); + if (!strcmp (path, ac_path)) { + *device = NM_DEVICE (iter->data); + return req; + } + } + + return NULL; +} + static gboolean check_connection_allowed (NMManager *manager, NMDeviceInterface *dev_iface, @@ -1296,13 +1379,13 @@ check_connection_allowed (NMManager *manager, return allowed; } -const char * -nm_manager_activate_device (NMManager *manager, - NMDevice *device, - NMConnection *connection, - const char *specific_object, - gboolean user_requested, - GError **error) +static const char * +internal_activate_device (NMManager *manager, + NMDevice *device, + NMConnection *connection, + const char *specific_object, + gboolean user_requested, + GError **error) { NMActRequest *req; NMDeviceInterface *dev_iface; @@ -1348,16 +1431,11 @@ wait_for_connection_expired (gpointer data) g_return_val_if_fail (info != NULL, FALSE); - nm_info ("%s: didn't receive connection details soon enough for activation.", - nm_device_get_iface (info->device)); - g_set_error (&error, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, "%s", "Connection was not provided by any settings service"); - nm_warning ("Failed to activate device %s: (%d) %s", - nm_device_get_iface (info->device), - error->code, - error->message); + nm_warning ("Connection (%d) %s failed to activate (timeout): (%d) %s", + info->scope, info->connection_path, error->code, error->message); dbus_g_method_return_error (info->context, error); g_error_free (error); @@ -1368,6 +1446,74 @@ wait_for_connection_expired (gpointer data) return FALSE; } +const char * +nm_manager_activate_connection (NMManager *manager, + NMConnection *connection, + const char *specific_object, + const char *device_path, + gboolean user_requested, + GError **error) +{ + NMDevice *device = NULL; + char *path = NULL; + NMSettingConnection *s_con; + + g_return_val_if_fail (manager != NULL, NULL); + g_return_val_if_fail (connection != NULL, NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (*error == NULL, NULL); + + s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); + g_assert (s_con); + + if (!strcmp (s_con->type, NM_SETTING_VPN_SETTING_NAME)) { + NMActRequest *req; + NMVPNManager *vpn_manager; + + /* VPN connection */ + req = nm_manager_get_act_request_by_path (manager, specific_object, &device); + if (!req) { + g_set_error (error, + NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, + "%s", "Base connection for VPN connection not active."); + return NULL; + } + + if (!device) { + g_set_error (error, + NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "%s", "Source connection had no active device."); + return NULL; + } + + vpn_manager = nm_vpn_manager_get (); + path = (char *) nm_vpn_manager_activate_connection (vpn_manager, + connection, + req, + device, + error); + g_object_unref (vpn_manager); + } else { + /* Device-based connection */ + device = nm_manager_get_device_by_path (manager, device_path); + if (!device) { + g_set_error (error, + NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, + "%s", "Device not found"); + return NULL; + } + + path = (char *) internal_activate_device (manager, + device, + connection, + specific_object, + user_requested, + error); + } + + return path; +} + static void connection_added_default_handler (NMManager *manager, NMConnection *connection, @@ -1390,21 +1536,19 @@ connection_added_default_handler (NMManager *manager, /* Will destroy below; can't be valid during the initial activation start */ priv->pending_connection_info = NULL; - path = nm_manager_activate_device (manager, - info->device, - connection, - info->specific_object_path, - TRUE, - &error); + path = nm_manager_activate_connection (manager, + connection, + info->specific_object_path, + info->device_path, + TRUE, + &error); if (path) { dbus_g_method_return (info->context, path); g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); } else { dbus_g_method_return_error (info->context, error); - nm_warning ("Failed to activate device %s: (%d) %s", - nm_device_get_iface (info->device), - error->code, - error->message); + nm_warning ("Connection (%d) %s failed to activate: (%d) %s", + scope, info->connection_path, error->code, error->message); g_error_free (error); } @@ -1419,21 +1563,11 @@ impl_manager_activate_connection (NMManager *manager, const char *specific_object_path, DBusGMethodInvocation *context) { - NMDevice *device; - NMConnectionScope scope; + NMConnectionScope scope = NM_CONNECTION_SCOPE_UNKNOWN; NMConnection *connection; GError *error = NULL; char *real_sop = NULL; - - device = nm_manager_get_device_by_path (manager, device_path); - if (!device) { - g_set_error (&error, - NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_DEVICE, - "%s", "Device not found"); - goto err; - } - - nm_info ("User request for activation of %s.", nm_device_get_iface (device)); + char *path = NULL; if (!strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS)) scope = NM_CONNECTION_SCOPE_USER; @@ -1452,14 +1586,12 @@ impl_manager_activate_connection (NMManager *manager, connection = nm_manager_get_connection_by_object_path (manager, scope, connection_path); if (connection) { - const char *path; - - path = nm_manager_activate_device (manager, - device, - connection, - real_sop, - TRUE, - &error); + path = (char *) nm_manager_activate_connection (manager, + connection, + real_sop, + device_path, + TRUE, + &error); if (path) { dbus_g_method_return (context, path); g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); @@ -1479,7 +1611,7 @@ impl_manager_activate_connection (NMManager *manager, info = g_slice_new0 (PendingConnectionInfo); info->context = context; - info->device = g_object_ref (device); + info->device_path = g_strdup (device_path); info->scope = scope; info->connection_path = g_strdup (connection_path); info->specific_object_path = g_strdup (real_sop); @@ -1492,24 +1624,25 @@ impl_manager_activate_connection (NMManager *manager, err: if (error) { dbus_g_method_return_error (context, error); - nm_warning ("Failed to activate device %s: (%d) %s", - nm_device_get_iface (device), - error->code, - error->message); + nm_warning ("Connection (%d) %s failed to activate: (%d) %s", + scope, connection_path, error->code, error->message); g_error_free (error); } g_free (real_sop); } -static gboolean -impl_manager_deactivate_connection (NMManager *manager, - const char *connection_path, - GError **error) +gboolean +nm_manager_deactivate_connection (NMManager *manager, + const char *connection_path, + GError **error) { NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); + NMVPNManager *vpn_manager; GSList *iter; + gboolean success = FALSE; + /* Check for device connections first */ for (iter = priv->devices; iter; iter = g_slist_next (iter)) { NMDevice *device = NM_DEVICE (iter->data); NMActRequest *req; @@ -1521,15 +1654,33 @@ impl_manager_deactivate_connection (NMManager *manager, if (!strcmp (connection_path, nm_act_request_get_active_connection_path (req))) { nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); - return TRUE; + success = TRUE; + goto done; } } - g_set_error (error, - NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, - "%s", "The connection was not active."); - - return FALSE; + /* Check for VPN connections next */ + vpn_manager = nm_vpn_manager_get (); + if (nm_vpn_manager_deactivate_connection (vpn_manager, connection_path)) { + success = TRUE; + } else { + g_set_error (error, + NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, + "%s", "The connection was not active."); + } + g_object_unref (vpn_manager); + +done: + g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); + return success; +} + +static gboolean +impl_manager_deactivate_connection (NMManager *manager, + const char *connection_path, + GError **error) +{ + return nm_manager_deactivate_connection (manager, connection_path, error); } gboolean @@ -1611,23 +1762,6 @@ impl_manager_sleep (NMManager *manager, gboolean sleep, GError **err) return TRUE; } -NMDevice * -nm_manager_get_active_device (NMManager *manager) -{ - GSList *iter; - - g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); - - for (iter = nm_manager_get_devices (manager); iter; iter = iter->next) { - NMDevice *dev = NM_DEVICE (iter->data); - - if (nm_device_get_state (dev) == NM_DEVICE_STATE_ACTIVATED) - return dev; - } - - return NULL; -} - /* Legacy 0.6 compatibility interface */ static gboolean @@ -1732,3 +1866,10 @@ nm_manager_get_connection_by_object_path (NMManager *manager, return connection; } +GPtrArray * +nm_manager_get_active_connections_by_connection (NMManager *manager, + NMConnection *connection) +{ + return get_active_connections (manager, connection); +} + diff --git a/src/nm-manager.h b/src/nm-manager.h index 69627567a2..bf19a0043c 100644 --- a/src/nm-manager.h +++ b/src/nm-manager.h @@ -62,14 +62,16 @@ GSList *nm_manager_get_devices (NMManager *manager); NMDevice *nm_manager_get_device_by_path (NMManager *manager, const char *path); NMDevice *nm_manager_get_device_by_udi (NMManager *manager, const char *udi); -NMDevice *nm_manager_get_active_device (NMManager *manager); +const char * nm_manager_activate_connection (NMManager *manager, + NMConnection *connection, + const char *specific_object, + const char *device_path, + gboolean user_requested, + GError **error); -const char *nm_manager_activate_device (NMManager *manager, - NMDevice *device, - NMConnection *connection, - const char *specific_object, - gboolean user_requested, - GError **error); +gboolean nm_manager_deactivate_connection (NMManager *manager, + const char *connection_path, + GError **error); gboolean nm_manager_activation_pending (NMManager *manager); @@ -90,4 +92,7 @@ NMConnection * nm_manager_get_connection_by_object_path (NMManager *manager, NMConnectionScope scope, const char *path); +GPtrArray * nm_manager_get_active_connections_by_connection (NMManager *manager, + NMConnection *connection); + #endif /* NM_MANAGER_H */ diff --git a/src/vpn-manager/Makefile.am b/src/vpn-manager/Makefile.am index 5c4fa6a3f0..9b8b0a589f 100644 --- a/src/vpn-manager/Makefile.am +++ b/src/vpn-manager/Makefile.am @@ -28,9 +28,6 @@ libvpn_manager_la_LIBADD = \ $(top_builddir)/src/marshallers/libmarshallers.la \ $(top_builddir)/libnm-util/libnm-util.la -nm-vpn-manager-glue.h: $(top_srcdir)/introspection/nm-vpn-manager.xml - dbus-binding-tool --prefix=nm_vpn_manager --mode=glib-server --output=nm-vpn-manager-glue.h $(top_srcdir)/introspection/nm-vpn-manager.xml - nm-vpn-connection-glue.h: $(top_srcdir)/introspection/nm-vpn-connection.xml dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-server --output=nm-vpn-connection-glue.h $(top_srcdir)/introspection/nm-vpn-connection.xml @@ -39,7 +36,6 @@ nm-vpn-plugin-bindings.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml built_sources = \ - nm-vpn-manager-glue.h \ nm-vpn-connection-glue.h \ nm-vpn-plugin-bindings.h diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index b540b5bfb5..3a43b655b2 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -18,7 +18,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - * (C) Copyright 2005 Red Hat, Inc. + * (C) Copyright 2008 Red Hat, Inc. */ @@ -39,8 +39,8 @@ #include "nm-utils.h" #include "nm-vpn-plugin-bindings.h" #include "nm-marshal.h" - -static gboolean impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err); +#include "nm-active-connection.h" +#include "nm-properties-changed-signal.h" #define CONNECTION_GET_SECRETS_CALL_TAG "get-secrets-call" @@ -49,10 +49,13 @@ static gboolean impl_vpn_connection_disconnect (NMVPNConnection *connection, GEr G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT) typedef struct { + gboolean disposed; + NMConnection *connection; + NMActRequest *act_request; NMDevice *parent_dev; - char *object_path; - + char *ac_path; + NMVPNConnectionState state; gulong device_monitor; DBusGProxy *proxy; @@ -65,6 +68,7 @@ typedef struct { #define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate)) enum { + PROPERTIES_CHANGED, STATE_CHANGED, LAST_SIGNAL @@ -74,7 +78,13 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, - PROP_NAME, + PROP_SERVICE_NAME, + PROP_CONNECTION, + PROP_SPECIFIC_OBJECT, + PROP_SHARED_SERVICE_NAME, + PROP_SHARED_CONNECTION, + PROP_DEVICES, + PROP_VPN, PROP_STATE, PROP_BANNER, @@ -116,12 +126,14 @@ device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data) NMVPNConnection * nm_vpn_connection_new (NMConnection *connection, - NMDevice *parent_device) + NMActRequest *act_request, + NMDevice *parent_device) { NMVPNConnection *vpn_connection; NMVPNConnectionPrivate *priv; g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL); vpn_connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL); @@ -131,6 +143,7 @@ nm_vpn_connection_new (NMConnection *connection, priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection); priv->connection = g_object_ref (connection); + priv->act_request = g_object_ref (act_request); priv->parent_dev = g_object_ref (parent_device); priv->device_monitor = g_signal_connect (parent_device, "state-changed", @@ -167,24 +180,27 @@ plugin_state_changed (DBusGProxy *proxy, { NMVPNConnection *connection = NM_VPN_CONNECTION (user_data); - nm_debug ("plugin state changed: %d", state); + nm_info ("VPN plugin state changed: %d", state); - if (state == NM_VPN_SERVICE_STATE_STOPPED) { - switch (nm_vpn_connection_get_state (connection)) { - case NM_VPN_CONNECTION_STATE_CONNECT: - case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: - nm_vpn_connection_set_state (connection, - NM_VPN_CONNECTION_STATE_FAILED, - NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); - break; - case NM_VPN_CONNECTION_STATE_ACTIVATED: - nm_vpn_connection_set_state (connection, - NM_VPN_CONNECTION_STATE_DISCONNECTED, - NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); - break; - default: - break; - } + if (state != NM_VPN_SERVICE_STATE_STOPPED) + return; + + switch (nm_vpn_connection_get_state (connection)) { + case NM_VPN_CONNECTION_STATE_PREPARE: + case NM_VPN_CONNECTION_STATE_NEED_AUTH: + case NM_VPN_CONNECTION_STATE_CONNECT: + case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: + nm_vpn_connection_set_state (connection, + NM_VPN_CONNECTION_STATE_FAILED, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); + break; + case NM_VPN_CONNECTION_STATE_ACTIVATED: + nm_vpn_connection_set_state (connection, + NM_VPN_CONNECTION_STATE_DISCONNECTED, + NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); + break; + default: + break; } } @@ -431,11 +447,11 @@ nm_vpn_connection_activate (NMVPNConnection *connection) } const char * -nm_vpn_connection_get_object_path (NMVPNConnection *connection) +nm_vpn_connection_get_active_connection_path (NMVPNConnection *connection) { g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); - return NM_VPN_CONNECTION_GET_PRIVATE (connection)->object_path; + return NM_VPN_CONNECTION_GET_PRIVATE (connection)->ac_path; } const char * @@ -452,6 +468,14 @@ nm_vpn_connection_get_name (NMVPNConnection *connection) return setting->id; } +NMConnection * +nm_vpn_connection_get_connection (NMVPNConnection *connection) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL); + + return NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection; +} + NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *connection) { @@ -490,14 +514,6 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection, reason); } -static gboolean -impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err) -{ - nm_vpn_connection_disconnect (connection, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); - - return TRUE; -} - /******************************************************************************/ static void @@ -737,12 +753,15 @@ connection_state_changed (NMVPNConnection *connection, } if (priv->ip4_config) { + NMIP4Config *dev_ip4_config; + /* Remove attributes of the VPN's IP4 Config */ nm_system_vpn_device_unset_from_ip4_config (priv->parent_dev, priv->tundev, priv->ip4_config); /* Reset routes, nameservers, and domains of the currently active device */ - nm_device_set_ip4_config (priv->parent_dev, - NM_IP4_CONFIG (g_object_ref (nm_device_get_ip4_config (priv->parent_dev)))); + dev_ip4_config = nm_device_get_ip4_config (priv->parent_dev); + if (dev_ip4_config) + nm_device_set_ip4_config (priv->parent_dev, g_object_ref (dev_ip4_config)); } if (priv->banner) { @@ -760,23 +779,28 @@ nm_vpn_connection_init (NMVPNConnection *connection) { NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); NMDBusManager *dbus_mgr; - static guint32 counter = 0; priv->state = NM_VPN_CONNECTION_STATE_PREPARE; - priv->object_path = g_strdup_printf (NM_DBUS_PATH_VPN_CONNECTION "/%d", counter++); + priv->ac_path = nm_active_connection_get_next_object_path (); dbus_mgr = nm_dbus_manager_get (); dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr), - priv->object_path, + priv->ac_path, G_OBJECT (connection)); g_object_unref (dbus_mgr); } static void -finalize (GObject *object) +dispose (GObject *object) { NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + if (priv->disposed) { + G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object); + return; + } + priv->disposed = TRUE; + if (priv->parent_dev) { if (priv->device_monitor) g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor); @@ -784,11 +808,6 @@ finalize (GObject *object) g_object_unref (priv->parent_dev); } - if (priv->banner) - g_free (priv->banner); - - g_free (priv->tundev); - if (priv->ip4_config) g_object_unref (priv->ip4_config); @@ -800,7 +819,17 @@ finalize (GObject *object) g_object_unref (priv->connection); - g_free (priv->object_path); + G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object); +} + +static void +finalize (GObject *object) +{ + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); + + g_free (priv->banner); + g_free (priv->tundev); + g_free (priv->ac_path); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object); } @@ -809,18 +838,35 @@ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { - const char *tmp; + NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); switch (prop_id) { - case PROP_NAME: - g_value_set_string (value, nm_vpn_connection_get_name (NM_VPN_CONNECTION (object))); + case PROP_SERVICE_NAME: + nm_active_connection_scope_to_value (priv->connection, value); + break; + case PROP_CONNECTION: + g_value_set_boxed (value, nm_connection_get_path (priv->connection)); + break; + case PROP_SPECIFIC_OBJECT: + g_value_set_boxed (value, nm_act_request_get_active_connection_path (priv->act_request)); + break; + case PROP_SHARED_SERVICE_NAME: + g_value_set_string (value, ""); + break; + case PROP_SHARED_CONNECTION: + g_value_set_boxed (value, "/"); + break; + case PROP_DEVICES: + g_value_take_boxed (value, g_ptr_array_new ()); + break; + case PROP_VPN: + g_value_set_boolean (value, TRUE); break; case PROP_STATE: g_value_set_uint (value, nm_vpn_connection_get_state (NM_VPN_CONNECTION (object))); break; case PROP_BANNER: - tmp = nm_vpn_connection_get_banner (NM_VPN_CONNECTION (object)); - g_value_set_string (value, tmp ? tmp : ""); + g_value_set_string (value, priv->banner ? priv->banner : ""); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -838,16 +884,59 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) /* virtual methods */ connection_class->state_changed = connection_state_changed; object_class->get_property = get_property; + object_class->dispose = dispose; object_class->finalize = finalize; /* properties */ g_object_class_install_property - (object_class, PROP_NAME, - g_param_spec_string (NM_VPN_CONNECTION_NAME, - "Name", - "Connection name", - NULL, - G_PARAM_READABLE)); + (object_class, PROP_SERVICE_NAME, + g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME, + "Service name", + "Service name", + NULL, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_CONNECTION, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION, + "Connection", + "Connection", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_SPECIFIC_OBJECT, + g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, + "Specific object", + "Specific object", + NULL, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_SHARED_SERVICE_NAME, + g_param_spec_string (NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME, + "Shared service name", + "Shared service name", + NULL, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_SHARED_CONNECTION, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_SHARED_CONNECTION, + "Shared connection", + "Shared connection", + DBUS_TYPE_G_OBJECT_PATH, + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_DEVICES, + g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES, + "Devices", + "Devices", + dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), + G_PARAM_READABLE)); + g_object_class_install_property + (object_class, PROP_VPN, + g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN, + "VPN", + "Is a VPN connection", + TRUE, + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_STATE, @@ -878,6 +967,11 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class) G_TYPE_NONE, 2, G_TYPE_UINT, G_TYPE_UINT); - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (connection_class), - &dbus_glib_nm_vpn_connection_object_info); + signals[PROPERTIES_CHANGED] = + nm_properties_changed_signal_new (object_class, + G_STRUCT_OFFSET (NMVPNConnectionClass, properties_changed)); + + dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (object_class), + &dbus_glib_nm_vpn_connection_object_info); } + diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index f3b4f9d3fb..dc3e004e51 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -27,6 +27,7 @@ #include #include "NetworkManagerVPN.h" #include "nm-device.h" +#include "nm-activation-request.h" #define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) #define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection)) @@ -35,7 +36,6 @@ #define NM_IS_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_CONNECTION)) #define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass)) -#define NM_VPN_CONNECTION_NAME "name" #define NM_VPN_CONNECTION_STATE "state" #define NM_VPN_CONNECTION_BANNER "banner" @@ -50,16 +50,20 @@ typedef struct { void (*state_changed) (NMVPNConnection *connection, NMVPNConnectionState state, NMVPNConnectionStateReason reason); + + void (*properties_changed) (NMVPNConnection *connection, GHashTable *properties); } NMVPNConnectionClass; GType nm_vpn_connection_get_type (void); -NMVPNConnection *nm_vpn_connection_new (NMConnection *connection, - NMDevice *parent_device); +NMVPNConnection * nm_vpn_connection_new (NMConnection *connection, + NMActRequest *act_request, + NMDevice *parent_device); void nm_vpn_connection_activate (NMVPNConnection *connection); -const char *nm_vpn_connection_get_object_path (NMVPNConnection *connection); -const char *nm_vpn_connection_get_name (NMVPNConnection *connection); +NMConnection * nm_vpn_connection_get_connection (NMVPNConnection *connection); +const char * nm_vpn_connection_get_active_connection_path (NMVPNConnection *connection); +const char * nm_vpn_connection_get_name (NMVPNConnection *connection); NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *connection); const char * nm_vpn_connection_get_banner (NMVPNConnection *connection); void nm_vpn_connection_fail (NMVPNConnection *connection, @@ -67,5 +71,4 @@ void nm_vpn_connection_fail (NMVPNConnection *connect void nm_vpn_connection_disconnect (NMVPNConnection *connection, NMVPNConnectionStateReason reason); - #endif /* NM_VPN_CONNECTION_H */ diff --git a/src/vpn-manager/nm-vpn-manager.c b/src/vpn-manager/nm-vpn-manager.c index 495d514de9..e3b5fa64b7 100644 --- a/src/vpn-manager/nm-vpn-manager.c +++ b/src/vpn-manager/nm-vpn-manager.c @@ -6,33 +6,70 @@ #include "nm-vpn-service.h" #include "nm-vpn-connection.h" #include "nm-setting-vpn.h" -#include "nm-manager.h" #include "nm-dbus-manager.h" #include "NetworkManagerVPN.h" #include "nm-utils.h" - -static gboolean impl_vpn_manager_connect (NMVPNManager *manager, - const char *connection_type, - const char *connection_path, - const char *device_path, - char **connection, - GError **err); - -static gboolean impl_vpn_manager_get_connections (NMVPNManager *manager, - GPtrArray **connections, - GError **err); - -#include "nm-vpn-manager-glue.h" +#include "nm-marshal.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 { - NMManager *nm_manager; - NMDBusManager *dbus_mgr; GSList *services; } NMVPNManagerPrivate; -#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate)) +enum { + CONNECTION_DEACTIVATED, + + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +typedef enum +{ + NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE = 0, + NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, + NM_VPN_MANAGER_ERROR_SERVICE_INVALID, +} NMVPNManagerError; + +#define NM_VPN_MANAGER_ERROR (nm_vpn_manager_error_quark ()) +#define NM_TYPE_VPN_MANAGER_ERROR (nm_vpn_manager_error_get_type ()) + +static GQuark +nm_vpn_manager_error_quark (void) +{ + static GQuark quark = 0; + if (!quark) + quark = g_quark_from_static_string ("nm-vpn-manager-error"); + return quark; +} + +/* This should really be standard. */ +#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } + +static GType +nm_vpn_manager_error_get_type (void) +{ + static GType etype = 0; + + if (etype == 0) { + static const GEnumValue values[] = { + /* The base device for the VPN connection is not active. */ + ENUM_ENTRY (NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, "BaseDeviceNotActive"), + /* The requested VPN connection was invalid. */ + ENUM_ENTRY (NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, "ConnectionInvalid"), + /* The VPN service required by this VPN connection did not exist or was invalid. */ + ENUM_ENTRY (NM_VPN_MANAGER_ERROR_SERVICE_INVALID, "ServiceInvalid"), + { 0, 0, 0 } + }; + etype = g_enum_register_static ("NMVPNManagerError", values); + } + return etype; +} + + static NMVPNService * nm_vpn_manager_get_service (NMVPNManager *manager, const char *service_name) @@ -66,24 +103,87 @@ nm_vpn_manager_add_service (NMVPNManager *manager, NMVPNService *service) g_object_weak_ref (G_OBJECT (service), remove_service, manager); } -NMVPNConnection * -nm_vpn_manager_connect (NMVPNManager *manager, - NMConnection *connection, - NMDevice *device) +static NMVPNConnection * +find_active_vpn_connection_by_connection (NMVPNManager *manager, NMConnection *connection) { - NMSettingVPN *vpn_setting; - NMVPNService *service; + NMVPNManagerPrivate *priv; + GSList *iter; g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); - g_return_val_if_fail (NM_IS_DEVICE (device), NULL); - if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) + priv = NM_VPN_MANAGER_GET_PRIVATE (manager); + for (iter = priv->services; iter; iter = g_slist_next (iter)) { + GSList *connections, *elt; + + connections = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (iter->data)); + for (elt = connections; elt; elt = g_slist_next (elt)) { + NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data); + + if (nm_vpn_connection_get_connection (vpn) == connection) + return vpn; + } + } + return NULL; +} + +static void +connection_state_changed (NMVPNConnection *connection, + NMVPNConnectionState state, + NMVPNConnectionStateReason reason, + gpointer user_data) +{ + NMVPNManager *manager = NM_VPN_MANAGER (user_data); + + switch (state) { + case NM_VPN_CONNECTION_STATE_FAILED: + case NM_VPN_CONNECTION_STATE_DISCONNECTED: + g_signal_emit (manager, signals[CONNECTION_DEACTIVATED], 0, connection, state, reason); + break; + default: + break; + } +} + +const char * +nm_vpn_manager_activate_connection (NMVPNManager *manager, + NMConnection *connection, + NMActRequest *act_request, + NMDevice *device, + GError **error) +{ + NMSettingVPN *vpn_setting; + NMVPNService *service; + char *path = NULL; + NMVPNConnection *vpn; + + g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); + g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL); + g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (*error == NULL, NULL); + + if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) { + g_set_error (error, + NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, + "%s", "The base device for the VPN connection was not active."); return NULL; + } vpn_setting = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); - if (!vpn_setting) + if (!vpn_setting) { + g_set_error (error, + NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, + "%s", "The connection was not a VPN connection."); return NULL; + } + + vpn = find_active_vpn_connection_by_connection (manager, connection); + if (vpn) { + nm_vpn_connection_disconnect (vpn, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); + vpn = NULL; + } service = nm_vpn_manager_get_service (manager, vpn_setting->service_type); if (!service) { @@ -92,134 +192,93 @@ nm_vpn_manager_connect (NMVPNManager *manager, nm_vpn_manager_add_service (manager, service); } - if (service) - return nm_vpn_service_activate (service, connection, device); + if (service) { + vpn = nm_vpn_service_activate (service, connection, act_request, device, error); + if (vpn) { + path = (char *) nm_vpn_connection_get_active_connection_path (vpn); + g_signal_connect (vpn, "state-changed", + G_CALLBACK (connection_state_changed), + manager); + } + } else { + g_set_error (error, + NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_INVALID, + "%s", "The VPN service was invalid."); + } - return NULL; + return path; } -static GError * -new_vpn_error (const gchar *format, ...) +gboolean +nm_vpn_manager_deactivate_connection (NMVPNManager *manager, const char *path) { - GError *err; - va_list args; - gchar *msg; - static GQuark domain_quark = 0; - - if (domain_quark == 0) - domain_quark = g_quark_from_static_string ("nm_vpn_error"); - - va_start (args, format); - msg = g_strdup_vprintf (format, args); - va_end (args); - - err = g_error_new_literal (domain_quark, 1, (const gchar *) msg); - - g_free (msg); - - return err; -} - -static gboolean -impl_vpn_manager_connect (NMVPNManager *manager, - const char *connection_type, - const char *connection_path, - const char *device_path, - char **vpn_connection_path, - GError **err) -{ - NMDevice *device; - NMConnection *connection = NULL; - NMVPNConnection *vpn_connection = NULL; NMVPNManagerPrivate *priv; + GSList *iter; + gboolean found = FALSE; - *vpn_connection_path = NULL; + g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), FALSE); + g_return_val_if_fail (path != NULL, FALSE); priv = NM_VPN_MANAGER_GET_PRIVATE (manager); - device = nm_manager_get_device_by_path (priv->nm_manager, device_path); - if (!device) { - *err = new_vpn_error ("%s.%d: No active device was found.", - __FILE__, __LINE__); - goto out; + for (iter = priv->services; iter; iter = g_slist_next (iter)) { + GSList *connections, *elt; + + connections = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (iter->data)); + for (elt = connections; elt; elt = g_slist_next (elt)) { + NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data); + const char *vpn_path; + + vpn_path = nm_vpn_connection_get_active_connection_path (vpn); + if (!strcmp (path, vpn_path)) { + nm_vpn_connection_disconnect (vpn, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED); + found = TRUE; + } + } } - if (!strcmp (connection_type, NM_DBUS_SERVICE_USER_SETTINGS)) - connection = nm_manager_get_connection_by_object_path (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager, - NM_CONNECTION_SCOPE_USER, - connection_path); - else if (!strcmp (connection_type, NM_DBUS_SERVICE_SYSTEM_SETTINGS)) - connection = nm_manager_get_connection_by_object_path (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager, - NM_CONNECTION_SCOPE_SYSTEM, - connection_path); - if (connection == NULL) { - *err = new_vpn_error ("%s.%d: VPN connection could not be found.", - __FILE__, __LINE__); - goto out; - } - - vpn_connection = nm_vpn_manager_connect (manager, connection, device); - if (vpn_connection) - *vpn_connection_path = g_strdup (nm_vpn_connection_get_object_path (vpn_connection)); - else { - *err = new_vpn_error ("%s.%d: VPN connection could not be started.", - __FILE__, __LINE__); - } - - out: - return *vpn_connection_path != NULL; + return found ? TRUE : FALSE; } -static void -get_connections (gpointer data, gpointer user_data) +void +nm_vpn_manager_add_active_connections (NMVPNManager *manager, + NMConnection *filter, + GPtrArray *array) { - NMVPNService *service = NM_VPN_SERVICE (data); - GSList **list = (GSList **) user_data; - - *list = g_slist_concat (*list, nm_vpn_service_get_connections (service)); -} - -GSList * -nm_vpn_manager_get_connections (NMVPNManager *manager) -{ - GSList *list = NULL; - - g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); - - g_slist_foreach (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, get_connections, &list); - - return list; -} - -static gboolean -impl_vpn_manager_get_connections (NMVPNManager *manager, GPtrArray **connections, GError **err) -{ - GSList *list; + NMVPNManagerPrivate *priv; GSList *iter; - list = nm_vpn_manager_get_connections (manager); - *connections = g_ptr_array_sized_new (g_slist_length (list)); + g_return_if_fail (NM_IS_VPN_MANAGER (manager)); + g_return_if_fail (array != NULL); - for (iter = list; iter; iter = iter->next) - g_ptr_array_add (*connections, - g_strdup (nm_vpn_connection_get_object_path (NM_VPN_CONNECTION (iter->data)))); + priv = NM_VPN_MANAGER_GET_PRIVATE (manager); + for (iter = priv->services; iter; iter = g_slist_next (iter)) { + GSList *active, *elt; - g_slist_free (list); + active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (iter->data)); + for (elt = active; elt; elt = g_slist_next (elt)) { + NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data); + const char *path; - return TRUE; + if (!filter || (nm_vpn_connection_get_connection (vpn) == filter)) { + path = nm_vpn_connection_get_active_connection_path (vpn); + g_ptr_array_add (array, g_strdup (path)); + } + } + } } NMVPNManager * -nm_vpn_manager_new (NMManager *nm_manager) +nm_vpn_manager_get (void) { - NMVPNManager *manager; + static NMVPNManager *singleton = NULL; - g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL); + if (!singleton) + singleton = NM_VPN_MANAGER (g_object_new (NM_TYPE_VPN_MANAGER, NULL)); + else + g_object_ref (singleton); - manager = (NMVPNManager *) g_object_new (NM_TYPE_VPN_MANAGER, NULL); - if (manager) - NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager = g_object_ref (nm_manager); - - return manager; + g_assert (singleton); + return singleton; } /******************************************************************************/ @@ -227,12 +286,6 @@ nm_vpn_manager_new (NMManager *nm_manager) static void nm_vpn_manager_init (NMVPNManager *manager) { - NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager); - - priv->dbus_mgr = nm_dbus_manager_get (); - dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr), - NM_DBUS_PATH_VPN, - G_OBJECT (manager)); } static void @@ -241,8 +294,6 @@ finalize (GObject *object) NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object); g_slist_foreach (priv->services, (GFunc) g_object_unref, NULL); - g_object_unref (priv->dbus_mgr); - g_object_unref (priv->nm_manager); G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object); } @@ -257,7 +308,17 @@ nm_vpn_manager_class_init (NMVPNManagerClass *manager_class) /* virtual methods */ object_class->finalize = finalize; - dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class), - &dbus_glib_nm_vpn_manager_object_info); + /* signals */ + signals[CONNECTION_DEACTIVATED] = + g_signal_new ("connection-deactivated", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMVPNManagerClass, connection_deactivated), + NULL, NULL, + nm_marshal_VOID__OBJECT_UINT_UINT, + G_TYPE_NONE, 3, + G_TYPE_OBJECT, G_TYPE_UINT, G_TYPE_UINT); + dbus_g_error_domain_register (NM_VPN_MANAGER_ERROR, NULL, NM_TYPE_VPN_MANAGER_ERROR); } + diff --git a/src/vpn-manager/nm-vpn-manager.h b/src/vpn-manager/nm-vpn-manager.h index a5e506c20a..3d064b2dd6 100644 --- a/src/vpn-manager/nm-vpn-manager.h +++ b/src/vpn-manager/nm-vpn-manager.h @@ -5,8 +5,8 @@ #include #include -#include "nm-manager.h" #include "nm-vpn-connection.h" +#include "nm-activation-request.h" #define NM_TYPE_VPN_MANAGER (nm_vpn_manager_get_type ()) #define NM_VPN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVPNManager)) @@ -21,17 +21,29 @@ typedef struct { typedef struct { GObjectClass parent; + + /* Signals */ + void (*connection_deactivated) (NMVPNManager *manager, + NMVPNConnection *connection, + NMVPNConnectionState state, + NMVPNConnectionStateReason reason); } NMVPNManagerClass; GType nm_vpn_manager_get_type (void); -NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager); +NMVPNManager *nm_vpn_manager_get (void); -NMVPNConnection *nm_vpn_manager_connect (NMVPNManager *manager, - NMConnection *connection, - NMDevice *device); +const char *nm_vpn_manager_activate_connection (NMVPNManager *manager, + NMConnection *connection, + NMActRequest *act_request, + NMDevice *device, + GError **error); -GSList *nm_vpn_manager_get_connections (NMVPNManager *manager); +gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager, + const char *path); +void nm_vpn_manager_add_active_connections (NMVPNManager *manager, + NMConnection *filter, + GPtrArray *list); #endif /* NM_VPN_VPN_MANAGER_H */ diff --git a/src/vpn-manager/nm-vpn-service.c b/src/vpn-manager/nm-vpn-service.c index b9bd29de7a..478105a9e2 100644 --- a/src/vpn-manager/nm-vpn-service.c +++ b/src/vpn-manager/nm-vpn-service.c @@ -311,37 +311,43 @@ connection_state_changed (NMVPNConnection *connection, NMVPNConnection * nm_vpn_service_activate (NMVPNService *service, - NMConnection *connection, - NMDevice *device) + NMConnection *connection, + NMActRequest *act_request, + NMDevice *device, + GError **error) { - NMVPNConnection *vpn_connection; + NMVPNConnection *vpn; NMVPNServicePrivate *priv; g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL); g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL); g_return_val_if_fail (NM_IS_DEVICE (device), NULL); + g_return_val_if_fail (error != NULL, NULL); + g_return_val_if_fail (*error == NULL, NULL); priv = NM_VPN_SERVICE_GET_PRIVATE (service); - vpn_connection = nm_vpn_connection_new (connection, device); - g_signal_connect (vpn_connection, "state-changed", + vpn = nm_vpn_connection_new (connection, act_request, device); + g_signal_connect (vpn, "state-changed", G_CALLBACK (connection_state_changed), service); - priv->connections = g_slist_prepend (priv->connections, vpn_connection); + priv->connections = g_slist_prepend (priv->connections, vpn); - if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, priv->dbus_service)) - nm_vpn_connection_activate (vpn_connection); - else if (priv->service_start_timeout == 0) { + if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, priv->dbus_service)) { + // FIXME: fill in error when errors happen + nm_vpn_connection_activate (vpn); + } else if (priv->service_start_timeout == 0) { nm_info ("VPN service '%s' exec scheduled...", nm_vpn_service_get_name (service)); g_idle_add (nm_vpn_service_daemon_exec, service); } - return vpn_connection; + return vpn; } GSList * -nm_vpn_service_get_connections (NMVPNService *service) +nm_vpn_service_get_active_connections (NMVPNService *service) { g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL); diff --git a/src/vpn-manager/nm-vpn-service.h b/src/vpn-manager/nm-vpn-service.h index 8037b320dc..6a0dee0664 100644 --- a/src/vpn-manager/nm-vpn-service.h +++ b/src/vpn-manager/nm-vpn-service.h @@ -7,6 +7,7 @@ #include #include "nm-device.h" #include "nm-vpn-connection.h" +#include "nm-activation-request.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)) @@ -25,13 +26,16 @@ typedef struct { GType nm_vpn_service_get_type (void); -NMVPNService *nm_vpn_service_new (const char *service_name); -const char *nm_vpn_service_get_name (NMVPNService *service); +NMVPNService * nm_vpn_service_new (const char *service_name); -NMVPNConnection *nm_vpn_service_activate (NMVPNService *service, - NMConnection *connection, - NMDevice *device); +const char * nm_vpn_service_get_name (NMVPNService *service); -GSList *nm_vpn_service_get_connections (NMVPNService *service); +NMVPNConnection * nm_vpn_service_activate (NMVPNService *service, + NMConnection *connection, + NMActRequest *act_request, + NMDevice *device, + GError **error); + +GSList * nm_vpn_service_get_active_connections (NMVPNService *service); #endif /* NM_VPN_VPN_SERVICE_H */