basic syncing of IKE_SAs

recreating SAs with keymat derivation
This commit is contained in:
Martin Willi
2010-04-07 13:55:11 +02:00
committed by Martin Willi
parent 190edaf527
commit 765935c8f6
9 changed files with 548 additions and 71 deletions
+1
View File
@@ -9,6 +9,7 @@ libstrongswan_ha_sync_la_SOURCES = \
ha_sync_message.h ha_sync_message.c \
ha_sync_socket.h ha_sync_socket.c \
ha_sync_dispatcher.h ha_sync_dispatcher.c \
ha_sync_dispatcher.h ha_sync_cache.c \
ha_sync_ike.h ha_sync_ike.c \
ha_sync_child.h ha_sync_child.c
libstrongswan_ha_sync_la_LDFLAGS = -module
+128
View File
@@ -0,0 +1,128 @@
/*
* 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 "ha_sync_cache.h"
#include <utils/linked_list.h>
typedef struct private_ha_sync_cache_t private_ha_sync_cache_t;
/**
* Private data of an ha_sync_cache_t object.
*/
struct private_ha_sync_cache_t {
/**
* Public ha_sync_cache_t interface.
*/
ha_sync_cache_t public;
/**
* Linked list of IKE_SAs, ike_sa_t
*/
linked_list_t *list;
};
/**
* Implementation of ha_sync_cache_t.get_ike_sa
*/
static ike_sa_t* get_ike_sa(private_ha_sync_cache_t *this, ike_sa_id_t *id)
{
enumerator_t *enumerator;
ike_sa_t *current, *found = NULL;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &current))
{
if (id->equals(id, current->get_id(current)))
{
found = current;
break;
}
}
enumerator->destroy(enumerator);
if (!found)
{
found = ike_sa_create(id);
this->list->insert_first(this->list, found);
}
return found;
}
/**
* Implementation of ha_sync_cache_t.delete_ike_sa
*/
static void delete_ike_sa(private_ha_sync_cache_t *this, ike_sa_id_t *id)
{
enumerator_t *enumerator;
ike_sa_t *ike_sa;
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &ike_sa))
{
if (id->equals(id, ike_sa->get_id(ike_sa)))
{
this->list->remove_at(this->list, enumerator);
ike_sa->destroy(ike_sa);
break;
}
}
enumerator->destroy(enumerator);
}
/**
* Implementation of ha_sync_cache_t.activate_segment
*/
static void activate_segment(private_ha_sync_cache_t *this, u_int segment)
{
ike_sa_t *ike_sa;
/* TODO: activate only segment, not all */
while (this->list->remove_last(this->list, (void**)&ike_sa) == SUCCESS)
{
/* TODO: fix checkin of inexisting IKE_SA in manager */
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
}
}
/**
* Implementation of ha_sync_cache_t.destroy.
*/
static void destroy(private_ha_sync_cache_t *this)
{
this->list->destroy_offset(this->list, offsetof(ike_sa_t, destroy));
free(this);
}
/**
* See header
*/
ha_sync_cache_t *ha_sync_cache_create()
{
private_ha_sync_cache_t *this = malloc_thing(private_ha_sync_cache_t);
this->public.get_ike_sa = (ike_sa_t*(*)(ha_sync_cache_t*, ike_sa_id_t *id))get_ike_sa;
this->public.delete_ike_sa = (void(*)(ha_sync_cache_t*, ike_sa_id_t *id))delete_ike_sa;
this->public.activate_segment = (void(*)(ha_sync_cache_t*, u_int segment))activate_segment;
this->public.destroy = (void(*)(ha_sync_cache_t*))destroy;
this->list = linked_list_create();
return &this->public;
}
@@ -0,0 +1,74 @@
/*
* 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 ha_sync_cache ha_sync_cache
* @{ @ingroup ha_sync
*/
#ifndef HA_SYNC_CACHE_H_
#define HA_SYNC_CACHE_H_
#include <daemon.h>
typedef struct ha_sync_cache_t ha_sync_cache_t;
/**
* Locally cached HA state synced from other nodes.
*/
struct ha_sync_cache_t {
/**
* Get a synced and cached IKE_SA entry.
*
* If no cached IKE_SA with such an id exists, it gets created.
*
* @param id IKE_SA identifier of cached SA.
* @return cached IKE_SA
*/
ike_sa_t* (*get_ike_sa)(ha_sync_cache_t *this, ike_sa_id_t *id);
/**
* Delete a synced and cached IKE_SA entry.
*
* @param id IKE_SA identifier of cached SA to delete.
*/
void (*delete_ike_sa)(ha_sync_cache_t *this, ike_sa_id_t *id);
/**
* Activate a set of IKE_SAs identified by a segment.
*
* Activating means do a takeover of SAs as the responsible node has failed.
* This involves moving all SAs to the daemons IKE_SA manager and handle
* them actively now.
*
* @param segment numerical segment to takeover
*/
void (*activate_segment)(ha_sync_cache_t *this, u_int segment);
/**
* Destroy a ha_sync_cache_t.
*/
void (*destroy)(ha_sync_cache_t *this);
};
/**
* Create a ha_sync_cache instance.
*/
ha_sync_cache_t *ha_sync_cache_create();
#endif /* HA_SYNC_CACHE_ @}*/
+194 -21
View File
@@ -37,12 +37,26 @@ struct private_ha_sync_dispatcher_t {
*/
ha_sync_socket_t *socket;
/**
* Synced SA state cache
*/
ha_sync_cache_t *cache;
/**
* Dispatcher job
*/
callback_job_t *job;
};
/**
* Quick and dirty hack implementation of diffie_hellman_t.get_shared_secret
*/
static status_t get_shared_secret(diffie_hellman_t *this, chunk_t *secret)
{
*secret = chunk_clone((*(chunk_t*)this->destroy));
return SUCCESS;
}
/**
* Process messages of type IKE_ADD
*/
@@ -52,49 +66,204 @@ static void process_ike_add(private_ha_sync_dispatcher_t *this,
ha_sync_message_attribute_t attribute;
ha_sync_message_value_t value;
enumerator_t *enumerator;
ike_sa_t *ike_sa = NULL;
u_int16_t encr = 0, len = 0, integ = 0, prf = 0;
chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty, secret = chunk_empty;
enumerator = message->create_attribute_enumerator(message);
while (enumerator->enumerate(enumerator, &attribute, &value))
{
switch (attribute)
{
/* ike_sa_id_t* */
case HA_SYNC_IKE_ID:
ike_sa = this->cache->get_ike_sa(this->cache, value.ike_sa_id);
break;
case HA_SYNC_IKE_REKEY_ID:
DBG1(DBG_IKE, " %d -> %llu:%llu %s", attribute,
value.ike_sa_id->get_initiator_spi(value.ike_sa_id),
value.ike_sa_id->get_responder_spi(value.ike_sa_id),
value.ike_sa_id->is_initiator(value.ike_sa_id) ?
"initiator" : "responder");
DBG1(DBG_IKE, "TODO: rekey HA sync");
break;
case HA_SYNC_NONCE_I:
nonce_i = value.chunk;
break;
case HA_SYNC_NONCE_R:
nonce_r = value.chunk;
break;
case HA_SYNC_SECRET:
secret = value.chunk;
break;
case HA_SYNC_ALG_ENCR:
encr = value.u16;
break;
case HA_SYNC_ALG_ENCR_LEN:
len = value.u16;
break;
case HA_SYNC_ALG_INTEG:
integ = value.u16;
break;
case HA_SYNC_ALG_PRF:
prf = value.u16;
break;
default:
break;
}
}
enumerator->destroy(enumerator);
if (ike_sa)
{
proposal_t *proposal;
keymat_t *keymat;
/* quick and dirty hack of a DH implementation ;-) */
diffie_hellman_t dh = { .get_shared_secret = get_shared_secret,
.destroy = (void*)&secret };
proposal = proposal_create(PROTO_IKE);
keymat = ike_sa->get_keymat(ike_sa);
if (integ)
{
proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, integ, 0);
}
if (encr)
{
proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, len);
}
if (prf)
{
proposal->add_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, prf, 0);
}
if (!keymat->derive_ike_keys(keymat, proposal, &dh, nonce_i, nonce_r,
ike_sa->get_id(ike_sa), NULL))
{
DBG1(DBG_IKE, "HA sync keymat derivation failed");
}
proposal->destroy(proposal);
}
}
/**
* Apply a condition flag to the IKE_SA if it is in set
*/
static void set_condition(ike_sa_t *ike_sa, ike_condition_t set,
ike_condition_t flag)
{
ike_sa->set_condition(ike_sa, flag, flag & set);
}
/**
* Apply a extension flag to the IKE_SA if it is in set
*/
static void set_extension(ike_sa_t *ike_sa, ike_extension_t set,
ike_extension_t flag)
{
if (flag & set)
{
ike_sa->enable_extension(ike_sa, flag);
}
}
/**
* Process messages of type IKE_UPDATE
*/
static void process_ike_update(private_ha_sync_dispatcher_t *this,
ha_sync_message_t *message)
{
ha_sync_message_attribute_t attribute;
ha_sync_message_value_t value;
enumerator_t *enumerator;
ike_sa_t *ike_sa = NULL;
peer_cfg_t *peer_cfg = NULL;
enumerator = message->create_attribute_enumerator(message);
while (enumerator->enumerate(enumerator, &attribute, &value))
{
if (attribute != HA_SYNC_IKE_ID && ike_sa == NULL)
{
DBG1(DBG_IKE, "HA_SYNC_IKE_ID must be first attribute");
break;
}
switch (attribute)
{
case HA_SYNC_IKE_ID:
ike_sa = this->cache->get_ike_sa(this->cache, value.ike_sa_id);
break;
/* identification_t* */
case HA_SYNC_LOCAL_ID:
ike_sa->set_my_id(ike_sa, value.id->clone(value.id));
break;
case HA_SYNC_REMOTE_ID:
ike_sa->set_other_id(ike_sa, value.id->clone(value.id));
break;
case HA_SYNC_EAP_ID:
DBG1(DBG_IKE, " %d -> %D", attribute, value.id);
ike_sa->set_eap_identity(ike_sa, value.id->clone(value.id));
break;
/* host_t* */
case HA_SYNC_LOCAL_ADDR:
ike_sa->set_my_host(ike_sa, value.host->clone(value.host));
break;
case HA_SYNC_REMOTE_ADDR:
ike_sa->set_other_host(ike_sa, value.host->clone(value.host));
break;
case HA_SYNC_LOCAL_VIP:
case HA_SYNC_REMOTE_VIP:
ike_sa->set_virtual_ip(ike_sa, attribute == HA_SYNC_LOCAL_VIP,
value.host->clone(value.host));
break;
case HA_SYNC_ADDITIONAL_ADDR:
DBG1(DBG_IKE, " %d -> %H", attribute, value.host);
ike_sa->add_additional_address(ike_sa,
value.host->clone(value.host));
break;
/* char* */
case HA_SYNC_CONFIG_NAME:
DBG1(DBG_IKE, " %d -> %s", attribute, value.str);
peer_cfg = charon->backends->get_peer_cfg_by_name(
charon->backends, value.str);
break;
/** u_int32_t */
case HA_SYNC_CONDITIONS:
case HA_SYNC_EXTENSIONS:
DBG1(DBG_IKE, " %d -> %lu", attribute, value.u32);
set_condition(ike_sa, value.u32, EXT_NATT);
set_condition(ike_sa, value.u32, EXT_MOBIKE);
set_condition(ike_sa, value.u32, EXT_HASH_AND_URL);
break;
/** chunk_t */
case HA_SYNC_NONCE_I:
case HA_SYNC_NONCE_R:
case HA_SYNC_SECRET:
DBG1(DBG_IKE, " %d -> %B", attribute, &value.chunk);
case HA_SYNC_EXTENSIONS:
set_extension(ike_sa, value.u32, COND_NAT_ANY);
set_extension(ike_sa, value.u32, COND_NAT_HERE);
set_extension(ike_sa, value.u32, COND_NAT_THERE);
set_extension(ike_sa, value.u32, COND_NAT_FAKE);
set_extension(ike_sa, value.u32, COND_EAP_AUTHENTICATED);
set_extension(ike_sa, value.u32, COND_CERTREQ_SEEN);
set_extension(ike_sa, value.u32, COND_ORIGINAL_INITIATOR);
break;
default:
break;
}
}
enumerator->destroy(enumerator);
if (peer_cfg)
{
ike_sa->set_peer_cfg(ike_sa, peer_cfg);
peer_cfg->destroy(peer_cfg);
}
else
{
DBG1(DBG_IKE, "HA sync is missing nodes configuration");
}
}
/**
* Process messages of type IKE_DELETE
*/
static void process_ike_delete(private_ha_sync_dispatcher_t *this,
ha_sync_message_t *message)
{
ha_sync_message_attribute_t attribute;
ha_sync_message_value_t value;
enumerator_t *enumerator;
enumerator = message->create_attribute_enumerator(message);
while (enumerator->enumerate(enumerator, &attribute, &value))
{
switch (attribute)
{
case HA_SYNC_IKE_ID:
this->cache->delete_ike_sa(this->cache, value.ike_sa_id);
break;
default:
break;
}
}
@@ -115,8 +284,10 @@ static job_requeue_t dispatch(private_ha_sync_dispatcher_t *this)
process_ike_add(this, message);
break;
case HA_SYNC_IKE_UPDATE:
process_ike_update(this, message);
break;
case HA_SYNC_IKE_DELETE:
process_ike_delete(this, message);
break;
case HA_SYNC_IKE_REKEY:
break;
@@ -146,13 +317,15 @@ static void destroy(private_ha_sync_dispatcher_t *this)
/**
* See header
*/
ha_sync_dispatcher_t *ha_sync_dispatcher_create(ha_sync_socket_t *socket)
ha_sync_dispatcher_t *ha_sync_dispatcher_create(ha_sync_socket_t *socket,
ha_sync_cache_t *cache)
{
private_ha_sync_dispatcher_t *this = malloc_thing(private_ha_sync_dispatcher_t);
this->public.destroy = (void(*)(ha_sync_dispatcher_t*))destroy;
this->socket = socket;
this->cache = cache;
this->job = callback_job_create((callback_job_cb_t)dispatch,
this, NULL, NULL);
charon->processor->queue_job(charon->processor, (job_t*)this->job);
@@ -24,6 +24,7 @@
#define HA_SYNC_DISPATCHER_H_
#include "ha_sync_socket.h"
#include "ha_sync_cache.h"
typedef struct ha_sync_dispatcher_t ha_sync_dispatcher_t;
@@ -42,8 +43,10 @@ struct ha_sync_dispatcher_t {
* Create a ha_sync_dispatcher instance pulling from socket.
*
* @param socket socket to pull messages from
* @param cache cache to push synced SAs to
* @return dispatcher object
*/
ha_sync_dispatcher_t *ha_sync_dispatcher_create(ha_sync_socket_t *socket);
ha_sync_dispatcher_t *ha_sync_dispatcher_create(ha_sync_socket_t *socket,
ha_sync_cache_t *cache);
#endif /* HA_SYNC_DISPATCHER_ @}*/
+99 -47
View File
@@ -66,31 +66,10 @@ static bool ike_keys(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r,
ike_sa_t *rekey)
{
iterator_t *iterator;
ha_sync_message_t *m;
peer_cfg_t *peer_cfg;
u_int32_t extension, condition;
host_t *local_vip, *remote_vip, *addr;
identification_t *eap_id;
chunk_t secret;
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
condition = copy_condition(ike_sa, COND_NAT_ANY)
| copy_condition(ike_sa, COND_NAT_HERE)
| copy_condition(ike_sa, COND_NAT_THERE)
| copy_condition(ike_sa, COND_NAT_FAKE)
| copy_condition(ike_sa, COND_EAP_AUTHENTICATED)
| copy_condition(ike_sa, COND_CERTREQ_SEEN)
| copy_condition(ike_sa, COND_ORIGINAL_INITIATOR);
extension = copy_extension(ike_sa, EXT_NATT)
| copy_extension(ike_sa, EXT_MOBIKE)
| copy_extension(ike_sa, EXT_HASH_AND_URL);
local_vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
remote_vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
eap_id = ike_sa->get_eap_identity(ike_sa);
proposal_t *proposal;
u_int16_t alg, len;
if (dh->get_shared_secret(dh, &secret) != SUCCESS)
{
@@ -102,30 +81,6 @@ static bool ike_keys(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
m = ha_sync_message_create(HA_SYNC_IKE_ADD);
m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa));
m->add_attribute(m, HA_SYNC_LOCAL_ID, ike_sa->get_my_id(ike_sa));
m->add_attribute(m, HA_SYNC_REMOTE_ID, ike_sa->get_other_id(ike_sa));
m->add_attribute(m, HA_SYNC_LOCAL_ADDR, ike_sa->get_my_host(ike_sa));
m->add_attribute(m, HA_SYNC_REMOTE_ADDR, ike_sa->get_other_host(ike_sa));
m->add_attribute(m, HA_SYNC_CONDITIONS, condition);
m->add_attribute(m, HA_SYNC_EXTENSIONS, extension);
if (local_vip)
{
m->add_attribute(m, HA_SYNC_LOCAL_VIP, local_vip);
}
if (remote_vip)
{
m->add_attribute(m, HA_SYNC_REMOTE_VIP, remote_vip);
}
if (eap_id)
{
m->add_attribute(m, HA_SYNC_EAP_ID, eap_id);
}
iterator = ike_sa->create_additional_address_iterator(ike_sa);
while (iterator->iterate(iterator, (void**)&addr))
{
m->add_attribute(m, HA_SYNC_ADDITIONAL_ADDR, addr);
}
iterator->destroy(iterator);
}
else
{
@@ -135,6 +90,23 @@ static bool ike_keys(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
m->add_attribute(m, HA_SYNC_IKE_REKEY_ID, rekey->get_id(rekey));
}
proposal = ike_sa->get_proposal(ike_sa);
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &len))
{
m->add_attribute(m, HA_SYNC_ALG_ENCR, alg);
if (len)
{
m->add_attribute(m, HA_SYNC_ALG_ENCR_LEN, len);
}
}
if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
{
m->add_attribute(m, HA_SYNC_ALG_INTEG, alg);
}
if (proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
{
m->add_attribute(m, HA_SYNC_ALG_PRF, alg);
}
m->add_attribute(m, HA_SYNC_NONCE_I, nonce_i);
m->add_attribute(m, HA_SYNC_NONCE_R, nonce_r);
m->add_attribute(m, HA_SYNC_SECRET, secret);
@@ -146,6 +118,85 @@ static bool ike_keys(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
return TRUE;
}
/**
* Implementation of listener_t.ike_state_change
*/
static bool ike_state_change(private_ha_sync_ike_t *this, ike_sa_t *ike_sa,
ike_sa_state_t state)
{
ha_sync_message_t *m;
switch (state)
{
case IKE_ESTABLISHED:
{
iterator_t *iterator;
peer_cfg_t *peer_cfg;
u_int32_t extension, condition;
host_t *local_vip, *remote_vip, *addr;
identification_t *eap_id;
peer_cfg = ike_sa->get_peer_cfg(ike_sa);
condition = copy_condition(ike_sa, COND_NAT_ANY)
| copy_condition(ike_sa, COND_NAT_HERE)
| copy_condition(ike_sa, COND_NAT_THERE)
| copy_condition(ike_sa, COND_NAT_FAKE)
| copy_condition(ike_sa, COND_EAP_AUTHENTICATED)
| copy_condition(ike_sa, COND_CERTREQ_SEEN)
| copy_condition(ike_sa, COND_ORIGINAL_INITIATOR);
extension = copy_extension(ike_sa, EXT_NATT)
| copy_extension(ike_sa, EXT_MOBIKE)
| copy_extension(ike_sa, EXT_HASH_AND_URL);
local_vip = ike_sa->get_virtual_ip(ike_sa, TRUE);
remote_vip = ike_sa->get_virtual_ip(ike_sa, FALSE);
eap_id = ike_sa->get_eap_identity(ike_sa);
m = ha_sync_message_create(HA_SYNC_IKE_UPDATE);
m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa));
m->add_attribute(m, HA_SYNC_LOCAL_ID, ike_sa->get_my_id(ike_sa));
m->add_attribute(m, HA_SYNC_REMOTE_ID, ike_sa->get_other_id(ike_sa));
m->add_attribute(m, HA_SYNC_LOCAL_ADDR, ike_sa->get_my_host(ike_sa));
m->add_attribute(m, HA_SYNC_REMOTE_ADDR, ike_sa->get_other_host(ike_sa));
m->add_attribute(m, HA_SYNC_CONDITIONS, condition);
m->add_attribute(m, HA_SYNC_EXTENSIONS, extension);
m->add_attribute(m, HA_SYNC_CONFIG_NAME, peer_cfg->get_name(peer_cfg));
if (local_vip)
{
m->add_attribute(m, HA_SYNC_LOCAL_VIP, local_vip);
}
if (remote_vip)
{
m->add_attribute(m, HA_SYNC_REMOTE_VIP, remote_vip);
}
if (eap_id)
{
m->add_attribute(m, HA_SYNC_EAP_ID, eap_id);
}
iterator = ike_sa->create_additional_address_iterator(ike_sa);
while (iterator->iterate(iterator, (void**)&addr))
{
m->add_attribute(m, HA_SYNC_ADDITIONAL_ADDR, addr);
}
iterator->destroy(iterator);
break;
}
case IKE_DESTROYING:
{
m = ha_sync_message_create(HA_SYNC_IKE_DELETE);
m->add_attribute(m, HA_SYNC_IKE_ID, ike_sa->get_id(ike_sa));
break;
}
default:
return TRUE;
}
this->socket->push(this->socket, m);
m->destroy(m);
return TRUE;
}
/**
* Implementation of ha_sync_ike_t.destroy.
*/
@@ -163,6 +214,7 @@ ha_sync_ike_t *ha_sync_ike_create(ha_sync_socket_t *socket)
memset(&this->public.listener, 0, sizeof(listener_t));
this->public.listener.ike_keys = (bool(*)(listener_t*, ike_sa_t *ike_sa, diffie_hellman_t *dh,chunk_t nonce_i, chunk_t nonce_r, ike_sa_t *rekey))ike_keys;
this->public.listener.ike_state_change = (bool(*)(listener_t*,ike_sa_t *ike_sa, ike_sa_state_t state))ike_state_change;
this->public.destroy = (void(*)(ha_sync_ike_t*))destroy;
this->socket = socket;
+30 -1
View File
@@ -191,6 +191,20 @@ static void add_attribute(private_ha_sync_message_t *this,
this->buf.len += len;
break;
}
/* u_int16_t */
case HA_SYNC_ALG_PRF:
case HA_SYNC_ALG_ENCR:
case HA_SYNC_ALG_ENCR_LEN:
case HA_SYNC_ALG_INTEG:
{
u_int16_t val;
val = (u_int16_t)va_arg(args, u_int32_t);
check_buf(this, sizeof(val));
*(u_int16_t*)(this->buf.ptr + this->buf.len) = htons(val);
this->buf.len += sizeof(val);
break;
}
/** u_int32_t */
case HA_SYNC_CONDITIONS:
case HA_SYNC_EXTENSIONS:
@@ -199,7 +213,7 @@ static void add_attribute(private_ha_sync_message_t *this,
val = va_arg(args, u_int32_t);
check_buf(this, sizeof(val));
this->buf.ptr[this->buf.len] = htonl(val);
*(u_int32_t*)(this->buf.ptr + this->buf.len) = htonl(val);
this->buf.len += sizeof(val);
break;
}
@@ -349,6 +363,21 @@ static bool attribute_enumerate(attribute_enumerator_t *this,
this->buf = chunk_skip(this->buf, len + 1);
return TRUE;
}
/** u_int16_t */
case HA_SYNC_ALG_PRF:
case HA_SYNC_ALG_ENCR:
case HA_SYNC_ALG_ENCR_LEN:
case HA_SYNC_ALG_INTEG:
{
if (this->buf.len < sizeof(u_int16_t))
{
return FALSE;
}
value->u16 = ntohs(*(u_int16_t*)this->buf.ptr);
*attr_out = attr;
this->buf = chunk_skip(this->buf, sizeof(u_int16_t));
return TRUE;
}
/** u_int32_t */
case HA_SYNC_CONDITIONS:
case HA_SYNC_EXTENSIONS:
@@ -92,6 +92,14 @@ enum ha_sync_message_attribute_t {
HA_SYNC_NONCE_R,
/** chunk_t, diffie hellman shared secret */
HA_SYNC_SECRET,
/** u_int16_t, pseudo random function */
HA_SYNC_ALG_PRF,
/** u_int16_t, encryption algorithm */
HA_SYNC_ALG_ENCR,
/** u_int16_t, encryption key size in bytes */
HA_SYNC_ALG_ENCR_LEN,
/** u_int16_t, integrity protection algorithm */
HA_SYNC_ALG_INTEG,
};
/**
@@ -99,6 +107,7 @@ enum ha_sync_message_attribute_t {
*/
union ha_sync_message_value_t {
u_int32_t u32;
u_int16_t u16;
char *str;
chunk_t chunk;
ike_sa_id_t *ike_sa_id;
+9 -1
View File
@@ -20,6 +20,7 @@
#include "ha_sync_child.h"
#include "ha_sync_socket.h"
#include "ha_sync_dispatcher.h"
#include "ha_sync_cache.h"
#include <daemon.h>
#include <config/child_cfg.h>
@@ -55,6 +56,11 @@ struct private_ha_sync_plugin_t {
* Dispatcher to process incoming messages
*/
ha_sync_dispatcher_t *dispatcher;
/**
* Local cache of a nodes synced SAs
*/
ha_sync_cache_t *cache;
};
/**
@@ -67,6 +73,7 @@ static void destroy(private_ha_sync_plugin_t *this)
this->ike->destroy(this->ike);
this->child->destroy(this->child);
this->dispatcher->destroy(this->dispatcher);
this->cache->destroy(this->cache);
this->socket->destroy(this->socket);
free(this);
}
@@ -86,7 +93,8 @@ plugin_t *plugin_create()
free(this);
return NULL;
}
this->dispatcher = ha_sync_dispatcher_create(this->socket);
this->cache = ha_sync_cache_create();
this->dispatcher = ha_sync_dispatcher_create(this->socket, this->cache);
this->ike = ha_sync_ike_create(this->socket);
this->child = ha_sync_child_create(this->socket);
charon->bus->add_listener(charon->bus, &this->ike->listener);