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>
Patch from Björn Martensen <bjoern.martensen@gmail.com>

View file

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

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-exported-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-plugin.xml"/>

View file

@ -1,20 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<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">
<tp:docstring>
Represents a connection to a Virtual Private Network.
Represents an active connection to a Virtual Private Network.
</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">
<tp:docstring>The state of the VPN connection.</tp:docstring>
</property>
@ -37,6 +49,7 @@
</tp:docstring>
</arg>
</signal>
<tp:enum name="NM_VPN_CONNECTION_STATE" type="u">
<tp:enumvalue suffix="UNKNOWN" value="0">
<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-exported-connection-glue.h \
nm-settings-glue.h \
nm-vpn-manager-bindings.h \
nm-vpn-connection-bindings.h \
nm-vpn-plugin-glue.h \
nm-active-connection-bindings.h
@ -39,7 +38,6 @@ libnminclude_HEADERS = \
nm-gsm-device.h \
nm-cdma-device.h \
nm-vpn-connection.h \
nm-vpn-manager.h \
nm-vpn-plugin.h \
nm-types.h \
nm-active-connection.h
@ -61,7 +59,6 @@ libnm_glib_la_SOURCES = \
nm-gsm-device.c \
nm-cdma-device.c \
nm-vpn-connection.c \
nm-vpn-manager.c \
nm-marshal-main.c \
nm-types.c \
nm-types-private.h \
@ -123,9 +120,6 @@ nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml
nm-exported-connection-glue.h: $(top_srcdir)/introspection/nm-exported-connection.xml
dbus-binding-tool --prefix=nm_exported_connection --mode=glib-server --output=nm-exported-connection-glue.h $(top_srcdir)/introspection/nm-exported-connection.xml
nm-vpn-manager-bindings.h: $(top_srcdir)/introspection/nm-vpn-manager.xml
dbus-binding-tool --prefix=nm_vpn_manager --mode=glib-client --output=nm-vpn-manager-bindings.h $(top_srcdir)/introspection/nm-vpn-manager.xml
nm-vpn-connection-bindings.h: $(top_srcdir)/introspection/nm-vpn-connection.xml
dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-client --output=nm-vpn-connection-bindings.h $(top_srcdir)/introspection/nm-vpn-connection.xml

View file

