reimplemented dbus plugin for NetworkManager 0.7, renamed to nm
authorMartin Willi <martin@strongswan.org>
Thu, 31 Jul 2008 11:16:14 +0000 (11:16 -0000)
committerMartin Willi <martin@strongswan.org>
Thu, 31 Jul 2008 11:16:14 +0000 (11:16 -0000)
15 files changed:
configure.in
src/charon/Makefile.am
src/charon/plugins/dbus/Makefile.am [deleted file]
src/charon/plugins/dbus/dbus.c [deleted file]
src/charon/plugins/dbus/dbus.h [deleted file]
src/charon/plugins/dbus/nm-strongswan.conf [deleted file]
src/charon/plugins/dbus/nm-strongswan.name [deleted file]
src/charon/plugins/dbus/nm_applet_auth.c [deleted file]
src/charon/plugins/dbus/nm_applet_gui.c [deleted file]
src/charon/plugins/dbus/nm_applet_gui.xml [deleted file]
src/charon/plugins/nm/Makefile.am [new file with mode: 0644]
src/charon/plugins/nm/nm_plugin.c [new file with mode: 0644]
src/charon/plugins/nm/nm_plugin.h [new file with mode: 0644]
src/charon/plugins/nm/nm_service.c [new file with mode: 0644]
src/charon/plugins/nm/nm_service.h [new file with mode: 0644]

index 9531bb3..8c790eb 100644 (file)
@@ -563,6 +563,14 @@ AC_ARG_ENABLE(
        fi]
 )
 
+AC_ARG_ENABLE(
+       [nm],
+       AS_HELP_STRING([--enable-nm],[enable NetworkManager plugin (default is NO).]),
+       [if test x$enableval = xyes; then
+               nm=true
+       fi]
+)
+
 dnl =========================
 dnl  check required programs
 dnl =========================
@@ -705,6 +713,12 @@ if test x$uci = xtrue; then
        AC_CHECK_HEADER([uci.h],,[AC_MSG_ERROR([UCI header uci.h not found!])])
 fi
 
+if test x$nm = xtrue; then
+       PKG_CHECK_MODULES(nm, [NetworkManager libnm_glib_vpn gthread-2.0])
+       AC_SUBST(nm_CFLAGS)
+       AC_SUBST(nm_LIBS)
+fi
+
 dnl ======================================
 dnl  collect all plugins for libstrongswan
 dnl ======================================
@@ -798,6 +812,7 @@ dnl ==============
 AM_CONDITIONAL(USE_STROKE, test x$stroke = xtrue)
 AM_CONDITIONAL(USE_MEDSRV, test x$medsrv = xtrue)
 AM_CONDITIONAL(USE_MEDCLI, test x$medcli = xtrue)
+AM_CONDITIONAL(USE_NM, test x$nm = xtrue)
 AM_CONDITIONAL(USE_UCI, test x$uci = xtrue)
 AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
 AM_CONDITIONAL(USE_SQL, test x$sql = xtrue)
