summaryrefslogtreecommitdiff
path: root/src/libcharon/sa
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa')
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_manager.c54
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_method.c47
-rw-r--r--src/libcharon/sa/authenticators/eap/eap_method.h30
-rw-r--r--src/libcharon/sa/authenticators/eap_authenticator.c122
-rw-r--r--src/libcharon/sa/authenticators/pubkey_authenticator.c6
-rw-r--r--src/libcharon/sa/child_sa.c532
-rw-r--r--src/libcharon/sa/connect_manager.c14
-rw-r--r--src/libcharon/sa/ike_sa.c237
-rw-r--r--src/libcharon/sa/ike_sa.h8
-rw-r--r--src/libcharon/sa/ike_sa_manager.c5
-rw-r--r--src/libcharon/sa/ike_sa_manager.h2
-rw-r--r--src/libcharon/sa/keymat.c348
-rw-r--r--src/libcharon/sa/keymat.h15
-rw-r--r--src/libcharon/sa/mediation_manager.c2
-rw-r--r--src/libcharon/sa/task_manager.c21
-rw-r--r--src/libcharon/sa/tasks/child_create.c4
-rw-r--r--src/libcharon/sa/tasks/child_delete.c17
-rw-r--r--src/libcharon/sa/tasks/child_rekey.c31
-rw-r--r--src/libcharon/sa/tasks/ike_auth.c12
-rw-r--r--src/libcharon/sa/tasks/ike_init.c2
-rw-r--r--src/libcharon/sa/tasks/ike_me.c10
-rw-r--r--src/libcharon/sa/tasks/ike_mobike.c215
-rw-r--r--src/libcharon/sa/tasks/ike_mobike.h5
-rw-r--r--src/libcharon/sa/tasks/ike_natd.c41
-rw-r--r--src/libcharon/sa/tasks/ike_rekey.c83
-rw-r--r--src/libcharon/sa/tasks/ike_vendor.c14
-rw-r--r--src/libcharon/sa/trap_manager.c5
27 files changed, 944 insertions, 938 deletions
diff --git a/src/libcharon/sa/authenticators/eap/eap_manager.c b/src/libcharon/sa/authenticators/eap/eap_manager.c
index f795183f0..bc2c4a617 100644
--- a/src/libcharon/sa/authenticators/eap/eap_manager.c
+++ b/src/libcharon/sa/authenticators/eap/eap_manager.c
@@ -68,12 +68,9 @@ struct private_eap_manager_t {
rwlock_t *lock;
};
-/**
- * Implementation of eap_manager_t.add_method.
- */
-static void add_method(private_eap_manager_t *this, eap_type_t type,
- u_int32_t vendor, eap_role_t role,
- eap_constructor_t constructor)
+METHOD(eap_manager_t, add_method, void,
+ private_eap_manager_t *this, eap_type_t type, u_int32_t vendor,
+ eap_role_t role, eap_constructor_t constructor)
{
eap_entry_t *entry = malloc_thing(eap_entry_t);
@@ -87,10 +84,8 @@ static void add_method(private_eap_manager_t *this, eap_type_t type,
this->lock->unlock(this->lock);
}
-/**
- * Implementation of eap_manager_t.remove_method.
- */
-static void remove_method(private_eap_manager_t *this, eap_constructor_t constructor)
+METHOD(eap_manager_t, remove_method, void,
+ private_eap_manager_t *this, eap_constructor_t constructor)
{
enumerator_t *enumerator;
eap_entry_t *entry;
@@ -109,13 +104,9 @@ static void remove_method(private_eap_manager_t *this, eap_constructor_t constru
this->lock->unlock(this->lock);
}
-/**
- * Implementation of eap_manager_t.create_instance.
- */
-static eap_method_t* create_instance(private_eap_manager_t *this,
- eap_type_t type, u_int32_t vendor,
- eap_role_t role, identification_t *server,
- identification_t *peer)
+METHOD(eap_manager_t, create_instance, eap_method_t*,
+ private_eap_manager_t *this, eap_type_t type, u_int32_t vendor,
+ eap_role_t role, identification_t *server, identification_t *peer)
{
enumerator_t *enumerator;
eap_entry_t *entry;
@@ -140,10 +131,8 @@ static eap_method_t* create_instance(private_eap_manager_t *this,
return method;
}
-/**
- * Implementation of 2008_t.destroy
- */
-static void destroy(private_eap_manager_t *this)
+METHOD(eap_manager_t, destroy, void,
+ private_eap_manager_t *this)
{
this->methods->destroy_function(this->methods, free);
this->lock->destroy(this->lock);
@@ -151,19 +140,22 @@ static void destroy(private_eap_manager_t *this)
}
/*
- * see header file
+ * See header
*/
eap_manager_t *eap_manager_create()
{
- private_eap_manager_t *this = malloc_thing(private_eap_manager_t);
-
- this->public.add_method = (void(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, eap_constructor_t constructor))add_method;
- this->public.remove_method = (void(*)(eap_manager_t*, eap_constructor_t constructor))remove_method;
- this->public.create_instance = (eap_method_t*(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, identification_t*,identification_t*))create_instance;
- this->public.destroy = (void(*)(eap_manager_t*))destroy;
-
- this->methods = linked_list_create();
- this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
+ private_eap_manager_t *this;
+
+ INIT(this,
+ .public = {
+ .add_method = _add_method,
+ .remove_method = _remove_method,
+ .create_instance = _create_instance,
+ .destroy = _destroy,
+ },
+ .methods = linked_list_create(),
+ .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
+ );
return &this->public;
}
diff --git a/src/libcharon/sa/authenticators/eap/eap_method.c b/src/libcharon/sa/authenticators/eap/eap_method.c
index ad7b92cfa..0fa4a00c5 100644
--- a/src/libcharon/sa/authenticators/eap/eap_method.c
+++ b/src/libcharon/sa/authenticators/eap/eap_method.c
@@ -15,55 +15,8 @@
#include "eap_method.h"
-/*
- * See header
- */
-eap_type_t eap_type_from_string(char *name)
-{
- int i;
- static struct {
- char *name;
- eap_type_t type;
- } types[] = {
- {"identity", EAP_IDENTITY},
- {"md5", EAP_MD5},
- {"otp", EAP_OTP},
- {"gtc", EAP_GTC},
- {"sim", EAP_SIM},
- {"aka", EAP_AKA},
- {"mschapv2", EAP_MSCHAPV2},
- {"radius", EAP_RADIUS},
- };
-
- for (i = 0; i < countof(types); i++)
- {
- if (strcaseeq(name, types[i].name))
- {
- return types[i].type;
- }
- }
- return 0;
-}
-
-ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE,
- "EAP_REQUEST",
- "EAP_RESPONSE",
- "EAP_SUCCESS",
- "EAP_FAILURE",
-);
-
-ENUM(eap_code_short_names, EAP_REQUEST, EAP_FAILURE,
- "REQ",
- "RES",
- "SUCC",
- "FAIL",
-);
-
ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
"EAP_SERVER",
"EAP_PEER",
);
-
-
-
diff --git a/src/libcharon/sa/authenticators/eap/eap_method.h b/src/libcharon/sa/authenticators/eap/eap_method.h
index df354edb4..9961039ff 100644
--- a/src/libcharon/sa/authenticators/eap/eap_method.h
+++ b/src/libcharon/sa/authenticators/eap/eap_method.h
@@ -23,10 +23,10 @@
typedef struct eap_method_t eap_method_t;
typedef enum eap_role_t eap_role_t;
-typedef enum eap_code_t eap_code_t;
#include <library.h>
#include <utils/identification.h>
+#include <eap/eap.h>
#include <encoding/payloads/eap_payload.h>
/**
@@ -42,34 +42,6 @@ enum eap_role_t {
extern enum_name_t *eap_role_names;
/**
- * Lookup the EAP method type from a string.
- *
- * @param name EAP method name (such as "md5", "aka")
- * @return method type, 0 if unkown
- */
-eap_type_t eap_type_from_string(char *name);
-
-/**
- * EAP code, type of an EAP message
- */
-enum eap_code_t {
- EAP_REQUEST = 1,
- EAP_RESPONSE = 2,
- EAP_SUCCESS = 3,
- EAP_FAILURE = 4,
-};
-
-/**
- * enum names for eap_code_t.
- */
-extern enum_name_t *eap_code_names;
-
-/**
- * short string enum names for eap_code_t.
- */
-extern enum_name_t *eap_code_short_names;
-
-/**
* Interface of an EAP method for server and client side.
*
* An EAP method initiates an EAP exchange and processes requests and
diff --git a/src/libcharon/sa/authenticators/eap_authenticator.c b/src/libcharon/sa/authenticators/eap_authenticator.c
index 3c0f3c358..8b22fd1d7 100644
--- a/src/libcharon/sa/authenticators/eap_authenticator.c
+++ b/src/libcharon/sa/authenticators/eap_authenticator.c
@@ -99,22 +99,30 @@ struct private_eap_authenticator_t {
static eap_method_t *load_method(private_eap_authenticator_t *this,
eap_type_t type, u_int32_t vendor, eap_role_t role)
{
- identification_t *server, *peer;
+ identification_t *server, *peer, *aaa;
+ auth_cfg_t *auth;
if (role == EAP_SERVER)
{
server = this->ike_sa->get_my_id(this->ike_sa);
peer = this->ike_sa->get_other_id(this->ike_sa);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
}
else
{
server = this->ike_sa->get_other_id(this->ike_sa);
peer = this->ike_sa->get_my_id(this->ike_sa);
+ auth = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
}
if (this->eap_identity)
{
peer = this->eap_identity;
}
+ aaa = auth->get(auth, AUTH_RULE_AAA_IDENTITY);
+ if (aaa)
+ {
+ server = aaa;
+ }
return charon->eap->create_instance(charon->eap, type, vendor,
role, server, peer);
}
@@ -458,11 +466,8 @@ static void build_auth(private_eap_authenticator_t *this, message_t *message,
chunk_free(&auth_data);
}
-/**
- * Implementation of authenticator_t.process for a server
- */
-static status_t process_server(private_eap_authenticator_t *this,
- message_t *message)
+METHOD(authenticator_t, process_server, status_t,
+ private_eap_authenticator_t *this, message_t *message)
{
eap_payload_t *eap_payload;
@@ -492,11 +497,8 @@ static status_t process_server(private_eap_authenticator_t *this,
return NEED_MORE;
}
-/**
- * Implementation of authenticator_t.build for a server
- */
-static status_t build_server(private_eap_authenticator_t *this,
- message_t *message)
+METHOD(authenticator_t, build_server, status_t,
+ private_eap_authenticator_t *this, message_t *message)
{
if (this->eap_payload)
{
@@ -519,11 +521,8 @@ static status_t build_server(private_eap_authenticator_t *this,
return FAILED;
}
-/**
- * Implementation of authenticator_t.process for a client
- */
-static status_t process_client(private_eap_authenticator_t *this,
- message_t *message)
+METHOD(authenticator_t, process_client, status_t,
+ private_eap_authenticator_t *this, message_t *message)
{
eap_payload_t *eap_payload;
@@ -603,11 +602,8 @@ static status_t process_client(private_eap_authenticator_t *this,
return FAILED;
}
-/**
- * Implementation of authenticator_t.build for a client
- */
-static status_t build_client(private_eap_authenticator_t *this,
- message_t *message)
+METHOD(authenticator_t, build_client, status_t,
+ private_eap_authenticator_t *this, message_t *message)
{
if (this->eap_payload)
{
@@ -623,20 +619,16 @@ static status_t build_client(private_eap_authenticator_t *this,
return NEED_MORE;
}
-/**
- * Implementation of authenticator_t.is_mutual.
- */
-static bool is_mutual(private_eap_authenticator_t *this)
+METHOD(authenticator_t, is_mutual, bool,
+ private_eap_authenticator_t *this)
{
/* we don't know yet, but insist on it after EAP is complete */
this->require_mutual = TRUE;
return TRUE;
}
-/**
- * Implementation of authenticator_t.destroy.
- */
-static void destroy(private_eap_authenticator_t *this)
+METHOD(authenticator_t, destroy, void,
+ private_eap_authenticator_t *this)
{
DESTROY_IF(this->method);
DESTROY_IF(this->eap_payload);
@@ -652,25 +644,23 @@ eap_authenticator_t *eap_authenticator_create_builder(ike_sa_t *ike_sa,
chunk_t received_nonce, chunk_t sent_nonce,
chunk_t received_init, chunk_t sent_init)
{
- private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
-
- this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *message))build_client;
- this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_client;
- this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))is_mutual;
- this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
-
- this->ike_sa = ike_sa;
- this->received_init = received_init;
- this->received_nonce = received_nonce;
- this->sent_init = sent_init;
- this->sent_nonce = sent_nonce;
- this->msk = chunk_empty;
- this->method = NULL;
- this->eap_payload = NULL;
- this->eap_complete = FALSE;
- this->auth_complete = FALSE;
- this->eap_identity = NULL;
- this->require_mutual = FALSE;
+ private_eap_authenticator_t *this;
+
+ INIT(this,
+ .public = {
+ .authenticator = {
+ .build = _build_client,
+ .process = _process_client,
+ .is_mutual = _is_mutual,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ .received_init = received_init,
+ .received_nonce = received_nonce,
+ .sent_init = sent_init,
+ .sent_nonce = sent_nonce,
+ );
return &this->public;
}
@@ -682,25 +672,23 @@ eap_authenticator_t *eap_authenticator_create_verifier(ike_sa_t *ike_sa,
chunk_t received_nonce, chunk_t sent_nonce,
chunk_t received_init, chunk_t sent_init)
{
- private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
-
- this->public.authenticator.build = (status_t(*)(authenticator_t*, message_t *messageh))build_server;
- this->public.authenticator.process = (status_t(*)(authenticator_t*, message_t *message))process_server;
- this->public.authenticator.is_mutual = (bool(*)(authenticator_t*))is_mutual;
- this->public.authenticator.destroy = (void(*)(authenticator_t*))destroy;
-
- this->ike_sa = ike_sa;
- this->received_init = received_init;
- this->received_nonce = received_nonce;
- this->sent_init = sent_init;
- this->sent_nonce = sent_nonce;
- this->msk = chunk_empty;
- this->method = NULL;
- this->eap_payload = NULL;
- this->eap_complete = FALSE;
- this->auth_complete = FALSE;
- this->eap_identity = NULL;
- this->require_mutual = FALSE;
+ private_eap_authenticator_t *this;
+
+ INIT(this,
+ .public = {
+ .authenticator = {
+ .build = _build_server,
+ .process = _process_server,
+ .is_mutual = _is_mutual,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ .received_init = received_init,
+ .received_nonce = received_nonce,
+ .sent_init = sent_init,
+ .sent_nonce = sent_nonce,
+ );
return &this->public;
}
diff --git a/src/libcharon/sa/authenticators/pubkey_authenticator.c b/src/libcharon/sa/authenticators/pubkey_authenticator.c
index 3c67f6db6..54b4338bb 100644
--- a/src/libcharon/sa/authenticators/pubkey_authenticator.c
+++ b/src/libcharon/sa/authenticators/pubkey_authenticator.c
@@ -84,15 +84,15 @@ static status_t build(private_pubkey_authenticator_t *this, message_t *message)
/* we try to deduct the signature scheme from the keysize */
switch (private->get_keysize(private))
{
- case 32:
+ case 256:
scheme = SIGN_ECDSA_256;
auth_method = AUTH_ECDSA_256;
break;
- case 48:
+ case 384:
scheme = SIGN_ECDSA_384;
auth_method = AUTH_ECDSA_384;
break;
- case 66:
+ case 521:
scheme = SIGN_ECDSA_521;
auth_method = AUTH_ECDSA_521;
break;
diff --git a/src/libcharon/sa/child_sa.c b/src/libcharon/sa/child_sa.c
index bd41cba56..b6ef31da0 100644
--- a/src/libcharon/sa/child_sa.c
+++ b/src/libcharon/sa/child_sa.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2009 Tobias Brunner
+ * Copyright (C) 2006-2010 Tobias Brunner
* Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2006 Daniel Roethlisberger
* Copyright (C) 2005 Jan Hutter
@@ -23,6 +23,7 @@
#include <string.h>
#include <time.h>
+#include <hydra.h>
#include <daemon.h>
ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
@@ -179,170 +180,144 @@ struct private_child_sa_t {
};
/**
- * Implementation of child_sa_t.get_name
+ * convert an IKEv2 specific protocol identifier to the IP protocol identifier.
*/
-static char *get_name(private_child_sa_t *this)
+static inline u_int8_t proto_ike2ip(protocol_id_t protocol)
+{
+ switch (protocol)
+ {
+ case PROTO_ESP:
+ return IPPROTO_ESP;
+ case PROTO_AH:
+ return IPPROTO_AH;
+ default:
+ return protocol;
+ }
+}
+
+METHOD(child_sa_t, get_name, char*,
+ private_child_sa_t *this)
{
return this->config->get_name(this->config);
}
-/**
- * Implements child_sa_t.get_reqid
- */
-static u_int32_t get_reqid(private_child_sa_t *this)
+METHOD(child_sa_t, get_reqid, u_int32_t,
+ private_child_sa_t *this)
{
return this->reqid;
}
-/**
- * Implements child_sa_t.get_config
- */
-static child_cfg_t* get_config(private_child_sa_t *this)
+METHOD(child_sa_t, get_config, child_cfg_t*,
+ private_child_sa_t *this)
{
return this->config;
}
-/**
- * Implements child_sa_t.set_state
- */
-static void set_state(private_child_sa_t *this, child_sa_state_t state)
+METHOD(child_sa_t, set_state, void,
+ private_child_sa_t *this, child_sa_state_t state)
{
charon->bus->child_state_change(charon->bus, &this->public, state);
this->state = state;
}
-/**
- * Implements child_sa_t.get_state
- */
-static child_sa_state_t get_state(private_child_sa_t *this)
+METHOD(child_sa_t, get_state, child_sa_state_t,
+ private_child_sa_t *this)
{
return this->state;
}
-/**
- * Implements child_sa_t.get_spi
- */
-u_int32_t get_spi(private_child_sa_t *this, bool inbound)
+METHOD(child_sa_t, get_spi, u_int32_t,
+ private_child_sa_t *this, bool inbound)
{
return inbound ? this->my_spi : this->other_spi;
}
-/**
- * Implements child_sa_t.get_cpi
- */
-u_int16_t get_cpi(private_child_sa_t *this, bool inbound)
+METHOD(child_sa_t, get_cpi, u_int16_t,
+ private_child_sa_t *this, bool inbound)
{
return inbound ? this->my_cpi : this->other_cpi;
}
-/**
- * Implements child_sa_t.get_protocol
- */
-protocol_id_t get_protocol(private_child_sa_t *this)
+METHOD(child_sa_t, get_protocol, protocol_id_t,
+ private_child_sa_t *this)
{
return this->protocol;
}
-/**
- * Implementation of child_sa_t.set_protocol
- */
-static void set_protocol(private_child_sa_t *this, protocol_id_t protocol)
+METHOD(child_sa_t, set_protocol, void,
+ private_child_sa_t *this, protocol_id_t protocol)
{
this->protocol = protocol;
}
-/**
- * Implementation of child_sa_t.get_mode
- */
-static ipsec_mode_t get_mode(private_child_sa_t *this)
+METHOD(child_sa_t, get_mode, ipsec_mode_t,
+ private_child_sa_t *this)
{
return this->mode;
}
-/**
- * Implementation of child_sa_t.set_mode
- */
-static void set_mode(private_child_sa_t *this, ipsec_mode_t mode)
+METHOD(child_sa_t, set_mode, void,
+ private_child_sa_t *this, ipsec_mode_t mode)
{
this->mode = mode;
}
-/**
- * Implementation of child_sa_t.has_encap
- */
-static bool has_encap(private_child_sa_t *this)
+METHOD(child_sa_t, has_encap, bool,
+ private_child_sa_t *this)
{
return this->encap;
}
-/**
- * Implementation of child_sa_t.get_ipcomp
- */
-static ipcomp_transform_t get_ipcomp(private_child_sa_t *this)
+METHOD(child_sa_t, get_ipcomp, ipcomp_transform_t,
+ private_child_sa_t *this)
{
return this->ipcomp;
}
-/**
- * Implementation of child_sa_t.set_ipcomp.
- */
-static void set_ipcomp(private_child_sa_t *this, ipcomp_transform_t ipcomp)
+METHOD(child_sa_t, set_ipcomp, void,
+ private_child_sa_t *this, ipcomp_transform_t ipcomp)
{
this->ipcomp = ipcomp;
}
-/**
- * Implementation of child_sa_t.set_close_action.
- */
-static void set_close_action(private_child_sa_t *this, action_t action)
+METHOD(child_sa_t, set_close_action, void,
+ private_child_sa_t *this, action_t action)
{
this->close_action = action;
}
-/**
- * Implementation of child_sa_t.get_close_action.
- */
-static action_t get_close_action(private_child_sa_t *this)
+METHOD(child_sa_t, get_close_action, action_t,
+ private_child_sa_t *this)
{
return this->close_action;
}
-/**
- * Implementation of child_sa_t.set_dpd_action.
- */
-static void set_dpd_action(private_child_sa_t *this, action_t action)
+METHOD(child_sa_t, set_dpd_action, void,
+ private_child_sa_t *this, action_t action)
{
this->dpd_action = action;
}
-/**
- * Implementation of child_sa_t.get_dpd_action.
- */
-static action_t get_dpd_action(private_child_sa_t *this)
+METHOD(child_sa_t, get_dpd_action, action_t,
+ private_child_sa_t *this)
{
return this->dpd_action;
}
-/**
- * Implementation of child_sa_t.get_proposal
- */
-static proposal_t* get_proposal(private_child_sa_t *this)
+METHOD(child_sa_t, get_proposal, proposal_t*,
+ private_child_sa_t *this)
{
return this->proposal;
}
-/**
- * Implementation of child_sa_t.set_proposal
- */
-static void set_proposal(private_child_sa_t *this, proposal_t *proposal)
+METHOD(child_sa_t, set_proposal, void,
+ private_child_sa_t *this, proposal_t *proposal)
{
this->proposal = proposal->clone(proposal);
}
-/**
- * Implementation of child_sa_t.get_traffic_selectors.
- */
-static linked_list_t *get_traffic_selectors(private_child_sa_t *this, bool local)
+METHOD(child_sa_t, get_traffic_selectors, linked_list_t*,
+ private_child_sa_t *this, bool local)
{
return local ? this->my_ts : this->other_ts;
}
@@ -365,11 +340,9 @@ struct policy_enumerator_t {
traffic_selector_t *ts;
};
-/**
- * enumerator function of create_policy_enumerator()
- */
-static bool policy_enumerate(policy_enumerator_t *this,
- traffic_selector_t **my_out, traffic_selector_t **other_out)
+METHOD(enumerator_t, policy_enumerate, bool,
+ policy_enumerator_t *this, traffic_selector_t **my_out,
+ traffic_selector_t **other_out)
{
traffic_selector_t *other_ts;
@@ -399,29 +372,29 @@ static bool policy_enumerate(policy_enumerator_t *this,
return FALSE;
}
-/**
- * destroy function of create_policy_enumerator()
- */
-static void policy_destroy(policy_enumerator_t *this)
+METHOD(enumerator_t, policy_destroy, void,
+ policy_enumerator_t *this)
{
this->mine->destroy(this->mine);
this->other->destroy(this->other);
free(this);
}
-/**
- * Implementation of child_sa_t.create_policy_enumerator
- */
-static enumerator_t* create_policy_enumerator(private_child_sa_t *this)
+METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
+ private_child_sa_t *this)
{
- policy_enumerator_t *e = malloc_thing(policy_enumerator_t);
-
- e->public.enumerate = (void*)policy_enumerate;
- e->public.destroy = (void*)policy_destroy;
- e->mine = this->my_ts->create_enumerator(this->my_ts);
- e->other = this->other_ts->create_enumerator(this->other_ts);
- e->list = this->other_ts;
- e->ts = NULL;
+ policy_enumerator_t *e;
+
+ INIT(e,
+ .public = {
+ .enumerate = (void*)_policy_enumerate,
+ .destroy = _policy_destroy,
+ },
+ .mine = this->my_ts->create_enumerator(this->my_ts),
+ .other = this->other_ts->create_enumerator(this->other_ts),
+ .list = this->other_ts,
+ .ts = NULL,
+ );
return &e->public;
}
@@ -441,10 +414,10 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
{
if (this->my_spi)
{
- status = charon->kernel_interface->query_sa(charon->kernel_interface,
- this->other_addr, this->my_addr,
- this->my_spi, this->protocol,
- this->mark_in, &bytes);
+ status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
+ this->other_addr, this->my_addr, this->my_spi,
+ proto_ike2ip(this->protocol), this->mark_in,
+ &bytes);
if (status == SUCCESS)
{
if (bytes > this->my_usebytes)
@@ -460,10 +433,10 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
{
if (this->other_spi)
{
- status = charon->kernel_interface->query_sa(charon->kernel_interface,
- this->my_addr, this->other_addr,
- this->other_spi, this->protocol,
- this->mark_out, &bytes);
+ status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
+ this->my_addr, this->other_addr, this->other_spi,
+ proto_ike2ip(this->protocol), this->mark_out,
+ &bytes);
if (status == SUCCESS)
{
if (bytes > this->other_usebytes)
@@ -494,14 +467,14 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
if (inbound)
{
- if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
other_ts, my_ts, POLICY_IN, this->mark_in, &in) == SUCCESS)
{
last_use = max(last_use, in);
}
if (this->mode != MODE_TRANSPORT)
{
- if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
other_ts, my_ts, POLICY_FWD, this->mark_in, &fwd) == SUCCESS)
{
last_use = max(last_use, fwd);
@@ -510,7 +483,7 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
}
else
{
- if (charon->kernel_interface->query_policy(charon->kernel_interface,
+ if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
my_ts, other_ts, POLICY_OUT, this->mark_out, &out) == SUCCESS)
{
last_use = max(last_use, out);
@@ -533,11 +506,8 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
}
}
-/**
- * Implementation of child_sa_t.get_usestats
- */
-static void get_usestats(private_child_sa_t *this, bool inbound,
- time_t *time, u_int64_t *bytes)
+METHOD(child_sa_t, get_usestats, void,
+ private_child_sa_t *this, bool inbound, time_t *time, u_int64_t *bytes)
{
if (update_usebytes(this, inbound) != FAILED)
{
@@ -556,48 +526,41 @@ static void get_usestats(private_child_sa_t *this, bool inbound,
}
}
-/**
- * Implementation of child_sa_t.get_lifetime
- */
-static time_t get_lifetime(private_child_sa_t *this, bool hard)
+METHOD(child_sa_t, get_lifetime, time_t,
+ private_child_sa_t *this, bool hard)
{
return hard ? this->expire_time : this->rekey_time;
}
-/**
- * Implementation of child_sa_t.alloc_spi
- */
-static u_int32_t alloc_spi(private_child_sa_t *this, protocol_id_t protocol)
+METHOD(child_sa_t, alloc_spi, u_int32_t,
+ private_child_sa_t *this, protocol_id_t protocol)
{
- if (charon->kernel_interface->get_spi(charon->kernel_interface,
- this->other_addr, this->my_addr, protocol,
- this->reqid, &this->my_spi) == SUCCESS)
+ if (hydra->kernel_interface->get_spi(hydra->kernel_interface,
+ this->other_addr, this->my_addr,
+ proto_ike2ip(protocol), this->reqid,
+ &this->my_spi) == SUCCESS)
{
return this->my_spi;
}
return 0;
}
-/**
- * Implementation of child_sa_t.alloc_cpi
- */
-static u_int16_t alloc_cpi(private_child_sa_t *this)
+METHOD(child_sa_t, alloc_cpi, u_int16_t,
+ private_child_sa_t *this)
{
- if (charon->kernel_interface->get_cpi(charon->kernel_interface,
- this->other_addr, this->my_addr, this->reqid,
- &this->my_cpi) == SUCCESS)
+ if (hydra->kernel_interface->get_cpi(hydra->kernel_interface,
+ this->other_addr, this->my_addr,
+ this->reqid, &this->my_cpi) == SUCCESS)
{
return this->my_cpi;
}
return 0;
}
-/**
- * Implementation of child_sa_t.install
- */
-static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
- u_int32_t spi, u_int16_t cpi, bool inbound,
- linked_list_t *my_ts, linked_list_t *other_ts)
+METHOD(child_sa_t, install, status_t,
+ private_child_sa_t *this, chunk_t encr, chunk_t integ, u_int32_t spi,
+ u_int16_t cpi, bool inbound, linked_list_t *my_ts,
+ linked_list_t *other_ts)
{
u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
traffic_selector_t *src_ts = NULL, *dst_ts = NULL;
@@ -674,8 +637,8 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
}
}
- status = charon->kernel_interface->add_sa(charon->kernel_interface,
- src, dst, spi, this->protocol, this->reqid,
+ status = hydra->kernel_interface->add_sa(hydra->kernel_interface,
+ src, dst, spi, proto_ike2ip(this->protocol), this->reqid,
inbound ? this->mark_in : this->mark_out,
lifetime, enc_alg, encr, int_alg, integ, this->mode,
this->ipcomp, cpi, this->encap, update, src_ts, dst_ts);
@@ -685,11 +648,9 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
return status;
}
-/**
- * Implementation of child_sa_t.add_policies
- */
-static status_t add_policies(private_child_sa_t *this,
- linked_list_t *my_ts_list, linked_list_t *other_ts_list)
+METHOD(child_sa_t, add_policies, status_t,
+ private_child_sa_t *this, linked_list_t *my_ts_list,
+ linked_list_t *other_ts_list)
{
enumerator_t *enumerator;
traffic_selector_t *my_ts, *other_ts;
@@ -712,26 +673,55 @@ static status_t add_policies(private_child_sa_t *this,
if (this->config->install_policy(this->config))
{
+ ipsec_sa_cfg_t my_sa = {
+ .mode = this->mode,
+ .reqid = this->reqid,
+ .ipcomp = {
+ .transform = this->ipcomp,
+ },
+ }, other_sa = my_sa;
+
+ my_sa.ipcomp.cpi = this->my_cpi;
+ other_sa.ipcomp.cpi = this->other_cpi;
+
+ if (this->protocol == PROTO_ESP)
+ {
+ my_sa.esp.use = TRUE;
+ my_sa.esp.spi = this->my_spi;
+ other_sa.esp.use = TRUE;
+ other_sa.esp.spi = this->other_spi;
+ }
+ else
+ {
+ my_sa.ah.use = TRUE;
+ my_sa.ah.spi = this->my_spi;
+ other_sa.ah.use = TRUE;
+ other_sa.ah.spi = this->other_spi;
+ }
+
/* enumerate pairs of traffic selectors */
enumerator = create_policy_enumerator(this);
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
/* install 3 policies: out, in and forward */
- status |= charon->kernel_interface->add_policy(charon->kernel_interface,
- this->my_addr, this->other_addr, my_ts, other_ts, POLICY_OUT,
- this->other_spi, this->protocol, this->reqid, this->mark_out,
- this->mode, this->ipcomp, this->other_cpi, routed);
-
- status |= charon->kernel_interface->add_policy(charon->kernel_interface,
- this->other_addr, this->my_addr, other_ts, my_ts, POLICY_IN,
- this->my_spi, this->protocol, this->reqid, this->mark_in,
- this->mode, this->ipcomp, this->my_cpi, routed);
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface,
+ this->my_addr, this->other_addr, my_ts, other_ts,
+ POLICY_OUT, POLICY_IPSEC, &other_sa,
+ this->mark_out, routed);
+
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface,
+ this->other_addr, this->my_addr, other_ts, my_ts,
+ POLICY_IN, POLICY_IPSEC, &my_sa,
+ this->mark_in, routed);
if (this->mode != MODE_TRANSPORT)
{
- status |= charon->kernel_interface->add_policy(charon->kernel_interface,
- this->other_addr, this->my_addr, other_ts, my_ts, POLICY_FWD,
- this->my_spi, this->protocol, this->reqid, this->mark_in,
- this->mode, this->ipcomp, this->my_cpi, routed);
+ status |= hydra->kernel_interface->add_policy(
+ hydra->kernel_interface,
+ this->other_addr, this->my_addr, other_ts, my_ts,
+ POLICY_FWD, POLICY_IPSEC, &my_sa,
+ this->mark_in, routed);
}
if (status != SUCCESS)
@@ -749,11 +739,9 @@ static status_t add_policies(private_child_sa_t *this,
return status;
}
-/**
- * Implementation of child_sa_t.update.
- */
-static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
- host_t *vip, bool encap)
+METHOD(child_sa_t, update, status_t,
+ private_child_sa_t *this, host_t *me, host_t *other, host_t *vip,
+ bool encap)
{
child_sa_state_t old;
bool transport_proxy_mode;
@@ -775,8 +763,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
/* update our (initator) SA */
if (this->my_spi)
{
- if (charon->kernel_interface->update_sa(charon->kernel_interface,
- this->my_spi, this->protocol,
+ if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
+ this->my_spi, proto_ike2ip(this->protocol),
this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
this->other_addr, this->my_addr, other, me,
this->encap, encap, this->mark_in) == NOT_SUPPORTED)
@@ -788,8 +776,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
/* update his (responder) SA */
if (this->other_spi)
{
- if (charon->kernel_interface->update_sa(charon->kernel_interface,
- this->other_spi, this->protocol,
+ if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
+ this->other_spi, proto_ike2ip(this->protocol),
this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
this->my_addr, this->other_addr, me, other,
this->encap, encap, this->mark_out) == NOT_SUPPORTED)
@@ -801,6 +789,32 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
if (this->config->install_policy(this->config))
{
+ ipsec_sa_cfg_t my_sa = {
+ .mode = this->mode,
+ .reqid = this->reqid,
+ .ipcomp = {
+ .transform = this->ipcomp,
+ },
+ }, other_sa = my_sa;
+
+ my_sa.ipcomp.cpi = this->my_cpi;
+ other_sa.ipcomp.cpi = this->other_cpi;
+
+ if (this->protocol == PROTO_ESP)
+ {
+ my_sa.esp.use = TRUE;
+ my_sa.esp.spi = this->my_spi;
+ other_sa.esp.use = TRUE;
+ other_sa.esp.spi = this->other_spi;
+ }
+ else
+ {
+ my_sa.ah.use = TRUE;
+ my_sa.ah.spi = this->my_spi;
+ other_sa.ah.use = TRUE;
+ other_sa.ah.spi = this->other_spi;
+ }
+
/* update policies */
if (!me->ip_equals(me, this->my_addr) ||
!other->ip_equals(other, this->other_addr))
@@ -813,13 +827,13 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
/* remove old policies first */
- charon->kernel_interface->del_policy(charon->kernel_interface,
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
my_ts, other_ts, POLICY_OUT, this->mark_out, FALSE);
- charon->kernel_interface->del_policy(charon->kernel_interface,
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
other_ts, my_ts, POLICY_IN, this->mark_in, FALSE);
if (this->mode != MODE_TRANSPORT)
{
- charon->kernel_interface->del_policy(charon->kernel_interface,
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
other_ts, my_ts, POLICY_FWD, this->mark_in, FALSE);
}
@@ -839,25 +853,22 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
* correctly */
if (vip)
{
- charon->kernel_interface->del_ip(charon->kernel_interface, vip);
- charon->kernel_interface->add_ip(charon->kernel_interface, vip, me);
+ hydra->kernel_interface->del_ip(hydra->kernel_interface, vip);
+ hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, me);
}
/* reinstall updated policies */
- charon->kernel_interface->add_policy(charon->kernel_interface,
- me, other, my_ts, other_ts, POLICY_OUT, this->other_spi,
- this->protocol, this->reqid, this->mark_out, this->mode,
- this->ipcomp, this->other_cpi, FALSE);
- charon->kernel_interface->add_policy(charon->kernel_interface,
- other, me, other_ts, my_ts, POLICY_IN, this->my_spi,
- this->protocol, this->reqid, this->mark_in, this->mode,
- this->ipcomp, this->my_cpi, FALSE);
+ hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ me, other, my_ts, other_ts, POLICY_OUT, POLICY_IPSEC,
+ &other_sa, this->mark_out, FALSE);
+ hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ other, me, other_ts, my_ts, POLICY_IN, POLICY_IPSEC,
+ &my_sa, this->mark_in, FALSE);
if (this->mode != MODE_TRANSPORT)
{
- charon->kernel_interface->add_policy(charon->kernel_interface,
- other, me, other_ts, my_ts, POLICY_FWD, this->my_spi,
- this->protocol, this->reqid, this->mark_in, this->mode,
- this->ipcomp, this->my_cpi, FALSE);
+ hydra->kernel_interface->add_policy(hydra->kernel_interface,
+ other, me, other_ts, my_ts, POLICY_FWD, POLICY_IPSEC,
+ &my_sa, this->mark_in, FALSE);
}
}
enumerator->destroy(enumerator);
@@ -885,10 +896,8 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
return SUCCESS;
}
-/**
- * Implementation of child_sa_t.destroy.
- */
-static void destroy(private_child_sa_t *this)
+METHOD(child_sa_t, destroy, void,
+ private_child_sa_t *this)
{
enumerator_t *enumerator;
traffic_selector_t *my_ts, *other_ts;
@@ -905,15 +914,17 @@ static void destroy(private_child_sa_t *this)
{
this->protocol = PROTO_ESP;
}
- charon->kernel_interface->del_sa(charon->kernel_interface,
+ hydra->kernel_interface->del_sa(hydra->kernel_interface,
this->other_addr, this->my_addr, this->my_spi,
- this->protocol, this->my_cpi, this->mark_in);
+ proto_ike2ip(this->protocol), this->my_cpi,
+ this->mark_in);
}
if (this->other_spi)
{
- charon->kernel_interface->del_sa(charon->kernel_interface,
+ hydra->kernel_interface->del_sa(hydra->kernel_interface,
this->my_addr, this->other_addr, this->other_spi,
- this->protocol, this->other_cpi, this->mark_out);
+ proto_ike2ip(this->protocol), this->other_cpi,
+ this->mark_out);
}
if (this->config->install_policy(this->config))
@@ -922,14 +933,14 @@ static void destroy(private_child_sa_t *this)
enumerator = create_policy_enumerator(this);
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
{
- charon->kernel_interface->del_policy(charon->kernel_interface,
- my_ts, other_ts, POLICY_OUT, this->mark_out, unrouted);
- charon->kernel_interface->del_policy(charon->kernel_interface,
- other_ts, my_ts, POLICY_IN, this->mark_in, unrouted);
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ my_ts, other_ts, POLICY_OUT, this->mark_out, unrouted);
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ other_ts, my_ts, POLICY_IN, this->mark_in, unrouted);
if (this->mode != MODE_TRANSPORT)
{
- charon->kernel_interface->del_policy(charon->kernel_interface,
- other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted);
+ hydra->kernel_interface->del_policy(hydra->kernel_interface,
+ other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted);
}
}
enumerator->destroy(enumerator);
@@ -944,75 +955,66 @@ static void destroy(private_child_sa_t *this)
free(this);
}
-/*
+/**
* Described in header.
*/
child_sa_t * child_sa_create(host_t *me, host_t* other,
child_cfg_t *config, u_int32_t rekey, bool encap)
{
static u_int32_t reqid = 0;
- private_child_sa_t *this = malloc_thing(private_child_sa_t);
-
- /* public functions */
- this->public.get_name = (char*(*)(child_sa_t*))get_name;
- this->public.get_reqid = (u_int32_t(*)(child_sa_t*))get_reqid;
- this->public.get_config = (child_cfg_t*(*)(child_sa_t*))get_config;
- this->public.get_state = (child_sa_state_t(*)(child_sa_t*))get_state;
- this->public.set_state = (void(*)(child_sa_t*,child_sa_state_t))set_state;
- this->public.get_spi = (u_int32_t(*)(child_sa_t*, bool))get_spi;
- this->public.get_cpi = (u_int16_t(*)(child_sa_t*, bool))get_cpi;
- this->public.get_protocol = (protocol_id_t(*)(child_sa_t*))get_protocol;
- this->public.set_protocol = (void(*)(child_sa_t*, protocol_id_t protocol))set_protocol;
- this->public.get_mode = (ipsec_mode_t(*)(child_sa_t*))get_mode;
- this->public.set_mode = (void(*)(child_sa_t*, ipsec_mode_t mode))set_mode;
- this->public.get_proposal = (proposal_t*(*)(child_sa_t*))get_proposal;
- this->public.set_proposal = (void(*)(child_sa_t*, proposal_t *proposal))set_proposal;
- this->public.get_lifetime = (time_t(*)(child_sa_t*, bool))get_lifetime;
- this->public.get_usestats = (void(*)(child_sa_t*,bool,time_t*,u_int64_t*))get_usestats;
- this->public.has_encap = (bool(*)(child_sa_t*))has_encap;
- this->public.get_ipcomp = (ipcomp_transform_t(*)(child_sa_t*))get_ipcomp;
- this->public.set_ipcomp = (void(*)(child_sa_t*,ipcomp_transform_t))set_ipcomp;
- this->public.get_close_action = (action_t(*)(child_sa_t*))get_close_action;
- this->public.set_close_action = (void(*)(child_sa_t*,action_t))set_close_action;
- this->public.get_dpd_action = (action_t(*)(child_sa_t*))get_dpd_action;
- this->public.set_dpd_action = (void(*)(child_sa_t*,action_t))set_dpd_action;
- this->public.alloc_spi = (u_int32_t(*)(child_sa_t*, protocol_id_t protocol))alloc_spi;
- this->public.alloc_cpi = (u_int16_t(*)(child_sa_t*))alloc_cpi;
- this->public.install = (status_t(*)(child_sa_t*, chunk_t encr, chunk_t integ, u_int32_t spi, u_int16_t cpi, bool inbound, linked_list_t *my_ts_list, linked_list_t *other_ts_list))install;
- this->public.update = (status_t (*)(child_sa_t*,host_t*,host_t*,host_t*,bool))update;
- this->public.add_policies = (status_t (*)(child_sa_t*, linked_list_t*,linked_list_t*))add_policies;
- this->public.get_traffic_selectors = (linked_list_t*(*)(child_sa_t*,bool))get_traffic_selectors;
- this->public.create_policy_enumerator = (enumerator_t*(*)(child_sa_t*))create_policy_enumerator;
- this->public.destroy = (void(*)(child_sa_t*))destroy;
-
- /* private data */
- this->my_addr = me->clone(me);
- this->other_addr = other->clone(other);
- this->my_spi = 0;
- this->other_spi = 0;
- this->my_cpi = 0;
- this->other_cpi = 0;
- this->encap = encap;
- this->ipcomp = IPCOMP_NONE;
- this->state = CHILD_CREATED;
- this->my_usetime = 0;
- this->other_usetime = 0;
- this->my_usebytes = 0;
- this->other_usebytes = 0;
- this->my_ts = linked_list_create();
- this->other_ts = linked_list_create();
- this->protocol = PROTO_NONE;
- this->mode = MODE_TUNNEL;
- this->close_action = config->get_close_action(config);
- this->dpd_action = config->get_dpd_action(config);
- this->proposal = NULL;
- this->rekey_time = 0;
- this->expire_time = 0;
+ private_child_sa_t *this;
+
+ INIT(this,
+ .public = {
+ .get_name = _get_name,
+ .get_reqid = _get_reqid,
+ .get_config = _get_config,
+ .get_state = _get_state,
+ .set_state = _set_state,
+ .get_spi = _get_spi,
+ .get_cpi = _get_cpi,
+ .get_protocol = _get_protocol,
+ .set_protocol = _set_protocol,
+ .get_mode = _get_mode,
+ .set_mode = _set_mode,
+ .get_proposal = _get_proposal,
+ .set_proposal = _set_proposal,
+ .get_lifetime = _get_lifetime,
+ .get_usestats = _get_usestats,
+ .has_encap = _has_encap,
+ .get_ipcomp = _get_ipcomp,
+ .set_ipcomp = _set_ipcomp,
+ .get_close_action = _get_close_action,
+ .set_close_action = _set_close_action,
+ .get_dpd_action = _get_dpd_action,
+ .set_dpd_action = _set_dpd_action,
+ .alloc_spi = _alloc_spi,
+ .alloc_cpi = _alloc_cpi,
+ .install = _install,
+ .update = _update,
+ .add_policies = _add_policies,
+ .get_traffic_selectors = _get_traffic_selectors,
+ .create_policy_enumerator = _create_policy_enumerator,
+ .destroy = _destroy,
+ },
+ .my_addr = me->clone(me),
+ .other_addr = other->clone(other),
+ .encap = encap,
+ .ipcomp = IPCOMP_NONE,
+ .state = CHILD_CREATED,
+ .my_ts = linked_list_create(),
+ .other_ts = linked_list_create(),
+ .protocol = PROTO_NONE,
+ .mode = MODE_TUNNEL,
+ .close_action = config->get_close_action(config),
+ .dpd_action = config->get_dpd_action(config),
+ .reqid = config->get_reqid(config),
+ .mark_in = config->get_mark(config, TRUE),
+ .mark_out = config->get_mark(config, FALSE),
+ );
+
this->config = config;
config->get_ref(config);
- this->reqid = config->get_reqid(config);
- this->mark_in = config->get_mark(config, TRUE);
- this->mark_out = config->get_mark(config, FALSE);
if (!this->reqid)
{
diff --git a/src/libcharon/sa/connect_manager.c b/src/libcharon/sa/connect_manager.c
index b78ba070d..1fb286863 100644
--- a/src/libcharon/sa/connect_manager.c
+++ b/src/libcharon/sa/connect_manager.c
@@ -932,7 +932,7 @@ static void update_checklist_state(private_connect_manager_t *this,
callback_data_t *data = callback_data_create(this, checklist->connect_id);
job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiator_finish, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
- charon->scheduler->schedule_job_ms(charon->scheduler, job, ME_WAIT_TO_FINISH);
+ lib->scheduler->schedule_job_ms(lib->scheduler, job, ME_WAIT_TO_FINISH);
checklist->is_finishing = TRUE;
}
@@ -1031,7 +1031,7 @@ static void queue_retransmission(private_connect_manager_t *this, check_list_t *
DBG2(DBG_IKE, "scheduling retransmission %d of pair '%d' in %dms",
retransmission, pair->id, rto);
- charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)job, rto);
+ lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)job, rto);
}
/**
@@ -1064,7 +1064,7 @@ static void send_check(private_connect_manager_t *this, check_list_t *checklist,
DBG2(DBG_IKE, "send ME_CONNECTAUTH %#B", &check->auth);
packet_t *packet;
- if (message->generate(message, NULL, NULL, &packet) == SUCCESS)
+ if (message->generate(message, NULL, &packet) == SUCCESS)
{
charon->sender->send(charon->sender, packet->clone(packet));
@@ -1170,7 +1170,7 @@ static void schedule_checks(private_connect_manager_t *this, check_list_t *check
{
callback_data_t *data = callback_data_create(this, checklist->connect_id);
checklist->sender = (job_t*)callback_job_create((callback_job_cb_t)sender, data, (callback_job_cleanup_t)callback_data_destroy, NULL);
- charon->scheduler->schedule_job_ms(charon->scheduler, checklist->sender, time);
+ lib->scheduler->schedule_job_ms(lib->scheduler, checklist->sender, time);
}
/**
@@ -1222,7 +1222,7 @@ static void finish_checks(private_connect_manager_t *this, check_list_t *checkli
initiate_data_t *data = initiate_data_create(checklist, initiated);
job_t *job = (job_t*)callback_job_create((callback_job_cb_t)initiate_mediated, data, (callback_job_cleanup_t)initiate_data_destroy, NULL);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
return;
}
else
@@ -1357,7 +1357,7 @@ static void process_request(private_connect_manager_t *this, check_t *check,
*/
static void process_check(private_connect_manager_t *this, message_t *message)
{
- if (message->parse_body(message, NULL, NULL) != SUCCESS)
+ if (message->parse_body(message, NULL) != SUCCESS)
{
DBG1(DBG_IKE, "%N %s with message ID %d processing failed",
exchange_type_names, message->get_exchange_type(message),
@@ -1477,7 +1477,7 @@ static void check_and_initiate(private_connect_manager_t *this,
{
job_t *job = (job_t*)reinitiate_mediation_job_create(mediation_sa,
waiting_sa);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
}
iterator->destroy(iterator);
diff --git a/src/libcharon/sa/ike_sa.c b/src/libcharon/sa/ike_sa.c
index 7536662ca..a4e4028ab 100644
--- a/src/libcharon/sa/ike_sa.c
+++ b/src/libcharon/sa/ike_sa.c
@@ -24,8 +24,8 @@
#include "ike_sa.h"
#include <library.h>
-#include <daemon.h>
#include <hydra.h>
+#include <daemon.h>
#include <utils/linked_list.h>
#include <utils/lexparser.h>
#include <sa/task_manager.h>
@@ -470,8 +470,8 @@ METHOD(ike_sa_t, send_keepalive, void,
diff = 0;
}
job = send_keepalive_job_create(this->ike_sa_id);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)job,
- this->keepalive_interval - diff);
+ lib->scheduler->schedule_job(lib->scheduler, (job_t*)job,
+ this->keepalive_interval - diff);
}
METHOD(ike_sa_t, get_ike_cfg, ike_cfg_t*,
@@ -605,7 +605,7 @@ METHOD(ike_sa_t, send_dpd, status_t,
}
/* recheck in "interval" seconds */
job = (job_t*)send_dpd_job_create(this->ike_sa_id);
- charon->scheduler->schedule_job(charon->scheduler, job, delay - diff);
+ lib->scheduler->schedule_job(lib->scheduler, job, delay - diff);
return SUCCESS;
}
@@ -644,7 +644,7 @@ METHOD(ike_sa_t, set_state, void,
{
this->stats[STAT_REKEY] = t + this->stats[STAT_ESTABLISHED];
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, FALSE);
- charon->scheduler->schedule_job(charon->scheduler, job, t);
+ lib->scheduler->schedule_job(lib->scheduler, job, t);
DBG1(DBG_IKE, "scheduling rekeying in %ds", t);
}
t = this->peer_cfg->get_reauth_time(this->peer_cfg);
@@ -653,7 +653,7 @@ METHOD(ike_sa_t, set_state, void,
{
this->stats[STAT_REAUTH] = t + this->stats[STAT_ESTABLISHED];
job = (job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job, t);
+ lib->scheduler->schedule_job(lib->scheduler, job, t);
DBG1(DBG_IKE, "scheduling reauthentication in %ds", t);
}
t = this->peer_cfg->get_over_time(this->peer_cfg);
@@ -675,7 +675,7 @@ METHOD(ike_sa_t, set_state, void,
this->stats[STAT_DELETE] += t;
t = this->stats[STAT_DELETE] - this->stats[STAT_ESTABLISHED];
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job, t);
+ lib->scheduler->schedule_job(lib->scheduler, job, t);
DBG1(DBG_IKE, "maximum IKE_SA lifetime %ds", t);
}
@@ -688,8 +688,8 @@ METHOD(ike_sa_t, set_state, void,
{
/* delete may fail if a packet gets lost, so set a timeout */
job_t *job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job,
- HALF_OPEN_IKE_SA_TIMEOUT);
+ lib->scheduler->schedule_job(lib->scheduler, job,
+ HALF_OPEN_IKE_SA_TIMEOUT);
break;
}
default:
@@ -730,14 +730,14 @@ METHOD(ike_sa_t, set_virtual_ip, void,
if (local)
{
DBG1(DBG_IKE, "installing new virtual IP %H", ip);
- if (charon->kernel_interface->add_ip(charon->kernel_interface, ip,
- this->my_host) == SUCCESS)
+ if (hydra->kernel_interface->add_ip(hydra->kernel_interface, ip,
+ this->my_host) == SUCCESS)
{
if (this->my_virtual_ip)
{
DBG1(DBG_IKE, "removing old virtual IP %H", this->my_virtual_ip);
- charon->kernel_interface->del_ip(charon->kernel_interface,
- this->my_virtual_ip);
+ hydra->kernel_interface->del_ip(hydra->kernel_interface,
+ this->my_virtual_ip);
}
DESTROY_IF(this->my_virtual_ip);
this->my_virtual_ip = ip->clone(ip);
@@ -810,6 +810,20 @@ METHOD(ike_sa_t, get_pending_updates, u_int32_t,
return this->pending_updates;
}
+METHOD(ike_sa_t, float_ports, void,
+ private_ike_sa_t *this)
+{
+ /* do not switch if we have a custom port from MOBIKE/NAT */
+ if (this->my_host->get_port(this->my_host) == IKEV2_UDP_PORT)
+ {
+ this->my_host->set_port(this->my_host, IKEV2_NATT_PORT);
+ }
+ if (this->other_host->get_port(this->other_host) == IKEV2_UDP_PORT)
+ {
+ this->other_host->set_port(this->other_host, IKEV2_NATT_PORT);
+ }
+}
+
METHOD(ike_sa_t, update_hosts, void,
private_ike_sa_t *this, host_t *me, host_t *other)
{
@@ -843,10 +857,8 @@ METHOD(ike_sa_t, update_hosts, void,
if (!other->equals(other, this->other_host))
{
- /* update others adress if we are NOT NATed,
- * and allow port changes if we are NATed */
- if (!has_condition(this, COND_NAT_HERE) ||
- other->ip_equals(other, this->other_host))
+ /* update others adress if we are NOT NATed */
+ if (!has_condition(this, COND_NAT_HERE))
{
set_other_host(this, other->clone(other));
update = TRUE;
@@ -882,8 +894,7 @@ METHOD(ike_sa_t, generate_message, status_t,
this->stats[STAT_OUTBOUND] = time_monotonic(NULL);
message->set_ike_sa_id(message, this->ike_sa_id);
return message->generate(message,
- this->keymat->get_crypter(this->keymat, FALSE),
- this->keymat->get_signer(this->keymat, FALSE), packet);
+ this->keymat->get_aead(this->keymat, FALSE), packet);
}
/**
@@ -1049,8 +1060,8 @@ static void resolve_hosts(private_ike_sa_t *this)
!this->other_host->is_anyaddr(this->other_host))
{
host->destroy(host);
- host = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, this->other_host, NULL);
+ host = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, this->other_host, NULL);
if (host)
{
host->set_port(host, this->ike_cfg->get_my_port(this->ike_cfg));
@@ -1150,7 +1161,7 @@ METHOD(ike_sa_t, initiate, status_t,
{
/* mediated connection, initiate mediation process */
job_t *job = (job_t*)initiate_mediation_job_create(this->ike_sa_id);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
return SUCCESS;
}
#endif /* ME */
@@ -1173,8 +1184,7 @@ METHOD(ike_sa_t, process_message, status_t,
is_request = message->get_request(message);
status = message->parse_body(message,
- this->keymat->get_crypter(this->keymat, TRUE),
- this->keymat->get_signer(this->keymat, TRUE));
+ this->keymat->get_aead(this->keymat, TRUE));
if (status != SUCCESS)
{
@@ -1229,15 +1239,12 @@ METHOD(ike_sa_t, process_message, status_t,
}
else
{
- host_t *me, *other;
-
- me = message->get_destination(message);
- other = message->get_source(message);
-
/* if this IKE_SA is virgin, we check for a config */
if (this->ike_cfg == NULL)
{
job_t *job;
+ host_t *me = message->get_destination(message),
+ *other = message->get_source(message);
this->ike_cfg = charon->backends->get_ike_cfg(charon->backends,
me, other);
if (this->ike_cfg == NULL)
@@ -1250,20 +1257,12 @@ METHOD(ike_sa_t, process_message, status_t,
}
/* add a timeout if peer does not establish it completely */
job = (job_t*)delete_ike_sa_job_create(this->ike_sa_id, FALSE);
- charon->scheduler->schedule_job(charon->scheduler, job,
- HALF_OPEN_IKE_SA_TIMEOUT);
+ lib->scheduler->schedule_job(lib->scheduler, job,
+ HALF_OPEN_IKE_SA_TIMEOUT);
}
this->stats[STAT_INBOUND] = time_monotonic(NULL);
- /* check if message is trustworthy, and update host information */
- if (this->state == IKE_CREATED || this->state == IKE_CONNECTING ||
- message->get_exchange_type(message) != IKE_SA_INIT)
- {
- if (!supports_extension(this, EXT_MOBIKE))
- { /* with MOBIKE, we do no implicit updates */
- update_hosts(this, me, other);
- }
- }
- status = this->task_manager->process_message(this->task_manager, message);
+ status = this->task_manager->process_message(this->task_manager,
+ message);
if (message->get_exchange_type(message) == IKE_AUTH &&
this->state == IKE_ESTABLISHED &&
lib->settings->get_bool(lib->settings,
@@ -1697,7 +1696,7 @@ METHOD(ike_sa_t, set_auth_lifetime, void,
{
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, starting reauthentication",
lifetime);
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE));
}
else if (this->stats[STAT_REAUTH] == 0 ||
@@ -1706,7 +1705,7 @@ METHOD(ike_sa_t, set_auth_lifetime, void,
this->stats[STAT_REAUTH] = reauth_time;
DBG1(DBG_IKE, "received AUTH_LIFETIME of %ds, scheduling reauthentication"
" in %ds", lifetime, lifetime - reduction);
- charon->scheduler->schedule_job(charon->scheduler,
+ lib->scheduler->schedule_job(lib->scheduler,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE),
lifetime - reduction);
}
@@ -1718,10 +1717,65 @@ METHOD(ike_sa_t, set_auth_lifetime, void,
}
}
+/**
+ * Check if the current combination of source and destination address is still
+ * valid.
+ */
+static bool is_current_path_valid(private_ike_sa_t *this)
+{
+ bool valid = FALSE;
+ host_t *src;
+ src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
+ this->other_host, this->my_host);
+ if (src)
+ {
+ if (src->ip_equals(src, this->my_host))
+ {
+ valid = TRUE;
+ }
+ src->destroy(src);
+ }
+ return valid;
+}
+
+/**
+ * Check if we have any path avialable for this IKE SA.
+ */
+static bool is_any_path_valid(private_ike_sa_t *this)
+{
+ bool valid = FALSE;
+ enumerator_t *enumerator;
+ host_t *src, *addr;
+ DBG1(DBG_IKE, "old path is not available anymore, try to find another");
+ src = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
+ this->other_host, NULL);
+ if (!src)
+ {
+ enumerator = this->additional_addresses->create_enumerator(
+ this->additional_addresses);
+ while (enumerator->enumerate(enumerator, &addr))
+ {
+ DBG1(DBG_IKE, "looking for a route to %H ...", addr);
+ src = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, addr, NULL);
+ if (src)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+ }
+ if (src)
+ {
+ valid = TRUE;
+ src->destroy(src);
+ }
+ return valid;
+}
+
METHOD(ike_sa_t, roam, status_t,
private_ike_sa_t *this, bool address)
{
- host_t *src;
ike_mobike_t *mobike;
switch (this->state)
@@ -1734,81 +1788,61 @@ METHOD(ike_sa_t, roam, status_t,
default:
break;
}
- /* responder just updates the peer about changed address config */
- if (!this->ike_sa_id->is_initiator(this->ike_sa_id))
+
+ /* keep existing path if possible */
+ if (is_current_path_valid(this))
{
+ DBG2(DBG_IKE, "keeping connection path %H - %H",
+ this->my_host, this->other_host);
+ set_condition(this, COND_STALE, FALSE);
+
if (supports_extension(this, EXT_MOBIKE) && address)
- {
+ { /* if any addresses changed, send an updated list */
DBG1(DBG_IKE, "sending address list update using MOBIKE");
mobike = ike_mobike_create(&this->public, TRUE);
- this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
+ mobike->addresses(mobike);
+ this->task_manager->queue_task(this->task_manager,
+ (task_t*)mobike);
return this->task_manager->initiate(this->task_manager);
}
return SUCCESS;
}
- /* keep existing path if possible */
- src = charon->kernel_interface->get_source_addr(charon->kernel_interface,
- this->other_host, this->my_host);
- if (src)
+ if (!is_any_path_valid(this))
{
- if (src->ip_equals(src, this->my_host))
- {
- DBG2(DBG_IKE, "keeping connection path %H - %H",
- src, this->other_host);
- src->destroy(src);
- set_condition(this, COND_STALE, FALSE);
- return SUCCESS;
- }
- src->destroy(src);
-
- }
- else
- {
- /* check if we find a route at all */
- enumerator_t *enumerator;
- host_t *addr;
-
- src = charon->kernel_interface->get_source_addr(charon->kernel_interface,
- this->other_host, NULL);
- if (!src)
- {
- enumerator = this->additional_addresses->create_enumerator(
- this->additional_addresses);
- while (enumerator->enumerate(enumerator, &addr))
- {
- DBG1(DBG_IKE, "looking for a route to %H ...", addr);
- src = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, addr, NULL);
- if (src)
- {
- break;
- }
- }
- enumerator->destroy(enumerator);
- }
- if (!src)
- {
- DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred",
- this->other_host);
- set_condition(this, COND_STALE, TRUE);
- return SUCCESS;
- }
- src->destroy(src);
+ DBG1(DBG_IKE, "no route found to reach %H, MOBIKE update deferred",
+ this->other_host);
+ set_condition(this, COND_STALE, TRUE);
+ return SUCCESS;
}
set_condition(this, COND_STALE, FALSE);
/* update addresses with mobike, if supported ... */
if (supports_extension(this, EXT_MOBIKE))
{
- DBG1(DBG_IKE, "requesting address change using MOBIKE");
+ if (!has_condition(this, COND_ORIGINAL_INITIATOR))
+ { /* responder updates the peer about changed address config */
+ DBG1(DBG_IKE, "sending address list update using MOBIKE, "
+ "implicitly requesting an address change");
+ address = TRUE;
+ }
+ else
+ {
+ DBG1(DBG_IKE, "requesting address change using MOBIKE");
+ }
mobike = ike_mobike_create(&this->public, TRUE);
mobike->roam(mobike, address);
this->task_manager->queue_task(this->task_manager, (task_t*)mobike);
return this->task_manager->initiate(this->task_manager);
}
- DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change");
+
/* ... reauth if not */
+ if (!has_condition(this, COND_ORIGINAL_INITIATOR))
+ { /* responder does not reauthenticate */
+ set_condition(this, COND_STALE, TRUE);
+ return SUCCESS;
+ }
+ DBG1(DBG_IKE, "reauthenticating IKE_SA due to address change");
return reauth(this);
}
@@ -1907,9 +1941,9 @@ METHOD(ike_sa_t, inherit, status_t,
this->stats[STAT_DELETE] = this->stats[STAT_REAUTH] + delete;
DBG1(DBG_IKE, "rescheduling reauthentication in %ds after rekeying, "
"lifetime reduced to %ds", reauth, delete);
- charon->scheduler->schedule_job(charon->scheduler,
+ lib->scheduler->schedule_job(lib->scheduler,
(job_t*)rekey_ike_sa_job_create(this->ike_sa_id, TRUE), reauth);
- charon->scheduler->schedule_job(charon->scheduler,
+ lib->scheduler->schedule_job(lib->scheduler,
(job_t*)delete_ike_sa_job_create(this->ike_sa_id, TRUE), delete);
}
/* we have to initate here, there may be new tasks to handle */
@@ -1946,8 +1980,8 @@ METHOD(ike_sa_t, destroy, void,
if (this->my_virtual_ip)
{
- charon->kernel_interface->del_ip(charon->kernel_interface,
- this->my_virtual_ip);
+ hydra->kernel_interface->del_ip(hydra->kernel_interface,
+ this->my_virtual_ip);
this->my_virtual_ip->destroy(this->my_virtual_ip);
}
if (this->other_virtual_ip)
@@ -2025,6 +2059,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
.get_other_host = _get_other_host,
.set_other_host = _set_other_host,
.set_message_id = _set_message_id,
+ .float_ports = _float_ports,
.update_hosts = _update_hosts,
.get_my_id = _get_my_id,
.set_my_id = _set_my_id,
diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h
index 34842a573..c0007e27d 100644
--- a/src/libcharon/sa/ike_sa.h
+++ b/src/libcharon/sa/ike_sa.h
@@ -329,6 +329,14 @@ struct ike_sa_t {
void (*set_other_host) (ike_sa_t *this, host_t *other);
/**
+ * Float to port 4500 (e.g. if a NAT is detected).
+ *
+ * The port of either endpoint is changed only if it is currently
+ * set to the default value of 500.
+ */
+ void (*float_ports)(ike_sa_t *this);
+
+ /**
* Update the IKE_SAs host.
*
* Hosts may be NULL to use current host.
diff --git a/src/libcharon/sa/ike_sa_manager.c b/src/libcharon/sa/ike_sa_manager.c
index c71c3b297..fa94bb86d 100644
--- a/src/libcharon/sa/ike_sa_manager.c
+++ b/src/libcharon/sa/ike_sa_manager.c
@@ -1613,6 +1613,9 @@ static void flush(private_ike_sa_manager_t *this)
enumerator->destroy(enumerator);
charon->bus->set_sa(charon->bus, NULL);
unlock_all_segments(this);
+
+ this->rng->destroy(this->rng);
+ this->hasher->destroy(this->hasher);
}
/**
@@ -1652,8 +1655,6 @@ static void destroy(private_ike_sa_manager_t *this)
free(this->half_open_segments);
free(this->connected_peers_segments);
- this->rng->destroy(this->rng);
- this->hasher->destroy(this->hasher);
free(this);
}
diff --git a/src/libcharon/sa/ike_sa_manager.h b/src/libcharon/sa/ike_sa_manager.h
index 38f5454e1..f4eabf808 100644
--- a/src/libcharon/sa/ike_sa_manager.h
+++ b/src/libcharon/sa/ike_sa_manager.h
@@ -199,6 +199,8 @@ struct ike_sa_manager_t {
* Delete all existing IKE_SAs and destroy them immediately.
*
* Threads will be driven out, so all SAs can be deleted cleanly.
+ * To a flush(), an immediate call to destroy() is mandatory; no other
+ * method may be used.
*/
void (*flush)(ike_sa_manager_t *this);
diff --git a/src/libcharon/sa/keymat.c b/src/libcharon/sa/keymat.c
index 837cbe428..878ad124f 100644
--- a/src/libcharon/sa/keymat.c
+++ b/src/libcharon/sa/keymat.c
@@ -36,24 +36,14 @@ struct private_keymat_t {
bool initiator;
/**
- * inbound signer (verify)
+ * inbound AEAD
*/
- signer_t *signer_in;
+ aead_t *aead_in;
/**
- * outbound signer (sign)
+ * outbound AEAD
*/
- signer_t *signer_out;
-
- /**
- * inbound crypter (decrypt)
- */
- crypter_t *crypter_in;
-
- /**
- * outbound crypter (encrypt)
- */
- crypter_t *crypter_out;
+ aead_t *aead_out;
/**
* General purpose PRF
@@ -134,30 +124,135 @@ static int lookup_keylen(keylen_entry_t *list, int algo)
return 0;
}
+METHOD(keymat_t, create_dh, diffie_hellman_t*,
+ private_keymat_t *this, diffie_hellman_group_t group)
+{
+ return lib->crypto->create_dh(lib->crypto, group);;
+}
+
/**
- * Implementation of keymat_t.create_dh
+ * Derive IKE keys for a combined AEAD algorithm
*/
-static diffie_hellman_t* create_dh(private_keymat_t *this,
- diffie_hellman_group_t group)
+static bool derive_ike_aead(private_keymat_t *this, u_int16_t alg,
+ u_int16_t key_size, prf_plus_t *prf_plus)
{
- return lib->crypto->create_dh(lib->crypto, group);;
+ aead_t *aead_i, *aead_r;
+ chunk_t key;
+
+ /* SK_ei/SK_er used for encryption */
+ aead_i = lib->crypto->create_aead(lib->crypto, alg, key_size / 8);
+ aead_r = lib->crypto->create_aead(lib->crypto, alg, key_size / 8);
+ if (aead_i == NULL || aead_r == NULL)
+ {
+ DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
+ transform_type_names, ENCRYPTION_ALGORITHM,
+ encryption_algorithm_names, alg, key_size);
+ return FALSE;
+ }
+ key_size = aead_i->get_key_size(aead_i);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_ei secret %B", &key);
+ aead_i->set_key(aead_i, key);
+ chunk_clear(&key);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_er secret %B", &key);
+ aead_r->set_key(aead_r, key);
+ chunk_clear(&key);
+
+ if (this->initiator)
+ {
+ this->aead_in = aead_r;
+ this->aead_out = aead_i;
+ }
+ else
+ {
+ this->aead_in = aead_i;
+ this->aead_out = aead_r;
+ }
+ return TRUE;
}
/**
- * Implementation of keymat_t.derive_keys
+ * Derive IKE keys for traditional encryption and MAC algorithms
*/
-static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
- diffie_hellman_t *dh, chunk_t nonce_i,
- chunk_t nonce_r, ike_sa_id_t *id,
- pseudo_random_function_t rekey_function,
- chunk_t rekey_skd)
+static bool derive_ike_traditional(private_keymat_t *this, u_int16_t enc_alg,
+ u_int16_t enc_size, u_int16_t int_alg, prf_plus_t *prf_plus)
{
- chunk_t skeyseed, key, secret, full_nonce, fixed_nonce, prf_plus_seed;
- chunk_t spi_i, spi_r;
crypter_t *crypter_i, *crypter_r;
signer_t *signer_i, *signer_r;
+ size_t key_size;
+ chunk_t key;
+
+ /* SK_ai/SK_ar used for integrity protection */
+ signer_i = lib->crypto->create_signer(lib->crypto, int_alg);
+ signer_r = lib->crypto->create_signer(lib->crypto, int_alg);
+ if (signer_i == NULL || signer_r == NULL)
+ {
+ DBG1(DBG_IKE, "%N %N not supported!",
+ transform_type_names, INTEGRITY_ALGORITHM,
+ integrity_algorithm_names, int_alg);
+ return FALSE;
+ }
+ key_size = signer_i->get_key_size(signer_i);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_ai secret %B", &key);
+ signer_i->set_key(signer_i, key);
+ chunk_clear(&key);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_ar secret %B", &key);
+ signer_r->set_key(signer_r, key);
+ chunk_clear(&key);
+
+ /* SK_ei/SK_er used for encryption */
+ crypter_i = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
+ crypter_r = lib->crypto->create_crypter(lib->crypto, enc_alg, enc_size / 8);
+ if (crypter_i == NULL || crypter_r == NULL)
+ {
+ DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
+ transform_type_names, ENCRYPTION_ALGORITHM,
+ encryption_algorithm_names, enc_alg, key_size);
+ signer_i->destroy(signer_i);
+ signer_r->destroy(signer_r);
+ return FALSE;
+ }
+ key_size = crypter_i->get_key_size(crypter_i);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_ei secret %B", &key);
+ crypter_i->set_key(crypter_i, key);
+ chunk_clear(&key);
+
+ prf_plus->allocate_bytes(prf_plus, key_size, &key);
+ DBG4(DBG_IKE, "Sk_er secret %B", &key);
+ crypter_r->set_key(crypter_r, key);
+ chunk_clear(&key);
+
+ if (this->initiator)
+ {
+ this->aead_in = aead_create(crypter_r, signer_r);
+ this->aead_out = aead_create(crypter_i, signer_i);
+ }
+ else
+ {
+ this->aead_in = aead_create(crypter_i, signer_i);
+ this->aead_out = aead_create(crypter_r, signer_r);
+ }
+ return TRUE;
+}
+
+METHOD(keymat_t, derive_ike_keys, bool,
+ private_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh,
+ chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id,
+ pseudo_random_function_t rekey_function, chunk_t rekey_skd)
+{
+ chunk_t skeyseed, key, secret, full_nonce, fixed_nonce, prf_plus_seed;
+ chunk_t spi_i, spi_r;
prf_plus_t *prf_plus;
- u_int16_t alg, key_size;
+ u_int16_t alg, key_size, int_alg;
prf_t *rekey_prf = NULL;
spi_i = chunk_alloca(sizeof(u_int64_t));
@@ -195,6 +290,9 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
/* while rfc4434 defines variable keys for AES-XCBC, rfc3664 does
* not and therefore fixed key semantics apply to XCBC for key
* derivation. */
+ case PRF_CAMELLIA128_XCBC:
+ /* draft-kanno-ipsecme-camellia-xcbc refers to rfc 4434, we
+ * assume fixed key length. */
key_size = this->prf->get_key_size(this->prf)/2;
nonce_i.len = min(nonce_i.len, key_size);
nonce_r.len = min(nonce_r.len, key_size);
@@ -255,50 +353,6 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
prf_plus->allocate_bytes(prf_plus, key_size, &this->skd);
DBG4(DBG_IKE, "Sk_d secret %B", &this->skd);
- /* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */
- if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
- {
- DBG1(DBG_IKE, "no %N selected",
- transform_type_names, INTEGRITY_ALGORITHM);
- prf_plus->destroy(prf_plus);
- DESTROY_IF(rekey_prf);
- return FALSE;
- }
- signer_i = lib->crypto->create_signer(lib->crypto, alg);
- signer_r = lib->crypto->create_signer(lib->crypto, alg);
- if (signer_i == NULL || signer_r == NULL)
- {
- DBG1(DBG_IKE, "%N %N not supported!",
- transform_type_names, INTEGRITY_ALGORITHM,
- integrity_algorithm_names ,alg);
- prf_plus->destroy(prf_plus);
- DESTROY_IF(rekey_prf);
- return FALSE;
- }
- key_size = signer_i->get_key_size(signer_i);
-
- prf_plus->allocate_bytes(prf_plus, key_size, &key);
- DBG4(DBG_IKE, "Sk_ai secret %B", &key);
- signer_i->set_key(signer_i, key);
- chunk_clear(&key);
-
- prf_plus->allocate_bytes(prf_plus, key_size, &key);
- DBG4(DBG_IKE, "Sk_ar secret %B", &key);
- signer_r->set_key(signer_r, key);
- chunk_clear(&key);
-
- if (this->initiator)
- {
- this->signer_in = signer_r;
- this->signer_out = signer_i;
- }
- else
- {
- this->signer_in = signer_i;
- this->signer_out = signer_r;
- }
-
- /* SK_ei/SK_er used for encryption => crypter_in/crypter_out */
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &key_size))
{
DBG1(DBG_IKE, "no %N selected",
@@ -307,38 +361,33 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
DESTROY_IF(rekey_prf);
return FALSE;
}
- crypter_i = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8);
- crypter_r = lib->crypto->create_crypter(lib->crypto, alg, key_size / 8);
- if (crypter_i == NULL || crypter_r == NULL)
- {
- DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
- transform_type_names, ENCRYPTION_ALGORITHM,
- encryption_algorithm_names, alg, key_size);
- prf_plus->destroy(prf_plus);
- DESTROY_IF(rekey_prf);
- return FALSE;
- }
- key_size = crypter_i->get_key_size(crypter_i);
- prf_plus->allocate_bytes(prf_plus, key_size, &key);
- DBG4(DBG_IKE, "Sk_ei secret %B", &key);
- crypter_i->set_key(crypter_i, key);
- chunk_clear(&key);
-
- prf_plus->allocate_bytes(prf_plus, key_size, &key);
- DBG4(DBG_IKE, "Sk_er secret %B", &key);
- crypter_r->set_key(crypter_r, key);
- chunk_clear(&key);
-
- if (this->initiator)
+ if (encryption_algorithm_is_aead(alg))
{
- this->crypter_in = crypter_r;
- this->crypter_out = crypter_i;
+ if (!derive_ike_aead(this, alg, key_size, prf_plus))
+ {
+ prf_plus->destroy(prf_plus);
+ DESTROY_IF(rekey_prf);
+ return FALSE;
+ }
}
else
{
- this->crypter_in = crypter_i;
- this->crypter_out = crypter_r;
+ if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM,
+ &int_alg, NULL))
+ {
+ DBG1(DBG_IKE, "no %N selected",
+ transform_type_names, INTEGRITY_ALGORITHM);
+ prf_plus->destroy(prf_plus);
+ DESTROY_IF(rekey_prf);
+ return FALSE;
+ }
+ if (!derive_ike_traditional(this, alg, key_size, int_alg, prf_plus))
+ {
+ prf_plus->destroy(prf_plus);
+ DESTROY_IF(rekey_prf);
+ return FALSE;
+ }
}
/* SK_pi/SK_pr used for authentication => stored for later */
@@ -371,14 +420,10 @@ static bool derive_ike_keys(private_keymat_t *this, proposal_t *proposal,
return TRUE;
}
-/**
- * Implementation of keymat_t.derive_child_keys
- */
-static bool derive_child_keys(private_keymat_t *this,
- proposal_t *proposal, diffie_hellman_t *dh,
- chunk_t nonce_i, chunk_t nonce_r,
- chunk_t *encr_i, chunk_t *integ_i,
- chunk_t *encr_r, chunk_t *integ_r)
+METHOD(keymat_t, derive_child_keys, bool,
+ private_keymat_t *this, proposal_t *proposal, diffie_hellman_t *dh,
+ chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i,
+ chunk_t *encr_r, chunk_t *integ_r)
{
u_int16_t enc_alg, int_alg, enc_size = 0, int_size = 0;
chunk_t seed, secret = chunk_empty;
@@ -480,37 +525,22 @@ static bool derive_child_keys(private_keymat_t *this,
return TRUE;
}
-/**
- * Implementation of keymat_t.get_skd
- */
-static pseudo_random_function_t get_skd(private_keymat_t *this, chunk_t *skd)
+METHOD(keymat_t, get_skd, pseudo_random_function_t,
+ private_keymat_t *this, chunk_t *skd)
{
*skd = this->skd;
return this->prf_alg;
}
-/**
- * Implementation of keymat_t.get_signer
- */
-static signer_t* get_signer(private_keymat_t *this, bool in)
-{
- return in ? this->signer_in : this->signer_out;
-}
-
-/**
- * Implementation of keymat_t.get_crypter
- */
-static crypter_t* get_crypter(private_keymat_t *this, bool in)
+METHOD(keymat_t, get_aead, aead_t*,
+ private_keymat_t *this, bool in)
{
- return in ? this->crypter_in : this->crypter_out;
+ return in ? this->aead_in : this->aead_out;
}
-/**
- * Implementation of keymat_t.get_auth_octets
- */
-static chunk_t get_auth_octets(private_keymat_t *this, bool verify,
- chunk_t ike_sa_init, chunk_t nonce,
- identification_t *id)
+METHOD(keymat_t, get_auth_octets, chunk_t,
+ private_keymat_t *this, bool verify, chunk_t ike_sa_init,
+ chunk_t nonce, identification_t *id)
{
chunk_t chunk, idx, octets;
chunk_t skp;
@@ -538,12 +568,9 @@ static chunk_t get_auth_octets(private_keymat_t *this, bool verify,
#define IKEV2_KEY_PAD "Key Pad for IKEv2"
#define IKEV2_KEY_PAD_LENGTH 17
-/**
- * Implementation of keymat_t.get_psk_sig
- */
-static chunk_t get_psk_sig(private_keymat_t *this, bool verify,
- chunk_t ike_sa_init, chunk_t nonce, chunk_t secret,
- identification_t *id)
+METHOD(keymat_t, get_psk_sig, chunk_t,
+ private_keymat_t *this, bool verify, chunk_t ike_sa_init,
+ chunk_t nonce, chunk_t secret, identification_t *id)
{
chunk_t key_pad, key, sig, octets;
@@ -567,15 +594,11 @@ static chunk_t get_psk_sig(private_keymat_t *this, bool verify,
return sig;
}
-/**
- * Implementation of keymat_t.destroy.
- */
-static void destroy(private_keymat_t *this)
+METHOD(keymat_t, destroy, void,
+ private_keymat_t *this)
{
- DESTROY_IF(this->signer_in);
- DESTROY_IF(this->signer_out);
- DESTROY_IF(this->crypter_in);
- DESTROY_IF(this->crypter_out);
+ DESTROY_IF(this->aead_in);
+ DESTROY_IF(this->aead_out);
DESTROY_IF(this->prf);
chunk_clear(&this->skd);
chunk_clear(&this->skp_verify);
@@ -588,29 +611,22 @@ static void destroy(private_keymat_t *this)
*/
keymat_t *keymat_create(bool initiator)
{
- private_keymat_t *this = malloc_thing(private_keymat_t);
-
- this->public.create_dh = (diffie_hellman_t*(*)(keymat_t*, diffie_hellman_group_t group))create_dh;
- this->public.derive_ike_keys = (bool(*)(keymat_t*, proposal_t *proposal, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, ike_sa_id_t *id, pseudo_random_function_t,chunk_t))derive_ike_keys;
- this->public.derive_child_keys = (bool(*)(keymat_t*, proposal_t *proposal, diffie_hellman_t *dh, chunk_t nonce_i, chunk_t nonce_r, chunk_t *encr_i, chunk_t *integ_i, chunk_t *encr_r, chunk_t *integ_r))derive_child_keys;
- this->public.get_skd = (pseudo_random_function_t(*)(keymat_t*, chunk_t *skd))get_skd;
- this->public.get_signer = (signer_t*(*)(keymat_t*, bool in))get_signer;
- this->public.get_crypter = (crypter_t*(*)(keymat_t*, bool in))get_crypter;
- this->public.get_auth_octets = (chunk_t(*)(keymat_t *, bool verify, chunk_t ike_sa_init, chunk_t nonce, identification_t *id))get_auth_octets;
- this->public.get_psk_sig = (chunk_t(*)(keymat_t*, bool verify, chunk_t ike_sa_init, chunk_t nonce, chunk_t secret, identification_t *id))get_psk_sig;
- this->public.destroy = (void(*)(keymat_t*))destroy;
-
- this->initiator = initiator;
-
- this->signer_in = NULL;
- this->signer_out = NULL;
- this->crypter_in = NULL;
- this->crypter_out = NULL;
- this->prf = NULL;
- this->prf_alg = PRF_UNDEFINED;
- this->skd = chunk_empty;
- this->skp_verify = chunk_empty;
- this->skp_build = chunk_empty;
+ private_keymat_t *this;
+
+ INIT(this,
+ .public = {
+ .create_dh = _create_dh,
+ .derive_ike_keys = _derive_ike_keys,
+ .derive_child_keys = _derive_child_keys,
+ .get_skd = _get_skd,
+ .get_aead = _get_aead,
+ .get_auth_octets = _get_auth_octets,
+ .get_psk_sig = _get_psk_sig,
+ .destroy = _destroy,
+ },
+ .initiator = initiator,
+ .prf_alg = PRF_UNDEFINED,
+ );
return &this->public;
}
diff --git a/src/libcharon/sa/keymat.h b/src/libcharon/sa/keymat.h
index e51709e8d..4f01aa411 100644
--- a/src/libcharon/sa/keymat.h
+++ b/src/libcharon/sa/keymat.h
@@ -24,8 +24,7 @@
#include <library.h>
#include <utils/identification.h>
#include <crypto/prfs/prf.h>
-#include <crypto/crypters/crypter.h>
-#include <crypto/signers/signer.h>
+#include <crypto/aead.h>
#include <config/proposal.h>
#include <sa/ike_sa_id.h>
@@ -99,21 +98,13 @@ struct keymat_t {
*/
pseudo_random_function_t (*get_skd)(keymat_t *this, chunk_t *skd);
- /**
- * Get a signer to sign/verify IKE messages.
- *
- * @param in TRUE for inbound (verify), FALSE for outbound (sign)
- * @return signer
- */
- signer_t* (*get_signer)(keymat_t *this, bool in);
-
/*
- * Get a crypter to en-/decrypt IKE messages.
+ * Get a AEAD transform to en-/decrypt and sign/verify IKE messages.
*
* @param in TRUE for inbound (decrypt), FALSE for outbound (encrypt)
* @return crypter
*/
- crypter_t* (*get_crypter)(keymat_t *this, bool in);
+ aead_t* (*get_aead)(keymat_t *this, bool in);
/**
* Generate octets to use for authentication procedure (RFC4306 2.15).
diff --git a/src/libcharon/sa/mediation_manager.c b/src/libcharon/sa/mediation_manager.c
index 035f49053..2fbab7c7c 100644
--- a/src/libcharon/sa/mediation_manager.c
+++ b/src/libcharon/sa/mediation_manager.c
@@ -241,7 +241,7 @@ static void update_sa_id(private_mediation_manager_t *this, identification_t *pe
(void**)&requester) == SUCCESS)
{
job_t *job = (job_t*)mediation_callback_job_create(requester, peer_id);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
requester->destroy(requester);
}
diff --git a/src/libcharon/sa/task_manager.c b/src/libcharon/sa/task_manager.c
index a68826440..18703ce36 100644
--- a/src/libcharon/sa/task_manager.c
+++ b/src/libcharon/sa/task_manager.c
@@ -274,7 +274,7 @@ METHOD(task_manager_t, retransmit, status_t,
this->initiating.retransmitted++;
job = (job_t*)retransmit_job_create(this->initiating.mid,
this->ike_sa->get_id(this->ike_sa));
- charon->scheduler->schedule_job_ms(charon->scheduler, job, timeout);
+ lib->scheduler->schedule_job_ms(lib->scheduler, job, timeout);
}
return SUCCESS;
}
@@ -883,11 +883,21 @@ METHOD(task_manager_t, process_message, status_t,
private_task_manager_t *this, message_t *msg)
{
u_int32_t mid = msg->get_message_id(msg);
+ host_t *me = msg->get_destination(msg), *other = msg->get_source(msg);
if (msg->get_request(msg))
{
if (mid == this->responding.mid)
{
+ if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
+ this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
+ msg->get_exchange_type(msg) != IKE_SA_INIT)
+ { /* only do host updates based on verified messages */
+ if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
+ { /* with MOBIKE, we do no implicit updates */
+ this->ike_sa->update_hosts(this->ike_sa, me, other);
+ }
+ }
charon->bus->message(charon->bus, msg, TRUE);
if (process_request(this, msg) != SUCCESS)
{
@@ -920,6 +930,15 @@ METHOD(task_manager_t, process_message, status_t,
{
if (mid == this->initiating.mid)
{
+ if (this->ike_sa->get_state(this->ike_sa) == IKE_CREATED ||
+ this->ike_sa->get_state(this->ike_sa) == IKE_CONNECTING ||
+ msg->get_exchange_type(msg) != IKE_SA_INIT)
+ { /* only do host updates based on verified messages */
+ if (!this->ike_sa->supports_extension(this->ike_sa, EXT_MOBIKE))
+ { /* with MOBIKE, we do no implicit updates */
+ this->ike_sa->update_hosts(this->ike_sa, me, other);
+ }
+ }
charon->bus->message(charon->bus, msg, TRUE);
if (process_response(this, msg) != SUCCESS)
{
diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c
index 3de27ee3f..57beedba9 100644
--- a/src/libcharon/sa/tasks/child_create.c
+++ b/src/libcharon/sa/tasks/child_create.c
@@ -261,7 +261,7 @@ static void schedule_inactivity_timeout(private_child_create_t *this)
{
close_ike = lib->settings->get_bool(lib->settings,
"charon.inactivity_close_ike", FALSE);
- charon->scheduler->schedule_job(charon->scheduler, (job_t*)
+ lib->scheduler->schedule_job(lib->scheduler, (job_t*)
inactivity_job_create(this->child_sa->get_reqid(this->child_sa),
timeout, close_ike), timeout);
}
@@ -871,7 +871,7 @@ static void handle_child_sa_failure(private_child_create_t *this,
/* we delay the delete for 100ms, as the IKE_AUTH response must arrive
* first */
DBG1(DBG_IKE, "closing IKE_SA due CHILD_SA setup failure");
- charon->scheduler->schedule_job_ms(charon->scheduler, (job_t*)
+ lib->scheduler->schedule_job_ms(lib->scheduler, (job_t*)
delete_ike_sa_job_create(this->ike_sa->get_id(this->ike_sa), TRUE),
100);
}
diff --git a/src/libcharon/sa/tasks/child_delete.c b/src/libcharon/sa/tasks/child_delete.c
index b0cd30e1e..45e97e4cd 100644
--- a/src/libcharon/sa/tasks/child_delete.c
+++ b/src/libcharon/sa/tasks/child_delete.c
@@ -117,11 +117,10 @@ static void build_payloads(private_child_delete_t *this, message_t *message)
*/
static void process_payloads(private_child_delete_t *this, message_t *message)
{
- enumerator_t *payloads;
- iterator_t *spis;
+ enumerator_t *payloads, *spis;
payload_t *payload;
delete_payload_t *delete_payload;
- u_int32_t *spi;
+ u_int32_t spi;
protocol_id_t protocol;
child_sa_t *child_sa;
@@ -136,19 +135,19 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
{
continue;
}
- spis = delete_payload->create_spi_iterator(delete_payload);
- while (spis->iterate(spis, (void**)&spi))
+ spis = delete_payload->create_spi_enumerator(delete_payload);
+ while (spis->enumerate(spis, &spi))
{
child_sa = this->ike_sa->get_child_sa(this->ike_sa, protocol,
- *spi, FALSE);
+ spi, FALSE);
if (child_sa == NULL)
{
DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x, "
- "but no such SA", protocol_id_names, protocol, ntohl(*spi));
+ "but no such SA", protocol_id_names, protocol, ntohl(spi));
continue;
}
DBG1(DBG_IKE, "received DELETE for %N CHILD_SA with SPI %.8x",
- protocol_id_names, protocol, ntohl(*spi));
+ protocol_id_names, protocol, ntohl(spi));
switch (child_sa->get_state(child_sa))
{
@@ -161,7 +160,7 @@ static void process_payloads(private_child_delete_t *this, message_t *message)
if (!this->initiator)
{
this->ike_sa->destroy_child_sa(this->ike_sa,
- protocol, *spi);
+ protocol, spi);
continue;
}
case CHILD_INSTALLED:
diff --git a/src/libcharon/sa/tasks/child_rekey.c b/src/libcharon/sa/tasks/child_rekey.c
index fb3452efd..fdaaea4b8 100644
--- a/src/libcharon/sa/tasks/child_rekey.c
+++ b/src/libcharon/sa/tasks/child_rekey.c
@@ -75,6 +75,15 @@ struct private_child_rekey_t {
* colliding task, may be delete or rekey
*/
task_t *collision;
+
+ /**
+ * Indicate that peer destroyed the redundant child from collision.
+ * This happens if a peer's delete notification for the redundant
+ * child gets processed before the rekey job. If so, we must not
+ * touch the child created in the collision since it points to
+ * memory already freed.
+ */
+ bool other_child_destroyed;
};
/**
@@ -239,9 +248,13 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
DBG1(DBG_IKE, "CHILD_SA rekey collision won, "
"deleting rekeyed child");
to_delete = this->child_sa;
- /* disable close action for the redundand child */
- child_sa = other->child_create->get_child(other->child_create);
- child_sa->set_close_action(child_sa, ACTION_NONE);
+ /* don't touch child other created, it has already been deleted */
+ if (!this->other_child_destroyed)
+ {
+ /* disable close action for the redundand child */
+ child_sa = other->child_create->get_child(other->child_create);
+ child_sa->set_close_action(child_sa, ACTION_NONE);
+ }
}
else
{
@@ -286,7 +299,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "peer seems to not support CHILD_SA rekeying, "
"starting reauthentication");
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)rekey_ike_sa_job_create(
this->ike_sa->get_id(this->ike_sa), TRUE));
return SUCCESS;
@@ -316,7 +329,7 @@ static status_t process_i(private_child_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "CHILD_SA rekeying failed, "
"trying again in %d seconds", retry);
this->child_sa->set_state(this->child_sa, CHILD_INSTALLED);
- charon->scheduler->schedule_job(charon->scheduler, job, retry);
+ lib->scheduler->schedule_job(lib->scheduler, job, retry);
}
return SUCCESS;
}
@@ -380,6 +393,13 @@ static void collide(private_child_rekey_t *this, task_t *other)
else if (other->get_type(other) == CHILD_DELETE)
{
child_delete_t *del = (child_delete_t*)other;
+ if (del->get_child(del) == this->child_create->get_child(this->child_create))
+ {
+ /* peer deletes redundant child created in collision */
+ this->other_child_destroyed = TRUE;
+ other->destroy(other);
+ return;
+ }
if (del == NULL || del->get_child(del) != this->child_sa)
{
/* not the same child => no collision */
@@ -466,6 +486,7 @@ child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, protocol_id_t protocol,
this->spi = spi;
this->collision = NULL;
this->child_delete = NULL;
+ this->other_child_destroyed = FALSE;
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_auth.c b/src/libcharon/sa/tasks/ike_auth.c
index a954782f2..b440ec811 100644
--- a/src/libcharon/sa/tasks/ike_auth.c
+++ b/src/libcharon/sa/tasks/ike_auth.c
@@ -481,9 +481,8 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
{
this->ike_sa->enable_extension(this->ike_sa, EXT_MULTIPLE_AUTH);
}
- if (this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) &&
- message->get_notify(message, EAP_ONLY_AUTHENTICATION))
- { /* EAP-only has no official notify, accept only from strongSwan */
+ if (message->get_notify(message, EAP_ONLY_AUTHENTICATION))
+ {
this->ike_sa->enable_extension(this->ike_sa,
EXT_EAP_ONLY_AUTHENTICATION);
}
@@ -538,6 +537,11 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
{
cfg->add(cfg, AUTH_RULE_EAP_IDENTITY, id->clone(id));
}
+ id = (identification_t*)cand->get(cand, AUTH_RULE_AAA_IDENTITY);
+ if (id)
+ {
+ cfg->add(cfg, AUTH_RULE_AAA_IDENTITY, id->clone(id));
+ }
}
/* verify authentication data */
@@ -821,7 +825,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
break;
default:
{
- if (type < 16383)
+ if (type <= 16383)
{
DBG1(DBG_IKE, "received %N notify error",
notify_type_names, type);
diff --git a/src/libcharon/sa/tasks/ike_init.c b/src/libcharon/sa/tasks/ike_init.c
index 38fb572f4..dd4a5f5c0 100644
--- a/src/libcharon/sa/tasks/ike_init.c
+++ b/src/libcharon/sa/tasks/ike_init.c
@@ -468,7 +468,7 @@ static status_t process_i(private_ike_init_t *this, message_t *message)
}
default:
{
- if (type < 16383)
+ if (type <= 16383)
{
DBG1(DBG_IKE, "received %N notify error",
notify_type_names, type);
diff --git a/src/libcharon/sa/tasks/ike_me.c b/src/libcharon/sa/tasks/ike_me.c
index 2d2847ae0..1de6ae8fc 100644
--- a/src/libcharon/sa/tasks/ike_me.c
+++ b/src/libcharon/sa/tasks/ike_me.c
@@ -17,6 +17,7 @@
#include <string.h>
+#include <hydra.h>
#include <daemon.h>
#include <config/peer_cfg.h>
#include <encoding/payloads/id_payload.h>
@@ -134,8 +135,8 @@ static void gather_and_add_endpoints(private_ike_me_t *this, message_t *message)
host = this->ike_sa->get_my_host(this->ike_sa);
port = host->get_port(host);
- enumerator = charon->kernel_interface->create_address_enumerator(
- charon->kernel_interface, FALSE, FALSE);
+ enumerator = hydra->kernel_interface->create_address_enumerator(
+ hydra->kernel_interface, FALSE, FALSE);
while (enumerator->enumerate(enumerator, (void**)&addr))
{
host = addr->clone(addr);
@@ -454,6 +455,9 @@ static status_t process_i(private_ike_me_t *this, message_t *message)
DBG1(DBG_IKE, "server did not return a ME_MEDIATION, aborting");
return FAILED;
}
+ /* if we are on a mediation connection we switch to port 4500 even
+ * if no NAT is detected. */
+ this->ike_sa->float_ports(this->ike_sa);
return NEED_MORE;
}
case IKE_AUTH:
@@ -689,7 +693,7 @@ static status_t build_r_ms(private_ike_me_t *this, message_t *message)
job_t *job = (job_t*)mediation_job_create(this->peer_id,
this->ike_sa->get_other_id(this->ike_sa), this->connect_id,
this->connect_key, this->remote_endpoints, this->response);
- charon->processor->queue_job(charon->processor, job);
+ lib->processor->queue_job(lib->processor, job);
break;
}
default:
diff --git a/src/libcharon/sa/tasks/ike_mobike.c b/src/libcharon/sa/tasks/ike_mobike.c
index a62886f02..5b12eaaac 100644
--- a/src/libcharon/sa/tasks/ike_mobike.c
+++ b/src/libcharon/sa/tasks/ike_mobike.c
@@ -17,6 +17,7 @@
#include <string.h>
+#include <hydra.h>
#include <daemon.h>
#include <sa/tasks/ike_natd.h>
#include <encoding/payloads/notify_payload.h>
@@ -70,6 +71,11 @@ struct private_ike_mobike_t {
* include address list update
*/
bool address;
+
+ /**
+ * additional addresses got updated
+ */
+ bool addresses_updated;
};
/**
@@ -153,6 +159,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
host = host_create_from_chunk(family, data, 0);
DBG2(DBG_IKE, "got additional MOBIKE peer address: %H", host);
this->ike_sa->add_additional_address(this->ike_sa, host);
+ this->addresses_updated = TRUE;
break;
}
case UPDATE_SA_ADDRESSES:
@@ -163,6 +170,7 @@ static void process_payloads(private_ike_mobike_t *this, message_t *message)
case NO_ADDITIONAL_ADDRESSES:
{
flush_additional_addresses(this);
+ this->addresses_updated = TRUE;
break;
}
case NAT_DETECTION_SOURCE_IP:
@@ -193,8 +201,8 @@ static void build_address_list(private_ike_mobike_t *this, message_t *message)
int added = 0;
me = this->ike_sa->get_my_host(this->ike_sa);
- enumerator = charon->kernel_interface->create_address_enumerator(
- charon->kernel_interface, FALSE, FALSE);
+ enumerator = hydra->kernel_interface->create_address_enumerator(
+ hydra->kernel_interface, FALSE, FALSE);
while (enumerator->enumerate(enumerator, (void**)&host))
{
if (me->ip_equals(me, host))
@@ -269,32 +277,23 @@ static void update_children(private_ike_mobike_t *this)
}
/**
- * Apply port of old address if it equals new, port otherwise
+ * Apply the port of the old host, if its ip equals the new, use port otherwise.
*/
-static void apply_port(private_ike_mobike_t *this, host_t *host, host_t *old,
- u_int16_t port)
+static void apply_port(host_t *host, host_t *old, u_int16_t port)
{
if (host->ip_equals(host, old))
{
- host->set_port(host, old->get_port(old));
+ port = old->get_port(old);
}
- else
+ else if (port == IKEV2_UDP_PORT)
{
- if (port == IKEV2_UDP_PORT)
- {
- host->set_port(host, IKEV2_NATT_PORT);
- }
- else
- {
- host->set_port(host, port);
- }
+ port = IKEV2_NATT_PORT;
}
+ host->set_port(host, port);
}
-/**
- * Implementation of ike_mobike_t.transmit
- */
-static void transmit(private_ike_mobike_t *this, packet_t *packet)
+METHOD(ike_mobike_t, transmit, void,
+ private_ike_mobike_t *this, packet_t *packet)
{
host_t *me, *other, *me_old, *other_old;
iterator_t *iterator;
@@ -310,11 +309,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
other_old = this->ike_sa->get_other_host(this->ike_sa);
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
- me = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, other_old, NULL);
+ me = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, other_old, NULL);
if (me)
{
- apply_port(this, me, me_old, ike_cfg->get_my_port(ike_cfg));
+ apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg));
DBG1(DBG_IKE, "checking original path %#H - %#H", me, other_old);
copy = packet->clone(packet);
copy->set_source(copy, me);
@@ -324,8 +323,8 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
iterator = this->ike_sa->create_additional_address_iterator(this->ike_sa);
while (iterator->iterate(iterator, (void**)&other))
{
- me = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, other, NULL);
+ me = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, other, NULL);
if (me)
{
if (me->get_family(me) != other->get_family(other))
@@ -334,9 +333,9 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
continue;
}
/* reuse port for an active address, 4500 otherwise */
- apply_port(this, me, me_old, ike_cfg->get_my_port(ike_cfg));
+ apply_port(me, me_old, ike_cfg->get_my_port(ike_cfg));
other = other->clone(other);
- apply_port(this, other, other_old, ike_cfg->get_other_port(ike_cfg));
+ apply_port(other, other_old, ike_cfg->get_other_port(ike_cfg));
DBG1(DBG_IKE, "checking path %#H - %#H", me, other);
copy = packet->clone(packet);
copy->set_source(copy, me);
@@ -347,12 +346,11 @@ static void transmit(private_ike_mobike_t *this, packet_t *packet)
iterator->destroy(iterator);
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t build_i(private_ike_mobike_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_mobike_t *this, message_t *message)
{
- if (message->get_message_id(message) == 1)
+ if (message->get_exchange_type(message) == IKE_AUTH &&
+ message->get_message_id(message) == 1)
{ /* only in first IKE_AUTH */
message->add_notify(message, FALSE, MOBIKE_SUPPORTED, chunk_empty);
build_address_list(this, message);
@@ -363,7 +361,7 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
/* we check if the existing address is still valid */
old = message->get_source(message);
- new = charon->kernel_interface->get_source_addr(charon->kernel_interface,
+ new = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
message->get_destination(message), old);
if (new)
{
@@ -379,11 +377,12 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
}
if (this->update)
{
- message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES, chunk_empty);
+ message->add_notify(message, FALSE, UPDATE_SA_ADDRESSES,
+ chunk_empty);
build_cookie(this, message);
update_children(this);
}
- if (this->address)
+ if (this->address && !this->check)
{
build_address_list(this, message);
}
@@ -395,12 +394,11 @@ static status_t build_i(private_ike_mobike_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_mobike_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_mobike_t *this, message_t *message)
{
- if (message->get_message_id(message) == 1)
+ if (message->get_exchange_type(message) == IKE_AUTH &&
+ message->get_message_id(message) == 1)
{ /* only first IKE_AUTH */
process_payloads(this, message);
}
@@ -421,14 +419,25 @@ static status_t process_r(private_ike_mobike_t *this, message_t *message)
{
this->natd->task.process(&this->natd->task, message);
}
+ if (this->addresses_updated && this->ike_sa->has_condition(this->ike_sa,
+ COND_ORIGINAL_INITIATOR))
+ {
+ host_t *other = message->get_source(message);
+ host_t *other_old = this->ike_sa->get_other_host(this->ike_sa);
+ if (!other->equals(other, other_old))
+ {
+ DBG1(DBG_IKE, "remote address changed from %H to %H", other_old,
+ other);
+ this->ike_sa->set_other_host(this->ike_sa, other->clone(other));
+ this->update = TRUE;
+ }
+ }
}
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_mobike_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
@@ -460,10 +469,8 @@ static status_t build_r(private_ike_mobike_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_mobike_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_mobike_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_AUTH &&
this->ike_sa->get_state(this->ike_sa) == IKE_ESTABLISHED)
@@ -536,14 +543,22 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
}
if (this->update)
{
- /* start the update with the same task */
- this->check = FALSE;
- this->address = FALSE;
- if (this->natd)
- {
- this->natd->task.destroy(&this->natd->task);
+ /* use the same task to ... */
+ if (!this->ike_sa->has_condition(this->ike_sa,
+ COND_ORIGINAL_INITIATOR))
+ { /*... send an updated list of addresses as responder */
+ update_children(this);
+ this->update = FALSE;
+ }
+ else
+ { /* ... send the update as original initiator */
+ if (this->natd)
+ {
+ this->natd->task.destroy(&this->natd->task);
+ }
+ this->natd = ike_natd_create(this->ike_sa, this->initiator);
}
- this->natd = ike_natd_create(this->ike_sa, this->initiator);
+ this->check = FALSE;
this->ike_sa->set_pending_updates(this->ike_sa, 1);
return NEED_MORE;
}
@@ -553,51 +568,48 @@ static status_t process_i(private_ike_mobike_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of ike_mobike_t.roam.
- */
-static void roam(private_ike_mobike_t *this, bool address)
+METHOD(ike_mobike_t, addresses, void,
+ private_ike_mobike_t *this)
+{
+ this->address = TRUE;
+ this->ike_sa->set_pending_updates(this->ike_sa,
+ this->ike_sa->get_pending_updates(this->ike_sa) + 1);
+}
+
+METHOD(ike_mobike_t, roam, void,
+ private_ike_mobike_t *this, bool address)
{
this->check = TRUE;
this->address = address;
this->ike_sa->set_pending_updates(this->ike_sa,
- this->ike_sa->get_pending_updates(this->ike_sa) + 1);
+ this->ike_sa->get_pending_updates(this->ike_sa) + 1);
}
-/**
- * Implementation of ike_mobike_t.dpd
- */
-static void dpd(private_ike_mobike_t *this)
+METHOD(ike_mobike_t, dpd, void,
+ private_ike_mobike_t *this)
{
if (!this->natd)
{
this->natd = ike_natd_create(this->ike_sa, this->initiator);
}
- this->address = FALSE;
this->ike_sa->set_pending_updates(this->ike_sa,
- this->ike_sa->get_pending_updates(this->ike_sa) + 1);
+ this->ike_sa->get_pending_updates(this->ike_sa) + 1);
}
-/**
- * Implementation of ike_mobike_t.is_probing.
- */
-static bool is_probing(private_ike_mobike_t *this)
+METHOD(ike_mobike_t, is_probing, bool,
+ private_ike_mobike_t *this)
{
return this->check;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_mobike_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_mobike_t *this)
{
return IKE_MOBIKE;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_mobike_t *this, ike_sa_t *ike_sa)
{
chunk_free(&this->cookie2);
this->ike_sa = ike_sa;
@@ -607,10 +619,8 @@ static void migrate(private_ike_mobike_t *this, ike_sa_t *ike_sa)
}
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_mobike_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_mobike_t *this)
{
chunk_free(&this->cookie2);
if (this->natd)
@@ -625,35 +635,36 @@ static void destroy(private_ike_mobike_t *this)
*/
ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_mobike_t *this = malloc_thing(private_ike_mobike_t);
-
- this->public.roam = (void(*)(ike_mobike_t*,bool))roam;
- this->public.dpd = (void(*)(ike_mobike_t*))dpd;
- this->public.transmit = (void(*)(ike_mobike_t*,packet_t*))transmit;
- this->public.is_probing = (bool(*)(ike_mobike_t*))is_probing;
- this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
- this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
- this->public.task.destroy = (void(*)(task_t*))destroy;
+ private_ike_mobike_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ .addresses = _addresses,
+ .roam = _roam,
+ .dpd = _dpd,
+ .transmit = _transmit,
+ .is_probing = _is_probing,
+ },
+ .ike_sa = ike_sa,
+ .initiator = initiator,
+ );
if (initiator)
{
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
+ this->public.task.build = _build_i;
+ this->public.task.process = _process_i;
}
else
{
- this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
- this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
+ this->public.task.build = _build_r;
+ this->public.task.process = _process_r;
}
- this->ike_sa = ike_sa;
- this->initiator = initiator;
- this->update = FALSE;
- this->check = FALSE;
- this->address = TRUE;
- this->cookie2 = chunk_empty;
- this->natd = NULL;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_mobike.h b/src/libcharon/sa/tasks/ike_mobike.h
index 05b2224d1..16611939e 100644
--- a/src/libcharon/sa/tasks/ike_mobike.h
+++ b/src/libcharon/sa/tasks/ike_mobike.h
@@ -46,6 +46,11 @@ struct ike_mobike_t {
task_t task;
/**
+ * Use the task to update the list of additional addresses.
+ */
+ void (*addresses)(ike_mobike_t *this);
+
+ /**
* Use the task to roam to other addresses.
*
* @param address TRUE to include address list update
diff --git a/src/libcharon/sa/tasks/ike_natd.c b/src/libcharon/sa/tasks/ike_natd.c
index 9ea20ba36..7839b52eb 100644
--- a/src/libcharon/sa/tasks/ike_natd.c
+++ b/src/libcharon/sa/tasks/ike_natd.c
@@ -18,6 +18,7 @@
#include <string.h>
+#include <hydra.h>
#include <daemon.h>
#include <config/peer_cfg.h>
#include <crypto/hashers/hasher.h>
@@ -265,41 +266,15 @@ static status_t process_i(private_ike_natd_t *this, message_t *message)
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
peer_cfg_t *peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
-
-#ifdef ME
- /* if we are on a mediated connection we have already switched to
- * port 4500 and the correct destination port is already configured,
- * therefore we must not switch again */
- if (peer_cfg->get_mediated_by(peer_cfg))
- {
- return SUCCESS;
- }
-#endif /* ME */
-
if (this->ike_sa->has_condition(this->ike_sa, COND_NAT_ANY) ||
-#ifdef ME
- /* if we are on a mediation connection we switch to port 4500 even
- * if no NAT is detected. */
- peer_cfg->is_mediation(peer_cfg) ||
-#endif /* ME */
/* if peer supports NAT-T, we switch to port 4500 even
- * if no NAT is detected. MOBIKE requires this. */
+ * if no NAT is detected. can't be done later (when we would know
+ * whether the peer supports MOBIKE) because there would be no
+ * exchange to actually do the switch (other than a forced DPD). */
(peer_cfg->use_mobike(peer_cfg) &&
this->ike_sa->supports_extension(this->ike_sa, EXT_NATT)))
{
- host_t *me, *other;
-
- /* do not switch if we have a custom port from mobike/NAT */
- me = this->ike_sa->get_my_host(this->ike_sa);
- if (me->get_port(me) == IKEV2_UDP_PORT)
- {
- me->set_port(me, IKEV2_NATT_PORT);
- }
- other = this->ike_sa->get_other_host(this->ike_sa);
- if (other->get_port(other) == IKEV2_UDP_PORT)
- {
- other->set_port(other, IKEV2_NATT_PORT);
- }
+ this->ike_sa->float_ports(this->ike_sa);
}
}
@@ -342,7 +317,7 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
}
else
{
- host = charon->kernel_interface->get_source_addr(charon->kernel_interface,
+ host = hydra->kernel_interface->get_source_addr(hydra->kernel_interface,
this->ike_sa->get_other_host(this->ike_sa), NULL);
if (host)
{ /* 2. */
@@ -353,8 +328,8 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
}
else
{ /* 3. */
- enumerator = charon->kernel_interface->create_address_enumerator(
- charon->kernel_interface, FALSE, FALSE);
+ enumerator = hydra->kernel_interface->create_address_enumerator(
+ hydra->kernel_interface, FALSE, FALSE);
while (enumerator->enumerate(enumerator, (void**)&host))
{
/* apply port 500 to host, but work on a copy */
diff --git a/src/libcharon/sa/tasks/ike_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c
index a2275e796..1a6c140c4 100644
--- a/src/libcharon/sa/tasks/ike_rekey.c
+++ b/src/libcharon/sa/tasks/ike_rekey.c
@@ -196,7 +196,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "peer seems to not support IKE rekeying, "
"starting reauthentication");
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- charon->processor->queue_job(charon->processor,
+ lib->processor->queue_job(lib->processor,
(job_t*)rekey_ike_sa_job_create(
this->ike_sa->get_id(this->ike_sa), TRUE));
return SUCCESS;
@@ -217,7 +217,7 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
DBG1(DBG_IKE, "IKE_SA rekeying failed, "
"trying again in %d seconds", retry);
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- charon->scheduler->schedule_job(charon->scheduler, job, retry);
+ lib->scheduler->schedule_job(lib->scheduler, job, retry);
}
return SUCCESS;
case NEED_MORE:
@@ -241,51 +241,56 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
if (this->collision &&
this->collision->get_type(this->collision) == IKE_REKEY)
{
- chunk_t this_nonce, other_nonce;
- host_t *host;
private_ike_rekey_t *other = (private_ike_rekey_t*)this->collision;
- this_nonce = this->ike_init->get_lower_nonce(this->ike_init);
- other_nonce = other->ike_init->get_lower_nonce(other->ike_init);
-
- /* if we have the lower nonce, delete rekeyed SA. If not, delete
- * the redundant. */
- if (memcmp(this_nonce.ptr, other_nonce.ptr,
- min(this_nonce.len, other_nonce.len)) < 0)
- {
- /* peer should delete this SA. Add a timeout just in case. */
- job_t *job = (job_t*)delete_ike_sa_job_create(
- other->new_sa->get_id(other->new_sa), TRUE);
- charon->scheduler->schedule_job(charon->scheduler, job, 10);
- DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA");
- charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa);
- other->new_sa = NULL;
- }
- else
+ /* ike_init can be NULL, if child_sa is half-open */
+ if (other->ike_init)
{
- DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA");
- /* apply host for a proper delete */
- host = this->ike_sa->get_my_host(this->ike_sa);
- this->new_sa->set_my_host(this->new_sa, host->clone(host));
- host = this->ike_sa->get_other_host(this->ike_sa);
- this->new_sa->set_other_host(this->new_sa, host->clone(host));
- this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
- if (this->new_sa->delete(this->new_sa) == DESTROY_ME)
+ host_t *host;
+ chunk_t this_nonce, other_nonce;
+
+ this_nonce = this->ike_init->get_lower_nonce(this->ike_init);
+ other_nonce = other->ike_init->get_lower_nonce(other->ike_init);
+
+ /* if we have the lower nonce, delete rekeyed SA. If not, delete
+ * the redundant. */
+ if (memcmp(this_nonce.ptr, other_nonce.ptr,
+ min(this_nonce.len, other_nonce.len)) < 0)
{
- charon->ike_sa_manager->checkin_and_destroy(
- charon->ike_sa_manager, this->new_sa);
+ /* peer should delete this SA. Add a timeout just in case. */
+ job_t *job = (job_t*)delete_ike_sa_job_create(
+ other->new_sa->get_id(other->new_sa), TRUE);
+ lib->scheduler->schedule_job(lib->scheduler, job, 10);
+ DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA");
+ charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa);
+ other->new_sa = NULL;
}
else
{
- charon->ike_sa_manager->checkin(
- charon->ike_sa_manager, this->new_sa);
+ DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_SA");
+ /* apply host for a proper delete */
+ host = this->ike_sa->get_my_host(this->ike_sa);
+ this->new_sa->set_my_host(this->new_sa, host->clone(host));
+ host = this->ike_sa->get_other_host(this->ike_sa);
+ this->new_sa->set_other_host(this->new_sa, host->clone(host));
+ this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
+ if (this->new_sa->delete(this->new_sa) == DESTROY_ME)
+ {
+ charon->ike_sa_manager->checkin_and_destroy(
+ charon->ike_sa_manager, this->new_sa);
+ }
+ else
+ {
+ charon->ike_sa_manager->checkin(
+ charon->ike_sa_manager, this->new_sa);
+ }
+ /* set threads active IKE_SA after checkin */
+ charon->bus->set_sa(charon->bus, this->ike_sa);
+ /* inherit to other->new_sa in destroy() */
+ this->new_sa = other->new_sa;
+ other->new_sa = NULL;
+ return SUCCESS;
}
- /* set threads active IKE_SA after checkin */
- charon->bus->set_sa(charon->bus, this->ike_sa);
- /* inherit to other->new_sa in destroy() */
- this->new_sa = other->new_sa;
- other->new_sa = NULL;
- return SUCCESS;
}
/* set threads active IKE_SA after checkin */
charon->bus->set_sa(charon->bus, this->ike_sa);
diff --git a/src/libcharon/sa/tasks/ike_vendor.c b/src/libcharon/sa/tasks/ike_vendor.c
index 7c435b6d1..1c14ee06b 100644
--- a/src/libcharon/sa/tasks/ike_vendor.c
+++ b/src/libcharon/sa/tasks/ike_vendor.c
@@ -123,12 +123,14 @@ ike_vendor_t *ike_vendor_create(ike_sa_t *ike_sa, bool initiator)
private_ike_vendor_t *this;
INIT(this,
- .public.task = {
- .build = _build,
- .process = _process,
- .migrate = _migrate,
- .get_type = _get_type,
- .destroy = _destroy,
+ .public = {
+ .task = {
+ .build = _build,
+ .process = _process,
+ .migrate = _migrate,
+ .get_type = _get_type,
+ .destroy = _destroy,
+ },
},
.initiator = initiator,
.ike_sa = ike_sa,
diff --git a/src/libcharon/sa/trap_manager.c b/src/libcharon/sa/trap_manager.c
index 80bf647cd..f91eff077 100644
--- a/src/libcharon/sa/trap_manager.c
+++ b/src/libcharon/sa/trap_manager.c
@@ -15,6 +15,7 @@
#include "trap_manager.h"
+#include <hydra.h>
#include <daemon.h>
#include <threading/rwlock.h>
#include <utils/linked_list.h>
@@ -138,8 +139,8 @@ static u_int32_t install(private_trap_manager_t *this, peer_cfg_t *peer,
if (!me || me->is_anyaddr(me))
{
DESTROY_IF(me);
- me = charon->kernel_interface->get_source_addr(
- charon->kernel_interface, other, NULL);
+ me = hydra->kernel_interface->get_source_addr(
+ hydra->kernel_interface, other, NULL);
if (!me)
{
DBG1(DBG_CFG, "installing trap failed, local address unknown");