@ -7,6 +7,7 @@
#include "nm-object-private.h"
#include "nm-types-private.h"
#include "nm-device.h"
#include "nm-connection.h"
#include "nm-active-connection-bindings.h"
@ -22,6 +23,7 @@ typedef struct {
DBusGProxy *proxy;
char *service_name;
NMConnectionScope scope;
char *connection;
char *specific_object;
char *shared_service_name;
@ -60,6 +62,17 @@ nm_active_connection_new (DBusGConnection *connection, const char *path)
NULL);
}
static NMConnectionScope
get_scope_for_service_name (const char *service_name)
{
if (service_name && !strcmp (service_name, NM_DBUS_SERVICE_USER_SETTINGS))
return NM_CONNECTION_SCOPE_USER;
else if (service_name && !strcmp (service_name, NM_DBUS_SERVICE_SYSTEM_SETTINGS))
return NM_CONNECTION_SCOPE_SYSTEM;
return NM_CONNECTION_SCOPE_UNKNOWN;
}
const char *
nm_active_connection_get_service_name (NMActiveConnection *connection)
{
@ -72,11 +85,22 @@ nm_active_connection_get_service_name (NMActiveConnection *connection)
priv->service_name = nm_object_get_string_property (NM_OBJECT (connection),
NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
DBUS_PROP_SERVICE_NAME);
priv->scope = get_scope_for_service_name (priv->service_name);
}
return priv->service_name;
}
NMConnectionScope
nm_active_connection_get_scope (NMActiveConnection *connection)
{
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), NM_CONNECTION_SCOPE_UNKNOWN);
/* Make sure service_name and scope are up-to-date */
nm_active_connection_get_service_name (connection);
return NM_ACTIVE_CONNECTION_GET_PRIVATE (connection)->scope;
}
const char *
nm_active_connection_get_connection (NMActiveConnection *connection)
{
@ -256,12 +280,24 @@ demarshal_devices (NMObject *object, GParamSpec *pspec, GValue *value, gpointer
return TRUE;
}
static gboolean
demarshal_service (NMObject *object, GParamSpec *pspec, GValue *value, gpointer field)
{
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (object);
if (nm_object_demarshal_generic (object, pspec, value, field)) {
priv->scope = get_scope_for_service_name (priv->service_name);
return TRUE;
}
return FALSE;
}
static void
register_for_property_changed (NMActiveConnection *connection)
{
NMActiveConnectionPrivate *priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection);
const NMPropertiesChangedInfo property_changed_info[] = {
{ NM_ACTIVE_CONNECTION_SERVICE_NAME, nm_object_demarshal_generic, &priv->service_name },
{ NM_ACTIVE_CONNECTION_SERVICE_NAME, demarshal_service, &priv->service_name },
{ NM_ACTIVE_CONNECTION_CONNECTION, nm_object_demarshal_generic, &priv->connection },
{ NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT, nm_object_demarshal_generic, &priv->specific_object },
{ NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME, nm_object_demarshal_generic, &priv->shared_service_name },

View file

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

View file

@ -14,6 +14,7 @@
#include "nm-types-private.h"
#include "nm-object-private.h"
#include "nm-active-connection.h"
#include "nm-vpn-connection.h"
#include "nm-object-cache.h"
#include "nm-dbus-glib-types.h"
@ -131,6 +132,46 @@ wireless_enabled_cb (GObject *object, GParamSpec *pspec, gpointer user_data)
poke_wireless_devices_with_rf_status (NM_CLIENT (object));
}
static GObject *
new_active_connection (DBusGConnection *connection, const char *path)
{
DBusGProxy *proxy;
GError *error = NULL;
GValue value = {0,};
GObject *object = NULL;
proxy = dbus_g_proxy_new_for_name (connection,
NM_DBUS_SERVICE,
path,
"org.freedesktop.DBus.Properties");
if (!proxy) {
g_warning ("%s: couldn't create D-Bus object proxy.", __func__);
return NULL;
}
/* Have to create an NMVPNConnection if it's a VPN connection, otherwise
* a plain NMActiveConnection.
*/
if (dbus_g_proxy_call (proxy,
"Get", &error,
G_TYPE_STRING, NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
G_TYPE_STRING, "Vpn",
G_TYPE_INVALID,
G_TYPE_VALUE, &value, G_TYPE_INVALID)) {
if (g_value_get_boolean (&value))
object = nm_vpn_connection_new (connection, path);
else
object = nm_active_connection_new (connection, path);
} else {
g_warning ("Error in getting active connection 'Vpn' property: (%d) %s",
error->code, error->message);
g_error_free (error);
}
g_object_unref (proxy);
return object;
}
static gboolean
demarshal_active_connections (NMObject *object,
GParamSpec *pspec,
@ -140,7 +181,7 @@ demarshal_active_connections (NMObject *object,
DBusGConnection *connection;
connection = nm_object_get_connection (object);
if (!nm_object_array_demarshal (value, (GPtrArray **) field, connection, nm_active_connection_new))
if (!nm_object_array_demarshal (value, (GPtrArray **) field, connection, new_active_connection))
return FALSE;
nm_object_queue_notify (object, NM_CLIENT_ACTIVE_CONNECTIONS);

View file

@ -27,14 +27,14 @@
#include "nm-vpn-connection-bindings.h"
#include "nm-marshal.h"
#include "nm-object-private.h"
#include "nm-active-connection.h"
G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_OBJECT)
G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_ACTIVE_CONNECTION)
#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
typedef struct {
DBusGProxy *proxy;
char *name;
char *banner;
NMVPNConnectionState state;
} NMVPNConnectionPrivate;
@ -48,38 +48,16 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
NMVPNConnection *
nm_vpn_connection_new (DBusGConnection *dbus_connection,
const char *path)
GObject *
nm_vpn_connection_new (DBusGConnection *dbus_connection, const char *path)
{
NMVPNConnection *connection;
g_return_val_if_fail (dbus_connection != NULL, NULL);
g_return_val_if_fail (path != NULL, NULL);
connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION,
NM_OBJECT_DBUS_CONNECTION, dbus_connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
nm_vpn_connection_get_name (connection);
return connection;
}
const char *
nm_vpn_connection_get_name (NMVPNConnection *vpn)
{
NMVPNConnectionPrivate *priv;
g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn);
if (!priv->name)
priv->name = nm_object_get_string_property (NM_OBJECT (vpn),
NM_DBUS_INTERFACE_VPN_CONNECTION,
"Name");
return priv->name;
return g_object_new (NM_TYPE_VPN_CONNECTION,
NM_OBJECT_DBUS_CONNECTION, dbus_connection,
NM_OBJECT_DBUS_PATH, path,
NULL);
}
const char *
@ -136,20 +114,6 @@ state_changed_proxy (DBusGProxy *proxy,
}
}
void
nm_vpn_connection_disconnect (NMVPNConnection *vpn)
{
GError *err = NULL;
g_return_if_fail (NM_IS_VPN_CONNECTION (vpn));
org_freedesktop_NetworkManager_VPN_Connection_disconnect (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy, &err);
if (err) {
nm_warning ("Error in VPN disconnect: %s", err->message);
g_error_free (err);
}
}
/*****************************************************************************/
static void
@ -199,12 +163,11 @@ finalize (GObject *object)
{
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
if (priv->name)
g_free (priv->name);
if (priv->banner)
g_free (priv->banner);
g_object_unref (priv->proxy);
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object);
}

View file

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

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-ip4-config.c \
nm-ip4-config.h \
nm-active-connection.h \
nm-active-connection.c \
NetworkManager.c \
NetworkManagerPolicy.c \
NetworkManagerPolicy.h \

View file

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

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

View file

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

View file