@@ -876,6 +891,7 @@ AC_OUTPUT(
        src/charon/plugins/sql/Makefile
        src/charon/plugins/medsrv/Makefile
        src/charon/plugins/medcli/Makefile
+       src/charon/plugins/nm/Makefile
        src/charon/plugins/uci/Makefile
        src/charon/plugins/stroke/Makefile
        src/charon/plugins/unit_tester/Makefile
index 782b2a9..3ea21a0 100644 (file)
@@ -180,6 +180,11 @@ if USE_MEDCLI
   PLUGINS += medcli
 endif
 
+if USE_NM
+  SUBDIRS += plugins/nm
+  PLUGINS += nm
+endif
+
 if USE_UCI
   SUBDIRS += plugins/uci
   PLUGINS += uci
diff --git a/src/charon/plugins/dbus/Makefile.am b/src/charon/plugins/dbus/Makefile.am
deleted file mode 100644 (file)
index 05f3253..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-
-INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${dbus_CFLAGS}
-
-AM_CFLAGS = -rdynamic
-
-plugin_LTLIBRARIES = libstrongswan-dbus.la
-
-libstrongswan_dbus_la_SOURCES = dbus.h dbus.c
-libstrongswan_dbus_la_LDFLAGS = -module
-libstrongswan_dbus_la_LIBADD = ${dbus_LIBS}
-
diff --git a/src/charon/plugins/dbus/dbus.c b/src/charon/plugins/dbus/dbus.c
deleted file mode 100644 (file)
index 97bd3b3..0000000
+++ /dev/null
@@ -1,422 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * $Id$
- */
-
-#define DBUS_API_SUBJECT_TO_CHANGE
-#include <dbus/dbus.h>
-#include <NetworkManager/NetworkManager.h>
-#include <NetworkManager/NetworkManagerVPN.h>
-#include <stdlib.h>
-
-#include "dbus.h"
-
-#include <library.h>
-#include <daemon.h>
-#include <processing/jobs/callback_job.h>
-
-
-#define NM_DBUS_SERVICE_STRONG "org.freedesktop.NetworkManager.strongswan"
-#define NM_dbus_STRONG "org.freedesktop.NetworkManager.strongswan"
-#define NM_DBUS_PATH_STRONG "/org/freedesktop/NetworkManager/strongswan"
-
-typedef struct private_dbus_t private_dbus_t;
-
-/**
- * Private data of an dbus_t object.
- */
-struct private_dbus_t {
-
-       /**
-        * Public part of dbus_t object.
-        */
-       dbus_t public;
-       
-       /**
-        * DBUS connection
-        */
-       DBusConnection* conn;
-       
-       /**
-        * error value used here and there
-        */
-       DBusError err;
-       
-       /**
-        * state of the daemon
-        */
-       NMVPNState state;
-       
-       /**
-        * job accepting stroke messages
-        */
-       callback_job_t *job;
-       
-       /**
-        * name of the currently active connection
-        */
-       char *name;
-};
-
-/**
- * set daemon state and send StateChange signal to the bus
- */
-static void set_state(private_dbus_t *this, NMVPNState state)
-{
-       DBusMessage* msg;
-
-       msg = dbus_message_new_signal(NM_DBUS_PATH_STRONG, NM_dbus_STRONG, NM_DBUS_VPN_SIGNAL_STATE_CHANGE);
-
-       if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &this->state,
-                                                         DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID) ||
-               !dbus_connection_send(this->conn, msg, NULL))
-       {
-               DBG1(DBG_CFG, "unable to send DBUS StateChange signal");
-       }
-       dbus_connection_flush(this->conn);
-       dbus_message_unref(msg);
-       this->state = state;
-}
-
-
-/**
- * get the child_cfg with the same name as the peer cfg
- */
-static child_cfg_t* get_child_from_peer(peer_cfg_t *peer_cfg, char *name)
-{
-       child_cfg_t *current, *found = NULL;
-       iterator_t *iterator;
-       
-       iterator = peer_cfg->create_child_cfg_iterator(peer_cfg);
-       while (iterator->iterate(iterator, (void**)&current))
-       {
-               if (streq(current->get_name(current), name))
-               {
-                       found = current;
-                       found->get_ref(found);
-                       break;
-               }
-       }
-       iterator->destroy(iterator);
-       return found;
-}
-
-
-/**
- * process NetworkManagers startConnection method call
- */
-static bool start_connection(private_dbus_t *this, DBusMessage* msg)
-{
-       DBusMessage *reply, *signal;
-       char *name, *user, **data, **passwords, **routes;
-       int data_count, passwords_count, routes_count;
-       u_int32_t me, other, p2p, netmask, mss;
-       char *dev, *domain, *banner;
-       const dbus_int32_t array[] = {};
-       const dbus_int32_t *varray = array;
-       peer_cfg_t *peer_cfg;
-       child_cfg_t *child_cfg;
-       status_t status = FAILED;
-       
-       dbus_error_free(&this->err);
-       
-       if (!dbus_message_get_args(msg, &this->err,
-                        DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &user,
-                        DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &passwords, &passwords_count,
-                        DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &data, &data_count,
-                        DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &routes, &routes_count,
-                        DBUS_TYPE_INVALID))
-       {
-               return FALSE;
-       }
-       set_state(this, NM_VPN_STATE_STARTING);
-       
-       peer_cfg = charon->backends->get_peer_cfg_by_name(charon->backends, name);
-       if (peer_cfg)
-       {
-               free(this->name);
-               this->name = strdup(peer_cfg->get_name(peer_cfg));
-               child_cfg = get_child_from_peer(peer_cfg, name);
-               if (child_cfg)
-               {
-                       status = charon->controller->initiate(charon->controller,
-                                               peer_cfg, child_cfg, controller_cb_empty, NULL);
-               }
-               else
-               {
-                       peer_cfg->destroy(peer_cfg);
-               }
-       }
-       reply = dbus_message_new_method_return(msg);
-       dbus_connection_send(this->conn, reply, NULL);
-       dbus_message_unref(reply);
-       
-       if (status == SUCCESS)
-       {
-       
-               set_state(this, NM_VPN_STATE_STARTED);
-               signal = dbus_message_new_signal(NM_DBUS_PATH_STRONG,
-                                                                                NM_dbus_STRONG,
-                                                                                NM_DBUS_VPN_SIGNAL_IP4_CONFIG);
-               me = other = p2p = mss = netmask = 0;
-               dev = domain = banner = "";
-               if (dbus_message_append_args(signal,
-                                               DBUS_TYPE_UINT32, &other,
-                                               DBUS_TYPE_STRING, &dev,
-                                               DBUS_TYPE_UINT32, &me,
-                                               DBUS_TYPE_UINT32, &p2p,
-                                               DBUS_TYPE_UINT32, &netmask,
-                                               DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &varray, 0,
-                                               DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &varray, 0,
-                                               DBUS_TYPE_UINT32, &mss,
-                                               DBUS_TYPE_STRING, &domain,
-                                               DBUS_TYPE_STRING, &banner, DBUS_TYPE_INVALID))
-               {
-                       dbus_connection_send(this->conn, signal, NULL);
-               }                                                
-               dbus_message_unref(signal);
-       }
-       else
-       {
-               set_state(this, NM_VPN_STATE_STOPPED);
-       }
-       
-       dbus_connection_flush(this->conn);
-       return TRUE;
-}
-
-/**
- * process NetworkManagers stopConnection method call
- */
-static bool stop_connection(private_dbus_t *this, DBusMessage* msg)
-{
-       u_int32_t id;
-       enumerator_t *enumerator;
-       ike_sa_t *ike_sa;
-       
-       if (this->name == NULL)
-       {
-               return FALSE;
-       }
-       
-       dbus_error_free(&this->err);
-       
-       set_state(this, NM_VPN_STATE_STOPPING);
-       
-       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
-       while (enumerator->enumerate(enumerator, (void**)&ike_sa))
-       {
-               child_sa_t *child_sa;
-               iterator_t *children;
-               
-               if (this->name && streq(this->name, ike_sa->get_name(ike_sa)))
-               {
-                       id = ike_sa->get_unique_id(ike_sa);
-                       enumerator->destroy(enumerator);
-                       charon->controller->terminate_ike(charon->controller, id, NULL, NULL);
-                       set_state(this, NM_VPN_STATE_STOPPED);
-                       return TRUE;;
-               }
-               children = ike_sa->create_child_sa_iterator(ike_sa);
-               while (children->iterate(children, (void**)&child_sa))
-               {
-                       if (this->name && streq(this->name, child_sa->get_name(child_sa)))
-                       {
-                               id = child_sa->get_reqid(child_sa);
-                               children->destroy(children);
-                               enumerator->destroy(enumerator);
-                               charon->controller->terminate_child(charon->controller, id, NULL, NULL);
-                               set_state(this, NM_VPN_STATE_STOPPED);
-                               return TRUE;
-                       }
-               }
-               children->destroy(children);
-       }
-       enumerator->destroy(enumerator);
-       set_state(this, NM_VPN_STATE_STOPPED);
-       return TRUE;
-}
-
-/**
- * process NetworkManagers getState method call
- */
-static bool get_state(private_dbus_t *this, DBusMessage* msg)
-{
-       DBusMessage* reply;
-       reply = dbus_message_new_method_return(msg);
-       if (!reply || !dbus_message_append_args(reply,
-                                                                                       DBUS_TYPE_UINT32, &this->state,
-                                                                                       DBUS_TYPE_INVALID))
-       {
-               return FALSE;
-       }
-       dbus_connection_send(this->conn, reply, NULL);
-       return TRUE;
-}
-
-/**
- * Handle incoming messages
- */
-static DBusHandlerResult message_handler(DBusConnection *con, DBusMessage *msg,
-                                                                                private_dbus_t *this)
-{
-       bool handled;
-
-       if (dbus_message_is_method_call(msg, NM_dbus_STRONG,
-                                                                       "startConnection"))
-       {
-               handled = start_connection(this, msg);
-       }
-       else if (dbus_message_is_method_call(msg, NM_dbus_STRONG,
-                                                                                "stopConnection"))
-       {
-               handled = stop_connection(this, msg);
-       }
-       else if (dbus_message_is_method_call(msg, NM_dbus_STRONG,
-                                                                                "getState"))
-       {
-               handled = get_state(this, msg);
-       }
-       else
-       {
-               DBG1(DBG_CFG, "ignoring DBUS message %s.%s",
-                        dbus_message_get_interface(msg), dbus_message_get_member(msg));
-               handled = FALSE;
-       }
-       
-       if (handled)
-       {
-               return DBUS_HANDLER_RESULT_HANDLED;
-       }
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-}
-
-/**
- * Handle received signals
-
-static DBusHandlerResult signal_handler(DBusConnection *con, DBusMessage *msg,
-                                                                               private_dbus_t *this)
-{
-       bool handled;
-
-       if (dbus_message_is_signal(msg, NM_dbus, "VPNConnectionStateChange"))
-       {
-               NMVPNState state;
-               char *name;
-               
-               if (dbus_message_get_args(msg, &this->err, DBUS_TYPE_STRING, &name, 
-                                                                 DBUS_TYPE_UINT32, &state, DBUS_TYPE_INVALID))
-               {
-                       DBG1(DBG_CFG, "got state %d for %s", state, name);
-               }
-               handled = TRUE;
-       }
-       else
-       {
-               DBG1(DBG_CFG, "ignoring DBUS signal %s.%s",
-                        dbus_message_get_interface(msg), dbus_message_get_member(msg));
-               handled = FALSE;
-       }
-       if (handled)
-       {
-               return DBUS_HANDLER_RESULT_HANDLED;
-       }
-       return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
-} */
-
-/**
- * dispatcher function processed by a seperate thread
- */
-static job_requeue_t dispatch(private_dbus_t *this)
-{
-       if (dbus_connection_read_write_dispatch(this->conn, -1))
-       {
-               return JOB_REQUEUE_DIRECT;
-       }
-       return JOB_REQUEUE_NONE;
-}
-
-/**
- * Implementation of interface_t.destroy.
- */
-static void destroy(private_dbus_t *this)
-{
-       this->job->cancel(this->job);
-       dbus_connection_close(this->conn);
-       dbus_error_free(&this->err);
-       dbus_shutdown();
-       free(this->name);
-       free(this);
-}
-
-/*
- * Described in header file
- */
-plugin_t *plugin_create()
-{
-       int ret;
-       DBusObjectPathVTable v = {NULL, (void*)&message_handler, NULL, NULL, NULL, NULL};
-       private_dbus_t *this = malloc_thing(private_dbus_t);
-  
-       this->public.plugin.destroy = (void (*)(plugin_t*))destroy;
-       
-       dbus_error_init(&this->err); 
-       this->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &this->err);
-       if (dbus_error_is_set(&this->err))
-       { 
-               DBG1(DBG_CFG, "unable to open DBUS connection: %s", this->err.message); 
-               charon->kill(charon, "DBUS initialization failed");
-       }
-       dbus_connection_set_exit_on_disconnect(this->conn, FALSE);
-       
-       ret = dbus_bus_request_name(this->conn, NM_DBUS_SERVICE_STRONG,
-                                                           DBUS_NAME_FLAG_REPLACE_EXISTING , &this->err);
-       if (dbus_error_is_set(&this->err))
-       {
-               DBG1(DBG_CFG, "unable to set DBUS name: %s", this->err.message);
-               charon->kill(charon, "unable to set DBUS name");
-       }
-       if (ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
-       {
-               charon->kill(charon, "DBUS name already owned");
-       }
-       if (!dbus_connection_register_object_path(this->conn, NM_DBUS_PATH_STRONG, &v, this))
-    {
-               charon->kill(charon, "unable to register DBUS message handler");
-    }
-       /*
-       if (!dbus_connection_add_filter(this->conn, (void*)signal_handler, this, NULL))
-       {
-               charon->kill(charon, "unable to register DBUS signal handler");
-       }
-       
-       dbus_bus_add_match(this->conn, "type='signal', "
-                                          "interface='" NM_dbus_VPN "',"
-                                          "path='" NM_DBUS_PATH_VPN "'", &this->err);
-       if (dbus_error_is_set (&this->err))
-       {
-               charon->kill(charon, "unable to add DBUS signal match");
-       }*/
-
-       this->name = NULL;
-       this->state = NM_VPN_STATE_INIT;
-       set_state(this, NM_VPN_STATE_STOPPED);
-
-       this->job = callback_job_create((callback_job_cb_t)dispatch, this, NULL, NULL);
-       charon->processor->queue_job(charon->processor, (job_t*)this->job);
-
-       return &this->public.plugin;
-}
-
diff --git a/src/charon/plugins/dbus/dbus.h b/src/charon/plugins/dbus/dbus.h
deleted file mode 100644 (file)
index e5bc2d2..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2007-2008 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-/**
- * @defgroup dbus dbus
- * @ingroup cplugins
- *
- * @defgroup dbus_i dbus
- * @{ @ingroup dbus
- */
-
-#ifndef DBUS_H_
-#define DBUS_H_
-
-#include <plugins/plugin.h>
-
-typedef struct dbus_t dbus_t;
-
-/**
- * NetworkManager DBUS control plugin.
- *
- * This plugin uses a DBUS connection. It is designed to work in conjuction
- * with NetworkManager to configure and control the daemon.
- */
-struct dbus_t {
-
-       /**
-        * implements plugin interface
-        */
-       plugin_t plugin;
-};
-
-/**
- * Create a dbus plugin instance.
- */
-plugin_t *plugin_create();
-
-#endif /* DBUS_H_ @}*/
diff --git a/src/charon/plugins/dbus/nm-strongswan.conf b/src/charon/plugins/dbus/nm-strongswan.conf
deleted file mode 100644 (file)
index 0206175..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE busconfig PUBLIC
- "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
-<busconfig>
-        <policy user="root">
-                <allow own="org.freedesktop.NetworkManager.strongswan"/>
-
-                <allow send_destination="org.freedesktop.NetworkManager.strongswan"/>
-                <allow send_interface="org.freedesktop.NetworkManager.strongswan"/>
-        </policy>
-        <policy at_console="true">
-                <allow send_destination="org.freedesktop.NetworkManager.strongswan"/>
-                <allow send_interface="org.freedesktop.NetworkManager.strongswan"/>
-        </policy>
-        <policy context="default">
-                <deny own="org.strongswan.charon"/>
-                <deny send_destination="org.freedesktop.NetworkManager.strongswan"/>
-                <deny send_interface="org.freedesktop.NetworkManager.strongswan"/>
-        </policy>
-</busconfig>
-
diff --git a/src/charon/plugins/dbus/nm-strongswan.name b/src/charon/plugins/dbus/nm-strongswan.name
deleted file mode 100644 (file)
index 2f6ed06..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-[VPN Connection]
-name=strongSwan
-service=org.freedesktop.NetworkManager.strongswan
-program=/usr/local/libexec/ipsec/charon
-
-[GNOME]
-auth-dialog=/home/martin/strongswan/trunk/src/networkmanager/nm_applet_auth
-properties=/home/martin/strongswan/trunk/src/networkmanager/strongswan.so
diff --git a/src/charon/plugins/dbus/nm_applet_auth.c b/src/charon/plugins/dbus/nm_applet_auth.c
deleted file mode 100644 (file)
index f48ee1b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <stdio.h>
-
-
-int main()
-{
-       char buf[1];
-       printf("PASSWORDL\n");
-       printf ("\n\n");
-       //fread (buf, sizeof (char), sizeof (buf), stdin);
-       return 0;
-}
diff --git a/src/charon/plugins/dbus/nm_applet_gui.c b/src/charon/plugins/dbus/nm_applet_gui.c
deleted file mode 100644 (file)
index 70abfad..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright (C) 2007 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * $Id$
- */
-
-#include <glade/glade.h>
-
-#define NM_VPN_API_SUBJECT_TO_CHANGE
-#include <nm-vpn-ui-interface.h>
-
-
-typedef struct private_nm_applet_gui_t private_nm_applet_gui_t;
-
-/**
- * Private data of an nm_applet_gui_t object.
- */
-struct private_nm_applet_gui_t {
-
-       /**
-        * Implements NetworkManagerVpnUI interface.
-        */
-       NetworkManagerVpnUI public;
-       
-       /**
-        * callback registered by NM to update validity
-        */
-       NetworkManagerVpnUIDialogValidityCallback callback;
-        
-       /**
-        * loaded Glade XML interface description
-        */
-       GladeXML *xml;
-       
-       /**
-        * root widget to return to druid
-        */
-       GtkWidget *widget;
-       
-       /**
-        * name of the connection
-        */
-       GtkEntry *name;
-       
-       /**
-        * gateway address
-        */
-       GtkEntry *gateway;
-       
-       /**
-        * username
-        */
-       GtkEntry *user;
-};
-
-static const char *get_display_name(private_nm_applet_gui_t *this)
-{
-       return "strongSwan (IPsec/IKEv2)";
-}
-
-static const char *get_service_name(private_nm_applet_gui_t *this)
-{
-       return "org.freedesktop.NetworkManager.strongswan";
-}
-
-static GtkWidget *get_widget(private_nm_applet_gui_t *this, GSList *properties,
-                                                        GSList *routes, const char *connection_name)
-{
-       GSList *i;
-
-       gtk_entry_set_text(this->name, "");
-       gtk_entry_set_text(this->gateway, "");
-       gtk_entry_set_text(this->user, "");
-       
-       if (connection_name)
-       {
-               gtk_entry_set_text(this->name, connection_name);
-       }
-
-       while (properties)
-       {
-               const char *key;
-               const char *value;
-
-               key = properties->data;
-               properties = g_slist_next(properties);
-               if (properties)
-               {
-                       value = properties->data;
-                       if (strcmp(key, "gateway") == 0)
-                       {
-                           gtk_entry_set_text(this->gateway, value);
-                       }
-                       if (strcmp(key, "user") == 0)
-                       {
-                           gtk_entry_set_text(this->user, value);
-                       }
-                       properties = g_slist_next(properties);
-               }
-       }
-       return this->widget;
-}
-
-static GSList *get_properties(private_nm_applet_gui_t *this)
-{
-       GSList *props = NULL;
-       
-       props = g_slist_append(props, g_strdup("gateway"));
-       props = g_slist_append(props, g_strdup(gtk_entry_get_text(this->gateway)));
-       props = g_slist_append(props, g_strdup("user"));
-       props = g_slist_append(props, g_strdup(gtk_entry_get_text(this->user)));
-       
-       return props;
-}
-
-static GSList *get_routes(private_nm_applet_gui_t *this)
-{
-       return NULL;
-}
-
-static char *get_connection_name(private_nm_applet_gui_t *this)
-{
-       const char *name;
-       
-       name = gtk_entry_get_text(this->name);
-       if (name != NULL)
-       {
-               return g_strdup(name);
-       }
-       return NULL;
-}
-
-static gboolean is_valid(private_nm_applet_gui_t *this)
-{
-       return TRUE;
-}
-
-static void set_validity_changed_callback(private_nm_applet_gui_t *this,
-                                                   NetworkManagerVpnUIDialogValidityCallback callback,
-                                                   gpointer user_data)
-{
-       this->callback = callback;
-}
-
-static void get_confirmation_details(private_nm_applet_gui_t *this, gchar **retval)
-{
-       *retval = g_strdup_printf("connection %s\n", gtk_entry_get_text(this->name));
-}
-
-static gboolean can_export(private_nm_applet_gui_t *this)
-{
-       return FALSE;
-}
-
-static gboolean import_file (private_nm_applet_gui_t *this, const char *path)
-{
-       return FALSE;
-}
-
-static gboolean export(private_nm_applet_gui_t *this, GSList *properties,
-                                          GSList *routes, const char *connection_name)
-{
-       return FALSE;
-}
-
-NetworkManagerVpnUI* nm_vpn_properties_factory(void)
-{
-       private_nm_applet_gui_t *this = g_new0(private_nm_applet_gui_t, 1);
-       
-       this->public.get_display_name = (const char *(*)(NetworkManagerVpnUI *))get_display_name;
-    this->public.get_service_name = (const char *(*) (NetworkManagerVpnUI *))get_service_name;
-    this->public.get_widget = (GtkWidget *(*) (NetworkManagerVpnUI *self, GSList *, GSList *, const char *))get_widget;
-    this->public.get_connection_name = (char *(*) (NetworkManagerVpnUI *))get_connection_name;
-    this->public.get_properties = (GSList *(*) (NetworkManagerVpnUI *))get_properties;
-    this->public.get_routes = (GSList *(*) (NetworkManagerVpnUI *))get_routes;
-    this->public.set_validity_changed_callback = (void (*) (NetworkManagerVpnUI *, NetworkManagerVpnUIDialogValidityCallback, gpointer))set_validity_changed_callback;
-    this->public.is_valid = (gboolean (*) (NetworkManagerVpnUI *))is_valid;
-    this->public.get_confirmation_details = (void (*)(NetworkManagerVpnUI *, gchar **))get_confirmation_details;
-    this->public.can_export = (gboolean (*) (NetworkManagerVpnUI *))can_export;
-    this->public.import_file = (gboolean (*) (NetworkManagerVpnUI *, const char *))import_file;
-    this->public.export = (gboolean (*) (NetworkManagerVpnUI *, GSList *, GSList *, const char *))export;
-    this->public.data = NULL;
-    
-    this->callback = NULL;
-    this->xml = glade_xml_new("/home/martin/strongswan/trunk/src/charon/plugins/dbus/nm_applet_gui.xml", NULL, NULL);
-       
-       if (this->xml != NULL)
-       {
-       this->widget = glade_xml_get_widget(this->xml, "main");
-       this->name = GTK_ENTRY(glade_xml_get_widget(this->xml, "name"));
-       this->gateway = GTK_ENTRY(glade_xml_get_widget(this->xml, "gateway"));
-       this->user = GTK_ENTRY(glade_xml_get_widget(this->xml, "user"));
-               
-               if (this->widget && this->name && this->gateway && this->user)
-               {
-                       return &this->public;
-               }
-       }
-       g_free(this);
-       return NULL;
-}
diff --git a/src/charon/plugins/dbus/nm_applet_gui.xml b/src/charon/plugins/dbus/nm_applet_gui.xml
deleted file mode 100644 (file)
index f59d3e9..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.0 on Sat Mar 15 17:12:28 2008 -->
-<glade-interface>
-  <widget class="GtkWindow" id="window1">
-    <child>
-      <widget class="GtkTable" id="main">
-        <property name="visible">True</property>
-        <property name="n_rows">3</property>
-        <property name="n_columns">2</property>
-        <property name="column_spacing">5</property>
-        <property name="row_spacing">5</property>
-        <child>
-          <widget class="GtkEntry" id="user">
-            <property name="visible">True</property>
-          </widget>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_FILL</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkLabel" id="label8">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">_Username</property>
-            <property name="use_underline">True</property>
-            <property name="justify">GTK_JUSTIFY_CENTER</property>
-          </widget>
-          <packing>
-            <property name="top_attach">2</property>
-            <property name="bottom_attach">3</property>
-            <property name="x_options">GTK_FILL</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkEntry" id="gateway">
-            <property name="visible">True</property>
-          </widget>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_FILL</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkLabel" id="label3">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">_Gateway</property>
-            <property name="use_underline">True</property>
-            <property name="justify">GTK_JUSTIFY_RIGHT</property>
-          </widget>
-          <packing>
-            <property name="top_attach">1</property>
-            <property name="bottom_attach">2</property>
-            <property name="x_options">GTK_FILL</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkEntry" id="name">
-            <property name="visible">True</property>
-          </widget>
-          <packing>
-            <property name="left_attach">1</property>
-            <property name="right_attach">2</property>
-            <property name="x_options">GTK_FILL</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="GtkLabel" id="label1">
-            <property name="visible">True</property>
-            <property name="label" translatable="yes">Connection _name</property>
-            <property name="use_underline">True</property>
-            <property name="justify">GTK_JUSTIFY_FILL</property>
-          </widget>
-          <packing>
-            <property name="x_options">GTK_FILL</property>
-            <property name="y_options">GTK_FILL</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
-</glade-interface>
diff --git a/src/charon/plugins/nm/Makefile.am b/src/charon/plugins/nm/Makefile.am
new file mode 100644 (file)
index 0000000..0d6677d
--- /dev/null
@@ -0,0 +1,11 @@
+
+INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/charon ${nm_CFLAGS}
+
+AM_CFLAGS = -rdynamic
+
+plugin_LTLIBRARIES = libstrongswan-nm.la
+libstrongswan_nm_la_SOURCES = \
+  nm_plugin.h nm_plugin.c nm_service.h nm_service.c 
+libstrongswan_nm_la_LDFLAGS = -module
+libstrongswan_nm_la_LIBADD = ${nm_LIBS}
+
diff --git a/src/charon/plugins/nm/nm_plugin.c b/src/charon/plugins/nm/nm_plugin.c
new file mode 100644 (file)
index 0000000..aa95528
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "nm_plugin.h"
+#include "nm_service.h"
+
+#include <daemon.h>
+#include <processing/jobs/callback_job.h>
+
+typedef struct private_nm_plugin_t private_nm_plugin_t;
+
+/**
+ * private data of nm plugin
+ */
+struct private_nm_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       nm_plugin_t public;
+       
+       GMainLoop *loop;
+};
+
+/**
+ * NM plugin processing routine, creates and handles NMVPNPlugin
+ */
+static job_requeue_t run(private_nm_plugin_t *this)
+{
+       NMStrongswanPlugin *plugin;
+       GMainLoop *loop;
+
+       plugin = nm_strongswan_plugin_new();
+       
+       this->loop = loop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(loop);
+       
+       g_main_loop_unref(loop);
+       g_object_unref(plugin);
+       
+       return JOB_REQUEUE_NONE;
+}
+
+/**
+ * Implementation of plugin_t.destroy
+ */
+static void destroy(private_nm_plugin_t *this)
+{
+       if (this->loop)
+       {
+               g_main_loop_quit(this->loop);
+       }
+       free(this);
+}
+
+/*
+ * see header file
+ */
+plugin_t *plugin_create()
+{
+       private_nm_plugin_t *this = malloc_thing(private_nm_plugin_t);
+       
+       this->public.plugin.destroy = (void(*)(plugin_t*))destroy;
+       
+       this->loop = NULL;
+       g_type_init ();
+       if (!g_thread_supported())
+       {
+               g_thread_init(NULL);
+       }
+       
+       charon->processor->queue_job(charon->processor, 
+                (job_t*)callback_job_create((callback_job_cb_t)run, this, NULL, NULL));
+       
+       return &this->public.plugin;
+}
+
diff --git a/src/charon/plugins/nm/nm_plugin.h b/src/charon/plugins/nm/nm_plugin.h
new file mode 100644 (file)
index 0000000..2604b80
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup nm nm
+ * @ingroup cplugins
+ *
+ * @defgroup nm_plugin nm_plugin
+ * @{ @ingroup nm
+ */
+
+#ifndef NM_PLUGIN_H_
+#define NM_PLUGIN_H_
+
+#include <plugins/plugin.h>
+
+typedef struct nm_plugin_t nm_plugin_t;
+
+/**
+ * NetworkManager integration plugin.
+ */
+struct nm_plugin_t {
+
+       /**
+        * implements plugin interface
+        */
+       plugin_t plugin;
+};
+
+/**
+ * Create a nm_plugin instance.
+ */
+plugin_t *plugin_create();
+
+#endif /* NM_PLUGIN_H_ @}*/
diff --git a/src/charon/plugins/nm/nm_service.c b/src/charon/plugins/nm/nm_service.c
new file mode 100644 (file)
index 0000000..ed30d7f
--- /dev/null
@@ -0,0 +1,351 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include <nm-setting-vpn.h>
+#include <nm-setting-vpn-properties.h>
+#include "nm_service.h"
+
+#include <daemon.h>
+#include <utils/host.h>
+#include <utils/identification.h>
+#include <config/peer_cfg.h>
+
+#include <stdio.h>
+
+#define CONFIG_NAME "NetworkManager"
+
+G_DEFINE_TYPE(NMStrongswanPlugin, nm_strongswan_plugin, NM_TYPE_VPN_PLUGIN)
+
+/**
+ * Private data of NMStrongswanPlugin
+ */
+typedef struct {
+       bus_listener_t listener;
+       ike_sa_t *ike_sa;
+       NMVPNPlugin *plugin;
+} NMStrongswanPluginPrivate;
+
+#define NM_STRONGSWAN_PLUGIN_GET_PRIVATE(o) \
+                       (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+                               NM_TYPE_STRONGSWAN_PLUGIN, NMStrongswanPluginPrivate))
+
+/**
+ * convert a traffic selector address range to subnet and its mask.
+ */
+static u_int ts2subnet(traffic_selector_t* ts, u_int8_t *mask)
+{
+       /* there is no way to do this cleanly, as the address range may
+        * be anything else but a subnet. We use from_addr as subnet 
+        * and try to calculate a usable subnet mask.
+        */
+       int byte, bit, net;
+       bool found = FALSE;
+       chunk_t from, to;
+       size_t size = (ts->get_type(ts) == TS_IPV4_ADDR_RANGE) ? 4 : 16;
+       
+       from = ts->get_from_address(ts);
+       to = ts->get_to_address(ts);
+       
+       *mask = (size * 8);
+       /* go trough all bits of the addresses, beginning in the front.
+        * as long as they are equal, the subnet gets larger
+        */
+       for (byte = 0; byte < size; byte++)
+       {
+               for (bit = 7; bit >= 0; bit--)
+               {
+                       if ((1<<bit & from.ptr[byte]) != (1<<bit & to.ptr[byte]))
+                       {
+                               *mask = ((7 - bit) + (byte * 8));
+                               found = TRUE;
+                               break;
+                       }
+               }
+               if (found)
+               {
+                       break;
+               }
+       }
+       net = *(u_int32_t*)from.ptr;
+       chunk_free(&from);
+       chunk_free(&to);
+       return net;
+}
+
+/**
+ * signal IPv4 config to NM, set connection as established
+ */
+static void signal_ipv4_config(NMVPNPlugin *plugin, child_sa_t *child_sa)
+{
+       linked_list_t *list;
+       traffic_selector_t *ts = NULL;
+       enumerator_t *enumerator;
+       
+       list = child_sa->get_traffic_selectors(child_sa, FALSE);
+       enumerator = list->create_enumerator(list);
+       while (enumerator->enumerate(enumerator, &ts))
+       {
+               GValue *val;
+               GHashTable *config;
+               u_int8_t mask;
+               
+               config = g_hash_table_new(g_str_hash, g_str_equal);
+               
+               val = g_slice_new0(GValue);
+               g_value_init(val, G_TYPE_UINT);
+               g_value_set_uint(val, ts2subnet(ts, &mask));
+               g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_ADDRESS, val);
+               
+               val = g_slice_new0(GValue);
+               g_value_init(val, G_TYPE_UINT);
+               g_value_set_uint(val, mask);
+               g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
+               
+               nm_vpn_plugin_set_ip4_config(plugin, config);
+       }
+       enumerator->destroy(enumerator);
+}
+
+/**
+ * Bus listen function to wait for SA establishing
+ */
+bool listen_bus(bus_listener_t *listener, signal_t signal, level_t level,
+                               int thread, ike_sa_t *ike_sa, void *data, 
+                               char* format, va_list args)
+{
+       NMStrongswanPluginPrivate *private = (NMStrongswanPluginPrivate*)listener;
+       
+       if (private->ike_sa == ike_sa)
+       {
+               switch (signal)
+               {
+                       case CHD_UP_SUCCESS:
+                               if (data)
+                               {
+                                       signal_ipv4_config(private->plugin, (child_sa_t*)data);
+                                       return FALSE;
+                               }
+                               /* FALL */
+                       case IKE_UP_FAILED:
+                       case CHD_UP_FAILED:
+                               nm_vpn_plugin_failure(private->plugin,
+                                                                         NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED);
+                               /* TODO: NM does not react on this failure!? So additionaly
+                                * reset state */
+                               nm_vpn_plugin_set_state(private->plugin,
+                                                                               NM_VPN_SERVICE_STATE_STOPPED);
+                               return FALSE;
+                       default:
+                               break;
+               }
+       }
+       return TRUE;
+}
+
+/**
+ * Read a string from a hash table using a given key
+ */
+static char* get_str(GHashTable *hash, char *key)
+{
+       GValue *value;
+
+       value = g_hash_table_lookup(hash, key);
+       if (G_VALUE_TYPE (value) == G_TYPE_STRING)
+       {
+               return (char*)g_value_get_string(value);
+       }
+       return NULL;
+}
+
+/**
+ * Connect function called from NM via DBUS
+ */
+static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
+                                                GError **err)
+{
+       NMSettingVPNProperties *properties;
+       identification_t *user = NULL;
+       char *address, *str;
+       ike_cfg_t *ike_cfg;
+       peer_cfg_t *peer_cfg;
+       child_cfg_t *child_cfg;
+       traffic_selector_t *ts;
+       ike_sa_t *ike_sa;
+       
+       /**
+        * Read parameters
+        */
+       properties = NM_SETTING_VPN_PROPERTIES(
+               nm_connection_get_setting(connection, NM_TYPE_SETTING_VPN_PROPERTIES));
+       
+       if (!properties)
+       {
+               g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+                                   "%s", "Invalid arguments.");
+               return FALSE;
+       }
+       
+       DBG2(DBG_CFG, "received NetworkManager connection: %s",
+                nm_setting_to_string(NM_SETTING(properties)));
+
+       str = get_str(properties->data, "user");
+       if (str)
+       {
+               user = identification_create_from_string(str);
+       }
+       if (!user)
+       {
+               g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+                                   "Username '%s' invalid.", str);
+               return FALSE;
+       }
+       address = get_str(properties->data, "address");
+       if (!address || !*address)
+       {
+               g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+                                   "Gateway address missing.");
+               return FALSE;
+       }
+       
+       /**
+        * Set up configurations
+        */
+       ike_cfg = ike_cfg_create(TRUE, TRUE, "0.0.0.0", address);
+       ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE));
+       peer_cfg = peer_cfg_create(CONFIG_NAME, 2, ike_cfg, user,
+                                       identification_create_from_encoding(ID_ANY, chunk_empty),
+                                       CERT_SEND_IF_ASKED, UNIQUE_REPLACE, CONF_AUTH_PUBKEY,
+                                       0, 0, 1, /* EAP method, vendor, keyingtries */
+                                       18000, 0, /* rekey 5h, reauth none */
+                                       600, 600, /* jitter, over 10min */
+                                       TRUE, 0, /* mobike, DPD */
+                                       host_create_from_string("0.0.0.0", 0), /* virtual ip */
+                                       NULL, FALSE, NULL, NULL); /* pool, mediation */
+       child_cfg = child_cfg_create(CONFIG_NAME,
+                                                                3600, 3000, /* lifetime 1h, rekey 50min */
+                                                                300, /* jitter 5min */
+                                                                NULL, TRUE, MODE_TUNNEL, /* updown, hostaccess */
+                                                                ACTION_NONE, ACTION_NONE, FALSE); /* ipcomp */
+       child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
+       ts = traffic_selector_create_dynamic(0, 0, 65535);
+       child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
+       ts = traffic_selector_create_from_string(0, TS_IPV4_ADDR_RANGE,
+                                                                                        "0.0.0.0", 0,
+                                                                                        "255.255.255.255", 65535);
+       child_cfg->add_traffic_selector(child_cfg, FALSE, ts);
+       peer_cfg->add_child_cfg(peer_cfg, child_cfg);
+       
+       /**
+        * Start to initiate
+        */
+       ike_sa = charon->ike_sa_manager->checkout_by_config(charon->ike_sa_manager,
+                                                                                                               peer_cfg);
+       if (!ike_sa->get_peer_cfg(ike_sa))
+       {
+               ike_sa->set_peer_cfg(ike_sa, peer_cfg);
+       }
+       else
+       {
+               peer_cfg->destroy(peer_cfg);
+       }
+       if (ike_sa->initiate(ike_sa, child_cfg) != SUCCESS)
+       {
+               charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager, ike_sa);
+               
+               g_set_error(err, NM_VPN_PLUGIN_ERROR, NM_VPN_PLUGIN_ERROR_LAUNCH_FAILED,
+                                   "Initiating failed.");
+               return FALSE;
+       }
+       
+       /**
+        * Register listener
+        */
+       NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->ike_sa = ike_sa;
+       charon->bus->add_listener(charon->bus, 
+                                                       &NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->listener);
+       charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
+       return TRUE;
+}
+
+/**
+ * NeedSecrets called from NM via DBUS 
+ */
+static gboolean need_secrets(NMVPNPlugin *plugin, NMConnection *connection,
+                                                        char **setting_name, GError **error)
+{
+       return FALSE;
+}
+
+/**
+ * Disconnect called from NM via DBUS 
+ */
+static gboolean disconnect(NMVPNPlugin *plugin, GError **err)
+{
+       enumerator_t *enumerator;
+       ike_sa_t *ike_sa;
+       u_int id;
+       
+       enumerator = charon->controller->create_ike_sa_enumerator(charon->controller);
+       while (enumerator->enumerate(enumerator, &ike_sa))
+       {
+               if (streq(CONFIG_NAME, ike_sa->get_name(ike_sa)))
+               {
+                       id = ike_sa->get_unique_id(ike_sa);
+                       enumerator->destroy(enumerator);
+                       charon->controller->terminate_ike(charon->controller, id,
+                                                                                         controller_cb_empty, NULL);
+                       return TRUE;
+               }
+       }
+       enumerator->destroy(enumerator);
+       return FALSE;
+}
+
+/**
+ * Initializer
+ */
+static void nm_strongswan_plugin_init(NMStrongswanPlugin *plugin)
+{
+       NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->plugin = NM_VPN_PLUGIN(plugin);
+       NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->listener.signal = listen_bus;
+}
+
+/**
+ * Class constructor
+ */
+static void nm_strongswan_plugin_class_init(
+                                                                       NMStrongswanPluginClass *strongswan_class)
+{
+       NMVPNPluginClass *parent_class = NM_VPN_PLUGIN_CLASS(strongswan_class);
+       
+       g_type_class_add_private(G_OBJECT_CLASS(strongswan_class),
+                                                        sizeof(NMStrongswanPluginPrivate));
+       parent_class->connect = connect_;
+       parent_class->need_secrets = need_secrets;
+       parent_class->disconnect = disconnect;
+}
+
+/**
+ * Object constructor
+ */
+NMStrongswanPlugin *nm_strongswan_plugin_new(void)
+{
+       return (NMStrongswanPlugin *)g_object_new (
+                                       NM_TYPE_STRONGSWAN_PLUGIN, NM_VPN_PLUGIN_DBUS_SERVICE_NAME,
+                                       NM_DBUS_SERVICE_STRONGSWAN, NULL);
+}
+
diff --git a/src/charon/plugins/nm/nm_service.h b/src/charon/plugins/nm/nm_service.h
new file mode 100644 (file)
index 0000000..7133472
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+/**
+ * @defgroup nm_service nm_service
+ * @{ @ingroup nm
+ */
+
+#ifndef NM_SERVICE_H_
+#define NM_SERVICE_H_
+
+#include <glib/gtypes.h>
+#include <glib-object.h>
+#include <nm-vpn-plugin.h>
+#undef TRUE
+#undef FALSE
+
+#define NM_TYPE_STRONGSWAN_PLUGIN            (nm_strongswan_plugin_get_type ())
+#define NM_STRONGSWAN_PLUGIN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPlugin))
+#define NM_STRONGSWAN_PLUGIN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPluginClass))
+#define NM_IS_STRONGSWAN_PLUGIN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_STRONGSWAN_PLUGIN))
+#define NM_IS_STRONGSWAN_PLUGIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), NM_TYPE_STRONGSWAN_PLUGIN))
+#define NM_STRONGSWAN_PLUGIN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_STRONGSWAN_PLUGIN, NMSTRONGSWANPluginClass))
+
+#define NM_DBUS_SERVICE_STRONGSWAN    "org.freedesktop.NetworkManager.strongswan"
+#define NM_DBUS_INTERFACE_STRONGSWAN  "org.freedesktop.NetworkManager.strongswan"
+#define NM_DBUS_PATH_STRONGSWAN       "/org/freedesktop/NetworkManager/strongswan"
+
+typedef struct {
+       NMVPNPlugin parent;
+} NMStrongswanPlugin;
+
+typedef struct {
+       NMVPNPluginClass parent;
+} NMStrongswanPluginClass;
+
+GType nm_strongswan_plugin_get_type(void);
+
+NMStrongswanPlugin *nm_strongswan_plugin_new(void);
+
+#endif /* NM_SERVICE_H_ */