2008-03-26 Dan Williams <dcbw@redhat.com>

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
This commit is contained in:
Dan Williams
2008-03-26 13:43:01 +00:00
parent 7d694073be
commit ec89663e7d
30 changed files with 973 additions and 715 deletions

View File

@@ -1,3 +1,17 @@
2008-03-26 Dan Williams <dcbw@redhat.com>
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 <dcbw@redhat.com> 2008-03-25 Dan Williams <dcbw@redhat.com>
Patch from Björn Martensen <bjoern.martensen@gmail.com> Patch from Björn Martensen <bjoern.martensen@gmail.com>

View File

@@ -10,7 +10,6 @@ EXTRA_DIST = \
nm-manager-client.xml \ nm-manager-client.xml \
nm-settings.xml \ nm-settings.xml \
nm-exported-connection.xml \ nm-exported-connection.xml \
nm-vpn-manager.xml \
nm-vpn-plugin.xml \ nm-vpn-plugin.xml \
nm-vpn-connection.xml \ nm-vpn-connection.xml \
nm-ppp-manager.xml \ nm-ppp-manager.xml \

View File

@@ -36,7 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.</
<xi:include href="nm-settings.xml"/> <xi:include href="nm-settings.xml"/>
<xi:include href="nm-exported-connection.xml"/> <xi:include href="nm-exported-connection.xml"/>
<xi:include href="nm-active-connection.xml"/> <xi:include href="nm-active-connection.xml"/>
<xi:include href="nm-vpn-manager.xml"/>
<xi:include href="nm-vpn-connection.xml"/> <xi:include href="nm-vpn-connection.xml"/>
<xi:include href="nm-vpn-plugin.xml"/> <xi:include href="nm-vpn-plugin.xml"/>

View File

@@ -1,20 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0"> <node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.Connection.Active">
<property name="ServiceName" type="s" access="read">
<tp:docstring>The D-Bus service name providing this connection.</tp:docstring>
</property>
<property name="Connection" type="o" access="read">
<tp:docstring>The path of the connection.</tp:docstring>
</property>
<property name="SpecificObject" type="o" access="read">
<tp:docstring>A specific object associated with the active connection.</tp:docstring>
</property>
<property name="SharedServiceName" type="s" access="read">
<tp:docstring>The D-Bus service name that provides a connection with which this active connection is shared.</tp:docstring>
</property>
<property name="SharedConnection" type="o" access="read">
<tp:docstring>The path of a connection provided by the D-Bus service SharedServiceName which which this connection is shared.</tp:docstring>
</property>
<property name="Devices" type="ao" access="read">
<tp:docstring>Array of object paths representing devices which are part of this active connection.</tp:docstring>
</property>
</interface>
<interface name="org.freedesktop.NetworkManager.VPN.Connection"> <interface name="org.freedesktop.NetworkManager.VPN.Connection">
<tp:docstring> <tp:docstring>
Represents a connection to a Virtual Private Network. Represents an active connection to a Virtual Private Network.
</tp:docstring> </tp:docstring>
<method name="Disconnect">
<tp:docstring>
Disconnect the VPN connection.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_connection_disconnect"/>
</method>
<property name="Name" type="s" access="read">
<tp:docstring>The name of the VPN connection.</tp:docstring>
</property>
<property name="State" type="u" access="read" tp:type="NM_VPN_CONNECTION_STATE"> <property name="State" type="u" access="read" tp:type="NM_VPN_CONNECTION_STATE">
<tp:docstring>The state of the VPN connection.</tp:docstring> <tp:docstring>The state of the VPN connection.</tp:docstring>
</property> </property>
@@ -37,6 +49,7 @@
</tp:docstring> </tp:docstring>
</arg> </arg>
</signal> </signal>
<tp:enum name="NM_VPN_CONNECTION_STATE" type="u"> <tp:enum name="NM_VPN_CONNECTION_STATE" type="u">
<tp:enumvalue suffix="UNKNOWN" value="0"> <tp:enumvalue suffix="UNKNOWN" value="0">
<tp:docstring> <tp:docstring>

View File

@@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
<interface name="org.freedesktop.NetworkManager.VPN.Manager">
<method name="Connect">
<tp:docstring>
Establish a VPN connection.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_manager_connect"/>
<arg name="connection_type" type="s" direction="in">
<tp:docstring>
String describing the connection type.
</tp:docstring>
</arg>
<arg name="connection" type="o" direction="in">
<tp:docstring>
Object path of the network connection to establish the VPN connection on.
</tp:docstring>
</arg>
<arg name="device" type="o" direction="in">
<tp:docstring>
Object path of the device to establish the VPN connection on.
</tp:docstring>
</arg>
<arg name="vpn_connection" type="o" direction="out">
<tp:docstring>
Object path of the newly created VPN connection.
</tp:docstring>
</arg>
</method>
<method name="ListConnections">
<tp:docstring>
Get the list of active VPN connections.
</tp:docstring>
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_manager_get_connections"/>
<arg name="connections" type="ao" direction="out">
<tp:docstring>
List of object paths of active VPN connections.
</tp:docstring>
</arg>
</method>
</interface>
</node>

View File

@@ -10,7 +10,6 @@ BUILT_SOURCES = \
nm-marshal.c \ nm-marshal.c \
nm-exported-connection-glue.h \ nm-exported-connection-glue.h \
nm-settings-glue.h \ nm-settings-glue.h \
nm-vpn-manager-bindings.h \
nm-vpn-connection-bindings.h \ nm-vpn-connection-bindings.h \
nm-vpn-plugin-glue.h \ nm-vpn-plugin-glue.h \
nm-active-connection-bindings.h nm-active-connection-bindings.h
@@ -39,7 +38,6 @@ libnminclude_HEADERS = \
nm-gsm-device.h \ nm-gsm-device.h \
nm-cdma-device.h \ nm-cdma-device.h \
nm-vpn-connection.h \ nm-vpn-connection.h \
nm-vpn-manager.h \
nm-vpn-plugin.h \ nm-vpn-plugin.h \
nm-types.h \ nm-types.h \
nm-active-connection.h nm-active-connection.h
@@ -61,7 +59,6 @@ libnm_glib_la_SOURCES = \
nm-gsm-device.c \ nm-gsm-device.c \
nm-cdma-device.c \ nm-cdma-device.c \
nm-vpn-connection.c \ nm-vpn-connection.c \
nm-vpn-manager.c \
nm-marshal-main.c \ nm-marshal-main.c \
nm-types.c \ nm-types.c \
nm-types-private.h \ 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 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 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 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 dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-client --output=nm-vpn-connection-bindings.h $(top_srcdir)/introspection/nm-vpn-connection.xml

