implemented Expanded EAP types to support vendor specific methods

This commit is contained in:
Martin Willi
2007-12-13 17:31:21 +00:00
parent 3243ac6d5e
commit 0f806802ae
19 changed files with 226 additions and 79 deletions
+1 -1
View File
@@ -186,7 +186,7 @@ static peer_cfg_t *process_peer_cfg_row(private_sqlite_backend_t *this,
2, ike_cfg, local_id, remote_id, NULL, NULL, linked_list_create(),
sqlite3_column_int(stmt, 4), /* cert_policy */
sqlite3_column_int(stmt, 5), /* auth_method */
sqlite3_column_int(stmt, 6), /* eap_type */
sqlite3_column_int(stmt, 6), 0 /* eap_type, vendor */
sqlite3_column_int(stmt, 7), /* keyingtries */
sqlite3_column_int(stmt, 8), /* rekey_time */
sqlite3_column_int(stmt, 9), /* reauth_time */
+10 -2
View File
@@ -126,6 +126,11 @@ struct private_peer_cfg_t {
*/
eap_type_t eap_type;
/**
* EAP vendor ID if vendor specific type is used
*/
u_int32_t eap_vendor;
/**
* number of tries after giving up if peer does not respond
*/
@@ -338,8 +343,9 @@ static auth_method_t get_auth_method(private_peer_cfg_t *this)
/**
* Implementation of connection_t.get_eap_type.
*/
static eap_type_t get_eap_type(private_peer_cfg_t *this)
static eap_type_t get_eap_type(private_peer_cfg_t *this, u_int32_t *vendor)
{
*vendor = this->eap_vendor;
return this->eap_type;
}
@@ -518,6 +524,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
identification_t *my_ca, identification_t *other_ca,
linked_list_t *groups, cert_policy_t cert_policy,
auth_method_t auth_method, eap_type_t eap_type,
u_int32_t eap_vendor,
u_int32_t keyingtries, u_int32_t rekey_time,
u_int32_t reauth_time, u_int32_t jitter_time,
u_int32_t over_time, bool mobike,
@@ -542,7 +549,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->public.get_groups = (linked_list_t* (*)(peer_cfg_t *))get_groups;
this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *))get_eap_type;
this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *,u_int32_t*))get_eap_type;
this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
@@ -574,6 +581,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
this->cert_policy = cert_policy;
this->auth_method = auth_method;
this->eap_type = eap_type;
this->eap_vendor = eap_vendor;
this->keyingtries = keyingtries;
this->rekey_time = rekey_time;
this->reauth_time = reauth_time;
+8 -1
View File
@@ -229,11 +229,16 @@ struct peer_cfg_t {
/**
* @brief Get the EAP type to use for peer authentication.
*
* If vendor specific types are used, a vendor ID != 0 is returned to
* to vendor argument. Then the returned type is specific for that
* vendor ID.
*
* @param this calling object
* @param vendor receives vendor specifier, 0 for predefined EAP types
* @return authentication method
*/
eap_type_t (*get_eap_type) (peer_cfg_t *this);
eap_type_t (*get_eap_type) (peer_cfg_t *this, u_int32_t *vendor);
/**
* @brief Get the max number of retries after timeout.
@@ -393,6 +398,7 @@ struct peer_cfg_t {
* @param cert_policy should we send a certificate payload?
* @param auth_method auth method to use to authenticate us
* @param eap_type EAP type to use for peer authentication
* @param eap_vendor EAP vendor identifier, if vendor specific type is used
* @param keyingtries how many keying tries should be done before giving up
* @param rekey_time timeout before starting rekeying
* @param reauth_time timeout before starting reauthentication
@@ -416,6 +422,7 @@ peer_cfg_t *peer_cfg_create(char *name, u_int ikev_version, ike_cfg_t *ike_cfg,
identification_t *my_ca, identification_t *other_ca,
linked_list_t *groups, cert_policy_t cert_policy,
auth_method_t auth_method, eap_type_t eap_type,
u_int32_t eap_vendor,
u_int32_t keyingtries, u_int32_t rekey_time,
u_int32_t reauth_time, u_int32_t jitter_time,
u_int32_t over_time, bool mobike,
@@ -245,6 +245,7 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
char *interface;
bool use_existing = FALSE;
iterator_t *iterator;
u_int32_t vendor;
pop_string(msg, &msg->add_conn.name);
DBG1(DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
@@ -543,7 +544,8 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
&& ietfAttr_list_equals(other_groups, peer_cfg->get_groups(peer_cfg))
&& peer_cfg->get_ike_version(peer_cfg) == (msg->add_conn.ikev2 ? 2 : 1)
&& peer_cfg->get_auth_method(peer_cfg) == msg->add_conn.auth_method
&& peer_cfg->get_eap_type(peer_cfg) == msg->add_conn.eap_type)
&& peer_cfg->get_eap_type(peer_cfg, &vendor) == msg->add_conn.eap_type
&& vendor == msg->add_conn.eap_vendor)
{
DBG1(DBG_CFG, "reusing existing configuration '%s'",
peer_cfg->get_name(peer_cfg));
@@ -626,8 +628,8 @@ static void stroke_add_conn(stroke_msg_t *msg, FILE *out)
peer_cfg = peer_cfg_create(msg->add_conn.name, msg->add_conn.ikev2 ? 2 : 1,
ike_cfg, my_id, other_id, my_ca, other_ca, other_groups,
msg->add_conn.me.sendcert,
msg->add_conn.auth_method, msg->add_conn.eap_type,
msg->add_conn.me.sendcert, msg->add_conn.auth_method,
msg->add_conn.eap_type, msg->add_conn.eap_vendor,
msg->add_conn.rekey.tries, rekey, reauth, jitter, over,
msg->add_conn.mobike,
msg->add_conn.dpd.delay, msg->add_conn.dpd.action, my_vip, other_vip,
+16 -3
View File
@@ -235,11 +235,23 @@ static u_int8_t get_identifier(private_eap_payload_t *this)
/**
* Implementation of eap_payload_t.get_type.
*/
static eap_type_t get_type(private_eap_payload_t *this)
static eap_type_t get_type(private_eap_payload_t *this, u_int32_t *vendor)
{
eap_type_t type;
*vendor = 0;
if (this->data.len > 4)
{
return *(this->data.ptr + 4);
type = *(this->data.ptr + 4);
if (type != EAP_EXPANDED)
{
return type;
}
if (this->data.len >= 12)
{
*vendor = ntohl(*(u_int32_t*)(this->data.ptr + 4)) & 0x00FFFFFF;
return ntohl(*(u_int32_t*)(this->data.ptr + 8));
}
}
return 0;
}
@@ -275,7 +287,7 @@ eap_payload_t *eap_payload_create()
this->public.set_data = (void (*) (eap_payload_t *,chunk_t))set_data;
this->public.get_code = (eap_code_t (*) (eap_payload_t*))get_code;
this->public.get_identifier = (u_int8_t (*) (eap_payload_t*))get_identifier;
this->public.get_type = (eap_type_t (*) (eap_payload_t*))get_type;
this->public.get_type = (eap_type_t (*) (eap_payload_t*,u_int32_t*))get_type;
/* private variables */
this->critical = FALSE;
@@ -329,3 +341,4 @@ eap_payload_t *eap_payload_create_nak()
this->set_data(this, data);
return this;
}
+3 -2
View File
@@ -95,9 +95,10 @@ struct eap_payload_t {
* @brief Get the EAP method type.
*
* @param this calling eap_payload_t object
* @return EAP method type
* @param vendor pointer receiving vendor identifier
* @return EAP method type, vendor specific if vendor != 0
*/
eap_type_t (*get_type) (eap_payload_t *this);
eap_type_t (*get_type) (eap_payload_t *this, u_int32_t *vendor);
/**
* @brief Destroys an eap_payload_t object.
+7 -4
View File
@@ -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;
+3 -2
View File
@@ -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;
+31 -11
View File
@@ -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;
}
@@ -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.
+3 -2
View File
@@ -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;
@@ -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 */
@@ -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.
+5 -3
View File
@@ -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)
{
+23 -6
View File
@@ -509,29 +509,46 @@ load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg)
}
break;
case KW_EAP:
/* TODO: a gperf function for all EAP types */
{
char *sep;
/* check for vendor-type format */
sep = strchr(kw->value, '-');
if (sep)
{
*(sep++) = '\0';
conn->eap_type = atoi(kw->value);
conn->eap_vendor = atoi(sep);
if (conn->eap_type == 0 || conn->eap_vendor == 0)
{
plog("# invalid EAP type: %s=%s", kw->entry->name, kw->value);
cfg->err++;
}
break;
}
if (streq(kw->value, "aka"))
{
conn->eap = 23;
conn->eap_type = 23;
}
else if (streq(kw->value, "sim"))
{
conn->eap = 18;
conn->eap_type = 18;
}
else if (streq(kw->value, "md5"))
{
conn->eap = 4;
conn->eap_type = 4;
}
else
{
conn->eap = atoi(kw->value);
if (conn->eap == 0)
conn->eap_type = atoi(kw->value);
if (conn->eap_type == 0)
{
plog("# unknown EAP type: %s=%s", kw->entry->name, kw->value);
cfg->err++;
}
}
break;
}
case KW_KEYINGTRIES:
if (streq(kw->value, "%forever"))
{
+2 -1
View File
@@ -106,7 +106,8 @@ struct starter_conn {
starter_state_t state;
keyexchange_t keyexchange;
int eap;
u_int32_t eap_type;
u_int32_t eap_vendor;
lset_t policy;
time_t sa_ike_life_seconds;
time_t sa_ipsec_life_seconds;
+12 -4
View File
@@ -350,13 +350,21 @@ in case of inactivity. This only applies to IKEv1, in IKEv2 the default
retransmission timeout applies, as every exchange is used to detect dead peers.
.TP
.B eap
defines the EAP type to be used if
defines the EAP type to propose as server if the client has
.B authby=eap
is selected. Acceptable values are
selected. Acceptable values are
.B aka
for EAP-AKA and
for EAP-AKA,
.B sim
for EAP-SIM.
for EAP-SIM and
.B md5
for EAP-MD5.
Additionally, IANA assigned EAP method numbers are accepted, or a definition
in the form
.B eap=type-vendor
(e.g.
.B eap=7-12345
) can be used to specify vendor specific EAP types.
.TP
.B esp
ESP encryption/authentication algorithm to be used
+2 -1
View File
@@ -197,7 +197,8 @@ int starter_stroke_add_conn(starter_conn_t *conn)
{
msg.add_conn.auth_method = AUTH_EAP;
}
msg.add_conn.eap_type = conn->eap;
msg.add_conn.eap_type = conn->eap_type;
msg.add_conn.eap_vendor = conn->eap_vendor;
if (conn->policy & POLICY_TUNNEL)
{
+2 -1
View File
@@ -182,7 +182,8 @@ struct stroke_msg_t {
char *name;
int ikev2;
int auth_method;
int eap_type;
u_int32_t eap_type;
u_int32_t eap_vendor;
int mode;
int mobike;
int force_encap;