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:
Tambet Ingo
2007-09-12 16:23:53 +00:00
parent be3a380b08
commit 326d1e8679
48 changed files with 3110 additions and 4104 deletions

View File

@@ -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.

View File

@@ -1,5 +1,4 @@
SUBDIRS = \
utils \
libnm-util \
libnm-glib \
src \

View File

@@ -258,7 +258,6 @@ fi
AC_OUTPUT([
Makefile
include/Makefile
utils/Makefile
src/Makefile
src/named-manager/Makefile
src/vpn-manager/Makefile

View File

@@ -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) \

View File

@@ -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 */

View 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>

View 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>

View 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>

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -1,4 +1,4 @@
#include "nm-utils.h"
#include "nm-dbus-utils.h"
char *
nm_dbus_get_string_property (DBusGProxy *proxy,

View File

@@ -3,6 +3,7 @@
#define NM_SETTINGS_H 1
#include <glib-object.h>
#include <dbus/dbus-glib.h>
G_BEGIN_DECLS

View File

@@ -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);
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;
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);
/* 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;
dbus_g_proxy_add_signal (priv->proxy, "StateChanged", G_TYPE_UINT, G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy,
"StateChanged",
G_CALLBACK (state_changed_proxy),
object,
NULL);
return G_OBJECT (object);
}
gboolean
nm_vpn_connection_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;
}
dbus_g_proxy_call_no_reply (NM_VPN_CONNECTION_GET_PRIVATE (vpn)->proxy,
"deactivateVPNConnection",
G_TYPE_INVALID, G_TYPE_INVALID);
return TRUE;
g_object_unref (priv->proxy);
}
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);
}

View File

@@ -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
View 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;
}

View 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
View 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 ();
}

View 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 */

View File

@@ -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

View File

@@ -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
View 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
View 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 */

View File

@@ -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 \

View File

@@ -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)

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -31,7 +31,6 @@
#include <stdarg.h>
#include "NetworkManager.h"
#include "NetworkManagerMain.h"
#include "nm-device.h"
typedef enum SockType

View File

@@ -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"

View File

@@ -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"

View File

@@ -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;

View File

@@ -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);

View File

@@ -29,7 +29,6 @@
#include "nm-device.h"
#include "NetworkManagerAP.h"
#include "NetworkManagerMain.h"
struct NMAccessPointList;

View File

@@ -26,7 +26,6 @@
#include <net/ethernet.h>
#include "nm-device.h"
#include "NetworkManagerMain.h"
G_BEGIN_DECLS

View File

@@ -2,7 +2,6 @@
#define NM_HAL_MANAGER_H
#include "nm-manager.h"
#include "NetworkManagerMain.h"
typedef struct _NMHalManager NMHalManager;

View File

@@ -30,7 +30,6 @@
#include "nm-logging.h"
#include "nm-utils.h"
#include "NetworkManagerMain.h"
static void
fallback_get_backtrace (void)

View File

@@ -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

View File

@@ -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

View File