View File

@@ -7,6 +7,7 @@
#include "nm-object-private.h" #include "nm-object-private.h"
#include "nm-types-private.h" #include "nm-types-private.h"
#include "nm-device.h" #include "nm-device.h"
#include "nm-connection.h"
#include "nm-active-connection-bindings.h" #include "nm-active-connection-bindings.h"
@@ -22,6 +23,7 @@ typedef struct {
DBusGProxy *proxy; DBusGProxy *proxy;
char *service_name; char *service_name;
NMConnectionScope scope;
char *connection; char *connection;
char *specific_object; char *specific_object;
char *shared_service_name; char *shared_service_name;
@@ -60,6 +62,17 @@ nm_active_connection_new (DBusGConnection *connection, const char *path)
NULL); 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 * const char *
nm_active_connection_get_service_name (NMActiveConnection *connection) 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), priv->service_name = nm_object_get_string_property (NM_OBJECT (connection),
NM_DBUS_INTERFACE_ACTIVE_CONNECTION, NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
DBUS_PROP_SERVICE_NAME); DBUS_PROP_SERVICE_NAME);
priv->scope = get_scope_for_service_name (priv->service_name);
} }
return 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 * const char *
nm_active_connection_get_connection (NMActiveConnection *connection) nm_active_connection_get_connection (NMActiveConnection *connection)
{ {
@@ -256,12 +280,24 @@ demarshal_devices (NMObject *object, GParamSpec *pspec, GValue *value, gpointer
return TRUE; 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 static void
register_for_property_changed (NMActiveConnection *connection) register_for_property_changed (NMActiveConnection *connection)
{ {
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection); NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection);
const NMPropertiesChangedInfo property_changed_info[] = { 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_CONNECTION, nm_object_demarshal_generic, &priv->connection },
{ NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, nm_object_demarshal_generic, &priv->specific_object }, { 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 }, { NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME, nm_object_demarshal_generic, &priv->shared_service_name },

View File

@@ -4,6 +4,7 @@
#include <glib/gtypes.h> #include <glib/gtypes.h>
#include <glib-object.h> #include <glib-object.h>
#include "nm-object.h" #include "nm-object.h"
#include <nm-connection.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@@ -34,6 +35,7 @@ GType nm_active_connection_get_type (void);
GObject *nm_active_connection_new (DBusGConnection *connection, const char *path); GObject *nm_active_connection_new (DBusGConnection *connection, const char *path);
const char * nm_active_connection_get_service_name (NMActiveConnection *connection); 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_connection (NMActiveConnection *connection);
const char * nm_active_connection_get_specific_object (NMActiveConnection *connection); const char * nm_active_connection_get_specific_object (NMActiveConnection *connection);
const char * nm_active_connection_get_shared_service_name (NMActiveConnection *connection); const char * nm_active_connection_get_shared_service_name (NMActiveConnection *connection);

View File

@@ -14,6 +14,7 @@
#include "nm-types-private.h" #include "nm-types-private.h"
#include "nm-object-private.h" #include "nm-object-private.h"
#include "nm-active-connection.h" #include "nm-active-connection.h"
#include "nm-vpn-connection.h"
#include "nm-object-cache.h" #include "nm-object-cache.h"
#include "nm-dbus-glib-types.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)); 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 static gboolean
demarshal_active_connections (NMObject *object, demarshal_active_connections (NMObject *object,
GParamSpec *pspec, GParamSpec *pspec,
@@ -140,7 +181,7 @@ demarshal_active_connections (NMObject *object,
DBusGConnection *connection; DBusGConnection *connection;
connection = nm_object_get_connection (object); 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; return FALSE;
nm_object_queue_notify (object, NM_CLIENT_ACTIVE_CONNECTIONS); nm_object_queue_notify (object, NM_CLIENT_ACTIVE_CONNECTIONS);

View File

@@ -27,14 +27,14 @@
#include "nm-vpn-connection-bindings.h" #include "nm-vpn-connection-bindings.h"
#include "nm-marshal.h" #include "nm-marshal.h"
#include "nm-object-private.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)) #define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
typedef struct { typedef struct {
DBusGProxy *proxy; DBusGProxy *proxy;
char *name;
char *banner; char *banner;
NMVPNConnectionState state; NMVPNConnectionState state;
} NMVPNConnectionPrivate; } NMVPNConnectionPrivate;
@@ -48,38 +48,16 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 }; static guint signals[LAST_SIGNAL] = { 0 };
NMVPNConnection * GObject *
nm_vpn_connection_new (DBusGConnection *dbus_connection, nm_vpn_connection_new (DBusGConnection *dbus_connection, const char *path)
const char *path)
{ {
NMVPNConnection *connection;
g_return_val_if_fail (dbus_connection != NULL, NULL); g_return_val_if_fail (dbus_connection != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL); g_return_val_if_fail (path != NULL, NULL);
connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, return g_object_new (NM_TYPE_VPN_CONNECTION,
NM_OBJECT_DBUS_CONNECTION, dbus_connection, NM_OBJECT_DBUS_CONNECTION, dbus_connection,
NM_OBJECT_DBUS_PATH, path, NM_OBJECT_DBUS_PATH, path,
NULL); 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;
} }
const char * 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 static void
@@ -199,12 +163,11 @@ finalize (GObject *object)
{ {
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
if (priv->name)
g_free (priv->name);
if (priv->banner) if (priv->banner)
g_free (priv->banner); g_free (priv->banner);
g_object_unref (priv->proxy); g_object_unref (priv->proxy);
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object);
} }

View File

@@ -26,7 +26,7 @@
#include <glib/gtypes.h> #include <glib/gtypes.h>
#include <glib-object.h> #include <glib-object.h>
#include <dbus/dbus-glib.h> #include <dbus/dbus-glib.h>
#include "nm-object.h" #include "nm-active-connection.h"
#include "NetworkManagerVPN.h" #include "NetworkManagerVPN.h"
G_BEGIN_DECLS 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)) #define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
typedef struct { typedef struct {
NMObject parent; NMActiveConnection parent;
} NMVPNConnection; } NMVPNConnection;
typedef struct { typedef struct {
NMObjectClass parent; NMActiveConnectionClass parent;
/* Signals */ /* Signals */
void (*state_changed) (NMVPNConnection *connection, void (*state_changed) (NMVPNConnection *connection,
@@ -53,16 +53,11 @@ typedef struct {
GType nm_vpn_connection_get_type (void); 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); NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *vpn);
const char * nm_vpn_connection_get_banner (NMVPNConnection *vpn); const char * nm_vpn_connection_get_banner (NMVPNConnection *vpn);
void nm_vpn_connection_disconnect (NMVPNConnection *vpn);
G_END_DECLS G_END_DECLS
#endif /* NM_VPN_CONNECTION_H */ #endif /* NM_VPN_CONNECTION_H */

View File

@@ -1,136 +0,0 @@
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
#include <dbus/dbus-glib.h>
#include <string.h>
#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;
}

View File

@@ -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 <glib/gtypes.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
#include <NetworkManager.h>
#include <NetworkManagerVPN.h>
#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 */

View File

@@ -38,6 +38,8 @@ NetworkManager_SOURCES = \
nm-hal-manager.h \ nm-hal-manager.h \
nm-ip4-config.c \ nm-ip4-config.c \
nm-ip4-config.h \ nm-ip4-config.h \
nm-active-connection.h \
nm-active-connection.c \
NetworkManager.c \ NetworkManager.c \
NetworkManagerPolicy.c \ NetworkManagerPolicy.c \
NetworkManagerPolicy.h \ NetworkManagerPolicy.h \

View File

@@ -303,6 +303,12 @@ main (int argc, char *argv[])
/* Initialize our DBus service & connection */ /* Initialize our DBus service & connection */
dbus_mgr = nm_dbus_manager_get (); 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 (); manager = nm_manager_new ();
if (manager == NULL) { if (manager == NULL) {
nm_error ("Failed to initialize the network manager."); nm_error ("Failed to initialize the network manager.");
@@ -322,12 +328,6 @@ main (int argc, char *argv[])
goto done; 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 (); named_mgr = nm_named_manager_get ();
if (!named_mgr) { if (!named_mgr) {
nm_warning ("Failed to start the named manager."); nm_warning ("Failed to start the named manager.");
@@ -354,9 +354,6 @@ main (int argc, char *argv[])
g_main_loop_run (main_loop); g_main_loop_run (main_loop);
done: done:
if (vpn_manager)
g_object_unref (vpn_manager);
if (hal_manager) if (hal_manager)
nm_hal_manager_destroy (hal_manager); nm_hal_manager_destroy (hal_manager);
@@ -366,6 +363,9 @@ done:
if (manager) if (manager)
g_object_unref (manager); g_object_unref (manager);
if (vpn_manager)
g_object_unref (vpn_manager);
if (sup_mgr) if (sup_mgr)
g_object_unref (sup_mgr); g_object_unref (sup_mgr);

View File

@@ -214,17 +214,22 @@ auto_activate_device (gpointer user_data)
best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object); best_connection = nm_device_get_best_auto_connection (data->device, connections, &specific_object);
if (best_connection) { if (best_connection) {
GError *error = NULL; GError *error = NULL;
const char *device_path;
if (!nm_manager_activate_device (policy->manager, device_path = nm_device_get_udi (data->device);
data->device, if (!nm_manager_activate_connection (policy->manager,
best_connection, best_connection,
specific_object, specific_object,
FALSE, device_path,
&error)) { FALSE,
nm_warning ("Failed to automatically activate device %s: (%d) %s", &error)) {
nm_device_get_iface (data->device), NMSettingConnection *s_con;
error->code,
error->message); 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); g_error_free (error);
} }
} }
@@ -476,23 +481,30 @@ connection_removed (NMManager *manager,
NMConnectionScope scope, NMConnectionScope scope,
gpointer user_data) gpointer user_data)
{ {
GSList *iter; NMSettingConnection *s_con;
GPtrArray *list;
int i;
/* If the connection just removed was active, deactive it */ s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION));
for (iter = nm_manager_get_devices (manager); iter; iter = g_slist_next (iter)) { if (!s_con)
NMDevice *device = NM_DEVICE (iter->data); return;
NMActRequest *req = nm_device_get_act_request (device);
NMConnection *dev_connection;
if (!req) list = nm_manager_get_active_connections_by_connection (manager, connection);
continue; if (!list)
return;
dev_connection = nm_act_request_get_connection (req); for (i = 0; i < list->len; i++) {
if (dev_connection == connection) { char *path = g_ptr_array_index (list, i);
nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); GError *error = NULL;
schedule_activate_check ((NMPolicy *) user_data, device);
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 * NMPolicy *

View File

@@ -8,3 +8,5 @@ VOID:UINT,UINT
VOID:STRING,STRING VOID:STRING,STRING
VOID:STRING,UCHAR VOID:STRING,UCHAR
VOID:STRING,OBJECT VOID:STRING,OBJECT
VOID:OBJECT,UINT,UINT

View File

@@ -30,7 +30,7 @@
#include "nm-dbus-manager.h" #include "nm-dbus-manager.h"
#include "nm-device.h" #include "nm-device.h"
#include "nm-properties-changed-signal.h" #include "nm-properties-changed-signal.h"
#include "nm-active-connection-glue.h" #include "nm-active-connection.h"
#include "nm-manager.h" /* FIXME! */ #include "nm-manager.h" /* FIXME! */
@@ -69,6 +69,7 @@ enum {
PROP_SHARED_SERVICE_NAME, PROP_SHARED_SERVICE_NAME,
PROP_SHARED_CONNECTION, PROP_SHARED_CONNECTION,
PROP_DEVICES, PROP_DEVICES,
PROP_VPN,
LAST_PROP LAST_PROP
}; };
@@ -82,8 +83,6 @@ nm_act_request_new (NMConnection *connection,
{ {
GObject *object; GObject *object;
NMActRequestPrivate *priv; 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_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (NM_DEVICE (device), 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->device = NM_DEVICE (device);
priv->user_requested = user_requested; 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); return NM_ACT_REQUEST (object);
} }
static void static void
nm_act_request_init (NMActRequest *req) 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 static void
@@ -152,27 +157,6 @@ finalize (GObject *object)
G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (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 static void
get_property (GObject *object, guint prop_id, get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec) GValue *value, GParamSpec *pspec)
@@ -182,7 +166,7 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_SERVICE_NAME: case PROP_SERVICE_NAME:
scope_to_value (priv->connection, value); nm_active_connection_scope_to_value (priv->connection, value);
break; break;
case PROP_CONNECTION: case PROP_CONNECTION:
g_value_set_boxed (value, nm_connection_get_path (priv->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, "/"); g_value_set_boxed (value, "/");
break; break;
case PROP_SHARED_SERVICE_NAME: case PROP_SHARED_SERVICE_NAME:
scope_to_value (priv->shared, value); nm_active_connection_scope_to_value (priv->shared, value);
break; break;
case PROP_SHARED_CONNECTION: case PROP_SHARED_CONNECTION:
if (!priv->shared) { 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_ptr_array_add (devices, g_strdup (nm_device_get_udi (priv->device)));
g_value_take_boxed (value, devices); g_value_take_boxed (value, devices);
break; break;
case PROP_VPN:
g_value_set_boolean (value, FALSE);
break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@@ -269,6 +256,13 @@ nm_act_request_class_init (NMActRequestClass *req_class)
"Devices", "Devices",
dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
G_PARAM_READABLE)); 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 */
signals[CONNECTION_SECRETS_UPDATED] = signals[CONNECTION_SECRETS_UPDATED] =
@@ -295,8 +289,7 @@ nm_act_request_class_init (NMActRequestClass *req_class)
nm_properties_changed_signal_new (object_class, nm_properties_changed_signal_new (object_class,
G_STRUCT_OFFSET (NMActRequestClass, properties_changed)); G_STRUCT_OFFSET (NMActRequestClass, properties_changed));
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (req_class), nm_active_connection_install_type_info (object_class);
&dbus_glib_nm_active_connection_object_info);
} }
typedef struct GetSecretsInfo { typedef struct GetSecretsInfo {

View File

@@ -25,6 +25,7 @@
#include <glib/gtypes.h> #include <glib/gtypes.h>
#include <glib-object.h> #include <glib-object.h>
#include "nm-connection.h" #include "nm-connection.h"
#include "nm-active-connection.h"
#define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ()) #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)) #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_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_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 { typedef struct {
GObject parent; GObject parent;
} NMActRequest; } NMActRequest;

View File

@@ -0,0 +1,63 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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 <glib.h>
#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;
}
}

View File

@@ -0,0 +1,42 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* 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 <glib-object.h>
#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 */

View File

@@ -6,12 +6,14 @@
#include "nm-manager.h" #include "nm-manager.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-dbus-manager.h" #include "nm-dbus-manager.h"
#include "nm-vpn-manager.h"
#include "nm-device-interface.h" #include "nm-device-interface.h"
#include "nm-device-802-11-wireless.h" #include "nm-device-802-11-wireless.h"
#include "NetworkManagerSystem.h" #include "NetworkManagerSystem.h"
#include "nm-properties-changed-signal.h" #include "nm-properties-changed-signal.h"
#include "nm-setting-connection.h" #include "nm-setting-connection.h"
#include "nm-setting-wireless.h" #include "nm-setting-wireless.h"
#include "nm-setting-vpn.h"
#include "nm-marshal.h" #include "nm-marshal.h"
static gboolean impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err); 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 { typedef struct {
DBusGMethodInvocation *context; DBusGMethodInvocation *context;
NMDevice *device;
NMConnectionScope scope; NMConnectionScope scope;
char *connection_path; char *connection_path;
char *specific_object_path; char *specific_object_path;
char *device_path;
guint timeout_id; guint timeout_id;
} PendingConnectionInfo; } PendingConnectionInfo;
@@ -74,6 +76,11 @@ typedef struct {
gboolean sleeping; gboolean sleeping;
guint poke_id; guint poke_id;
NMVPNManager *vpn_manager;
guint vpn_manager_id;
gboolean disposed;
} NMManagerPrivate; } NMManagerPrivate;
#define NM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_MANAGER, 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; 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 static void
nm_manager_init (NMManager *manager) nm_manager_init (NMManager *manager)
{ {
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
guint id;
priv->wireless_enabled = TRUE; priv->wireless_enabled = TRUE;
priv->wireless_hw_enabled = TRUE; priv->wireless_hw_enabled = TRUE;
@@ -180,6 +198,11 @@ nm_manager_init (NMManager *manager)
g_str_equal, g_str_equal,
g_free, g_free,
g_object_unref); 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 NMState
@@ -239,17 +262,23 @@ pending_connection_info_destroy (PendingConnectionInfo *info)
g_free (info->connection_path); g_free (info->connection_path);
g_free (info->specific_object_path); g_free (info->specific_object_path);
g_object_unref (info->device); g_free (info->device_path);
g_slice_free (PendingConnectionInfo, info); g_slice_free (PendingConnectionInfo, info);
} }
static void static void
finalize (GObject *object) dispose (GObject *object)
{ {
NMManager *manager = NM_MANAGER (object); NMManager *manager = NM_MANAGER (object);
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); 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); pending_connection_info_destroy (priv->pending_connection_info);
priv->pending_connection_info = NULL; priv->pending_connection_info = NULL;
@@ -269,10 +298,15 @@ finalize (GObject *object)
priv->poke_id = 0; priv->poke_id = 0;
} }
if (priv->dbus_mgr) if (priv->vpn_manager_id) {
g_object_unref (priv->dbus_mgr); 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 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 static void
get_property (GObject *object, guint prop_id, get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec) 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) { switch (prop_id) {
case PROP_STATE: case PROP_STATE:
nm_manager_update_state (NM_MANAGER (object)); nm_manager_update_state (self);
g_value_set_uint (value, priv->state); g_value_set_uint (value, priv->state);
break; break;
case PROP_WIRELESS_ENABLED: case PROP_WIRELESS_ENABLED:
@@ -306,25 +374,9 @@ get_property (GObject *object, guint prop_id,
case PROP_WIRELESS_HARDWARE_ENABLED: case PROP_WIRELESS_HARDWARE_ENABLED:
g_value_set_boolean (value, priv->wireless_hw_enabled); g_value_set_boolean (value, priv->wireless_hw_enabled);
break; break;
case PROP_ACTIVE_CONNECTIONS: { case PROP_ACTIVE_CONNECTIONS:
GPtrArray *active; g_value_take_boxed (value, get_active_connections (self, NULL));
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);
break; break;
}
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break; break;
@@ -343,7 +395,7 @@ nm_manager_class_init (NMManagerClass *manager_class)
object_class->set_property = set_property; object_class->set_property = set_property;
object_class->get_property = get_property; object_class->get_property = get_property;
object_class->finalize = finalize; object_class->dispose = dispose;
/* properties */ /* properties */
g_object_class_install_property g_object_class_install_property
@@ -1261,6 +1313,37 @@ nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
return NULL; 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 static gboolean
check_connection_allowed (NMManager *manager, check_connection_allowed (NMManager *manager,
NMDeviceInterface *dev_iface, NMDeviceInterface *dev_iface,
@@ -1296,13 +1379,13 @@ check_connection_allowed (NMManager *manager,
return allowed; return allowed;
} }
const char * static const char *
nm_manager_activate_device (NMManager *manager, internal_activate_device (NMManager *manager,
NMDevice *device, NMDevice *device,
NMConnection *connection, NMConnection *connection,
const char *specific_object, const char *specific_object,
gboolean user_requested, gboolean user_requested,
GError **error) GError **error)
{ {
NMActRequest *req; NMActRequest *req;
NMDeviceInterface *dev_iface; NMDeviceInterface *dev_iface;
@@ -1348,16 +1431,11 @@ wait_for_connection_expired (gpointer data)
g_return_val_if_fail (info != NULL, FALSE); 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, g_set_error (&error,
NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION, NM_MANAGER_ERROR, NM_MANAGER_ERROR_UNKNOWN_CONNECTION,
"%s", "Connection was not provided by any settings service"); "%s", "Connection was not provided by any settings service");
nm_warning ("Failed to activate device %s: (%d) %s", nm_warning ("Connection (%d) %s failed to activate (timeout): (%d) %s",
nm_device_get_iface (info->device), info->scope, info->connection_path, error->code, error->message);
error->code,
error->message);
dbus_g_method_return_error (info->context, error); dbus_g_method_return_error (info->context, error);
g_error_free (error); g_error_free (error);
@@ -1368,6 +1446,74 @@ wait_for_connection_expired (gpointer data)
return FALSE; 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 static void
connection_added_default_handler (NMManager *manager, connection_added_default_handler (NMManager *manager,
NMConnection *connection, NMConnection *connection,
@@ -1390,21 +1536,19 @@ connection_added_default_handler (NMManager *manager,
/* Will destroy below; can't be valid during the initial activation start */ /* Will destroy below; can't be valid during the initial activation start */
priv->pending_connection_info = NULL; priv->pending_connection_info = NULL;
path = nm_manager_activate_device (manager, path = nm_manager_activate_connection (manager,
info->device, connection,
connection, info->specific_object_path,
info->specific_object_path, info->device_path,
TRUE, TRUE,
&error); &error);
if (path) { if (path) {
dbus_g_method_return (info->context, path); dbus_g_method_return (info->context, path);
g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
} else { } else {
dbus_g_method_return_error (info->context, error); dbus_g_method_return_error (info->context, error);
nm_warning ("Failed to activate device %s: (%d) %s", nm_warning ("Connection (%d) %s failed to activate: (%d) %s",
nm_device_get_iface (info->device), scope, info->connection_path, error->code, error->message);
error->code,
error->message);
g_error_free (error); g_error_free (error);
} }
@@ -1419,21 +1563,11 @@ impl_manager_activate_connection (NMManager *manager,
const char *specific_object_path, const char *specific_object_path,
DBusGMethodInvocation *context) DBusGMethodInvocation *context)
{ {
NMDevice *device; NMConnectionScope scope = NM_CONNECTION_SCOPE_UNKNOWN;
NMConnectionScope scope;
NMConnection *connection; NMConnection *connection;
GError *error = NULL; GError *error = NULL;
char *real_sop = NULL; char *real_sop = NULL;
char *path = 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));
if (!strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS)) if (!strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS))
scope = NM_CONNECTION_SCOPE_USER; 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); connection = nm_manager_get_connection_by_object_path (manager, scope, connection_path);
if (connection) { if (connection) {
const char *path; path = (char *) nm_manager_activate_connection (manager,
connection,
path = nm_manager_activate_device (manager, real_sop,
device, device_path,
connection, TRUE,
real_sop, &error);
TRUE,
&error);
if (path) { if (path) {
dbus_g_method_return (context, path); dbus_g_method_return (context, path);
g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); 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 = g_slice_new0 (PendingConnectionInfo);
info->context = context; info->context = context;
info->device = g_object_ref (device); info->device_path = g_strdup (device_path);
info->scope = scope; info->scope = scope;
info->connection_path = g_strdup (connection_path); info->connection_path = g_strdup (connection_path);
info->specific_object_path = g_strdup (real_sop); info->specific_object_path = g_strdup (real_sop);
@@ -1492,24 +1624,25 @@ impl_manager_activate_connection (NMManager *manager,
err: err:
if (error) { if (error) {
dbus_g_method_return_error (context, error); dbus_g_method_return_error (context, error);
nm_warning ("Failed to activate device %s: (%d) %s", nm_warning ("Connection (%d) %s failed to activate: (%d) %s",
nm_device_get_iface (device), scope, connection_path, error->code, error->message);
error->code,
error->message);
g_error_free (error); g_error_free (error);
} }
g_free (real_sop); g_free (real_sop);
} }
static gboolean gboolean
impl_manager_deactivate_connection (NMManager *manager, nm_manager_deactivate_connection (NMManager *manager,
const char *connection_path, const char *connection_path,
GError **error) GError **error)
{ {
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager); NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (manager);
NMVPNManager *vpn_manager;
GSList *iter; GSList *iter;
gboolean success = FALSE;
/* Check for device connections first */
for (iter = priv->devices; iter; iter = g_slist_next (iter)) { for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
NMDevice *device = NM_DEVICE (iter->data); NMDevice *device = NM_DEVICE (iter->data);
NMActRequest *req; NMActRequest *req;
@@ -1521,15 +1654,33 @@ impl_manager_deactivate_connection (NMManager *manager,
if (!strcmp (connection_path, nm_act_request_get_active_connection_path (req))) { if (!strcmp (connection_path, nm_act_request_get_active_connection_path (req))) {
nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device)); nm_device_interface_deactivate (NM_DEVICE_INTERFACE (device));
g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS); g_object_notify (G_OBJECT (manager), NM_MANAGER_ACTIVE_CONNECTIONS);
return TRUE; success = TRUE;
goto done;
} }
} }
g_set_error (error, /* Check for VPN connections next */
NM_MANAGER_ERROR, NM_MANAGER_ERROR_CONNECTION_NOT_ACTIVE, vpn_manager = nm_vpn_manager_get ();
"%s", "The connection was not active."); if (nm_vpn_manager_deactivate_connection (vpn_manager, connection_path)) {
success = TRUE;
return FALSE; } 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 gboolean
@@ -1611,23 +1762,6 @@ impl_manager_sleep (NMManager *manager, gboolean sleep, GError **err)
return TRUE; 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 */ /* Legacy 0.6 compatibility interface */
static gboolean static gboolean
@@ -1732,3 +1866,10 @@ nm_manager_get_connection_by_object_path (NMManager *manager,
return connection; return connection;
} }
GPtrArray *
nm_manager_get_active_connections_by_connection (NMManager *manager,
NMConnection *connection)
{
return get_active_connections (manager, connection);
}

View File

@@ -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_path (NMManager *manager, const char *path);
NMDevice *nm_manager_get_device_by_udi (NMManager *manager, const char *udi); 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, gboolean nm_manager_deactivate_connection (NMManager *manager,
NMDevice *device, const char *connection_path,
NMConnection *connection, GError **error);
const char *specific_object,
gboolean user_requested,
GError **error);
gboolean nm_manager_activation_pending (NMManager *manager); gboolean nm_manager_activation_pending (NMManager *manager);
@@ -90,4 +92,7 @@ NMConnection * nm_manager_get_connection_by_object_path (NMManager *manager,
NMConnectionScope scope, NMConnectionScope scope,
const char *path); const char *path);
GPtrArray * nm_manager_get_active_connections_by_connection (NMManager *manager,
NMConnection *connection);
#endif /* NM_MANAGER_H */ #endif /* NM_MANAGER_H */

