summaryrefslogtreecommitdiff
path: root/src/libcharon/sa/tasks
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/sa/tasks')
-rw-r--r--src/libcharon/sa/tasks/child_create.c182
-rw-r--r--src/libcharon/sa/tasks/child_rekey.c7
-rw-r--r--src/libcharon/sa/tasks/ike_auth.c200
-rw-r--r--src/libcharon/sa/tasks/ike_cert_pre.c19
-rw-r--r--src/libcharon/sa/tasks/ike_rekey.c7
5 files changed, 237 insertions, 178 deletions
diff --git a/src/libcharon/sa/tasks/child_create.c b/src/libcharon/sa/tasks/child_create.c
index 57beedba9..fc02a334b 100644
--- a/src/libcharon/sa/tasks/child_create.c
+++ b/src/libcharon/sa/tasks/child_create.c
@@ -117,6 +117,11 @@ struct private_child_create_t {
ipsec_mode_t mode;
/**
+ * peer accepts TFC padding for this SA
+ */
+ bool tfcv3;
+
+ /**
* IPComp transform to use
*/
ipcomp_transform_t ipcomp;
@@ -455,17 +460,21 @@ static status_t select_and_install(private_child_create_t *this,
{
if (this->initiator)
{
- status_i = this->child_sa->install(this->child_sa, encr_r, integ_r,
- this->my_spi, this->my_cpi, TRUE, my_ts, other_ts);
- status_o = this->child_sa->install(this->child_sa, encr_i, integ_i,
- this->other_spi, this->other_cpi, FALSE, my_ts, other_ts);
+ status_i = this->child_sa->install(this->child_sa,
+ encr_r, integ_r, this->my_spi, this->my_cpi,
+ TRUE, this->tfcv3, my_ts, other_ts);
+ status_o = this->child_sa->install(this->child_sa,
+ encr_i, integ_i, this->other_spi, this->other_cpi,
+ FALSE, this->tfcv3, my_ts, other_ts);
}
else
{
- status_i = this->child_sa->install(this->child_sa, encr_i, integ_i,
- this->my_spi, this->my_cpi, TRUE, my_ts, other_ts);
- status_o = this->child_sa->install(this->child_sa, encr_r, integ_r,
- this->other_spi, this->other_cpi, FALSE, my_ts, other_ts);
+ status_i = this->child_sa->install(this->child_sa,
+ encr_i, integ_i, this->my_spi, this->my_cpi,
+ TRUE, this->tfcv3, my_ts, other_ts);
+ status_o = this->child_sa->install(this->child_sa,
+ encr_r, integ_r, this->other_spi, this->other_cpi,
+ FALSE, this->tfcv3, my_ts, other_ts);
}
}
chunk_clear(&integ_i);
@@ -631,7 +640,13 @@ static void handle_notify(private_child_create_t *this, notify_payload_t *notify
ipcomp_transform_names, ipcomp);
break;
}
+ break;
}
+ case ESP_TFC_PADDING_NOT_SUPPORTED:
+ DBG1(DBG_IKE, "received %N, not using ESPv3 TFC padding",
+ notify_type_names, notify->get_notify_type(notify));
+ this->tfcv3 = FALSE;
+ break;
default:
break;
}
@@ -691,10 +706,8 @@ static void process_payloads(private_child_create_t *this, message_t *message)
enumerator->destroy(enumerator);
}
-/**
- * Implementation of task_t.build for initiator
- */
-static status_t build_i(private_child_create_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_child_create_t *this, message_t *message)
{
host_t *me, *other, *vip;
peer_cfg_t *peer_cfg;
@@ -831,10 +844,8 @@ static status_t build_i(private_child_create_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_child_create_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_child_create_t *this, message_t *message)
{
switch (message->get_exchange_type(message))
{
@@ -877,10 +888,8 @@ static void handle_child_sa_failure(private_child_create_t *this,
}
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_child_create_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_child_create_t *this, message_t *message)
{
peer_cfg_t *peer_cfg;
payload_t *payload;
@@ -958,7 +967,7 @@ static status_t build_r(private_child_create_t *this, message_t *message)
case INTERNAL_ADDRESS_FAILURE:
case FAILED_CP_REQUIRED:
{
- DBG1(DBG_IKE,"configuration payload negotation "
+ DBG1(DBG_IKE,"configuration payload negotiation "
"failed, no CHILD_SA built");
enumerator->destroy(enumerator);
handle_child_sa_failure(this, message);
@@ -1029,10 +1038,8 @@ static status_t build_r(private_child_create_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_child_create_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_child_create_t *this, message_t *message)
{
enumerator_t *enumerator;
payload_t *payload;
@@ -1103,7 +1110,21 @@ static status_t process_i(private_child_create_t *this, message_t *message)
return NEED_MORE;
}
default:
+ {
+ if (message->get_exchange_type(message) == CREATE_CHILD_SA)
+ { /* handle notifies if not handled in IKE_AUTH */
+ if (type <= 16383)
+ {
+ DBG1(DBG_IKE, "received %N notify error",
+ notify_type_names, type);
+ enumerator->destroy(enumerator);
+ return SUCCESS;
+ }
+ DBG2(DBG_IKE, "received %N notify",
+ notify_type_names, type);
+ }
break;
+ }
}
}
}
@@ -1155,34 +1176,20 @@ static status_t process_i(private_child_create_t *this, message_t *message)
return SUCCESS;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_child_create_t *this)
-{
- return CHILD_CREATE;
-}
-
-/**
- * Implementation of child_create_t.use_reqid
- */
-static void use_reqid(private_child_create_t *this, u_int32_t reqid)
+METHOD(child_create_t, use_reqid, void,
+ private_child_create_t *this, u_int32_t reqid)
{
this->reqid = reqid;
}
-/**
- * Implementation of child_create_t.get_child
- */
-static child_sa_t* get_child(private_child_create_t *this)
+METHOD(child_create_t, get_child, child_sa_t*,
+ private_child_create_t *this)
{
return this->child_sa;
}
-/**
- * Implementation of child_create_t.get_lower_nonce
- */
-static chunk_t get_lower_nonce(private_child_create_t *this)
+METHOD(child_create_t, get_lower_nonce, chunk_t,
+ private_child_create_t *this)
{
if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
min(this->my_nonce.len, this->other_nonce.len)) < 0)
@@ -1195,10 +1202,14 @@ static chunk_t get_lower_nonce(private_child_create_t *this)
}
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_child_create_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, get_type, task_type_t,
+ private_child_create_t *this)
+{
+ return CHILD_CREATE;
+}
+
+METHOD(task_t, migrate, void,
+ private_child_create_t *this, ike_sa_t *ike_sa)
{
chunk_free(&this->my_nonce);
chunk_free(&this->other_nonce);
@@ -1234,10 +1245,8 @@ static void migrate(private_child_create_t *this, ike_sa_t *ike_sa)
this->established = FALSE;
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_child_create_t *this)
+METHOD(task_t, destroy, void,
+ private_child_create_t *this)
{
chunk_free(&this->my_nonce);
chunk_free(&this->other_nonce);
@@ -1273,52 +1282,45 @@ child_create_t *child_create_create(ike_sa_t *ike_sa,
child_cfg_t *config, bool rekey,
traffic_selector_t *tsi, traffic_selector_t *tsr)
{
- private_child_create_t *this = malloc_thing(private_child_create_t);
-
- this->public.get_child = (child_sa_t*(*)(child_create_t*))get_child;
- this->public.get_lower_nonce = (chunk_t(*)(child_create_t*))get_lower_nonce;
- this->public.use_reqid = (void(*)(child_create_t*,u_int32_t))use_reqid;
- 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_child_create_t *this;
+
+ INIT(this,
+ .public = {
+ .get_child = _get_child,
+ .get_lower_nonce = _get_lower_nonce,
+ .use_reqid = _use_reqid,
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ .config = config,
+ .packet_tsi = tsi ? tsi->clone(tsi) : NULL,
+ .packet_tsr = tsr ? tsr->clone(tsr) : NULL,
+ .dh_group = MODP_NONE,
+ .keymat = ike_sa->get_keymat(ike_sa),
+ .mode = MODE_TUNNEL,
+ .tfcv3 = TRUE,
+ .ipcomp = IPCOMP_NONE,
+ .ipcomp_received = IPCOMP_NONE,
+ .rekey = rekey,
+ );
+
if (config)
{
- 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;
this->initiator = TRUE;
config->get_ref(config);
}
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->initiator = FALSE;
}
- this->ike_sa = ike_sa;
- this->config = config;
- this->my_nonce = chunk_empty;
- this->other_nonce = chunk_empty;
- this->proposals = NULL;
- this->proposal = NULL;
- this->tsi = NULL;
- this->tsr = NULL;
- this->packet_tsi = tsi ? tsi->clone(tsi) : NULL;
- this->packet_tsr = tsr ? tsr->clone(tsr) : NULL;
- this->dh = NULL;
- this->dh_group = MODP_NONE;
- this->keymat = ike_sa->get_keymat(ike_sa);
- this->child_sa = NULL;
- this->mode = MODE_TUNNEL;
- this->ipcomp = IPCOMP_NONE;
- this->ipcomp_received = IPCOMP_NONE;
- this->my_spi = 0;
- this->other_spi = 0;
- this->my_cpi = 0;
- this->other_cpi = 0;
- this->reqid = 0;
- this->established = FALSE;
- this->rekey = rekey;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/child_rekey.c b/src/libcharon/sa/tasks/child_rekey.c
index fdaaea4b8..e74ca4eef 100644
--- a/src/libcharon/sa/tasks/child_rekey.c
+++ b/src/libcharon/sa/tasks/child_rekey.c
@@ -241,12 +241,11 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
/* 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)
+ min(this_nonce.len, other_nonce.len)) > 0)
{
child_sa_t *child_sa;
- DBG1(DBG_IKE, "CHILD_SA rekey collision won, "
- "deleting rekeyed child");
+ DBG1(DBG_IKE, "CHILD_SA rekey collision won, deleting old child");
to_delete = this->child_sa;
/* don't touch child other created, it has already been deleted */
if (!this->other_child_destroyed)
@@ -259,7 +258,7 @@ static child_sa_t *handle_collision(private_child_rekey_t *this)
else
{
DBG1(DBG_IKE, "CHILD_SA rekey collision lost, "
- "deleting redundant child");
+ "deleting rekeyed child");
to_delete = this->child_create->get_child(this->child_create);
}
}
diff --git a/src/libcharon/sa/tasks/ike_auth.c b/src/libcharon/sa/tasks/ike_auth.c
index b440ec811..0756c7d60 100644
--- a/src/libcharon/sa/tasks/ike_auth.c
+++ b/src/libcharon/sa/tasks/ike_auth.c
@@ -68,6 +68,11 @@ struct private_ike_auth_t {
packet_t *other_packet;
/**
+ * Reserved bytes of ID payload
+ */
+ char reserved[3];
+
+ /**
* currently active authenticator, to authenticate us
*/
authenticator_t *my_auth;
@@ -101,6 +106,11 @@ struct private_ike_auth_t {
* should we send a AUTHENTICATION_FAILED notify?
*/
bool authentication_failed;
+
+ /**
+ * received an INITIAL_CONTACT?
+ */
+ bool initial_contact;
};
/**
@@ -160,6 +170,24 @@ static status_t collect_other_init_data(private_ike_auth_t *this,
}
/**
+ * Get and store reserved bytes of id_payload, required for AUTH payload
+ */
+static void get_reserved_id_bytes(private_ike_auth_t *this, id_payload_t *id)
+{
+ u_int8_t *byte;
+ int i;
+
+ for (i = 0; i < countof(this->reserved); i++)
+ {
+ byte = payload_get_field(&id->payload_interface, RESERVED_BYTE, i);
+ if (byte)
+ {
+ this->reserved[i] = *byte;
+ }
+ }
+}
+
+/**
* Get the next authentication configuration
*/
static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local)
@@ -329,10 +357,8 @@ static bool update_cfg_candidates(private_ike_auth_t *this, bool strict)
return this->peer_cfg != NULL;
}
-/**
- * Implementation of task_t.build for initiator
- */
-static status_t build_i(private_ike_auth_t *this, message_t *message)
+METHOD(task_t, build_i, status_t,
+ private_ike_auth_t *this, message_t *message)
{
auth_cfg_t *cfg;
@@ -367,7 +393,7 @@ static status_t build_i(private_ike_auth_t *this, message_t *message)
/* check if an authenticator is in progress */
if (this->my_auth == NULL)
{
- identification_t *id;
+ identification_t *idi, *idr = NULL;
id_payload_t *id_payload;
/* clean up authentication config from a previous round */
@@ -378,33 +404,48 @@ static status_t build_i(private_ike_auth_t *this, message_t *message)
cfg = get_auth_cfg(this, FALSE);
if (cfg)
{
- id = cfg->get(cfg, AUTH_RULE_IDENTITY);
- if (id && !id->contains_wildcards(id))
+ idr = cfg->get(cfg, AUTH_RULE_IDENTITY);
+ if (idr && !idr->contains_wildcards(idr))
{
- this->ike_sa->set_other_id(this->ike_sa, id->clone(id));
+ this->ike_sa->set_other_id(this->ike_sa, idr->clone(idr));
id_payload = id_payload_create_from_identification(
- ID_RESPONDER, id);
+ ID_RESPONDER, idr);
message->add_payload(message, (payload_t*)id_payload);
}
}
/* add IDi */
cfg = this->ike_sa->get_auth_cfg(this->ike_sa, TRUE);
cfg->merge(cfg, get_auth_cfg(this, TRUE), TRUE);
- id = cfg->get(cfg, AUTH_RULE_IDENTITY);
- if (!id)
+ idi = cfg->get(cfg, AUTH_RULE_IDENTITY);
+ if (!idi)
{
DBG1(DBG_CFG, "configuration misses IDi");
return FAILED;
}
- this->ike_sa->set_my_id(this->ike_sa, id->clone(id));
- id_payload = id_payload_create_from_identification(ID_INITIATOR, id);
+ this->ike_sa->set_my_id(this->ike_sa, idi->clone(idi));
+ id_payload = id_payload_create_from_identification(ID_INITIATOR, idi);
+ get_reserved_id_bytes(this, id_payload);
message->add_payload(message, (payload_t*)id_payload);
+ if (idr && message->get_message_id(message) == 1 &&
+ this->peer_cfg->get_unique_policy(this->peer_cfg) != UNIQUE_NO)
+ {
+ host_t *host;
+
+ host = this->ike_sa->get_other_host(this->ike_sa);
+ if (!charon->ike_sa_manager->has_contact(charon->ike_sa_manager,
+ idi, idr, host->get_family(host)))
+ {
+ message->add_notify(message, FALSE, INITIAL_CONTACT, chunk_empty);
+ }
+ }
+
/* build authentication data */
this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
this->other_nonce, this->my_nonce,
this->other_packet->get_data(this->other_packet),
- this->my_packet->get_data(this->my_packet));
+ this->my_packet->get_data(this->my_packet),
+ this->reserved);
if (!this->my_auth)
{
return FAILED;
@@ -441,10 +482,8 @@ static status_t build_i(private_ike_auth_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for responder
- */
-static status_t process_r(private_ike_auth_t *this, message_t *message)
+METHOD(task_t, process_r, status_t,
+ private_ike_auth_t *this, message_t *message)
{
auth_cfg_t *cfg, *cand;
id_payload_t *id_payload;
@@ -498,6 +537,7 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
return FAILED;
}
id = id_payload->get_identification(id_payload);
+ get_reserved_id_bytes(this, id_payload);
this->ike_sa->set_other_id(this->ike_sa, id);
cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
@@ -548,7 +588,8 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
this->other_auth = authenticator_create_verifier(this->ike_sa,
message, this->other_nonce, this->my_nonce,
this->other_packet->get_data(this->other_packet),
- this->my_packet->get_data(this->my_packet));
+ this->my_packet->get_data(this->my_packet),
+ this->reserved);
if (!this->other_auth)
{
this->authentication_failed = TRUE;
@@ -572,10 +613,13 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
return NEED_MORE;
}
- /* store authentication information */
- cfg = auth_cfg_create();
- cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
- this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg);
+ /* If authenticated (with non-EAP) and received INITIAL_CONTACT,
+ * delete any existing IKE_SAs with that peer. */
+ if (message->get_message_id(message) == 1 &&
+ message->get_notify(message, INITIAL_CONTACT))
+ {
+ this->initial_contact = TRUE;
+ }
/* another auth round done, invoke authorize hook */
if (!charon->bus->authorize(charon->bus, FALSE))
@@ -585,6 +629,11 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
return NEED_MORE;
}
+ /* store authentication information */
+ cfg = auth_cfg_create();
+ cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
+ this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg);
+
if (!update_cfg_candidates(this, FALSE))
{
this->authentication_failed = TRUE;
@@ -603,10 +652,8 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.build for responder
- */
-static status_t build_r(private_ike_auth_t *this, message_t *message)
+METHOD(task_t, build_r, status_t,
+ private_ike_auth_t *this, message_t *message)
{
auth_cfg_t *cfg;
@@ -662,8 +709,16 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
}
id_payload = id_payload_create_from_identification(ID_RESPONDER, id);
+ get_reserved_id_bytes(this, id_payload);
message->add_payload(message, (payload_t*)id_payload);
+ if (this->initial_contact)
+ {
+ charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
+ this->ike_sa, TRUE);
+ this->initial_contact = FALSE;
+ }
+
if ((uintptr_t)cfg->get(cfg, AUTH_RULE_AUTH_CLASS) == AUTH_CLASS_EAP)
{ /* EAP-only authentication */
if (!this->ike_sa->supports_extension(this->ike_sa,
@@ -682,7 +737,8 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
this->my_auth = authenticator_create_builder(this->ike_sa, cfg,
this->other_nonce, this->my_nonce,
this->other_packet->get_data(this->other_packet),
- this->my_packet->get_data(this->my_packet));
+ this->my_packet->get_data(this->my_packet),
+ this->reserved);
if (!this->my_auth)
{
message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
@@ -744,7 +800,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
if (!this->do_another_auth && !this->expect_another_auth)
{
if (charon->ike_sa_manager->check_uniqueness(charon->ike_sa_manager,
- this->ike_sa))
+ this->ike_sa, FALSE))
{
DBG1(DBG_IKE, "cancelling IKE_SA setup due uniqueness policy");
message->add_notify(message, TRUE, AUTHENTICATION_FAILED,
@@ -772,10 +828,8 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.process for initiator
- */
-static status_t process_i(private_ike_auth_t *this, message_t *message)
+METHOD(task_t, process_i, status_t,
+ private_ike_auth_t *this, message_t *message)
{
enumerator_t *enumerator;
payload_t *payload;
@@ -857,6 +911,7 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
return FAILED;
}
id = id_payload->get_identification(id_payload);
+ get_reserved_id_bytes(this, id_payload);
this->ike_sa->set_other_id(this->ike_sa, id);
cfg = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
cfg->add(cfg, AUTH_RULE_IDENTITY, id->clone(id));
@@ -867,7 +922,8 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
this->other_auth = authenticator_create_verifier(this->ike_sa,
message, this->other_nonce, this->my_nonce,
this->other_packet->get_data(this->other_packet),
- this->my_packet->get_data(this->my_packet));
+ this->my_packet->get_data(this->my_packet),
+ this->reserved);
if (!this->other_auth)
{
return FAILED;
@@ -893,17 +949,17 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
this->other_auth->destroy(this->other_auth);
this->other_auth = NULL;
}
- /* store authentication information, reset authenticator */
- cfg = auth_cfg_create();
- cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
- this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg);
-
/* another auth round done, invoke authorize hook */
if (!charon->bus->authorize(charon->bus, FALSE))
{
DBG1(DBG_IKE, "authorization forbids IKE_SA, cancelling");
return FAILED;
}
+
+ /* store authentication information, reset authenticator */
+ cfg = auth_cfg_create();
+ cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE);
+ this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg);
}
if (this->my_auth)
@@ -964,18 +1020,14 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
return NEED_MORE;
}
-/**
- * Implementation of task_t.get_type
- */
-static task_type_t get_type(private_ike_auth_t *this)
+METHOD(task_t, get_type, task_type_t,
+ private_ike_auth_t *this)
{
return IKE_AUTHENTICATE;
}
-/**
- * Implementation of task_t.migrate
- */
-static void migrate(private_ike_auth_t *this, ike_sa_t *ike_sa)
+METHOD(task_t, migrate, void,
+ private_ike_auth_t *this, ike_sa_t *ike_sa)
{
chunk_free(&this->my_nonce);
chunk_free(&this->other_nonce);
@@ -998,10 +1050,8 @@ static void migrate(private_ike_auth_t *this, ike_sa_t *ike_sa)
this->candidates = linked_list_create();
}
-/**
- * Implementation of task_t.destroy
- */
-static void destroy(private_ike_auth_t *this)
+METHOD(task_t, destroy, void,
+ private_ike_auth_t *this)
{
chunk_free(&this->my_nonce);
chunk_free(&this->other_nonce);
@@ -1019,37 +1069,29 @@ static void destroy(private_ike_auth_t *this)
*/
ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator)
{
- private_ike_auth_t *this = malloc_thing(private_ike_auth_t);
-
- 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_auth_t *this;
+
+ INIT(this,
+ .public = {
+ .task = {
+ .get_type = _get_type,
+ .migrate = _migrate,
+ .build = _build_r,
+ .process = _process_r,
+ .destroy = _destroy,
+ },
+ },
+ .ike_sa = ike_sa,
+ .initiator = initiator,
+ .candidates = linked_list_create(),
+ .do_another_auth = TRUE,
+ .expect_another_auth = TRUE,
+ );
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;
- }
- 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_i;
+ this->public.task.process = _process_i;
}
-
- this->ike_sa = ike_sa;
- this->initiator = initiator;
- this->my_nonce = chunk_empty;
- this->other_nonce = chunk_empty;
- this->my_packet = NULL;
- this->other_packet = NULL;
- this->peer_cfg = NULL;
- this->candidates = linked_list_create();
- this->my_auth = NULL;
- this->other_auth = NULL;
- this->do_another_auth = TRUE;
- this->expect_another_auth = TRUE;
- this->authentication_failed = FALSE;
-
return &this->public;
}
diff --git a/src/libcharon/sa/tasks/ike_cert_pre.c b/src/libcharon/sa/tasks/ike_cert_pre.c
index 1c0c54727..a59b8dcce 100644
--- a/src/libcharon/sa/tasks/ike_cert_pre.c
+++ b/src/libcharon/sa/tasks/ike_cert_pre.c
@@ -76,6 +76,7 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
{
certreq_payload_t *certreq = (certreq_payload_t*)payload;
enumerator_t *enumerator;
+ u_int unknown = 0;
chunk_t keyid;
this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
@@ -103,12 +104,18 @@ static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
}
else
{
- DBG1(DBG_IKE, "received cert request for unknown ca "
+ DBG2(DBG_IKE, "received cert request for unknown ca "
"with keyid %Y", id);
+ unknown++;
}
id->destroy(id);
}
enumerator->destroy(enumerator);
+ if (unknown)
+ {
+ DBG1(DBG_IKE, "received %u cert requests for an unknown ca",
+ unknown);
+ }
break;
}
case NOTIFY:
@@ -253,11 +260,19 @@ static void process_certs(private_ike_cert_pre_t *this, message_t *message)
}
break;
}
+ case ENC_CRL:
+ cert = cert_payload->get_cert(cert_payload);
+ if (cert)
+ {
+ DBG1(DBG_IKE, "received CRL \"%Y\"",
+ cert->get_subject(cert));
+ auth->add(auth, AUTH_HELPER_REVOCATION_CERT, cert);
+ }
+ break;
case ENC_PKCS7_WRAPPED_X509:
case ENC_PGP:
case ENC_DNS_SIGNED_KEY:
case ENC_KERBEROS_TOKEN:
- case ENC_CRL:
case ENC_ARL:
case ENC_SPKI:
case ENC_X509_ATTRIBUTE:
diff --git a/src/libcharon/sa/tasks/ike_rekey.c b/src/libcharon/sa/tasks/ike_rekey.c
index 1a6c140c4..44c55036e 100644
--- a/src/libcharon/sa/tasks/ike_rekey.c
+++ b/src/libcharon/sa/tasks/ike_rekey.c
@@ -255,19 +255,20 @@ static status_t process_i(private_ike_rekey_t *this, message_t *message)
/* 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)
+ 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);
lib->scheduler->schedule_job(lib->scheduler, job, 10);
- DBG1(DBG_IKE, "IKE_SA rekey collision won, deleting rekeyed IKE_SA");
+ DBG1(DBG_IKE, "IKE_SA rekey collision won, waiting for delete");
charon->ike_sa_manager->checkin(charon->ike_sa_manager, other->new_sa);
other->new_sa = NULL;
}
else
{
- DBG1(DBG_IKE, "IKE_SA rekey collision lost, deleting redundant IKE_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));