diff options
-rw-r--r-- | src/charon/sa/authenticators/eap/eap_identity.c | 135 | ||||
-rw-r--r-- | src/charon/sa/authenticators/eap/eap_identity.h | 59 | ||||
-rw-r--r-- | src/charon/sa/authenticators/eap_authenticator.c | 21 |
3 files changed, 215 insertions, 0 deletions
diff --git a/src/charon/sa/authenticators/eap/eap_identity.c b/src/charon/sa/authenticators/eap/eap_identity.c new file mode 100644 index 000000000..12a8bf7cc --- /dev/null +++ b/src/charon/sa/authenticators/eap/eap_identity.c @@ -0,0 +1,135 @@ +/** + * @file eap_identity.c + * + * @brief Implementation of eap_identity_t. + * + */ + +/* + * Copyright (C) 2007 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "eap_identity.h" + +#include <daemon.h> +#include <library.h> + +typedef struct private_eap_identity_t private_eap_identity_t; + +/** + * Private data of an eap_identity_t object. + */ +struct private_eap_identity_t { + + /** + * Public authenticator_t interface. + */ + eap_identity_t public; + + /** + * ID of the peer + */ + identification_t *peer; +}; + +/** + * Implementation of eap_method_t.process for the peer + */ +static status_t process(private_eap_identity_t *this, + eap_payload_t *in, eap_payload_t **out) +{ + chunk_t id, hdr; + + hdr = chunk_alloca(5); + id = this->peer->get_encoding(this->peer); + + *(hdr.ptr + 0) = EAP_RESPONSE; + *(hdr.ptr + 1) = in->get_identifier(in); + *(u_int16_t*)(hdr.ptr + 2) = htons(hdr.len + id.len); + *(hdr.ptr + 4) = EAP_IDENTITY; + + *out = eap_payload_create_data(chunk_cata("cc", hdr, id)); + return SUCCESS; + +} + +/** + * Implementation of eap_method_t.initiate for the peer + */ +static status_t initiate(private_eap_identity_t *this, eap_payload_t **out) +{ + /* peer never initiates */ + return FAILED; +} + +/** + * Implementation of eap_method_t.get_type. + */ +static eap_type_t get_type(private_eap_identity_t *this) +{ + return EAP_IDENTITY; +} + +/** + * Implementation of eap_method_t.get_msk. + */ +static status_t get_msk(private_eap_identity_t *this, chunk_t *msk) +{ + return FAILED; +} + +/** + * Implementation of eap_method_t.is_mutual. + */ +static bool is_mutual(private_eap_identity_t *this) +{ + return FALSE; +} + +/** + * Implementation of eap_method_t.destroy. + */ +static void destroy(private_eap_identity_t *this) +{ + free(this); +} + +/* + * Described in header. + */ +eap_identity_t *eap_create(eap_role_t role, + identification_t *server, identification_t *peer) +{ + private_eap_identity_t *this; + + if (role != EAP_PEER) + { + return NULL; + } + + this = malloc_thing(private_eap_identity_t); + + /* 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.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; + + /* private data */ + this->peer = peer; + + return &this->public; +} diff --git a/src/charon/sa/authenticators/eap/eap_identity.h b/src/charon/sa/authenticators/eap/eap_identity.h new file mode 100644 index 000000000..20f0f0b67 --- /dev/null +++ b/src/charon/sa/authenticators/eap/eap_identity.h @@ -0,0 +1,59 @@ +/** + * @file eap_identity.h + * + * @brief Interface of eap_identity_t. + * + */ + +/* + * Copyright (C) 2007 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef EAP_IDENTITY_H_ +#define EAP_IDENTITY_H_ + +typedef struct eap_identity_t eap_identity_t; + +#include <sa/authenticators/eap/eap_method.h> + +/** + * @brief Implementation of the eap_method_t interface using EAP Identity. + * + * @b Constructors: + * - eap_identity_create() + * - eap_client_create() using eap_method EAP_IDENTITY + * + * @ingroup eap + */ +struct eap_identity_t { + + /** + * Implemented eap_method_t interface. + */ + eap_method_t eap_method_interface; +}; + +/** + * @brief Creates the EAP method EAP Identity. + * + * @param server ID of the EAP server + * @param peer ID of the EAP client + * @return eap_identity_t object + * + * @ingroup eap + */ +eap_identity_t *eap_create(eap_role_t role, + identification_t *server, identification_t *peer); + +#endif /* EAP_IDENTITY_H_ */ diff --git a/src/charon/sa/authenticators/eap_authenticator.c b/src/charon/sa/authenticators/eap_authenticator.c index 8736e05c3..3b2b4be97 100644 --- a/src/charon/sa/authenticators/eap_authenticator.c +++ b/src/charon/sa/authenticators/eap_authenticator.c @@ -163,6 +163,27 @@ static status_t process_peer(private_eap_authenticator_t *this, { eap_type_t type = in->get_type(in); + if (type == EAP_IDENTITY) + { + eap_method_t *method = eap_method_create(type, EAP_PEER, + this->ike_sa->get_other_id(this->ike_sa), + this->ike_sa->get_my_id(this->ike_sa)); + + if (method == NULL || method->process(method, in, out) != SUCCESS) + { + DBG1(DBG_IKE, "EAP server requested %N, but unable to process", + eap_type_names, type); + DESTROY_IF(method); + return FAILED; + } + + DBG1(DBG_IKE, "EAP server requested %N, sending IKE identity", + eap_type_names, type); + + method->destroy(method); + return NEED_MORE; + } + /* create an eap_method for the first call */ if (this->method == NULL) { |