nm plugin handles DNS/NBNS configuration attributes
This commit is contained in:
@@ -5,6 +5,9 @@ AM_CFLAGS = -rdynamic -Wformat=0
|
||||
|
||||
plugin_LTLIBRARIES = libstrongswan-nm.la
|
||||
libstrongswan_nm_la_SOURCES = \
|
||||
nm_plugin.h nm_plugin.c nm_service.h nm_service.c nm_creds.h nm_creds.c
|
||||
nm_plugin.h nm_plugin.c \
|
||||
nm_service.h nm_service.c \
|
||||
nm_creds.h nm_creds.c \
|
||||
nm_handler.h nm_handler.c
|
||||
libstrongswan_nm_la_LDFLAGS = -module
|
||||
libstrongswan_nm_la_LIBADD = ${nm_LIBS}
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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_handler.h"
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
typedef struct private_nm_handler_t private_nm_handler_t;
|
||||
|
||||
/**
|
||||
* Private data of an nm_handler_t object.
|
||||
*/
|
||||
struct private_nm_handler_t {
|
||||
|
||||
/**
|
||||
* Public nm_handler_t interface.
|
||||
*/
|
||||
nm_handler_t public;
|
||||
|
||||
/**
|
||||
* list of received DNS server attributes, pointer to 4 byte data
|
||||
*/
|
||||
linked_list_t *dns;
|
||||
|
||||
/**
|
||||
* list of received NBNS server attributes, pointer to 4 byte data
|
||||
*/
|
||||
linked_list_t *nbns;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of attribute_handler_t.handle
|
||||
*/
|
||||
static bool handle(private_nm_handler_t *this, ike_sa_t *ike_sa,
|
||||
configuration_attribute_type_t type, chunk_t data)
|
||||
{
|
||||
linked_list_t *list;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INTERNAL_IP4_DNS:
|
||||
list = this->dns;
|
||||
break;
|
||||
case INTERNAL_IP4_NBNS:
|
||||
list = this->nbns;
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
if (data.len != 4)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
list->insert_last(list, chunk_clone(data).ptr);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* convert plain byte ptrs to handy chunk during enumeration
|
||||
*/
|
||||
static bool filter_chunks(void* null, char **in, chunk_t *out)
|
||||
{
|
||||
*out = chunk_create(*in, 4);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of nm_handler_t.create_enumerator
|
||||
*/
|
||||
static enumerator_t* create_enumerator(private_nm_handler_t *this,
|
||||
configuration_attribute_type_t type)
|
||||
{
|
||||
linked_list_t *list;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INTERNAL_IP4_DNS:
|
||||
list = this->dns;
|
||||
break;
|
||||
case INTERNAL_IP4_NBNS:
|
||||
list = this->nbns;
|
||||
default:
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
return enumerator_create_filter(list->create_enumerator(list),
|
||||
(void*)filter_chunks, NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of nm_handler_t.reset
|
||||
*/
|
||||
static void reset(private_nm_handler_t *this)
|
||||
{
|
||||
void *data;
|
||||
|
||||
while (this->dns->remove_last(this->dns, (void**)&data) == SUCCESS)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
while (this->nbns->remove_last(this->nbns, (void**)&data) == SUCCESS)
|
||||
{
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of nm_handler_t.destroy.
|
||||
*/
|
||||
static void destroy(private_nm_handler_t *this)
|
||||
{
|
||||
reset(this);
|
||||
this->dns->destroy(this->dns);
|
||||
this->nbns->destroy(this->nbns);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
nm_handler_t *nm_handler_create()
|
||||
{
|
||||
private_nm_handler_t *this = malloc_thing(private_nm_handler_t);
|
||||
|
||||
this->public.handler.handle = (bool(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))handle;
|
||||
this->public.handler.release = (void(*)(attribute_handler_t*, ike_sa_t*, configuration_attribute_type_t, chunk_t))nop;
|
||||
this->public.create_enumerator = (enumerator_t*(*)(nm_handler_t*, configuration_attribute_type_t type))create_enumerator;
|
||||
this->public.reset = (void(*)(nm_handler_t*))reset;
|
||||
this->public.destroy = (void(*)(nm_handler_t*))destroy;
|
||||
|
||||
this->dns = linked_list_create();
|
||||
this->nbns = linked_list_create();
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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_handler nm_handler
|
||||
* @{ @ingroup nm
|
||||
*/
|
||||
|
||||
#ifndef NM_HANDLER_H_
|
||||
#define NM_HANDLER_H_
|
||||
|
||||
#include <config/attributes/attribute_handler.h>
|
||||
|
||||
typedef struct nm_handler_t nm_handler_t;
|
||||
|
||||
/**
|
||||
* Handles DNS/NBNS attributes to pass to NM.
|
||||
*/
|
||||
struct nm_handler_t {
|
||||
|
||||
/**
|
||||
* Implements attribute handler interface
|
||||
*/
|
||||
attribute_handler_t handler;
|
||||
|
||||
/**
|
||||
* Create an enumerator over received attributes of a given kind.
|
||||
*
|
||||
* @param type type of attributes to enumerate
|
||||
* @return enumerator over attribute data (chunk_t)
|
||||
*/
|
||||
enumerator_t* (*create_enumerator)(nm_handler_t *this,
|
||||
configuration_attribute_type_t type);
|
||||
/**
|
||||
* Reset state, flush all received attributes.
|
||||
*/
|
||||
void (*reset)(nm_handler_t *this);
|
||||
|
||||
/**
|
||||
* Destroy a nm_handler_t.
|
||||
*/
|
||||
void (*destroy)(nm_handler_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a nm_handler instance.
|
||||
*/
|
||||
nm_handler_t *nm_handler_create();
|
||||
|
||||
#endif /* NM_HANDLER_ @}*/
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "nm_plugin.h"
|
||||
#include "nm_service.h"
|
||||
#include "nm_creds.h"
|
||||
#include "nm_handler.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <processing/jobs/callback_job.h>
|
||||
@@ -50,6 +51,11 @@ struct private_nm_plugin_t {
|
||||
* credential set registered at the daemon
|
||||
*/
|
||||
nm_creds_t *creds;
|
||||
|
||||
/**
|
||||
* attribute handler regeisterd at the daemon
|
||||
*/
|
||||
nm_handler_t *handler;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -79,6 +85,8 @@ static void destroy(private_nm_plugin_t *this)
|
||||
}
|
||||
charon->credentials->remove_set(charon->credentials, &this->creds->set);
|
||||
this->creds->destroy(this->creds);
|
||||
charon->attributes->remove_handler(charon->attributes, &this->handler->handler);
|
||||
this->handler->destroy(this->handler);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -99,8 +107,10 @@ plugin_t *plugin_create()
|
||||
}
|
||||
|
||||
this->creds = nm_creds_create();
|
||||
this->handler = nm_handler_create();
|
||||
charon->credentials->add_set(charon->credentials, &this->creds->set);
|
||||
this->plugin = nm_strongswan_plugin_new(this->creds);
|
||||
charon->attributes->add_handler(charon->attributes, &this->handler->handler);
|
||||
this->plugin = nm_strongswan_plugin_new(this->creds, this->handler);
|
||||
if (!this->plugin)
|
||||
{
|
||||
DBG1(DBG_CFG, "DBUS binding failed");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -34,16 +34,47 @@ G_DEFINE_TYPE(NMStrongswanPlugin, nm_strongswan_plugin, NM_TYPE_VPN_PLUGIN)
|
||||
* Private data of NMStrongswanPlugin
|
||||
*/
|
||||
typedef struct {
|
||||
/* implements bus listener interface */
|
||||
listener_t listener;
|
||||
/* IKE_SA we are listening on */
|
||||
ike_sa_t *ike_sa;
|
||||
/* backref to public plugin */
|
||||
NMVPNPlugin *plugin;
|
||||
/* credentials to use for authentication */
|
||||
nm_creds_t *creds;
|
||||
/* attribute handler for DNS/NBNS server information */
|
||||
nm_handler_t *handler;
|
||||
} NMStrongswanPluginPrivate;
|
||||
|
||||
#define NM_STRONGSWAN_PLUGIN_GET_PRIVATE(o) \
|
||||
(G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
||||
NM_TYPE_STRONGSWAN_PLUGIN, NMStrongswanPluginPrivate))
|
||||
|
||||
/**
|
||||
* convert enumerated handler chunks to a UINT_ARRAY GValue
|
||||
*/
|
||||
static GValue* handler_to_val(nm_handler_t *handler,
|
||||
configuration_attribute_type_t type)
|
||||
{
|
||||
GValue *val;
|
||||
GArray *array;
|
||||
enumerator_t *enumerator;
|
||||
chunk_t chunk;
|
||||
|
||||
enumerator = handler->create_enumerator(handler, type);
|
||||
array = g_array_new (FALSE, TRUE, sizeof (guint32));
|
||||
while (enumerator->enumerate(enumerator, &chunk))
|
||||
{
|
||||
g_array_append_val (array, *(u_int32_t*)chunk.ptr);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
val = g_slice_new0 (GValue);
|
||||
g_value_init (val, DBUS_TYPE_G_UINT_ARRAY);
|
||||
g_value_set_boxed (val, array);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* signal IPv4 config to NM, set connection as established
|
||||
*/
|
||||
@@ -53,10 +84,12 @@ static void signal_ipv4_config(NMVPNPlugin *plugin,
|
||||
GValue *val;
|
||||
GHashTable *config;
|
||||
host_t *me, *other;
|
||||
nm_handler_t *handler;
|
||||
|
||||
config = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
me = ike_sa->get_my_host(ike_sa);
|
||||
other = ike_sa->get_other_host(ike_sa);
|
||||
handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler;
|
||||
|
||||
/* NM requires a tundev, but netkey does not use one. Passing an invalid
|
||||
* iface makes NM complain, but it accepts it without fiddling on eth0. */
|
||||
@@ -75,6 +108,14 @@ static void signal_ipv4_config(NMVPNPlugin *plugin,
|
||||
g_value_set_uint(val, me->get_address(me).len * 8);
|
||||
g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_PREFIX, val);
|
||||
|
||||
val = handler_to_val(handler, INTERNAL_IP4_DNS);
|
||||
g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_DNS, val);
|
||||
|
||||
val = handler_to_val(handler, INTERNAL_IP4_NBNS);
|
||||
g_hash_table_insert(config, NM_VPN_PLUGIN_IP4_CONFIG_NBNS, val);
|
||||
|
||||
handler->reset(handler);
|
||||
|
||||
nm_vpn_plugin_set_ip4_config(plugin, config);
|
||||
}
|
||||
|
||||
@@ -83,6 +124,10 @@ static void signal_ipv4_config(NMVPNPlugin *plugin,
|
||||
*/
|
||||
static void signal_failure(NMVPNPlugin *plugin)
|
||||
{
|
||||
nm_handler_t *handler = NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler;
|
||||
|
||||
handler->reset(handler);
|
||||
|
||||
/* TODO: NM does not handle this failure!? */
|
||||
nm_vpn_plugin_failure(plugin, NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED);
|
||||
nm_vpn_plugin_set_state(plugin, NM_VPN_SERVICE_STATE_STOPPED);
|
||||
@@ -223,7 +268,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
||||
str = nm_setting_vpn_get_data_item(settings, "user");
|
||||
if (str)
|
||||
{
|
||||
user = identification_create_from_string(str);
|
||||
user = identification_create_from_string((char*)str);
|
||||
str = nm_setting_vpn_get_secret(settings, "password");
|
||||
creds->set_username_password(creds, user, (char*)str);
|
||||
}
|
||||
@@ -494,7 +539,8 @@ static void nm_strongswan_plugin_class_init(
|
||||
/**
|
||||
* Object constructor
|
||||
*/
|
||||
NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds)
|
||||
NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds,
|
||||
nm_handler_t *handler)
|
||||
{
|
||||
NMStrongswanPlugin *plugin = (NMStrongswanPlugin *)g_object_new (
|
||||
NM_TYPE_STRONGSWAN_PLUGIN,
|
||||
@@ -503,6 +549,7 @@ NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds)
|
||||
if (plugin)
|
||||
{
|
||||
NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->creds = creds;
|
||||
NM_STRONGSWAN_PLUGIN_GET_PRIVATE(plugin)->handler = handler;
|
||||
}
|
||||
return plugin;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2008-2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <nm-vpn-plugin.h>
|
||||
|
||||
#include "nm_creds.h"
|
||||
#include "nm_handler.h"
|
||||
|
||||
#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))
|
||||
@@ -50,6 +51,7 @@ typedef struct {
|
||||
|
||||
GType nm_strongswan_plugin_get_type(void);
|
||||
|
||||
NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds);
|
||||
NMStrongswanPlugin *nm_strongswan_plugin_new(nm_creds_t *creds,
|
||||
nm_handler_t *handler);
|
||||
|
||||
#endif /** NM_SERVICE_H_ @}*/
|
||||
|
||||
Reference in New Issue
Block a user