aboutsummaryrefslogtreecommitdiffstats
path: root/src/charon/sa
diff options
context:
space:
mode:
Diffstat (limited to 'src/charon/sa')
-rw-r--r--src/charon/sa/authenticators/eap/eap_aka.c11
-rw-r--r--src/charon/sa/authenticators/eap/eap_md5.c5
-rw-r--r--src/charon/sa/authenticators/eap/eap_method.c42
-rw-r--r--src/charon/sa/authenticators/eap/eap_method.h11
-rw-r--r--src/charon/sa/authenticators/eap/eap_sim.c5
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.c105
-rw-r--r--src/charon/sa/authenticators/eap_authenticator.h9
-rw-r--r--src/charon/sa/tasks/ike_auth.c8
8 files changed, 142 insertions, 54 deletions
diff --git a/src/charon/sa/authenticators/eap/eap_aka.c b/src/charon/sa/authenticators/eap/eap_aka.c
index fc2ffcd3f..8fb1f85cd 100644
--- a/src/charon/sa/authenticators/eap/eap_aka.c
+++ b/src/charon/sa/authenticators/eap/eap_aka.c
@@ -42,6 +42,8 @@
#include <string.h>
#include <unistd.h>
+#include <sys/time.h>
+#include <time.h>
#include "eap_aka.h"
@@ -582,8 +584,8 @@ static status_t load_key(identification_t *me, identification_t *other, chunk_t
{
chunk_t shared_key;
- if (charon->credentials->get_shared_key(charon->credentials, me,
- other, &shared_key) != SUCCESS)
+ if (charon->credentials->get_eap_key(charon->credentials, me,
+ other, &shared_key) != SUCCESS)
{
return NOT_FOUND;
}
@@ -1353,8 +1355,9 @@ static status_t peer_initiate(private_eap_aka_t *this, eap_payload_t **out)
/**
* Implementation of eap_method_t.get_type.
*/
-static eap_type_t get_type(private_eap_aka_t *this)
+static eap_type_t get_type(private_eap_aka_t *this, u_int32_t *vendor)
{
+ *vendor = 0;
return EAP_AKA;
}
@@ -1417,7 +1420,7 @@ eap_aka_t *eap_create(eap_role_t role,
free(this);
return NULL;
}
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*))get_type;
+ this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
diff --git a/src/charon/sa/authenticators/eap/eap_md5.c b/src/charon/sa/authenticators/eap/eap_md5.c
index 8fe74ed25..ca5c1d6b7 100644
--- a/src/charon/sa/authenticators/eap/eap_md5.c
+++ b/src/charon/sa/authenticators/eap/eap_md5.c
@@ -212,8 +212,9 @@ static status_t process_server(private_eap_md5_t *this,
/**
* Implementation of eap_method_t.get_type.
*/
-static eap_type_t get_type(private_eap_md5_t *this)
+static eap_type_t get_type(private_eap_md5_t *this, u_int32_t *vendor)
{
+ *vendor = 0;
return EAP_MD5;
}
@@ -265,7 +266,7 @@ eap_md5_t *eap_create(eap_role_t role,
free(this);
return NULL;
}
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*))get_type;
+ this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
diff --git a/src/charon/sa/authenticators/eap/eap_method.c b/src/charon/sa/authenticators/eap/eap_method.c
index e4a58f0a3..7434ca2a1 100644
--- a/src/charon/sa/authenticators/eap/eap_method.c
+++ b/src/charon/sa/authenticators/eap/eap_method.c
@@ -45,7 +45,10 @@ ENUM_NEXT(eap_type_names, EAP_SIM, EAP_SIM, EAP_TOKEN_CARD,
"EAP_SIM");
ENUM_NEXT(eap_type_names, EAP_AKA, EAP_AKA, EAP_SIM,
"EAP_AKA");
-ENUM_END(eap_type_names, EAP_AKA);
+ENUM_NEXT(eap_type_names, EAP_EXPANDED, EAP_EXPERIMENTAL, EAP_AKA,
+ "EAP_EXPANDED",
+ "EAP_EXPERIMENTAL");
+ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
ENUM(eap_code_names, EAP_REQUEST, EAP_FAILURE,
"EAP_REQUEST",
@@ -67,6 +70,7 @@ typedef struct module_entry_t module_entry_t;
*/
struct module_entry_t {
eap_type_t type;
+ u_int32_t vendor;
void *handle;
eap_constructor_t constructor;
};
@@ -85,7 +89,8 @@ void eap_method_unload()
while (modules->remove_last(modules, (void**)&entry) == SUCCESS)
{
- DBG2(DBG_CFG, "unloaded module for %N", eap_type_names, entry->type);
+ DBG2(DBG_CFG, "unloaded module EAP module %d-%d",
+ entry->type, entry->vendor);
dlclose(entry->handle);
free(entry);
}
@@ -165,11 +170,19 @@ void eap_method_load(char *directory)
dlclose(module.handle);
continue;
}
- module.type = method->get_type(method);
+ module.type = method->get_type(method, &module.vendor);
method->destroy(method);
- DBG1(DBG_CFG, " loaded EAP method %N successfully from %s",
- eap_type_names, module.type, entry->d_name);
+ if (module.vendor)
+ {
+ DBG1(DBG_CFG, " loaded EAP method %d, vendor %d successfully from %s",
+ module.type, module.vendor, entry->d_name);
+ }
+ else
+ {
+ DBG1(DBG_CFG, " loaded EAP method %N successfully from %s",
+ eap_type_names, module.type, entry->d_name);
+ }
loaded_module = malloc_thing(module_entry_t);
memcpy(loaded_module, &module, sizeof(module));
@@ -181,9 +194,8 @@ void eap_method_load(char *directory)
/*
* Described in header.
*/
-eap_method_t *eap_method_create(eap_type_t type, eap_role_t role,
- identification_t *server,
- identification_t *peer)
+eap_method_t *eap_method_create(eap_type_t type, u_int32_t vendor, eap_role_t role,
+ identification_t *server, identification_t *peer)
{
eap_method_t *method = NULL;
iterator_t *iterator;
@@ -192,7 +204,7 @@ eap_method_t *eap_method_create(eap_type_t type, eap_role_t role,
iterator = modules->create_iterator(modules, TRUE);
while (iterator->iterate(iterator, (void**)&entry))
{
- if (entry->type == type)
+ if (entry->type == type && entry->vendor == vendor)
{
method = entry->constructor(role, server, peer);
if (method)
@@ -205,8 +217,16 @@ eap_method_t *eap_method_create(eap_type_t type, eap_role_t role,
if (method == NULL)
{
- DBG1(DBG_CFG, "no EAP module found for %N %N",
- eap_type_names, type, eap_role_names, role);
+ if (vendor)
+ {
+ DBG1(DBG_CFG, "no vendor %d specific EAP module found for method "
+ "%d %N", vendor, type, eap_role_names, role);
+ }
+ else
+ {
+ DBG1(DBG_CFG, "no EAP module found for %N %N",
+ eap_type_names, type, eap_role_names, role);
+ }
}
return method;
}
diff --git a/src/charon/sa/authenticators/eap/eap_method.h b/src/charon/sa/authenticators/eap/eap_method.h
index d43dc001f..8675fd8ec 100644
--- a/src/charon/sa/authenticators/eap/eap_method.h
+++ b/src/charon/sa/authenticators/eap/eap_method.h
@@ -62,6 +62,8 @@ enum eap_type_t {
EAP_TOKEN_CARD = 6,
EAP_SIM = 18,
EAP_AKA = 23,
+ EAP_EXPANDED = 254,
+ EAP_EXPERIMENTAL = 255,
};
/**
@@ -148,9 +150,10 @@ struct eap_method_t {
* @brief Get the EAP type implemented in this method.
*
* @param this calling object
+ * @param vendor pointer receiving vendor identifier for type, 0 for none
* @return type of the EAP method
*/
- eap_type_t (*get_type) (eap_method_t *this);
+ eap_type_t (*get_type) (eap_method_t *this, u_int32_t *vendor);
/**
* @brief Check if this EAP method authenticates the server.
@@ -188,6 +191,7 @@ struct eap_method_t {
* @brief Creates an EAP method for a specific type and role.
*
* @param eap_type EAP type to use
+ * @param eap_vendor vendor identifier if a vendor specifc EAP type is used
* @param role role of the eap_method, server or peer
* @param server ID of acting server
* @param peer ID of involved peer (client)
@@ -195,8 +199,9 @@ struct eap_method_t {
*
* @ingroup eap
*/
-eap_method_t *eap_method_create(eap_type_t eap_type, eap_role_t role,
- identification_t *server, identification_t *peer);
+eap_method_t *eap_method_create(eap_type_t eap_type, u_int32_t eap_vendor,
+ eap_role_t role, identification_t *server,
+ identification_t *peer);
/**
* @brief (Re-)Load all EAP modules in the EAP modules directory.
diff --git a/src/charon/sa/authenticators/eap/eap_sim.c b/src/charon/sa/authenticators/eap/eap_sim.c
index e369c56e3..c9eb5ce8f 100644
--- a/src/charon/sa/authenticators/eap/eap_sim.c
+++ b/src/charon/sa/authenticators/eap/eap_sim.c
@@ -698,8 +698,9 @@ static status_t initiate(private_eap_sim_t *this, eap_payload_t **out)
/**
* Implementation of eap_method_t.get_type.
*/
-static eap_type_t get_type(private_eap_sim_t *this)
+static eap_type_t get_type(private_eap_sim_t *this, u_int32_t *vendor)
{
+ *vendor = 0;
return EAP_SIM;
}
@@ -786,7 +787,7 @@ eap_sim_t *eap_create(eap_role_t role,
/* public functions */
this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate;
this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process;
- this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*))get_type;
+ this->public.eap_method_interface.get_type = (eap_type_t(*)(eap_method_t*,u_int32_t*))get_type;
this->public.eap_method_interface.is_mutual = (bool(*)(eap_method_t*))is_mutual;
this->public.eap_method_interface.get_msk = (status_t(*)(eap_method_t*,chunk_t*))get_msk;
this->public.eap_method_interface.destroy = (void(*)(eap_method_t*))destroy;
diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c
index 6e2f73a43..6250604a6 100644
--- a/src/charon/sa/authenticators/eap_authenticator.c
+++ b/src/charon/sa/authenticators/eap_authenticator.c
@@ -138,7 +138,7 @@ static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init,
* Implementation of eap_authenticator_t.initiate
*/
static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
- eap_payload_t **out)
+ u_int32_t vendor, eap_payload_t **out)
{
/* if initiate() is called, role is always server */
this->role = EAP_SERVER;
@@ -151,21 +151,30 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
return FAILED;
}
- DBG1(DBG_IKE, "requesting %N authentication", eap_type_names, type);
- this->method = eap_method_create(type, this->role,
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "requesting vendor specific EAP authentication %d-%d",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "requesting %N authentication", eap_type_names, type);
+ }
+ this->method = eap_method_create(type, vendor, this->role,
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa));
if (this->method == NULL)
{
- DBG1(DBG_IKE, "configured EAP server method %N not supported, sending %N",
- eap_type_names, type, eap_code_names, EAP_FAILURE);
+
+ DBG1(DBG_IKE, "configured EAP server method not supported, sending %N",
+ eap_code_names, EAP_FAILURE);
*out = eap_payload_create_code(EAP_FAILURE);
return FAILED;
}
if (this->method->initiate(this->method, out) != NEED_MORE)
{
- DBG1(DBG_IKE, "failed to initiate %N, sending %N",
+ DBG1(DBG_IKE, "failed to initiate EAP exchange, sending %N",
eap_type_names, type, eap_code_names, EAP_FAILURE);
*out = eap_payload_create_code(EAP_FAILURE);
return FAILED;
@@ -179,11 +188,14 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
static status_t process_peer(private_eap_authenticator_t *this,
eap_payload_t *in, eap_payload_t **out)
{
- eap_type_t type = in->get_type(in);
+ eap_type_t type;
+ u_int32_t vendor;
- if (type == EAP_IDENTITY)
+ type = in->get_type(in, &vendor);
+
+ if (!vendor && type == EAP_IDENTITY)
{
- eap_method_t *method = eap_method_create(type, EAP_PEER,
+ eap_method_t *method = eap_method_create(type, 0, EAP_PEER,
this->ike_sa->get_other_id(this->ike_sa),
this->ike_sa->get_my_id(this->ike_sa));
@@ -205,32 +217,57 @@ static status_t process_peer(private_eap_authenticator_t *this,
/* create an eap_method for the first call */
if (this->method == NULL)
{
- DBG1(DBG_IKE, "EAP server requested %N authentication",
- eap_type_names, type);
- this->method = eap_method_create(type, EAP_PEER,
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP server requested vendor specific EAP method %d-%d",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP server requested %N authentication",
+ eap_type_names, type);
+ }
+ this->method = eap_method_create(type, vendor, EAP_PEER,
this->ike_sa->get_other_id(this->ike_sa),
this->ike_sa->get_my_id(this->ike_sa));
if (this->method == NULL)
{
DBG1(DBG_IKE, "EAP server requested unsupported "
- "EAP method %N, sending EAP_NAK", eap_type_names, type);
+ "EAP method, sending EAP_NAK");
*out = eap_payload_create_nak();
return NEED_MORE;
}
}
+ type = this->method->get_type(this->method, &vendor);
+
switch (this->method->process(this->method, in, out))
{
case NEED_MORE:
return NEED_MORE;
case SUCCESS:
- DBG1(DBG_IKE, "EAP method %N succeded",
- eap_type_names, this->method->get_type(this->method));
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeded",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N succeded", eap_type_names, type);
+ }
return SUCCESS;
case FAILED:
default:
- DBG1(DBG_IKE, "EAP method %N failed",
- eap_type_names, this->method->get_type(this->method));
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d failed",
+ type, vendor);
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N failed",
+ eap_type_names, type);
+ }
return FAILED;
}
}
@@ -241,6 +278,11 @@ static status_t process_peer(private_eap_authenticator_t *this,
static status_t process_server(private_eap_authenticator_t *this,
eap_payload_t *in, eap_payload_t **out)
{
+ eap_type_t type;
+ u_int32_t vendor;
+
+ type = this->method->get_type(this->method, &vendor);
+
switch (this->method->process(this->method, in, out))
{
case NEED_MORE:
@@ -248,22 +290,35 @@ static status_t process_server(private_eap_authenticator_t *this,
case SUCCESS:
if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
{
- DBG1(DBG_IKE, "EAP method %N succeded, MSK established",
- eap_type_names, this->method->get_type(this->method));
this->msk = chunk_clone(this->msk);
}
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d succeded, "
+ "%sMSK established", type, vendor,
+ this->msk.ptr ? "" : "no ");
+ }
else
{
- DBG1(DBG_IKE, "EAP method %N succeded, no MSK established",
- eap_type_names, this->method->get_type(this->method));
+ DBG1(DBG_IKE, "EAP method %N succeded, %sMSK established",
+ eap_type_names, type, this->msk.ptr ? "" : "no ");
}
*out = eap_payload_create_code(EAP_SUCCESS);
return SUCCESS;
case FAILED:
default:
- DBG1(DBG_IKE, "EAP method %N failed for peer %D",
- eap_type_names, this->method->get_type(this->method),
- this->ike_sa->get_other_id(this->ike_sa));
+ if (vendor)
+ {
+ DBG1(DBG_IKE, "EAP vendor specific method %d-%d failed for "
+ "peer %D", type, vendor,
+ this->ike_sa->get_other_id(this->ike_sa));
+ }
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N failed for peer %D",
+ eap_type_names, type,
+ this->ike_sa->get_other_id(this->ike_sa));
+ }
*out = eap_payload_create_code(EAP_FAILURE);
return FAILED;
}
@@ -363,7 +418,7 @@ eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa)
this->public.authenticator_interface.destroy = (void(*)(authenticator_t*))destroy;
this->public.is_mutual = (bool(*)(eap_authenticator_t*))is_mutual;
- this->public.initiate = (status_t(*)(eap_authenticator_t*,eap_type_t,eap_payload_t**))initiate;
+ this->public.initiate = (status_t(*)(eap_authenticator_t*,eap_type_t,u_int32_t,eap_payload_t**))initiate;
this->public.process = (status_t(*)(eap_authenticator_t*,eap_payload_t*,eap_payload_t**))process;
/* private data */
diff --git a/src/charon/sa/authenticators/eap_authenticator.h b/src/charon/sa/authenticators/eap_authenticator.h
index 64a3267d7..cf2180ee3 100644
--- a/src/charon/sa/authenticators/eap_authenticator.h
+++ b/src/charon/sa/authenticators/eap_authenticator.h
@@ -105,15 +105,16 @@ struct eap_authenticator_t {
* this method. If initiate() returns NEED_MORE, the EAP authentication
* process started. In any case, a payload is created in "out".
*
- * @param this calling object
- * @param type EAP method to use to authenticate client
- * @param out created initiaal EAP message to send
+ * @param this calling object
+ * @param type EAP method to use to authenticate client
+ * @param vendor EAP vendor identifier, if type is vendor specific, or 0
+ * @param out created initiaal EAP message to send
* @return
* - FAILED, if initiation failed
* - NEED_MORE, if more EAP exchanges reqired
*/
status_t (*initiate) (eap_authenticator_t* this, eap_type_t type,
- eap_payload_t **out);
+ u_int32_t vendor, eap_payload_t **out);
/**
* @brief Process an EAP message.
diff --git a/src/charon/sa/tasks/ike_auth.c b/src/charon/sa/tasks/ike_auth.c
index 29c38ee83..de88a0abe 100644
--- a/src/charon/sa/tasks/ike_auth.c
+++ b/src/charon/sa/tasks/ike_auth.c
@@ -548,6 +548,7 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
{
peer_cfg_t *config;
eap_type_t eap_type;
+ u_int32_t eap_vendor;
eap_payload_t *eap_payload;
status_t status;
@@ -592,10 +593,11 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
return FAILED;
}
-
+
/* initiate EAP authenitcation */
- eap_type = config->get_eap_type(config);
- status = this->eap_auth->initiate(this->eap_auth, eap_type, &eap_payload);
+ eap_type = config->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);
if (status != NEED_MORE)
{