ported parts of two-sim branch
eap_identity parameter to exchange in eap_identity some auth_info/peer_cfg refactorings fixed some bugs, introduced new ones
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Tobias Brunner
|
||||
* Copyright (C) 2006 Martin Willi
|
||||
* Copyright (C) 2006-2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -33,22 +33,27 @@ ENUM_NEXT(auth_method_names, AUTH_ECDSA_256, AUTH_ECDSA_521, AUTH_DSS,
|
||||
"ECDSA-256 signature",
|
||||
"ECDSA-384 signature",
|
||||
"ECDSA-521 signature");
|
||||
ENUM_NEXT(auth_method_names, AUTH_EAP, AUTH_EAP, AUTH_ECDSA_521,
|
||||
"EAP");
|
||||
ENUM_END(auth_method_names, AUTH_EAP);
|
||||
ENUM_END(auth_method_names, AUTH_ECDSA_521);
|
||||
|
||||
ENUM(auth_class_names, AUTH_CLASS_PUBKEY, AUTH_CLASS_EAP,
|
||||
"public key",
|
||||
"pre-shared key",
|
||||
"EAP",
|
||||
);
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
authenticator_t *authenticator_create(ike_sa_t *ike_sa, config_auth_method_t auth_method)
|
||||
authenticator_t *authenticator_create_from_class(ike_sa_t *ike_sa,
|
||||
auth_class_t class)
|
||||
{
|
||||
switch (auth_method)
|
||||
switch (class)
|
||||
{
|
||||
case CONF_AUTH_PUBKEY:
|
||||
case AUTH_CLASS_PUBKEY:
|
||||
return (authenticator_t*)pubkey_authenticator_create(ike_sa);
|
||||
case CONF_AUTH_PSK:
|
||||
case AUTH_CLASS_PSK:
|
||||
return (authenticator_t*)psk_authenticator_create(ike_sa);
|
||||
case CONF_AUTH_EAP:
|
||||
case AUTH_CLASS_EAP:
|
||||
return (authenticator_t*)eap_authenticator_create(ike_sa);
|
||||
default:
|
||||
return NULL;
|
||||
@@ -58,9 +63,10 @@ authenticator_t *authenticator_create(ike_sa_t *ike_sa, config_auth_method_t aut
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
authenticator_t *authenticator_create_from_auth_payload(ike_sa_t *ike_sa, auth_payload_t *auth_payload)
|
||||
authenticator_t *authenticator_create_from_method(ike_sa_t *ike_sa,
|
||||
auth_method_t method)
|
||||
{
|
||||
switch (auth_payload->get_auth_method(auth_payload))
|
||||
switch (method)
|
||||
{
|
||||
case AUTH_RSA:
|
||||
case AUTH_ECDSA_256:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Tobias Brunner
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005-2008 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -26,6 +26,7 @@
|
||||
#define AUTHENTICATOR_H_
|
||||
|
||||
typedef enum auth_method_t auth_method_t;
|
||||
typedef enum auth_class_t auth_class_t;
|
||||
typedef struct authenticator_t authenticator_t;
|
||||
|
||||
#include <library.h>
|
||||
@@ -34,7 +35,7 @@ typedef struct authenticator_t authenticator_t;
|
||||
#include <encoding/payloads/auth_payload.h>
|
||||
|
||||
/**
|
||||
* Method to use for authentication.
|
||||
* Method to use for authentication, as defined in IKEv2.
|
||||
*/
|
||||
enum auth_method_t {
|
||||
/**
|
||||
@@ -70,12 +71,6 @@ enum auth_method_t {
|
||||
* ECDSA with SHA-512 on the P-521 curve as specified in RFC 4754
|
||||
*/
|
||||
AUTH_ECDSA_521 = 11,
|
||||
|
||||
/**
|
||||
* EAP authentication. This value is never negotiated and therefore
|
||||
* a value from private use.
|
||||
*/
|
||||
AUTH_EAP = 201,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -83,12 +78,32 @@ enum auth_method_t {
|
||||
*/
|
||||
extern enum_name_t *auth_method_names;
|
||||
|
||||
/**
|
||||
* Class of authentication to use. This is different to auth_method_t in that
|
||||
* it does not specify a method, but a class of acceptable methods. The found
|
||||
* certificate finally dictates wich method is used.
|
||||
*/
|
||||
enum auth_class_t {
|
||||
/** authentication using public keys (RSA, ECDSA) */
|
||||
AUTH_CLASS_PUBKEY = 1,
|
||||
/** authentication using a pre-shared secrets */
|
||||
AUTH_CLASS_PSK = 2,
|
||||
/** authentication using EAP */
|
||||
AUTH_CLASS_EAP = 3,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum strings for auth_class_t
|
||||
*/
|
||||
extern enum_name_t *auth_class_names;
|
||||
|
||||
/**
|
||||
* Authenticator interface implemented by the various authenticators.
|
||||
*
|
||||
* Currently the following two AUTH methods are supported:
|
||||
* - shared key message integrity code
|
||||
* - RSA digital signature
|
||||
* - EAP using the EAP framework and one of the EAP plugins
|
||||
* - ECDSA is supported using OpenSSL
|
||||
*/
|
||||
struct authenticator_t {
|
||||
@@ -96,15 +111,14 @@ struct authenticator_t {
|
||||
/**
|
||||
* Verify a received authentication payload.
|
||||
*
|
||||
* @param ike_sa_init binary representation of received ike_sa_init
|
||||
* @param my_nonce the sent nonce
|
||||
* @param auth_payload authentication payload to verify
|
||||
*
|
||||
* @param ike_sa_init binary representation of received ike_sa_init
|
||||
* @param my_nonce the sent nonce
|
||||
* @param auth_payload authentication payload to verify
|
||||
* @return
|
||||
* - SUCCESS,
|
||||
* - FAILED if verification failed
|
||||
* - INVALID_ARG if auth_method does not match
|
||||
* - NOT_FOUND if credentials not found
|
||||
* - SUCCESS,
|
||||
* - FAILED if verification failed
|
||||
* - INVALID_ARG if auth_method does not match
|
||||
* - NOT_FOUND if credentials not found
|
||||
*/
|
||||
status_t (*verify) (authenticator_t *this, chunk_t ike_sa_init,
|
||||
chunk_t my_nonce, auth_payload_t *auth_payload);
|
||||
@@ -112,13 +126,12 @@ struct authenticator_t {
|
||||
/**
|
||||
* Build an authentication payload to send to the other peer.
|
||||
*
|
||||
* @param ike_sa_init binary representation of sent ike_sa_init
|
||||
* @param other_nonce the received nonce
|
||||
* @param[out] auth_payload the resulting authentication payload
|
||||
*
|
||||
* @param ike_sa_init binary representation of sent ike_sa_init
|
||||
* @param other_nonce the received nonce
|
||||
* @param auth_payload the resulting authentication payload
|
||||
* @return
|
||||
* - SUCCESS,
|
||||
* - NOT_FOUND if the data for AUTH method could not be found
|
||||
* - SUCCESS,
|
||||
* - NOT_FOUND if credentials not found
|
||||
*/
|
||||
status_t (*build) (authenticator_t *this, chunk_t ike_sa_init,
|
||||
chunk_t other_nonce, auth_payload_t **auth_payload);
|
||||
@@ -130,23 +143,23 @@ struct authenticator_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an authenticator for the specified auth method (as configured).
|
||||
* Creates an authenticator for the specified auth class (as configured).
|
||||
*
|
||||
* @param ike_sa associated ike_sa
|
||||
* @param auth_method authentication method to use for build()/verify()
|
||||
*
|
||||
* @param class class of authentication to use
|
||||
* @return authenticator_t object
|
||||
*/
|
||||
authenticator_t *authenticator_create(ike_sa_t *ike_sa, config_auth_method_t auth_method);
|
||||
authenticator_t *authenticator_create_from_class(ike_sa_t *ike_sa,
|
||||
auth_class_t class);
|
||||
|
||||
/**
|
||||
* Creates an authenticator from the given auth payload.
|
||||
* Creates an authenticator for method (as received in payload).
|
||||
*
|
||||
* @param ike_sa associated ike_sa
|
||||
* @param auth_payload auth payload
|
||||
*
|
||||
* @param method method as found in payload
|
||||
* @return authenticator_t object
|
||||
*/
|
||||
authenticator_t *authenticator_create_from_auth_payload(ike_sa_t *ike_sa, auth_payload_t *auth_payload);
|
||||
authenticator_t *authenticator_create_from_method(ike_sa_t *ike_sa,
|
||||
auth_method_t method);
|
||||
|
||||
#endif /* AUTHENTICATOR_H_ @} */
|
||||
|
||||
@@ -95,6 +95,8 @@ extern enum_name_t *eap_code_names;
|
||||
* authentication. Even if a mutual EAP method is used, the traditional
|
||||
* AUTH payloads are required. Only these include the nonces and messages from
|
||||
* ike_sa_init and therefore prevent man in the middle attacks.
|
||||
* The EAP method must use an initial EAP identifier value != 0, as a preceding
|
||||
* EAP-Identity exchange always uses identifier 0.
|
||||
*/
|
||||
struct eap_method_t {
|
||||
|
||||
@@ -148,7 +150,8 @@ struct eap_method_t {
|
||||
/**
|
||||
* Get the MSK established by this EAP method.
|
||||
*
|
||||
* Not all EAP methods establish a shared secret.
|
||||
* Not all EAP methods establish a shared secret. For implementations of
|
||||
* the EAP-Identity method, get_msk() returns the received identity.
|
||||
*
|
||||
* @param msk chunk receiving internal stored MSK
|
||||
* @return
|
||||
@@ -171,6 +174,8 @@ struct eap_method_t {
|
||||
* Constructors for server and peers are identical, to support both roles
|
||||
* of a EAP method, a plugin needs register two constructors in the
|
||||
* eap_manager_t.
|
||||
* The passed identites are of type ID_EAP and valid only during the
|
||||
* constructor invocation.
|
||||
*
|
||||
* @param server ID of the server to use for credential lookup
|
||||
* @param peer ID of the peer to use for credential lookup
|
||||
|
||||
@@ -54,6 +54,21 @@ struct private_eap_authenticator_t {
|
||||
* MSK used to build and verify auth payload
|
||||
*/
|
||||
chunk_t msk;
|
||||
|
||||
/**
|
||||
* should we do a EAP-Identity exchange as server?
|
||||
*/
|
||||
bool do_eap_identity;
|
||||
|
||||
/**
|
||||
* saved EAP type if we do eap_identity
|
||||
*/
|
||||
eap_type_t type;
|
||||
|
||||
/**
|
||||
* saved vendor id if we do eap_identity
|
||||
*/
|
||||
u_int32_t vendor;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -93,7 +108,7 @@ static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init,
|
||||
chunk_free(&auth_data);
|
||||
|
||||
DBG1(DBG_IKE, "authentication of '%D' with %N successful",
|
||||
other_id, auth_method_names, AUTH_EAP);
|
||||
other_id, auth_class_names, AUTH_CLASS_EAP);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -107,7 +122,7 @@ static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init,
|
||||
identification_t *my_id = this->ike_sa->get_my_id(this->ike_sa);
|
||||
|
||||
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
|
||||
my_id, auth_method_names, AUTH_EAP);
|
||||
my_id, auth_class_names, AUTH_CLASS_EAP);
|
||||
|
||||
if (this->msk.len)
|
||||
{ /* use MSK if EAP method established one... */
|
||||
@@ -129,6 +144,79 @@ static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init,
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the peers identity to use in the EAP method
|
||||
*/
|
||||
static identification_t *get_peer_id(private_eap_authenticator_t *this)
|
||||
{
|
||||
identification_t *id;
|
||||
peer_cfg_t *config;
|
||||
auth_info_t *auth;
|
||||
|
||||
id = this->ike_sa->get_eap_identity(this->ike_sa);
|
||||
if (!id)
|
||||
{
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
auth = config->get_auth(config);
|
||||
if (!auth->get_item(auth, AUTHN_EAP_IDENTITY, (void**)&id))
|
||||
{
|
||||
if (this->role == EAP_PEER)
|
||||
{
|
||||
id = this->ike_sa->get_my_id(this->ike_sa);
|
||||
}
|
||||
else
|
||||
{
|
||||
id = this->ike_sa->get_other_id(this->ike_sa);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (id->get_type(id) == ID_EAP)
|
||||
{
|
||||
return id->clone(id);
|
||||
}
|
||||
return identification_create_from_encoding(ID_EAP, id->get_encoding(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the servers identity to use in the EAP method
|
||||
*/
|
||||
static identification_t *get_server_id(private_eap_authenticator_t *this)
|
||||
{
|
||||
identification_t *id;
|
||||
|
||||
if (this->role == EAP_SERVER)
|
||||
{
|
||||
id = this->ike_sa->get_my_id(this->ike_sa);
|
||||
}
|
||||
else
|
||||
{
|
||||
id = this->ike_sa->get_other_id(this->ike_sa);
|
||||
}
|
||||
if (id->get_type(id) == ID_EAP)
|
||||
{
|
||||
return id->clone(id);
|
||||
}
|
||||
return identification_create_from_encoding(ID_EAP, id->get_encoding(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* load an EAP method using the correct identities
|
||||
*/
|
||||
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;
|
||||
eap_method_t *method;
|
||||
|
||||
server = get_server_id(this);
|
||||
peer = get_peer_id(this);
|
||||
method = charon->eap->create_instance(charon->eap, type, vendor, role,
|
||||
server, peer);
|
||||
server->destroy(server);
|
||||
peer->destroy(peer);
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of eap_authenticator_t.initiate
|
||||
*/
|
||||
@@ -138,6 +226,14 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
|
||||
/* if initiate() is called, role is always server */
|
||||
this->role = EAP_SERVER;
|
||||
|
||||
if (this->do_eap_identity)
|
||||
{ /* do an EAP-Identity request first */
|
||||
this->type = type;
|
||||
this->vendor = vendor;
|
||||
vendor = 0;
|
||||
type = EAP_IDENTITY;
|
||||
}
|
||||
|
||||
if (type == 0)
|
||||
{
|
||||
DBG1(DBG_IKE,
|
||||
@@ -148,20 +244,23 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
|
||||
|
||||
if (vendor)
|
||||
{
|
||||
DBG1(DBG_IKE, "requesting vendor specific EAP authentication %d-%d",
|
||||
DBG1(DBG_IKE, "requesting vendor specific EAP method %d-%d",
|
||||
type, vendor);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "requesting %N authentication", eap_type_names, type);
|
||||
DBG1(DBG_IKE, "requesting EAP method %N", eap_type_names, type);
|
||||
}
|
||||
this->method = charon->eap->create_instance(charon->eap, type, vendor,
|
||||
this->role, this->ike_sa->get_my_id(this->ike_sa),
|
||||
this->ike_sa->get_other_id(this->ike_sa));
|
||||
|
||||
this->method = load_method(this, type, vendor, this->role);
|
||||
if (this->method == NULL)
|
||||
{
|
||||
|
||||
if (vendor == 0 && type == EAP_IDENTITY)
|
||||
{
|
||||
DBG1(DBG_IKE, "skipping %N, no implementation found",
|
||||
eap_type_names, type);
|
||||
this->do_eap_identity = FALSE;
|
||||
return initiate(this, this->type, this->vendor, out);
|
||||
}
|
||||
DBG1(DBG_IKE, "configured EAP server method not supported, sending %N",
|
||||
eap_code_names, EAP_FAILURE);
|
||||
*out = eap_payload_create_code(EAP_FAILURE, 0);
|
||||
@@ -192,10 +291,7 @@ static status_t process_peer(private_eap_authenticator_t *this,
|
||||
{
|
||||
eap_method_t *method;
|
||||
|
||||
method = charon->eap->create_instance(charon->eap, type, 0, EAP_PEER,
|
||||
this->ike_sa->get_other_id(this->ike_sa),
|
||||
this->ike_sa->get_my_id(this->ike_sa));
|
||||
|
||||
method = load_method(this, type, 0, EAP_PEER);
|
||||
if (method == NULL || method->process(method, in, out) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_IKE, "EAP server requested %N, but unable to process",
|
||||
@@ -203,10 +299,7 @@ static status_t process_peer(private_eap_authenticator_t *this,
|
||||
DESTROY_IF(method);
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
DBG1(DBG_IKE, "EAP server requested %N, sending IKE identity",
|
||||
eap_type_names, type);
|
||||
|
||||
DBG1(DBG_IKE, "EAP server requested %N", eap_type_names, type);
|
||||
method->destroy(method);
|
||||
return NEED_MORE;
|
||||
}
|
||||
@@ -224,10 +317,7 @@ static status_t process_peer(private_eap_authenticator_t *this,
|
||||
DBG1(DBG_IKE, "EAP server requested %N authentication",
|
||||
eap_type_names, type);
|
||||
}
|
||||
this->method = charon->eap->create_instance(charon->eap,
|
||||
type, vendor, EAP_PEER,
|
||||
this->ike_sa->get_other_id(this->ike_sa),
|
||||
this->ike_sa->get_my_id(this->ike_sa));
|
||||
this->method = load_method(this, type, vendor, EAP_PEER);
|
||||
if (this->method == NULL)
|
||||
{
|
||||
DBG1(DBG_IKE, "EAP server requested unsupported "
|
||||
@@ -251,7 +341,7 @@ static status_t process_peer(private_eap_authenticator_t *this,
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IKE, "EAP method %N succeded", eap_type_names, type);
|
||||
DBG1(DBG_IKE, "EAP method %N succeeded", eap_type_names, type);
|
||||
}
|
||||
return SUCCESS;
|
||||
case FAILED:
|
||||
@@ -270,6 +360,27 @@ static status_t process_peer(private_eap_authenticator_t *this,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle an EAP-Identity response on the server
|
||||
*/
|
||||
static status_t process_eap_identity(private_eap_authenticator_t *this,
|
||||
eap_payload_t **out)
|
||||
{
|
||||
chunk_t data;
|
||||
identification_t *id;
|
||||
|
||||
if (this->method->get_msk(this->method, &data) == SUCCESS)
|
||||
{
|
||||
id = identification_create_from_encoding(ID_EAP, data);
|
||||
DBG1(DBG_IKE, "using EAP Identity '%D'", id);
|
||||
this->ike_sa->set_eap_identity(this->ike_sa, id);
|
||||
}
|
||||
/* restart EAP exchange, but with real method */
|
||||
this->method->destroy(this->method);
|
||||
this->do_eap_identity = FALSE;
|
||||
return initiate(this, this->type, this->vendor, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processing method for a server
|
||||
*/
|
||||
@@ -286,6 +397,10 @@ static status_t process_server(private_eap_authenticator_t *this,
|
||||
case NEED_MORE:
|
||||
return NEED_MORE;
|
||||
case SUCCESS:
|
||||
if (this->do_eap_identity)
|
||||
{
|
||||
return process_eap_identity(this, out);
|
||||
}
|
||||
if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
|
||||
{
|
||||
this->msk = chunk_clone(this->msk);
|
||||
@@ -409,6 +524,9 @@ static void destroy(private_eap_authenticator_t *this)
|
||||
*/
|
||||
eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa)
|
||||
{
|
||||
peer_cfg_t *config;
|
||||
auth_info_t *auth;
|
||||
identification_t *id;
|
||||
private_eap_authenticator_t *this = malloc_thing(private_eap_authenticator_t);
|
||||
|
||||
/* public functions */
|
||||
@@ -425,6 +543,25 @@ eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa)
|
||||
this->role = EAP_PEER;
|
||||
this->method = NULL;
|
||||
this->msk = chunk_empty;
|
||||
this->do_eap_identity = FALSE;
|
||||
this->type = 0;
|
||||
this->vendor = 0;
|
||||
|
||||
config = ike_sa->get_peer_cfg(ike_sa);
|
||||
if (config)
|
||||
{
|
||||
auth = config->get_auth(config);
|
||||
if (auth->get_item(auth, AUTHN_EAP_IDENTITY, (void**)&id))
|
||||
{
|
||||
if (id->get_type(id) == ID_ANY)
|
||||
{ /* %any as configured EAP identity runs EAP-Identity first */
|
||||
this->do_eap_identity = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
ike_sa->set_eap_identity(ike_sa, id->clone(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ typedef struct eap_authenticator_t eap_authenticator_t;
|
||||
#include <encoding/payloads/eap_payload.h>
|
||||
|
||||
/**
|
||||
* Implementation of the authenticator_t interface using AUTH_EAP.
|
||||
* Implementation of the authenticator_t interface using AUTH_CLASS_EAP.
|
||||
*
|
||||
* Authentication using EAP involves the most complex authenticator. It stays
|
||||
* alive over multiple ike_auth transactions and handles multiple EAP
|
||||
@@ -137,7 +137,7 @@ struct eap_authenticator_t {
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates an authenticator for AUTH_EAP.
|
||||
* Creates an authenticator for AUTH_CLASS_EAP.
|
||||
*
|
||||
* @param ike_sa associated ike_sa
|
||||
* @return eap_authenticator_t object
|
||||
|
||||
@@ -169,6 +169,11 @@ struct private_ike_sa_t {
|
||||
*/
|
||||
identification_t *other_id;
|
||||
|
||||
/**
|
||||
* EAP Identity exchange in EAP-Identity method
|
||||
*/
|
||||
identification_t *eap_identity;;
|
||||
|
||||
/**
|
||||
* set of extensions the peer supports
|
||||
*/
|
||||
@@ -1540,6 +1545,23 @@ static void set_other_id(private_ike_sa_t *this, identification_t *other)
|
||||
this->other_id = other;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.get_eap_identity.
|
||||
*/
|
||||
static identification_t* get_eap_identity(private_ike_sa_t *this)
|
||||
{
|
||||
return this->eap_identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.set_eap_identity.
|
||||
*/
|
||||
static void set_eap_identity(private_ike_sa_t *this, identification_t *id)
|
||||
{
|
||||
DESTROY_IF(this->eap_identity);
|
||||
this->eap_identity = id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of ike_sa_t.derive_keys.
|
||||
*/
|
||||
@@ -2476,6 +2498,7 @@ static void destroy(private_ike_sa_t *this)
|
||||
DESTROY_IF(this->other_host);
|
||||
DESTROY_IF(this->my_id);
|
||||
DESTROY_IF(this->other_id);
|
||||
DESTROY_IF(this->eap_identity);
|
||||
|
||||
DESTROY_IF(this->ike_cfg);
|
||||
DESTROY_IF(this->peer_cfg);
|
||||
@@ -2520,6 +2543,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
||||
this->public.set_my_id = (void (*)(ike_sa_t*,identification_t*)) set_my_id;
|
||||
this->public.get_other_id = (identification_t* (*)(ike_sa_t*)) get_other_id;
|
||||
this->public.set_other_id = (void (*)(ike_sa_t*,identification_t*)) set_other_id;
|
||||
this->public.get_eap_identity = (identification_t* (*)(ike_sa_t*)) get_eap_identity;
|
||||
this->public.set_eap_identity = (void (*)(ike_sa_t*,identification_t*)) set_eap_identity;
|
||||
this->public.enable_extension = (void(*)(ike_sa_t*, ike_extension_t extension))enable_extension;
|
||||
this->public.supports_extension = (bool(*)(ike_sa_t*, ike_extension_t extension))supports_extension;
|
||||
this->public.set_condition = (void (*)(ike_sa_t*, ike_condition_t,bool)) set_condition;
|
||||
@@ -2578,6 +2603,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
||||
this->other_host = host_create_from_string("0.0.0.0", IKEV2_UDP_PORT);
|
||||
this->my_id = identification_create_from_encoding(ID_ANY, chunk_empty);
|
||||
this->other_id = identification_create_from_encoding(ID_ANY, chunk_empty);
|
||||
this->eap_identity = NULL;
|
||||
this->extensions = 0;
|
||||
this->conditions = 0;
|
||||
this->selected_proposal = NULL;
|
||||
|
||||
@@ -329,6 +329,22 @@ struct ike_sa_t {
|
||||
*/
|
||||
void (*set_other_id) (ike_sa_t *this, identification_t *other);
|
||||
|
||||
/**
|
||||
* Get the peers EAP identity.
|
||||
*
|
||||
* The EAP identity is exchanged in a EAP-Identity exchange.
|
||||
*
|
||||
* @return identification, NULL if none set
|
||||
*/
|
||||
identification_t* (*get_eap_identity) (ike_sa_t *this);
|
||||
|
||||
/**
|
||||
* Set the peer's EAP identity.
|
||||
*
|
||||
* @param id identification
|
||||
*/
|
||||
void (*set_eap_identity) (ike_sa_t *this, identification_t *id);
|
||||
|
||||
/**
|
||||
* Get the config used to setup this IKE_SA.
|
||||
*
|
||||
|
||||
@@ -149,6 +149,44 @@ static bool check_uniqueness(private_ike_auth_t *this)
|
||||
return cancel;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the authentication class of a config
|
||||
*/
|
||||
auth_class_t get_auth_class(peer_cfg_t *config)
|
||||
{
|
||||
auth_class_t *class;
|
||||
auth_info_t *auth_info;
|
||||
|
||||
auth_info = config->get_auth(config);
|
||||
if (auth_info->get_item(auth_info, AUTHN_AUTH_CLASS, (void**)&class))
|
||||
{
|
||||
return *class;
|
||||
}
|
||||
/* fallback to pubkey authentication */
|
||||
return AUTH_CLASS_PUBKEY;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the eap type/vendor
|
||||
*/
|
||||
static eap_type_t get_eap_type(peer_cfg_t *config, u_int32_t *vendor)
|
||||
{
|
||||
auth_info_t *auth_info;
|
||||
u_int *ptr;
|
||||
|
||||
*vendor = 0;
|
||||
auth_info = config->get_auth(config);
|
||||
if (auth_info->get_item(auth_info, AUTHN_EAP_VENDOR, (void**)&ptr))
|
||||
{
|
||||
*vendor = *ptr;
|
||||
}
|
||||
if (auth_info->get_item(auth_info, AUTHN_EAP_TYPE, (void**)&ptr))
|
||||
{
|
||||
return *ptr;
|
||||
}
|
||||
return EAP_NAK;
|
||||
}
|
||||
|
||||
/**
|
||||
* build the AUTH payload
|
||||
*/
|
||||
@@ -157,7 +195,6 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message)
|
||||
authenticator_t *auth;
|
||||
auth_payload_t *auth_payload;
|
||||
peer_cfg_t *config;
|
||||
config_auth_method_t method;
|
||||
status_t status;
|
||||
|
||||
/* create own authenticator and add auth payload */
|
||||
@@ -167,13 +204,12 @@ static status_t build_auth(private_ike_auth_t *this, message_t *message)
|
||||
SIG_IKE(UP_FAILED, "unable to authenticate, no peer config found");
|
||||
return FAILED;
|
||||
}
|
||||
method = config->get_auth_method(config);
|
||||
|
||||
auth = authenticator_create(this->ike_sa, method);
|
||||
auth = authenticator_create_from_class(this->ike_sa, get_auth_class(config));
|
||||
if (auth == NULL)
|
||||
{
|
||||
SIG_IKE(UP_FAILED, "configured authentication method %N not supported",
|
||||
config_auth_method_names, method);
|
||||
SIG_IKE(UP_FAILED, "configured authentication class %N not supported",
|
||||
auth_class_names, get_auth_class(config));
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
@@ -244,8 +280,8 @@ static status_t process_auth(private_ike_auth_t *this, message_t *message)
|
||||
}
|
||||
|
||||
auth_method = auth_payload->get_auth_method(auth_payload);
|
||||
auth = authenticator_create_from_auth_payload(this->ike_sa, auth_payload);
|
||||
|
||||
auth = authenticator_create_from_method(this->ike_sa,
|
||||
auth_payload->get_auth_method(auth_payload));
|
||||
if (auth == NULL)
|
||||
{
|
||||
SIG_IKE(UP_FAILED, "authentication method %N used by '%D' not "
|
||||
@@ -414,7 +450,7 @@ static status_t process_auth_eap(private_ike_auth_t *this, message_t *message)
|
||||
{
|
||||
SIG_IKE(UP_FAILED, "authentication of '%D' with %N failed",
|
||||
this->ike_sa->get_other_id(this->ike_sa),
|
||||
auth_method_names, AUTH_EAP);
|
||||
auth_class_names, AUTH_CLASS_EAP);
|
||||
if (this->initiator)
|
||||
{
|
||||
return FAILED;
|
||||
@@ -514,7 +550,7 @@ static status_t build_eap_r(private_ike_auth_t *this, message_t *message)
|
||||
default:
|
||||
SIG_IKE(UP_FAILED, "authentication of '%D' with %N failed",
|
||||
this->ike_sa->get_other_id(this->ike_sa),
|
||||
auth_method_names, AUTH_EAP);
|
||||
auth_class_names, AUTH_CLASS_EAP);
|
||||
status = FAILED;
|
||||
break;
|
||||
}
|
||||
@@ -540,7 +576,7 @@ static status_t build_i(private_ike_auth_t *this, message_t *message)
|
||||
}
|
||||
|
||||
config = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (config->get_auth_method(config) == CONF_AUTH_EAP)
|
||||
if (get_auth_class(config) == AUTH_CLASS_EAP)
|
||||
{
|
||||
this->eap_auth = eap_authenticator_create(this->ike_sa);
|
||||
}
|
||||
@@ -580,7 +616,6 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
|
||||
case NOT_FOUND:
|
||||
/* use EAP if no AUTH payload found */
|
||||
this->ike_sa->set_condition(this->ike_sa, COND_EAP_AUTHENTICATED, TRUE);
|
||||
this->eap_auth = eap_authenticator_create(this->ike_sa);
|
||||
break;
|
||||
default:
|
||||
return NEED_MORE;
|
||||
@@ -597,7 +632,10 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
|
||||
this->ike_sa->set_peer_cfg(this->ike_sa, config);
|
||||
config->destroy(config);
|
||||
}
|
||||
|
||||
if (!this->peer_authenticated)
|
||||
{
|
||||
this->eap_auth = eap_authenticator_create(this->ike_sa);
|
||||
}
|
||||
return NEED_MORE;
|
||||
}
|
||||
|
||||
@@ -662,7 +700,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
|
||||
}
|
||||
|
||||
/* initiate EAP authenitcation */
|
||||
eap_type = config->get_eap_type(config, &eap_vendor);
|
||||
eap_type = get_eap_type(config, &eap_vendor);
|
||||
status = this->eap_auth->initiate(this->eap_auth, eap_type,
|
||||
eap_vendor, &eap_payload);
|
||||
message->add_payload(message, (payload_t*)eap_payload);
|
||||
|
||||
@@ -97,6 +97,11 @@ static cert_payload_t *build_cert_payload(private_ike_cert_post_t *this, certifi
|
||||
return payload;
|
||||
}
|
||||
|
||||
/**
|
||||
* from ike_auth.c
|
||||
*/
|
||||
auth_class_t get_auth_class(peer_cfg_t *config);
|
||||
|
||||
/**
|
||||
* add certificates to message
|
||||
*/
|
||||
@@ -105,7 +110,7 @@ static void build_certs(private_ike_cert_post_t *this, message_t *message)
|
||||
peer_cfg_t *peer_cfg;
|
||||
|
||||
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
|
||||
if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == CONF_AUTH_PUBKEY)
|
||||
if (peer_cfg && get_auth_class(peer_cfg) == AUTH_CLASS_PUBKEY)
|
||||
{
|
||||
switch (peer_cfg->get_cert_policy(peer_cfg))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user