@@ -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 */
char * name;
char * user_name;
char * service_name;
G_DEFINE_TYPE (NMVPNConnection, nm_vpn_connection, G_TYPE_OBJECT)
NMNamedManager *named_manager;
typedef struct {
char *name;
char *dbus_service;
GHashTable *properties;
char **routes;
NMDevice *parent_dev;
char *object_path;
/* Change when connection is activated/deactivated */
NMDevice * parent_dev;
NMIP4Config * ip4_config;
char * vpn_iface;
NMVPNConnectionState state;
gulong device_monitor;
DBusGProxy *proxy;
guint ipconfig_timeout;
NMIP4Config *ip4_config;
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);
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);
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_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;
}
/* 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);
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);
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;
/* 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);
out:
return success;
/* Ip4Config signal */
dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE, G_TYPE_VALUE, G_TYPE_INVALID);
dbus_g_proxy_add_signal (priv->proxy, "Ip4Config",
dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
G_TYPE_INVALID);
dbus_g_proxy_connect_signal (priv->proxy, "Ip4Config",
G_CALLBACK (nm_vpn_connection_ip4_config_get),
connection, NULL);
org_freedesktop_NetworkManager_VPN_Plugin_connect_async (priv->proxy,
priv->properties,
priv->routes,
nm_vpn_connection_connect_cb,
connection);
nm_vpn_connection_set_state (connection, NM_VPN_CONNECTION_STATE_CONNECT);
}
void nm_vpn_connection_deactivate (NMVPNConnection *connection)
const char *
nm_vpn_connection_get_object_path (NMVPNConnection *connection)
{
g_return_if_fail (connection != NULL);
g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
if (connection->vpn_iface)
{
nm_system_device_set_up_down_with_iface (connection->vpn_iface, FALSE);
nm_system_device_flush_routes_with_iface (connection->vpn_iface);
nm_system_device_flush_addresses_with_iface (connection->vpn_iface);
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->object_path;
}
const char *
nm_vpn_connection_get_name (NMVPNConnection *connection)
{
g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NULL);
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->name;
}
NMVPNConnectionState
nm_vpn_connection_get_state (NMVPNConnection *connection)
{
g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), NM_VPN_CONNECTION_STATE_UNKNOWN);
return NM_VPN_CONNECTION_GET_PRIVATE (connection)->state;
}
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);
}
if (connection->ip4_config)
{
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);
}
const char *nm_vpn_connection_get_name (NMVPNConnection *connection)
{
g_return_val_if_fail (connection != NULL, NULL);
return connection->name;
}
const char *nm_vpn_connection_get_user_name (NMVPNConnection *connection)
{
g_return_val_if_fail (connection != NULL, NULL);
return connection->user_name;
}
const char *nm_vpn_connection_get_service_name (NMVPNConnection *connection)
{
g_return_val_if_fail (connection != NULL, NULL);
return connection->service_name;
}
static void nm_vpn_connection_set_vpn_iface (NMVPNConnection *con, const char *vpn_iface)
{
g_return_if_fail (con != NULL);
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;
break;
default:
break;
}
}
static void
nm_vpn_connection_init (NMVPNConnection *connection)
{
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection);
NMDBusManager *dbus_mgr;
static guint32 counter = 0;
priv->state = NM_VPN_CONNECTION_STATE_PREPARE;
priv->object_path = g_strdup_printf (NM_DBUS_PATH_VPN_CONNECTION "/%d", counter++);
dbus_mgr = nm_dbus_manager_get ();
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (dbus_mgr),
priv->object_path,
G_OBJECT (connection));
g_object_unref (dbus_mgr);
}
static void
finalize (GObject *object)
{
NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (object);
if (priv->parent_dev) {
if (priv->device_monitor)
g_signal_handler_disconnect (priv->parent_dev, priv->device_monitor);
g_object_unref (priv->parent_dev);
}
g_free (priv->tundev);
if (priv->ip4_config)
g_object_unref (priv->ip4_config);
if (priv->ipconfig_timeout)
g_source_remove (priv->ipconfig_timeout);
if (priv->proxy)
g_object_unref (priv->proxy);
g_free (priv->name);
g_free (priv->dbus_service);
g_hash_table_unref (priv->properties);
g_strfreev (priv->routes);
g_free (priv->object_path);
G_OBJECT_CLASS (nm_vpn_connection_parent_class)->finalize (object);
}
static void
get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_NAME:
g_value_set_string (value, nm_vpn_connection_get_name (NM_VPN_CONNECTION (object)));
break;
case PROP_STATE:
g_value_set_uint (value, nm_vpn_connection_get_state (NM_VPN_CONNECTION (object)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (connection_class);
g_type_class_add_private (connection_class, sizeof (NMVPNConnectionPrivate));
/* virtual methods */
connection_class->state_changed = connection_state_changed;
object_class->get_property = get_property;
object_class->finalize = finalize;
/* properties */
g_object_class_install_property
(object_class, PROP_NAME,
g_param_spec_string (NM_VPN_CONNECTION_NAME,
"Name",
"Connection name",
NULL,
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_STATE,
g_param_spec_uint (NM_VPN_CONNECTION_STATE,
"State",
"Current state",
NM_VPN_CONNECTION_STATE_UNKNOWN,
NM_VPN_CONNECTION_STATE_DISCONNECTED,
NM_VPN_CONNECTION_STATE_UNKNOWN,
G_PARAM_READABLE));
/* signals */
signals[STATE_CHANGED] =
g_signal_new ("state-changed",
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (NMVPNConnectionClass, state_changed),
NULL, NULL,
g_cclosure_marshal_VOID__UINT,
G_TYPE_NONE, 1,
G_TYPE_UINT);
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (connection_class),
&dbus_glib_nm_vpn_connection_object_info);
}

View File

@@ -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 */

View File

@@ -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"
static gboolean impl_vpn_manager_connect (NMVPNManager *manager,
const char *type,
const char *name,
GHashTable *properties,
const char *device_path,
char **routes,
char **connection,
GError **err);
struct NMVPNManager
static gboolean impl_vpn_manager_get_connections (NMVPNManager *manager,
GPtrArray **connections,
GError **err);
#include "nm-vpn-manager-glue.h"
G_DEFINE_TYPE (NMVPNManager, nm_vpn_manager, G_TYPE_OBJECT)
typedef struct {
NMManager *nm_mgr;
NMDBusManager *dbus_mgr;
GSList *services;
} NMVPNManagerPrivate;
#define NM_VPN_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_VPN_MANAGER, NMVPNManagerPrivate))
static NMVPNService *
nm_vpn_manager_get_service (NMVPNManager *manager, const char *service_name)
{
NMManager * nm_manager;
GHashTable * service_table;
GSList * connections;
GSList *iter;
NMVPNActRequest * act_req;
gulong device_signal_id;
};
for (iter = NM_VPN_MANAGER_GET_PRIVATE (manager)->services; iter; iter = iter->next) {
NMVPNService *service = NM_VPN_SERVICE (iter->data);
static void load_services (NMVPNManager *manager, GHashTable *table);
if (!strcmp (service_name, nm_vpn_service_get_name (service)))
return service;
}
return NULL;
}
static void
nm_name_owner_changed_handler (NMDBusManager *mgr,
const char *name,
const char *old,
const char *new,
gpointer user_data)
remove_service (gpointer data, GObject *service)
{
NMVPNManager *vpn_manager = (NMVPNManager *) user_data;
gboolean old_owner_good = (old && (strlen (old) > 0));
gboolean new_owner_good = (new && (strlen (new) > 0));
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (data);
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);
priv->services = g_slist_remove (priv->services, service);
}
static void
nm_vpn_manager_add_service (NMVPNManager *manager, NMVPNService *service)
{
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
priv->services = g_slist_prepend (priv->services, service);
g_object_weak_ref (G_OBJECT (service), remove_service, manager);
}
NMVPNConnection *
nm_vpn_manager_connect (NMVPNManager *manager,
const char *type,
const char *name,
NMDevice *device,
GHashTable *properties,
char **routes)
{
NMVPNService *service;
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
g_return_val_if_fail (type != NULL, NULL);
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
g_return_val_if_fail (properties != NULL, 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);
}
if (service)
return nm_vpn_service_activate (service, name, device, properties, routes);
return NULL;
}
static NMDevice *
find_device (NMVPNManager *manager, const char *device_path)
{
GSList *devices;
GSList *iter;
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;
}
static gboolean
nm_dbus_nmi_vpn_signal_handler (DBusConnection *connection,
DBusMessage *message,
gpointer user_data)
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)
{
NMVPNManager *manager = (NMVPNManager *) user_data;
const char * object_path;
gboolean handled = FALSE;
NMDevice *device;
NMVPNConnection *connection;
GHashTable *properties_dup;
char **routes_dup;
if (!(object_path = dbus_message_get_path (message)))
device = find_device (manager, device_path);
if (!device)
return FALSE;
if (strcmp (object_path, NMI_DBUS_PATH) != 0)
return FALSE;
properties_dup = nm_utils_gvalue_hash_dup (properties);
routes_dup = g_strdupv (routes);
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;
}
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 handled;
return *connection_path != NULL;
}
/*
* nm_vpn_manager_new
*
* Create a new VPN manager instance.
*
*/
NMVPNManager *nm_vpn_manager_new (NMManager *nm_manager)
static void
get_connections (gpointer data, gpointer user_data)
{
NMVPNManager * manager;
NMDBusManager * dbus_mgr;
NMVPNService *service = NM_VPN_SERVICE (data);
GSList **list = (GSList **) user_data;
g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
manager = g_slice_new0 (NMVPNManager);
manager->nm_manager = g_object_ref (nm_manager);
manager->service_table = g_hash_table_new_full (g_str_hash,
g_str_equal,
NULL,
(GDestroyNotify) nm_vpn_service_unref);
load_services (manager, manager->service_table);
if (!nm_dbus_vpn_methods_setup (manager)) {
nm_vpn_manager_dispose (manager);
return NULL;
}
dbus_mgr = nm_dbus_manager_get ();
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;
*list = g_slist_concat (*list, nm_vpn_service_get_connections (service));
}
/*
* nm_vpn_manager_dispose
*
* Release the VPN manager and all its data.
*
*/
void nm_vpn_manager_dispose (NMVPNManager *manager)
GSList *
nm_vpn_manager_get_connections (NMVPNManager *manager)
{
g_return_if_fail (manager != NULL);
GSList *list = NULL;
if (manager->act_req)
nm_vpn_manager_deactivate_vpn_connection (manager, nm_vpn_act_request_get_parent_dev (manager->act_req));
g_return_val_if_fail (NM_IS_VPN_MANAGER (manager), NULL);
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);
}
/*
* nm_vpn_manager_find_connection_by_name
*
* Return the NMVPNConnection object associated with a particular name.
*
*/
NMVPNConnection *nm_vpn_manager_find_connection_by_name (NMVPNManager *manager, const char *con_name)
{
NMVPNConnection *con = NULL;
GSList *elt;
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (con_name != NULL, NULL);
for (elt = manager->connections; elt; elt = g_slist_next (elt))
{
if ((con = (NMVPNConnection *)(elt->data)))
{
const char *search_name = nm_vpn_connection_get_name (con);
if (search_name && (strcmp (con_name, search_name) == 0))
break;
}
con = NULL;
}
return con;
}
NMVPNService *nm_vpn_manager_find_service_by_name (NMVPNManager *manager, const char *service_name)
{
g_return_val_if_fail (manager != NULL, NULL);
g_return_val_if_fail (service_name != NULL, NULL);
return (NMVPNService *) g_hash_table_lookup (manager->service_table, service_name);
}
/*
* 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)
{
GSList * list;
GSList * elt;
g_return_val_if_fail (manager != NULL, NULL);
list = g_slist_copy (manager->connections);
for (elt = list; elt; elt = g_slist_next (elt))
nm_vpn_connection_ref (elt->data);
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;
}
struct dup_search_data {
const char * name;
const char * serv_name;
gboolean found;
};
static void
find_dup_name (gpointer key, gpointer value, gpointer user_data)
NMVPNManager *
nm_vpn_manager_new (NMManager *nm_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);
NMVPNManager *manager;
/* already found a dupe, do nothing */
if (data->found)
return;
g_return_val_if_fail (NM_IS_MANAGER (nm_manager), NULL);
if (strcmp (serv_name, data->serv_name) == 0)
data->found = TRUE;
else if (strcmp (name, data->name) == 0)
data->found = TRUE;
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
load_services (NMVPNManager *manager, GHashTable *table)
nm_vpn_manager_init (NMVPNManager *manager)
{
GDir * vpn_dir;
const char *file_name;
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (manager);
g_return_if_fail (manager != NULL);
g_return_if_fail (table != NULL);
/* Load allowed service names */
if (!(vpn_dir = g_dir_open (VPN_SERVICE_FILE_PATH, 0, NULL)))
return;
while ((file_name = g_dir_read_name (vpn_dir))) {
char * file_path;
char * contents;
char ** lines;
NMVPNService * service;
char * err = NULL;
gboolean success;
file_path = g_strdup_printf (VPN_SERVICE_FILE_PATH"/%s", file_name);
/* Check for the .name extension */
if (strcmp (file_name + strlen (file_name) - 5, ".name") != 0) {
nm_warning ("Error loading VPN service file '%s': doesn't "
"end with .name", file_path);
goto free_file_path;
}
if (!g_file_get_contents (file_path, &contents, NULL, NULL))
goto free_file_path;
lines = g_strsplit (contents, "\n", 0);
g_free (contents);
if (!lines)
goto free_file_path;
service = nm_vpn_service_new (manager);
success = set_service_from_contents (lines, service, &err);
g_strfreev (lines);
if (!success) {
nm_warning ("Error loading VPN service file '%s': %s.",
file_path, err);
nm_vpn_service_unref (service);
} else {
const char * serv_name = nm_vpn_service_get_service_name (service);
const char * name = nm_vpn_service_get_name (service);
struct dup_search_data dup_data = { name, serv_name, FALSE };
/* Check for duplicates */
g_hash_table_foreach (table, find_dup_name, &dup_data);
if (dup_data.found) {
nm_warning ("Ignoring duplicate VPN service '%s' (%s) from %s.",
name, serv_name, file_path);
} else {
/* All good, add it */
nm_info ("New VPN service '%s' (%s).", name, serv_name);
g_hash_table_insert (table, (char *) serv_name, service);
}
}
free_file_path:
g_free (file_path);
}
g_dir_close (vpn_dir);
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
finalize (GObject *object)
{
NMVPNManagerPrivate *priv = NM_VPN_MANAGER_GET_PRIVATE (object);
g_slist_foreach (priv->services, (GFunc) g_object_unref, NULL);
g_object_unref (priv->dbus_mgr);
g_object_unref (priv->nm_mgr);
G_OBJECT_CLASS (nm_vpn_manager_parent_class)->finalize (object);
}
static void
nm_vpn_manager_class_init (NMVPNManagerClass *manager_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
g_type_class_add_private (manager_class, sizeof (NMVPNManagerPrivate));
/* virtual methods */
object_class->finalize = finalize;
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (manager_class),
&dbus_glib_nm_vpn_manager_object_info);
}

View File

@@ -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_connect (NMVPNManager *manager,
const char *type,
const char *name,
NMDevice *device,
GHashTable *properties,
char **routes);
GSList *nm_vpn_manager_get_connections (NMVPNManager *manager);
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);
GSList * nm_vpn_manager_vpn_connection_list_copy (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

View File

@@ -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);
const char * nm_vpn_service_get_name (NMVPNService *service);
void nm_vpn_service_set_name (NMVPNService *service, const char *name);
NMVPNService *nm_vpn_service_new (const char *service_name);
const char *nm_vpn_service_get_name (NMVPNService *service);
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 */

View File

@@ -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