View File

@@ -28,9 +28,6 @@ libvpn_manager_la_LIBADD = \
$(top_builddir)/src/marshallers/libmarshallers.la \ $(top_builddir)/src/marshallers/libmarshallers.la \
$(top_builddir)/libnm-util/libnm-util.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 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 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 = \ built_sources = \
nm-vpn-manager-glue.h \
nm-vpn-connection-glue.h \ nm-vpn-connection-glue.h \
nm-vpn-plugin-bindings.h nm-vpn-plugin-bindings.h

View File

@@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 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-utils.h"
#include "nm-vpn-plugin-bindings.h" #include "nm-vpn-plugin-bindings.h"
#include "nm-marshal.h" #include "nm-marshal.h"
#include "nm-active-connection.h"
static gboolean impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err); #include "nm-properties-changed-signal.h"
#define CONNECTION_GET_SECRETS_CALL_TAG "get-secrets-call" #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) G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
typedef struct { typedef struct {
gboolean disposed;
NMConnection *connection; NMConnection *connection;
NMActRequest *act_request;
NMDevice *parent_dev; NMDevice *parent_dev;
char *object_path; char *ac_path;
NMVPNConnectionState state; NMVPNConnectionState state;
gulong device_monitor; gulong device_monitor;
DBusGProxy *proxy; 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)) #define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
enum { enum {
PROPERTIES_CHANGED,
STATE_CHANGED, STATE_CHANGED,
LAST_SIGNAL LAST_SIGNAL
@@ -74,7 +78,13 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum { enum {
PROP_0, 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_STATE,
PROP_BANNER, PROP_BANNER,
@@ -116,12 +126,14 @@ device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
NMVPNConnection * NMVPNConnection *
nm_vpn_connection_new (NMConnection *connection, nm_vpn_connection_new (NMConnection *connection,
NMDevice *parent_device) NMActRequest *act_request,
NMDevice *parent_device)
{ {
NMVPNConnection *vpn_connection; NMVPNConnection *vpn_connection;
NMVPNConnectionPrivate *priv; NMVPNConnectionPrivate *priv;
g_return_val_if_fail (NM_IS_CONNECTION (connection), 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 (parent_device), NULL); g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
vpn_connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, 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 = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection);
priv->connection = g_object_ref (connection); priv->connection = g_object_ref (connection);
priv->act_request = g_object_ref (act_request);
priv->parent_dev = g_object_ref (parent_device); priv->parent_dev = g_object_ref (parent_device);
priv->device_monitor = g_signal_connect (parent_device, "state-changed", 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); 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) { if (state != NM_VPN_SERVICE_STATE_STOPPED)
switch (nm_vpn_connection_get_state (connection)) { return;
case NM_VPN_CONNECTION_STATE_CONNECT:
case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET: switch (nm_vpn_connection_get_state (connection)) {
nm_vpn_connection_set_state (connection, case NM_VPN_CONNECTION_STATE_PREPARE:
NM_VPN_CONNECTION_STATE_FAILED, case NM_VPN_CONNECTION_STATE_NEED_AUTH:
NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); case NM_VPN_CONNECTION_STATE_CONNECT:
break; case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
case NM_VPN_CONNECTION_STATE_ACTIVATED: nm_vpn_connection_set_state (connection,
nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED,
NM_VPN_CONNECTION_STATE_DISCONNECTED, NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED); break;
break; case NM_VPN_CONNECTION_STATE_ACTIVATED:
default: nm_vpn_connection_set_state (connection,
break; 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 * 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); 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 * const char *
@@ -452,6 +468,14 @@ nm_vpn_connection_get_name (NMVPNConnection *connection)
return setting->id; 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 NMVPNConnectionState
nm_vpn_connection_get_state (NMVPNConnection *connection) nm_vpn_connection_get_state (NMVPNConnection *connection)
{ {
@@ -490,14 +514,6 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection,
reason); 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 static void
@@ -737,12 +753,15 @@ connection_state_changed (NMVPNConnection *connection,
} }
if (priv->ip4_config) { if (priv->ip4_config) {
NMIP4Config *dev_ip4_config;
/* Remove attributes of the VPN's 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); 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 */ /* Reset routes, nameservers, and domains of the currently active device */
nm_device_set_ip4_config (priv->parent_dev, dev_ip4_config = nm_device_get_ip4_config (priv->parent_dev);
NM_IP4_CONFIG (g_object_ref (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) { if (priv->banner) {
@@ -760,23 +779,28 @@ nm_vpn_connection_init (NMVPNConnection *connection)
{ {
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
NMDBusManager *dbus_mgr; NMDBusManager *dbus_mgr;
static guint32 counter = 0;
priv->state = NM_VPN_CONNECTION_STATE_PREPARE; 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_mgr = nm_dbus_manager_get ();
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr), dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
priv->object_path, priv->ac_path,
G_OBJECT (connection)); G_OBJECT (connection));
g_object_unref (dbus_mgr); g_object_unref (dbus_mgr);
} }
static void static void
finalize (GObject *object) dispose (GObject *object)
{ {
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (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->parent_dev) {
if (priv->device_monitor) if (priv->device_monitor)
g_signal_handler_disconnect (priv->parent_dev, 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); g_object_unref (priv->parent_dev);
} }
if (priv->banner)
g_free (priv->banner);
g_free (priv->tundev);
if (priv->ip4_config) if (priv->ip4_config)
g_object_unref (priv->ip4_config); g_object_unref (priv->ip4_config);
@@ -800,7 +819,17 @@ finalize (GObject *object)
g_object_unref (priv->connection); 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); G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object);
} }
@@ -809,18 +838,35 @@ static void
get_property (GObject *object, guint prop_id, get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec) GValue *value, GParamSpec *pspec)
{ {
const char *tmp; NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
switch (prop_id) { switch (prop_id) {
case PROP_NAME: case PROP_SERVICE_NAME:
g_value_set_string (value, nm_vpn_connection_get_name (NM_VPN_CONNECTION (object))); 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; break;
case PROP_STATE: case PROP_STATE:
g_value_set_uint (value, nm_vpn_connection_get_state (NM_VPN_CONNECTION (object))); g_value_set_uint (value, nm_vpn_connection_get_state (NM_VPN_CONNECTION (object)));
break; break;
case PROP_BANNER: case PROP_BANNER:
tmp = nm_vpn_connection_get_banner (NM_VPN_CONNECTION (object)); g_value_set_string (value, priv->banner ? priv->banner : "");
g_value_set_string (value, tmp ? tmp : "");
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -838,16 +884,59 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
/* virtual methods */ /* virtual methods */
connection_class->state_changed = connection_state_changed; connection_class->state_changed = connection_state_changed;
object_class->get_property = get_property; object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize; object_class->finalize = finalize;
/* properties */ /* properties */
g_object_class_install_property g_object_class_install_property
(object_class, PROP_NAME, (object_class, PROP_SERVICE_NAME,
g_param_spec_string (NM_VPN_CONNECTION_NAME, g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME,
"Name", "Service name",
"Connection name", "Service name",
NULL, NULL,
G_PARAM_READABLE)); 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 g_object_class_install_property
(object_class, PROP_STATE, (object_class, PROP_STATE,
@@ -878,6 +967,11 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
G_TYPE_NONE, 2, G_TYPE_NONE, 2,
G_TYPE_UINT, G_TYPE_UINT); G_TYPE_UINT, G_TYPE_UINT);
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (connection_class), signals[PROPERTIES_CHANGED] =
&dbus_glib_nm_vpn_connection_object_info); 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);
} }

View File

@@ -27,6 +27,7 @@
#include <glib-object.h> #include <glib-object.h>
#include "NetworkManagerVPN.h" #include "NetworkManagerVPN.h"
#include "nm-device.h" #include "nm-device.h"
#include "nm-activation-request.h"
#define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ()) #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)) #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_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_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_STATE "state"
#define NM_VPN_CONNECTION_BANNER "banner" #define NM_VPN_CONNECTION_BANNER "banner"
@@ -50,16 +50,20 @@ typedef struct {
void (*state_changed) (NMVPNConnection *connection, void (*state_changed) (NMVPNConnection *connection,
NMVPNConnectionState state, NMVPNConnectionState state,
NMVPNConnectionStateReason reason); NMVPNConnectionStateReason reason);
void (*properties_changed) (NMVPNConnection *connection, GHashTable *properties);
} NMVPNConnectionClass; } NMVPNConnectionClass;
GType nm_vpn_connection_get_type (void); GType nm_vpn_connection_get_type (void);
NMVPNConnection *nm_vpn_connection_new (NMConnection *connection, NMVPNConnection * nm_vpn_connection_new (NMConnection *connection,
NMDevice *parent_device); NMActRequest *act_request,
NMDevice *parent_device);
void nm_vpn_connection_activate (NMVPNConnection *connection); void nm_vpn_connection_activate (NMVPNConnection *connection);
const char *nm_vpn_connection_get_object_path (NMVPNConnection *connection); NMConnection * nm_vpn_connection_get_connection (NMVPNConnection *connection);
const char *nm_vpn_connection_get_name (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); NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *connection);
const char * nm_vpn_connection_get_banner (NMVPNConnection *connection); const char * nm_vpn_connection_get_banner (NMVPNConnection *connection);
void nm_vpn_connection_fail (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, void nm_vpn_connection_disconnect (NMVPNConnection *connection,
NMVPNConnectionStateReason reason); NMVPNConnectionStateReason reason);
#endif /* NM_VPN_CONNECTION_H */ #endif /* NM_VPN_CONNECTION_H */

View File

@@ -6,33 +6,70 @@
#include "nm-vpn-service.h" #include "nm-vpn-service.h"
#include "nm-vpn-connection.h" #include "nm-vpn-connection.h"
#include "nm-setting-vpn.h" #include "nm-setting-vpn.h"
#include "nm-manager.h"
#include "nm-dbus-manager.h" #include "nm-dbus-manager.h"
#include "NetworkManagerVPN.h" #include "NetworkManagerVPN.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-marshal.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"
G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT) 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 { typedef struct {
NMManager *nm_manager;
NMDBusManager *dbus_mgr;
GSList *services; GSList *services;
} NMVPNManagerPrivate; } 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 * static NMVPNService *
nm_vpn_manager_get_service (NMVPNManager *manager, const char *service_name) 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); g_object_weak_ref (G_OBJECT (service), remove_service, manager);
} }
NMVPNConnection * static NMVPNConnection *
nm_vpn_manager_connect (NMVPNManager *manager, find_active_vpn_connection_by_connection (NMVPNManager *manager, NMConnection *connection)
NMConnection *connection,
NMDevice *device)
{ {
NMSettingVPN *vpn_setting; NMVPNManagerPrivate *priv;
NMVPNService *service; GSList *iter;
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL); 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_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; return NULL;
}
vpn_setting = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); 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; 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); service = nm_vpn_manager_get_service (manager, vpn_setting->service_type);
if (!service) { if (!service) {
@@ -92,134 +192,93 @@ nm_vpn_manager_connect (NMVPNManager *manager,
nm_vpn_manager_add_service (manager, service); nm_vpn_manager_add_service (manager, service);
} }
if (service) if (service) {
return nm_vpn_service_activate (service, connection, device); 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 * gboolean
new_vpn_error (const gchar *format, ...) 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; 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); priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
device = nm_manager_get_device_by_path (priv->nm_manager, device_path); for (iter = priv->services; iter; iter = g_slist_next (iter)) {
if (!device) { GSList *connections, *elt;
*err = new_vpn_error ("%s.%d: No active device was found.",
__FILE__, __LINE__); connections = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (iter->data));
goto out; 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)) return found ? TRUE : FALSE;
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;
} }
static void void
get_connections (gpointer data, gpointer user_data) nm_vpn_manager_add_active_connections (NMVPNManager *manager,
NMConnection *filter,
GPtrArray *array)
{ {
NMVPNService *service = NM_VPN_SERVICE (data); NMVPNManagerPrivate *priv;
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;
GSList *iter; GSList *iter;
list = nm_vpn_manager_get_connections (manager); g_return_if_fail (NM_IS_VPN_MANAGER (manager));
*connections = g_ptr_array_sized_new (g_slist_length (list)); g_return_if_fail (array != NULL);
for (iter = list; iter; iter = iter->next) priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
g_ptr_array_add (*connections, for (iter = priv->services; iter; iter = g_slist_next (iter)) {
g_strdup (nm_vpn_connection_get_object_path (NM_VPN_CONNECTION (iter->data)))); 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 * 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); g_assert (singleton);
if (manager) return singleton;
NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager = g_object_ref (nm_manager);
return manager;
} }
/******************************************************************************/ /******************************************************************************/
@@ -227,12 +286,6 @@ nm_vpn_manager_new (NMManager *nm_manager)
static void static void
nm_vpn_manager_init (NMVPNManager *manager) 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 static void
@@ -241,8 +294,6 @@ finalize (GObject *object)
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object); NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
g_slist_foreach (priv->services, (GFunc) g_object_unref, NULL); 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); G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object);
} }
@@ -257,7 +308,17 @@ nm_vpn_manager_class_init (NMVPNManagerClass *manager_class)
/* virtual methods */ /* virtual methods */
object_class->finalize = finalize; object_class->finalize = finalize;
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class), /* signals */
&dbus_glib_nm_vpn_manager_object_info); 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);
} }