@ -30,7 +30,7 @@
#include "nm-dbus-manager.h"
#include "nm-device.h"
#include "nm-properties-changed-signal.h"
#include "nm-active-connection-glue.h"
#include "nm-active-connection.h"
#include "nm-manager.h" /* FIXME! */
@ -69,6 +69,7 @@ enum {
PROP_SHARED_SERVICE_NAME,
PROP_SHARED_CONNECTION,
PROP_DEVICES,
PROP_VPN,
LAST_PROP
};
@ -82,8 +83,6 @@ nm_act_request_new (NMConnection *connection,
{
GObject *object;
NMActRequestPrivate *priv;
DBusGConnection *g_connection;
static guint32 counter = 0;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (NM_DEVICE (device), NULL);
@ -100,16 +99,22 @@ nm_act_request_new (NMConnection *connection,
priv->device = NM_DEVICE (device);
priv->user_requested = user_requested;
g_connection = nm_dbus_manager_get_connection (nm_dbus_manager_get ());
priv->ac_path = g_strdup_printf (NM_DBUS_PATH "/ActiveConnection/%d", counter++);
dbus_g_connection_register_g_object (g_connection, priv->ac_path, object);
return NM_ACT_REQUEST (object);
}
static void
nm_act_request_init (NMActRequest *req)
{
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (req);
NMDBusManager *dbus_mgr;
priv->ac_path = nm_active_connection_get_next_object_path ();
dbus_mgr = nm_dbus_manager_get ();
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
priv->ac_path,
G_OBJECT (req));
g_object_unref (dbus_mgr);
}
static void
@ -152,27 +157,6 @@ finalize (GObject *object)
G_OBJECT_CLASS (nm_act_request_parent_class)->finalize (object);
}
static void
scope_to_value (NMConnection *connection, GValue *value)
{
if (!connection) {
g_value_set_string (value, "");
return;
}
switch (nm_connection_get_scope (connection)) {
case NM_CONNECTION_SCOPE_SYSTEM:
g_value_set_string (value, NM_DBUS_SERVICE_SYSTEM_SETTINGS);
break;
case NM_CONNECTION_SCOPE_USER:
g_value_set_string (value, NM_DBUS_SERVICE_USER_SETTINGS);
break;
default:
g_warning ("%s: unknown connection scope!", __func__);
break;
}
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
@ -182,7 +166,7 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) {
case PROP_SERVICE_NAME:
scope_to_value (priv->connection, value);
nm_active_connection_scope_to_value (priv->connection, value);
break;
case PROP_CONNECTION:
g_value_set_boxed (value, nm_connection_get_path (priv->connection));
@ -194,7 +178,7 @@ get_property (GObject *object, guint prop_id,
g_value_set_boxed (value, "/");
break;
case PROP_SHARED_SERVICE_NAME:
scope_to_value (priv->shared, value);
nm_active_connection_scope_to_value (priv->shared, value);
break;
case PROP_SHARED_CONNECTION:
if (!priv->shared) {
@ -208,6 +192,9 @@ get_property (GObject *object, guint prop_id,
g_ptr_array_add (devices, g_strdup (nm_device_get_udi (priv->device)));
g_value_take_boxed (value, devices);
break;
case PROP_VPN:
g_value_set_boolean (value, FALSE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -269,6 +256,13 @@ nm_act_request_class_init (NMActRequestClass *req_class)
"Devices",
dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_VPN,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN,
"VPN",
"Is a VPN connection",
FALSE,
G_PARAM_READABLE));
/* Signals */
signals[CONNECTION_SECRETS_UPDATED] =
@ -295,8 +289,7 @@ nm_act_request_class_init (NMActRequestClass *req_class)
nm_properties_changed_signal_new (object_class,
G_STRUCT_OFFSET (NMActRequestClass, properties_changed));
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (req_class),
&dbus_glib_nm_active_connection_object_info);
nm_active_connection_install_type_info (object_class);
}
typedef struct GetSecretsInfo {

View file

@ -25,6 +25,7 @@
#include <glib/gtypes.h>
#include <glib-object.h>
#include "nm-connection.h"
#include "nm-active-connection.h"
#define NM_TYPE_ACT_REQUEST (nm_act_request_get_type ())
#define NM_ACT_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_ACT_REQUEST, NMActRequest))
@ -33,13 +34,6 @@
#define NM_IS_ACT_REQUEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_ACT_REQUEST))
#define NM_ACT_REQUEST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_ACT_REQUEST, NMActRequestClass))
#define NM_ACTIVE_CONNECTION_SERVICE_NAME "service-name"
#define NM_ACTIVE_CONNECTION_CONNECTION "connection"
#define NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT "specific-object"
#define NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME "shared-service-name"
#define NM_ACTIVE_CONNECTION_SHARED_CONNECTION "shared-connection"
#define NM_ACTIVE_CONNECTION_DEVICES "devices"
typedef struct {
GObject parent;
} NMActRequest;

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

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

View file

@ -28,9 +28,6 @@ libvpn_manager_la_LIBADD = \
$(top_builddir)/src/marshallers/libmarshallers.la \
$(top_builddir)/libnm-util/libnm-util.la
nm-vpn-manager-glue.h: $(top_srcdir)/introspection/nm-vpn-manager.xml
dbus-binding-tool --prefix=nm_vpn_manager --mode=glib-server --output=nm-vpn-manager-glue.h $(top_srcdir)/introspection/nm-vpn-manager.xml
nm-vpn-connection-glue.h: $(top_srcdir)/introspection/nm-vpn-connection.xml
dbus-binding-tool --prefix=nm_vpn_connection --mode=glib-server --output=nm-vpn-connection-glue.h $(top_srcdir)/introspection/nm-vpn-connection.xml
@ -39,7 +36,6 @@ nm-vpn-plugin-bindings.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml
built_sources = \
nm-vpn-manager-glue.h \
nm-vpn-connection-glue.h \
nm-vpn-plugin-bindings.h

View file

@ -18,7 +18,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2005 Red Hat, Inc.
* (C) Copyright 2008 Red Hat, Inc.
*/
@ -39,8 +39,8 @@
#include "nm-utils.h"
#include "nm-vpn-plugin-bindings.h"
#include "nm-marshal.h"
static gboolean impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err);
#include "nm-active-connection.h"
#include "nm-properties-changed-signal.h"
#define CONNECTION_GET_SECRETS_CALL_TAG "get-secrets-call"
@ -49,10 +49,13 @@ static gboolean impl_vpn_connection_disconnect (NMVPNConnection *connection, GEr
G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
typedef struct {
gboolean disposed;
NMConnection *connection;
NMActRequest *act_request;
NMDevice *parent_dev;
char *object_path;
char *ac_path;
NMVPNConnectionState state;
gulong device_monitor;
DBusGProxy *proxy;
@ -65,6 +68,7 @@ typedef struct {
#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
enum {
PROPERTIES_CHANGED,
STATE_CHANGED,
LAST_SIGNAL
@ -74,7 +78,13 @@ static guint signals[LAST_SIGNAL] = { 0 };
enum {
PROP_0,
PROP_NAME,
PROP_SERVICE_NAME,
PROP_CONNECTION,
PROP_SPECIFIC_OBJECT,
PROP_SHARED_SERVICE_NAME,
PROP_SHARED_CONNECTION,
PROP_DEVICES,
PROP_VPN,
PROP_STATE,
PROP_BANNER,
@ -116,12 +126,14 @@ device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
NMVPNConnection *
nm_vpn_connection_new (NMConnection *connection,
NMDevice *parent_device)
NMActRequest *act_request,
NMDevice *parent_device)
{
NMVPNConnection *vpn_connection;
NMVPNConnectionPrivate *priv;
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL);
g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
vpn_connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
@ -131,6 +143,7 @@ nm_vpn_connection_new (NMConnection *connection,
priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn_connection);
priv->connection = g_object_ref (connection);
priv->act_request = g_object_ref (act_request);
priv->parent_dev = g_object_ref (parent_device);
priv->device_monitor = g_signal_connect (parent_device, "state-changed",
@ -167,24 +180,27 @@ plugin_state_changed (DBusGProxy *proxy,
{
NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
nm_debug ("plugin state changed: %d", state);
nm_info ("VPN plugin state changed: %d", state);
if (state == NM_VPN_SERVICE_STATE_STOPPED) {
switch (nm_vpn_connection_get_state (connection)) {
case NM_VPN_CONNECTION_STATE_CONNECT:
case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
nm_vpn_connection_set_state (connection,
NM_VPN_CONNECTION_STATE_FAILED,
NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
break;
case NM_VPN_CONNECTION_STATE_ACTIVATED:
nm_vpn_connection_set_state (connection,
NM_VPN_CONNECTION_STATE_DISCONNECTED,
NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
break;
default:
break;
}
if (state != NM_VPN_SERVICE_STATE_STOPPED)
return;
switch (nm_vpn_connection_get_state (connection)) {
case NM_VPN_CONNECTION_STATE_PREPARE:
case NM_VPN_CONNECTION_STATE_NEED_AUTH:
case NM_VPN_CONNECTION_STATE_CONNECT:
case NM_VPN_CONNECTION_STATE_IP_CONFIG_GET:
nm_vpn_connection_set_state (connection,
NM_VPN_CONNECTION_STATE_FAILED,
NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
break;
case NM_VPN_CONNECTION_STATE_ACTIVATED:
nm_vpn_connection_set_state (connection,
NM_VPN_CONNECTION_STATE_DISCONNECTED,
NM_VPN_CONNECTION_STATE_REASON_SERVICE_STOPPED);
break;
default:
break;
}
}
@ -431,11 +447,11 @@ nm_vpn_connection_activate (NMVPNConnection *connection)
}
const char *
nm_vpn_connection_get_object_path (NMVPNConnection *connection)
nm_vpn_connection_get_active_connection_path (NMVPNConnection *connection)
{
g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->object_path;
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->ac_path;
}
const char *
@ -452,6 +468,14 @@ nm_vpn_connection_get_name (NMVPNConnection *connection)
return setting->id;
}
NMConnection *
nm_vpn_connection_get_connection (NMVPNConnection *connection)
{
g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->connection;
}
NMVPNConnectionState
nm_vpn_connection_get_state (NMVPNConnection *connection)
{
@ -490,14 +514,6 @@ nm_vpn_connection_disconnect (NMVPNConnection *connection,
reason);
}
static gboolean
impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err)
{
nm_vpn_connection_disconnect (connection, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED);
return TRUE;
}
/******************************************************************************/
static void
@ -737,12 +753,15 @@ connection_state_changed (NMVPNConnection *connection,
}
if (priv->ip4_config) {
NMIP4Config *dev_ip4_config;
/* Remove attributes of the VPN's IP4 Config */
nm_system_vpn_device_unset_from_ip4_config (priv->parent_dev, priv->tundev, priv->ip4_config);
/* Reset routes, nameservers, and domains of the currently active device */
nm_device_set_ip4_config (priv->parent_dev,
NM_IP4_CONFIG (g_object_ref (nm_device_get_ip4_config (priv->parent_dev))));
dev_ip4_config = nm_device_get_ip4_config (priv->parent_dev);
if (dev_ip4_config)
nm_device_set_ip4_config (priv->parent_dev, g_object_ref (dev_ip4_config));
}
if (priv->banner) {
@ -760,23 +779,28 @@ nm_vpn_connection_init (NMVPNConnection *connection)
{
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
NMDBusManager *dbus_mgr;
static guint32 counter = 0;
priv->state = NM_VPN_CONNECTION_STATE_PREPARE;
priv->object_path = g_strdup_printf (NM_DBUS_PATH_VPN_CONNECTION "/%d", counter++);
priv->ac_path = nm_active_connection_get_next_object_path ();
dbus_mgr = nm_dbus_manager_get ();
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
priv->object_path,
priv->ac_path,
G_OBJECT (connection));
g_object_unref (dbus_mgr);
}
static void
finalize (GObject *object)
dispose (GObject *object)
{
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
if (priv->disposed) {
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object);
return;
}
priv->disposed = TRUE;
if (priv->parent_dev) {
if (priv->device_monitor)
g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor);
@ -784,11 +808,6 @@ finalize (GObject *object)
g_object_unref (priv->parent_dev);
}
if (priv->banner)
g_free (priv->banner);
g_free (priv->tundev);
if (priv->ip4_config)
g_object_unref (priv->ip4_config);
@ -800,7 +819,17 @@ finalize (GObject *object)
g_object_unref (priv->connection);
g_free (priv->object_path);
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->dispose (object);
}
static void
finalize (GObject *object)
{
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
g_free (priv->banner);
g_free (priv->tundev);
g_free (priv->ac_path);
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object);
}
@ -809,18 +838,35 @@ static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
const char *tmp;
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, nm_vpn_connection_get_name (NM_VPN_CONNECTION (object)));
case PROP_SERVICE_NAME:
nm_active_connection_scope_to_value (priv->connection, value);
break;
case PROP_CONNECTION:
g_value_set_boxed (value, nm_connection_get_path (priv->connection));
break;
case PROP_SPECIFIC_OBJECT:
g_value_set_boxed (value, nm_act_request_get_active_connection_path (priv->act_request));
break;
case PROP_SHARED_SERVICE_NAME:
g_value_set_string (value, "");
break;
case PROP_SHARED_CONNECTION:
g_value_set_boxed (value, "/");
break;
case PROP_DEVICES:
g_value_take_boxed (value, g_ptr_array_new ());
break;
case PROP_VPN:
g_value_set_boolean (value, TRUE);
break;
case PROP_STATE:
g_value_set_uint (value, nm_vpn_connection_get_state (NM_VPN_CONNECTION (object)));
break;
case PROP_BANNER:
tmp = nm_vpn_connection_get_banner (NM_VPN_CONNECTION (object));
g_value_set_string (value, tmp ? tmp : "");
g_value_set_string (value, priv->banner ? priv->banner : "");
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -838,16 +884,59 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
/* virtual methods */
connection_class->state_changed = connection_state_changed;
object_class->get_property = get_property;
object_class->dispose = dispose;
object_class->finalize = finalize;
/* properties */
g_object_class_install_property
(object_class, PROP_NAME,
g_param_spec_string (NM_VPN_CONNECTION_NAME,
"Name",
"Connection name",
NULL,
G_PARAM_READABLE));
(object_class, PROP_SERVICE_NAME,
g_param_spec_string (NM_ACTIVE_CONNECTION_SERVICE_NAME,
"Service name",
"Service name",
NULL,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_CONNECTION,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_CONNECTION,
"Connection",
"Connection",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_SPECIFIC_OBJECT,
g_param_spec_string (NM_ACTIVE_CONNECTION_SPECIFIC_OBJECT,
"Specific object",
"Specific object",
NULL,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_SHARED_SERVICE_NAME,
g_param_spec_string (NM_ACTIVE_CONNECTION_SHARED_SERVICE_NAME,
"Shared service name",
"Shared service name",
NULL,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_SHARED_CONNECTION,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_SHARED_CONNECTION,
"Shared connection",
"Shared connection",
DBUS_TYPE_G_OBJECT_PATH,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_DEVICES,
g_param_spec_boxed (NM_ACTIVE_CONNECTION_DEVICES,
"Devices",
"Devices",
dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH),
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_VPN,
g_param_spec_boolean (NM_ACTIVE_CONNECTION_VPN,
"VPN",
"Is a VPN connection",
TRUE,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_STATE,
@ -878,6 +967,11 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
G_TYPE_NONE, 2,
G_TYPE_UINT, G_TYPE_UINT);
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (connection_class),
&dbus_glib_nm_vpn_connection_object_info);
signals[PROPERTIES_CHANGED] =
nm_properties_changed_signal_new (object_class,
G_STRUCT_OFFSET (NMVPNConnectionClass, properties_changed));
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (object_class),
&dbus_glib_nm_vpn_connection_object_info);
}

View file

@ -27,6 +27,7 @@
#include <glib-object.h>
#include "NetworkManagerVPN.h"
#include "nm-device.h"
#include "nm-activation-request.h"
#define NM_TYPE_VPN_CONNECTION (nm_vpn_connection_get_type ())
#define NM_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnection))
@ -35,7 +36,6 @@
#define NM_IS_VPN_CONNECTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_CONNECTION))
#define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
#define NM_VPN_CONNECTION_NAME "name"
#define NM_VPN_CONNECTION_STATE "state"
#define NM_VPN_CONNECTION_BANNER "banner"
@ -50,16 +50,20 @@ typedef struct {
void (*state_changed) (NMVPNConnection *connection,
NMVPNConnectionState state,
NMVPNConnectionStateReason reason);
void (*properties_changed) (NMVPNConnection *connection, GHashTable *properties);
} NMVPNConnectionClass;
GType nm_vpn_connection_get_type (void);
NMVPNConnection *nm_vpn_connection_new (NMConnection *connection,
NMDevice *parent_device);
NMVPNConnection * nm_vpn_connection_new (NMConnection *connection,
NMActRequest *act_request,
NMDevice *parent_device);
void nm_vpn_connection_activate (NMVPNConnection *connection);
const char *nm_vpn_connection_get_object_path (NMVPNConnection *connection);
const char *nm_vpn_connection_get_name (NMVPNConnection *connection);
NMConnection * nm_vpn_connection_get_connection (NMVPNConnection *connection);
const char * nm_vpn_connection_get_active_connection_path (NMVPNConnection *connection);
const char * nm_vpn_connection_get_name (NMVPNConnection *connection);
NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *connection);
const char * nm_vpn_connection_get_banner (NMVPNConnection *connection);
void nm_vpn_connection_fail (NMVPNConnection *connection,
@ -67,5 +71,4 @@ void nm_vpn_connection_fail (NMVPNConnection *connect
void nm_vpn_connection_disconnect (NMVPNConnection *connection,
NMVPNConnectionStateReason reason);
#endif /* NM_VPN_CONNECTION_H */

View file

@ -6,33 +6,70 @@
#include "nm-vpn-service.h"
#include "nm-vpn-connection.h"
#include "nm-setting-vpn.h"
#include "nm-manager.h"
#include "nm-dbus-manager.h"
#include "NetworkManagerVPN.h"
#include "nm-utils.h"
static gboolean impl_vpn_manager_connect (NMVPNManager *manager,
const char *connection_type,
const char *connection_path,
const char *device_path,
char **connection,
GError **err);
static gboolean impl_vpn_manager_get_connections (NMVPNManager *manager,
GPtrArray **connections,
GError **err);
#include "nm-vpn-manager-glue.h"
#include "nm-marshal.h"
G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT)
#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate))
typedef struct {
NMManager *nm_manager;
NMDBusManager *dbus_mgr;
GSList *services;
} NMVPNManagerPrivate;
#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate))
enum {
CONNECTION_DEACTIVATED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
typedef enum
{
NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE = 0,
NM_VPN_MANAGER_ERROR_CONNECTION_INVALID,
NM_VPN_MANAGER_ERROR_SERVICE_INVALID,
} NMVPNManagerError;
#define NM_VPN_MANAGER_ERROR (nm_vpn_manager_error_quark ())
#define NM_TYPE_VPN_MANAGER_ERROR (nm_vpn_manager_error_get_type ())
static GQuark
nm_vpn_manager_error_quark (void)
{
static GQuark quark = 0;
if (!quark)
quark = g_quark_from_static_string ("nm-vpn-manager-error");
return quark;
}
/* This should really be standard. */
#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
static GType
nm_vpn_manager_error_get_type (void)
{
static GType etype = 0;
if (etype == 0) {
static const GEnumValue values[] = {
/* The base device for the VPN connection is not active. */
ENUM_ENTRY (NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE, "BaseDeviceNotActive"),
/* The requested VPN connection was invalid. */
ENUM_ENTRY (NM_VPN_MANAGER_ERROR_CONNECTION_INVALID, "ConnectionInvalid"),
/* The VPN service required by this VPN connection did not exist or was invalid. */
ENUM_ENTRY (NM_VPN_MANAGER_ERROR_SERVICE_INVALID, "ServiceInvalid"),
{ 0, 0, 0 }
};
etype = g_enum_register_static ("NMVPNManagerError", values);
}
return etype;
}
static NMVPNService *
nm_vpn_manager_get_service (NMVPNManager *manager, const char *service_name)
@ -66,24 +103,87 @@ nm_vpn_manager_add_service (NMVPNManager *manager, NMVPNService *service)
g_object_weak_ref (G_OBJECT (service), remove_service, manager);
}
NMVPNConnection *
nm_vpn_manager_connect (NMVPNManager *manager,
NMConnection *connection,
NMDevice *device)
static NMVPNConnection *
find_active_vpn_connection_by_connection (NMVPNManager *manager, NMConnection *connection)
{
NMSettingVPN *vpn_setting;
NMVPNService *service;
NMVPNManagerPrivate *priv;
GSList *iter;
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED)
priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
for (iter = priv->services; iter; iter = g_slist_next (iter)) {
GSList *connections, *elt;
connections = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (iter->data));
for (elt = connections; elt; elt = g_slist_next (elt)) {
NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data);
if (nm_vpn_connection_get_connection (vpn) == connection)
return vpn;
}
}
return NULL;
}
static void
connection_state_changed (NMVPNConnection *connection,
NMVPNConnectionState state,
NMVPNConnectionStateReason reason,
gpointer user_data)
{
NMVPNManager *manager = NM_VPN_MANAGER (user_data);
switch (state) {
case NM_VPN_CONNECTION_STATE_FAILED:
case NM_VPN_CONNECTION_STATE_DISCONNECTED:
g_signal_emit (manager, signals[CONNECTION_DEACTIVATED], 0, connection, state, reason);
break;
default:
break;
}
}
const char *
nm_vpn_manager_activate_connection (NMVPNManager *manager,
NMConnection *connection,
NMActRequest *act_request,
NMDevice *device,
GError **error)
{
NMSettingVPN *vpn_setting;
NMVPNService *service;
char *path = NULL;
NMVPNConnection *vpn;
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
g_return_val_if_fail (NM_IS_CONNECTION (connection), NULL);
g_return_val_if_fail (NM_IS_ACT_REQUEST (act_request), NULL);
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
g_return_val_if_fail (error != NULL, NULL);
g_return_val_if_fail (*error == NULL, NULL);
if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED) {
g_set_error (error,
NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_DEVICE_NOT_ACTIVE,
"%s", "The base device for the VPN connection was not active.");
return NULL;
}
vpn_setting = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN);
if (!vpn_setting)
if (!vpn_setting) {
g_set_error (error,
NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_CONNECTION_INVALID,
"%s", "The connection was not a VPN connection.");
return NULL;
}
vpn = find_active_vpn_connection_by_connection (manager, connection);
if (vpn) {
nm_vpn_connection_disconnect (vpn, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED);
vpn = NULL;
}
service = nm_vpn_manager_get_service (manager, vpn_setting->service_type);
if (!service) {
@ -92,134 +192,93 @@ nm_vpn_manager_connect (NMVPNManager *manager,
nm_vpn_manager_add_service (manager, service);
}
if (service)
return nm_vpn_service_activate (service, connection, device);
if (service) {
vpn = nm_vpn_service_activate (service, connection, act_request, device, error);
if (vpn) {
path = (char *) nm_vpn_connection_get_active_connection_path (vpn);
g_signal_connect (vpn, "state-changed",
G_CALLBACK (connection_state_changed),
manager);
}
} else {
g_set_error (error,
NM_VPN_MANAGER_ERROR, NM_VPN_MANAGER_ERROR_SERVICE_INVALID,
"%s", "The VPN service was invalid.");
}
return NULL;
return path;
}
static GError *
new_vpn_error (const gchar *format, ...)
gboolean
nm_vpn_manager_deactivate_connection (NMVPNManager *manager, const char *path)
{
GError *err;
va_list args;
gchar *msg;
static GQuark domain_quark = 0;
if (domain_quark == 0)
domain_quark = g_quark_from_static_string ("nm_vpn_error");
va_start (args, format);
msg = g_strdup_vprintf (format, args);
va_end (args);
err = g_error_new_literal (domain_quark, 1, (const gchar *) msg);
g_free (msg);
return err;
}
static gboolean
impl_vpn_manager_connect (NMVPNManager *manager,
const char *connection_type,
const char *connection_path,
const char *device_path,
char **vpn_connection_path,
GError **err)
{
NMDevice *device;
NMConnection *connection = NULL;
NMVPNConnection *vpn_connection = NULL;
NMVPNManagerPrivate *priv;
GSList *iter;
gboolean found = FALSE;
*vpn_connection_path = NULL;
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), FALSE);
g_return_val_if_fail (path != NULL, FALSE);
priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
device = nm_manager_get_device_by_path (priv->nm_manager, device_path);
if (!device) {
*err = new_vpn_error ("%s.%d: No active device was found.",
__FILE__, __LINE__);
goto out;
for (iter = priv->services; iter; iter = g_slist_next (iter)) {
GSList *connections, *elt;
connections = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (iter->data));
for (elt = connections; elt; elt = g_slist_next (elt)) {
NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data);
const char *vpn_path;
vpn_path = nm_vpn_connection_get_active_connection_path (vpn);
if (!strcmp (path, vpn_path)) {
nm_vpn_connection_disconnect (vpn, NM_VPN_CONNECTION_STATE_REASON_USER_DISCONNECTED);
found = TRUE;
}
}
}
if (!strcmp (connection_type, NM_DBUS_SERVICE_USER_SETTINGS))
connection = nm_manager_get_connection_by_object_path (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager,
NM_CONNECTION_SCOPE_USER,
connection_path);
else if (!strcmp (connection_type, NM_DBUS_SERVICE_SYSTEM_SETTINGS))
connection = nm_manager_get_connection_by_object_path (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager,
NM_CONNECTION_SCOPE_SYSTEM,
connection_path);
if (connection == NULL) {
*err = new_vpn_error ("%s.%d: VPN connection could not be found.",
__FILE__, __LINE__);
goto out;
}
vpn_connection = nm_vpn_manager_connect (manager, connection, device);
if (vpn_connection)
*vpn_connection_path = g_strdup (nm_vpn_connection_get_object_path (vpn_connection));
else {
*err = new_vpn_error ("%s.%d: VPN connection could not be started.",
__FILE__, __LINE__);
}
out:
return *vpn_connection_path != NULL;
return found ? TRUE : FALSE;
}
static void
get_connections (gpointer data, gpointer user_data)
void
nm_vpn_manager_add_active_connections (NMVPNManager *manager,
NMConnection *filter,
GPtrArray *array)
{
NMVPNService *service = NM_VPN_SERVICE (data);
GSList **list = (GSList **) user_data;
*list = g_slist_concat (*list, nm_vpn_service_get_connections (service));
}
GSList *
nm_vpn_manager_get_connections (NMVPNManager *manager)
{
GSList *list = NULL;
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
g_slist_foreach (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, get_connections, &list);
return list;
}
static gboolean
impl_vpn_manager_get_connections (NMVPNManager *manager, GPtrArray **connections, GError **err)
{
GSList *list;
NMVPNManagerPrivate *priv;
GSList *iter;
list = nm_vpn_manager_get_connections (manager);
*connections = g_ptr_array_sized_new (g_slist_length (list));
g_return_if_fail (NM_IS_VPN_MANAGER (manager));
g_return_if_fail (array != NULL);
for (iter = list; iter; iter = iter->next)
g_ptr_array_add (*connections,
g_strdup (nm_vpn_connection_get_object_path (NM_VPN_CONNECTION (iter->data))));
priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
for (iter = priv->services; iter; iter = g_slist_next (iter)) {
GSList *active, *elt;
g_slist_free (list);
active = nm_vpn_service_get_active_connections (NM_VPN_SERVICE (iter->data));
for (elt = active; elt; elt = g_slist_next (elt)) {
NMVPNConnection *vpn = NM_VPN_CONNECTION (elt->data);
const char *path;
return TRUE;
if (!filter || (nm_vpn_connection_get_connection (vpn) == filter)) {
path = nm_vpn_connection_get_active_connection_path (vpn);
g_ptr_array_add (array, g_strdup (path));
}
}
}
}
NMVPNManager *
nm_vpn_manager_new (NMManager *nm_manager)
nm_vpn_manager_get (void)
{
NMVPNManager *manager;
static NMVPNManager *singleton = NULL;
g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
if (!singleton)
singleton = NM_VPN_MANAGER (g_object_new (NM_TYPE_VPN_MANAGER, NULL));
else
g_object_ref (singleton);
manager = (NMVPNManager *) g_object_new (NM_TYPE_VPN_MANAGER, NULL);
if (manager)
NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_manager = g_object_ref (nm_manager);
return manager;
g_assert (singleton);
return singleton;
}
/******************************************************************************/
@ -227,12 +286,6 @@ nm_vpn_manager_new (NMManager *nm_manager)
static void
nm_vpn_manager_init (NMVPNManager *manager)
{
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
priv->dbus_mgr = nm_dbus_manager_get ();
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr),
NM_DBUS_PATH_VPN,
G_OBJECT (manager));
}
static void
@ -241,8 +294,6 @@ finalize (GObject *object)
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
g_slist_foreach (priv->services, (GFunc) g_object_unref, NULL);
g_object_unref (priv->dbus_mgr);
g_object_unref (priv->nm_manager);
G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object);
}
@ -257,7 +308,17 @@ nm_vpn_manager_class_init (NMVPNManagerClass *manager_class)
/* virtual methods */
object_class->finalize = finalize;
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class),
&dbus_glib_nm_vpn_manager_object_info);
/* signals */
signals[CONNECTION_DEACTIVATED] =
g_signal_new ("connection-deactivated",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMVPNManagerClass, connection_deactivated),
NULL, NULL,
nm_marshal_VOID__OBJECT_UINT_UINT,
G_TYPE_NONE, 3,
G_TYPE_OBJECT, G_TYPE_UINT, G_TYPE_UINT);
dbus_g_error_domain_register (NM_VPN_MANAGER_ERROR, NULL, NM_TYPE_VPN_MANAGER_ERROR);
}

