Merge branch 'multi-eap'

Fixes the use of EAP methods in the non-first authentication round if the
initiator demands mutual EAP. Also mutual EAP can now be enforced when the
initiator sets rightauth=eap, not only with rightauth=any.
This commit is contained in:
Martin Willi
2013-03-01 11:36:41 +01:00
2 changed files with 50 additions and 28 deletions
@@ -667,6 +667,16 @@ METHOD(authenticator_t, build_client, status_t,
METHOD(authenticator_t, is_mutual, bool, METHOD(authenticator_t, is_mutual, bool,
private_eap_authenticator_t *this) private_eap_authenticator_t *this)
{ {
if (this->method)
{
u_int32_t vendor;
if (this->method->get_type(this->method, &vendor) != EAP_IDENTITY ||
vendor != 0)
{
return this->method->is_mutual(this->method);
}
}
/* we don't know yet, but insist on it after EAP is complete */ /* we don't know yet, but insist on it after EAP is complete */
this->require_mutual = TRUE; this->require_mutual = TRUE;
return TRUE; return TRUE;
+40 -28
View File
@@ -222,6 +222,18 @@ static auth_cfg_t *get_auth_cfg(private_ike_auth_t *this, bool local)
return next; return next;
} }
/**
* Move the currently active auth config to the auth configs completed
*/
static void apply_auth_cfg(private_ike_auth_t *this, bool local)
{
auth_cfg_t *cfg;
cfg = auth_cfg_create();
cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, local), local);
this->ike_sa->add_auth_cfg(this->ike_sa, local, cfg);
}
/** /**
* Check if we have should initiate another authentication round * Check if we have should initiate another authentication round
*/ */
@@ -307,7 +319,7 @@ static bool update_cfg_candidates(private_ike_auth_t *this, bool strict)
{ {
if (this->peer_cfg) if (this->peer_cfg)
{ {
bool complies = TRUE; char *comply_error = NULL;
enumerator_t *e1, *e2, *tmp; enumerator_t *e1, *e2, *tmp;
auth_cfg_t *c1, *c2; auth_cfg_t *c1, *c2;
@@ -324,22 +336,30 @@ static bool update_cfg_candidates(private_ike_auth_t *this, bool strict)
while (e1->enumerate(e1, &c1)) while (e1->enumerate(e1, &c1))
{ {
/* check if done authentications comply to configured ones */ /* check if done authentications comply to configured ones */
if ((!e2->enumerate(e2, &c2)) || if (!e2->enumerate(e2, &c2))
(!strict && !c1->complies(c1, c2, TRUE)) ||
(strict && !c2->complies(c2, c1, TRUE)))
{ {
complies = FALSE; comply_error = "insufficient authentication rounds";
break;
}
if (!strict && !c1->complies(c1, c2, TRUE))
{
comply_error = "non-matching authentication done";
break;
}
if (strict && !c2->complies(c2, c1, TRUE))
{
comply_error = "constraint checking failed";
break; break;
} }
} }
e1->destroy(e1); e1->destroy(e1);
e2->destroy(e2); e2->destroy(e2);
if (complies) if (!comply_error)
{ {
break; break;
} }
DBG1(DBG_CFG, "selected peer config '%s' inacceptable", DBG1(DBG_CFG, "selected peer config '%s' inacceptable: %s",
this->peer_cfg->get_name(this->peer_cfg)); this->peer_cfg->get_name(this->peer_cfg), comply_error);
this->peer_cfg->destroy(this->peer_cfg); this->peer_cfg->destroy(this->peer_cfg);
} }
if (this->candidates->remove_first(this->candidates, if (this->candidates->remove_first(this->candidates,
@@ -464,10 +484,7 @@ METHOD(task_t, build_i, status_t,
switch (this->my_auth->build(this->my_auth, message)) switch (this->my_auth->build(this->my_auth, message))
{ {
case SUCCESS: case SUCCESS:
/* authentication step complete, reset authenticator */ apply_auth_cfg(this, TRUE);
cfg = auth_cfg_create();
cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE), TRUE);
this->ike_sa->add_auth_cfg(this->ike_sa, TRUE, cfg);
this->my_auth->destroy(this->my_auth); this->my_auth->destroy(this->my_auth);
this->my_auth = NULL; this->my_auth = NULL;
break; break;
@@ -640,10 +657,7 @@ METHOD(task_t, process_r, status_t,
return NEED_MORE; return NEED_MORE;
} }
/* store authentication information */ apply_auth_cfg(this, FALSE);
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)) if (!update_cfg_candidates(this, FALSE))
{ {
@@ -778,10 +792,7 @@ METHOD(task_t, build_r, status_t,
switch (this->my_auth->build(this->my_auth, message)) switch (this->my_auth->build(this->my_auth, message))
{ {
case SUCCESS: case SUCCESS:
cfg = auth_cfg_create(); apply_auth_cfg(this, TRUE);
cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE),
TRUE);
this->ike_sa->add_auth_cfg(this->ike_sa, TRUE, cfg);
this->my_auth->destroy(this->my_auth); this->my_auth->destroy(this->my_auth);
this->my_auth = NULL; this->my_auth = NULL;
break; break;
@@ -969,10 +980,10 @@ METHOD(task_t, process_i, status_t,
goto peer_auth_failed; goto peer_auth_failed;
} }
/* store authentication information, reset authenticator */ if (!mutual_eap)
cfg = auth_cfg_create(); {
cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, FALSE), FALSE); apply_auth_cfg(this, FALSE);
this->ike_sa->add_auth_cfg(this->ike_sa, FALSE, cfg); }
} }
if (this->my_auth) if (this->my_auth)
@@ -980,10 +991,11 @@ METHOD(task_t, process_i, status_t,
switch (this->my_auth->process(this->my_auth, message)) switch (this->my_auth->process(this->my_auth, message))
{ {
case SUCCESS: case SUCCESS:
cfg = auth_cfg_create(); apply_auth_cfg(this, TRUE);
cfg->merge(cfg, this->ike_sa->get_auth_cfg(this->ike_sa, TRUE), if (this->my_auth->is_mutual(this->my_auth))
TRUE); {
this->ike_sa->add_auth_cfg(this->ike_sa, TRUE, cfg); apply_auth_cfg(this, FALSE);
}
this->my_auth->destroy(this->my_auth); this->my_auth->destroy(this->my_auth);
this->my_auth = NULL; this->my_auth = NULL;
this->do_another_auth = do_another_auth(this); this->do_another_auth = do_another_auth(this);