+2007-09-12 Tambet Ingo <tambet@gmail.com>
+
+ * src/vpn-manager/nm-vpn-connection.[ch]:
+ * src/vpn-manager/nm-vpn-manager.[ch]:
+ * src/vpn-manager/nm-vpn-service.[ch]: Rewrite the vpn handling code. Using
+ dbus-glib, GObjects, signals etc.
+
+ * libnm-glib/nm-vpn-manager.[ch]:
+ * libnm-glib/nm-vpn-connection.[ch]: Now that the NM implementation changed
+ so much, rewrite these too.
+
+ * libnm-glib/Makefile.am: Add new files to build, build new binding files for
+ the new introspection files.
+
+ * libnm-glib/nm-client.[ch]: Remove all VPN related stuff from here.
+
+ * libnm-glib/nm-dbus-utils.[ch]: Renamed from nm-utils.[ch] that was shadowing
+ the header with the same name from libnm-utils.
+
+ * libnm-glib/nm-vpn-plugin.[ch]: Implement.
+
+ * libnm-util/Makefile.am: Add nm-utils.[ch] to build.
+
+ * introspection/nm-vpn-plugin.xml: Implement.
+
+ * introspection/nm-vpn-connection.xml: Implement.
+
+ * introspection/nm-vpn-manager.xml: Implement.
+
+ * src/NetworkManagerSystem.c (nm_system_vpn_device_set_from_ip4_config): Remove
+ the named manager argument, it can just as easily get it as the caller.
+ (nm_system_vpn_device_unset_from_ip4_config): Ditto.
+
+ * src/vpn-manager/nm-dbus-vpn.[ch]: Remove.
+
+ * src/nm-dbus-manager.h: Fix up the name_owner signal signature.
+
+ * src/dhcp-manager/nm-dhcp-manager.c (garray_to_string): Remove, use one from
+ libnm-utils.
+
+ * libnm-util/nm-connection.c: Ditto.
+
+ * src/NetworkManagerMain.h: Remove, it's finally empty.
+
+ * configure.in: Remove utils/ from build.
+
+ * include/NetworkManagerVPN.h: Add some more defines to reduce the amount
+ of hard-coded strings.
+
+ * utils/: Move it over to libnm-util.
+
+ * test/Makefile.am: Link against libnm-util now that util/ is gone.
+
+ * dispatcher-daemon/Makefile.am: Ditto.
+
+ * src/Makefile.am: Ditto.
+
2007-09-12 Dan Williams <dcbw@redhat.com>
Wireless connections can be made with config data from the applet now.
SUBDIRS = \
- utils \
libnm-util \
libnm-glib \
src \
AC_OUTPUT([
Makefile
include/Makefile
-utils/Makefile
src/Makefile
src/named-manager/Makefile
src/vpn-manager/Makefile
NetworkManagerDispatcher_CPPFLAGS = \
-I$(top_srcdir) \
- -I$(top_srcdir)/utils \
-I$(top_srcdir)/include \
-I$(top_srcdir)/libnm-util \
-I$(top_srcdir)/libnm-glib \
$(NULL)
NetworkManagerDispatcher_LDADD = \
- $(top_builddir)/utils/libnmutils.la \
$(top_builddir)/libnm-util/libnm-util.la\
$(top_builddir)/libnm-glib/libnm_glib.la\
$(DBUS_LIBS) \
/*
* dbus services details
*/
-#define NM_DBUS_PATH_VPN "/org/freedesktop/NetworkManager/VPNConnections"
-#define NM_DBUS_INTERFACE_VPN "org.freedesktop.NetworkManager.VPNConnections"
+#define NM_DBUS_PATH_VPN "/org/freedesktop/NetworkManager/VPN/Manager"
+#define NM_DBUS_INTERFACE_VPN "org.freedesktop.NetworkManager.VPN.Manager"
+#define NM_DBUS_PATH_VPN_CONNECTION "/org/freedesktop/NetworkManager/VPN/Connection"
+#define NM_DBUS_INTERFACE_VPN_CONNECTION "org.freedesktop.NetworkManager.VPN.Connection"
+
+#define NM_VPN_DBUS_PLUGIN_PATH "/org/freedesktop/NetworkManager/VPN/Plugin"
+#define NM_VPN_DBUS_PLUGIN_INTERFACE "org.freedesktop.NetworkManager.VPN.Plugin"
/*
* VPN Errors
typedef enum NMVPNConnectionState
{
NM_VPN_CONNECTION_STATE_UNKNOWN = 0,
- NM_VPN_CONNECTION_STATE_DISCONNECTED,
NM_VPN_CONNECTION_STATE_PREPARE,
NM_VPN_CONNECTION_STATE_CONNECT,
NM_VPN_CONNECTION_STATE_IP_CONFIG_GET,
NM_VPN_CONNECTION_STATE_ACTIVATED,
NM_VPN_CONNECTION_STATE_FAILED,
- NM_VPN_CONNECTION_STATE_CANCELED
+ NM_VPN_CONNECTION_STATE_DISCONNECTED,
} NMVPNConnectionState;
+#define NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY "gateway"
+#define NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS "address"
+#define NM_VPN_PLUGIN_IP4_CONFIG_PTP "ptp"
+#define NM_VPN_PLUGIN_IP4_CONFIG_NETMASK "netmask"
+#define NM_VPN_PLUGIN_IP4_CONFIG_DNS "dns"
+#define NM_VPN_PLUGIN_IP4_CONFIG_NBNS "nbns"
+#define NM_VPN_PLUGIN_IP4_CONFIG_MSS "mss"
+#define NM_VPN_PLUGIN_IP4_CONFIG_MTU "mtu"
+#define NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV "tundev"
+#define NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN "domain"
+#define NM_VPN_PLUGIN_IP4_CONFIG_BANNER "banner"
+
#endif /* NETWORK_MANAGER_VPN_H */
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.NetworkManager.VPN.Connection">
+ <method name="Disconnect">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_connection_disconnect"/>
+ </method>
+
+ <property name="Name" type="s" access="read"/>
+ <property name="State" type="u" access="read"/>
+
+ <signal name="StateChanged">
+ <arg name="state" type="u"/>
+ </signal>
+ </interface>
+</node>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.NetworkManager.VPN.Manager">
+ <method name="Connect">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_manager_connect"/>
+ <arg name="type" type="s" direction="in"/>
+ <arg name="name" type="s" direction="in"/>
+ <arg name="properties" type="a{sv}" direction="in"/>
+ <arg name="device" type="o" direction="in"/>
+ <arg name="routes" type="as" direction="in"/>
+ <arg name="connection" type="o" direction="out"/>
+ </method>
+
+ <method name="ListConnections">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_manager_get_connections"/>
+ <arg name="connections" type="ao" direction="out"/>
+ </method>
+
+ </interface>
+</node>
+
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<node name="/">
+ <interface name="org.freedesktop.NetworkManager.VPN.Plugin">
+ <method name="Connect">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_plugin_connect"/>
+ <arg name="connection" type="a{sv}" direction="in"/>
+ <arg name="routes" type="as" direction="in"/>
+ </method>
+
+ <method name="Disconnect">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_plugin_disconnect"/>
+ </method>
+
+ <method name="SetIp4Config">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_plugin_set_ip4_config"/>
+ <arg name="config" type="a{sv}" direction="in"/>
+ </method>
+
+ <method name="SetFailure">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="impl_vpn_plugin_set_failure"/>
+ <arg name="reason" type="s" direction="in"/>
+ </method>
+
+ <property name="State" type="u" access="read"/>
+
+ <signal name="StateChanged">
+ <arg name="state" type="u"/>
+ </signal>
+
+ <signal name="Ip4Config">
+ <arg name="ip4config" type="a{sv}"/>
+ </signal>
+
+ <signal name="LoginBanner">
+ <arg name="banner" type="s"/>
+ </signal>
+
+ <signal name="Failure">
+ <arg name="reason" type="u"/>
+ </signal>
+
+ </interface>
+</node>
-INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/utils -I$(top_srcdir)/libnm-util
+INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/libnm-util
BUILT_SOURCES = \
nm-access-point-bindings.h \
nm-marshal.h \
nm-marshal.c \
nm-settings-connection-glue.h \
- nm-settings-glue.h
+ nm-settings-glue.h \
+ nm-vpn-manager-bindings.h \
+ nm-vpn-connection-bindings.h \
+ nm-vpn-plugin-glue.h
-lib_LTLIBRARIES = libnm_glib.la
+lib_LTLIBRARIES = libnm_glib.la libnm_glib_vpn.la
libnm_glib_la_CFLAGS = \
$(GLIB_CFLAGS) \
nm-access-point.h \
nm-ip4-config.h \
nm-settings.h \
- nm-vpn-connection.h
+ nm-vpn-connection.h \
+ nm-vpn-manager.h \
+ nm-vpn-plugin.h
libnm_glib_la_SOURCES = \
libnm_glib.c \
nm-object.c \
nm-client.c \
+ nm-dbus-utils.c \
+ nm-dbus-utils.h \
nm-device.c \
nm-device-private.h \
nm-device-802-3-ethernet.c \
nm-ip4-config.c \
nm-settings.c \
nm-vpn-connection.c \
+ nm-vpn-manager.c \
nm-marshal-main.c
libnm_glib_la_LIBADD = \
- $(top_builddir)/utils/libnmutils.la \
$(top_builddir)/libnm-util/libnm-util.la \
$(GLIB_LIBS) \
$(GTHREAD_LIBS) \
libnm_glib_test_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS)
libnm_glib_test_LDADD = libnm_glib.la $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) $(DBUS_LIBS)
+libnm_glib_vpn_la_SOURCES = nm-vpn-plugin.c
+libnm_glib_vpn_la_CFLAGS = $(GLIB_CFLAGS) $(DBUS_CFLAGS)
+libnm_glib_vpn_la_LIBADD = $(top_builddir)/libnm-util/libnm-util.la $(GLIB_LIBS) $(DBUS_LIBS)
+
+
nm-marshal.h: Makefile.am nm-marshal.list
$(GLIB_GENMARSHAL) --prefix=nm_marshal $(srcdir)/nm-marshal.list --header > \
xgen-gmh \
nm-settings-connection-glue.h: $(top_srcdir)/introspection/nm-settings-connection.xml
dbus-binding-tool --prefix=nm_connection_settings --mode=glib-server --output=nm-settings-connection-glue.h $(top_srcdir)/introspection/nm-settings-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
+
+nm-vpn-plugin-glue.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml
+ dbus-binding-tool --prefix=nm_vpn_plugin --mode=glib-server --output=nm-vpn-plugin-glue.h $(top_srcdir)/introspection/nm-vpn-plugin.xml
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnm_glib.pc
NMState state;
gboolean have_device_list;
GHashTable *devices;
-
- DBusGProxy *vpn_proxy;
- NMVPNConnectionState vpn_state;
- gboolean have_vpn_connections;
- GHashTable *vpn_connections;
} NMClientPrivate;
enum {
DEVICE_REMOVED,
STATE_CHANGE,
- VPN_CONNECTION_ADDED,
- VPN_CONNECTION_REMOVED,
- VPN_STATE_CHANGE,
-
LAST_SIGNAL
};
static void client_device_added_proxy (DBusGProxy *proxy, char *path, gpointer user_data);
static void client_device_removed_proxy (DBusGProxy *proxy, char *path, gpointer user_data);
-static void setup_vpn_proxy (NMClient *client, DBusGConnection *connection);
-static void clear_vpn_connections (NMClient * client);
-
static void
nm_client_init (NMClient *client)
{
priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) g_object_unref);
-
- priv->vpn_connections = g_hash_table_new_full (g_str_hash, g_str_equal,
- (GDestroyNotify) g_free,
- NULL);
-
- priv->vpn_state = NM_VPN_CONNECTION_STATE_UNKNOWN;
}
static GObject*
object,
NULL);
- setup_vpn_proxy (NM_CLIENT (object), connection);
-
priv->bus_proxy = dbus_g_proxy_new_for_name (connection,
"org.freedesktop.DBus",
"/org/freedesktop/DBus",
{
NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (object);
- g_object_unref (priv->vpn_proxy);
g_object_unref (priv->client_proxy);
g_object_unref (priv->bus_proxy);
g_hash_table_destroy (priv->devices);
- g_hash_table_destroy (priv->vpn_connections);
}
static void
priv->state = NM_STATE_UNKNOWN;
g_hash_table_remove_all (priv->devices);
priv->have_device_list = FALSE;
-
- clear_vpn_connections (client);
- priv->have_vpn_connections = FALSE;
}
}
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1,
G_TYPE_UINT);
-
- signals[VPN_CONNECTION_ADDED] =
- g_signal_new ("vpn-connection-added",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMClientClass, vpn_connection_added),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
-
- signals[VPN_CONNECTION_REMOVED] =
- g_signal_new ("vpn-connection-removed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMClientClass, vpn_connection_removed),
- NULL, NULL,
- g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1,
- G_TYPE_OBJECT);
-
- signals[VPN_STATE_CHANGE] =
- g_signal_new ("vpn-state-change",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMClientClass, state_change),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1,
- G_TYPE_UINT);
}
NMClient *
g_error_free (err);
}
}
-
-/* VPN */
-
-/*
- * This "best" state is the summary of all states from all connections and
- * available for convenience.
- * For the exact state, each connection has it's own state which' changes
- * are also signalled.
- */
-static NMVPNConnectionState
-nm_client_get_best_vpn_state (NMClient *client)
-{
- GSList *iter, *list;
- NMVPNConnectionState state;
- NMVPNConnectionState best_state = NM_VPN_CONNECTION_STATE_UNKNOWN;
-
- list = nm_client_get_vpn_connections (client);
- for (iter = list; iter; iter = iter->next) {
- state = nm_vpn_connection_get_state (NM_VPN_CONNECTION (iter->data));
- if (state > best_state && state < NM_VPN_CONNECTION_STATE_FAILED)
- best_state = state;
- }
- g_slist_free (list);
-
- return best_state;
-}
-
-static void
-proxy_vpn_state_change (DBusGProxy *proxy,
- char *connection_name,
- NMVPNConnectionState state,
- gpointer user_data)
-{
- NMClient *client = NM_CLIENT (user_data);
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
- NMVPNConnection *connection;
- NMVPNConnectionState best_state;
-
- connection = nm_client_get_vpn_connection_by_name (client, connection_name);
- if (connection)
- nm_vpn_connection_set_state (connection, state);
-
- best_state = nm_client_get_best_vpn_state (client);
- if (best_state != priv->vpn_state) {
- priv->vpn_state = state;
- g_signal_emit (client, signals[VPN_STATE_CHANGE], 0, best_state);
- }
-}
-
-static void
-proxy_vpn_connection_added (DBusGProxy *proxy, char *name, gpointer user_data)
-{
- NMClient *client = NM_CLIENT (user_data);
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
- NMVPNConnection *connection;
-
- if (g_hash_table_lookup (priv->vpn_connections, name))
- return;
-
- connection = nm_vpn_connection_new (proxy, name);
- if (connection == NULL) {
- g_log (G_LOG_DOMAIN,
- G_LOG_LEVEL_WARNING,
- "Warning: out of memory creating NMVPNConnection for '%s'\n",
- name);
- return;
- }
-
- g_hash_table_insert (priv->vpn_connections, g_strdup (name), connection);
- g_signal_emit (client, signals[VPN_CONNECTION_ADDED], 0, connection);
-}
-
-static void
-proxy_vpn_connection_removed (DBusGProxy *proxy, char *name, gpointer user_data)
-{
- NMClient *client = NM_CLIENT (user_data);
- NMVPNConnection *connection;
-
- connection = nm_client_get_vpn_connection_by_name (client, name);
- if (connection)
- nm_client_remove_vpn_connection (client, connection);
-}
-
-static void
-proxy_vpn_connection_update (DBusGProxy *proxy, char *name, gpointer user_data)
-{
- NMClient *client = NM_CLIENT (user_data);
- NMVPNConnection *connection;
-
- connection = nm_client_get_vpn_connection_by_name (client, name);
- if (connection)
- nm_vpn_connection_update (connection);
-}
-
-static void
-setup_vpn_proxy (NMClient *client, DBusGConnection *connection)
-{
- DBusGProxy *proxy;
-
- proxy = dbus_g_proxy_new_for_name (connection,
- NM_DBUS_SERVICE,
- NM_DBUS_PATH_VPN,
- NM_DBUS_INTERFACE_VPN);
-
- dbus_g_object_register_marshaller (nm_marshal_VOID__STRING_INT,
- G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID);
-
- dbus_g_proxy_add_signal (proxy, "VPNConnectionStateChange", G_TYPE_STRING, G_TYPE_UINT, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (proxy, "VPNConnectionStateChange",
- G_CALLBACK (proxy_vpn_state_change),
- client, NULL);
-
- dbus_g_proxy_add_signal (proxy, "VPNConnectionAdded", G_TYPE_STRING, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (proxy, "VPNConnectionAdded",
- G_CALLBACK (proxy_vpn_connection_added),
- client, NULL);
-
- dbus_g_proxy_add_signal (proxy, "VPNConnectionRemoved", G_TYPE_STRING, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (proxy, "VPNConnectionRemoved",
- G_CALLBACK (proxy_vpn_connection_removed),
- client, NULL);
-
- dbus_g_proxy_add_signal (proxy, "VPNConnectionUpdate", G_TYPE_STRING, G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (proxy, "VPNConnectionUpdate",
- G_CALLBACK (proxy_vpn_connection_update),
- client, NULL);
-
- NM_CLIENT_GET_PRIVATE (client)->vpn_proxy = proxy;
-}
-
-static void
-get_connections (NMClient *client)
-{
- NMClientPrivate *priv = NM_CLIENT_GET_PRIVATE (client);
- char **name;
- char **vpn_names = NULL;
- GError *err = NULL;
-
- if (!dbus_g_proxy_call (priv->vpn_proxy, "getVPNConnections", &err,
- G_TYPE_INVALID,
- G_TYPE_STRV, &vpn_names,
- G_TYPE_INVALID)) {
- g_warning ("Error while getting VPN connections: %s", err->message);
- g_error_free (err);
- return;
- }
-
- for (name = vpn_names; *name; name++)
- proxy_vpn_connection_added (priv->vpn_proxy, *name, client);
- g_strfreev (vpn_names);
-}
-
-static void
-signal_one_vpn_connection_removed (gpointer data,
- gpointer user_data)
-{
- NMClient * client = NM_CLIENT (user_data);
- NMVPNConnection * connection = NM_VPN_CONNECTION (data);
-
- g_signal_emit (client, signals[VPN_CONNECTION_REMOVED], 0, connection);
-}
-
-static void
-clear_vpn_connections (NMClient * client)
-{
- NMClientPrivate * priv;
- GSList * list;
-
- g_return_if_fail (NM_IS_CLIENT (client));
-
- priv = NM_CLIENT_GET_PRIVATE (client);
-
- list = nm_client_get_vpn_connections (client);
- g_hash_table_remove_all (priv->vpn_connections);
-
- g_slist_foreach (list, signal_one_vpn_connection_removed, client);
- g_slist_foreach (list, (GFunc) g_object_unref, NULL);
- g_slist_free (list);
-}
-
-static void
-vpn_connections_to_slist (gpointer key, gpointer value, gpointer user_data)
-{
- GSList **list = (GSList **) user_data;
-
- *list = g_slist_prepend (*list, value);
-}
-
-GSList *
-nm_client_get_vpn_connections (NMClient *client)
-{
- NMClientPrivate *priv;
- GSList * list = NULL;
-
- g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
-
- priv = NM_CLIENT_GET_PRIVATE (client);
-
- if (!priv->have_vpn_connections) {
- get_connections (client);
- priv->have_vpn_connections = TRUE;
- }
-
- g_hash_table_foreach (priv->vpn_connections,
- vpn_connections_to_slist,
- &list);
- return list;
-}
-
-NMVPNConnection *
-nm_client_get_vpn_connection_by_name (NMClient *client, const char *name)
-{
- NMClientPrivate *priv;
- GSList * list;
-
- g_return_if_fail (NM_IS_CLIENT (client));
-
- priv = NM_CLIENT_GET_PRIVATE (client);
-
- /* Ensure list of VPN connections is current */
- list = nm_client_get_vpn_connections (client);
- g_slist_free (list);
-
- return g_hash_table_lookup (priv->vpn_connections, name);
-}
-
-struct find_info {
- char * found_key;
- NMVPNConnection * connection;
-};
-
-static void
-find_connection (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- struct find_info * info = (struct find_info *) user_data;
-
- if (info->connection == value)
- info->found_key = key;
-}
-
-void
-nm_client_remove_vpn_connection (NMClient *client, NMVPNConnection *connection)
-{
- NMClientPrivate *priv;
- struct find_info info = { NULL, NULL };
-
- g_return_if_fail (NM_IS_CLIENT (client));
- g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
-
- /* Note that the connection isn't removed from NetworkManager, it's
- because it doesn't have DBUS API for that right now. */
-
- priv = NM_CLIENT_GET_PRIVATE (client);
-
- info.connection = connection;
- g_hash_table_foreach (priv->vpn_connections, find_connection, &info);
- if (!info.found_key) {
- g_log (G_LOG_DOMAIN,
- G_LOG_LEVEL_WARNING,
- "Warning: tried to remove unknown NMVPNConnection object %p\n",
- connection);
- return;
- }
-
- g_hash_table_remove (priv->vpn_connections, info.found_key);
- g_signal_emit (client, signals[VPN_CONNECTION_REMOVED], 0, connection);
- g_object_unref (connection);
-}
-
-NMVPNConnectionState
-nm_client_get_vpn_state (NMClient *client)
-{
- NMClientPrivate *priv;
-
- g_return_val_if_fail (NM_IS_CLIENT (client), NM_VPN_CONNECTION_STATE_UNKNOWN);
-
- priv = NM_CLIENT_GET_PRIVATE (client);
-
- if (priv->vpn_state == NM_VPN_CONNECTION_STATE_UNKNOWN)
- priv->vpn_state = nm_client_get_best_vpn_state (client);
-
- return priv->vpn_state;
-}
#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-vpn-connection.h"
G_BEGIN_DECLS
void (*device_added) (NMClient *client, NMDevice *device);
void (*device_removed) (NMClient *client, NMDevice *device);
void (*state_change) (NMClient *client, NMState state);
-
- void (*vpn_connection_added) (NMClient *client, NMVPNConnection *connection);
- void (*vpn_connection_removed) (NMClient *client, NMVPNConnection *connection);
- void (*vpn_state_change) (NMClient *client, NMVPNConnectionState state);
} NMClientClass;
GType nm_client_get_type (void);
NMState nm_client_get_state (NMClient *client);
void nm_client_sleep (NMClient *client, gboolean sleep);
-/* VPN */
-
-GSList *nm_client_get_vpn_connections (NMClient *client);
-NMVPNConnection *nm_client_get_vpn_connection_by_name (NMClient *client,
- const char *name);
-
-void nm_client_remove_vpn_connection (NMClient *client,
- NMVPNConnection *connection);
-
-NMVPNConnectionState nm_client_get_vpn_state (NMClient *client);
-
G_END_DECLS
#endif /* NM_CLIENT_H */
-#include "nm-utils.h"
+#include "nm-dbus-utils.h"
char *
nm_dbus_get_string_property (DBusGProxy *proxy,
#define NM_SETTINGS_H 1
#include <glib-object.h>
+#include <dbus/dbus-glib.h>
G_BEGIN_DECLS
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw@redhat.com>
#include <string.h>
#include "nm-vpn-connection.h"
+#include "NetworkManager.h"
+#include "nm-utils.h"
+#include "nm-vpn-connection-bindings.h"
-G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
+G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, NM_TYPE_OBJECT)
#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 *user_name;
- char *service;
NMVPNConnectionState state;
} NMVPNConnectionPrivate;
enum {
- UPDATED,
STATE_CHANGED,
LAST_SIGNAL
static guint signals[LAST_SIGNAL] = { 0 };
-static void
-nm_vpn_connection_init (NMVPNConnection *connection)
-{
- NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
-
- priv->state = NM_VPN_CONNECTION_STATE_UNKNOWN;
-}
-
-static void
-finalize (GObject *object)
-{
- NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
-
- g_free (priv->name);
- g_free (priv->user_name);
- g_free (priv->service);
-}
-static void
-nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
+NMVPNConnection *
+nm_vpn_connection_new (DBusGConnection *dbus_connection,
+ const char *path)
{
- GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
+ NMVPNConnection *connection;
- g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
+ g_return_val_if_fail (dbus_connection != NULL, NULL);
+ g_return_val_if_fail (path != NULL, NULL);
- /* virtual methods */
- object_class->finalize = finalize;
+ connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION,
+ NM_OBJECT_CONNECTION, dbus_connection,
+ NM_OBJECT_PATH, path,
+ NULL);
- /* signals */
- signals[UPDATED] =
- g_signal_new ("updated",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMVPNConnectionClass, updated),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- signals[STATE_CHANGED] =
- g_signal_new ("state-changed",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (NMVPNConnectionClass, state_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__UINT,
- G_TYPE_NONE, 1,
- G_TYPE_UINT);
+ nm_vpn_connection_get_name (connection);
+ return connection;
}
-static gboolean
-update_properties (NMVPNConnection *connection)
+const char *
+nm_vpn_connection_get_name (NMVPNConnection *vpn)
{
NMVPNConnectionPrivate *priv;
- char *name = NULL;
- char *user_name = NULL;
- char *service = NULL;
- NMVPNConnectionState state;
- GError *err = NULL;
- priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
-
- if (!dbus_g_proxy_call (priv->proxy, "getVPNConnectionProperties", &err,
- G_TYPE_STRING, priv->name,
- G_TYPE_INVALID,
- G_TYPE_STRING, &name,
- G_TYPE_STRING, &user_name,
- G_TYPE_STRING, &service,
- G_TYPE_UINT, &state,
- G_TYPE_INVALID)) {
- g_warning ("Error while updating VPN connection: %s", err->message);
- g_error_free (err);
- return FALSE;
- }
-
- g_free (priv->name);
- g_free (priv->user_name);
- g_free (priv->service);
-
- priv->name = name;
- priv->user_name = user_name;
- priv->service = service;
-
- nm_vpn_connection_set_state (connection, (NMVPNConnectionState) state);
+ g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
- return TRUE;
+ 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;
}
-NMVPNConnection *
-nm_vpn_connection_new (DBusGProxy *proxy, const char *name)
+NMVPNConnectionState
+nm_vpn_connection_get_state (NMVPNConnection *vpn)
{
- GObject *object;
- NMVPNConnectionPrivate *priv;
-
- g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL);
- g_return_val_if_fail (name != NULL, NULL);
-
- object = g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
- if (!object)
- return NULL;
-
- priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
- priv->proxy = proxy;
- priv->name = g_strdup (name);
-
- if (!update_properties ((NMVPNConnection *) object)) {
- g_object_unref (object);
- return NULL;
- }
+ g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NM_VPN_CONNECTION_STATE_UNKNOWN);
- return (NMVPNConnection *) object;
+ return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->state;
}
-gboolean
-nm_vpn_connection_update (NMVPNConnection *vpn)
+static void
+state_changed_proxy (DBusGProxy *proxy, NMVPNConnectionState state, gpointer user_data)
{
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
+ NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
- if (update_properties (vpn)) {
- g_signal_emit (vpn, signals[UPDATED], 0);
- return TRUE;
+ if (priv->state != state) {
+ priv->state = state;
+ g_signal_emit (connection, signals[STATE_CHANGED], 0, state);
}
-
- return FALSE;
}
-const char *
-nm_vpn_connection_get_name (NMVPNConnection *vpn)
+void
+nm_vpn_connection_disconnect (NMVPNConnection *vpn)
{
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
-
- return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->name;
-}
+ GError *err = NULL;
-const char *
-nm_vpn_connection_get_user_name (NMVPNConnection *vpn)
-{
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
+ g_return_if_fail (NM_IS_VPN_CONNECTION (vpn));
- return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->user_name;
+ 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);
+ }
}
-const char *
-nm_vpn_connection_get_service (NMVPNConnection *vpn)
-{
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
-
- return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->service;
-}
+/*****************************************************************************/
-NMVPNConnectionState
-nm_vpn_connection_get_state (NMVPNConnection *vpn)
+static void
+nm_vpn_connection_init (NMVPNConnection *connection)
{
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NM_VPN_CONNECTION_STATE_UNKNOWN);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
- return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->state;
+ priv->state = NM_VPN_CONNECTION_STATE_UNKNOWN;
}
-void
-nm_vpn_connection_set_state (NMVPNConnection *vpn, NMVPNConnectionState state)
+static GObject*
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
{
+ NMObject *object;
NMVPNConnectionPrivate *priv;
- g_return_if_fail (NM_IS_VPN_CONNECTION (vpn));
+ object = (NMObject *) G_OBJECT_CLASS (nm_vpn_connection_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+ if (!object)
+ return NULL;
- priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn);
- if (priv->state != state) {
- priv->state = state;
- g_signal_emit (vpn, signals[STATE_CHANGED], 0, state);
- }
+ priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
+
+ priv->proxy = dbus_g_proxy_new_for_name (nm_object_get_connection (object),
+ NM_DBUS_SERVICE,
+ nm_object_get_path (object),
+ NM_DBUS_INTERFACE_VPN_CONNECTION);
+
+ dbus_g_proxy_add_signal (priv->proxy, "StateChanged", G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy,
+ "StateChanged",
+ G_CALLBACK (state_changed_proxy),
+ object,
+ NULL);
+ return G_OBJECT (object);
}
-gboolean
-nm_vpn_connection_is_activating (NMVPNConnection *vpn)
+static void
+finalize (GObject *object)
{
- NMVPNConnectionState state;
-
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
-
- state = nm_vpn_connection_get_state (vpn);
- if (state == NM_VPN_CONNECTION_STATE_PREPARE ||
- state == NM_VPN_CONNECTION_STATE_CONNECT ||
- state == NM_VPN_CONNECTION_STATE_IP_CONFIG_GET)
- return TRUE;
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
- return FALSE;
+ g_object_unref (priv->proxy);
}
-gboolean
-nm_vpn_connection_activate (NMVPNConnection *vpn, GSList *passwords)
+static void
+nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
{
- char **password_strings;
- GSList *iter;
- int i;
-
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
- g_return_val_if_fail (passwords != NULL, FALSE);
-
- if (nm_vpn_connection_get_state (vpn) != NM_VPN_CONNECTION_STATE_DISCONNECTED) {
- g_warning ("VPN connection is already connected or connecting");
- return FALSE;
- }
+ GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
- i = 0;
- password_strings = g_new (char *, g_slist_length (passwords) + 1);
- for (iter = passwords; iter; iter = iter->next)
- password_strings[i++] = iter->data;
- password_strings[i] = NULL;
-
- /* FIXME: This has to be ASYNC for now since NM will call back to get routes.
- We should just pass the routes along with this call */
- dbus_g_proxy_call_no_reply (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy,
- "activateVPNConnection",
- G_TYPE_STRING, nm_vpn_connection_get_name (vpn),
- G_TYPE_STRV, password_strings,
- G_TYPE_INVALID,
- G_TYPE_INVALID);
- g_free (password_strings);
-
- return TRUE;
-}
+ g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
-gboolean
-nm_vpn_connection_deactivate (NMVPNConnection *vpn)
-{
- g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
+ /* virtual methods */
+ object_class->constructor = constructor;
+ object_class->finalize = finalize;
- if (nm_vpn_connection_get_state (vpn) != NM_VPN_CONNECTION_STATE_ACTIVATED &&
- !nm_vpn_connection_is_activating (vpn)) {
- g_warning ("VPN connection isn't activated");
- return FALSE;
- }
-
- dbus_g_proxy_call_no_reply (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy,
- "deactivateVPNConnection",
- G_TYPE_INVALID, G_TYPE_INVALID);
- return TRUE;
+ /* signals */
+ signals[STATE_CHANGED] =
+ g_signal_new ("state-changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMVPNConnectionClass, state_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
}
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
/* NetworkManager Wireless Applet -- Display wireless access points and allow user control
*
* Dan Williams <dcbw@redhat.com>
#include <glib/gtypes.h>
#include <glib-object.h>
#include <dbus/dbus-glib.h>
+#include "nm-object.h"
#include "NetworkManagerVPN.h"
G_BEGIN_DECLS
#define NM_VPN_CONNECTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
typedef struct {
- GObject parent;
+ NMObject parent;
} NMVPNConnection;
typedef struct {
- GObjectClass parent;
+ NMObjectClass parent;
/* Signals */
- void (*updated) (NMVPNConnection *connection);
void (*state_changed) (NMVPNConnection *connection, NMVPNConnectionState state);
} NMVPNConnectionClass;
GType nm_vpn_connection_get_type (void);
-NMVPNConnection *nm_vpn_connection_new (DBusGProxy *proxy, const char *name);
-gboolean nm_vpn_connection_update (NMVPNConnection *vpn);
+NMVPNConnection *nm_vpn_connection_new (DBusGConnection *dbus_connection,
+ const char *path);
-const char *nm_vpn_connection_get_name (NMVPNConnection *vpn);
-const char *nm_vpn_connection_get_user_name (NMVPNConnection *vpn);
-const char *nm_vpn_connection_get_service (NMVPNConnection *vpn);
-NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *vpn);
-gboolean nm_vpn_connection_is_activating (NMVPNConnection *vpn);
+const char *nm_vpn_connection_get_name (NMVPNConnection *vpn);
+NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *vpn);
-gboolean nm_vpn_connection_activate (NMVPNConnection *vpn,
- GSList *passwords);
-
-gboolean nm_vpn_connection_deactivate (NMVPNConnection *vpn);
-
-void nm_vpn_connection_set_state (NMVPNConnection *vpn, NMVPNConnectionState state);
+void nm_vpn_connection_disconnect (NMVPNConnection *vpn);
G_END_DECLS
--- /dev/null
+/* -*- 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_CONNECTION, connection,
+ NM_OBJECT_PATH, NM_DBUS_PATH_VPN,
+ NULL);
+
+}
+
+NMVPNConnection *
+nm_vpn_manager_connect (NMVPNManager *manager,
+ const char *type,
+ const char *name,
+ GHashTable *properties,
+ NMDevice *device,
+ char **routes)
+{
+ char *connection_path = NULL;
+ GError *err = NULL;
+
+ g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
+ g_return_val_if_fail (type != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (properties != NULL, 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,
+ type, name,
+ properties,
+ nm_object_get_path (NM_OBJECT (device)),
+ routes,
+ &connection_path,
+ &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)), connection_path);
+}
+
+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);
+}
+
+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;
+}
--- /dev/null
+/* -*- 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-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 *type,
+ const char *name,
+ GHashTable *properties,
+ NMDevice *device,
+ char **routes);
+
+GSList *nm_vpn_manager_get_connections (NMVPNManager *manager);
+
+G_END_DECLS
+
+#endif /* NM_MANAGER_H */
--- /dev/null
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#include <signal.h>
+#include "nm-vpn-plugin.h"
+#include "nm-utils.h"
+
+static gboolean impl_vpn_plugin_connect (NMVPNPlugin *plugin,
+ GHashTable *connection,
+ char **routes,
+ GError **err);
+
+static gboolean impl_vpn_plugin_disconnect (NMVPNPlugin *plugin,
+ GError **err);
+
+static gboolean impl_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
+ GHashTable *config,
+ GError **err);
+
+static gboolean impl_vpn_plugin_set_failure (NMVPNPlugin *plugin,
+ char *reason,
+ GError **err);
+
+#include "nm-vpn-plugin-glue.h"
+
+#define NM_VPN_PLUGIN_CONNECT_TIMER 60000
+#define NM_VPN_PLUGIN_QUIT_TIMER 20000
+
+G_DEFINE_ABSTRACT_TYPE (NMVPNPlugin, nm_vpn_plugin, G_TYPE_OBJECT)
+
+typedef struct {
+ NMVPNServiceState state;
+
+ /* DBUS-y stuff */
+ DBusGConnection *connection;
+ char *dbus_service_name;
+
+ /* GObject-y stuff */
+ gboolean disposed;
+
+ /* Temporary stuff */
+ guint connect_timer;
+ guint quit_timer;
+} NMVPNPluginPrivate;
+
+#define NM_VPN_PLUGIN_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_PLUGIN, NMVPNPluginPrivate))
+
+enum {
+ STATE_CHANGED,
+ IP4_CONFIG,
+ LOGIN_BANNER,
+ FAILURE,
+ QUIT,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+enum {
+ PROP_0,
+ PROP_DBUS_SERVICE_NAME,
+ PROP_STATE,
+
+ LAST_PROP
+};
+
+static GSList *active_plugins = NULL;
+
+
+GQuark
+nm_vpn_plugin_error_quark (void)
+{
+ static GQuark quark = 0;
+
+ if (!quark)
+ quark = g_quark_from_static_string ("nm_vpn_plugin_error");
+
+ return quark;
+}
+
+#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC }
+
+GType
+nm_vpn_plugin_error_get_type (void)
+{
+ static GType etype = 0;
+
+ if (etype == 0) {
+ static const GEnumValue values[] = {
+ ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_GENERAL, "General"),
+ ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS, "StartingInProgress"),
+ ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_ALREADY_STARTED, "AlreadyStarted"),
+ ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS, "StoppingInProgress"),
+ ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED, "AlreadyStopped"),
+ ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_WRONG_STATE, "WrongState"),
+ ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, "BadArguments"),
+ ENUM_ENTRY (NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED, "LaunchFailed"),
+ { 0, 0, 0 }
+ };
+
+ etype = g_enum_register_static ("NMVPNPluginError", values);
+ }
+
+ return etype;
+}
+
+
+static void
+nm_vpn_plugin_set_connection (NMVPNPlugin *plugin,
+ DBusGConnection *connection)
+{
+ NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+
+ if (priv->connection)
+ dbus_g_connection_unref (priv->connection);
+
+ priv->connection = connection;
+}
+
+DBusGConnection *
+nm_vpn_plugin_get_connection (NMVPNPlugin *plugin)
+{
+ DBusGConnection *connection;
+
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), NULL);
+
+ connection = NM_VPN_PLUGIN_GET_PRIVATE (plugin)->connection;
+
+ if (connection)
+ dbus_g_connection_ref (connection);
+
+ return connection;
+}
+
+NMVPNServiceState
+nm_vpn_plugin_get_state (NMVPNPlugin *plugin)
+{
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), NM_VPN_SERVICE_STATE_UNKNOWN);
+
+ return NM_VPN_PLUGIN_GET_PRIVATE (plugin)->state;
+}
+
+void
+nm_vpn_plugin_set_state (NMVPNPlugin *plugin,
+ NMVPNServiceState state)
+{
+ NMVPNPluginPrivate *priv;
+
+ g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
+
+ priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+ if (priv->state != state) {
+ priv->state = state;
+ g_signal_emit (plugin, signals[STATE_CHANGED], 0, state);
+ }
+}
+
+void
+nm_vpn_plugin_set_login_banner (NMVPNPlugin *plugin,
+ const char *banner)
+{
+ g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
+ g_return_if_fail (banner != NULL);
+
+ g_signal_emit (plugin, signals[LOGIN_BANNER], 0, banner);
+}
+
+void
+nm_vpn_plugin_failure (NMVPNPlugin *plugin,
+ NMVPNPluginFailure reason)
+{
+ g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
+
+ g_signal_emit (plugin, signals[FAILURE], 0, reason);
+}
+
+gboolean
+nm_vpn_plugin_disconnect (NMVPNPlugin *plugin, GError **err)
+{
+ gboolean ret = FALSE;
+ NMVPNServiceState state;
+
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
+
+ state = nm_vpn_plugin_get_state (plugin);
+ switch (state) {
+ case NM_VPN_SERVICE_STATE_STOPPING:
+ g_set_error (err,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
+ "%s",
+ "Could not process the request because the VPN connection is already being stopped.");
+ break;
+ case NM_VPN_SERVICE_STATE_STOPPED:
+ g_set_error (err,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED,
+ "%s",
+ "Could not process the request because no VPN connection was active.");
+ break;
+ case NM_VPN_SERVICE_STATE_STARTING:
+ case NM_VPN_SERVICE_STATE_STARTED:
+ nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPING);
+ ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->disconnect (plugin, err);
+ nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ return ret;
+}
+
+static void
+nm_vpn_plugin_emit_quit (NMVPNPlugin *plugin)
+{
+ g_signal_emit (plugin, signals[QUIT], 0);
+}
+
+static gboolean
+connect_timer_expired (gpointer data)
+{
+ NMVPNPlugin *plugin = NM_VPN_PLUGIN (data);
+ GError *err = NULL;
+
+ nm_info ("Connect timer expired, disconnecting.");
+ nm_vpn_plugin_disconnect (plugin, &err);
+ if (err) {
+ nm_warning ("Disconnect failed: %s", err->message);
+ g_error_free (err);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+quit_timer_expired (gpointer data)
+{
+ NMVPNPlugin *plugin = NM_VPN_PLUGIN (data);
+
+ nm_vpn_plugin_emit_quit (plugin);
+
+ return FALSE;
+}
+
+static gboolean
+nm_vpn_plugin_connect (NMVPNPlugin *plugin,
+ GHashTable *properties,
+ char **routes,
+ GError **err)
+{
+ gboolean ret = FALSE;
+ NMVPNServiceState state;
+
+ g_return_val_if_fail (NM_IS_VPN_PLUGIN (plugin), FALSE);
+
+ state = nm_vpn_plugin_get_state (plugin);
+ switch (state) {
+ case NM_VPN_SERVICE_STATE_STARTING:
+ g_set_error (err,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS,
+ "%s",
+ "Could not process the request because the VPN connection is already being started.");
+ break;
+ case NM_VPN_SERVICE_STATE_STARTED:
+ g_set_error (err,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_ALREADY_STARTED,
+ "%s",
+ "Could not process the request because a VPN connection was already active.");
+ break;
+ case NM_VPN_SERVICE_STATE_STOPPING:
+ g_set_error (err,
+ NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
+ "%s",
+ "Could not process the request because the VPN connection is being stopped.");
+ break;
+ case NM_VPN_SERVICE_STATE_STOPPED:
+ case NM_VPN_SERVICE_STATE_INIT:
+ nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTING);
+ ret = NM_VPN_PLUGIN_GET_CLASS (plugin)->connect (plugin, properties, routes, err);
+ if (!ret)
+ nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STOPPED);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ return ret;
+}
+
+void
+nm_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
+ GHashTable *ip4_config)
+{
+ g_return_if_fail (NM_IS_VPN_PLUGIN (plugin));
+ g_return_if_fail (ip4_config != NULL);
+
+ g_signal_emit (plugin, signals[IP4_CONFIG], 0, ip4_config);
+
+ nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_STARTED);
+}
+
+
+static gboolean
+impl_vpn_plugin_connect (NMVPNPlugin *plugin,
+ GHashTable *properties,
+ char **routes,
+ GError **err)
+{
+ return nm_vpn_plugin_connect (plugin, properties, routes, err);
+}
+
+static gboolean
+impl_vpn_plugin_disconnect (NMVPNPlugin *plugin,
+ GError **err)
+{
+ return nm_vpn_plugin_disconnect (plugin, err);
+}
+
+static gboolean
+impl_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
+ GHashTable *config,
+ GError **err)
+{
+ nm_vpn_plugin_set_ip4_config (plugin, config);
+
+ return TRUE;
+}
+
+static gboolean
+impl_vpn_plugin_set_failure (NMVPNPlugin *plugin,
+ char *reason,
+ GError **err)
+{
+ nm_vpn_plugin_failure (plugin, NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG);
+
+ return TRUE;
+}
+
+/*********************************************************************/
+
+static void
+sigterm_handler (int signum)
+{
+ g_slist_foreach (active_plugins, (GFunc) nm_vpn_plugin_emit_quit, NULL);
+}
+
+static void
+setup_unix_signal_handler (void)
+{
+ struct sigaction action;
+ sigset_t block_mask;
+
+ action.sa_handler = sigterm_handler;
+ sigemptyset (&block_mask);
+ action.sa_mask = block_mask;
+ action.sa_flags = 0;
+ sigaction (SIGINT, &action, NULL);
+ sigaction (SIGTERM, &action, NULL);
+}
+
+/*********************************************************************/
+
+static void
+one_plugin_destroyed (gpointer data,
+ GObject *object)
+{
+ active_plugins = g_slist_remove (active_plugins, object);
+}
+
+static void
+nm_vpn_plugin_init (NMVPNPlugin *plugin)
+{
+ active_plugins = g_slist_append (active_plugins, plugin);
+ g_object_weak_ref (G_OBJECT (plugin),
+ one_plugin_destroyed,
+ NULL);
+}
+
+static GObject *
+constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params)
+{
+ GObject *object;
+ NMVPNPlugin *plugin;
+ NMVPNPluginPrivate *priv;
+ DBusGConnection *connection;
+ DBusGProxy *proxy;
+ guint request_name_result;
+ GError *err = NULL;
+
+ object = G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+ if (!object)
+ return NULL;
+
+ priv = NM_VPN_PLUGIN_GET_PRIVATE (object);
+ if (!priv->dbus_service_name)
+ goto err;
+
+ connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, &err);
+ if (!connection)
+ goto err;
+
+ proxy = dbus_g_proxy_new_for_name (connection,
+ "org.freedesktop.DBus",
+ "/org/freedesktop/DBus",
+ "org.freedesktop.DBus");
+
+ if (!dbus_g_proxy_call (proxy, "RequestName", &err,
+ G_TYPE_STRING, priv->dbus_service_name,
+ G_TYPE_UINT, 0,
+ G_TYPE_INVALID,
+ G_TYPE_UINT, &request_name_result,
+ G_TYPE_INVALID)) {
+ g_object_unref (proxy);
+ goto err;
+ }
+
+ g_object_unref (proxy);
+
+ dbus_g_connection_register_g_object (connection,
+ NM_VPN_DBUS_PLUGIN_PATH,
+ object);
+
+ plugin = NM_VPN_PLUGIN (object);
+
+ nm_vpn_plugin_set_connection (plugin, connection);
+ nm_vpn_plugin_set_state (plugin, NM_VPN_SERVICE_STATE_INIT);
+
+ return object;
+
+ err:
+ if (err) {
+ nm_warning ("%s", err->message);
+ g_error_free (err);
+ }
+
+ if (object)
+ g_object_unref (object);
+
+ return NULL;
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_DBUS_SERVICE_NAME:
+ /* Construct-only */
+ priv->dbus_service_name = g_strdup (g_value_get_string (value));
+ break;
+ case PROP_STATE:
+ nm_vpn_plugin_set_state (NM_VPN_PLUGIN (object),
+ (NMVPNServiceState) g_value_get_uint (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_DBUS_SERVICE_NAME:
+ g_value_set_string (value, priv->dbus_service_name);
+ break;
+ case PROP_STATE:
+ g_value_set_uint (value, nm_vpn_plugin_get_state (NM_VPN_PLUGIN (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+dispose (GObject *object)
+{
+ NMVPNPlugin *plugin = NM_VPN_PLUGIN (object);
+ NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+ NMVPNServiceState state;
+ GError *err = NULL;
+
+ if (priv->disposed)
+ return;
+
+ priv->disposed = TRUE;
+
+ state = nm_vpn_plugin_get_state (plugin);
+
+ if (state == NM_VPN_SERVICE_STATE_STARTED ||
+ state == NM_VPN_SERVICE_STATE_STARTING)
+ nm_vpn_plugin_disconnect (plugin, &err);
+
+ if (err) {
+ nm_warning ("%s", err->message);
+ g_error_free (err);
+ }
+
+ G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->dispose (object);
+}
+
+static void
+finalize (GObject *object)
+{
+ NMVPNPlugin *plugin = NM_VPN_PLUGIN (object);
+ NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+
+ nm_vpn_plugin_set_connection (plugin, NULL);
+ g_free (priv->dbus_service_name);
+
+ G_OBJECT_CLASS (nm_vpn_plugin_parent_class)->finalize (object);
+}
+
+static void
+connect_timer_removed (gpointer data)
+{
+ NM_VPN_PLUGIN_GET_PRIVATE (data)->connect_timer = 0;
+}
+
+static void
+quit_timer_removed (gpointer data)
+{
+ NM_VPN_PLUGIN_GET_PRIVATE (data)->quit_timer = 0;
+}
+
+static void
+state_changed (NMVPNPlugin *plugin, NMVPNServiceState state)
+{
+ NMVPNPluginPrivate *priv = NM_VPN_PLUGIN_GET_PRIVATE (plugin);
+
+ switch (state) {
+ case NM_VPN_SERVICE_STATE_STARTING:
+ /* Remove the quit timer. */
+ if (priv->quit_timer)
+ g_source_remove (priv->quit_timer);
+
+ /* Add a timer to make sure we do not wait indefinitely for the successful connect. */
+ priv->connect_timer = g_timeout_add_full (G_PRIORITY_DEFAULT,
+ NM_VPN_PLUGIN_CONNECT_TIMER,
+ connect_timer_expired,
+ plugin,
+ connect_timer_removed);
+ break;
+ case NM_VPN_SERVICE_STATE_STOPPED:
+ priv->quit_timer = g_timeout_add_full (G_PRIORITY_DEFAULT,
+ NM_VPN_PLUGIN_QUIT_TIMER,
+ quit_timer_expired,
+ plugin,
+ quit_timer_removed);
+ break;
+ default:
+ /* Clean up all timers we might have set up. */
+ if (priv->connect_timer)
+ g_source_remove (priv->connect_timer);
+
+ if (priv->quit_timer)
+ g_source_remove (priv->quit_timer);
+
+ break;
+ }
+}
+
+static void
+nm_vpn_plugin_class_init (NMVPNPluginClass *plugin_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (plugin_class);
+
+ g_type_class_add_private (object_class, sizeof (NMVPNPluginPrivate));
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (plugin_class),
+ &dbus_glib_nm_vpn_plugin_object_info);
+
+ /* virtual methods */
+ object_class->constructor = constructor;
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->dispose = dispose;
+ object_class->finalize = finalize;
+
+ plugin_class->state_changed = state_changed;
+
+ /* properties */
+ g_object_class_install_property
+ (object_class, PROP_DBUS_SERVICE_NAME,
+ g_param_spec_string (NM_VPN_PLUGIN_DBUS_SERVICE_NAME,
+ "DBus service name",
+ "DBus service name",
+ NULL,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property
+ (object_class, PROP_STATE,
+ g_param_spec_uint (NM_VPN_PLUGIN_STATE,
+ "State",
+ "Current VPN service state",
+ NM_VPN_SERVICE_STATE_UNKNOWN,
+ NM_VPN_SERVICE_STATE_STOPPED,
+ NM_VPN_SERVICE_STATE_INIT,
+ G_PARAM_READWRITE));
+
+ /* signals */
+ signals[STATE_CHANGED] =
+ g_signal_new ("state-changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMVPNPluginClass, state_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ signals[IP4_CONFIG] =
+ g_signal_new ("ip4-config",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMVPNPluginClass, ip4_config),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE));
+
+ signals[LOGIN_BANNER] =
+ g_signal_new ("login-banner",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMVPNPluginClass, login_banner),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1,
+ G_TYPE_STRING);
+
+ signals[FAILURE] =
+ g_signal_new ("failure",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMVPNPluginClass, failure),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ signals[QUIT] =
+ g_signal_new ("quit",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMVPNPluginClass, quit),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0,
+ G_TYPE_NONE);
+
+ dbus_g_error_domain_register (NM_VPN_PLUGIN_ERROR,
+ NULL,
+ NM_TYPE_VPN_PLUGIN_ERROR);
+
+ setup_unix_signal_handler ();
+}
--- /dev/null
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+#ifndef NM_VPN_PLUGIN_H
+#define NM_VPN_PLUGIN_H
+
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include <dbus/dbus-glib.h>
+#include <NetworkManagerVPN.h>
+
+G_BEGIN_DECLS
+
+#define NM_TYPE_VPN_PLUGIN (nm_vpn_plugin_get_type ())
+#define NM_VPN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_VPN_PLUGIN, NMVPNPlugin))
+#define NM_VPN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_PLUGIN, NMVPNPluginClass))
+#define NM_IS_VPN_PLUGIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_PLUGIN))
+#define NM_IS_VPN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_PLUGIN))
+#define NM_VPN_PLUGIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_PLUGIN, NMVPNPluginClass))
+
+#define NM_VPN_PLUGIN_DBUS_SERVICE_NAME "service-name"
+#define NM_VPN_PLUGIN_STATE "state"
+
+typedef enum {
+ NM_VPN_PLUGIN_ERROR_GENERAL,
+ NM_VPN_PLUGIN_ERROR_STARTING_IN_PROGRESS,
+ NM_VPN_PLUGIN_ERROR_ALREADY_STARTED,
+ NM_VPN_PLUGIN_ERROR_STOPPING_IN_PROGRESS,
+ NM_VPN_PLUGIN_ERROR_ALREADY_STOPPED,
+ NM_VPN_PLUGIN_ERROR_WRONG_STATE,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+} NMVPNPluginError;
+
+#define NM_VPN_PLUGIN_ERROR (nm_vpn_plugin_error_quark ())
+#define NM_TYPE_VPN_PLUGIN_ERROR (nm_vpn_plugin_error_get_type ())
+
+typedef enum {
+ NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED,
+ NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED,
+ NM_VPN_PLUGIN_FAILURE_BAD_IP_CONFIG
+} NMVPNPluginFailure;
+
+typedef struct {
+ GObject parent;
+} NMVPNPlugin;
+
+typedef struct {
+ GObjectClass parent;
+
+ /* virtual methods */
+ gboolean (*connect) (NMVPNPlugin *plugin,
+ GHashTable *properties,
+ char **routes,
+ GError **err);
+
+ gboolean (*disconnect) (NMVPNPlugin *plugin,
+ GError **err);
+
+ /* Signals */
+ void (*state_changed) (NMVPNPlugin *plugin,
+ NMVPNServiceState state);
+
+ void (*ip4_config) (NMVPNPlugin *plugin,
+ GHashTable *ip4_config);
+
+ void (*login_banner) (NMVPNPlugin *plugin,
+ const char *banner);
+
+ void (*failure) (NMVPNPlugin *plugin,
+ NMVPNPluginFailure reason);
+
+ void (*quit) (NMVPNPlugin *plugin);
+} NMVPNPluginClass;
+
+GType nm_vpn_plugin_get_type (void);
+GQuark nm_vpn_plugin_error_quark (void);
+GType nm_vpn_plugin_error_get_type (void);
+
+DBusGConnection *nm_vpn_plugin_get_connection (NMVPNPlugin *plugin);
+NMVPNServiceState nm_vpn_plugin_get_state (NMVPNPlugin *plugin);
+void nm_vpn_plugin_set_state (NMVPNPlugin *plugin,
+ NMVPNServiceState state);
+
+void nm_vpn_plugin_set_login_banner (NMVPNPlugin *plugin,
+ const char *banner);
+
+void nm_vpn_plugin_failure (NMVPNPlugin *plugin,
+ NMVPNPluginFailure reason);
+
+void nm_vpn_plugin_set_ip4_config (NMVPNPlugin *plugin,
+ GHashTable *ip4_config);
+
+gboolean nm_vpn_plugin_disconnect (NMVPNPlugin *plugin,
+ GError **err);
+
+G_END_DECLS
+
+#endif /* NM_VPN_PLUGIN_H */
nm-connection.c \
nm-connection.h \
nm-setting.c \
- nm-setting.h
+ nm-setting.h \
+ nm-utils.c \
+ nm-utils.h
if !WITH_GCRYPT
libnm_util_la_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h
dbus-method-dispatcher.h \
dbus-dict-helpers.h \
nm-connection.h \
- nm-setting.h
+ nm-setting.h \
+ nm-utils.h
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libnm-util.pc
return connection_hash;
}
-static char *
-garray_to_string (GArray *array)
-{
- GString *str;
- int i;
- char c;
-
- g_return_val_if_fail (array != NULL, NULL);
-
- str = g_string_sized_new (array->len);
- for (i = 0; i < array->len; i++) {
- c = array->data[i];
-
- /* Convert NULLs to spaces to increase the readability. */
- if (c == '\0')
- c = ' ';
- str = g_string_append_c (str, c);
- }
- str = g_string_append_c (str, '\0');
-
- return g_string_free (str, FALSE);
-}
-
static char *
gvalue_to_string (GValue *val)
{
default:
/* These return dynamic values and thus can't be 'case's */
if (type == DBUS_TYPE_G_UCHAR_ARRAY)
- ret = garray_to_string ((GArray *) g_value_get_boxed (val));
+ ret = nm_utils_garray_to_string ((GArray *) g_value_get_boxed (val));
else if (type == dbus_g_type_get_collection ("GSList", G_TYPE_STRING)) {
GSList *iter;
ptr_array = (GPtrArray *) g_value_get_boxed (val);
for (i = 0; i < ptr_array->len; i++) {
- ret = garray_to_string ((GArray *) g_ptr_array_index (ptr_array, i));
+ ret = nm_utils_garray_to_string ((GArray *) g_ptr_array_index (ptr_array, i));
if (need_comma)
g_string_append (str, ", ");
--- /dev/null
+/* NetworkManager -- Network link manager
+ *
+ * Ray Strode <rstrode@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 2005 Red Hat, Inc.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <iwlib.h>
+#include <wireless.h>
+
+#include <glib.h>
+#include <glib-object.h>
+#include <dbus/dbus.h>
+#include "nm-utils.h"
+
+gchar *nm_dbus_escape_object_path (const gchar *utf8_string)
+{
+ const gchar *p;
+ gchar *object_path;
+ GString *string;
+
+ g_return_val_if_fail (utf8_string != NULL, NULL);
+ g_return_val_if_fail (g_utf8_validate (utf8_string, -1, NULL), NULL);
+
+ string = g_string_sized_new ((strlen (utf8_string) + 1) * 6);
+
+ for (p = utf8_string; *p != '\0'; p = g_utf8_next_char (p))
+ {
+ gunichar character;
+
+ character = g_utf8_get_char (p);
+
+ if (((character >= ((gunichar) 'a')) &&
+ (character <= ((gunichar) 'z'))) ||
+ ((character >= ((gunichar) 'A')) &&
+ (character <= ((gunichar) 'Z'))) ||
+ ((character >= ((gunichar) '0')) &&
+ (character <= ((gunichar) '9'))) ||
+ (character == ((gunichar) '/')))
+ {
+ g_string_append_c (string, (gchar) character);
+ continue;
+ }
+
+ g_string_append_printf (string, "_%x_", character);
+ }
+
+ object_path = string->str;
+
+ g_string_free (string, FALSE);
+
+ return object_path;
+}
+
+gchar *nm_dbus_unescape_object_path (const gchar *object_path)
+{
+ const gchar *p;
+ gchar *utf8_string;
+ GString *string;
+
+ g_return_val_if_fail (object_path != NULL, NULL);
+
+ string = g_string_sized_new (strlen (object_path) + 1);
+
+ for (p = object_path; *p != '\0'; p++)
+ {
+ const gchar *q;
+ gchar *hex_digits, *end, utf8_character[6] = { '\0' };
+ gint utf8_character_size;
+ gunichar character;
+ gulong hex_value;
+
+ if (*p != '_')
+ {
+ g_string_append_c (string, *p);
+ continue;
+ }
+
+ q = strchr (p + 1, '_');
+
+ if ((q == NULL) || (q == p + 1))
+ {
+ g_string_free (string, TRUE);
+ return NULL;
+ }
+
+ hex_digits = g_strndup (p + 1, (q - 1) - p);
+
+ hex_value = strtoul (hex_digits, &end, 16);
+
+ character = (gunichar) hex_value;
+
+ if (((hex_value == G_MAXLONG) && (errno == ERANGE)) ||
+ (hex_value > G_MAXUINT32) ||
+ (*end != '\0') ||
+ (!g_unichar_validate (character)))
+ {
+ g_free (hex_digits);
+ g_string_free (string, TRUE);
+ return NULL;
+ }
+
+ utf8_character_size =
+ g_unichar_to_utf8 (character, utf8_character);
+
+ g_assert (utf8_character_size > 0);
+
+ g_string_append_len (string, utf8_character,
+ utf8_character_size);
+
+ p = q;
+ }
+
+ utf8_string = string->str;
+
+ g_string_free (string, FALSE);
+
+ return utf8_string;
+}
+
+struct EncodingTriplet
+{
+ const char *encoding1;
+ const char *encoding2;
+ const char *encoding3;
+};
+
+struct IsoLangToEncodings
+{
+ const char * lang;
+ struct EncodingTriplet encodings;
+};
+
+/* 5-letter language codes */
+static const struct IsoLangToEncodings isoLangEntries5[] =
+{
+ /* Simplified Chinese */
+ { "zh_cn", {"euc-cn", "gb2312", "gb18030"} }, /* PRC */
+ { "zh_sg", {"euc-cn", "gb2312", "gb18030"} }, /* Singapore */
+
+ /* Traditional Chinese */
+ { "zh_tw", {"big5", "euc-tw", NULL} }, /* Taiwan */
+ { "zh_hk", {"big5", "euc-tw", "big5-hkcs"} },/* Hong Kong */
+ { "zh_mo", {"big5", "euc-tw", NULL} }, /* Macau */
+
+ /* Table end */
+ { NULL, {NULL, NULL, NULL} }
+};
+
+/* 2-letter language codes; we don't care about the other 3 in this table */
+static const struct IsoLangToEncodings isoLangEntries2[] =
+{
+ /* Japanese */
+ { "ja", {"euc-jp", "shift_jis", "iso-2022-jp"} },
+
+ /* Korean */
+ { "ko", {"euc-kr", "iso-2022-kr", "johab"} },
+
+ /* Thai */
+ { "th", {"iso-8859-11","windows-874", NULL} },
+
+ /* Central European */
+ { "hu", {"iso-8859-2", "windows-1250", NULL} }, /* Hungarian */
+ { "cs", {"iso-8859-2", "windows-1250", NULL} }, /* Czech */
+ { "hr", {"iso-8859-2", "windows-1250", NULL} }, /* Croatian */
+ { "pl", {"iso-8859-2", "windows-1250", NULL} }, /* Polish */
+ { "ro", {"iso-8859-2", "windows-1250", NULL} }, /* Romanian */
+ { "sk", {"iso-8859-2", "windows-1250", NULL} }, /* Slovakian */
+ { "sl", {"iso-8859-2", "windows-1250", NULL} }, /* Slovenian */
+ { "sh", {"iso-8859-2", "windows-1250", NULL} }, /* Serbo-Croatian */
+
+ /* Cyrillic */
+ { "ru", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Russian */
+ { "be", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Belorussian */
+ { "bg", {"windows-1251","koi8-r", "iso-8859-5"} }, /* Bulgarian */
+ { "mk", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Macedonian */
+ { "sr", {"koi8-r", "windows-1251", "iso-8859-5"} }, /* Serbian */
+ { "uk", {"koi8-u", "koi8-r", "windows-1251"} }, /* Ukranian */
+
+ /* Arabic */
+ { "ar", {"iso-8859-6", "windows-1256", NULL} },
+
+ /* Balitc */
+ { "et", {"iso-8859-4", "windows-1257", NULL} }, /* Estonian */
+ { "lt", {"iso-8859-4", "windows-1257", NULL} }, /* Lithuanian */
+ { "lv", {"iso-8859-4", "windows-1257", NULL} }, /* Latvian */
+
+ /* Greek */
+ { "el", {"iso-8859-7", "windows-1253", NULL} },
+
+ /* Hebrew */
+ { "he", {"iso-8859-8", "windows-1255", NULL} },
+ { "iw", {"iso-8859-8", "windows-1255", NULL} },
+
+ /* Turkish */
+ { "tr", {"iso-8859-9", "windows-1254", NULL} },
+
+ /* Table end */
+ { NULL, {NULL, NULL, NULL} }
+};
+
+
+static GHashTable * langToEncodings5 = NULL;
+static GHashTable * langToEncodings2 = NULL;
+
+static void
+init_lang_to_encodings_hash (void)
+{
+ static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+
+ g_static_mutex_lock (&mutex);
+ if (G_UNLIKELY (!langToEncodings5 || !langToEncodings2))
+ {
+ const struct IsoLangToEncodings * enc = &isoLangEntries5[0];
+
+ /* Five-letter codes */
+ langToEncodings5 = g_hash_table_new (g_str_hash, g_str_equal);
+ while (enc->lang)
+ {
+ g_hash_table_insert (langToEncodings5, (gpointer) enc->lang,
+ (gpointer) &enc->encodings);
+ enc++;
+ }
+
+ /* Two-letter codes */
+ enc = &isoLangEntries2[0];
+ langToEncodings2 = g_hash_table_new (g_str_hash, g_str_equal);
+ while (enc->lang)
+ {
+ g_hash_table_insert (langToEncodings2, (gpointer) enc->lang,
+ (gpointer) &enc->encodings);
+ enc++;
+ }
+ }
+ g_static_mutex_unlock (&mutex);
+}
+
+
+static gboolean
+get_encodings_for_lang (const char *lang,
+ char **encoding1,
+ char **encoding2,
+ char **encoding3)
+{
+ struct EncodingTriplet * encodings;
+ gboolean success = FALSE;
+ char * tmp_lang;
+
+ g_return_val_if_fail (lang != NULL, FALSE);
+ g_return_val_if_fail (encoding1 != NULL, FALSE);
+ g_return_val_if_fail (encoding2 != NULL, FALSE);
+ g_return_val_if_fail (encoding3 != NULL, FALSE);
+
+ *encoding1 = "iso-8859-1";
+ *encoding2 = "windows-1251";
+ *encoding3 = NULL;
+
+ init_lang_to_encodings_hash ();
+
+ tmp_lang = g_strdup (lang);
+ if ((encodings = g_hash_table_lookup (langToEncodings5, tmp_lang)))
+ {
+ *encoding1 = (char *) encodings->encoding1;
+ *encoding2 = (char *) encodings->encoding2;
+ *encoding3 = (char *) encodings->encoding3;
+ success = TRUE;
+ }
+
+ /* Truncate tmp_lang to length of 2 */
+ if (strlen (tmp_lang) > 2)
+ tmp_lang[2] = '\0';
+ if (!success && (encodings = g_hash_table_lookup (langToEncodings2, tmp_lang)))
+ {
+ *encoding1 = (char *) encodings->encoding1;
+ *encoding2 = (char *) encodings->encoding2;
+ *encoding3 = (char *) encodings->encoding3;
+ success = TRUE;
+ }
+
+ g_free (tmp_lang);
+ return success;
+}
+
+
+
+char *
+nm_utils_ssid_to_utf8 (const char *ssid, guint32 len)
+{
+ char * new_ssid = NULL;
+ char buf[IW_ESSID_MAX_SIZE + 1];
+ guint32 buf_len = MIN (sizeof (buf) - 1, len);
+ char * lang;
+ char *e1 = NULL, *e2 = NULL, *e3 = NULL;
+
+ g_return_val_if_fail (ssid != NULL, NULL);
+
+ memset (buf, 0, sizeof (buf));
+ memcpy (buf, ssid, buf_len);
+
+ if (g_utf8_validate (buf, buf_len, NULL)) {
+ new_ssid = g_strdup (buf);
+ goto out;
+ }
+
+ /* Even if the local encoding is UTF-8, LANG may give
+ * us a clue as to what encoding SSIDs are more likely to be in.
+ */
+ g_get_charset ((const char **)(&e1));
+ if ((lang = getenv ("LANG"))) {
+ char * dot;
+
+ lang = g_ascii_strdown (lang, -1);
+ if ((dot = strchr (lang, '.')))
+ *dot = '\0';
+
+ get_encodings_for_lang (lang, &e1, &e2, &e3);
+ g_free (lang);
+ }
+
+ new_ssid = g_convert (buf, buf_len, "UTF-8", e1, NULL, NULL, NULL);
+ if (!new_ssid && e2) {
+ new_ssid = g_convert (buf, buf_len, "UTF-8", e2, NULL, NULL, NULL);
+ }
+ if (!new_ssid && e3) {
+ new_ssid = g_convert (buf, buf_len, "UTF-8", e3, NULL, NULL, NULL);
+ }
+ if (!new_ssid) {
+ new_ssid = g_convert_with_fallback (buf, buf_len, "UTF-8", e1,
+ "?", NULL, NULL, NULL);
+ }
+
+out:
+ return new_ssid;
+}
+
+
+/*
+ * Pending Call Debug stuff
+ *
+ */
+typedef struct PCallInfo
+{
+ DBusPendingCall * pcall;
+ char * caller;
+ guint32 id;
+ GTimeVal start;
+} PCallInfo;
+
+static GStaticMutex pcall_mutex = G_STATIC_MUTEX_INIT;
+static GHashTable * pcall_table = NULL;
+static guint32 pcall_gid = 0;
+static guint32 pcall_pending = 0;
+
+
+DBusPendingCall *
+nm_dbus_send_with_callback (DBusConnection *connection,
+ DBusMessage *msg,
+ DBusPendingCallNotifyFunction func,
+ gpointer data,
+ DBusFreeFunction free_func,
+ const char *caller)
+{
+ PCallInfo * info = NULL;
+ DBusPendingCall * pcall = NULL;
+
+ g_return_val_if_fail (connection != NULL, NULL);
+ g_return_val_if_fail (msg != NULL, NULL);
+ g_return_val_if_fail (func != NULL, NULL);
+ g_return_val_if_fail (caller != NULL, NULL);
+
+ if (!(info = g_malloc0 (sizeof (PCallInfo))))
+ {
+ g_warning ("Error: '%s' couldn't allocate memory for tracking PCall.", caller);
+ if (free_func)
+ (*free_func)(data);
+ return NULL;
+ }
+
+ dbus_connection_send_with_reply (connection, msg, &pcall, -1);
+ if (!pcall)
+ {
+ g_warning ("Error: '%s' couldn't send dbus message.", caller);
+ if (free_func)
+ (*free_func)(data);
+ g_free (info);
+ return NULL;
+ }
+ dbus_pending_call_set_notify (pcall, func, data, free_func);
+
+ info->caller = g_strdup (caller);
+ info->pcall = pcall;
+ g_get_current_time (&info->start);
+ dbus_pending_call_ref (pcall);
+
+ g_static_mutex_lock (&pcall_mutex);
+ info->id = pcall_gid++;
+ pcall_pending++;
+
+ if (!pcall_table)
+ pcall_table = g_hash_table_new (g_direct_hash, g_direct_equal);
+ g_hash_table_insert (pcall_table, pcall, info);
+
+#ifdef DBUS_PENDING_CALL_DEBUG
+ nm_info ("PCall Debug: new id %d (%p), from '%s' (%s), "
+ "%d pending.", info->id, pcall, info->caller,
+ dbus_message_get_member (msg), pcall_pending);
+#endif
+
+ g_static_mutex_unlock (&pcall_mutex);
+
+ return pcall;
+}
+
+void
+nm_dbus_send_with_callback_replied (DBusPendingCall *pcall,
+ const char *caller)
+{
+ PCallInfo * info;
+#ifdef DBUS_PENDING_CALL_DEBUG
+ GTimeVal now;
+ long elapsed_ms = 0;
+#endif
+
+ g_return_if_fail (pcall != NULL);
+ g_return_if_fail (caller != NULL);
+
+ g_static_mutex_lock (&pcall_mutex);
+ if (!(info = g_hash_table_lookup (pcall_table, pcall)))
+ {
+ nm_warning ("Error: couldn't find pending call %p in tracking"
+ " table.", pcall);
+ goto out;
+ }
+
+ pcall_pending--;
+#ifdef DBUS_PENDING_CALL_DEBUG
+ g_get_current_time (&now);
+ if (info->start.tv_usec > now.tv_usec)
+ {
+ now.tv_sec--;
+ now.tv_usec = G_USEC_PER_SEC - (info->start.tv_usec - now.tv_usec);
+ }
+ else
+ now.tv_usec -= info->start.tv_usec;
+ now.tv_sec -= info->start.tv_sec;
+ elapsed_ms = now.tv_sec * G_USEC_PER_SEC + now.tv_usec;
+ elapsed_ms /= 1000;
+
+ nm_info ("PCall Debug: unregistered ID %d (%p), %s -> %s,"
+ " %lums elapsed. Total pending: %d", info->id, info->pcall, info->caller,
+ caller, elapsed_ms, pcall_pending);
+#endif
+
+ g_hash_table_remove (pcall_table, pcall);
+ g_free (info->caller);
+ dbus_pending_call_unref (info->pcall);
+ g_free (info);
+
+out:
+ g_static_mutex_unlock (&pcall_mutex);
+}
+
+static void
+value_destroy (gpointer data)
+{
+ GValue *value = (GValue *) data;
+
+ g_value_unset (value);
+ g_slice_free (GValue, value);
+}
+
+static void
+value_dup (gpointer key, gpointer val, gpointer user_data)
+{
+ GHashTable *dup = (GHashTable *) user_data;
+ GValue *value = (GValue *) val;
+ GValue *dup_value;
+
+ dup_value = g_slice_new0 (GValue);
+ g_value_init (dup_value, G_VALUE_TYPE (val));
+ g_value_copy (value, dup_value);
+
+ g_hash_table_insert (dup, g_strdup ((char *) key), dup_value);
+}
+
+GHashTable *
+nm_utils_gvalue_hash_dup (GHashTable *hash)
+{
+ GHashTable *dup;
+
+ g_return_val_if_fail (hash != NULL, NULL);
+
+ dup = g_hash_table_new_full (g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ value_destroy);
+
+ g_hash_table_foreach (hash, value_dup, dup);
+
+ return dup;
+}
+
+char *
+nm_utils_garray_to_string (GArray *array)
+{
+ GString *str;
+ int i;
+ char c;
+
+ g_return_val_if_fail (array != NULL, NULL);
+
+ str = g_string_sized_new (array->len);
+ for (i = 0; i < array->len; i++) {
+ c = array->data[i];
+
+ /* Convert NULLs to spaces to increase the readability. */
+ if (c == '\0')
+ c = ' ';
+ str = g_string_append_c (str, c);
+ }
+ str = g_string_append_c (str, '\0');
+
+ return g_string_free (str, FALSE);
+}
--- /dev/null
+/* NetworkManager -- Network link manager
+ *
+ * Ray Strode <rstrode@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 2005 Red Hat, Inc.
+ */
+
+#ifndef NM_UTILS_H
+#define NM_UTILS_H
+
+#include <glib.h>
+#include <execinfo.h>
+#include <dbus/dbus.h>
+
+#define nm_print_backtrace() \
+G_STMT_START \
+{ \
+ void *_call_stack[512]; \
+ int _call_stack_size; \
+ char **_symbols; \
+ _call_stack_size = backtrace (_call_stack, \
+ G_N_ELEMENTS (_call_stack)); \
+ _symbols = backtrace_symbols (_call_stack, _call_stack_size); \
+ if (_symbols != NULL) \
+ { \
+ int _i; \
+ _i = 0; \
+ g_critical ("traceback:\n"); \
+ while (_i < _call_stack_size) \
+ { \
+ g_critical ("\t%s\n", _symbols[_i]); \
+ _i++; \
+ } \
+ free (_symbols); \
+ } \
+} \
+G_STMT_END
+
+#define nm_get_timestamp(timestamp) \
+G_STMT_START \
+{ \
+ GTimeVal _tv; \
+ g_get_current_time (&_tv); \
+ *timestamp = (_tv.tv_sec * (1.0 * G_USEC_PER_SEC) + \
+ _tv.tv_usec) / G_USEC_PER_SEC; \
+} \
+G_STMT_END
+
+#define nm_info(fmt, args...) \
+G_STMT_START \
+{ \
+ g_message ("<info> " fmt "\n", ##args); \
+} G_STMT_END
+
+#define nm_info_str(fmt_str, args...) \
+G_STMT_START \
+{ \
+ g_message ("<info> %s\n", fmt_str, ##args); \
+} G_STMT_END
+
+#define nm_debug(fmt, args...) \
+G_STMT_START \
+{ \
+ gdouble _timestamp; \
+ nm_get_timestamp (&_timestamp); \
+ g_debug ("<debug> [%f] %s(): " fmt "\n", _timestamp, \
+ G_STRFUNC, ##args); \
+} G_STMT_END
+
+#define nm_debug_str(fmt_str, args...) \
+G_STMT_START \
+{ \
+ gdouble _timestamp; \
+ nm_get_timestamp (&_timestamp); \
+ g_debug ("<debug> [%f] %s(): %s\n", _timestamp, \
+ G_STRFUNC, fmt_str, ##args); \
+} G_STMT_END
+
+#define nm_warning(fmt, args...) \
+G_STMT_START \
+{ \
+ g_warning ("<WARN> %s(): " fmt "\n", \
+ G_STRFUNC, ##args); \
+} G_STMT_END
+
+#define nm_warning_str(fmt_str, args...) \
+G_STMT_START \
+{ \
+ g_warning ("<WARN> %s(): %s\n", \
+ G_STRFUNC, fmt_str, ##args); \
+} G_STMT_END
+
+#define nm_error(fmt, args...) \
+G_STMT_START \
+{ \
+ gdouble _timestamp; \
+ nm_get_timestamp (&_timestamp); \
+ g_critical ("<ERROR>\t[%f] %s (): " fmt "\n", _timestamp, \
+ G_STRFUNC, ##args); \
+ nm_print_backtrace (); \
+ G_BREAKPOINT (); \
+} G_STMT_END
+
+#define nm_error_str(fmt_str, args...) \
+G_STMT_START \
+{ \
+ gdouble _timestamp; \
+ nm_get_timestamp (&_timestamp); \
+ g_critical ("<ERROR>\t[%f] %s (): %s\n", _timestamp, \
+ G_STRFUNC, fmt_str, ##args); \
+ nm_print_backtrace (); \
+ G_BREAKPOINT (); \
+} G_STMT_END
+
+gchar *nm_dbus_escape_object_path (const gchar *utf8_string);
+gchar *nm_dbus_unescape_object_path (const gchar *object_path);
+
+char *nm_utils_ssid_to_utf8 (const char *ssid, guint32 len);
+
+/* #define DBUS_PENDING_CALL_DEBUG */
+
+DBusPendingCall * nm_dbus_send_with_callback (DBusConnection *connection,
+ DBusMessage *msg,
+ DBusPendingCallNotifyFunction func,
+ gpointer data,
+ DBusFreeFunction free_func,
+ const char *caller);
+void nm_dbus_send_with_callback_replied (DBusPendingCall *pcall,
+ const char *caller);
+
+GHashTable *nm_utils_gvalue_hash_dup (GHashTable *hash);
+char *nm_utils_garray_to_string (GArray *array);
+
+#endif /* NM_UTILS_H */
-I${top_srcdir}/src/vpn-manager \
-I${top_srcdir}/src/dhcp-manager \
-I${top_srcdir}/src/supplicant-manager \
- -I${top_srcdir}/utils \
-I${top_srcdir}/libnm-util
sbin_PROGRAMS = NetworkManager
nm-ip4-config.c \
nm-ip4-config.h \
NetworkManager.c \
- NetworkManagerMain.h \
NetworkManagerPolicy.c \
NetworkManagerPolicy.h \
NetworkManagerUtils.c \
$(HAL_LIBS) \
$(IWLIB) \
$(LIBNL_LIBS) \
- $(top_builddir)/utils/libnmutils.la \
./named-manager/libnamed-manager.la \
./vpn-manager/libvpn-manager.la \
./dhcp-manager/libdhcp-manager.la \
#include "NetworkManagerPolicy.h"
#include "NetworkManagerSystem.h"
#include "nm-named-manager.h"
-#include "nm-dbus-vpn.h"
#include "nm-dbus-manager.h"
#include "nm-supplicant-manager.h"
#include "nm-netlink-monitor.h"
+#include "nm-vpn-manager.h"
#include "nm-logging.h"
#define NM_DEFAULT_PID_FILE LOCALSTATEDIR"/run/NetworkManager.pid"
nm_print_open_socks ();
if (vpn_manager)
- nm_vpn_manager_dispose (vpn_manager);
+ g_object_unref (vpn_manager);
nm_hal_manager_destroy (hal_manager);
if (policy)
+++ /dev/null
-/* 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 2004 Red Hat, Inc.
- */
-
-#ifndef NETWORK_MANAGER_MAIN_H
-#define NETWORK_MANAGER_MAIN_H
-
-typedef struct NMVPNActRequest NMVPNActRequest;
-typedef struct NMVPNManager NMVPNManager;
-
-#endif
#include <pthread.h>
#include "NetworkManagerSystem.h"
#include "nm-device.h"
+#include "nm-named-manager.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-netlink.h"
*
*/
gboolean
-nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
- NMDevice *active_device,
+nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
const char *iface,
NMIP4Config *config,
- char **routes,
- int num_routes)
+ char **routes)
{
NMIP4Config * ad_config = NULL;
struct nl_handle * nlh = NULL;
struct rtnl_addr * addr = NULL;
struct rtnl_link * request = NULL;
+ int num_routes;
+ NMNamedManager *named_mgr;
g_return_val_if_fail (config != NULL, FALSE);
sleep (1);
+ num_routes = g_strv_length (routes);
nm_system_device_flush_routes_with_iface (iface);
+
+
if (num_routes <= 0)
{
nm_system_delete_default_route ();
}
}
- nm_named_manager_add_ip4_config (named, config);
+ named_mgr = nm_named_manager_get ();
+ nm_named_manager_add_ip4_config (named_mgr, config);
+ g_object_unref (named_mgr);
return TRUE;
}
* Unset an IPv4 configuration of a VPN device from an NMIP4Config object.
*
*/
-gboolean nm_system_vpn_device_unset_from_ip4_config (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config)
+gboolean nm_system_vpn_device_unset_from_ip4_config (NMDevice *active_device, const char *iface, NMIP4Config *config)
{
- g_return_val_if_fail (named != NULL, FALSE);
+ NMNamedManager *named_mgr;
+
g_return_val_if_fail (active_device != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
- nm_named_manager_remove_ip4_config (named, config);
+ named_mgr = nm_named_manager_get ();
+ nm_named_manager_remove_ip4_config (named_mgr, config);
+ g_object_unref (named_mgr);
return TRUE;
}
#include <glib.h>
#include "nm-device.h"
#include "nm-ip4-config.h"
-#include "nm-named-manager.h"
/* Prototypes for system/distribution dependent functions,
* implemented in the backend files in backends/ directory
gboolean nm_system_device_get_disabled (NMDevice *dev);
gboolean nm_system_device_set_from_ip4_config (NMDevice *dev);
-gboolean nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config, char **routes, int num_routes);
-gboolean nm_system_vpn_device_unset_from_ip4_config (NMNamedManager *named, NMDevice *active_device, const char *iface, NMIP4Config *config);
+gboolean nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
+ const char *iface,
+ NMIP4Config *config,
+ char **routes);
+
+gboolean nm_system_vpn_device_unset_from_ip4_config (NMDevice *active_device,
+ const char *iface,
+ NMIP4Config *config);
gboolean nm_system_device_set_up_down (NMDevice *dev, gboolean up);
gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up);
#include <stdarg.h>
#include "NetworkManager.h"
-#include "NetworkManagerMain.h"
#include "nm-device.h"
typedef enum SockType
#include "nm-device.h"
#include "nm-device-802-3-ethernet.h"
#include "nm-device-802-11-wireless.h"
-#include "NetworkManagerMain.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "autoip.h"
#include "NetworkManagerGeneric.h"
#include "NetworkManagerSystem.h"
#include "NetworkManagerUtils.h"
-#include "NetworkManagerMain.h"
#include "nm-device.h"
#include "NetworkManagerPolicy.h"
#include "nm-device-802-3-ethernet.h"
return 255;
}
-static char *
-garray_to_string (GArray *array)
-{
- GString *str;
- int i;
- char c;
-
- str = g_string_sized_new (array->len + 1);
- if (str == NULL)
- return NULL;
-
- for (i = 0; i < array->len; i++) {
- c = array->data[i];
-
- /* Convert NULLs to spaces to increase the readability. */
- if (c == '\0')
- c = ' ';
- str = g_string_append_c (str, c);
- }
- str = g_string_append_c (str, '\0');
-
- return g_string_free (str, FALSE);
-}
-
static char *
get_option (GHashTable * hash,
gpointer key)
return NULL;
}
- return garray_to_string ((GArray *) g_value_get_boxed (value));
+ return nm_utils_garray_to_string ((GArray *) g_value_get_boxed (value));
}
static void
goto error;
}
- dup_value = garray_to_string ((GArray *) g_value_get_boxed (value));
+ dup_value = nm_utils_garray_to_string ((GArray *) g_value_get_boxed (value));
if (!dup_value)
goto error;
DBusConnection *connection);
void (*name_owner_changed) (NMDBusManager *mgr,
- DBusConnection *connection,
const char *name,
const char *old_owner,
const char *new_owner);
#include "nm-device.h"
#include "NetworkManagerAP.h"
-#include "NetworkManagerMain.h"
struct NMAccessPointList;
#include <net/ethernet.h>
#include "nm-device.h"
-#include "NetworkManagerMain.h"
G_BEGIN_DECLS
#define NM_HAL_MANAGER_H
#include "nm-manager.h"
-#include "NetworkManagerMain.h"
typedef struct _NMHalManager NMHalManager;
#include "nm-logging.h"
#include "nm-utils.h"
-#include "NetworkManagerMain.h"
static void
fallback_get_backtrace (void)
-I${top_srcdir}/libnm-util \
-I${top_srcdir}/utils \
-I${top_srcdir}/src \
- -I${top_srcdir}/src/named-manager
+ -I${top_srcdir}/src/named-manager \
+ -DVPN_NAME_FILES_DIR=\""$(sysconfdir)/NetworkManager/VPN"\"
+
noinst_LTLIBRARIES = libvpn-manager.la
-libvpn_manager_la_SOURCES = nm-dbus-vpn.c \
- nm-dbus-vpn.h \
- nm-vpn-connection.c \
- nm-vpn-connection.h \
- nm-vpn-manager.c \
- nm-vpn-manager.h \
- nm-vpn-service.c \
- nm-vpn-service.h \
- nm-vpn-act-request.c \
- nm-vpn-act-request.h
-
-libvpn_manager_la_CPPFLAGS = $(DBUS_CFLAGS) \
- $(GTHREAD_CFLAGS) \
- $(HAL_CFLAGS) \
- -g \
- -Wall \
- -DDBUS_API_SUBJECT_TO_CHANGE \
- -DG_DISABLE_DEPRECATED \
- -DBINDIR=\"$(bindir)\" \
- -DDATADIR=\"$(datadir)\" \
- -DSYSCONFDIR=\"$(sysconfdir)\"
-
-
-libvpn_manager_la_LIBADD = $(DBUS_LIBS) \
- $(GTHREAD_LIBS) \
- $(top_builddir)/libnm-util/libnm-util.la
+libvpn_manager_la_SOURCES = \
+ nm-vpn-manager.c \
+ nm-vpn-manager.h \
+ nm-vpn-service.c \
+ nm-vpn-service.h \
+ nm-vpn-connection.c \
+ nm-vpn-connection.h
+
+libvpn_manager_la_CPPFLAGS = \
+ $(DBUS_CFLAGS) \
+ -DG_DISABLE_DEPRECATED
+
+libvpn_manager_la_LIBADD = \
+ $(DBUS_LIBS) \
+ $(GTHREAD_LIBS) \
+ $(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
+
+nm-vpn-plugin-bindings.h: $(top_srcdir)/introspection/nm-vpn-plugin.xml
+ dbus-binding-tool --prefix=nm_vpn_plugin --mode=glib-client --output=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
+
+$(libvpn_manager_la_OBJECTS): $(built_sources)
+
+CLEANFILES = $(built_sources)
\ No newline at end of file
+++ /dev/null
-/* 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 2005 Red Hat, Inc.
- */
-
-#include <glib.h>
-#include <dbus/dbus.h>
-#include "NetworkManagerMain.h"
-#include "nm-device.h"
-#include "NetworkManagerUtils.h"
-#include "NetworkManagerVPN.h"
-#include "nm-dbus-vpn.h"
-#include "nm-vpn-manager.h"
-#include "nm-vpn-connection.h"
-#include "nm-vpn-service.h"
-#include "nm-vpn-act-request.h"
-#include "nm-utils.h"
-#include "nm-dbus-manager.h"
-
-/*
- * nm_dbus_create_error_message
- *
- * Make a DBus error message
- *
- */
-static DBusMessage *
-nm_dbus_create_error_message (DBusMessage *message,
- const char *exception_namespace,
- const char *exception,
- const char *format,
- ...)
-{
- char *exception_text;
- DBusMessage *reply_message;
- va_list args;
- char error_text[512];
-
- va_start (args, format);
- vsnprintf (error_text, 512, format, args);
- va_end (args);
-
- exception_text = g_strdup_printf ("%s.%s", exception_namespace, exception);
- reply_message = dbus_message_new_error (message, exception_text, error_text);
- g_free (exception_text);
-
- return (reply_message);
-}
-
-
-static DBusMessage *
-nm_dbus_new_invalid_args_error (DBusMessage *replyto,
- const char *namespace)
-{
- return nm_dbus_create_error_message (replyto,
- namespace,
- "InvalidArguments",
- "Invalid method arguments.");
-}
-
-/*
- * Pending Call Debug stuff
- *
- */
-typedef struct PCallInfo
-{
- DBusPendingCall * pcall;
- char * caller;
- guint32 id;
- GTimeVal start;
-} PCallInfo;
-
-static GStaticMutex pcall_mutex = G_STATIC_MUTEX_INIT;
-static GHashTable * pcall_table = NULL;
-static guint32 pcall_gid = 0;
-static guint32 pcall_pending = 0;
-
-
-static DBusPendingCall *
-nm_dbus_send_with_callback (DBusConnection *connection,
- DBusMessage *msg,
- DBusPendingCallNotifyFunction func,
- gpointer data,
- DBusFreeFunction free_func,
- const char *caller)
-{
- PCallInfo * info = NULL;
- DBusPendingCall * pcall = NULL;
-
- g_return_val_if_fail (connection != NULL, NULL);
- g_return_val_if_fail (msg != NULL, NULL);
- g_return_val_if_fail (func != NULL, NULL);
- g_return_val_if_fail (caller != NULL, NULL);
-
- if (!(info = g_malloc0 (sizeof (PCallInfo))))
- {
- g_warning ("Error: '%s' couldn't allocate memory for tracking PCall.", caller);
- if (free_func)
- (*free_func)(data);
- return NULL;
- }
-
- dbus_connection_send_with_reply (connection, msg, &pcall, -1);
- if (!pcall)
- {
- g_warning ("Error: '%s' couldn't send dbus message.", caller);
- if (free_func)
- (*free_func)(data);
- g_free (info);
- return NULL;
- }
- dbus_pending_call_set_notify (pcall, func, data, free_func);
-
- info->caller = g_strdup (caller);
- info->pcall = pcall;
- g_get_current_time (&info->start);
- dbus_pending_call_ref (pcall);
-
- g_static_mutex_lock (&pcall_mutex);
- info->id = pcall_gid++;
- pcall_pending++;
-
- if (!pcall_table)
- pcall_table = g_hash_table_new (g_direct_hash, g_direct_equal);
- g_hash_table_insert (pcall_table, pcall, info);
-
-#ifdef DBUS_PENDING_CALL_DEBUG
- nm_info ("PCall Debug: new id %d (%p), from '%s' (%s), "
- "%d pending.", info->id, pcall, info->caller,
- dbus_message_get_member (msg), pcall_pending);
-#endif
-
- g_static_mutex_unlock (&pcall_mutex);
-
- return pcall;
-}
-
-static void
-nm_dbus_send_with_callback_replied (DBusPendingCall *pcall,
- const char *caller)
-{
- PCallInfo * info;
-#ifdef DBUS_PENDING_CALL_DEBUG
- GTimeVal now;
- long elapsed_ms = 0;
-#endif
-
- g_return_if_fail (pcall != NULL);
- g_return_if_fail (caller != NULL);
-
- g_static_mutex_lock (&pcall_mutex);
- if (!(info = g_hash_table_lookup (pcall_table, pcall)))
- {
- nm_warning ("Error: couldn't find pending call %p in tracking"
- " table.", pcall);
- goto out;
- }
-
- pcall_pending--;
-#ifdef DBUS_PENDING_CALL_DEBUG
- g_get_current_time (&now);
- if (info->start.tv_usec > now.tv_usec)
- {
- now.tv_sec--;
- now.tv_usec = G_USEC_PER_SEC - (info->start.tv_usec - now.tv_usec);
- }
- else
- now.tv_usec -= info->start.tv_usec;
- now.tv_sec -= info->start.tv_sec;
- elapsed_ms = now.tv_sec * G_USEC_PER_SEC + now.tv_usec;
- elapsed_ms /= 1000;
-
- nm_info ("PCall Debug: unregistered ID %d (%p), %s -> %s,"
- " %lums elapsed. Total pending: %d", info->id, info->pcall, info->caller,
- caller, elapsed_ms, pcall_pending);
-#endif
-
- g_hash_table_remove (pcall_table, pcall);
- g_free (info->caller);
- dbus_pending_call_unref (info->pcall);
- g_free (info);
-
-out:
- g_static_mutex_unlock (&pcall_mutex);
-}
-
-
-
-static DBusMessage *
-new_invalid_vpn_connection_error (DBusMessage *replyto)
-{
- return nm_dbus_create_error_message (replyto, NM_DBUS_INTERFACE_VPN,
- "InvalidVPNConnection",
- "No VPN connection with that name"
- " was found.");
-}
-
-/*
- * nm_dbus_vpn_signal_vpn_connection_update
- *
- * Notifies the bus that a VPN connection's properties have changed.
- *
- */
-void
-nm_dbus_vpn_signal_vpn_connection_update (DBusConnection *connection,
- NMVPNConnection *vpn,
- const char *signal)
-{
- DBusMessage *message;
- const char *vpn_name;
-
- g_return_if_fail (connection != NULL);
- g_return_if_fail (vpn != NULL);
-
- message = dbus_message_new_signal (NM_DBUS_PATH_VPN,
- NM_DBUS_INTERFACE_VPN,
- signal);
- if (!message) {
- nm_warning ("could not allocate the dbus message.");
- return;
- }
-
- vpn_name = nm_vpn_connection_get_name (vpn);
- dbus_message_append_args (message,
- DBUS_TYPE_STRING, &vpn_name,
- DBUS_TYPE_INVALID);
- dbus_connection_send (connection, message, NULL);
- dbus_message_unref (message);
-}
-
-/*
- * nm_dbus_vpn_signal_vpn_connection_state_change
- *
- * Notifies the bus that a VPN connection's state has changed.
- */
-void
-nm_dbus_vpn_signal_vpn_connection_state_change (DBusConnection *connection,
- NMVPNConnection *vpn,
- NMVPNConnectionState new_state)
-{
- DBusMessage * message;
- const char * vpn_name;
- dbus_uint32_t int_state = (dbus_uint32_t) new_state;
-
- g_return_if_fail (connection != NULL);
- g_return_if_fail (vpn != NULL);
-
- message = dbus_message_new_signal (NM_DBUS_PATH_VPN,
- NM_DBUS_INTERFACE_VPN,
- "VPNConnectionStateChange");
- if (!message) {
- nm_warning ("could not allocate dbus connection.");
- return;
- }
-
- vpn_name = nm_vpn_connection_get_name (vpn);
- dbus_message_append_args (message,
- DBUS_TYPE_STRING, &vpn_name,
- DBUS_TYPE_UINT32, &int_state,
- DBUS_TYPE_INVALID);
- dbus_connection_send (connection, message, NULL);
- dbus_message_unref (message);
-}
-
-
-/*
- * nnm_dbus_vpn_signal_vpn_failure
- *
- * Proxy a VPN Failure message from the vpn daemon to the bus.
- *
- */
-void
-nm_dbus_vpn_signal_vpn_failed (DBusConnection *connection,
- const char *signal,
- NMVPNConnection *vpn,
- const char *error_msg)
-{
- DBusMessage *message;
- const char *vpn_name;
-
- g_return_if_fail (connection != NULL);
- g_return_if_fail (signal != NULL);
- g_return_if_fail (vpn != NULL);
- g_return_if_fail (error_msg != NULL);
-
- message = dbus_message_new_signal (NM_DBUS_PATH_VPN,
- NM_DBUS_INTERFACE_VPN,
- signal);
- if (!message) {
- nm_warning ("could not allocate the dbus message.");
- return;
- }
-
- vpn_name = nm_vpn_connection_get_name (vpn);
- dbus_message_append_args (message,
- DBUS_TYPE_STRING, &vpn_name,
- DBUS_TYPE_STRING, &error_msg,
- DBUS_TYPE_INVALID);
- dbus_connection_send (connection, message, NULL);
- dbus_message_unref (message);
-}
-
-
-/*
- * nnm_dbus_vpn_signal_vpn_login_banner
- *
- * Pass the VPN's login banner message to the bus if anyone wants to use it.
- *
- */
-void
-nm_dbus_vpn_signal_vpn_login_banner (DBusConnection *connection,
- NMVPNConnection *vpn,
- const char *banner)
-{
- DBusMessage *message;
- const char *vpn_name;
-
- g_return_if_fail (connection != NULL);
- g_return_if_fail (vpn != NULL);
- g_return_if_fail (banner != NULL);
-
- message = dbus_message_new_signal (NM_DBUS_PATH_VPN,
- NM_DBUS_INTERFACE_VPN,
- NM_DBUS_VPN_SIGNAL_LOGIN_BANNER);
- if (!message) {
- nm_warning ("could not allocate the dbus message.");
- return;
- }
-
- vpn_name = nm_vpn_connection_get_name (vpn);
- dbus_message_append_args (message,
- DBUS_TYPE_STRING, &vpn_name,
- DBUS_TYPE_STRING, &banner,
- DBUS_TYPE_INVALID);
- dbus_connection_send (connection, message, NULL);
- dbus_message_unref (message);
-}
-
-
-/*
- * nm_dbus_vpn_get_vpn_data
- *
- * Get VPN specific data from NMI for a vpn connection
- *
- * NOTE: caller MUST free returned value using g_strfreev()
- *
- */
-static char **
-nm_dbus_vpn_get_vpn_data (DBusConnection *connection,
- NMVPNConnection *vpn,
- int *num_items)
-{
- DBusMessage *message;
- DBusError error;
- DBusMessage *reply = NULL;
- char **data_items = NULL;
- const char *vpn_name;
- DBusMessageIter iter, array_iter;
- GArray * buffer;
-
- g_return_val_if_fail (connection != NULL, NULL);
- g_return_val_if_fail (vpn != NULL, NULL);
- g_return_val_if_fail (num_items != NULL, NULL);
-
- *num_items = -1;
-
- message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
- NMI_DBUS_PATH,
- NMI_DBUS_INTERFACE,
- "getVPNConnectionVPNData");
- if (!message) {
- nm_warning ("couldn't allocate the dbus message.");
- return NULL;
- }
-
- vpn_name = nm_vpn_connection_get_name (vpn);
- dbus_message_append_args (message,
- DBUS_TYPE_STRING, &vpn_name,
- DBUS_TYPE_INVALID);
-
- dbus_error_init (&error);
- reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
- dbus_message_unref (message);
- if (dbus_error_is_set (&error)) {
- nm_warning ("%s raised %s", error.name, error.message);
- dbus_error_free (&error);
- goto out;
- }
-
- if (!reply) {
- nm_warning ("did not receive a reply.");
- goto out;
- }
-
- dbus_message_iter_init (reply, &iter);
- dbus_message_iter_recurse (&iter, &array_iter);
-
- buffer = g_array_new (TRUE, TRUE, sizeof (gchar *));
- if (buffer == NULL) {
- nm_warning ("could not allocate buffer for VPN connection data.");
- goto out;
- }
-
- while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
- const char *value;
- char *str;
-
- dbus_message_iter_get_basic (&array_iter, &value);
- str = g_strdup (value);
- if (!str) {
- nm_warning ("could not allocate string.");
- g_array_free (buffer, TRUE);
- goto out;
- }
- g_array_append_val (buffer, str);
- dbus_message_iter_next (&array_iter);
- }
- data_items = (gchar **)(buffer->data);
- *num_items = buffer->len;
- g_array_free (buffer, FALSE);
-
-out:
- if (reply)
- dbus_message_unref (reply);
-
- return data_items;
-}
-
-
-/*
- * nm_dbus_vpn_get_routes
- *
- * Get VPN routes from NMI for a vpn connection
- *
- * NOTE: caller MUST free returned value using g_strfreev()
- *
- */
-char **
-nm_dbus_vpn_get_routes (DBusConnection *connection,
- NMVPNConnection *vpn,
- int *num_items)
-{
- DBusMessage *message;
- DBusError error;
- DBusMessage *reply;
- char **routes = NULL;
- const char *vpn_name;
- DBusMessageIter iter, array_iter;
- GArray * buffer;
-
- g_return_val_if_fail (connection != NULL, NULL);
- g_return_val_if_fail (vpn != NULL, NULL);
- g_return_val_if_fail (num_items != NULL, NULL);
-
- *num_items = -1;
-
- message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
- NMI_DBUS_PATH,
- NMI_DBUS_INTERFACE,
- "getVPNConnectionRoutes");
- if (!message) {
- nm_warning ("couldn't allocate the dbus message.");
- return NULL;
- }
-
- vpn_name = nm_vpn_connection_get_name (vpn);
- dbus_message_append_args (message,
- DBUS_TYPE_STRING, &vpn_name,
- DBUS_TYPE_INVALID);
-
- dbus_error_init (&error);
- reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
- dbus_message_unref (message);
- if (dbus_error_is_set (&error)) {
- nm_warning ("%s raised %s", error.name, error.message);
- dbus_error_free (&error);
- goto out;
- }
-
- if (!reply) {
- nm_warning ("did not receive a reply.");
- goto out;
- }
-
- dbus_message_iter_init (reply, &iter);
- dbus_message_iter_recurse (&iter, &array_iter);
-
- buffer = g_array_new (TRUE, TRUE, sizeof (gchar *));
- if (!buffer) {
- nm_warning ("could not allocate buffer for VPN routes.");
- goto out;
- }
-
- while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
- const char *value;
- char *str;
-
- dbus_message_iter_get_basic (&array_iter, &value);
- str = g_strdup (value);
- if (!str) {
- nm_warning ("could not allocate string.");
- g_array_free (buffer, TRUE);
- goto out;
- }
- g_array_append_val (buffer, str);
- dbus_message_iter_next (&array_iter);
- }
- routes = (gchar **)(buffer->data);
- *num_items = buffer->len;
- g_array_free (buffer, FALSE);
-
-out:
- if (reply)
- dbus_message_unref (reply);
-
- return routes;
-}
-
-
-typedef struct UpdateOneVPNCBData {
- NMVPNManager *manager;
- char * vpn;
-} UpdateOneVPNCBData;
-
-
-static void
-free_update_one_vpn_cb_data (UpdateOneVPNCBData *data)
-{
- if (data)
- g_free (data->vpn);
- g_slice_free (UpdateOneVPNCBData, data);
-}
-
-/*
- * nm_dbus_vpn_update_one_connection_cb
- *
- * Retrieve and add to our VPN Manager one VPN connection from NMI.
- *
- */
-static void
-nm_dbus_vpn_update_one_connection_cb (DBusPendingCall *pcall,
- void *user_data)
-{
- UpdateOneVPNCBData * cb_data = (UpdateOneVPNCBData *) user_data;
- NMDBusManager * dbus_mgr = NULL;
- DBusConnection * dbus_connection;
- DBusMessage * reply = NULL;
- const char * con_name = NULL;
- const char * service_name = NULL;
- const char * user_name = NULL;
- const char * vpn_service_name;
- NMVPNConnection * vpn;
- gboolean new = TRUE;
-
- g_return_if_fail (pcall != NULL);
- g_return_if_fail (cb_data != NULL);
- g_return_if_fail (cb_data->manager != NULL);
-
- nm_dbus_send_with_callback_replied (pcall, __func__);
-
- dbus_pending_call_ref (pcall);
-
- if (!dbus_pending_call_get_completed (pcall))
- goto out;
-
- dbus_mgr = nm_dbus_manager_get ();
- dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
- if (!dbus_connection) {
- nm_warning ("couldn't get the dbus connection.");
- goto out;
- }
-
- if (!(reply = dbus_pending_call_steal_reply (pcall)))
- goto out;
-
- if (dbus_message_is_error (reply, "BadVPNConnectionData")) {
- /* Bad VPN, remove it from our VPN connection list */
- if ((vpn = nm_vpn_manager_find_connection_by_name (cb_data->manager,
- cb_data->vpn))) {
- nm_vpn_connection_ref (vpn);
- nm_vpn_manager_remove_connection (cb_data->manager, vpn);
- nm_dbus_vpn_signal_vpn_connection_update (dbus_connection,
- vpn,
- "VPNConnectionRemoved");
- nm_vpn_connection_unref (vpn);
- }
- goto unref_reply;
- }
-
- if (!dbus_message_get_args (reply,
- NULL,
- DBUS_TYPE_STRING, &con_name,
- DBUS_TYPE_STRING, &service_name,
- DBUS_TYPE_STRING, &user_name,
- DBUS_TYPE_INVALID)) {
- goto unref_reply;
- }
-
- vpn = nm_vpn_manager_find_connection_by_name (cb_data->manager,
- con_name);
- if (vpn) {
- /* If all attributes of the existing connection are the same as
- * the one we get from NMI, don't do anything.
- */
- vpn_service_name = nm_vpn_connection_get_service_name (vpn);
- if ( (strcmp (vpn_service_name, service_name) != 0)
- || (strcmp (nm_vpn_connection_get_user_name (vpn), user_name) != 0)) {
- nm_vpn_manager_remove_connection (cb_data->manager, vpn);
- } else {
- new = FALSE;
- }
- }
-
- if (new) {
- vpn = nm_vpn_manager_add_connection (cb_data->manager,
- con_name,
- service_name,
- user_name);
- }
-
- if (vpn) {
- const char * signal = new ? "VPNConnectionAdded" : "VPNConnectionUpdate";
- nm_dbus_vpn_signal_vpn_connection_update (dbus_connection, vpn, signal);
- }
-
-unref_reply:
- dbus_message_unref (reply);
-
-out:
- if (dbus_mgr)
- g_object_unref (dbus_mgr);
- dbus_pending_call_unref (pcall);
-}
-
-
-/*
- * nm_dbus_vpn_connections_update_cb
- *
- * Async callback from nnm_dbus_vpn_connections_update
- *
- */
-static void
-nm_dbus_vpn_connections_update_cb (DBusPendingCall *pcall,
- void *user_data)
-{
- NMVPNManager *manager = (NMVPNManager *) user_data;
- DBusMessage * reply;
- DBusMessageIter iter, array_iter;
- GSList * remove_list = NULL;
- GSList * elt;
- NMDBusManager * dbus_mgr = NULL;
- DBusConnection * dbus_connection;
-
- g_return_if_fail (pcall);
- g_return_if_fail (manager != NULL);
-
- nm_dbus_send_with_callback_replied (pcall, __func__);
-
- dbus_pending_call_ref (pcall);
-
- if (!dbus_pending_call_get_completed (pcall))
- goto out;
-
- dbus_mgr = nm_dbus_manager_get ();
- dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
- if (!dbus_connection) {
- nm_warning ("couldn't get the dbus connection.");
- goto out;
- }
-
- if (!(reply = dbus_pending_call_steal_reply (pcall)))
- goto out;
-
- if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR)
- goto unref_reply;
-
- nm_info ("Updating VPN Connections...");
-
- remove_list = nm_vpn_manager_vpn_connection_list_copy (manager);
-
- dbus_message_iter_init (reply, &iter);
- dbus_message_iter_recurse (&iter, &array_iter);
- while (dbus_message_iter_get_arg_type (&array_iter) == DBUS_TYPE_STRING) {
- DBusMessage * message;
- const char * con_name;
- NMVPNConnection * vpn;
-
- dbus_message_iter_get_basic (&array_iter, &con_name);
-
- /* If the connection already exists, remove it from the remove list */
- if ((vpn = nm_vpn_manager_find_connection_by_name (manager, con_name)))
- remove_list = g_slist_remove (remove_list, vpn);
-
- message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
- NMI_DBUS_PATH,
- NMI_DBUS_INTERFACE,
- "getVPNConnectionProperties");
- if (message) {
- UpdateOneVPNCBData * vpn_cb_data = g_slice_new0 (UpdateOneVPNCBData);
-
- dbus_message_append_args (message,
- DBUS_TYPE_STRING, &con_name,
- DBUS_TYPE_INVALID);
-
- vpn_cb_data->manager = manager;
- vpn_cb_data->vpn = g_strdup (con_name);
- nm_dbus_send_with_callback (dbus_connection,
- message,
- (DBusPendingCallNotifyFunction) nm_dbus_vpn_update_one_connection_cb,
- vpn_cb_data,
- (DBusFreeFunction) free_update_one_vpn_cb_data,
- __func__);
- dbus_message_unref (message);
- }
- dbus_message_iter_next (&array_iter);
- }
-
- /* VPN connections left in the remove list aren't known by NMI, therefore we delete them */
- for (elt = remove_list; elt; elt = g_slist_next (elt)) {
- nm_vpn_manager_remove_connection (manager, elt->data);
- nm_vpn_connection_unref (elt->data);
- }
-
- g_slist_free (remove_list);
-
-unref_reply:
- dbus_message_unref (reply);
-
-out:
- if (dbus_mgr)
- g_object_unref (dbus_mgr);
- dbus_pending_call_unref (pcall);
-}
-
-
-/*
- * nm_dbus_vpn_update_one_vpn_connection
- *
- * Update one VPN connection
- *
- */
-void
-nm_dbus_vpn_update_one_vpn_connection (DBusConnection *connection,
- NMVPNManager *manager,
- const char *vpn)
-{
- DBusMessage * message;
- UpdateOneVPNCBData *cb_data;
-
- g_return_if_fail (connection != NULL);
- g_return_if_fail (manager != NULL);
- g_return_if_fail (vpn != NULL);
-
- message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
- NMI_DBUS_PATH,
- NMI_DBUS_INTERFACE,
- "getVPNConnectionProperties");
- if (!message) {
- nm_warning ("Couldn't allocate the dbus message.");
- return;
- }
-
- dbus_message_append_args (message, DBUS_TYPE_STRING, &vpn, DBUS_TYPE_INVALID);
-
- cb_data = g_slice_new0 (UpdateOneVPNCBData);
- cb_data->manager = manager;
- cb_data->vpn = g_strdup (vpn);
- nm_dbus_send_with_callback (connection,
- message,
- (DBusPendingCallNotifyFunction) nm_dbus_vpn_update_one_connection_cb,
- cb_data,
- (DBusFreeFunction) free_update_one_vpn_cb_data,
- __func__);
- dbus_message_unref (message);
-}
-
-
-/*
- * nm_dbus_vpn_connections_update_from_nmi
- *
- * Update VPN connections from NetworkManagerInfo.
- *
- */
-static gboolean
-nm_dbus_vpn_connections_update_from_nmi (NMVPNManager *manager)
-{
- DBusMessage * message;
- NMDBusManager * dbus_mgr;
- DBusConnection * dbus_connection;
-
- g_return_val_if_fail (manager != NULL, FALSE);
-
- dbus_mgr = nm_dbus_manager_get ();
- dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
- if (!dbus_connection) {
- nm_warning ("couldn't get the dbus connection.");
- goto out;
- }
-
- message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
- NMI_DBUS_PATH,
- NMI_DBUS_INTERFACE,
- "getVPNConnections");
- if (!message) {
- nm_warning ("Couldn't allocate the dbus message.");
- goto out;
- }
-
- nm_dbus_send_with_callback (dbus_connection,
- message,
- (DBusPendingCallNotifyFunction) nm_dbus_vpn_connections_update_cb,
- manager,
- NULL,
- __func__);
- dbus_message_unref (message);
-
-out:
- g_object_unref (dbus_mgr);
- return FALSE;
-}
-
-
-/*
- * nm_dbus_vpn_schedule_vpn_connections_update
- *
- * Schedule an update of VPN connections in the main thread
- *
- */
-void nm_dbus_vpn_schedule_vpn_connections_update (NMVPNManager *manager)
-{
- g_return_if_fail (manager != NULL);
-
- g_idle_add_full (G_PRIORITY_HIGH_IDLE,
- (GSourceFunc) nm_dbus_vpn_connections_update_from_nmi,
- manager,
- NULL);
-}
-
-
-/*
- * nm_dbus_vpn_get_vpn_connections
- *
- * Returns a string array of VPN connection names.
- *
- */
-static DBusMessage *
-nm_dbus_vpn_get_vpn_connections (DBusConnection *connection,
- DBusMessage *message,
- gpointer user_data)
-{
- NMVPNManager * vpn_mgr = (NMVPNManager *) user_data;
- DBusMessage * reply = NULL;
- char ** vpn_names = NULL;
- int num_names;
-
- g_return_val_if_fail (vpn_mgr != NULL, NULL);
- g_return_val_if_fail (connection != NULL, NULL);
- g_return_val_if_fail (message != NULL, NULL);
-
- vpn_names = nm_vpn_manager_get_connection_names (vpn_mgr);
- num_names = vpn_names ? g_strv_length (vpn_names) : 0;
- if (num_names == 0) {
- reply = nm_dbus_create_error_message (message,
- NM_DBUS_INTERFACE_VPN,
- "NoVPNConnections",
- "There are no available VPN "
- "connections.");
- goto out;
- }
-
- if (!(reply = dbus_message_new_method_return (message)))
- goto out;
-
- dbus_message_append_args (reply,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &vpn_names, num_names,
- DBUS_TYPE_INVALID);
-
-out:
- if (vpn_names)
- g_strfreev (vpn_names);
-
- return (reply);
-}
-
-
-/*
- * nm_dbus_vpn_get_vpn_connection_properties
- *
- * Grab properties of a VPN connection
- *
- */
-static DBusMessage *
-nm_dbus_vpn_get_vpn_connection_properties (DBusConnection *connection,
- DBusMessage *message,
- gpointer user_data)
-{
- DBusMessage * reply = NULL;
- DBusError error;
- const char * name;
- gboolean success = FALSE;
- NMVPNManager * vpn_mgr = (NMVPNManager *) user_data;
- NMVPNConnection * vpn;
- const char * user_name;
- const char * service_name;
- NMVPNService * service;
- NMVPNActRequest * req;
- dbus_uint32_t state;
-
- g_return_val_if_fail (vpn_mgr != NULL, NULL);
- g_return_val_if_fail (connection != NULL, NULL);
- g_return_val_if_fail (message != NULL, NULL);
-
- if (!(reply = dbus_message_new_method_return (message)))
- return NULL;
-
- dbus_error_init (&error);
- if (!dbus_message_get_args (message, &error,
- DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) {
- if (dbus_error_is_set (&error))
- dbus_error_free (&error);
- reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE_VPN);
- goto out;
- }
-
- if (!(vpn = nm_vpn_manager_find_connection_by_name (vpn_mgr, name)))
- goto out;
-
- user_name = nm_vpn_connection_get_user_name (vpn);
- service_name = nm_vpn_connection_get_service_name (vpn);
- if (!(service = nm_vpn_manager_find_service_by_name (vpn_mgr, service_name)))
- goto out;
-
- req = nm_vpn_manager_get_vpn_act_request (vpn_mgr);
- state = (dbus_uint32_t) NM_VPN_CONNECTION_STATE_DISCONNECTED;
- if (req && (nm_vpn_act_request_get_connection (req) == vpn))
- state = nm_vpn_act_request_get_state (req);
-
- dbus_message_append_args (reply, DBUS_TYPE_STRING, &name,
- DBUS_TYPE_STRING, &user_name,
- DBUS_TYPE_STRING, &service_name,
- DBUS_TYPE_UINT32, &state,
- DBUS_TYPE_INVALID);
- success = TRUE;
-
-out:
- if (!success)
- reply = new_invalid_vpn_connection_error (message);
-
- return reply;
-}
-
-
-/*
- * nm_dbus_vpn_activate_connection
- *
- * Activate a specific VPN connection.
- *
- */
-static DBusMessage *
-nm_dbus_vpn_activate_connection (DBusConnection *connection,
- DBusMessage *message,
- gpointer user_data)
-{
- NMVPNManager * vpn_mgr = (NMVPNManager *) user_data;
- DBusMessage * reply = NULL;
- DBusError error;
- const char * name;
- char ** passwords;
- int num_passwords;
- NMVPNConnection * vpn;
- int item_count = -1;
- char **items;
- int routes_count = -1;
- char **routes;
-
- g_return_val_if_fail (vpn_mgr != NULL, NULL);
- g_return_val_if_fail (connection != NULL, NULL);
- g_return_val_if_fail (message != NULL, NULL);
-
- dbus_error_init (&error);
- if (!dbus_message_get_args (message, &error,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &passwords, &num_passwords,
- DBUS_TYPE_INVALID)) {
- reply = nm_dbus_new_invalid_args_error (message, NM_DBUS_INTERFACE_VPN);
- goto out;
- }
-
- if (!(vpn = nm_vpn_manager_find_connection_by_name (vpn_mgr, name))) {
- reply = new_invalid_vpn_connection_error (message);
- goto out;
- }
-
- routes = nm_dbus_vpn_get_routes (connection, vpn, &routes_count);
- if ((items = nm_dbus_vpn_get_vpn_data (connection, vpn, &item_count)))
- {
- char * joined_string = g_strjoinv (" / ", items);
- char * routes_string = g_strjoinv (" / ", routes);
- nm_info ("Will activate VPN connection '%s', service '%s', user_name "
- "'%s', vpn_data '%s', route '%s'.",
- name,
- nm_vpn_connection_get_service_name (vpn),
- nm_vpn_connection_get_user_name (vpn),
- joined_string,
- routes_string);
- nm_vpn_manager_activate_vpn_connection (vpn_mgr, vpn, passwords,
- num_passwords, items, item_count,
- routes, routes_count);
-
- g_free (joined_string);
- g_free (routes_string);
- g_strfreev (items);
- }
-
-out:
- return reply;
-}
-
-
-/*
- * nm_dbus_vpn_deactivate_connection
- *
- * Deactivate the active VPN connection, if any.
- *
- */
-static DBusMessage *
-nm_dbus_vpn_deactivate_connection (DBusConnection *connection,
- DBusMessage *message,
- gpointer user_data)
-{
- NMVPNManager * vpn_mgr = (NMVPNManager *) user_data;
- NMVPNActRequest * req;
- NMVPNConnection * vpn;
-
- g_return_val_if_fail (vpn_mgr != NULL, NULL);
- g_return_val_if_fail (connection != NULL, NULL);
- g_return_val_if_fail (message != NULL, NULL);
-
- if (!(req = nm_vpn_manager_get_vpn_act_request (vpn_mgr)))
- return NULL;
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
-
- nm_info ("Will deactivate the VPN connection '%s', service '%s'.",
- nm_vpn_connection_get_name (vpn),
- nm_vpn_connection_get_service_name (vpn));
- nm_vpn_manager_deactivate_vpn_connection (vpn_mgr,
- nm_vpn_act_request_get_parent_dev (req));
-
- return NULL;
-}
-
-
-static DBusHandlerResult
-dbus_message_handler (DBusConnection *con, DBusMessage *message, void *user_data)
-{
- DBusMessage *reply = NULL;
- DBusHandlerResult result = DBUS_HANDLER_RESULT_HANDLED;
-
- if (dbus_message_has_member (message, "getVPNConnections"))
- reply = nm_dbus_vpn_get_vpn_connections (con, message, user_data);
- else if (dbus_message_has_member (message, "getVPNConnectionProperties"))
- reply = nm_dbus_vpn_get_vpn_connection_properties (con, message, user_data);
- else if (dbus_message_has_member (message, "activateVPNConnection"))
- reply = nm_dbus_vpn_activate_connection (con, message, user_data);
- else if (dbus_message_has_member (message, "deactivateVPNConnection"))
- reply = nm_dbus_vpn_deactivate_connection (con, message, user_data);
- else
- result = DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-
- if (reply) {
- dbus_connection_send (con, reply, NULL);
- dbus_message_unref (reply);
- }
-
- return result;
-}
-
-
-/*
- * nm_dbus_vpn_methods_setup
- *
- * Register handlers for dbus methods on the
- * org.freedesktop.NetworkManager.VPNConnections object.
- *
- */
-gboolean
-nm_dbus_vpn_methods_setup (NMVPNManager *mgr)
-{
- NMDBusManager *dbus_mgr;
- gboolean success;
- DBusObjectPathVTable vtable = { NULL, &dbus_message_handler, NULL, NULL, NULL, NULL };
-
- dbus_mgr = nm_dbus_manager_get ();
- success = dbus_connection_register_object_path (nm_dbus_manager_get_dbus_connection (dbus_mgr),
- NM_DBUS_PATH_VPN, &vtable, mgr);
- if (!success)
- nm_warning ("Could not register a dbus handler for VPN. Not enough memory?");
-
- g_object_unref (dbus_mgr);
-
- return success;
-}
+++ /dev/null
-/* 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 2005 Red Hat, Inc.
- */
-
-#ifndef NM_DBUS_VPN_H
-#define NM_DBUS_VPN_H
-
-#include "NetworkManagerDbusUtils.h"
-#include "nm-vpn-manager.h"
-#include "nm-vpn-connection.h"
-
-#define NMI_DBUS_SERVICE "org.freedesktop.NetworkManagerInfo"
-#define NMI_DBUS_PATH "/org/freedesktop/NetworkManagerInfo"
-#define NMI_DBUS_INTERFACE "org.freedesktop.NetworkManagerInfo"
-
-void nm_dbus_vpn_schedule_vpn_connections_update (NMVPNManager *manager);
-
-void nm_dbus_vpn_update_one_vpn_connection (DBusConnection *connection,
- NMVPNManager *manager,
- const char *vpn);
-
-void nm_dbus_vpn_signal_vpn_connection_update (DBusConnection *con,
- NMVPNConnection *vpn,
- const char *signal);
-
-void nm_dbus_vpn_signal_vpn_failed (DBusConnection *con,
- const char *signal,
- NMVPNConnection *vpn,
- const char *error_msg);
-
-void nm_dbus_vpn_signal_vpn_login_banner (DBusConnection *con,
- NMVPNConnection *vpn,
- const char *banner);
-
-void nm_dbus_vpn_signal_vpn_connection_state_change (DBusConnection *con,
- NMVPNConnection *vpn,
- NMVPNConnectionState new_state);
-
-char ** nm_dbus_vpn_get_routes (DBusConnection *connection,
- NMVPNConnection *vpn,
- int *num_items);
-
-gboolean nm_dbus_vpn_methods_setup (NMVPNManager *mgr);
-
-#endif
-/* nm-vpn-connection.c - handle a single VPN connections within NetworkManager's framework
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
+/* NetworkManager -- Network link manager
*
- * Copyright (C) 2005 Dan Williams
+ * 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, or (at your option)
- * any later version.
+ * 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
*
* 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.
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * (C) Copyright 2005 Red Hat, Inc.
*/
-#include "config.h"
+
#include <glib.h>
#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
#include "nm-vpn-connection.h"
-#include "nm-dbus-vpn.h"
#include "nm-dbus-manager.h"
-#include "nm-utils.h"
#include "NetworkManagerSystem.h"
+#include "nm-utils.h"
+#include "nm-vpn-plugin-bindings.h"
+static gboolean impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err);
-struct NMVPNConnection
-{
- int refcount;
+#include "nm-vpn-connection-glue.h"
+
+G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
- /* Won't change over life of object */
- char * name;
- char * user_name;
- char * service_name;
+typedef struct {
+ char *name;
+ char *dbus_service;
+ GHashTable *properties;
+ char **routes;
+ NMDevice *parent_dev;
+ char *object_path;
+
+ NMVPNConnectionState state;
+ gulong device_monitor;
+ DBusGProxy *proxy;
+ guint ipconfig_timeout;
+ NMIP4Config *ip4_config;
+ char *tundev;
+} NMVPNConnectionPrivate;
- NMNamedManager *named_manager;
+#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
- /* Change when connection is activated/deactivated */
- NMDevice * parent_dev;
- NMIP4Config * ip4_config;
- char * vpn_iface;
+enum {
+ STATE_CHANGED,
+
+ LAST_SIGNAL
};
+static guint signals[LAST_SIGNAL] = { 0 };
-static void nm_vpn_connection_set_vpn_iface (NMVPNConnection *con, const char *vpn_iface);
-static void nm_vpn_connection_set_ip4_config (NMVPNConnection *con, NMIP4Config *ip4_config);
-static void nm_vpn_connection_set_parent_device(NMVPNConnection *con, NMDevice *parent_dev);
+enum {
+ PROP_0,
+ PROP_NAME,
+ PROP_STATE,
+ LAST_PROP
+};
-NMVPNConnection *
-nm_vpn_connection_new (const char *name,
- const char *user_name,
- const char *service_name,
- NMNamedManager *named_manager)
+static void
+nm_vpn_connection_set_state (NMVPNConnection *connection,
+ NMVPNConnectionState state)
{
- NMVPNConnection *connection;
+ NMVPNConnectionPrivate *priv;
- g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (user_name != NULL, NULL);
- g_return_val_if_fail (service_name != NULL, NULL);
- g_return_val_if_fail (named_manager != NULL, NULL);
-
- connection = g_malloc0 (sizeof (NMVPNConnection));
- connection->refcount = 1;
+ g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
- connection->name = g_strdup (name);
- connection->user_name = g_strdup (user_name);
- connection->service_name = g_strdup (service_name);
+ priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
- g_object_ref (named_manager);
- connection->named_manager = named_manager;
+ if (state != priv->state) {
+ priv->state = state;
- return connection;
+ g_object_ref (connection);
+ g_signal_emit (connection, signals[STATE_CHANGED], 0, state);
+ g_object_unref (connection);
+ }
}
+static void
+device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
+{
+ NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+
+ if (state == NM_DEVICE_STATE_DISCONNECTED)
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_DISCONNECTED);
+}
-void nm_vpn_connection_ref (NMVPNConnection *connection)
+NMVPNConnection *
+nm_vpn_connection_new (const char *name,
+ const char *dbus_service,
+ NMDevice *parent_device,
+ GHashTable *properties,
+ char **routes)
{
- g_return_if_fail (connection != NULL);
+ NMVPNConnection *connection;
+
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
+ g_return_val_if_fail (properties != NULL, NULL);
+
+ connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
+ if (connection) {
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+ priv->name = g_strdup (name);
+ priv->dbus_service = g_strdup (dbus_service);
+ priv->parent_dev = g_object_ref (parent_device);
+ priv->properties = properties;
+ priv->routes = routes;
+
+ priv->device_monitor = g_signal_connect (parent_device, "state-changed",
+ G_CALLBACK (device_state_changed),
+ connection);
+ }
- connection->refcount++;
+ return connection;
}
-void nm_vpn_connection_unref (NMVPNConnection *connection)
+static void
+plugin_state_changed (DBusGProxy *proxy,
+ NMVPNServiceState state,
+ gpointer user_data)
{
- g_return_if_fail (connection != NULL);
+ NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+
+ nm_debug ("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);
+ break;
+ case NM_VPN_CONNECTION_STATE_ACTIVATED:
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_DISCONNECTED);
+ break;
+ default:
+ break;
+ }
+ }
+}
- connection->refcount--;
- if (connection->refcount <= 0)
- {
- g_free (connection->name);
- g_free (connection->user_name);
- g_free (connection->service_name);
+static void
+print_vpn_config (NMIP4Config *config,
+ const char *tundev,
+ const char *login_banner)
+{
+ struct in_addr temp_addr;
+ char * dns_domain = NULL;
+ guint32 num;
+ guint32 i;
+
+ g_return_if_fail (config != NULL);
+
+ temp_addr.s_addr = nm_ip4_config_get_gateway (config);
+ nm_info ("VPN Gateway: %s", inet_ntoa (temp_addr));
+ nm_info ("Tunnel Device: %s", tundev);
+ temp_addr.s_addr = nm_ip4_config_get_address (config);
+ nm_info ("Internal IP4 Address: %s", inet_ntoa (temp_addr));
+ temp_addr.s_addr = nm_ip4_config_get_netmask (config);
+ nm_info ("Internal IP4 Netmask: %s", inet_ntoa (temp_addr));
+ temp_addr.s_addr = nm_ip4_config_get_ptp_address (config);
+ nm_info ("Internal IP4 Point-to-Point Address: %s", inet_ntoa (temp_addr));
+ nm_info ("Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (config));
+
+ num = nm_ip4_config_get_num_nameservers (config);
+ for (i = 1; i <= num; i++)
+ {
+ temp_addr.s_addr = nm_ip4_config_get_nameserver (config, i);
+ nm_info ("Internal IP4 DNS: %s", inet_ntoa (temp_addr));
+ }
+
+ if (nm_ip4_config_get_num_domains (config) > 0)
+ dns_domain = (char *) nm_ip4_config_get_domain (config, 1);
+ nm_info ("DNS Domain: '%s'", dns_domain ? dns_domain : "(none)");
+ nm_info ("Login Banner:");
+ nm_info ("-----------------------------------------");
+ nm_info ("%s", login_banner);
+ nm_info ("-----------------------------------------");
+}
- if (connection->parent_dev)
- g_object_unref (G_OBJECT (connection->parent_dev));
- if (connection->ip4_config)
- g_object_unref (connection->ip4_config);
- g_free (connection->vpn_iface);
+static void
+nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
+ GHashTable *config_hash,
+ gpointer user_data)
+{
+ NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+ NMIP4Config *config;
+ GValue *val;
+ const char *banner = NULL;
+ int i;
+
+ nm_info ("VPN connection '%s' (IP Config Get) reply received.",
+ nm_vpn_connection_get_name (connection));
+
+ g_source_remove (priv->ipconfig_timeout);
+ priv->ipconfig_timeout = 0;
+
+ config = nm_ip4_config_new ();
+ nm_ip4_config_set_secondary (config, TRUE);
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_GATEWAY);
+ if (val)
+ nm_ip4_config_set_gateway (config, g_value_get_uint (val));
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS);
+ if (val)
+ nm_ip4_config_set_address (config, g_value_get_uint (val));
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_PTP);
+ if (val)
+ nm_ip4_config_set_ptp_address (config, g_value_get_uint (val));
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NETMASK);
+ if (val)
+ nm_ip4_config_set_netmask (config, g_value_get_uint (val));
+ else
+ /* If no netmask, default to Class C address */
+ nm_ip4_config_set_netmask (config, 0x00FF);
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_DNS);
+ if (val) {
+ GArray *dns = (GArray *) g_value_get_boxed (val);
+
+ for (i = 0; i < dns->len; i++)
+ nm_ip4_config_add_nameserver (config, g_array_index (dns, guint, i));
+ }
- g_object_unref (connection->named_manager);
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NBNS);
+ if (val) {
+ GArray *nbns = (GArray *) g_value_get_boxed (val);
- memset (connection, 0, sizeof (NMVPNConnection));
- g_free (connection);
+ for (i = 0; i < nbns->len; i++)
+ nm_ip4_config_add_nameserver (config, g_array_index (nbns, guint, i));
}
-}
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_MSS);
+ if (val)
+ nm_ip4_config_set_mss (config, g_value_get_uint (val));
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_MTU);
+ if (val)
+ nm_ip4_config_set_mtu (config, g_value_get_uint (val));
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_TUNDEV);
+ if (val)
+ priv->tundev = g_strdup (g_value_get_string (val));
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN);
+ if (val)
+ nm_ip4_config_add_domain (config, g_value_get_string (val));
+
+ val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_BANNER);
+ if (val)
+ banner = g_value_get_string (val);
+
+ print_vpn_config (config, priv->tundev, banner);
+
+ priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+ priv->ip4_config = config;
+
+ if (nm_system_vpn_device_set_from_ip4_config (priv->parent_dev,
+ priv->tundev,
+ priv->ip4_config,
+ priv->routes)) {
+ nm_info ("VPN connection '%s' (IP Config Get) complete.",
+ nm_vpn_connection_get_name (connection));
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_ACTIVATED);
+ } else {
+ nm_warning ("VPN connection '%s' did not receive valid IP config information.",
+ nm_vpn_connection_get_name (connection));
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
+ }
+}
-void nm_vpn_connection_activate (NMVPNConnection *connection)
+static gboolean
+nm_vpn_connection_ip_config_timeout (gpointer user_data)
{
- g_return_if_fail (connection != NULL);
+ NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+ priv->ipconfig_timeout = 0;
+
+ /* If the activation request's state is still IP_CONFIG_GET and we're
+ * in this timeout, cancel activation because it's taken too long.
+ */
+ if (nm_vpn_connection_get_state (connection) == NM_VPN_CONNECTION_STATE_IP_CONFIG_GET) {
+ nm_info ("VPN connection '%s' (IP Config Get) timeout exceeded.",
+ nm_vpn_connection_get_name (connection));
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
+ }
- /* Nothing done here yet */
+ return FALSE;
}
+static void
+nm_vpn_connection_connect_cb (DBusGProxy *proxy, GError *err, gpointer user_data)
+{
+ NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+ nm_info ("VPN connection '%s' (Connect) reply received.",
+ nm_vpn_connection_get_name (connection));
+
+ if (err) {
+ nm_warning ("(VPN connection '%s' could not start. dbus says: '%s'.",
+ nm_vpn_connection_get_name (connection), err->message);
+ g_error_free (err);
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
+ } else {
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_IP_CONFIG_GET);
+
+ /* 40 second timeout waiting for IP config signal from VPN service */
+ priv->ipconfig_timeout = g_timeout_add (40000, nm_vpn_connection_ip_config_timeout, connection);
+ }
+}
-gboolean
-nm_vpn_connection_set_config (NMVPNConnection *connection,
- const char *vpn_iface,
- NMDevice *dev,
- NMIP4Config *ip4_config)
+void
+nm_vpn_connection_activate (NMVPNConnection *connection)
{
- gboolean success = FALSE;
- int num_routes = -1;
- char ** routes;
- DBusConnection *dbus_connection;
- NMDBusManager * dbus_mgr = NULL;
+ NMVPNConnectionPrivate *priv;
+ NMDBusManager *dbus_mgr;
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (dev != NULL, FALSE);
- g_return_val_if_fail (ip4_config != NULL, FALSE);
+ g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
+ g_return_if_fail (nm_vpn_connection_get_state (connection) == NM_VPN_CONNECTION_STATE_PREPARE);
+ priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
dbus_mgr = nm_dbus_manager_get ();
- dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
- if (!dbus_connection) {
- nm_warning ("couldn't get dbus connection.");
- goto out;
- }
- /* IPsec VPNs will not have tunnel device */
- if (vpn_iface != NULL && strlen (vpn_iface))
- nm_vpn_connection_set_vpn_iface (connection, vpn_iface);
- nm_vpn_connection_set_parent_device (connection, dev);
- nm_vpn_connection_set_ip4_config (connection, ip4_config);
-
- routes = nm_dbus_vpn_get_routes (dbus_connection, connection, &num_routes);
- nm_system_vpn_device_set_from_ip4_config (connection->named_manager,
- connection->parent_dev,
- connection->vpn_iface,
- connection->ip4_config,
- routes,
- num_routes);
- g_strfreev(routes);
- success = TRUE;
-
-out:
- return success;
+ priv->proxy = dbus_g_proxy_new_for_name (nm_dbus_manager_get_connection (dbus_mgr),
+ priv->dbus_service,
+ NM_VPN_DBUS_PLUGIN_PATH,
+ NM_VPN_DBUS_PLUGIN_INTERFACE);
+ g_object_unref (dbus_mgr);
+
+ /* StateChanges signal */
+ dbus_g_proxy_add_signal (priv->proxy, "StateChanged", G_TYPE_UINT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "StateChanged",
+ G_CALLBACK (plugin_state_changed),
+ connection, NULL);
+
+ /* Ip4Config signal */
+ dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, G_TYPE_VALUE, G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (priv->proxy, "Ip4Config",
+ dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
+ G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal (priv->proxy, "Ip4Config",
+ G_CALLBACK (nm_vpn_connection_ip4_config_get),
+ connection, NULL);
+
+ org_freedesktop_NetworkManager_VPN_Plugin_connect_async (priv->proxy,
+ priv->properties,
+ priv->routes,
+ nm_vpn_connection_connect_cb,
+ connection);
+
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_CONNECT);
}
-
-void nm_vpn_connection_deactivate (NMVPNConnection *connection)
+const char *
+nm_vpn_connection_get_object_path (NMVPNConnection *connection)
{
- g_return_if_fail (connection != NULL);
+ g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
- if (connection->vpn_iface)
- {
- nm_system_device_set_up_down_with_iface (connection->vpn_iface, FALSE);
- nm_system_device_flush_routes_with_iface (connection->vpn_iface);
- nm_system_device_flush_addresses_with_iface (connection->vpn_iface);
- }
-
- if (connection->ip4_config)
- {
- /* Remove attributes of the VPN's IP4 Config */
- nm_system_vpn_device_unset_from_ip4_config (connection->named_manager, connection->parent_dev,
- connection->vpn_iface, connection->ip4_config);
+ return NM_VPN_CONNECTION_GET_PRIVATE (connection)->object_path;
+}
- /* Reset routes, nameservers, and domains of the currently active device */
- nm_system_device_set_from_ip4_config (connection->parent_dev);
- }
+const char *
+nm_vpn_connection_get_name (NMVPNConnection *connection)
+{
+ g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
- nm_vpn_connection_set_ip4_config (connection, NULL);
- nm_vpn_connection_set_vpn_iface (connection, NULL);
- nm_vpn_connection_set_parent_device (connection, NULL);
+ return NM_VPN_CONNECTION_GET_PRIVATE (connection)->name;
}
+NMVPNConnectionState
+nm_vpn_connection_get_state (NMVPNConnection *connection)
+{
+ g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NM_VPN_CONNECTION_STATE_UNKNOWN);
+
+ return NM_VPN_CONNECTION_GET_PRIVATE (connection)->state;
+}
-const char *nm_vpn_connection_get_name (NMVPNConnection *connection)
+void
+nm_vpn_connection_fail (NMVPNConnection *connection)
{
- g_return_val_if_fail (connection != NULL, NULL);
+ g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
- return connection->name;
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
}
-const char *nm_vpn_connection_get_user_name (NMVPNConnection *connection)
+void
+nm_vpn_connection_disconnect (NMVPNConnection *connection)
{
- g_return_val_if_fail (connection != NULL, NULL);
+ g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
- return connection->user_name;
+ nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_DISCONNECTED);
}
-const char *nm_vpn_connection_get_service_name (NMVPNConnection *connection)
+static gboolean
+impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err)
{
- g_return_val_if_fail (connection != NULL, NULL);
+ nm_vpn_connection_disconnect (connection);
- return connection->service_name;
+ return TRUE;
}
+/******************************************************************************/
-static void nm_vpn_connection_set_vpn_iface (NMVPNConnection *con, const char *vpn_iface)
+static void
+connection_state_changed (NMVPNConnection *connection, NMVPNConnectionState state)
{
- g_return_if_fail (con != NULL);
-
- if (con->vpn_iface)
- {
- g_free (con->vpn_iface);
- con->vpn_iface = NULL;
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+
+ switch (state) {
+ case NM_VPN_CONNECTION_STATE_DISCONNECTED:
+ case NM_VPN_CONNECTION_STATE_FAILED:
+ if (priv->proxy) {
+ GError *err = NULL;
+
+ org_freedesktop_NetworkManager_VPN_Plugin_disconnect (priv->proxy, &err);
+ if (err) {
+ nm_warning ("%s", err->message);
+ g_error_free (err);
+ }
+
+ g_object_unref (priv->proxy);
+ priv->proxy = NULL;
+ }
+
+ if (priv->tundev) {
+ nm_system_device_set_up_down_with_iface (priv->tundev, FALSE);
+ nm_system_device_flush_routes_with_iface (priv->tundev);
+ nm_system_device_flush_addresses_with_iface (priv->tundev);
+ }
+
+ if (priv->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_system_device_set_from_ip4_config (priv->parent_dev);
+ }
+
+ break;
+ default:
+ break;
}
-
- if (vpn_iface)
- con->vpn_iface = g_strdup (vpn_iface);
}
-static void nm_vpn_connection_set_ip4_config (NMVPNConnection *con, NMIP4Config *ip4_config)
+static void
+nm_vpn_connection_init (NMVPNConnection *connection)
{
- g_return_if_fail (con != NULL);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
+ NMDBusManager *dbus_mgr;
+ static guint32 counter = 0;
- if (con->ip4_config)
- {
- g_object_unref (con->ip4_config);
- con->ip4_config = NULL;
- }
+ priv->state = NM_VPN_CONNECTION_STATE_PREPARE;
+ priv->object_path = g_strdup_printf (NM_DBUS_PATH_VPN_CONNECTION "/%d", counter++);
- if (ip4_config)
- con->ip4_config = g_object_ref (ip4_config);
+ dbus_mgr = nm_dbus_manager_get ();
+ dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
+ priv->object_path,
+ G_OBJECT (connection));
+ g_object_unref (dbus_mgr);
}
-static void nm_vpn_connection_set_parent_device (NMVPNConnection *con, NMDevice *parent_dev)
+static void
+finalize (GObject *object)
{
- g_return_if_fail (con != NULL);
+ NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
- if (con->parent_dev)
- {
- g_object_unref (G_OBJECT (con->parent_dev));
- con->parent_dev = NULL;
+ if (priv->parent_dev) {
+ if (priv->device_monitor)
+ g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor);
+
+ g_object_unref (priv->parent_dev);
}
- if (parent_dev)
- {
- g_object_ref (G_OBJECT (parent_dev));
- con->parent_dev = parent_dev;
+ g_free (priv->tundev);
+
+ if (priv->ip4_config)
+ g_object_unref (priv->ip4_config);
+
+ if (priv->ipconfig_timeout)
+ g_source_remove (priv->ipconfig_timeout);
+
+ if (priv->proxy)
+ g_object_unref (priv->proxy);
+
+ g_free (priv->name);
+ g_free (priv->dbus_service);
+ g_hash_table_unref (priv->properties);
+ g_strfreev (priv->routes);
+ g_free (priv->object_path);
+
+ G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object);
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ switch (prop_id) {
+ case PROP_NAME:
+ g_value_set_string (value, nm_vpn_connection_get_name (NM_VPN_CONNECTION (object)));
+ break;
+ case PROP_STATE:
+ g_value_set_uint (value, nm_vpn_connection_get_state (NM_VPN_CONNECTION (object)));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
}
+
+static void
+nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
+
+ g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
+
+ /* virtual methods */
+ connection_class->state_changed = connection_state_changed;
+ object_class->get_property = get_property;
+ 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));
+
+ g_object_class_install_property
+ (object_class, PROP_STATE,
+ g_param_spec_uint (NM_VPN_CONNECTION_STATE,
+ "State",
+ "Current state",
+ NM_VPN_CONNECTION_STATE_UNKNOWN,
+ NM_VPN_CONNECTION_STATE_DISCONNECTED,
+ NM_VPN_CONNECTION_STATE_UNKNOWN,
+ G_PARAM_READABLE));
+
+ /* signals */
+ signals[STATE_CHANGED] =
+ g_signal_new ("state-changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (NMVPNConnectionClass, state_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__UINT,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (connection_class),
+ &dbus_glib_nm_vpn_connection_object_info);
+}
-/* nm-vpn-connection.h - handle a single VPN connection within NetworkManager's framework
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+/* NetworkManager -- Network link manager
*
- * Copyright (C) 2005 Dan Williams
+ * 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, or (at your option)
- * any later version.
+ * 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
*
* 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.
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * (C) Copyright 2005 Red Hat, Inc.
*/
+
#ifndef NM_VPN_CONNECTION_H
#define NM_VPN_CONNECTION_H
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include "NetworkManagerVPN.h"
#include "nm-device.h"
-#include "nm-named-manager.h"
-typedef struct NMVPNConnection NMVPNConnection;
+#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_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_CONNECTION, NMVPNConnectionClass))
+#define NM_IS_VPN_CONNECTION(obj) (G_TYPE_CHECK_INSTANCE_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_NAME "name"
+#define NM_VPN_CONNECTION_STATE "state"
+
+typedef struct {
+ GObject parent;
+} NMVPNConnection;
+
+typedef struct {
+ GObjectClass parent;
+ /* Signals */
+ void (*state_changed) (NMVPNConnection *connection, NMVPNConnectionState state);
+} NMVPNConnectionClass;
-NMVPNConnection * nm_vpn_connection_new (const char *name, const char *user_name, const char *service_name,
- NMNamedManager *named_manager);
-void nm_vpn_connection_ref (NMVPNConnection *con);
-void nm_vpn_connection_unref (NMVPNConnection *con);
+GType nm_vpn_connection_get_type (void);
-const char * nm_vpn_connection_get_name (NMVPNConnection *con);
-const char * nm_vpn_connection_get_user_name (NMVPNConnection *con);
-const char * nm_vpn_connection_get_service_name (NMVPNConnection *con);
+NMVPNConnection *nm_vpn_connection_new (const char *name,
+ const char *dbus_service,
+ NMDevice *parent_device,
+ GHashTable *properties,
+ char **routes);
-void nm_vpn_connection_activate (NMVPNConnection *con);
-void nm_vpn_connection_deactivate (NMVPNConnection *con);
+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);
+NMVPNConnectionState nm_vpn_connection_get_state (NMVPNConnection *connection);
+void nm_vpn_connection_fail (NMVPNConnection *connection);
+void nm_vpn_connection_disconnect (NMVPNConnection *connection);
-gboolean nm_vpn_connection_set_config (NMVPNConnection *con, const char *vpn_iface, NMDevice *dev, NMIP4Config *ip4_config);
-#endif /* NM_VPN_MANAGER_H */
+#endif /* NM_VPN_CONNECTION_H */
-/* nm-vpn-manager.c - handle VPN connections within NetworkManager's framework
- *
- * Copyright (C) 2005 Dan Williams
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, 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.
- */
-
-#include <glib.h>
-#include <stdio.h>
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
#include <string.h>
-#include <dbus/dbus.h>
+
#include "nm-vpn-manager.h"
-#include "nm-named-manager.h"
-#include "NetworkManager.h"
-#include "NetworkManagerMain.h"
-#include "NetworkManagerSystem.h"
-#include "nm-vpn-act-request.h"
-#include "nm-vpn-connection.h"
#include "nm-vpn-service.h"
-#include "nm-dbus-vpn.h"
-#include "nm-utils.h"
+#include "nm-vpn-connection.h"
#include "nm-dbus-manager.h"
+#include "NetworkManagerVPN.h"
+#include "nm-utils.h"
-#define VPN_SERVICE_FILE_PATH SYSCONFDIR"/NetworkManager/VPN"
-
-struct NMVPNManager
-{
- NMManager * nm_manager;
- GHashTable * service_table;
- GSList * connections;
-
- NMVPNActRequest * act_req;
- gulong device_signal_id;
-};
-
-static void load_services (NMVPNManager *manager, GHashTable *table);
-
-static void
-nm_name_owner_changed_handler (NMDBusManager *mgr,
- const char *name,
- const char *old,
- const char *new,
- gpointer user_data)
-{
- NMVPNManager *vpn_manager = (NMVPNManager *) user_data;
- gboolean old_owner_good = (old && (strlen (old) > 0));
- gboolean new_owner_good = (new && (strlen (new) > 0));
-
- if (strcmp (name, NMI_DBUS_SERVICE) == 0 && (!old_owner_good && new_owner_good))
- /* NMI appeared, update stuff */
- nm_dbus_vpn_schedule_vpn_connections_update (vpn_manager);
-}
-
-static gboolean
-nm_dbus_nmi_vpn_signal_handler (DBusConnection *connection,
- DBusMessage *message,
- gpointer user_data)
-{
- NMVPNManager *manager = (NMVPNManager *) user_data;
- const char * object_path;
- gboolean handled = FALSE;
-
- if (!(object_path = dbus_message_get_path (message)))
- return FALSE;
-
- if (strcmp (object_path, NMI_DBUS_PATH) != 0)
- return FALSE;
-
- if (dbus_message_is_signal (message, NMI_DBUS_INTERFACE, "VPNConnectionUpdate")) {
- char *name = NULL;
-
- if (dbus_message_get_args (message,
- NULL,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_INVALID)) {
- nm_debug ("NetworkManagerInfo triggered update of VPN connection '%s'", name);
- nm_dbus_vpn_update_one_vpn_connection (connection, manager, name);
- handled = TRUE;
- }
- }
-
- return handled;
-}
-
-/*
- * nm_vpn_manager_new
- *
- * Create a new VPN manager instance.
- *
- */
-NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager)
-{
- NMVPNManager * manager;
- NMDBusManager * dbus_mgr;
-
- g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
-
- manager = g_slice_new0 (NMVPNManager);
- manager->nm_manager = g_object_ref (nm_manager);
-
- manager->service_table = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- NULL,
- (GDestroyNotify) nm_vpn_service_unref);
- load_services (manager, manager->service_table);
-
- if (!nm_dbus_vpn_methods_setup (manager)) {
- nm_vpn_manager_dispose (manager);
- return NULL;
- }
+static gboolean impl_vpn_manager_connect (NMVPNManager *manager,
+ const char *type,
+ const char *name,
+ GHashTable *properties,
+ const char *device_path,
+ char **routes,
+ char **connection,
+ GError **err);
- dbus_mgr = nm_dbus_manager_get ();
+static gboolean impl_vpn_manager_get_connections (NMVPNManager *manager,
+ GPtrArray **connections,
+ GError **err);
- g_signal_connect (dbus_mgr,
- "name-owner-changed",
- G_CALLBACK (nm_name_owner_changed_handler),
- manager);
+#include "nm-vpn-manager-glue.h"
- nm_dbus_manager_register_signal_handler (dbus_mgr,
- NMI_DBUS_INTERFACE,
- NULL,
- nm_dbus_nmi_vpn_signal_handler,
- manager);
+G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT)
- if (nm_dbus_manager_name_has_owner (dbus_mgr, NMI_DBUS_SERVICE))
- nm_dbus_vpn_schedule_vpn_connections_update (manager);
+typedef struct {
+ NMManager *nm_mgr;
+ NMDBusManager *dbus_mgr;
+ GSList *services;
+} NMVPNManagerPrivate;
- g_object_unref (dbus_mgr);
+#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate))
- return manager;
-}
-
-
-/*
- * nm_vpn_manager_dispose
- *
- * Release the VPN manager and all its data.
- *
- */
-void nm_vpn_manager_dispose (NMVPNManager *manager)
+static NMVPNService *
+nm_vpn_manager_get_service (NMVPNManager *manager, const char *service_name)
{
- g_return_if_fail (manager != NULL);
-
- if (manager->act_req)
- nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (manager->act_req));
-
- g_slist_foreach (manager->connections, (GFunc) nm_vpn_connection_unref, NULL);
- g_slist_free (manager->connections);
+ GSList *iter;
- g_hash_table_destroy (manager->service_table);
-
- g_object_unref (manager->nm_manager);
-
- memset (manager, 0, sizeof (NMVPNManager));
- g_slice_free (NMVPNManager, manager);
-}
+ for (iter = NM_VPN_MANAGER_GET_PRIVATE (manager)->services; iter; iter = iter->next) {
+ NMVPNService *service = NM_VPN_SERVICE (iter->data);
-
-/*
- * nm_vpn_manager_find_connection_by_name
- *
- * Return the NMVPNConnection object associated with a particular name.
- *
- */
-NMVPNConnection *nm_vpn_manager_find_connection_by_name (NMVPNManager *manager, const char *con_name)
-{
- NMVPNConnection *con = NULL;
- GSList *elt;
-
- g_return_val_if_fail (manager != NULL, NULL);
- g_return_val_if_fail (con_name != NULL, NULL);
-
- for (elt = manager->connections; elt; elt = g_slist_next (elt))
- {
- if ((con = (NMVPNConnection *)(elt->data)))
- {
- const char *search_name = nm_vpn_connection_get_name (con);
- if (search_name && (strcmp (con_name, search_name) == 0))
- break;
- }
- con = NULL;
+ if (!strcmp (service_name, nm_vpn_service_get_name (service)))
+ return service;
}
- return con;
+ return NULL;
}
-
-NMVPNService *nm_vpn_manager_find_service_by_name (NMVPNManager *manager, const char *service_name)
+static void
+remove_service (gpointer data, GObject *service)
{
- g_return_val_if_fail (manager != NULL, NULL);
- g_return_val_if_fail (service_name != NULL, NULL);
+ NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (data);
- return (NMVPNService *) g_hash_table_lookup (manager->service_table, service_name);
+ priv->services = g_slist_remove (priv->services, service);
}
-
-/*
- * nm_vpn_manager_vpn_connection_list_copy
- *
- * Make a shallow copy of the VPN connection list, should
- * only be used by nm-dbus-vpn.c
- *
- */
-GSList *nm_vpn_manager_vpn_connection_list_copy (NMVPNManager *manager)
+static void
+nm_vpn_manager_add_service (NMVPNManager *manager, NMVPNService *service)
{
- GSList * list;
- GSList * elt;
-
- g_return_val_if_fail (manager != NULL, NULL);
+ NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
- list = g_slist_copy (manager->connections);
- for (elt = list; elt; elt = g_slist_next (elt))
- nm_vpn_connection_ref (elt->data);
-
- return list;
+ priv->services = g_slist_prepend (priv->services, service);
+ g_object_weak_ref (G_OBJECT (service), remove_service, manager);
}
-
-/*
- * nm_vpn_manager_add_connection
- *
- * Add a new VPN connection if none already exits, otherwise update the existing one.
- *
- */
NMVPNConnection *
-nm_vpn_manager_add_connection (NMVPNManager *manager,
- const char *name,
- const char *service_name,
- const char *user_name)
+nm_vpn_manager_connect (NMVPNManager *manager,
+ const char *type,
+ const char *name,
+ NMDevice *device,
+ GHashTable *properties,
+ char **routes)
{
- NMVPNConnection * connection = NULL;
- NMVPNService * service;
- DBusConnection * dbus_connection;
- NMDBusManager * dbus_mgr = NULL;
- NMNamedManager * named_mgr = NULL;
- GSList * elt;
-
- g_return_val_if_fail (manager != NULL, NULL);
+ NMVPNService *service;
+
+ g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
+ g_return_val_if_fail (type != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
- g_return_val_if_fail (service_name != NULL, NULL);
- g_return_val_if_fail (user_name != NULL, NULL);
+ g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (properties != NULL, NULL);
- /* Verify that the service name we are adding is in our allowed list */
- if (!(service = nm_vpn_manager_find_service_by_name (manager, service_name)))
+ if (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED)
return NULL;
- dbus_mgr = nm_dbus_manager_get ();
- dbus_connection = nm_dbus_manager_get_dbus_connection (dbus_mgr);
- if (!dbus_connection) {
- nm_warning ("couldn't get dbus connection.");
- goto out;
+ service = nm_vpn_manager_get_service (manager, type);
+ if (!service) {
+ service = nm_vpn_service_new (type);
+ if (service)
+ nm_vpn_manager_add_service (manager, service);
}
- named_mgr = nm_named_manager_get ();
- connection = nm_vpn_connection_new (name,
- user_name,
- service_name,
- named_mgr);
- g_object_unref (named_mgr);
- if (!connection) {
- nm_warning ("couldn't create VPN connecton for '%s (%s).",
- name,
- service_name);
- goto out;
- }
-
- /* Remove the existing connection if found */
- for (elt = manager->connections; elt; elt = g_slist_next (elt)) {
- NMVPNConnection *con = (NMVPNConnection *)(elt->data);
-
-
- if (!con || !nm_vpn_connection_get_name (con))
- continue;
- if (strcmp (nm_vpn_connection_get_name (con), name) != 0)
- continue;
+ if (service)
+ return nm_vpn_service_activate (service, name, device, properties, routes);
- manager->connections = g_slist_remove_link (manager->connections, elt);
- nm_vpn_connection_unref (con);
- g_slist_free (elt);
- }
-
- /* Add in the updated connection */
- manager->connections = g_slist_append (manager->connections, connection);
-
-out:
- g_object_unref (dbus_mgr);
- return connection;
+ return NULL;
}
-
-/*
- * nm_vpn_manager_remove_connection
- *
- * Remove a VPN connection.
- *
- */
-void nm_vpn_manager_remove_connection (NMVPNManager *manager, NMVPNConnection *vpn)
+static NMDevice *
+find_device (NMVPNManager *manager, const char *device_path)
{
- g_return_if_fail (manager != NULL);
- g_return_if_fail (vpn != NULL);
+ GSList *devices;
+ GSList *iter;
- /* If this VPN is currently active, kill it */
- if (manager->act_req && (nm_vpn_act_request_get_connection (manager->act_req) == vpn))
- {
- NMVPNService * service = nm_vpn_act_request_get_service (manager->act_req);
- NMVPNConnection * v = nm_vpn_act_request_get_connection (manager->act_req);
+ devices = nm_manager_get_devices (NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_mgr);
+ for (iter = devices; iter; iter = iter->next) {
+ NMDevice *device = NM_DEVICE (iter->data);
- nm_vpn_connection_deactivate (v);
- nm_vpn_service_stop_connection (service, manager->act_req);
-
- nm_vpn_act_request_unref (manager->act_req);
- manager->act_req = NULL;
+ if (!strcmp (device_path, nm_device_get_dbus_path (device)))
+ return device;
}
- manager->connections = g_slist_remove (manager->connections, vpn);
- nm_vpn_connection_unref (vpn);
+ return NULL;
}
+static gboolean
+impl_vpn_manager_connect (NMVPNManager *manager,
+ const char *type,
+ const char *name,
+ GHashTable *properties,
+ const char *device_path,
+ char **routes,
+ char **connection_path,
+ GError **err)
+{
+ NMDevice *device;
+ NMVPNConnection *connection;
+ GHashTable *properties_dup;
+ char **routes_dup;
+
+ device = find_device (manager, device_path);
+ if (!device)
+ return FALSE;
-/*
- * nm_vpn_manager_get_connection_names
- *
- * Return an array of strings of all the VPN Connection names
- * we know about.
- *
- */
-char **nm_vpn_manager_get_connection_names (NMVPNManager *manager)
-{
- char **names = NULL;
- GSList *elt;
- int i;
-
- g_return_val_if_fail (manager != NULL, NULL);
-
- names = g_malloc0 ((g_slist_length (manager->connections) + 1) * sizeof (char *));
- for (elt = manager->connections, i = 0; elt; elt = g_slist_next (elt), i++)
- {
- NMVPNConnection *vpn_con = (NMVPNConnection *)(elt->data);
- if (vpn_con)
- names[i] = g_strdup (nm_vpn_connection_get_name (vpn_con));
+ properties_dup = nm_utils_gvalue_hash_dup (properties);
+ routes_dup = g_strdupv (routes);
+
+ connection = nm_vpn_manager_connect (manager,
+ type, name,
+ device,
+ properties_dup,
+ routes_dup);
+ if (connection)
+ *connection_path = g_strdup (nm_vpn_connection_get_object_path (connection));
+ else {
+ g_hash_table_destroy (properties_dup);
+ g_strfreev (routes_dup);
}
- return names;
+ return *connection_path != NULL;
}
-
-/*
- * nm_vpn_manager_get_vpn_act_request
- *
- * Return the VPN activation request, if any.
- *
- */
-NMVPNActRequest *nm_vpn_manager_get_vpn_act_request (NMVPNManager *manager)
-{
- g_return_val_if_fail (manager != NULL, NULL);
-
- return manager->act_req;
-}
-
-
static void
-device_state_changed (NMDevice *device, NMDeviceState state, gpointer user_data)
+get_connections (gpointer data, gpointer user_data)
{
- NMVPNManager *manager = (NMVPNManager *) user_data;
+ NMVPNService *service = NM_VPN_SERVICE (data);
+ GSList **list = (GSList **) user_data;
- if (state == NM_DEVICE_STATE_DISCONNECTED)
- nm_vpn_manager_deactivate_vpn_connection (manager, device);
+ *list = g_slist_concat (*list, nm_vpn_service_get_connections (service));
}
-
-/*
- * nm_vpn_manager_activate_vpn_connection
- *
- * Signal the VPN service daemon to activate a particular VPN connection,
- * launching that daemon if necessary.
- *
- */
-void nm_vpn_manager_activate_vpn_connection (NMVPNManager *manager, NMVPNConnection *vpn,
- char **password_items, int password_count, char **data_items, int data_count, char **user_routes, int user_routes_count)
+GSList *
+nm_vpn_manager_get_connections (NMVPNManager *manager)
{
- NMDevice * parent_dev;
- NMVPNActRequest * req;
- NMVPNService * service;
- const char * service_name;
-
- g_return_if_fail (manager != NULL);
- g_return_if_fail (vpn != NULL);
- g_return_if_fail (password_items != NULL);
- g_return_if_fail (data_items != NULL);
-
- if (nm_vpn_manager_get_vpn_act_request (manager))
- nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (manager->act_req));
-
- service_name = nm_vpn_connection_get_service_name (vpn);
- if (!(service = nm_vpn_manager_find_service_by_name (manager, service_name)))
- return;
-
- if (!(parent_dev = nm_manager_get_active_device (manager->nm_manager)))
- {
- nm_warning ("nm_vpn_manager_activate_vpn_connection(): no currently active network device, won't activate VPN.");
- return;
- }
-
- req = nm_vpn_act_request_new (manager, service, vpn, parent_dev, password_items, password_count, data_items, data_count,
- user_routes, user_routes_count);
- manager->act_req = req;
-
- manager->device_signal_id = g_signal_connect (parent_dev, "state-changed",
- G_CALLBACK (device_state_changed),
- manager);
-
- nm_vpn_service_start_connection (service, req);
-}
-
-
-/*
- * nm_vpn_manager_deactivate_vpn_connection
- *
- * Signal the VPN service daemon to deactivate a particular VPN connection.
- *
- */
-void nm_vpn_manager_deactivate_vpn_connection (NMVPNManager *manager, NMDevice *dev)
-{
- NMVPNService * service;
- NMVPNConnection * vpn;
-
- g_return_if_fail (manager != NULL);
+ GSList *list = NULL;
- if (!manager->act_req || (dev != nm_vpn_act_request_get_parent_dev (manager->act_req)))
- return;
+ g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
- if (manager->device_signal_id) {
- g_signal_handler_disconnect (dev, manager->device_signal_id);
- manager->device_signal_id = 0;
- }
+ g_slist_foreach (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, get_connections, &list);
- if (nm_vpn_act_request_is_activating (manager->act_req)
- || nm_vpn_act_request_is_activated (manager->act_req)
- || nm_vpn_act_request_is_failed (manager->act_req))
- {
- if (nm_vpn_act_request_is_activated (manager->act_req))
- {
- vpn = nm_vpn_act_request_get_connection (manager->act_req);
- g_assert (vpn);
- nm_vpn_connection_deactivate (vpn);
- }
-
- service = nm_vpn_act_request_get_service (manager->act_req);
- g_assert (service);
- nm_vpn_service_stop_connection (service, manager->act_req);
- }
-
- nm_vpn_act_request_unref (manager->act_req);
- manager->act_req = NULL;
+ return list;
}
-
-static gboolean nm_vpn_manager_vpn_activation_failed (gpointer user_data)
+static gboolean
+impl_vpn_manager_get_connections (NMVPNManager *manager, GPtrArray **connections, GError **err)
{
- NMVPNActRequest * req = (NMVPNActRequest *) user_data;
- NMVPNManager * manager;
-
- g_assert (req);
+ GSList *list;
+ GSList *iter;
- manager = nm_vpn_act_request_get_manager (req);
- g_assert (manager);
+ list = nm_vpn_manager_get_connections (manager);
+ *connections = g_ptr_array_sized_new (g_slist_length (list));
- if (manager->act_req == req)
- nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (req));
-
- return FALSE;
-}
+ 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))));
+ g_slist_free (list);
-void nm_vpn_manager_schedule_vpn_activation_failed (NMVPNManager *manager, NMVPNActRequest *req)
-{
- g_return_if_fail (manager != NULL);
- g_return_if_fail (req != NULL);
-
- g_idle_add (nm_vpn_manager_vpn_activation_failed, req);
+ return TRUE;
}
-
-static gboolean nm_vpn_manager_vpn_connection_died (gpointer user_data)
+NMVPNManager *
+nm_vpn_manager_new (NMManager *nm_manager)
{
- NMVPNActRequest * req = (NMVPNActRequest *) user_data;
- NMVPNManager * manager;
-
- g_assert (req);
+ NMVPNManager *manager;
- manager = nm_vpn_act_request_get_manager (req);
- g_assert (manager);
+ g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
- if (manager->act_req == req)
- nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (req));
+ manager = (NMVPNManager *) g_object_new (NM_TYPE_VPN_MANAGER, NULL);
+ if (manager)
+ NM_VPN_MANAGER_GET_PRIVATE (manager)->nm_mgr = g_object_ref (nm_manager);
- return FALSE;
+ return manager;
}
+/******************************************************************************/
-void nm_vpn_manager_schedule_vpn_connection_died (NMVPNManager *manager, NMVPNActRequest *req)
+static void
+nm_vpn_manager_init (NMVPNManager *manager)
{
- g_return_if_fail (manager != NULL);
- g_return_if_fail (req != NULL);
+ NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
- g_idle_add (nm_vpn_manager_vpn_connection_died, req);
+ 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));
}
-
-/*********************************************************************/
-
-#define NAME_TAG "name="
-#define SERVICE_TAG "service="
-#define PROGRAM_TAG "program="
-
-static gboolean
-set_service_from_contents (char ** lines, NMVPNService * service, char **err)
+static void
+finalize (GObject *object)
{
- int i;
- guint32 len = g_strv_length (lines);
- gboolean have_name = FALSE;
- gboolean have_service = FALSE;
- gboolean have_program = FALSE;
-
- g_return_val_if_fail (err != NULL, FALSE);
- g_return_val_if_fail (*err == NULL, FALSE);
-
- for (i = 0; i < len; i++) {
- char * line = lines[i];
-
- /* Blank lines, or comment lines */
- if (!line || !strlen (line) || (line[0] == '#'))
- continue;
-
- if ((strncmp (line, NAME_TAG, strlen (NAME_TAG)) == 0)) {
- const char * name = line+strlen (NAME_TAG);
-
- if (have_name) {
- *err = "already parsed 'name' tag";
- return FALSE;
- }
-
- nm_vpn_service_set_name (service, name);
- have_name = TRUE;
- continue;
- }
-
- if ((strncmp (line, SERVICE_TAG, strlen (SERVICE_TAG)) == 0)) {
- const char * serv_name = line+strlen (SERVICE_TAG);
-
- /* Minimal service name sanity checking */
- if (have_service) {
- *err = "already parsed 'service' tag";
- return FALSE;
- }
-
- if ( !strcmp (serv_name, NM_DBUS_SERVICE)
- || !strcmp (serv_name, NMI_DBUS_SERVICE)) {
- *err = "service name is invalid";
- return FALSE;
- }
-
- nm_vpn_service_set_service_name (service, serv_name);
- have_service = TRUE;
- continue;
- }
-
- if ((strncmp (line, PROGRAM_TAG, strlen (PROGRAM_TAG)) == 0)) {
- const char * program = line+strlen (PROGRAM_TAG);
-
- if (have_program) {
- *err = "already parsed 'program' tag";
- return FALSE;
- }
-
- if (!g_path_is_absolute (program)) {
- *err = "path to program was not absolute";
- return FALSE;
- }
-
- if (!g_file_test (program, G_FILE_TEST_EXISTS
- | G_FILE_TEST_IS_EXECUTABLE
- | G_FILE_TEST_IS_REGULAR )) {
- *err = "program does not exist, or is not executable";
- return FALSE;
- }
-
- nm_vpn_service_set_program (service, (const char *)(line+strlen (PROGRAM_TAG)));
- have_program = TRUE;
- continue;
- }
- }
+ NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
- if (!have_name || !have_service || !have_program) {
- *err = "didn't contain all required tags";
- return FALSE;
- }
+ g_slist_foreach (priv->services, (GFunc) g_object_unref, NULL);
+ g_object_unref (priv->dbus_mgr);
+ g_object_unref (priv->nm_mgr);
- return TRUE;
+ G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object);
}
-
-struct dup_search_data {
- const char * name;
- const char * serv_name;
- gboolean found;
-};
-
static void
-find_dup_name (gpointer key, gpointer value, gpointer user_data)
+nm_vpn_manager_class_init (NMVPNManagerClass *manager_class)
{
- struct dup_search_data * data = (struct dup_search_data *) user_data;
- NMVPNService * service = (NMVPNService *) value;
- const char * serv_name = nm_vpn_service_get_service_name (service);
- const char * name = nm_vpn_service_get_name (service);
-
- /* already found a dupe, do nothing */
- if (data->found)
- return;
-
- if (strcmp (serv_name, data->serv_name) == 0)
- data->found = TRUE;
- else if (strcmp (name, data->name) == 0)
- data->found = TRUE;
-}
+ GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
+ g_type_class_add_private (manager_class, sizeof (NMVPNManagerPrivate));
-static void
-load_services (NMVPNManager *manager, GHashTable *table)
-{
- GDir * vpn_dir;
- const char *file_name;
-
- g_return_if_fail (manager != NULL);
- g_return_if_fail (table != NULL);
-
- /* Load allowed service names */
- if (!(vpn_dir = g_dir_open (VPN_SERVICE_FILE_PATH, 0, NULL)))
- return;
-
- while ((file_name = g_dir_read_name (vpn_dir))) {
- char * file_path;
- char * contents;
- char ** lines;
- NMVPNService * service;
- char * err = NULL;
- gboolean success;
-
- file_path = g_strdup_printf (VPN_SERVICE_FILE_PATH"/%s", file_name);
-
- /* Check for the .name extension */
- if (strcmp (file_name + strlen (file_name) - 5, ".name") != 0) {
- nm_warning ("Error loading VPN service file '%s': doesn't "
- "end with .name", file_path);
- goto free_file_path;
- }
-
- if (!g_file_get_contents (file_path, &contents, NULL, NULL))
- goto free_file_path;
-
- lines = g_strsplit (contents, "\n", 0);
- g_free (contents);
- if (!lines)
- goto free_file_path;
-
- service = nm_vpn_service_new (manager);
- success = set_service_from_contents (lines, service, &err);
- g_strfreev (lines);
-
- if (!success) {
- nm_warning ("Error loading VPN service file '%s': %s.",
- file_path, err);
- nm_vpn_service_unref (service);
- } else {
- const char * serv_name = nm_vpn_service_get_service_name (service);
- const char * name = nm_vpn_service_get_name (service);
- struct dup_search_data dup_data = { name, serv_name, FALSE };
-
- /* Check for duplicates */
- g_hash_table_foreach (table, find_dup_name, &dup_data);
- if (dup_data.found) {
- nm_warning ("Ignoring duplicate VPN service '%s' (%s) from %s.",
- name, serv_name, file_path);
- } else {
- /* All good, add it */
- nm_info ("New VPN service '%s' (%s).", name, serv_name);
- g_hash_table_insert (table, (char *) serv_name, service);
- }
- }
-
- free_file_path:
- g_free (file_path);
- }
+ /* virtual methods */
+ object_class->finalize = finalize;
- g_dir_close (vpn_dir);
+ dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class),
+ &dbus_glib_nm_vpn_manager_object_info);
}
-
-/* nm-vpn-manager.h - handle VPN connections within NetworkManager's framework
- *
- * Copyright (C) 2005 Dan Williams
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, 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.
- */
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
#ifndef NM_VPN_MANAGER_H
#define NM_VPN_MANAGER_H
-#include <dbus/dbus.h>
-#include "nm-manager.h"
-#include "NetworkManagerMain.h"
+#include <glib/gtypes.h>
+#include <glib-object.h>
#include "nm-vpn-connection.h"
-#include "nm-vpn-service.h"
+#include "nm-manager.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))
+#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 {
+ GObject parent;
+} NMVPNManager;
-NMVPNManager * nm_vpn_manager_new (NMManager *nm_manager);
-NMVPNConnection * nm_vpn_manager_add_connection (NMVPNManager *manager, const char *name, const char *service_name, const char *user_name);
-void nm_vpn_manager_remove_connection (NMVPNManager *manager, NMVPNConnection *vpn);
-char ** nm_vpn_manager_get_connection_names (NMVPNManager *manager);
-void nm_vpn_manager_dispose (NMVPNManager *manager);
+typedef struct {
+ GObjectClass parent;
+} NMVPNManagerClass;
-NMVPNActRequest * nm_vpn_manager_get_vpn_act_request (NMVPNManager *manager);
+GType nm_vpn_manager_get_type (void);
-GSList * nm_vpn_manager_vpn_connection_list_copy (NMVPNManager *manager);
+NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager);
-void nm_vpn_manager_activate_vpn_connection (NMVPNManager *manager, NMVPNConnection *vpn, char **password_items,
- int password_count, char **data_items, int data_count,
- char **user_routes, int user_routes_count );
-void nm_vpn_manager_deactivate_vpn_connection (NMVPNManager *manager, NMDevice *dev);
+NMVPNConnection *nm_vpn_manager_connect (NMVPNManager *manager,
+ const char *type,
+ const char *name,
+ NMDevice *device,
+ GHashTable *properties,
+ char **routes);
-NMVPNConnection * nm_vpn_manager_find_connection_by_name (NMVPNManager *manager, const char *con_name);
-NMVPNService * nm_vpn_manager_find_service_by_name (NMVPNManager *manager, const char *service_name);
+GSList *nm_vpn_manager_get_connections (NMVPNManager *manager);
-void nm_vpn_manager_schedule_vpn_activation_failed(NMVPNManager *manager, NMVPNActRequest *req);
-void nm_vpn_manager_schedule_vpn_connection_died (NMVPNManager *manager, NMVPNActRequest *req);
-#endif /* NM_VPN_MANAGER_H */
+#endif /* NM_VPN_VPN_MANAGER_H */
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
+
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
#include <glib.h>
#include <string.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
#include <dbus/dbus.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
-#include "nm-dbus-vpn.h"
#include "nm-vpn-service.h"
-#include "nm-vpn-act-request.h"
-#include "nm-utils.h"
-#include "dbus-dict-helpers.h"
#include "nm-dbus-manager.h"
+#include "nm-utils.h"
-/* define this for getting VPN debug messages */
-#undef NM_DEBUG_VPN_CONFIG
-
-struct NMVPNService
-{
- int refcount;
- NMVPNManager * manager;
- GPid pid;
- guint32 sig_handler_id;
- gulong watch_id;
- gulong dbus_con_watch_id;
- NMDBusManager * dbus_mgr;
-
- char * name;
- char * service;
- char * program;
- NMVPNServiceState state;
-};
-
-
-static void nm_vpn_service_add_watch (NMVPNService *service);
-static void nm_vpn_service_remove_watch (NMVPNService *service);
-static void nm_vpn_service_stop_connection_internal (NMVPNService *service);
-
-static void nm_vpn_service_schedule_stage1_daemon_exec (NMVPNService *service, NMVPNActRequest *req);
-static void nm_vpn_service_schedule_stage3_connect (NMVPNService *service, NMVPNActRequest *req);
-static void nm_vpn_service_schedule_stage2_daemon_wait (NMVPNService *service, NMVPNActRequest *req);
-static void nm_vpn_service_schedule_stage4_ip_config_get_timeout (NMVPNService *service, NMVPNActRequest *req);
-static void nm_vpn_service_cancel_callback (NMVPNService *service, NMVPNActRequest *req);
-
-static gboolean nm_vpn_service_process_signal (DBusConnection *connection,
- DBusMessage *message,
- gpointer user_data);
-
-static void nm_vpn_service_name_owner_changed (NMDBusManager *mgr,
- const char *name,
- const char *old,
- const char *new,
- gpointer user_data);
-
-static void nm_vpn_service_dbus_connection_changed (NMDBusManager *mgr,
- DBusConnection *connection,
- gpointer user_data);
-
-#ifdef NM_DEBUG_VPN_CONFIG
-static void print_vpn_config (NMIP4Config *config,
- const char *tundev,
- const char *login_banner);
-#endif
-
-
-/*
- * nm_vpn_service_new
- *
- * Create a new VPNService object
- *
- */
-NMVPNService *nm_vpn_service_new (NMVPNManager *manager)
-{
- NMVPNService *service = g_malloc0 (sizeof (NMVPNService));
-
- service->refcount = 1;
- service->state = NM_VPN_SERVICE_STATE_SHUTDOWN;
- service->manager = manager;
- service->dbus_mgr = nm_dbus_manager_get ();
-
- return service;
-}
-
-void nm_vpn_service_ref (NMVPNService *service)
-{
- g_return_if_fail (service != NULL);
-
- service->refcount++;
-}
-
-
-void nm_vpn_service_unref (NMVPNService *service)
-{
- g_return_if_fail (service != NULL);
-
- service->refcount--;
- if (service->refcount <= 0)
- {
- nm_vpn_service_remove_watch (service);
- g_free (service->name);
- g_free (service->service);
- g_free (service->program);
- g_object_unref (service->dbus_mgr);
- memset (service, 0, sizeof (NMVPNService));
- g_free (service);
- }
-}
-
-
-const char *nm_vpn_service_get_name (NMVPNService *service)
-{
- g_return_val_if_fail (service != NULL, NULL);
-
- return service->name;
-}
-
-
-void nm_vpn_service_set_name (NMVPNService *service, const char *name)
-{
- g_return_if_fail (service != NULL);
-
- if (service->name)
- g_free (service->name);
- service->name = g_strdup (name);
-}
+G_DEFINE_TYPE (NMVPNService, nm_vpn_service, G_TYPE_OBJECT)
+typedef struct {
+ NMDBusManager *dbus_mgr;
+ char *name;
+ char *dbus_service;
+ char *program;
-const char *nm_vpn_service_get_service_name (NMVPNService *service)
-{
- g_return_val_if_fail (service != NULL, NULL);
+ GPid pid;
+ GSList *connections;
+ guint service_start_timeout;
+ gulong name_owner_id;
+} NMVPNServicePrivate;
- return service->service;
-}
+#define NM_VPN_SERVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_SERVICE, NMVPNServicePrivate))
+#define VPN_CONNECTION_GROUP "VPN Connection"
-void nm_vpn_service_set_service_name (NMVPNService *service, const char *name)
+static GKeyFile *
+find_service_file (const char *name)
{
- g_return_if_fail (service != NULL);
+ GDir *dir;
+ const char *fn;
+ GKeyFile *key_file = NULL;
- if (service->service)
- g_free (service->service);
- service->service = g_strdup (name);
-
- /* If the VPN daemon is currently running, tell it to stop */
- if (nm_dbus_manager_name_has_owner (service->dbus_mgr, service->service))
- nm_vpn_service_stop_connection_internal (service);
-}
-
-
-const char *nm_vpn_service_get_program (NMVPNService *service)
-{
- g_return_val_if_fail (service != NULL, NULL);
+ dir = g_dir_open (VPN_NAME_FILES_DIR, 0, NULL);
+ if (!dir)
+ return NULL;
- return service->program;
-}
+ while ((fn = g_dir_read_name (dir))) {
+ char *path;
+ gboolean found = FALSE;
+ key_file = g_key_file_new ();
+ path = g_build_filename (VPN_NAME_FILES_DIR, fn, NULL);
-void nm_vpn_service_set_program (NMVPNService *service, const char *program)
-{
- g_return_if_fail (service != NULL);
+ if (g_key_file_load_from_file (key_file, path, G_KEY_FILE_NONE, NULL)) {
+ gchar *val;
- if (service->program)
- g_free (service->program);
- service->program = g_strdup (program);
-}
+ val = g_key_file_get_string (key_file, VPN_CONNECTION_GROUP, "service", NULL);
+ if (val) {
+ if (!strcmp (val, name))
+ found = TRUE;
+ g_free (val);
+ }
+ }
+ g_free (path);
-NMVPNServiceState
-nm_vpn_service_get_state (NMVPNService *service)
-{
- g_return_val_if_fail (service != NULL, NM_VPN_SERVICE_STATE_UNKNOWN);
+ if (found)
+ break;
- return service->state;
-}
+ g_key_file_free (key_file);
+ key_file = NULL;
+ }
+ g_dir_close (dir);
-static void
-nm_vpn_service_set_state (NMVPNService *service,
- const NMVPNServiceState state)
-{
- g_return_if_fail (service != NULL);
-
- service->state = state;
+ return key_file;
}
-
-/*
- * construct_op_from_service_name
- *
- * Construct an object path from a dbus service name by replacing
- * all "." in the service with "/" and prepending a "/" to the
- * object path.
- *
- */
-static char *construct_op_from_service_name (const char *service_name)
+NMVPNService *
+nm_vpn_service_new (const char *name)
{
- char **split = NULL;
- char *temp1;
- char *temp2;
+ GKeyFile *key_file;
+ NMVPNService *service;
+ NMVPNServicePrivate *priv;
+ char *dbus_service = NULL;
+ char *program = NULL;
+ gboolean success = FALSE;
- g_return_val_if_fail (service_name != NULL, NULL);
+ g_return_val_if_fail (name != NULL, NULL);
- if (!(split = g_strsplit (service_name, ".", 0)))
+ key_file = find_service_file (name);
+ if (!key_file)
return NULL;
- temp1 = g_strjoinv ("/", split);
- g_strfreev (split);
- temp2 = g_strdup_printf ("/%s", temp1);
- g_free (temp1);
-
- return temp2;
-}
+ dbus_service = g_key_file_get_string (key_file, VPN_CONNECTION_GROUP, "service", NULL);
+ if (!dbus_service)
+ goto out;
+ program = g_key_file_get_string (key_file, VPN_CONNECTION_GROUP, "program", NULL);
+ if (!program)
+ goto out;
-/*
- * nm_vpn_service_act_request_failed
- *
- * Clean up after an activation request and tell the VPN manager that it
- * has failed.
- *
- */
-static void
-nm_vpn_service_act_request_failed (NMVPNService *service,
- NMVPNActRequest *req)
-{
- NMVPNConnection *vpn;
+ service = (NMVPNService *) g_object_new (NM_TYPE_VPN_SERVICE, NULL);
+ if (!service)
+ goto out;
- g_return_if_fail (service != NULL);
- g_return_if_fail (req != NULL);
+ priv = NM_VPN_SERVICE_GET_PRIVATE (service);
- /* Sanity checks */
- if (nm_vpn_act_request_get_service (req) != service)
- return;
+ priv->name = g_strdup (name);
+ priv->dbus_service = dbus_service;
+ priv->program = program;
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
+ success = TRUE;
- nm_vpn_service_cancel_callback (service, req);
+ out:
+ g_key_file_free (key_file);
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_FAILED);
- nm_info ("VPN Activation (%s) failed.", nm_vpn_connection_get_name (vpn));
+ if (!success) {
+ g_free (dbus_service);
+ g_free (program);
+ }
- nm_vpn_act_request_unref (req);
- nm_vpn_manager_schedule_vpn_activation_failed (service->manager, req);
+ return service;
}
-
-static void
-nm_vpn_service_activation_success (NMVPNService *service,
- NMVPNActRequest *req)
+const char *
+nm_vpn_service_get_name (NMVPNService *service)
{
- NMVPNConnection * vpn = NULL;
-
- g_assert (service != NULL);
- g_assert (req != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
+ g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
- nm_vpn_service_cancel_callback (service, req);
-
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_ACTIVATED);
- nm_info ("VPN Activation (%s) successful.", nm_vpn_connection_get_name (vpn));
+ return NM_VPN_SERVICE_GET_PRIVATE (service)->name;
}
-
-/*
- * nm_vpn_service_start_connection
- *
- * Kick off the VPN connection process.
- *
- */
-void
-nm_vpn_service_start_connection (NMVPNService *service,
- NMVPNActRequest *req)
+static void
+nm_vpn_service_connections_stop (NMVPNService *service, gboolean fail)
{
- g_return_if_fail (service != NULL);
- g_return_if_fail (req != NULL);
-
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_PREPARE);
- nm_vpn_service_add_watch (service);
+ NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+ GSList *iter;
- /* Start the daemon if it's not already running */
- nm_vpn_act_request_ref (req);
- if (!nm_dbus_manager_name_has_owner (service->dbus_mgr, service->service))
- nm_vpn_service_schedule_stage1_daemon_exec (service, req);
- else
- nm_vpn_service_schedule_stage2_daemon_wait (service, req);
+ for (iter = priv->connections; iter; iter = iter->next)
+ fail ? nm_vpn_connection_fail (NM_VPN_CONNECTION (iter->data))
+ : nm_vpn_connection_disconnect (NM_VPN_CONNECTION (iter->data));
}
-
/*
* nm_vpn_service_child_setup
*
setpgid (pid, pid);
}
-
-/*
- * nm_vpn_service_stage_1_daemon_exec
- *
- * Execute the VPN service daemon.
- *
- */
-static gboolean nm_vpn_service_stage1_daemon_exec (gpointer user_data)
-{
- NMVPNActRequest * req = (NMVPNActRequest *) user_data;
- NMVPNService * service;
- NMVPNConnection * vpn = NULL;
- GPtrArray * vpn_argv;
- GError * error = NULL;
- gboolean launched = FALSE;
-
- g_assert (req != NULL);
-
- service = nm_vpn_act_request_get_service (req);
- g_assert (service != NULL);
- g_assert (service->program != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
-
- nm_vpn_act_request_set_callback_id (req, 0);
-
- vpn_argv = g_ptr_array_new ();
- g_ptr_array_add (vpn_argv, service->program);
- g_ptr_array_add (vpn_argv, NULL);
-
- launched = g_spawn_async (NULL,
- (char **) vpn_argv->pdata,
- NULL,
- 0,
- &nm_vpn_service_child_setup,
- NULL,
- &service->pid,
- &error);
- if (!launched) {
- g_ptr_array_free (vpn_argv, TRUE);
- nm_warning ("(VPN Service %s): could not launch the VPN service. "
- "error: '%s'.",
- service->service,
- error->message);
- g_error_free (error);
- nm_vpn_service_act_request_failed (service, req);
- goto out;
- }
- g_ptr_array_free (vpn_argv, TRUE);
- nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) ran VPN "
- "service daemon %s (PID %d)",
- nm_vpn_connection_get_name (vpn),
- service->service,
- service->pid);
- nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) complete.",
- nm_vpn_connection_get_name (vpn));
-
- nm_vpn_service_schedule_stage2_daemon_wait (service, req);
-
-out:
- return FALSE;
-}
-
-
static void
-nm_vpn_service_schedule_stage1_daemon_exec (NMVPNService *service,
- NMVPNActRequest *req)
-{
- NMVPNConnection * vpn = NULL;
- guint id;
-
- g_assert (service != NULL);
- g_assert (req != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
+vpn_service_watch_cb (GPid pid, gint status, gpointer user_data)
+{
+ NMVPNService *service = NM_VPN_SERVICE (user_data);
+ NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+
+ if (WIFEXITED (status)) {
+ guint err = WEXITSTATUS (status);
+
+ if (err != 0)
+ nm_warning ("VPN service '%s' exited with error: %d",
+ nm_vpn_service_get_name (service), WSTOPSIG (status));
+ } else if (WIFSTOPPED (status))
+ nm_warning ("VPN service '%s' stopped unexpectedly with signal %d",
+ nm_vpn_service_get_name (service), WSTOPSIG (status));
+ else if (WIFSIGNALED (status))
+ nm_warning ("VPN service '%s' died with signal %d",
+ nm_vpn_service_get_name (service), WTERMSIG (status));
+ else
+ nm_warning ("VPN service '%s' died from an unknown cause",
+ nm_vpn_service_get_name (service));
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_PREPARE);
- nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_SHUTDOWN);
+ /* Reap child if needed. */
+ waitpid (pid, NULL, WNOHANG);
+ priv->pid = 0;
- id = g_idle_add (nm_vpn_service_stage1_daemon_exec, req);
- nm_vpn_act_request_set_callback_id (req, id);
- nm_info ("VPN Activation (%s) Stage 1 of 4 (Connection Prepare) scheduled...",
- nm_vpn_connection_get_name (vpn));
+ nm_vpn_service_connections_stop (service, TRUE);
}
-
-/*
- * nm_vpn_service_stage2_daemon_wait
- *
- * Wait until the VPN daemon has become active.
- *
- */
static gboolean
-nm_vpn_service_stage2_daemon_wait (gpointer user_data)
+nm_vpn_service_timeout (gpointer data)
{
- NMVPNActRequest * req = (NMVPNActRequest *) user_data;
- NMVPNService * service;
- NMVPNConnection * vpn = NULL;
- gboolean service_exists = FALSE;
-
- g_assert (req != NULL);
-
- service = nm_vpn_act_request_get_service (req);
- g_assert (service != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
-
- nm_vpn_act_request_set_callback_id (req, 0);
-
- nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) "
- "waiting...", nm_vpn_connection_get_name (vpn));
-
- service_exists = nm_dbus_manager_name_has_owner (service->dbus_mgr,
- service->service);
- if (service_exists && (service->state == NM_VPN_SERVICE_STATE_STOPPED)) {
- nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) "
- "complete.", nm_vpn_connection_get_name (vpn));
- nm_vpn_service_schedule_stage3_connect (service, req);
- } else if (nm_vpn_act_request_get_daemon_wait_count (req) > 10) {
- /* We only wait 2s (10 * 200 milliseconds) for the service to
- * become available.
- */
- nm_vpn_service_act_request_failed (service, req);
- } else {
- nm_vpn_service_schedule_stage2_daemon_wait (service, req);
- }
-
- return FALSE;
-}
-
-
-static void
-nm_vpn_service_schedule_stage2_daemon_wait (NMVPNService *service,
- NMVPNActRequest *req)
-{
- NMVPNConnection * vpn = NULL;
- guint id;
-
- g_assert (service != NULL);
- g_assert (req != NULL);
+ NMVPNService *service = NM_VPN_SERVICE (data);
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
+ nm_info ("VPN service '%s' did not start in time, cancelling connections",
+ nm_vpn_service_get_name (service));
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_PREPARE);
+ NM_VPN_SERVICE_GET_PRIVATE (service)->service_start_timeout = 0;
+ nm_vpn_service_connections_stop (service, TRUE);
- nm_vpn_act_request_set_daemon_wait_count (req, nm_vpn_act_request_get_daemon_wait_count (req) + 1);
-
- id = g_timeout_add (200, nm_vpn_service_stage2_daemon_wait, req);
- nm_vpn_act_request_set_callback_id (req, id);
- nm_info ("VPN Activation (%s) Stage 2 of 4 (Connection Prepare Wait) "
- "scheduled...",
- nm_vpn_connection_get_name (vpn));
+ return FALSE;
}
-
-static void
-nm_vpn_service_stage3_connect_cb (DBusPendingCall *pcall,
- void *user_data)
+static gboolean
+nm_vpn_service_daemon_exec (gpointer user_data)
{
- DBusMessage * reply;
- NMVPNActRequest * req = (NMVPNActRequest *) user_data;
- NMVPNService * service;
- NMVPNConnection * vpn;
+ NMVPNService *service = NM_VPN_SERVICE (user_data);
+ NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+ GPtrArray *vpn_argv;
+ gboolean launched;
+ GError *err = NULL;
- g_assert (pcall != NULL);
- g_assert (req != NULL);
-
- service = nm_vpn_act_request_get_service (req);
- g_assert (service != NULL);
+ vpn_argv = g_ptr_array_new ();
+ g_ptr_array_add (vpn_argv, priv->program);
+ g_ptr_array_add (vpn_argv, NULL);
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
+ launched = g_spawn_async (NULL,
+ (char **) vpn_argv->pdata,
+ NULL,
+ 0,
+ nm_vpn_service_child_setup,
+ NULL,
+ &priv->pid,
+ &err);
- nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) reply received.",
- nm_vpn_connection_get_name (vpn));
+ g_ptr_array_free (vpn_argv, TRUE);
- if (!(reply = dbus_pending_call_steal_reply (pcall))) {
- nm_warning ("(VPN Service %s): could not obtain VPN service's reply.",
- service->service);
- nm_vpn_service_act_request_failed (service, req);
- goto out;
- }
+ if (launched) {
+ GSource *vpn_watch;
- if (dbus_message_get_type (reply) == DBUS_MESSAGE_TYPE_ERROR) {
- const char *member = dbus_message_get_member (reply);
- char *message;
+ vpn_watch = g_child_watch_source_new (priv->pid);
+ g_source_set_callback (vpn_watch, (GSourceFunc) vpn_service_watch_cb, service, NULL);
+ g_source_attach (vpn_watch, NULL);
+ g_source_unref (vpn_watch);
- if (!dbus_message_get_args (reply, NULL, DBUS_TYPE_STRING, &message, NULL))
- message = (char *) "";
+ nm_info ("VPN service '%s' executed (%s), PID %d",
+ nm_vpn_service_get_name (service),
+ priv->dbus_service,
+ priv->pid);
- nm_warning ("(VPN Service %s): could not start the VPN '%s'. dbus says: '%s' '%s'.",
- service->service, nm_vpn_connection_get_name (vpn), member, message);
- nm_vpn_service_act_request_failed (service, req);
+ priv->service_start_timeout = g_timeout_add (2000, nm_vpn_service_timeout, service);
} else {
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_IP_CONFIG_GET);
- nm_vpn_service_schedule_stage4_ip_config_get_timeout (service, req);
- nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) complete, "
- "waiting for IP configuration...", nm_vpn_connection_get_name (vpn));
- }
-
- dbus_message_unref (reply);
-
-out:
- dbus_pending_call_unref (pcall);
-}
-
-
-static char **
-sanitize_dbus_string_array (char **in_array, dbus_uint32_t *in_num)
-{
- char ** out_array;
-
- g_return_val_if_fail (in_num != NULL, NULL);
-
- if (in_array)
- return in_array;
-
- out_array = g_malloc0 (sizeof (char *));
- out_array[0] = g_strdup ("");
- *in_num = 1;
- return out_array;
-}
-
-
-static gboolean nm_vpn_service_stage3_connect (gpointer user_data)
-{
- NMVPNActRequest * req = (NMVPNActRequest *) user_data;
- NMVPNService * service;
- NMVPNConnection * vpn;
- char * op;
- const char * name;
- const char * user_name;
- char ** password_items;
- dbus_uint32_t password_count;
- char ** data_items;
- dbus_uint32_t data_count;
- char ** user_routes;
- dbus_uint32_t user_routes_count = 0;
- DBusMessage * message;
- DBusPendingCall * pcall = NULL;
- DBusConnection * dbus_connection;
- gboolean success = FALSE;
-
- g_assert (req != NULL);
-
- service = nm_vpn_act_request_get_service (req);
- g_assert (service != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn != NULL);
-
- dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
- if (!dbus_connection) {
- nm_warning ("VPN Activation (%s) Stage 3 of 4 (Connect) could not get "
- "the DBus connection.",
- nm_vpn_connection_get_name (vpn));
- goto out;
- }
-
- nm_vpn_act_request_set_callback_id (req, 0);
-
- /* Send the start vpn request to the daemon */
- op = construct_op_from_service_name (service->service);
- message = dbus_message_new_method_call (service->service,
- op,
- service->service,
- "startConnection");
- g_free (op);
- if (!message) {
- nm_warning ("VPN Activation (%s) Stage 3 of 4 (Connect): couldn't "
- " allocate dbus message.",
- service->service);
- goto out;
- }
+ nm_warning ("VPN service '%s': could not launch the VPN service. error: '%s'.",
+ nm_vpn_service_get_name (service), err->message);
+ g_error_free (err);
- name = nm_vpn_connection_get_name (vpn);
- user_name = nm_vpn_connection_get_user_name (vpn);
- password_items = (char **) nm_vpn_act_request_get_password_items (req, &password_count);
- data_items = (char **) nm_vpn_act_request_get_data_items (req, &data_count);
- user_routes = (char **) nm_vpn_act_request_get_user_routes(req, &user_routes_count);
-
- /* Ensure that data_items and user_routes are safe to put through dbus */
- data_items = sanitize_dbus_string_array (data_items, &data_count);
- user_routes = sanitize_dbus_string_array (user_routes, &user_routes_count);
-
- nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) sending connect request.",
- nm_vpn_connection_get_name (vpn));
- dbus_message_append_args (message, DBUS_TYPE_STRING, &name,
- DBUS_TYPE_STRING, &user_name,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &password_items, password_count,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &data_items, data_count,
- DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &user_routes, user_routes_count,
- DBUS_TYPE_INVALID);
-
- dbus_connection_send_with_reply (dbus_connection, message, &pcall, -1);
- if (pcall) {
- dbus_pending_call_set_notify (pcall,
- nm_vpn_service_stage3_connect_cb,
- req,
- NULL);
- nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) request sent,"
- " waiting for reply...",
- nm_vpn_connection_get_name (vpn));
- success = TRUE;
+ nm_vpn_service_connections_stop (service, TRUE);
}
- dbus_message_unref (message);
-
-out:
- if (!success)
- nm_vpn_service_act_request_failed (service, req);
return FALSE;
}
-
-static void
-nm_vpn_service_schedule_stage3_connect (NMVPNService *service,
- NMVPNActRequest *req)
-{
- NMVPNConnection * vpn = NULL;
- guint id;
-
- g_assert (service != NULL);
- g_assert (req != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
-
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_CONNECT);
-
- id = g_idle_add (nm_vpn_service_stage3_connect, req);
- nm_vpn_act_request_set_callback_id (req, id);
- nm_info ("VPN Activation (%s) Stage 3 of 4 (Connect) scheduled...",
- nm_vpn_connection_get_name (vpn));
-}
-
-
static gboolean
-nm_vpn_service_stage4_ip_config_get_timeout (gpointer user_data)
+destroy_service (gpointer data)
{
- NMVPNActRequest * req = (NMVPNActRequest *) user_data;
- NMVPNService * service;
- NMVPNConnection * vpn;
-
- g_assert (req != NULL);
-
- service = nm_vpn_act_request_get_service (req);
- g_assert (service != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn != NULL);
-
- nm_vpn_act_request_set_callback_id (req, 0);
-
- /* If the activation request's state is still IP_CONFIG_GET and we're
- * in this timeout, cancel activation because it's taken too long.
- */
- if (nm_vpn_act_request_get_state (req) == NM_VPN_CONNECTION_STATE_IP_CONFIG_GET) {
- nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) timeout "
- "exceeded.",
- nm_vpn_connection_get_name (vpn));
- nm_vpn_service_act_request_failed (service, req);
- }
+ g_object_unref (data);
return FALSE;
}
-
static void
-nm_vpn_service_schedule_stage4_ip_config_get_timeout (NMVPNService *service,
- NMVPNActRequest *req)
+connection_state_changed (NMVPNConnection *connection, NMVPNConnectionState state, gpointer user_data)
{
- NMVPNConnection * vpn = NULL;
- guint id;
-
- g_assert (service != NULL);
- g_assert (req != NULL);
+ NMVPNServicePrivate *priv;
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
+ switch (state) {
+ case NM_VPN_CONNECTION_STATE_FAILED:
+ case NM_VPN_CONNECTION_STATE_DISCONNECTED:
+ /* Remove the connection from our list */
+ priv = NM_VPN_SERVICE_GET_PRIVATE (user_data);
+ priv->connections = g_slist_remove (priv->connections, connection);
+ g_object_unref (connection);
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_IP_CONFIG_GET);
-
- /* 20 second timeout waiting for IP config signal from VPN service */
- id = g_timeout_add (20000, nm_vpn_service_stage4_ip_config_get_timeout, req);
- nm_vpn_act_request_set_callback_id (req, id);
- nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) timeout "
- " scheduled...",
- nm_vpn_connection_get_name (vpn));
+ if (priv->connections == NULL) {
+ /* schedule a timeout (10 seconds) to destroy the service */
+ g_timeout_add (10000, destroy_service, user_data);
+ }
+ break;
+ default:
+ break;
+ }
}
-
-static void nm_vpn_service_cancel_callback (NMVPNService *service, NMVPNActRequest *req)
+NMVPNConnection *
+nm_vpn_service_activate (NMVPNService *service,
+ const char *name,
+ NMDevice *device,
+ GHashTable *properties,
+ char **routes)
{
- guint id;
+ NMVPNConnection *connection;
+ NMVPNServicePrivate *priv;
- g_return_if_fail (service != NULL);
- g_return_if_fail (req != NULL);
+ g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
+ g_return_val_if_fail (name != NULL, NULL);
+ g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
+ g_return_val_if_fail (properties != NULL, NULL);
- if ((id = nm_vpn_act_request_get_callback_id (req)) == 0)
- return;
+ priv = NM_VPN_SERVICE_GET_PRIVATE (service);
- g_source_destroy (g_main_context_find_source_by_id (NULL, id));
- nm_vpn_act_request_set_callback_id (req, 0);
-}
+ connection = nm_vpn_connection_new (name, priv->dbus_service, device, properties, routes);
+ g_signal_connect (connection, "state-changed",
+ G_CALLBACK (connection_state_changed),
+ service);
+ priv->connections = g_slist_prepend (priv->connections, connection);
-static gboolean
-get_dbus_guint32_helper (DBusMessageIter *iter,
- guint32 *num,
- char *desc)
-{
- if (!dbus_message_iter_next (iter)
- || (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_UINT32))
- {
- nm_warning ("Error: couldn't get %s from VPN IP Config message.", desc);
- return FALSE;
+ if (nm_dbus_manager_name_has_owner (priv->dbus_mgr, priv->dbus_service))
+ nm_vpn_connection_activate (connection);
+ 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);
}
- dbus_message_iter_get_basic (iter, num);
- return TRUE;
-}
-static gboolean
-get_dbus_string_helper (DBusMessageIter *iter,
- char **str,
- char *desc)
-{
- if (!dbus_message_iter_next (iter)
- || (dbus_message_iter_get_arg_type (iter) != DBUS_TYPE_STRING))
- {
- nm_warning ("Error: couldn't get %s from VPN IP Config message.", desc);
- return FALSE;
- }
- dbus_message_iter_get_basic (iter, str);
- return TRUE;
+ return connection;
}
-
-/*
- * nm_vpn_service_stage4_ip4_config_get_old
- *
- * Configure a device with IPv4 config info in response the the VPN daemon.
- *
- */
-static void
-nm_vpn_service_stage4_ip4_config_get_old (NMVPNService *service,
- NMVPNActRequest *req,
- DBusConnection *dbus_connection,
- DBusMessage *message)
+GSList *
+nm_vpn_service_get_connections (NMVPNService *service)
{
- NMVPNConnection * vpn;
- guint32 num;
- char * str;
- char * tundev;
- char * login_banner;
- gboolean success = FALSE;
- DBusMessageIter iter;
- DBusMessageIter subiter;
- NMIP4Config * config = NULL;
- NMDevice * parent_dev;
-
- g_return_if_fail (service != NULL);
- g_return_if_fail (message != NULL);
- g_return_if_fail (req != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
-
- nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) reply received.",
- nm_vpn_connection_get_name (vpn));
-
- config = nm_ip4_config_new ();
- nm_ip4_config_set_secondary (config, TRUE);
-
- dbus_message_iter_init (message, &iter);
-
- /* First arg: IP4 VPN Gateway address (UINT32) */
- if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_UINT32) {
- nm_warning ("Error: couldn't get IP4 VPN Gateway Address"
- " from VPN IP Config message.");
- goto out;
- }
- dbus_message_iter_get_basic (&iter, &num);
- nm_ip4_config_set_gateway (config, num);
-
- /* Second arg: Tunnel device, if any (STRING) */
- if (!get_dbus_string_helper (&iter, &tundev, "Tunnel Device"))
- goto out;
-
- /* Third arg: IP4 VPN Local Address (UINT32) */
- if (!get_dbus_guint32_helper (&iter, &num, "IP4 VPN Local Address"))
- goto out;
- nm_ip4_config_set_address (config, num);
-
- /* Fourth arg: IP4 VPN Point-to-Point Address (UINT32) */
- if (!get_dbus_guint32_helper (&iter, &num, "IP4 VPN PtP Address"))
- goto out;
- nm_ip4_config_set_ptp_address (config, num);
-
- /* Fifth arg: IP4 VPN Local Netmask (UINT32) */
- if (!get_dbus_guint32_helper (&iter, &num, "IP4 VPN Local Netmask"))
- goto out;
- /* If no netmask, default to Class C address */
- nm_ip4_config_set_netmask (config, num ? num : 0x00FF);
-
- /* Sixth arg: IP4 DNS Server Addresses (ARRAY, UINT32) */
- if ( !dbus_message_iter_next (&iter)
- || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)) {
- nm_warning ("Error: couldn't get IP4 DNS Server Addresses"
- " from VPN IP Config message.");
- goto out;
- }
- dbus_message_iter_recurse (&iter, &subiter);
- while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_UINT32) {
- dbus_message_iter_get_basic (&subiter, &num);
- if (num)
- nm_ip4_config_add_nameserver (config, num);
- dbus_message_iter_next (&subiter);
- }
-
- /* Seventh arg: IP4 NBNS Server Addresses (ARRAY, UINT32) */
- if ( !dbus_message_iter_next (&iter)
- || (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY)) {
- nm_warning ("Error: couldn't get IP4 NBNS Server Addresses"
- " from VPN IP Config message.");
- goto out;
- }
- dbus_message_iter_recurse (&iter, &subiter);
- while (dbus_message_iter_get_arg_type (&subiter) == DBUS_TYPE_UINT32) {
- dbus_message_iter_get_basic (&subiter, &num);
- /* We don't do anything with these yet */
- dbus_message_iter_next (&subiter);
- }
-
- /* Eighth arg: MSS (UINT32) */
- if (!get_dbus_guint32_helper (&iter, &num, "MSS"))
- goto out;
- nm_ip4_config_set_mss (config, num);
-
- /* Ninth arg: DNS Domain (STRING) */
- if (!get_dbus_string_helper (&iter, &str, "DNS Domain"))
- goto out;
- if (strlen (str))
- nm_ip4_config_add_domain (config, str);
+ g_return_val_if_fail (NM_IS_VPN_SERVICE (service), NULL);
- /* Tenth arg: VPN Login Banner (STRING) */
- if (!get_dbus_string_helper (&iter, &login_banner, "Login Banner"))
- goto out;
-
-#ifdef NM_DEBUG_VPN_CONFIG
- print_vpn_config (config, tundev, login_banner);
-#endif
-
- if (!(parent_dev = nm_vpn_act_request_get_parent_dev (req)))
- goto out;
-
- if (nm_vpn_connection_set_config (vpn, tundev, parent_dev, config)) {
- nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) complete.",
- nm_vpn_connection_get_name (vpn));
- if (login_banner && strlen (login_banner)) {
- nm_dbus_vpn_signal_vpn_login_banner (dbus_connection,
- vpn,
- login_banner);
- }
- success = TRUE;
- nm_vpn_service_activation_success (service, req);
- }
-
-out:
- if (!success) {
- g_object_unref (config);
- nm_warning ("(VPN Service %s): did not receive valid IP config "
- "information.",
- service->service);
- nm_vpn_service_act_request_failed (service, req);
- }
+ return g_slist_copy (NM_VPN_SERVICE_GET_PRIVATE (service)->connections);
}
-
-#define HANDLE_DICT_ITEM(in_key, in_type, in_ary_type, op) \
- if (!strcmp (entry.key, in_key)) { \
- if (entry.type != in_type) { \
- nm_warning (in_key "had invalid type in VPN IP Config message."); \
- } else { \
- if (in_type == DBUS_TYPE_ARRAY && entry.array_type != in_ary_type) { \
- nm_warning (in_key "had invalid type in VPN IP Config message."); \
- } else { \
- op \
- } \
- } \
- goto next; \
- }
-
-
-/*
- * nm_vpn_service_stage4_ip4_config_get
- *
- * Configure a device with IPv4 config info in response the the VPN daemon.
- *
- */
static void
-nm_vpn_service_stage4_ip4_config_get (NMVPNService *service,
- NMVPNActRequest *req,
- DBusMessage *message)
+nm_vpn_service_name_owner_changed (NMDBusManager *mgr,
+ const char *name,
+ const char *old,
+ const char *new,
+ gpointer user_data)
{
- NMVPNConnection * vpn;
- char * tundev = NULL;
- char * login_banner = NULL;
- gboolean success = FALSE;
- DBusMessageIter iter;
- DBusMessageIter iter_dict;
- NMIP4Config * config = NULL;
- NMDevice * parent_dev;
- NMUDictEntry entry = { .type = DBUS_TYPE_STRING };
- DBusConnection *dbus_connection;
-
- g_return_if_fail (service != NULL);
- g_return_if_fail (message != NULL);
- g_return_if_fail (req != NULL);
-
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
-
- nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) reply received.",
- nm_vpn_connection_get_name (vpn));
-
- dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
- if (!dbus_connection) {
- nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) could not "
- "get the DBus connection.",
- nm_vpn_connection_get_name (vpn));
- goto out;
- }
-
- dbus_message_iter_init (message, &iter);
+ NMVPNService *service = NM_VPN_SERVICE (user_data);
+ NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
+ gboolean old_owner_good;
+ gboolean new_owner_good;
- /* If first arg is (UINT32) then this is an old type message */
- if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_UINT32) {
- nm_warning ("Warning: VPN plugin is using the old IP4Config message type");
- nm_vpn_service_stage4_ip4_config_get_old (service,
- req,
- dbus_connection,
- message);
+ if (strcmp (name, priv->dbus_service))
return;
- }
- if (!nmu_dbus_dict_open_read (&iter, &iter_dict)) {
- nm_warning ("Warning: couldn't get config dictionary"
- " from VPN IP Config message.");
- goto out;
+ /* Service changed, no need to wait for the timeout any longer */
+ if (priv->service_start_timeout) {
+ g_source_remove (priv->service_start_timeout);
+ priv->service_start_timeout = 0;
}
- config = nm_ip4_config_new ();
- nm_ip4_config_set_secondary (config, TRUE);
+ old_owner_good = (old && (strlen (old) > 0));
+ new_owner_good = (new && (strlen (new) > 0));
- /* First arg: Dict Type */
- if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
- nm_warning ("Error: couldn't get configuration dict"
- " from VPN IP Config message.");
- goto out;
- }
-
- while (nmu_dbus_dict_has_dict_entry (&iter_dict)) {
- int i;
-
- if (!nmu_dbus_dict_get_entry (&iter_dict, &entry)) {
- nm_warning ("Error: couldn't read dict entry"
- " from VPN IP Config message.");
- goto out;
- }
-
- /* IP specific options */
- HANDLE_DICT_ITEM("gateway", DBUS_TYPE_UINT32, 0,
- { nm_ip4_config_set_gateway (config, entry.uint32_value); });
- HANDLE_DICT_ITEM("local_addr", DBUS_TYPE_UINT32, 0,
- { nm_ip4_config_set_address (config, entry.uint32_value); });
- HANDLE_DICT_ITEM("ptp_addr", DBUS_TYPE_UINT32, 0,
- { nm_ip4_config_set_ptp_address (config, entry.uint32_value); });
- /* If no netmask, default to Class C address */
- HANDLE_DICT_ITEM("local_netmask", DBUS_TYPE_UINT32, 0,
- { nm_ip4_config_set_netmask (config, entry.uint32_value ? entry.uint32_value : 0x00FF); });
- /* Multiple DNS servers are allowed */
- HANDLE_DICT_ITEM("dns_server", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
- {
- for (i = 0; i < entry.array_len; i++)
- nm_ip4_config_add_nameserver (config, entry.uint32array_value[i]);
- });
- /* Multiple NBNS servers are allowed */
- HANDLE_DICT_ITEM("nbns_server", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,
- {
- for (i = 0; i < entry.array_len; i++) {
- /* We don't do anything with these yet */
- }
- });
- /* Generic options */
- HANDLE_DICT_ITEM("mss", DBUS_TYPE_UINT32, 0,
- { nm_ip4_config_set_mss (config, entry.uint32_value); });
- HANDLE_DICT_ITEM("mtu", DBUS_TYPE_UINT32, 0,
- { nm_ip4_config_set_mtu (config, entry.uint32_value); });
- HANDLE_DICT_ITEM("tundev", DBUS_TYPE_STRING, 0,
- { if (strlen (entry.str_value)) tundev = g_strdup (entry.str_value); });
- HANDLE_DICT_ITEM("dns_domain", DBUS_TYPE_STRING, 0,
- { if (strlen (entry.str_value)) nm_ip4_config_add_domain (config, entry.str_value); });
- HANDLE_DICT_ITEM("login_banner", DBUS_TYPE_STRING, 0,
- { if (strlen (entry.str_value)) login_banner = g_strdup (entry.str_value); });
-
- next:
- nmu_dbus_dict_entry_clear (&entry);
- };
-
-#ifdef NM_DEBUG_VPN_CONFIG
- print_vpn_config (config, tundev, login_banner);
-#endif
-
- if (!(parent_dev = nm_vpn_act_request_get_parent_dev (req)))
- goto out;
-
- if (nm_vpn_connection_set_config (vpn, tundev, parent_dev, config)) {
- nm_info ("VPN Activation (%s) Stage 4 of 4 (IP Config Get) complete.",
- nm_vpn_connection_get_name (vpn));
- if (login_banner && strlen (login_banner)) {
- nm_dbus_vpn_signal_vpn_login_banner (dbus_connection,
- vpn,
- login_banner);
- }
- success = TRUE;
- nm_vpn_service_activation_success (service, req);
- }
-
-out:
- if (tundev) g_free (tundev);
- if (login_banner) g_free (login_banner);
- if (!success) {
- if (config)
- g_object_unref (config);
- nm_warning ("(VPN Service %s): did not receive valid IP config "
- "information.",
- service->service);
- nm_vpn_service_act_request_failed (service, req);
- }
-}
-
-
-static void
-nm_vpn_service_stop_connection_internal (NMVPNService *service)
-{
- DBusConnection * dbus_connection;
-
- g_return_if_fail (service != NULL);
-
- dbus_connection = nm_dbus_manager_get_dbus_connection (service->dbus_mgr);
- if (dbus_connection) {
- DBusMessage * message;
- char * op;
-
- /* Construct a new method call with the correct service and object path */
- op = construct_op_from_service_name (service->service);
- message = dbus_message_new_method_call (service->service,
- op,
- service->service,
- "stopConnection");
- g_free (op);
- if (!message) {
- nm_warning ("(VPN Service %s): couldn't allocate dbus message.",
- service->service);
- } else {
- dbus_connection_send (dbus_connection, message, NULL);
- dbus_message_unref (message);
- }
- } else {
- /* If we have the PID of the VPN service daemon, send it a TERM */
- if (service->pid) {
- kill (service->pid, SIGTERM);
- service->pid = 0;
- } else {
- nm_warning ("(VPN Service %s): stop called, but did not have PID "
- "for VPN service daemon.",
- service->service);
- }
- }
-}
-
-
-void
-nm_vpn_service_stop_connection (NMVPNService *service,
- NMVPNActRequest *req)
-{
- NMVPNConnection *vpn;
-
- g_return_if_fail (service != NULL);
- g_return_if_fail (req != NULL);
+ if (!old_owner_good && new_owner_good) {
+ /* service just appeared */
+ GSList *iter;
- vpn = nm_vpn_act_request_get_connection (req);
- g_assert (vpn);
+ nm_info ("VPN service '%s' just appeared, activating connections",
+ nm_vpn_service_get_name (service));
- nm_vpn_service_cancel_callback (service, req);
- nm_vpn_act_request_set_state (req, NM_VPN_CONNECTION_STATE_DISCONNECTED);
+ for (iter = priv->connections; iter; iter = iter->next)
+ nm_vpn_connection_activate (NM_VPN_CONNECTION (iter->data));
- /* Ensure we can stop the connection in this state */
- if ( (service->state != NM_VPN_SERVICE_STATE_STARTED)
- && (service->state != NM_VPN_SERVICE_STATE_STARTING)) {
- nm_warning ("(VPN Service %s): could not stop connection '%s' because "
- " service was %d.",
- service->service,
- nm_vpn_connection_get_name (vpn),
- service->state);
- return;
+ } else if (old_owner_good && !new_owner_good) {
+ /* service went away */
+ nm_info ("VPN service '%s' disappeared, cancelling connections",
+ nm_vpn_service_get_name (service));
+ nm_vpn_service_connections_stop (service, TRUE);
}
-
- nm_vpn_service_stop_connection_internal (service);
- nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_STOPPED);
-}
-
-
-static void
-nm_vpn_service_add_watch (NMVPNService *service)
-{
- guint32 id;
-
- g_return_if_fail (service != NULL);
-
- if (service->watch_id)
- return;
-
- /* Add a dbus filter for this connection's service name so its signals
- * get delivered to us.
- */
- id = nm_dbus_manager_register_signal_handler (service->dbus_mgr,
- service->service,
- NULL,
- nm_vpn_service_process_signal,
- service);
- service->sig_handler_id = id;
- service->watch_id = g_signal_connect (service->dbus_mgr,
- "name-owner-changed",
- G_CALLBACK (nm_vpn_service_name_owner_changed),
- service);
- service->dbus_con_watch_id = g_signal_connect (service->dbus_mgr,
- "dbus-connection-changed",
- G_CALLBACK (nm_vpn_service_dbus_connection_changed),
- service);
}
+/******************************************************************************/
static void
-nm_vpn_service_remove_watch (NMVPNService *service)
+nm_vpn_service_init (NMVPNService *service)
{
- g_return_if_fail (service != NULL);
+ NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (service);
- if (!service->watch_id)
- return;
-
- nm_dbus_manager_remove_signal_handler (service->dbus_mgr, service->sig_handler_id);
- g_signal_handler_disconnect (service->dbus_mgr, service->watch_id);
- service->watch_id = 0;
- g_signal_handler_disconnect (service->dbus_mgr, service->dbus_con_watch_id);
- service->dbus_con_watch_id = 0;
-}
-
-
-static inline gboolean same_service_name (NMVPNService *service, NMVPNConnection *vpn)
-{
- g_return_val_if_fail (service != NULL, FALSE);
- g_return_val_if_fail (vpn != NULL, FALSE);
-
- return (!strcmp (nm_vpn_service_get_service_name (service), nm_vpn_connection_get_service_name (vpn)));
+ priv->dbus_mgr = nm_dbus_manager_get ();
+
+ priv->name_owner_id = g_signal_connect (priv->dbus_mgr, "name-owner-changed",
+ G_CALLBACK (nm_vpn_service_name_owner_changed),
+ service);
}
static void
-nm_vpn_service_dbus_connection_changed (NMDBusManager *mgr,
- DBusConnection *dbus_connection,
- gpointer user_data)
+finalize (GObject *object)
{
- NMVPNService * service = (NMVPNService *) user_data;
+ NMVPNServicePrivate *priv = NM_VPN_SERVICE_GET_PRIVATE (object);
- g_return_if_fail (service != NULL);
+ if (priv->service_start_timeout)
+ g_source_remove (priv->service_start_timeout);
- if (!dbus_connection) {
- NMVPNActRequest * req;
- NMVPNConnection * vpn;
- gboolean valid_vpn = FALSE;
+ nm_vpn_service_connections_stop (NM_VPN_SERVICE (object), FALSE);
- /* Kill the VPN service since we can't talk to it anymore anyway */
- nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_SHUTDOWN);
- nm_vpn_service_remove_watch (service);
+ g_signal_handler_disconnect (priv->dbus_mgr, priv->name_owner_id);
+ g_object_unref (priv->dbus_mgr);
- req = nm_vpn_manager_get_vpn_act_request (service->manager);
- if (req && (vpn = nm_vpn_act_request_get_connection (req)))
- valid_vpn = same_service_name (service, vpn);
+ g_free (priv->name);
+ g_free (priv->dbus_service);
+ g_free (priv->program);
- if (valid_vpn) {
- nm_vpn_act_request_unref (req);
- nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
- }
- }
+ G_OBJECT_CLASS (nm_vpn_service_parent_class)->finalize (object);
}
static void
-nm_vpn_service_name_owner_changed (NMDBusManager *mgr,
- const char *name,
- const char *old,
- const char *new,
- gpointer user_data)
+nm_vpn_service_class_init (NMVPNServiceClass *service_class)
{
- NMVPNService * service = (NMVPNService *) user_data;
- NMVPNActRequest * req;
- NMVPNConnection * vpn;
- gboolean valid_vpn = FALSE;
- gboolean old_owner_good = (old && strlen (old));
- gboolean new_owner_good = (new && strlen (new));
-
- g_return_if_fail (service != NULL);
-
- if (strcmp (name, service->service) != 0)
- return;
+ GObjectClass *object_class = G_OBJECT_CLASS (service_class);
- req = nm_vpn_manager_get_vpn_act_request (service->manager);
- if (req && (vpn = nm_vpn_act_request_get_connection (req)))
- valid_vpn = same_service_name (service, vpn);
+ g_type_class_add_private (service_class, sizeof (NMVPNServicePrivate));
- if (!old_owner_good && new_owner_good) {
- /* VPN service started. */
- nm_vpn_service_add_watch (service);
- nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_INIT);
- } else if (old_owner_good && !new_owner_good) {
- /* VPN service went away. */
- nm_vpn_service_set_state (service, NM_VPN_SERVICE_STATE_SHUTDOWN);
- nm_vpn_service_remove_watch (service);
-
- if (valid_vpn) {
- nm_vpn_act_request_unref (req);
- nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
- }
- }
-}
-
-
-static gboolean
-nm_vpn_service_process_signal (DBusConnection *connection,
- DBusMessage *message,
- gpointer user_data)
-{
- NMVPNService * service = (NMVPNService *) user_data;
- NMVPNConnection * vpn = NULL;
- NMVPNActRequest * req;
- gboolean valid_vpn = FALSE;
-
- g_return_val_if_fail (connection != NULL, FALSE);
- g_return_val_if_fail (message != NULL, FALSE);
- g_return_val_if_fail (service != NULL, FALSE);
-
- req = nm_vpn_manager_get_vpn_act_request (service->manager);
- if (req && (vpn = nm_vpn_act_request_get_connection (req)))
- valid_vpn = same_service_name (service, vpn);
-
- if ( dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_LOGIN_FAILED)
- || dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_LAUNCH_FAILED)
- || dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_CONNECT_FAILED)
- || dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_VPN_CONFIG_BAD)
- || dbus_message_is_signal (message, service->service, NM_DBUS_VPN_SIGNAL_IP_CONFIG_BAD))
- {
- const char * member = dbus_message_get_member (message);
- char * error_msg;
-
- if (valid_vpn) {
- if (!dbus_message_get_args (message,
- NULL,
- DBUS_TYPE_STRING, &error_msg,
- DBUS_TYPE_INVALID)) {
- error_msg = (char *) "";
- }
- nm_warning ("VPN failed for service '%s', signal '%s', with "
- " message '%s'.",
- service->service,
- member,
- error_msg);
- nm_dbus_vpn_signal_vpn_failed (connection, member, vpn, error_msg);
-
- /* Don't deal with VPN Connection stopping here, we'll do that
- * when we get the STOPPED or STOPPING signal below.
- */
- }
- } else if (dbus_message_is_signal (message, service->service,
- NM_DBUS_VPN_SIGNAL_STATE_CHANGE)) {
- dbus_uint32_t old_state_int;
- dbus_uint32_t new_state_int;
-
- if (dbus_message_get_args (message,
- NULL,
- DBUS_TYPE_UINT32, &old_state_int,
- DBUS_TYPE_UINT32, &new_state_int,
- DBUS_TYPE_INVALID)) {
- NMVPNServiceState old_state = (NMVPNServiceState) old_state_int;
- NMVPNServiceState new_state = (NMVPNServiceState) new_state_int;
-
- nm_info ("VPN service '%s' signaled state change %d -> %d.",
- service->service,
- old_state,
- new_state);
- nm_vpn_service_set_state (service, new_state);
-
- /* If the VPN daemon state is now stopped and it was starting,
- * clear the active connection.
- */
- if ( ( (new_state == NM_VPN_SERVICE_STATE_STOPPED)
- || (new_state == NM_VPN_SERVICE_STATE_SHUTDOWN)
- || (new_state == NM_VPN_SERVICE_STATE_STOPPING))
- && ( (old_state == NM_VPN_SERVICE_STATE_STARTED)
- || (old_state == NM_VPN_SERVICE_STATE_STARTING))
- && valid_vpn) {
- nm_vpn_act_request_unref (req);
- nm_vpn_manager_schedule_vpn_connection_died (service->manager, req);
- }
- }
- } else if ( valid_vpn
- && dbus_message_is_signal (message, service->service,
- NM_DBUS_VPN_SIGNAL_IP4_CONFIG)) {
- nm_vpn_service_stage4_ip4_config_get (service, req, message);
- }
-
- return TRUE;
-}
-
-#ifdef NM_DEBUG_VPN_CONFIG
-/*
- * Prints config returned from the service daemo
- */
-static void print_vpn_config (NMIP4Config *config,
- const char *tundev,
- const char *login_banner)
-{
- struct in_addr temp_addr;
- char * dns_domain = NULL;
- guint32 num;
- guint32 i;
-
- g_return_if_fail (config != NULL);
-
- temp_addr.s_addr = nm_ip4_config_get_gateway (config);
- nm_info ("VPN Gateway: %s", inet_ntoa (temp_addr));
- nm_info ("Tunnel Device: %s", tundev);
- temp_addr.s_addr = nm_ip4_config_get_address (config);
- nm_info ("Internal IP4 Address: %s", inet_ntoa (temp_addr));
- temp_addr.s_addr = nm_ip4_config_get_netmask (config);
- nm_info ("Internal IP4 Netmask: %s", inet_ntoa (temp_addr));
- temp_addr.s_addr = nm_ip4_config_get_ptp_address (config);
- nm_info ("Internal IP4 Point-to-Point Address: %s", inet_ntoa (temp_addr));
- nm_info ("Maximum Segment Size (MSS): %d", nm_ip4_config_get_mss (config));
-
- num = nm_ip4_config_get_num_nameservers (config);
- for (i = 1; i <= num; i++)
- {
- temp_addr.s_addr = nm_ip4_config_get_nameserver (config, i);
- nm_info ("Internal IP4 DNS: %s", inet_ntoa (temp_addr));
- }
-
- if (nm_ip4_config_get_num_domains (config) > 0)
- dns_domain = (char *) nm_ip4_config_get_domain (config, 1);
- nm_info ("DNS Domain: '%s'", dns_domain ? dns_domain : "(none)");
- nm_info ("Login Banner:");
- nm_info ("-----------------------------------------");
- nm_info ("%s", login_banner);
- nm_info ("-----------------------------------------");
+ /* virtual methods */
+ object_class->finalize = finalize;
}
-
-#endif
-/* 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 2005 Red Hat, Inc.
- */
+/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
#ifndef NM_VPN_SERVICE_H
#define NM_VPN_SERVICE_H
-
-#include <dbus/dbus.h>
-#include "NetworkManager.h"
-#include "NetworkManagerVPN.h"
-#include "NetworkManagerMain.h"
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include "nm-device.h"
#include "nm-vpn-connection.h"
-typedef struct NMVPNService NMVPNService;
-
-
-NMVPNService * nm_vpn_service_new (NMVPNManager *manager);
+#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_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_VPN_SERVICE, NMVPNServiceClass))
+#define NM_IS_VPN_SERVICE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_VPN_SERVICE))
+#define NM_IS_VPN_SERVICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_VPN_SERVICE))
+#define NM_VPN_SERVICE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_VPN_SERVICE, NMVPNServiceClass))
-void nm_vpn_service_ref (NMVPNService *service);
-void nm_vpn_service_unref (NMVPNService *service);
+typedef struct {
+ GObject parent;
+} NMVPNService;
-const char * nm_vpn_service_get_name (NMVPNService *service);
-void nm_vpn_service_set_name (NMVPNService *service, const char *name);
+typedef struct {
+ GObjectClass parent;
+} NMVPNServiceClass;
-const char * nm_vpn_service_get_service_name (NMVPNService *service);
-void nm_vpn_service_set_service_name (NMVPNService *service, const char *name);
+GType nm_vpn_service_get_type (void);
-const char * nm_vpn_service_get_program (NMVPNService *service);
-void nm_vpn_service_set_program (NMVPNService *service, const char *program);
+NMVPNService *nm_vpn_service_new (const char *service_name);
+const char *nm_vpn_service_get_name (NMVPNService *service);
-NMVPNServiceState nm_vpn_service_get_state (NMVPNService *service);
+NMVPNConnection *nm_vpn_service_activate (NMVPNService *service,
+ const char *name,
+ NMDevice *device,
+ GHashTable *properties,
+ char **routes);
-void nm_vpn_service_start_connection (NMVPNService *service, NMVPNActRequest *req);
-void nm_vpn_service_stop_connection (NMVPNService *service, NMVPNActRequest *req);
+GSList *nm_vpn_service_get_connections (NMVPNService *service);
-#endif
+#endif /* NM_VPN_VPN_SERVICE_H */
-I${top_srcdir}/libnm-util \
-I${top_srcdir}/libnm-glib \
-I${top_srcdir}/gnome/libnm_glib \
- -I${top_srcdir}/utils \
-I${top_srcdir}/include
AM_CPPFLAGS = \
nm_online_SOURCES = nm-online.c
nm_online_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS) \
- $(top_builddir)/utils/libnmutils.la
+ $(top_builddir)/libnm-util/libnm-util.la
nmtestdevices_SOURCES = nmtestdevices.c
nmtestdevices_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) \
- $(top_builddir)/utils/libnmutils.la
+ $(top_builddir)/libnm-util/libnm-util.la
libnm_glib_test_SOURCES = libnm_glib_test.c
libnm_glib_test_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) \
$(top_builddir)/libnm-glib/libnm_glib.la \
- $(top_builddir)/utils/libnmutils.la \
$(top_builddir)/libnm-util/libnm-util.la
nm_supplicant_test_SOURCES = nm-supplicant-test.c