View file

@ -5,8 +5,8 @@
#include <glib/gtypes.h>
#include <glib-object.h>
#include "nm-manager.h"
#include "nm-vpn-connection.h"
#include "nm-activation-request.h"
#define NM_TYPE_VPN_MANAGER (nm_vpn_manager_get_type ())
#define NM_VPN_MANAGER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_MANAGER, NMVPNManager))
@ -21,17 +21,29 @@ typedef struct {
typedef struct {
GObjectClass parent;
/* Signals */
void (*connection_deactivated) (NMVPNManager *manager,
NMVPNConnection *connection,
NMVPNConnectionState state,
NMVPNConnectionStateReason reason);
} NMVPNManagerClass;
GType nm_vpn_manager_get_type (void);
NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager);
NMVPNManager *nm_vpn_manager_get (void);
NMVPNConnection *nm_vpn_manager_connect (NMVPNManager *manager,
NMConnection *connection,
NMDevice *device);
const char *nm_vpn_manager_activate_connection (NMVPNManager *manager,
NMConnection *connection,
NMActRequest *act_request,
NMDevice *device,
GError **error);
GSList *nm_vpn_manager_get_connections (NMVPNManager *manager);
gboolean nm_vpn_manager_deactivate_connection (NMVPNManager *manager,
const char *path);
void nm_vpn_manager_add_active_connections (NMVPNManager *manager,
NMConnection *filter,
GPtrArray *list);
#endif /* NM_VPN_VPN_MANAGER_H */

View file

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

View file

@ -7,6 +7,7 @@
#include <glib-object.h>
#include "nm-device.h"
#include "nm-vpn-connection.h"
#include "nm-activation-request.h"
#define NM_TYPE_VPN_SERVICE (nm_vpn_service_get_type ())
#define NM_VPN_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_SERVICE, NMVPNService))
@ -25,13 +26,16 @@ typedef struct {
GType nm_vpn_service_get_type (void);
NMVPNService *nm_vpn_service_new (const char *service_name);
const char *nm_vpn_service_get_name (NMVPNService *service);
NMVPNService * nm_vpn_service_new (const char *service_name);
NMVPNConnection *nm_vpn_service_activate (NMVPNService *service,
NMConnection *connection,
NMDevice *device);
const char * nm_vpn_service_get_name (NMVPNService *service);
GSList *nm_vpn_service_get_connections (NMVPNService *service);
NMVPNConnection * nm_vpn_service_activate (NMVPNService *service,
NMConnection *connection,
NMActRequest *act_request,
NMDevice *device,
GError **error);
GSList * nm_vpn_service_get_active_connections (NMVPNService *service);
#endif /* NM_VPN_VPN_SERVICE_H */