View File

@@ -5,8 +5,8 @@
#include <glib/gtypes.h> #include <glib/gtypes.h>
#include <glib-object.h> #include <glib-object.h>
#include "nm-manager.h"
#include "nm-vpn-connection.h" #include "nm-vpn-connection.h"
#include "nm-activation-request.h"
#define NM_TYPE_VPN_MANAGER (nm_vpn_manager_get_type ()) #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(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVPNManager))
@@ -21,17 +21,29 @@ typedef struct {
typedef struct { typedef struct {
GObjectClass parent; GObjectClass parent;
/* Signals */
void (*connection_deactivated) (NMVPNManager *manager,
NMVPNConnection *connection,
NMVPNConnectionState state,
NMVPNConnectionStateReason reason);
} NMVPNManagerClass; } NMVPNManagerClass;
GType nm_vpn_manager_get_type (void); 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, const char *nm_vpn_manager_activate_connection (NMVPNManager *manager,
NMConnection *connection, NMConnection *connection,
NMDevice *device); 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 */ #endif /* NM_VPN_VPN_MANAGER_H */

View File

@@ -311,37 +311,43 @@ connection_state_changed (NMVPNConnection *connection,
NMVPNConnection * NMVPNConnection *
nm_vpn_service_activate (NMVPNService *service, nm_vpn_service_activate (NMVPNService *service,
NMConnection *connection, NMConnection *connection,
NMDevice *device) NMActRequest *act_request,
NMDevice *device,
GError **error)
{ {
NMVPNConnection *vpn_connection; NMVPNConnection *vpn;
NMVPNServicePrivate *priv; NMVPNServicePrivate *priv;
g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL); 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_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 (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); priv = NM_VPN_SERVICE_GET_PRIVATE (service);
vpn_connection = nm_vpn_connection_new (connection, device); vpn = nm_vpn_connection_new (connection, act_request, device);
g_signal_connect (vpn_connection, "state-changed", g_signal_connect (vpn, "state-changed",
G_CALLBACK (connection_state_changed), G_CALLBACK (connection_state_changed),
service); 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)) if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, priv->dbus_service)) {
nm_vpn_connection_activate (vpn_connection); // FIXME: fill in error when errors happen
else if (priv->service_start_timeout == 0) { 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)); nm_info ("VPN service '%s' exec scheduled...", nm_vpn_service_get_name (service));
g_idle_add (nm_vpn_service_daemon_exec, service); g_idle_add (nm_vpn_service_daemon_exec, service);
} }
return vpn_connection; return vpn;
} }
GSList * 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); g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);

View File

@@ -7,6 +7,7 @@
#include <glib-object.h> #include <glib-object.h>
#include "nm-device.h" #include "nm-device.h"
#include "nm-vpn-connection.h" #include "nm-vpn-connection.h"
#include "nm-activation-request.h"
#define NM_TYPE_VPN_SERVICE (nm_vpn_service_get_type ()) #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)) #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); GType nm_vpn_service_get_type (void);
NMVPNService *nm_vpn_service_new (const char *service_name); NMVPNService * nm_vpn_service_new (const char *service_name);
const char *nm_vpn_service_get_name (NMVPNService *service);
NMVPNConnection *nm_vpn_service_activate (NMVPNService *service, const char * nm_vpn_service_get_name (NMVPNService *service);
NMConnection *connection,
NMDevice *device);
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 */ #endif /* NM_VPN_VPN_SERVICE_H */