Use a second authentication config to configure XAUTH authentication
This commit is contained in:
@@ -469,13 +469,9 @@ static auth_cfg_t *build_auth_cfg(private_stroke_config_t *this,
|
|||||||
{
|
{
|
||||||
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
|
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
|
||||||
}
|
}
|
||||||
else if (streq(auth, "xauthpsk"))
|
else if (streq(auth, "xauth"))
|
||||||
{
|
{
|
||||||
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_XAUTH_PSK);
|
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_XAUTH);
|
||||||
}
|
|
||||||
else if (streq(auth, "xauthrsasig"))
|
|
||||||
{
|
|
||||||
cfg->add(cfg, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_XAUTH_PUBKEY);
|
|
||||||
}
|
}
|
||||||
else if (strneq(auth, "eap", 3))
|
else if (strneq(auth, "eap", 3))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -254,24 +254,103 @@ static bool get_nonce_ke(private_main_mode_t *this, chunk_t *nonce,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get auth method to use
|
* Get the two auth classes from local or remote config
|
||||||
*/
|
*/
|
||||||
static auth_method_t get_auth_method(private_main_mode_t *this)
|
static void get_auth_class(peer_cfg_t *peer_cfg, bool local,
|
||||||
|
auth_class_t *c1, auth_class_t *c2)
|
||||||
{
|
{
|
||||||
switch ((uintptr_t)this->my_auth->get(this->my_auth, AUTH_RULE_AUTH_CLASS))
|
enumerator_t *enumerator;
|
||||||
|
auth_cfg_t *auth;
|
||||||
|
|
||||||
|
*c1 = *c2 = AUTH_CLASS_ANY;
|
||||||
|
|
||||||
|
enumerator = peer_cfg->create_auth_cfg_enumerator(peer_cfg, local);
|
||||||
|
while (enumerator->enumerate(enumerator, &auth))
|
||||||
{
|
{
|
||||||
case AUTH_CLASS_PSK:
|
if (*c1 == AUTH_CLASS_ANY)
|
||||||
return AUTH_PSK;
|
{
|
||||||
case AUTH_CLASS_XAUTH_PSK:
|
*c1 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
|
||||||
return AUTH_XAUTH_INIT_PSK;
|
}
|
||||||
case AUTH_CLASS_XAUTH_PUBKEY:
|
else
|
||||||
return AUTH_XAUTH_INIT_RSA;
|
{
|
||||||
case AUTH_CLASS_PUBKEY:
|
*c2 = (uintptr_t)auth->get(auth, AUTH_RULE_AUTH_CLASS);
|
||||||
/* TODO-IKEv1: look for a key, return RSA or ECDSA */
|
break;
|
||||||
default:
|
}
|
||||||
/* TODO-IKEv1: XAUTH methods */
|
|
||||||
return AUTH_RSA;
|
|
||||||
}
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get auth method to use from a peer config
|
||||||
|
*/
|
||||||
|
static auth_method_t get_auth_method(private_main_mode_t *this,
|
||||||
|
peer_cfg_t *peer_cfg)
|
||||||
|
{
|
||||||
|
auth_class_t i1, i2, r1, r2;
|
||||||
|
|
||||||
|
get_auth_class(peer_cfg, this->initiator, &i1, &i2);
|
||||||
|
get_auth_class(peer_cfg, !this->initiator, &r1, &r2);
|
||||||
|
|
||||||
|
if (i1 == AUTH_CLASS_PUBKEY && r1 == AUTH_CLASS_PUBKEY)
|
||||||
|
{
|
||||||
|
if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
|
||||||
|
{
|
||||||
|
/* TODO-IKEv1: ECDSA? */
|
||||||
|
return AUTH_RSA;
|
||||||
|
}
|
||||||
|
if (i2 == AUTH_CLASS_XAUTH)
|
||||||
|
{
|
||||||
|
return AUTH_XAUTH_INIT_RSA;
|
||||||
|
}
|
||||||
|
if (r2 == AUTH_CLASS_XAUTH)
|
||||||
|
{
|
||||||
|
return AUTH_XAUTH_RESP_RSA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i1 == AUTH_CLASS_PSK && r2 == AUTH_CLASS_PSK)
|
||||||
|
{
|
||||||
|
if (i2 == AUTH_CLASS_ANY && r2 == AUTH_CLASS_ANY)
|
||||||
|
{
|
||||||
|
return AUTH_PSK;
|
||||||
|
}
|
||||||
|
if (i2 == AUTH_CLASS_XAUTH)
|
||||||
|
{
|
||||||
|
return AUTH_XAUTH_INIT_PSK;
|
||||||
|
}
|
||||||
|
if (r2 == AUTH_CLASS_XAUTH)
|
||||||
|
{
|
||||||
|
return AUTH_XAUTH_RESP_PSK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* TODO-IKEv1: Hybrid methods? */
|
||||||
|
return AUTH_NONE;;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select the best configuration as responder
|
||||||
|
*/
|
||||||
|
static peer_cfg_t *select_config(private_main_mode_t *this, identification_t *id)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
identification_t *any;
|
||||||
|
peer_cfg_t *current, *found = NULL;
|
||||||
|
|
||||||
|
any = identification_create_from_encoding(ID_ANY, chunk_empty);
|
||||||
|
enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
|
||||||
|
this->ike_sa->get_my_host(this->ike_sa),
|
||||||
|
this->ike_sa->get_other_host(this->ike_sa), any, id);
|
||||||
|
while (enumerator->enumerate(enumerator, ¤t))
|
||||||
|
{
|
||||||
|
if (get_auth_method(this, current) == this->auth_method)
|
||||||
|
{
|
||||||
|
found = current->get_ref(current);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
any->destroy(any);
|
||||||
|
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -392,9 +471,12 @@ METHOD(task_t, build_i, status_t,
|
|||||||
DBG1(DBG_CFG, "no auth config found");
|
DBG1(DBG_CFG, "no auth config found");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
this->auth_method = get_auth_method(this, this->peer_cfg);
|
||||||
proposals = this->ike_cfg->get_proposals(this->ike_cfg);
|
if (this->auth_method == AUTH_NONE)
|
||||||
this->auth_method = get_auth_method(this);
|
{
|
||||||
|
DBG1(DBG_CFG, "configuration uses unsupported authentication");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
this->lifetime = this->peer_cfg->get_reauth_time(this->peer_cfg,
|
this->lifetime = this->peer_cfg->get_reauth_time(this->peer_cfg,
|
||||||
FALSE);
|
FALSE);
|
||||||
if (!this->lifetime)
|
if (!this->lifetime)
|
||||||
@@ -402,6 +484,7 @@ METHOD(task_t, build_i, status_t,
|
|||||||
this->lifetime = this->peer_cfg->get_rekey_time(this->peer_cfg,
|
this->lifetime = this->peer_cfg->get_rekey_time(this->peer_cfg,
|
||||||
FALSE);
|
FALSE);
|
||||||
}
|
}
|
||||||
|
proposals = this->ike_cfg->get_proposals(this->ike_cfg);
|
||||||
sa_payload = sa_payload_create_from_proposals_v1(proposals,
|
sa_payload = sa_payload_create_from_proposals_v1(proposals,
|
||||||
this->lifetime, 0, this->auth_method, MODE_NONE, FALSE);
|
this->lifetime, 0, this->auth_method, MODE_NONE, FALSE);
|
||||||
proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
|
proposals->destroy_offset(proposals, offsetof(proposal_t, destroy));
|
||||||
@@ -555,9 +638,8 @@ METHOD(task_t, process_r, status_t,
|
|||||||
}
|
}
|
||||||
case MM_KE:
|
case MM_KE:
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
|
||||||
id_payload_t *id_payload;
|
id_payload_t *id_payload;
|
||||||
identification_t *id, *any;
|
identification_t *id;
|
||||||
|
|
||||||
id_payload = (id_payload_t*)message->get_payload(message, ID_V1);
|
id_payload = (id_payload_t*)message->get_payload(message, ID_V1);
|
||||||
if (!id_payload)
|
if (!id_payload)
|
||||||
@@ -567,26 +649,13 @@ METHOD(task_t, process_r, status_t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
id = id_payload->get_identification(id_payload);
|
id = id_payload->get_identification(id_payload);
|
||||||
any = identification_create_from_encoding(ID_ANY, chunk_empty);
|
this->ike_sa->set_other_id(this->ike_sa, id);
|
||||||
enumerator = charon->backends->create_peer_cfg_enumerator(
|
this->peer_cfg = select_config(this, id);
|
||||||
charon->backends,
|
if (!this->peer_cfg)
|
||||||
this->ike_sa->get_my_host(this->ike_sa),
|
|
||||||
this->ike_sa->get_other_host(this->ike_sa),
|
|
||||||
any, id);
|
|
||||||
if (!enumerator->enumerate(enumerator, &this->peer_cfg))
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "no peer config found");
|
DBG1(DBG_IKE, "no peer config found");
|
||||||
id->destroy(id);
|
|
||||||
any->destroy(any);
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
return set_notify_error(this, AUTHENTICATION_FAILED, chunk_empty);
|
return set_notify_error(this, AUTHENTICATION_FAILED, chunk_empty);
|
||||||
}
|
}
|
||||||
this->peer_cfg->get_ref(this->peer_cfg);
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
any->destroy(any);
|
|
||||||
|
|
||||||
this->ike_sa->set_other_id(this->ike_sa, id);
|
|
||||||
|
|
||||||
this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
|
this->ike_sa->set_peer_cfg(this->ike_sa, this->peer_cfg);
|
||||||
|
|
||||||
this->my_auth = get_auth_cfg(this, TRUE);
|
this->my_auth = get_auth_cfg(this, TRUE);
|
||||||
|
|||||||
@@ -42,10 +42,8 @@ enum auth_class_t {
|
|||||||
AUTH_CLASS_PSK = 2,
|
AUTH_CLASS_PSK = 2,
|
||||||
/** authentication using EAP */
|
/** authentication using EAP */
|
||||||
AUTH_CLASS_EAP = 3,
|
AUTH_CLASS_EAP = 3,
|
||||||
/** authentication using pre-shared secrets in combination with XAuth */
|
/** authentication using IKEv1 XAUTH */
|
||||||
AUTH_CLASS_XAUTH_PSK = 4,
|
AUTH_CLASS_XAUTH = 4,
|
||||||
/** authentication using public keys in combination with XAuth */
|
|
||||||
AUTH_CLASS_XAUTH_PUBKEY = 5,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user