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. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2798 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
57
ChangeLog
57
ChangeLog
@@ -1,3 +1,60 @@
|
||||
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.
|
||||
|
@@ -1,5 +1,4 @@
|
||||
SUBDIRS = \
|
||||
utils \
|
||||
libnm-util \
|
||||
libnm-glib \
|
||||
src \
|
||||
|
@@ -258,7 +258,6 @@ fi
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
include/Makefile
|
||||
utils/Makefile
|
||||
src/Makefile
|
||||
src/named-manager/Makefile
|
||||
src/vpn-manager/Makefile
|
||||
|
@@ -8,7 +8,6 @@ NetworkManagerDispatcher_SOURCES = \
|
||||
|
||||
NetworkManagerDispatcher_CPPFLAGS = \
|
||||
-I$(top_srcdir) \
|
||||
-I$(top_srcdir)/utils \
|
||||
-I$(top_srcdir)/include \
|
||||
-I$(top_srcdir)/libnm-util \
|
||||
-I$(top_srcdir)/libnm-glib \
|
||||
@@ -26,7 +25,6 @@ NetworkManagerDispatcher_CFLAGS = \
|
||||
$(NULL)
|
||||
|
||||
NetworkManagerDispatcher_LDADD = \
|
||||
$(top_builddir)/utils/libnmutils.la \
|
||||
$(top_builddir)/libnm-util/libnm-util.la\
|
||||
$(top_builddir)/libnm-glib/libnm_glib.la\
|
||||
$(DBUS_LIBS) \
|
||||
|
@@ -25,9 +25,14 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -77,14 +82,25 @@ typedef enum NMVPNServiceState
|
||||
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 */
|
||||
|
17
introspection/nm-vpn-connection.xml
Normal file
17
introspection/nm-vpn-connection.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?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>
|
||||
|
22
introspection/nm-vpn-manager.xml
Normal file
22
introspection/nm-vpn-manager.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?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>
|
||||
|
44
introspection/nm-vpn-plugin.xml
Normal file
44
introspection/nm-vpn-plugin.xml
Normal file
@@ -0,0 +1,44 @@
|
||||
<?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>
|
@@ -1,4 +1,4 @@
|
||||
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 \
|
||||
@@ -9,9 +9,12 @@ BUILT_SOURCES = \
|
||||
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) \
|
||||
@@ -32,12 +35,16 @@ libnminclude_HEADERS = \
|
||||
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 \
|
||||
@@ -46,10 +53,10 @@ libnm_glib_la_SOURCES = \
|
||||
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) \
|
||||
@@ -63,6 +70,11 @@ libnm_glib_test_SOURCES = libnm-glib-test.c
|
||||
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 \
|
||||
@@ -98,6 +110,15 @@ nm-settings-glue.h: $(top_srcdir)/introspection/nm-settings.xml
|
||||
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
|
||||
|
||||
|
@@ -19,11 +19,6 @@ typedef struct {
|
||||
NMState state;
|
||||
gboolean have_device_list;
|
||||
GHashTable *devices;
|
||||
|
||||
DBusGProxy *vpn_proxy;
|
||||
NMVPNConnectionState vpn_state;
|
||||
gboolean have_vpn_connections;
|
||||
GHashTable *vpn_connections;
|
||||
} NMClientPrivate;
|
||||
|
||||
enum {
|
||||
@@ -32,10 +27,6 @@ enum {
|
||||
DEVICE_REMOVED,
|
||||
STATE_CHANGE,
|
||||
|
||||
VPN_CONNECTION_ADDED,
|
||||
VPN_CONNECTION_REMOVED,
|
||||
VPN_STATE_CHANGE,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -51,9 +42,6 @@ static void client_state_change_proxy (DBusGProxy *proxy, guint state, gpointer
|
||||
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)
|
||||
{
|
||||
@@ -63,12 +51,6 @@ 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*
|
||||
@@ -116,8 +98,6 @@ constructor (GType type,
|
||||
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",
|
||||
@@ -149,11 +129,9 @@ finalize (GObject *object)
|
||||
{
|
||||
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
|
||||
@@ -165,9 +143,6 @@ manager_running (NMClient *client, gboolean running)
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,36 +198,6 @@ nm_client_class_init (NMClientClass *client_class)
|
||||
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 *
|
||||
@@ -498,288 +443,3 @@ nm_client_sleep (NMClient *client, gboolean sleep)
|
||||
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;
|
||||
}
|
||||
|
@@ -6,10 +6,8 @@
|
||||
#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
|
||||
|
||||
@@ -32,10 +30,6 @@ typedef struct {
|
||||
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);
|
||||
@@ -53,17 +47,6 @@ void nm_client_wireless_set_enabled (NMClient *client, gboolean enabled);
|
||||
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 */
|
||||
|
@@ -1,4 +1,4 @@
|
||||
#include "nm-utils.h"
|
||||
#include "nm-dbus-utils.h"
|
||||
|
||||
char *
|
||||
nm_dbus_get_string_property (DBusGProxy *proxy,
|
@@ -3,6 +3,7 @@
|
||||
#define NM_SETTINGS_H 1
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* -*- 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>
|
||||
@@ -21,21 +22,21 @@
|
||||
|
||||
#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
|
||||
@@ -43,153 +44,39 @@ enum {
|
||||
|
||||
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)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
|
||||
|
||||
g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
|
||||
|
||||
/* virtual methods */
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* 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);
|
||||
|
||||
}
|
||||
|
||||
static gboolean
|
||||
update_properties (NMVPNConnection *connection)
|
||||
{
|
||||
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);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NMVPNConnection *
|
||||
nm_vpn_connection_new (DBusGProxy *proxy, const char *name)
|
||||
nm_vpn_connection_new (DBusGConnection *dbus_connection,
|
||||
const char *path)
|
||||
{
|
||||
GObject *object;
|
||||
NMVPNConnectionPrivate *priv;
|
||||
NMVPNConnection *connection;
|
||||
|
||||
g_return_val_if_fail (DBUS_IS_G_PROXY (proxy), NULL);
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
g_return_val_if_fail (dbus_connection != NULL, NULL);
|
||||
g_return_val_if_fail (path != NULL, NULL);
|
||||
|
||||
object = g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
|
||||
if (!object)
|
||||
return NULL;
|
||||
connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION,
|
||||
NM_OBJECT_CONNECTION, dbus_connection,
|
||||
NM_OBJECT_PATH, path,
|
||||
NULL);
|
||||
|
||||
priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
|
||||
priv->proxy = proxy;
|
||||
priv->name = g_strdup (name);
|
||||
nm_vpn_connection_get_name (connection);
|
||||
|
||||
if (!update_properties ((NMVPNConnection *) object)) {
|
||||
g_object_unref (object);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (NMVPNConnection *) object;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_connection_update (NMVPNConnection *vpn)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
|
||||
|
||||
if (update_properties (vpn)) {
|
||||
g_signal_emit (vpn, signals[UPDATED], 0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return connection;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_vpn_connection_get_name (NMVPNConnection *vpn)
|
||||
{
|
||||
NMVPNConnectionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
|
||||
|
||||
return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->name;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_vpn_connection_get_user_name (NMVPNConnection *vpn)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), NULL);
|
||||
|
||||
return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->user_name;
|
||||
}
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
NMVPNConnectionState
|
||||
@@ -200,83 +87,99 @@ nm_vpn_connection_get_state (NMVPNConnection *vpn)
|
||||
return NM_VPN_CONNECTION_GET_PRIVATE (vpn)->state;
|
||||
}
|
||||
|
||||
void
|
||||
nm_vpn_connection_set_state (NMVPNConnection *vpn, NMVPNConnectionState state)
|
||||
static void
|
||||
state_changed_proxy (DBusGProxy *proxy, NMVPNConnectionState state, gpointer user_data)
|
||||
{
|
||||
NMVPNConnectionPrivate *priv;
|
||||
NMVPNConnection *connection = NM_VPN_CONNECTION (user_data);
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
if (priv->state != state) {
|
||||
priv->state = state;
|
||||
g_signal_emit (connection, signals[STATE_CHANGED], 0, state);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_vpn_connection_disconnect (NMVPNConnection *vpn)
|
||||
{
|
||||
GError *err = NULL;
|
||||
|
||||
g_return_if_fail (NM_IS_VPN_CONNECTION (vpn));
|
||||
|
||||
priv = NM_VPN_CONNECTION_GET_PRIVATE (vpn);
|
||||
if (priv->state != state) {
|
||||
priv->state = state;
|
||||
g_signal_emit (vpn, signals[STATE_CHANGED], 0, state);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_connection_is_activating (NMVPNConnection *vpn)
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
nm_vpn_connection_init (NMVPNConnection *connection)
|
||||
{
|
||||
NMVPNConnectionState state;
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
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;
|
||||
|
||||
return FALSE;
|
||||
priv->state = NM_VPN_CONNECTION_STATE_UNKNOWN;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_connection_activate (NMVPNConnection *vpn, GSList *passwords)
|
||||
static GObject*
|
||||
constructor (GType type,
|
||||
guint n_construct_params,
|
||||
GObjectConstructParam *construct_params)
|
||||
{
|
||||
char **password_strings;
|
||||
GSList *iter;
|
||||
int i;
|
||||
NMObject *object;
|
||||
NMVPNConnectionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
|
||||
g_return_val_if_fail (passwords != NULL, FALSE);
|
||||
object = (NMObject *) G_OBJECT_CLASS (nm_vpn_connection_parent_class)->constructor (type,
|
||||
n_construct_params,
|
||||
construct_params);
|
||||
if (!object)
|
||||
return NULL;
|
||||
|
||||
if (nm_vpn_connection_get_state (vpn) != NM_VPN_CONNECTION_STATE_DISCONNECTED) {
|
||||
g_warning ("VPN connection is already connected or connecting");
|
||||
return FALSE;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_connection_deactivate (NMVPNConnection *vpn)
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_CONNECTION (vpn), FALSE);
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
|
||||
|
||||
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;
|
||||
g_object_unref (priv->proxy);
|
||||
}
|
||||
|
||||
dbus_g_proxy_call_no_reply (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy,
|
||||
"deactivateVPNConnection",
|
||||
G_TYPE_INVALID, G_TYPE_INVALID);
|
||||
return TRUE;
|
||||
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 */
|
||||
object_class->constructor = constructor;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
/* -*- 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>
|
||||
@@ -25,6 +26,7 @@
|
||||
#include <glib/gtypes.h>
|
||||
#include <glib-object.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include "nm-object.h"
|
||||
#include "NetworkManagerVPN.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -37,35 +39,26 @@ 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);
|
||||
|
||||
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
|
||||
|
||||
|
139
libnm-glib/nm-vpn-manager.c
Normal file
139
libnm-glib/nm-vpn-manager.c
Normal file
@@ -0,0 +1,139 @@
|
||||
/* -*- 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;
|
||||
}
|
47
libnm-glib/nm-vpn-manager.h
Normal file
47
libnm-glib/nm-vpn-manager.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* -*- 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 */
|
676
libnm-glib/nm-vpn-plugin.c
Normal file
676
libnm-glib/nm-vpn-plugin.c
Normal file
@@ -0,0 +1,676 @@
|
||||
/* -*- 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 ();
|
||||
}
|
98
libnm-glib/nm-vpn-plugin.h
Normal file
98
libnm-glib/nm-vpn-plugin.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/* -*- 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 */
|
@@ -40,7 +40,9 @@ libnm_util_la_SOURCES= \
|
||||
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
|
||||
@@ -67,7 +69,8 @@ libnm_util_include_HEADERS = \
|
||||
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
|
||||
|
@@ -225,29 +225,6 @@ nm_connection_to_hash (NMConnection *connection)
|
||||
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)
|
||||
{
|
||||
@@ -277,7 +254,7 @@ 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;
|
||||
|
||||
@@ -302,7 +279,7 @@ gvalue_to_string (GValue *val)
|
||||
|
||||
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, ", ");
|
||||
|
541
libnm-util/nm-utils.c
Normal file
541
libnm-util/nm-utils.c
Normal file
@@ -0,0 +1,541 @@
|
||||
/* 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);
|
||||
}
|
148
libnm-util/nm-utils.h
Normal file
148
libnm-util/nm-utils.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/* 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 */
|
@@ -6,7 +6,6 @@ INCLUDES = -I${top_srcdir} \
|
||||
-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
|
||||
@@ -35,7 +34,6 @@ NetworkManager_SOURCES = \
|
||||
nm-ip4-config.c \
|
||||
nm-ip4-config.h \
|
||||
NetworkManager.c \
|
||||
NetworkManagerMain.h \
|
||||
NetworkManagerPolicy.c \
|
||||
NetworkManagerPolicy.h \
|
||||
NetworkManagerUtils.c \
|
||||
@@ -129,7 +127,6 @@ NetworkManager_LDADD = \
|
||||
$(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 \
|
||||
|
@@ -49,10 +49,10 @@
|
||||
#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"
|
||||
@@ -375,7 +375,7 @@ done:
|
||||
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)
|
||||
|
@@ -1,28 +0,0 @@
|
||||
/* 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
|
@@ -43,6 +43,7 @@
|
||||
#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"
|
||||
@@ -310,17 +311,17 @@ out:
|
||||
*
|
||||
*/
|
||||
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);
|
||||
|
||||
@@ -370,7 +371,10 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
|
||||
|
||||
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 ();
|
||||
@@ -400,7 +404,9 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -412,13 +418,16 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
|
||||
* 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;
|
||||
}
|
||||
|
@@ -25,7 +25,6 @@
|
||||
#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
|
||||
@@ -63,8 +62,14 @@ gboolean nm_system_device_get_use_dhcp (NMDevice *dev);
|
||||
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);
|
||||
|
@@ -31,7 +31,6 @@
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerMain.h"
|
||||
#include "nm-device.h"
|
||||
|
||||
typedef enum SockType
|
||||
|
@@ -33,7 +33,6 @@
|
||||
#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"
|
||||
|
@@ -36,7 +36,6 @@
|
||||
#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"
|
||||
|
@@ -288,30 +288,6 @@ string_to_state (const char *state)
|
||||
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)
|
||||
@@ -329,7 +305,7 @@ get_option (GHashTable * hash,
|
||||
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
|
||||
@@ -352,7 +328,7 @@ copy_option (gpointer key,
|
||||
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;
|
||||
|
||||
|
@@ -52,7 +52,6 @@ typedef struct {
|
||||
DBusConnection *connection);
|
||||
|
||||
void (*name_owner_changed) (NMDBusManager *mgr,
|
||||
DBusConnection *connection,
|
||||
const char *name,
|
||||
const char *old_owner,
|
||||
const char *new_owner);
|
||||
|
@@ -29,7 +29,6 @@
|
||||
|
||||
#include "nm-device.h"
|
||||
#include "NetworkManagerAP.h"
|
||||
#include "NetworkManagerMain.h"
|
||||
|
||||
struct NMAccessPointList;
|
||||
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#include "nm-device.h"
|
||||
#include "NetworkManagerMain.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
|
@@ -2,7 +2,6 @@
|
||||
#define NM_HAL_MANAGER_H
|
||||
|
||||
#include "nm-manager.h"
|
||||
#include "NetworkManagerMain.h"
|
||||
|
||||
typedef struct _NMHalManager NMHalManager;
|
||||
|
||||
|
@@ -30,7 +30,6 @@
|
||||
|
||||
#include "nm-logging.h"
|
||||
#include "nm-utils.h"
|
||||
#include "NetworkManagerMain.h"
|
||||
|
||||
static void
|
||||
fallback_get_backtrace (void)
|
||||
|
@@ -3,33 +3,44 @@ INCLUDES = -I${top_srcdir} \
|
||||
-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 \
|
||||
libvpn_manager_la_SOURCES = \
|
||||
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
|
||||
nm-vpn-connection.c \
|
||||
nm-vpn-connection.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_CPPFLAGS = \
|
||||
$(DBUS_CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED
|
||||
|
||||
|
||||
libvpn_manager_la_LIBADD = $(DBUS_LIBS) \
|
||||
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)
|
File diff suppressed because it is too large
Load Diff
@@ -1,62 +0,0 @@
|
||||
/* 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
|
@@ -1,11 +1,13 @@
|
||||
/* 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
|
||||
@@ -14,244 +16,565 @@
|
||||
*
|
||||
* 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"
|
||||
|
||||
/* Won't change over life of object */
|
||||
G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
char * user_name;
|
||||
char * service_name;
|
||||
|
||||
NMNamedManager *named_manager;
|
||||
|
||||
/* Change when connection is activated/deactivated */
|
||||
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 * vpn_iface;
|
||||
char *tundev;
|
||||
} NMVPNConnectionPrivate;
|
||||
|
||||
#define NM_VPN_CONNECTION_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_CONNECTION, NMVPNConnectionPrivate))
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
static void
|
||||
nm_vpn_connection_set_state (NMVPNConnection *connection,
|
||||
NMVPNConnectionState state)
|
||||
{
|
||||
NMVPNConnectionPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
|
||||
|
||||
priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
if (state != priv->state) {
|
||||
priv->state = state;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
NMVPNConnection *
|
||||
nm_vpn_connection_new (const char *name,
|
||||
const char *user_name,
|
||||
const char *service_name,
|
||||
NMNamedManager *named_manager)
|
||||
const char *dbus_service,
|
||||
NMDevice *parent_device,
|
||||
GHashTable *properties,
|
||||
char **routes)
|
||||
{
|
||||
NMVPNConnection *connection;
|
||||
|
||||
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);
|
||||
g_return_val_if_fail (NM_IS_DEVICE (parent_device), NULL);
|
||||
g_return_val_if_fail (properties != NULL, NULL);
|
||||
|
||||
connection = g_malloc0 (sizeof (NMVPNConnection));
|
||||
connection->refcount = 1;
|
||||
connection = (NMVPNConnection *) g_object_new (NM_TYPE_VPN_CONNECTION, NULL);
|
||||
if (connection) {
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
||||
|
||||
connection->name = g_strdup (name);
|
||||
connection->user_name = g_strdup (user_name);
|
||||
connection->service_name = g_strdup (service_name);
|
||||
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;
|
||||
|
||||
g_object_ref (named_manager);
|
||||
connection->named_manager = named_manager;
|
||||
priv->device_monitor = g_signal_connect (parent_device, "state-changed",
|
||||
G_CALLBACK (device_state_changed),
|
||||
connection);
|
||||
}
|
||||
|
||||
return connection;
|
||||
}
|
||||
|
||||
|
||||
void nm_vpn_connection_ref (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);
|
||||
|
||||
connection->refcount++;
|
||||
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;
|
||||
}
|
||||
|
||||
void nm_vpn_connection_unref (NMVPNConnection *connection)
|
||||
{
|
||||
g_return_if_fail (connection != NULL);
|
||||
|
||||
connection->refcount--;
|
||||
if (connection->refcount <= 0)
|
||||
{
|
||||
g_free (connection->name);
|
||||
g_free (connection->user_name);
|
||||
g_free (connection->service_name);
|
||||
|
||||
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);
|
||||
|
||||
g_object_unref (connection->named_manager);
|
||||
|
||||
memset (connection, 0, sizeof (NMVPNConnection));
|
||||
g_free (connection);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void nm_vpn_connection_activate (NMVPNConnection *connection)
|
||||
static void
|
||||
print_vpn_config (NMIP4Config *config,
|
||||
const char *tundev,
|
||||
const char *login_banner)
|
||||
{
|
||||
g_return_if_fail (connection != NULL);
|
||||
struct in_addr temp_addr;
|
||||
char * dns_domain = NULL;
|
||||
guint32 num;
|
||||
guint32 i;
|
||||
|
||||
/* Nothing done here yet */
|
||||
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 ("-----------------------------------------");
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_vpn_connection_set_config (NMVPNConnection *connection,
|
||||
const char *vpn_iface,
|
||||
NMDevice *dev,
|
||||
NMIP4Config *ip4_config)
|
||||
static void
|
||||
nm_vpn_connection_ip4_config_get (DBusGProxy *proxy,
|
||||
GHashTable *config_hash,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
int num_routes = -1;
|
||||
char ** routes;
|
||||
DBusConnection *dbus_connection;
|
||||
NMDBusManager * dbus_mgr = NULL;
|
||||
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;
|
||||
|
||||
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);
|
||||
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));
|
||||
}
|
||||
|
||||
val = (GValue *) g_hash_table_lookup (config_hash, NM_VPN_PLUGIN_IP4_CONFIG_NBNS);
|
||||
if (val) {
|
||||
GArray *nbns = (GArray *) g_value_get_boxed (val);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_vpn_connection_ip_config_timeout (gpointer user_data)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_vpn_connection_activate (NMVPNConnection *connection)
|
||||
{
|
||||
NMVPNConnectionPrivate *priv;
|
||||
NMDBusManager *dbus_mgr;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
const char *
|
||||
nm_vpn_connection_get_object_path (NMVPNConnection *connection)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
|
||||
|
||||
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;
|
||||
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->object_path;
|
||||
}
|
||||
|
||||
|
||||
void nm_vpn_connection_deactivate (NMVPNConnection *connection)
|
||||
const char *
|
||||
nm_vpn_connection_get_name (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);
|
||||
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->name;
|
||||
}
|
||||
|
||||
if (connection->ip4_config)
|
||||
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;
|
||||
}
|
||||
|
||||
void
|
||||
nm_vpn_connection_fail (NMVPNConnection *connection)
|
||||
{
|
||||
g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
|
||||
|
||||
nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_FAILED);
|
||||
}
|
||||
|
||||
void
|
||||
nm_vpn_connection_disconnect (NMVPNConnection *connection)
|
||||
{
|
||||
g_return_if_fail (NM_IS_VPN_CONNECTION (connection));
|
||||
|
||||
nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_DISCONNECTED);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
impl_vpn_connection_disconnect (NMVPNConnection *connection, GError **err)
|
||||
{
|
||||
nm_vpn_connection_disconnect (connection);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void
|
||||
connection_state_changed (NMVPNConnection *connection, NMVPNConnectionState state)
|
||||
{
|
||||
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 (connection->named_manager, connection->parent_dev,
|
||||
connection->vpn_iface, connection->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 (connection->parent_dev);
|
||||
nm_system_device_set_from_ip4_config (priv->parent_dev);
|
||||
}
|
||||
|
||||
nm_vpn_connection_set_ip4_config (connection, NULL);
|
||||
nm_vpn_connection_set_vpn_iface (connection, NULL);
|
||||
nm_vpn_connection_set_parent_device (connection, NULL);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const char *nm_vpn_connection_get_name (NMVPNConnection *connection)
|
||||
static void
|
||||
nm_vpn_connection_init (NMVPNConnection *connection)
|
||||
{
|
||||
g_return_val_if_fail (connection != NULL, NULL);
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
|
||||
NMDBusManager *dbus_mgr;
|
||||
static guint32 counter = 0;
|
||||
|
||||
return connection->name;
|
||||
priv->state = NM_VPN_CONNECTION_STATE_PREPARE;
|
||||
priv->object_path = g_strdup_printf (NM_DBUS_PATH_VPN_CONNECTION "/%d", counter++);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
const char *nm_vpn_connection_get_user_name (NMVPNConnection *connection)
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
g_return_val_if_fail (connection != NULL, NULL);
|
||||
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
|
||||
|
||||
return connection->user_name;
|
||||
if (priv->parent_dev) {
|
||||
if (priv->device_monitor)
|
||||
g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor);
|
||||
|
||||
g_object_unref (priv->parent_dev);
|
||||
}
|
||||
|
||||
const char *nm_vpn_connection_get_service_name (NMVPNConnection *connection)
|
||||
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)
|
||||
{
|
||||
g_return_val_if_fail (connection != NULL, NULL);
|
||||
|
||||
return connection->service_name;
|
||||
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_set_vpn_iface (NMVPNConnection *con, const char *vpn_iface)
|
||||
static void
|
||||
nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
|
||||
{
|
||||
g_return_if_fail (con != NULL);
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
|
||||
|
||||
if (con->vpn_iface)
|
||||
{
|
||||
g_free (con->vpn_iface);
|
||||
con->vpn_iface = NULL;
|
||||
}
|
||||
|
||||
if (vpn_iface)
|
||||
con->vpn_iface = g_strdup (vpn_iface);
|
||||
}
|
||||
|
||||
static void nm_vpn_connection_set_ip4_config (NMVPNConnection *con, NMIP4Config *ip4_config)
|
||||
{
|
||||
g_return_if_fail (con != NULL);
|
||||
|
||||
if (con->ip4_config)
|
||||
{
|
||||
g_object_unref (con->ip4_config);
|
||||
con->ip4_config = NULL;
|
||||
}
|
||||
|
||||
if (ip4_config)
|
||||
con->ip4_config = g_object_ref (ip4_config);
|
||||
}
|
||||
|
||||
static void nm_vpn_connection_set_parent_device (NMVPNConnection *con, NMDevice *parent_dev)
|
||||
{
|
||||
g_return_if_fail (con != NULL);
|
||||
|
||||
if (con->parent_dev)
|
||||
{
|
||||
g_object_unref (G_OBJECT (con->parent_dev));
|
||||
con->parent_dev = NULL;
|
||||
}
|
||||
|
||||
if (parent_dev)
|
||||
{
|
||||
g_object_ref (G_OBJECT (parent_dev));
|
||||
con->parent_dev = parent_dev;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
@@ -1,11 +1,12 @@
|
||||
/* 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
|
||||
@@ -14,30 +15,54 @@
|
||||
*
|
||||
* 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;
|
||||
|
||||
GType nm_vpn_connection_get_type (void);
|
||||
|
||||
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 *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);
|
||||
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
void nm_vpn_connection_activate (NMVPNConnection *con);
|
||||
void nm_vpn_connection_deactivate (NMVPNConnection *con);
|
||||
|
||||
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 */
|
||||
|
@@ -1,710 +1,245 @@
|
||||
/* 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.
|
||||
*/
|
||||
/* -*- Mode: C; tab-width: 5; indent-tabs-mode: t; c-basic-offset: 5 -*- */
|
||||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#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,
|
||||
static gboolean impl_vpn_manager_connect (NMVPNManager *manager,
|
||||
const char *type,
|
||||
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));
|
||||
GHashTable *properties,
|
||||
const char *device_path,
|
||||
char **routes,
|
||||
char **connection,
|
||||
GError **err);
|
||||
|
||||
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 impl_vpn_manager_get_connections (NMVPNManager *manager,
|
||||
GPtrArray **connections,
|
||||
GError **err);
|
||||
|
||||
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;
|
||||
#include "nm-vpn-manager-glue.h"
|
||||
|
||||
if (!(object_path = dbus_message_get_path (message)))
|
||||
return FALSE;
|
||||
G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT)
|
||||
|
||||
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;
|
||||
typedef struct {
|
||||
NMManager *nm_mgr;
|
||||
NMDBusManager *dbus_mgr;
|
||||
GSList *services;
|
||||
} NMVPNManagerPrivate;
|
||||
|
||||
g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
|
||||
#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate))
|
||||
|
||||
manager = g_slice_new0 (NMVPNManager);
|
||||
manager->nm_manager = g_object_ref (nm_manager);
|
||||
static NMVPNService *
|
||||
nm_vpn_manager_get_service (NMVPNManager *manager, const char *service_name)
|
||||
{
|
||||
GSList *iter;
|
||||
|
||||
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);
|
||||
for (iter = NM_VPN_MANAGER_GET_PRIVATE (manager)->services; iter; iter = iter->next) {
|
||||
NMVPNService *service = NM_VPN_SERVICE (iter->data);
|
||||
|
||||
if (!strcmp (service_name, nm_vpn_service_get_name (service)))
|
||||
return service;
|
||||
}
|
||||
|
||||
if (!nm_dbus_vpn_methods_setup (manager)) {
|
||||
nm_vpn_manager_dispose (manager);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dbus_mgr = nm_dbus_manager_get ();
|
||||
static void
|
||||
remove_service (gpointer data, GObject *service)
|
||||
{
|
||||
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (data);
|
||||
|
||||
g_signal_connect (dbus_mgr,
|
||||
"name-owner-changed",
|
||||
G_CALLBACK (nm_name_owner_changed_handler),
|
||||
manager);
|
||||
|
||||
nm_dbus_manager_register_signal_handler (dbus_mgr,
|
||||
NMI_DBUS_INTERFACE,
|
||||
NULL,
|
||||
nm_dbus_nmi_vpn_signal_handler,
|
||||
manager);
|
||||
|
||||
if (nm_dbus_manager_name_has_owner (dbus_mgr, NMI_DBUS_SERVICE))
|
||||
nm_dbus_vpn_schedule_vpn_connections_update (manager);
|
||||
|
||||
g_object_unref (dbus_mgr);
|
||||
|
||||
return manager;
|
||||
priv->services = g_slist_remove (priv->services, service);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_vpn_manager_dispose
|
||||
*
|
||||
* Release the VPN manager and all its data.
|
||||
*
|
||||
*/
|
||||
void nm_vpn_manager_dispose (NMVPNManager *manager)
|
||||
static void
|
||||
nm_vpn_manager_add_service (NMVPNManager *manager, NMVPNService *service)
|
||||
{
|
||||
g_return_if_fail (manager != NULL);
|
||||
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
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);
|
||||
|
||||
g_hash_table_destroy (manager->service_table);
|
||||
|
||||
g_object_unref (manager->nm_manager);
|
||||
|
||||
memset (manager, 0, sizeof (NMVPNManager));
|
||||
g_slice_free (NMVPNManager, manager);
|
||||
priv->services = g_slist_prepend (priv->services, service);
|
||||
g_object_weak_ref (G_OBJECT (service), remove_service, manager);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 *
|
||||
nm_vpn_manager_connect (NMVPNManager *manager,
|
||||
const char *type,
|
||||
const char *name,
|
||||
NMDevice *device,
|
||||
GHashTable *properties,
|
||||
char **routes)
|
||||
{
|
||||
NMVPNConnection *con = NULL;
|
||||
GSList *elt;
|
||||
NMVPNService *service;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, NULL);
|
||||
g_return_val_if_fail (con_name != NULL, 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 (NM_IS_DEVICE (device), NULL);
|
||||
g_return_val_if_fail (properties != 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 (nm_device_get_state (device) != NM_DEVICE_STATE_ACTIVATED)
|
||||
return NULL;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return con;
|
||||
if (service)
|
||||
return nm_vpn_service_activate (service, name, device, properties, routes);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
NMVPNService *nm_vpn_manager_find_service_by_name (NMVPNManager *manager, const char *service_name)
|
||||
static NMDevice *
|
||||
find_device (NMVPNManager *manager, const char *device_path)
|
||||
{
|
||||
g_return_val_if_fail (manager != NULL, NULL);
|
||||
g_return_val_if_fail (service_name != NULL, NULL);
|
||||
GSList *devices;
|
||||
GSList *iter;
|
||||
|
||||
return (NMVPNService *) g_hash_table_lookup (manager->service_table, service_name);
|
||||
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);
|
||||
|
||||
if (!strcmp (device_path, nm_device_get_dbus_path (device)))
|
||||
return device;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 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)
|
||||
{
|
||||
GSList * list;
|
||||
GSList * elt;
|
||||
NMDevice *device;
|
||||
NMVPNConnection *connection;
|
||||
GHashTable *properties_dup;
|
||||
char **routes_dup;
|
||||
|
||||
g_return_val_if_fail (manager != NULL, NULL);
|
||||
device = find_device (manager, device_path);
|
||||
if (!device)
|
||||
return FALSE;
|
||||
|
||||
list = g_slist_copy (manager->connections);
|
||||
for (elt = list; elt; elt = g_slist_next (elt))
|
||||
nm_vpn_connection_ref (elt->data);
|
||||
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 *connection_path != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
get_connections (gpointer data, gpointer user_data)
|
||||
{
|
||||
NMVPNService *service = NM_VPN_SERVICE (data);
|
||||
GSList **list = (GSList **) user_data;
|
||||
|
||||
*list = g_slist_concat (*list, nm_vpn_service_get_connections (service));
|
||||
}
|
||||
|
||||
GSList *
|
||||
nm_vpn_manager_get_connections (NMVPNManager *manager)
|
||||
{
|
||||
GSList *list = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
|
||||
|
||||
g_slist_foreach (NM_VPN_MANAGER_GET_PRIVATE (manager)->services, get_connections, &list);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
/* 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)))
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_vpn_manager_remove_connection
|
||||
*
|
||||
* Remove a VPN connection.
|
||||
*
|
||||
*/
|
||||
void nm_vpn_manager_remove_connection (NMVPNManager *manager, NMVPNConnection *vpn)
|
||||
{
|
||||
g_return_if_fail (manager != NULL);
|
||||
g_return_if_fail (vpn != NULL);
|
||||
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
manager->connections = g_slist_remove (manager->connections, vpn);
|
||||
nm_vpn_connection_unref (vpn);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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));
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
NMVPNManager *manager = (NMVPNManager *) user_data;
|
||||
|
||||
if (state == NM_DEVICE_STATE_DISCONNECTED)
|
||||
nm_vpn_manager_deactivate_vpn_connection (manager, device);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
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);
|
||||
|
||||
if (!manager->act_req || (dev != nm_vpn_act_request_get_parent_dev (manager->act_req)))
|
||||
return;
|
||||
|
||||
if (manager->device_signal_id) {
|
||||
g_signal_handler_disconnect (dev, manager->device_signal_id);
|
||||
manager->device_signal_id = 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
static gboolean nm_vpn_manager_vpn_activation_failed (gpointer user_data)
|
||||
{
|
||||
NMVPNActRequest * req = (NMVPNActRequest *) user_data;
|
||||
NMVPNManager * manager;
|
||||
|
||||
g_assert (req);
|
||||
|
||||
manager = nm_vpn_act_request_get_manager (req);
|
||||
g_assert (manager);
|
||||
|
||||
if (manager->act_req == req)
|
||||
nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (req));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
static gboolean nm_vpn_manager_vpn_connection_died (gpointer user_data)
|
||||
{
|
||||
NMVPNActRequest * req = (NMVPNActRequest *) user_data;
|
||||
NMVPNManager * manager;
|
||||
|
||||
g_assert (req);
|
||||
|
||||
manager = nm_vpn_act_request_get_manager (req);
|
||||
g_assert (manager);
|
||||
|
||||
if (manager->act_req == req)
|
||||
nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (req));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void nm_vpn_manager_schedule_vpn_connection_died (NMVPNManager *manager, NMVPNActRequest *req)
|
||||
{
|
||||
g_return_if_fail (manager != NULL);
|
||||
g_return_if_fail (req != NULL);
|
||||
|
||||
g_idle_add (nm_vpn_manager_vpn_connection_died, req);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
#define NAME_TAG "name="
|
||||
#define SERVICE_TAG "service="
|
||||
#define PROGRAM_TAG "program="
|
||||
|
||||
static gboolean
|
||||
set_service_from_contents (char ** lines, NMVPNService * service, char **err)
|
||||
impl_vpn_manager_get_connections (NMVPNManager *manager, GPtrArray **connections, GError **err)
|
||||
{
|
||||
int i;
|
||||
guint32 len = g_strv_length (lines);
|
||||
gboolean have_name = FALSE;
|
||||
gboolean have_service = FALSE;
|
||||
gboolean have_program = FALSE;
|
||||
GSList *list;
|
||||
GSList *iter;
|
||||
|
||||
g_return_val_if_fail (err != NULL, FALSE);
|
||||
g_return_val_if_fail (*err == NULL, FALSE);
|
||||
list = nm_vpn_manager_get_connections (manager);
|
||||
*connections = g_ptr_array_sized_new (g_slist_length (list));
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
char * line = lines[i];
|
||||
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))));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
if (!have_name || !have_service || !have_program) {
|
||||
*err = "didn't contain all required tags";
|
||||
return FALSE;
|
||||
}
|
||||
g_slist_free (list);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NMVPNManager *
|
||||
nm_vpn_manager_new (NMManager *nm_manager)
|
||||
{
|
||||
NMVPNManager *manager;
|
||||
|
||||
struct dup_search_data {
|
||||
const char * name;
|
||||
const char * serv_name;
|
||||
gboolean found;
|
||||
};
|
||||
g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
|
||||
|
||||
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 manager;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static void
|
||||
find_dup_name (gpointer key, gpointer value, gpointer user_data)
|
||||
nm_vpn_manager_init (NMVPNManager *manager)
|
||||
{
|
||||
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);
|
||||
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
/* 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;
|
||||
priv->dbus_mgr = nm_dbus_manager_get ();
|
||||
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (priv->dbus_mgr),
|
||||
NM_DBUS_PATH_VPN,
|
||||
G_OBJECT (manager));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
load_services (NMVPNManager *manager, GHashTable *table)
|
||||
finalize (GObject *object)
|
||||
{
|
||||
GDir * vpn_dir;
|
||||
const char *file_name;
|
||||
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
|
||||
|
||||
g_return_if_fail (manager != NULL);
|
||||
g_return_if_fail (table != NULL);
|
||||
g_slist_foreach (priv->services, (GFunc) g_object_unref, NULL);
|
||||
g_object_unref (priv->dbus_mgr);
|
||||
g_object_unref (priv->nm_mgr);
|
||||
|
||||
/* 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;
|
||||
G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
if (!g_file_get_contents (file_path, &contents, NULL, NULL))
|
||||
goto free_file_path;
|
||||
static void
|
||||
nm_vpn_manager_class_init (NMVPNManagerClass *manager_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
|
||||
|
||||
lines = g_strsplit (contents, "\n", 0);
|
||||
g_free (contents);
|
||||
if (!lines)
|
||||
goto free_file_path;
|
||||
g_type_class_add_private (manager_class, sizeof (NMVPNManagerPrivate));
|
||||
|
||||
service = nm_vpn_service_new (manager);
|
||||
success = set_service_from_contents (lines, service, &err);
|
||||
g_strfreev (lines);
|
||||
/* virtual methods */
|
||||
object_class->finalize = finalize;
|
||||
|
||||
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);
|
||||
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class),
|
||||
&dbus_glib_nm_vpn_manager_object_info);
|
||||
}
|
||||
}
|
||||
|
||||
free_file_path:
|
||||
g_free (file_path);
|
||||
}
|
||||
|
||||
g_dir_close (vpn_dir);
|
||||
}
|
||||
|
||||
|
@@ -1,51 +1,40 @@
|
||||
/* 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;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
} NMVPNManagerClass;
|
||||
|
||||
GType nm_vpn_manager_get_type (void);
|
||||
|
||||
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);
|
||||
|
||||
NMVPNActRequest * nm_vpn_manager_get_vpn_act_request (NMVPNManager *manager);
|
||||
NMVPNConnection *nm_vpn_manager_connect (NMVPNManager *manager,
|
||||
const char *type,
|
||||
const char *name,
|
||||
NMDevice *device,
|
||||
GHashTable *properties,
|
||||
char **routes);
|
||||
|
||||
GSList * nm_vpn_manager_vpn_connection_list_copy (NMVPNManager *manager);
|
||||
GSList *nm_vpn_manager_get_connections (NMVPNManager *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_find_connection_by_name (NMVPNManager *manager, const char *con_name);
|
||||
NMVPNService * nm_vpn_manager_find_service_by_name (NMVPNManager *manager, const char *service_name);
|
||||
|
||||
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 */
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -1,54 +1,39 @@
|
||||
/* 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;
|
||||
#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))
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
} NMVPNService;
|
||||
|
||||
NMVPNService * nm_vpn_service_new (NMVPNManager *manager);
|
||||
typedef struct {
|
||||
GObjectClass parent;
|
||||
} NMVPNServiceClass;
|
||||
|
||||
void nm_vpn_service_ref (NMVPNService *service);
|
||||
void nm_vpn_service_unref (NMVPNService *service);
|
||||
GType nm_vpn_service_get_type (void);
|
||||
|
||||
NMVPNService *nm_vpn_service_new (const char *service_name);
|
||||
const char *nm_vpn_service_get_name (NMVPNService *service);
|
||||
void nm_vpn_service_set_name (NMVPNService *service, const char *name);
|
||||
|
||||
const char * nm_vpn_service_get_service_name (NMVPNService *service);
|
||||
void nm_vpn_service_set_service_name (NMVPNService *service, const char *name);
|
||||
NMVPNConnection *nm_vpn_service_activate (NMVPNService *service,
|
||||
const char *name,
|
||||
NMDevice *device,
|
||||
GHashTable *properties,
|
||||
char **routes);
|
||||
|
||||
const char * nm_vpn_service_get_program (NMVPNService *service);
|
||||
void nm_vpn_service_set_program (NMVPNService *service, const char *program);
|
||||
GSList *nm_vpn_service_get_connections (NMVPNService *service);
|
||||
|
||||
NMVPNServiceState nm_vpn_service_get_state (NMVPNService *service);
|
||||
|
||||
void nm_vpn_service_start_connection (NMVPNService *service, NMVPNActRequest *req);
|
||||
void nm_vpn_service_stop_connection (NMVPNService *service, NMVPNActRequest *req);
|
||||
|
||||
#endif
|
||||
#endif /* NM_VPN_VPN_SERVICE_H */
|
||||
|
@@ -4,7 +4,6 @@ INCLUDES = -I${top_srcdir} \
|
||||
-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 = \
|
||||
@@ -28,16 +27,15 @@ nm_tool_LDADD = $(DBUS_LIBS) $(GTHREAD_LIBS) $(HAL_LIBS) \
|
||||
|
||||
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
|
||||
|
Reference in New Issue
Block a user