merged the modularization branch (credentials) back to trunk

This commit is contained in:
Martin Willi
2008-03-13 14:14:44 +00:00
parent 2df655134c
commit 552cc11b1f
495 changed files with 30378 additions and 23843 deletions
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file authenticator.c
*
* @brief Generic constructor for authenticators.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include <string.h>
+13 -28
View File
@@ -1,10 +1,3 @@
/**
* @file authenticator.h
*
* @brief Interface of authenticator_t.
*
*/
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup authenticator authenticator
* @{ @ingroup authenticators
*/
#ifndef AUTHENTICATOR_H_
@@ -33,8 +33,6 @@ typedef struct authenticator_t authenticator_t;
/**
* Method to use for authentication.
*
* @ingroup authenticators
*/
enum auth_method_t {
/**
@@ -65,29 +63,21 @@ enum auth_method_t {
/**
* enum names for auth_method_t.
*
* @ingroup authenticators
*/
extern enum_name_t *auth_method_names;
/**
* @brief Authenticator interface implemented by the various authenticators.
* Authenticator interface implemented by the various authenticators.
*
* Currently the following two AUTH methods are supported:
* - shared key message integrity code (AUTH_PSK)
* - RSA digital signature (AUTH_RSA)
*
* @b Constructors:
* - authenticator_create()
*
* @ingroup authenticators
*/
struct authenticator_t {
/**
* @brief Verify a received authentication payload.
* Verify a received authentication payload.
*
* @param this calling object
* @param ike_sa_init binary representation of received ike_sa_init
* @param my_nonce the sent nonce
* @param auth_payload authentication payload to verify
@@ -102,9 +92,8 @@ struct authenticator_t {
chunk_t my_nonce, auth_payload_t *auth_payload);
/**
* @brief Build an authentication payload to send to the other peer.
* Build an authentication payload to send to the other peer.
*
* @param this calling object
* @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
@@ -117,23 +106,19 @@ struct authenticator_t {
chunk_t other_nonce, auth_payload_t **auth_payload);
/**
* @brief Destroys a authenticator_t object.
*
* @param this calling object
* Destroys a authenticator_t object.
*/
void (*destroy) (authenticator_t *this);
};
/**
* @brief Creates an authenticator for the specified auth method.
* Creates an authenticator for the specified auth method.
*
* @param ike_sa associated ike_sa
* @param auth_method authentication method to use for build()/verify()
*
* @return authenticator_t object
*
* @ingroup authenticators
*/
authenticator_t *authenticator_create(ike_sa_t *ike_sa, auth_method_t auth_method);
#endif /* AUTHENTICATOR_H_ */
#endif /* AUTHENTICATOR_H_ @} */
File diff suppressed because it is too large Load Diff
-141
View File
@@ -1,141 +0,0 @@
/**
* @file eap_aka.h
*
* @brief Interface of eap_aka_t.
*
*/
/*
* Copyright (C) 2006 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_AKA_H_
#define EAP_AKA_H_
typedef struct eap_aka_t eap_aka_t;
typedef enum aka_subtype_t aka_subtype_t;
typedef enum aka_attribute_t aka_attribute_t;
#include <sa/authenticators/eap/eap_method.h>
/**
* Subtypes of AKA messages
*/
enum aka_subtype_t {
AKA_CHALLENGE = 1,
AKA_AUTHENTICATION_REJECT = 2,
AKA_SYNCHRONIZATION_FAILURE = 4,
AKA_IDENTITY = 5,
AKA_NOTIFICATION = 12,
AKA_REAUTHENTICATION = 13,
AKA_CLIENT_ERROR = 14,
};
/**
* enum names for aka_subtype_t
*/
extern enum_name_t *aka_subtype_names;
/**
* Attribute types in AKA messages
*/
enum aka_attribute_t {
/** defines the end of attribute list */
AT_END = -1,
AT_RAND = 1,
AT_AUTN = 2,
AT_RES = 3,
AT_AUTS = 4,
AT_PADDING = 6,
AT_NONCE_MT = 7,
AT_PERMANENT_ID_REQ = 10,
AT_MAC = 11,
AT_NOTIFICATION = 12,
AT_ANY_ID_REQ = 13,
AT_IDENTITY = 14,
AT_VERSION_LIST = 15,
AT_SELECTED_VERSION = 16,
AT_FULLAUTH_ID_REQ = 17,
AT_COUNTER = 19,
AT_COUNTER_TOO_SMALL = 20,
AT_NONCE_S = 21,
AT_CLIENT_ERROR_CODE = 22,
AT_IV = 129,
AT_ENCR_DATA = 130,
AT_NEXT_PSEUDONYM = 132,
AT_NEXT_REAUTH_ID = 133,
AT_CHECKCODE = 134,
AT_RESULT_IND = 135,
};
/**
* enum names for aka_attribute_t
*/
extern enum_name_t *aka_attribute_names;
/** check SEQ values as client for validity, disabled by default */
#ifndef SEQ_CHECK
# define SEQ_CHECK 0
#endif
/**
* @brief Implementation of the eap_method_t interface using EAP-AKA.
*
* EAP-AKA uses 3rd generation mobile phone standard authentication
* mechanism for authentication. It is a mutual authentication
* mechanism which establishs a shared key and therefore supports EAP_ONLY
* authentication. This implementation follows the standard of the
* 3GPP2 (S.S0055) and not the one of 3GGP.
* The shared key used for authentication is from ipsec.secrets. The
* peers ID is used to query it.
* The AKA mechanism uses sequence numbers to detect replay attacks. The
* peer stores the sequence number normally in a USIM and accepts
* incremental sequence numbers (incremental for lifetime of the USIM). To
* prevent a complex sequence number management, this implementation uses
* a sequence number derived from time. It is initialized to the startup
* time of the daemon. As long as the (UTC) time of the system is not
* turned back while the daemon is not running, this method is secure.
* To enable time based SEQs, #define SEQ_CHECK as 1. Default is to accept
* any SEQ numbers. This allows an attacker to do replay attacks. But since
* the server has proven his identity via IKE, such an attack is only
* possible between server and AAA (if any).
*
* @b Constructors:
* - eap_aka_create()
* - eap_client_create() using eap_method EAP_AKA
*
* @ingroup eap
*/
struct eap_aka_t {
/**
* Implemented eap_method_t interface.
*/
eap_method_t eap_method_interface;
};
/**
* @brief Creates the EAP method EAP-AKA.
*
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_aka_t object
*
* @ingroup eap
*/
eap_aka_t *eap_create(eap_role_t role,
identification_t *server, identification_t *peer);
#endif /* EAP_AKA_H_ */
@@ -1,135 +0,0 @@
/**
* @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;
}
@@ -1,59 +0,0 @@
/**
* @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_ */
@@ -0,0 +1,172 @@
/*
* Copyright (C) 2008 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.
*
* $Id$
*/
#include "eap_manager.h"
#include <pthread.h>
#include <utils/linked_list.h>
typedef struct private_eap_manager_t private_eap_manager_t;
typedef struct eap_entry_t eap_entry_t;
/**
* EAP constructor entry
*/
struct eap_entry_t {
/**
* EAP method type, vendor specific if vendor is set
*/
eap_type_t type;
/**
* vendor ID, 0 for default EAP methods
*/
u_int32_t vendor;
/**
* Role of the method returned by the constructor, EAP_SERVER or EAP_PEER
*/
eap_role_t role;
/**
* constructor function to create instance
*/
eap_constructor_t constructor;
};
/**
* private data of eap_manager
*/
struct private_eap_manager_t {
/**
* public functions
*/
eap_manager_t public;
/**
* list of eap_entry_t's
*/
linked_list_t *methods;
/**
* mutex to lock methods
*/
pthread_mutex_t mutex;
};
/**
* Implementation of eap_manager_t.add_method.
*/
static void add_method(private_eap_manager_t *this, eap_type_t type,
u_int32_t vendor, eap_role_t role,
eap_constructor_t constructor)
{
eap_entry_t *entry = malloc_thing(eap_entry_t);
entry->type = type;
entry->vendor = vendor;
entry->role = role;
entry->constructor = constructor;
pthread_mutex_lock(&this->mutex);
this->methods->insert_last(this->methods, entry);
pthread_mutex_unlock(&this->mutex);
}
/**
* Implementation of eap_manager_t.remove_method.
*/
static void remove_method(private_eap_manager_t *this, eap_constructor_t constructor)
{
enumerator_t *enumerator;
eap_entry_t *entry;
pthread_mutex_lock(&this->mutex);
enumerator = this->methods->create_enumerator(this->methods);
while (enumerator->enumerate(enumerator, &entry))
{
if (constructor == entry->constructor)
{
this->methods->remove_at(this->methods, enumerator);
free(entry);
}
}
enumerator->destroy(enumerator);
pthread_mutex_unlock(&this->mutex);
}
/**
* Implementation of eap_manager_t.create_instance.
*/
static eap_method_t* create_instance(private_eap_manager_t *this,
eap_type_t type, u_int32_t vendor,
eap_role_t role, identification_t *server,
identification_t *peer)
{
enumerator_t *enumerator;
eap_entry_t *entry;
eap_method_t *method = NULL;
pthread_mutex_lock(&this->mutex);
enumerator = this->methods->create_enumerator(this->methods);
while (enumerator->enumerate(enumerator, &entry))
{
if (type == entry->type && vendor == entry->vendor &&
role == entry->role)
{
method = entry->constructor(server, peer);
if (method)
{
break;
}
}
}
enumerator->destroy(enumerator);
pthread_mutex_unlock(&this->mutex);
return method;
}
/**
* Implementation of 2008_t.destroy
*/
static void destroy(private_eap_manager_t *this)
{
this->methods->destroy_function(this->methods, free);
free(this);
}
/*
* see header file
*/
eap_manager_t *eap_manager_create()
{
private_eap_manager_t *this = malloc_thing(private_eap_manager_t);
this->public.add_method = (void(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, eap_constructor_t constructor))add_method;
this->public.remove_method = (void(*)(eap_manager_t*, eap_constructor_t constructor))remove_method;
this->public.create_instance = (eap_method_t*(*)(eap_manager_t*, eap_type_t type, u_int32_t vendor, eap_role_t role, identification_t*,identification_t*))create_instance;
this->public.destroy = (void(*)(eap_manager_t*))destroy;
this->methods = linked_list_create();
pthread_mutex_init(&this->mutex, NULL);
return &this->public;
}
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2008 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.
*
* $Id$
*/
/**
* @defgroup eap_manager eap_manager
* @{ @ingroup eap
*/
#ifndef EAP_MANAGER_H_
#define EAP_MANAGER_H_
#include <sa/authenticators/eap/eap_method.h>
typedef struct eap_manager_t eap_manager_t;
/**
* The EAP manager manages all EAP implementations and creates instances.
*
* A plugin registers it's implemented EAP method at the manager by
* providing type and a contructor function. The manager then instanciates
* eap_method_t instances through the provided constructor to handle
* EAP authentication.
*/
struct eap_manager_t {
/**
* Register a EAP method implementation.
*
* @param method vendor specific method, if vendor != 0
* @param vendor vendor ID, 0 for non-vendor (default) EAP methods
* @param role EAP role of the registered method
* @param constructor constructor function, returns an eap_method_t
*/
void (*add_method)(eap_manager_t *this, eap_type_t type, u_int32_t vendor,
eap_role_t role, eap_constructor_t constructor);
/**
* Unregister a EAP method implementation using it's constructor.
*
* @param constructor constructor function to remove, as added in add_method
*/
void (*remove_method)(eap_manager_t *this, eap_constructor_t constructor);
/**
* Create a new EAP method instance.
*
* @param type type of the EAP method
* @param vendor vendor ID, 0 for non-vendor (default) EAP methods
* @param role role of EAP method, either EAP_SERVER or EAP_PEER
* @param server identity of the server
* @param peer identity of the peer (client)
* @return EAP method instance, NULL if no constructor found
*/
eap_method_t* (*create_instance)(eap_manager_t *this, eap_type_t type,
u_int32_t vendor, eap_role_t role,
identification_t *server,
identification_t *peer);
/**
* Destroy a eap_manager instance.
*/
void (*destroy)(eap_manager_t *this);
};
/**
* Create a eap_manager instance.
*/
eap_manager_t *eap_manager_create();
#endif /* EAP_MANAGER_H_ @}*/
-282
View File
@@ -1,282 +0,0 @@
/**
* @file eap_md5.c
*
* @brief Implementation of eap_md5_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_md5.h"
#include <daemon.h>
#include <library.h>
typedef struct private_eap_md5_t private_eap_md5_t;
/**
* Private data of an eap_md5_t object.
*/
struct private_eap_md5_t {
/**
* Public authenticator_t interface.
*/
eap_md5_t public;
/**
* ID of the server
*/
identification_t *server;
/**
* ID of the peer
*/
identification_t *peer;
/**
* challenge sent by the server
*/
chunk_t challenge;
/**
* EAP message identififier
*/
u_int8_t identifier;
};
typedef struct eap_md5_header_t eap_md5_header_t;
/**
* packed eap MD5 header struct
*/
struct eap_md5_header_t {
/** EAP code (REQUEST/RESPONSE) */
u_int8_t code;
/** unique message identifier */
u_int8_t identifier;
/** length of whole message */
u_int16_t length;
/** EAP type */
u_int8_t type;
/** length of value (challenge) */
u_int8_t value_size;
/** actual value */
u_int8_t value[];
} __attribute__((__packed__));
#define CHALLENGE_LEN 16
#define PAYLOAD_LEN (CHALLENGE_LEN + sizeof(eap_md5_header_t))
/**
* Hash the challenge string, create response
*/
static status_t hash_challenge(private_eap_md5_t *this, chunk_t *response)
{
chunk_t concat, secret;
hasher_t *hasher;
if (charon->credentials->get_eap_key(charon->credentials, this->server,
this->peer, &secret) != SUCCESS)
{
DBG1(DBG_IKE, "no EAP key found for hosts '%D' - '%D'",
this->server, this->peer);
return NOT_FOUND;
}
concat = chunk_cata("cmc", chunk_from_thing(this->identifier),
secret, this->challenge);
hasher = hasher_create(HASH_MD5);
hasher->allocate_hash(hasher, concat, response);
hasher->destroy(hasher);
return SUCCESS;
}
/**
* Implementation of eap_method_t.initiate for the peer
*/
static status_t initiate_peer(private_eap_md5_t *this, eap_payload_t **out)
{
/* peer never initiates */
return FAILED;
}
/**
* Implementation of eap_method_t.initiate for the server
*/
static status_t initiate_server(private_eap_md5_t *this, eap_payload_t **out)
{
randomizer_t *randomizer;
status_t status;
eap_md5_header_t *req;
randomizer = randomizer_create();
status = randomizer->allocate_pseudo_random_bytes(randomizer, CHALLENGE_LEN,
&this->challenge);
randomizer->destroy(randomizer);
if (status != SUCCESS)
{
return FAILED;
}
req = alloca(PAYLOAD_LEN);
req->length = htons(PAYLOAD_LEN);
req->code = EAP_REQUEST;
req->identifier = this->identifier;
req->type = EAP_MD5;
req->value_size = this->challenge.len;
memcpy(req->value, this->challenge.ptr, this->challenge.len);
*out = eap_payload_create_data(chunk_create((void*)req, PAYLOAD_LEN));
return NEED_MORE;
}
/**
* Implementation of eap_method_t.process for the peer
*/
static status_t process_peer(private_eap_md5_t *this,
eap_payload_t *in, eap_payload_t **out)
{
chunk_t response;
chunk_t data;
eap_md5_header_t *req;
this->identifier = in->get_identifier(in);
data = in->get_data(in);
this->challenge = chunk_clone(chunk_skip(data, 6));
if (data.len < 6 || this->challenge.len < *(data.ptr + 5))
{
DBG1(DBG_IKE, "received invalid EAP-MD5 message");
return FAILED;
}
if (hash_challenge(this, &response) != SUCCESS)
{
return FAILED;
}
req = alloca(PAYLOAD_LEN);
req->length = htons(PAYLOAD_LEN);
req->code = EAP_RESPONSE;
req->identifier = this->identifier;
req->type = EAP_MD5;
req->value_size = response.len;
memcpy(req->value, response.ptr, response.len);
chunk_free(&response);
*out = eap_payload_create_data(chunk_create((void*)req, PAYLOAD_LEN));
return NEED_MORE;
}
/**
* Implementation of eap_method_t.process for the server
*/
static status_t process_server(private_eap_md5_t *this,
eap_payload_t *in, eap_payload_t **out)
{
chunk_t response, expected;
chunk_t data;
if (this->identifier != in->get_identifier(in))
{
DBG1(DBG_IKE, "received invalid EAP-MD5 message");
return FAILED;
}
if (hash_challenge(this, &expected) != SUCCESS)
{
return FAILED;
}
data = in->get_data(in);
response = chunk_skip(data, 6);
if (response.len < expected.len ||
!memeq(response.ptr, expected.ptr, expected.len))
{
chunk_free(&expected);
DBG1(DBG_IKE, "EAP-MD5 verification failed");
return FAILED;
}
chunk_free(&expected);
return SUCCESS;
}
/**
* Implementation of eap_method_t.get_type.
*/
static eap_type_t get_type(private_eap_md5_t *this, u_int32_t *vendor)
{
*vendor = 0;
return EAP_MD5;
}
/**
* Implementation of eap_method_t.get_msk.
*/
static status_t get_msk(private_eap_md5_t *this, chunk_t *msk)
{
return FAILED;
}
/**
* Implementation of eap_method_t.is_mutual.
*/
static bool is_mutual(private_eap_md5_t *this)
{
return FALSE;
}
/**
* Implementation of eap_method_t.destroy.
*/
static void destroy(private_eap_md5_t *this)
{
chunk_free(&this->challenge);
free(this);
}
/*
* Described in header.
*/
eap_md5_t *eap_create(eap_role_t role,
identification_t *server, identification_t *peer)
{
private_eap_md5_t *this = malloc_thing(private_eap_md5_t);
/* public functions */
switch (role)
{
case EAP_SERVER:
this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_server;
this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_server;
break;
case EAP_PEER:
this->public.eap_method_interface.initiate = (status_t(*)(eap_method_t*,eap_payload_t**))initiate_peer;
this->public.eap_method_interface.process = (status_t(*)(eap_method_t*,eap_payload_t*,eap_payload_t**))process_peer;
break;
default:
free(this);
return NULL;
}
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;
/* private data */
this->peer = peer;
this->server = server;
this->challenge = chunk_empty;
this->identifier = random();
return &this->public;
}
@@ -1,59 +0,0 @@
/**
* @file eap_md5.h
*
* @brief Interface of eap_md5_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_MD5_H_
#define EAP_MD5_H_
typedef struct eap_md5_t eap_md5_t;
#include <sa/authenticators/eap/eap_method.h>
/**
* @brief Implementation of the eap_method_t interface using EAP-MD5 (CHAP).
*
* @b Constructors:
* - eap_md5_create()
* - eap_client_create() using eap_method EAP_MD5
*
* @ingroup eap
*/
struct eap_md5_t {
/**
* Implemented eap_method_t interface.
*/
eap_method_t eap_method_interface;
};
/**
* @brief Creates the EAP method EAP-MD5.
*
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_md5_t object
*
* @ingroup eap
*/
eap_md5_t *eap_create(eap_role_t role,
identification_t *server, identification_t *peer);
#endif /* EAP_MD5_H_ */
+2 -187
View File
@@ -1,10 +1,3 @@
/**
* @file eap_method.c
*
* @brief Generic constructor for eap_methods.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,22 +11,12 @@
* 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.
*
* $Id$
*/
#include <string.h>
#include <sys/stat.h>
#include <dirent.h>
#include <error.h>
#include <dlfcn.h>
#include "eap_method.h"
#include <daemon.h>
#include <library.h>
#include <utils/linked_list.h>
#include <utils/identification.h>
ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_TOKEN_CARD,
"EAP_IDENTITY",
"EAP_NOTIFICATION",
@@ -62,171 +45,3 @@ ENUM(eap_role_names, EAP_SERVER, EAP_PEER,
"EAP_PEER",
);
typedef struct module_entry_t module_entry_t;
/**
* Representation of a loaded module: EAP type, library handle, constructor
*/
struct module_entry_t {
eap_type_t type;
u_int32_t vendor;
void *handle;
eap_constructor_t constructor;
};
/** List of module_entry_t's */
static linked_list_t *modules = NULL;
/**
* unload modules at daemon shutdown
*/
void eap_method_unload()
{
if (modules)
{
module_entry_t *entry;
while (modules->remove_last(modules, (void**)&entry) == SUCCESS)
{
DBG2(DBG_CFG, "unloaded module EAP module %d-%d",
entry->type, entry->vendor);
dlclose(entry->handle);
free(entry);
}
modules->destroy(modules);
modules = NULL;
}
}
/**
* Load EAP modules at daemon startup
*/
void eap_method_load(char *directory)
{
struct dirent* entry;
DIR* dir;
eap_method_unload();
modules = linked_list_create();
dir = opendir(directory);
if (dir == NULL)
{
DBG1(DBG_CFG, "error opening EAP modules directory %s", directory);
return;
}
DBG1(DBG_CFG, "loading EAP modules from '%s'", directory);
while ((entry = readdir(dir)) != NULL)
{
char file[256];
module_entry_t module, *loaded_module;
eap_method_t *method;
identification_t *id;
char *ending;
snprintf(file, sizeof(file), "%s/%s", directory, entry->d_name);
ending = entry->d_name + strlen(entry->d_name) - 3;
if (ending <= entry->d_name || !streq(ending, ".so"))
{
/* skip anything which does not look like a library */
DBG2(DBG_CFG, " skipping %s, doesn't look like a library",
entry->d_name);
continue;
}
/* try to load the library */
module.handle = dlopen(file, RTLD_LAZY);
if (module.handle == NULL)
{
DBG1(DBG_CFG, " opening EAP module %s failed: %s", entry->d_name,
dlerror());
continue;
}
module.constructor = dlsym(module.handle, "eap_create");
if (module.constructor == NULL)
{
DBG1(DBG_CFG, " EAP module %s has no eap_create() function, skipped",
entry->d_name);
dlclose(module.handle);
continue;
}
/* get the type implemented in the method, create an instance for it */
id = identification_create_from_string("[email protected]");
method = module.constructor(EAP_SERVER, id, id);
if (method == NULL)
{
method = module.constructor(EAP_PEER, id, id);
}
id->destroy(id);
if (method == NULL)
{
DBG1(DBG_CFG, " unable to create instance of EAP method %s, skipped",
entry->d_name);
dlclose(module.handle);
continue;
}
module.type = method->get_type(method, &module.vendor);
method->destroy(method);
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));
modules->insert_last(modules, loaded_module);
}
closedir(dir);
}
/*
* Described in header.
*/
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;
module_entry_t *entry;
iterator = modules->create_iterator(modules, TRUE);
while (iterator->iterate(iterator, (void**)&entry))
{
if (entry->type == type && entry->vendor == vendor)
{
method = entry->constructor(role, server, peer);
if (method)
{
break;
}
}
}
iterator->destroy(iterator);
if (method == NULL)
{
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;
}
+21 -86
View File
@@ -1,10 +1,3 @@
/**
* @file eap_method.h
*
* @brief Interface eap_method_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup eap_method eap_method
* @{ @ingroup eap
*/
#ifndef EAP_METHOD_H_
@@ -34,8 +34,6 @@ typedef enum eap_code_t eap_code_t;
/**
* Role of an eap_method, SERVER or PEER (client)
*
* @ingroup eap
*/
enum eap_role_t {
EAP_SERVER,
@@ -43,15 +41,11 @@ enum eap_role_t {
};
/**
* enum names for eap_role_t.
*
* @ingroup eap
*/
extern enum_name_t *eap_role_names;
/**
* EAP types, defines the EAP method implementation
*
* @ingroup eap
*/
enum eap_type_t {
EAP_IDENTITY = 1,
@@ -68,15 +62,11 @@ enum eap_type_t {
/**
* enum names for eap_type_t.
*
* @ingroup eap
*/
extern enum_name_t *eap_type_names;
/**
* EAP code, type of an EAP message
*
* @ingroup eap
*/
enum eap_code_t {
EAP_REQUEST = 1,
@@ -87,14 +77,12 @@ enum eap_code_t {
/**
* enum names for eap_code_t.
*
* @ingroup eap
*/
extern enum_name_t *eap_code_names;
/**
* @brief Interface of an EAP method for server and client side.
* Interface of an EAP method for server and client side.
*
* An EAP method initiates an EAP exchange and processes requests and
* responses. An EAP method may need multiple exchanges before succeeding, and
@@ -107,22 +95,16 @@ 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.
*
* @b Constructors:
* - eap_method_create()
*
* @ingroup eap
*/
struct eap_method_t {
/**
* @brief Initiate the EAP exchange.
* Initiate the EAP exchange.
*
* initiate() is only useable for server implementations, as clients only
* reply to server requests.
* A eap_payload is created in "out" if result is NEED_MORE.
*
* @param this calling object
* @param out eap_payload to send to the client
* @return
* - NEED_MORE, if an other exchange is required
@@ -131,11 +113,10 @@ struct eap_method_t {
status_t (*initiate) (eap_method_t *this, eap_payload_t **out);
/**
* @brief Process a received EAP message.
* Process a received EAP message.
*
* A eap_payload is created in "out" if result is NEED_MORE.
*
* @param this calling object
* @param in eap_payload response received
* @param out created eap_payload to send
* @return
@@ -147,31 +128,28 @@ struct eap_method_t {
eap_payload_t **out);
/**
* @brief Get the EAP type implemented in this method.
* 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, u_int32_t *vendor);
/**
* @brief Check if this EAP method authenticates the server.
* Check if this EAP method authenticates the server.
*
* Some EAP methods provide mutual authentication and
* allow authentication using only EAP, if the peer supports it.
*
* @param this calling object
* @return TRUE if methods provides mutual authentication
*/
bool (*is_mutual) (eap_method_t *this);
/**
* @brief Get the MSK established by this EAP method.
* Get the MSK established by this EAP method.
*
* Not all EAP methods establish a shared secret.
*
* @param this calling object
* @param msk chunk receiving internal stored MSK
* @return
* - SUCCESS, or
@@ -180,68 +158,25 @@ struct eap_method_t {
status_t (*get_msk) (eap_method_t *this, chunk_t *msk);
/**
* @brief Destroys a eap_method_t object.
*
* @param this calling object
* Destroys a eap_method_t object.
*/
void (*destroy) (eap_method_t *this);
};
/**
* @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)
* @return eap_method_t object
*
* @ingroup eap
*/
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.
*
* For security reasons, the directory and all it's modules must be owned
* by root and must not be writeable by someone else.
*
* @param dir directory of the EAP modules
*
* @ingroup eap
*/
void eap_method_load(char *directory);
/**
* @brief Unload all loaded EAP modules
*
* @ingroup eap
*/
void eap_method_unload();
/**
* @brief Constructor definition for a pluggable EAP module.
* Constructor definition for a pluggable EAP method.
*
* Each EAP module must define a constructor function which will return
* an initialized object with the methods defined in eap_method_t. The
* constructor must be named eap_create() and it's signature must be equal
* to that of eap_constructor_t.
* A module may implement only a single role. If it does not support the role
* requested, NULL should be returned. Multiple modules are allowed of the
* same EAP type to support seperate implementations of peer/server.
* an initialized object with the methods defined in 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.
*
* @param role role the module will play, peer or server
* @param server ID of the server to use for credential lookup
* @param peer ID of the peer to use for credential lookup
* @return implementation of the eap_method_t interface
*
* @ingroup eap
*/
typedef eap_method_t *(*eap_constructor_t)(eap_role_t role,
identification_t *server,
typedef eap_method_t *(*eap_constructor_t)(identification_t *server,
identification_t *peer);
#endif /* EAP_METHOD_H_ */
#endif /* EAP_METHOD_H_ @} */
File diff suppressed because it is too large Load Diff
-114
View File
@@ -1,114 +0,0 @@
/**
* @file eap_sim.h
*
* @brief Interface of eap_sim_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_SIM_H_
#define EAP_SIM_H_
typedef struct eap_sim_t eap_sim_t;
#include <sa/authenticators/eap/eap_method.h>
/** the library containing with the triplet functions */
#ifndef SIM_READER_LIB
#error SIM_READER_LIB not specified, use --with-sim-reader option
#endif /* SIM_READER_LIB */
/**
* @brief Cardreaders SIM function.
*
* @param rand RAND to run algo with
* @param rand_length length of value in rand
* @param sres buffer to get SRES
* @param sres_length size of buffer in sres, returns bytes written to SRES
* @param kc buffer to get Kc
* @param kc_length size of buffer in Kc, returns bytes written to Kc
* @return zero on success
*/
typedef int (*sim_algo_t)(const unsigned char *rand, int rand_length,
unsigned char *sres, int *sres_length,
unsigned char *kc, int *kc_length);
#ifndef SIM_READER_ALG
/** the SIM_READER_LIB's algorithm, uses sim_algo_t signature */
#define SIM_READER_ALG "sim_run_alg"
#endif /* SIM_READER_ALG */
/**
* @brief Function to get a SIM triplet.
*
* @param identity identity (imsi) to get a triplet for
* @param rand buffer to get RAND
* @param rand_length size of buffer in rand, returns bytes written to RAND
* @param sres buffer to get SRES
* @param sres_length size of buffer in sres, returns bytes written to SRES
* @param kc buffer to get Kc
* @param kc_length size of buffer in Kc, returns bytes written to Kc
* @return zero on success
*/
typedef int (*sim_get_triplet_t)(char *identity,
unsigned char *rand, int *rand_length,
unsigned char *sres, int *sres_length,
unsigned char *kc, int *kc_length);
#ifndef SIM_READER_GET_TRIPLET
/** the SIM_READER_LIB's get-triplet function, uses sim_get_triplet_t signature */
#define SIM_READER_GET_TRIPLET "sim_get_triplet"
#endif /* SIM_READER_GET_TRIPLET */
/**
* @brief Implementation of the eap_method_t interface using EAP-SIM.
*
* This EAP-SIM client implementation uses another pluggable library to
* access the SIM card/triplet provider. This module is specified using the
* SIM_READER_LIB definition. It has to privde a sim_run_alg() function to
* calculate a triplet (client), and/or a sim_get_triplet() function to get
* a triplet (server). These functions are named to the SIM_READER_ALG and
* the SIM_READER_GET_TRIPLET definitions.
*
* @b Constructors:
* - eap_create() of this module
* - eap_client_create() using eap_method EAP_SIM
*
* @ingroup eap
*/
struct eap_sim_t {
/**
* Implemented eap_method_t interface.
*/
eap_method_t eap_method_interface;
};
/**
* @brief Creates the EAP method EAP-SIM.
*
* @param role role of the module, client/server
* @param server ID of the EAP server
* @param peer ID of the EAP client
* @return eap_sim_t object
*
* @ingroup eap
*/
eap_sim_t *eap_create(eap_role_t role,
identification_t *server, identification_t *peer);
#endif /* EAP_SIM_H_ */
@@ -1,288 +0,0 @@
/**
* @file eap_sim.h
*
* @brief Interface of eap_sim_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 <string.h>
#include <stdio.h>
#include <errno.h>
#include <daemon.h>
#define IMSI_LEN 64
#define RAND_LEN 16
#define SRES_LEN 4
#define KC_LEN 8
typedef struct triplet_t triplet_t;
struct triplet_t {
unsigned char imsi[IMSI_LEN];
unsigned char rand[RAND_LEN];
unsigned char sres[SRES_LEN];
unsigned char kc[KC_LEN];
};
static triplet_t *triplets = NULL;
static int triplet_count = 0;
#define TRIPLET_FILE IPSEC_CONFDIR "/ipsec.d/triplets.dat"
/**
* convert a single HEX char to its integer value
*/
static int hexchr(char chr)
{
switch (chr)
{
case '0'...'9':
return chr - '0';
case 'A'...'F':
return 10 + chr - 'A';
case 'a'...'f':
return 10 + chr - 'a';
}
return 0;
}
/**
* convert a HEX string into a char array bin, limited by array length len
*/
static void hex2bin(char *hex, unsigned char *bin, size_t len)
{
char *pos;
int i, even = 1;
pos = hex - 1;
/* find the end, as we convert bottom up */
while (TRUE)
{
switch (*(pos+1))
{
case '0'...'9':
case 'A'...'F':
case 'a'...'f':
pos++;
continue;
}
break;
}
/* convert two hex chars into a single bin byte */
for (i = 0; pos >= hex && i < len; pos--)
{
if (even)
{
bin[len - 1 - i] = hexchr(*pos);
}
else
{
bin[len - 1 - i] |= 16 * hexchr(*pos);
i++;
}
even = !even;
}
}
/**
* free up allocated triplets
*/
static void __attribute__ ((destructor)) free_triplets()
{
free(triplets);
}
/**
* read the triplets from the file, using freeradius triplet file syntax:
* http://www.freeradius.org/radiusd/doc/rlm_sim_triplets
*/
static void __attribute__ ((constructor)) read_triplets()
{
char line[512], *data[4], *pos;
FILE *file;
int i, nr = 0;
triplet_t *triplet;
file = fopen(TRIPLET_FILE, "r");
if (file == NULL)
{
DBG1(DBG_CFG, "opening triplet file %s failed: %s",
TRIPLET_FILE, strerror(errno));
return;
}
if (triplets)
{
free(triplets);
triplets = NULL;
triplet_count = 0;
}
/* read line by line */
while (fgets(line, sizeof(line), file))
{
nr++;
/* skip comments, empty lines */
switch (line[0])
{
case '\n':
case '\r':
case '#':
case '\0':
continue;
default:
break;
}
/* read comma separated values */
pos = line;
for (i = 0; i < 4; i++)
{
data[i] = pos;
pos = strchr(pos, ',');
if (pos)
{
*pos = '\0';
pos++;
}
else if (i != 3)
{
DBG1(DBG_CFG, "error in triplet file, line %d", nr);
fclose(file);
return;
}
}
/* allocate new triplet */
triplet_count++;
triplets = realloc(triplets, triplet_count * sizeof(triplet_t));
triplet = &triplets[triplet_count - 1];
memset(triplet, 0, sizeof(triplet_t));
/* convert/copy triplet data */
for (i = 0; i < IMSI_LEN - 1; i++)
{
switch (data[0][i])
{
case '\n':
case '\r':
case '\0':
break;
default:
triplet->imsi[i] = data[0][i];
continue;
}
break;
}
hex2bin(data[1], triplet->rand, RAND_LEN);
hex2bin(data[2], triplet->sres, SRES_LEN);
hex2bin(data[3], triplet->kc, KC_LEN);
DBG4(DBG_CFG, "triplet: imsi %b\nrand %b\nsres %b\nkc %b",
triplet->imsi, IMSI_LEN, triplet->rand, RAND_LEN,
triplet->sres, SRES_LEN, triplet->kc, KC_LEN);
}
fclose(file);
DBG2(DBG_CFG, "read %d triplets from %s", triplet_count, TRIPLET_FILE);
}
/**
* Run the sim algorithm, see eap_sim.h
*/
int sim_run_alg(const unsigned char *rand, int rand_length,
unsigned char *sres, int *sres_length,
unsigned char *kc, int *kc_length)
{
int current;
if (rand_length != RAND_LEN ||
*sres_length < SRES_LEN ||
*kc_length < KC_LEN)
{
return 1;
}
for (current = 0; current < triplet_count; current++)
{
if (memcmp(triplets[current].rand, rand, RAND_LEN) == 0)
{
memcpy(sres, triplets[current].sres, SRES_LEN);
memcpy(kc, triplets[current].kc, KC_LEN);
*sres_length = SRES_LEN;
*kc_length = KC_LEN;
return 0;
}
}
return 2;
}
/**
* Get a single triplet, see_eap_sim.h
*/
int sim_get_triplet(char *imsi,
unsigned char *rand, int *rand_length,
unsigned char *sres, int *sres_length,
unsigned char *kc, int *kc_length)
{
int current;
triplet_t *triplet;
static int skip = -1;
DBG2(DBG_CFG, "getting triplet for %s", imsi);
if (*rand_length < RAND_LEN ||
*sres_length < SRES_LEN ||
*kc_length < KC_LEN)
{
return 1;
}
if (triplet_count == 0)
{
return 2;
}
for (current = 0; current < triplet_count; current++)
{
triplet = &triplets[current];
if (streq(imsi, triplet->imsi))
{
/* skip triplet if already used */
if (skip >= current)
{
continue;
}
*rand_length = RAND_LEN;
*sres_length = SRES_LEN;
*kc_length = KC_LEN;
memcpy(rand, triplet->rand, RAND_LEN);
memcpy(sres, triplet->sres, SRES_LEN);
memcpy(kc, triplet->kc, KC_LEN);
/* remember used triplet */
skip = current;
return 0;
}
}
if (skip > -1)
{
/* no triplet left, reuse triplets */
skip = -1;
return sim_get_triplet(imsi, rand, rand_length,
sres, sres_length, kc, kc_length);
}
return 2;
}
@@ -1,10 +1,3 @@
/**
* @file eap_authenticator.c
*
* @brief Implementation of eap_authenticator_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include <string.h>
@@ -160,9 +155,9 @@ static status_t initiate(private_eap_authenticator_t *this, eap_type_t type,
{
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));
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));
if (this->method == NULL)
{
@@ -195,9 +190,11 @@ static status_t process_peer(private_eap_authenticator_t *this,
if (!vendor && type == EAP_IDENTITY)
{
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));
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));
if (method == NULL || method->process(method, in, out) != SUCCESS)
{
@@ -227,9 +224,10 @@ static status_t process_peer(private_eap_authenticator_t *this,
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));
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));
if (this->method == NULL)
{
DBG1(DBG_IKE, "EAP server requested unsupported "
@@ -1,10 +1,3 @@
/**
* @file eap_authenticator.h
*
* @brief Interface of eap_authenticator_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup eap_authenticator eap_authenticator
* @{ @ingroup authenticators
*/
#ifndef EAP_AUTHENTICATOR_H_
@@ -29,7 +29,7 @@ typedef struct eap_authenticator_t eap_authenticator_t;
#include <encoding/payloads/eap_payload.h>
/**
* @brief Implementation of the authenticator_t interface using AUTH_EAP.
* Implementation of the authenticator_t interface using AUTH_EAP.
*
* Authentication using EAP involves the most complex authenticator. It stays
* alive over multiple ike_auth transactions and handles multiple EAP
@@ -68,11 +68,6 @@ typedef struct eap_authenticator_t eap_authenticator_t;
+--------+ +--------+
@endverbatim
* @b Constructors:
* - eap_authenticator_create()
* - authenticator_create() using auth_method AUTH_EAP
*
* @ingroup authenticators
*/
struct eap_authenticator_t {
@@ -82,7 +77,7 @@ struct eap_authenticator_t {
authenticator_t authenticator_interface;
/**
* @brief Check if the EAP method was/is mutual and secure.
* Check if the EAP method was/is mutual and secure.
*
* RFC4306 proposes to authenticate the EAP responder (server) by standard
* IKEv2 methods (RSA, psk). Not all, but some EAP methods
@@ -93,19 +88,17 @@ struct eap_authenticator_t {
* AUTH payload, the client must verify that the server initiated mutual
* EAP authentication before it can trust the server.
*
* @param this calling object
* @return TRUE, if no AUTH payload required, FALSE otherwise
*/
bool (*is_mutual) (eap_authenticator_t* this);
/**
* @brief Initiate the EAP exchange.
* Initiate the EAP exchange.
*
* The server initiates EAP exchanges, so the client never calls
* 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 vendor EAP vendor identifier, if type is vendor specific, or 0
* @param out created initiaal EAP message to send
@@ -117,7 +110,7 @@ struct eap_authenticator_t {
u_int32_t vendor, eap_payload_t **out);
/**
* @brief Process an EAP message.
* Process an EAP message.
*
* After receiving an EAP message "in", the peer/server processes
* the payload and creates a reply/subsequent request.
@@ -132,7 +125,6 @@ struct eap_authenticator_t {
* If a SUCCESS is returned (on any side), the EAP authentication was
* successful and the AUTH payload can be exchanged.
*
* @param this calling object
* @param in received EAP message
* @param out created EAP message to send
* @return
@@ -145,13 +137,11 @@ struct eap_authenticator_t {
};
/**
* @brief Creates an authenticator for AUTH_EAP.
* Creates an authenticator for AUTH_EAP.
*
* @param ike_sa associated ike_sa
* @return eap_authenticator_t object
*
* @ingroup authenticators
*/
eap_authenticator_t *eap_authenticator_create(ike_sa_t *ike_sa);
#endif /* EAP_AUTHENTICATOR_H_ */
#endif /* EAP_AUTHENTICATOR_H_ @} */
@@ -1,10 +1,3 @@
/**
* @file psk_authenticator.c
*
* @brief Implementation of psk_authenticator_t.
*
*/
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include <string.h>
@@ -26,6 +21,7 @@
#include "psk_authenticator.h"
#include <daemon.h>
#include <credentials/auth_info.h>
/**
* Key pad for the AUTH method SHARED_KEY_MESSAGE_INTEGRITY_CODE.
@@ -105,39 +101,49 @@ chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce,
* Implementation of authenticator_t.verify.
*/
static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
chunk_t my_nonce, auth_payload_t *auth_payload)
chunk_t my_nonce, auth_payload_t *auth_payload)
{
status_t status;
chunk_t auth_data, recv_auth_data, shared_key;
chunk_t auth_data, recv_auth_data;
identification_t *my_id, *other_id;
shared_key_t *shared_key;
enumerator_t *enumerator;
bool authenticated = FALSE;
int keys_found = 0;
my_id = this->ike_sa->get_my_id(this->ike_sa);
other_id = this->ike_sa->get_other_id(this->ike_sa);
status = charon->credentials->get_shared_key(charon->credentials, my_id,
other_id, &shared_key);
if (status != SUCCESS)
enumerator = charon->credentials->create_shared_enumerator(
charon->credentials, SHARED_IKE, my_id, other_id);
while (!authenticated && enumerator->enumerate(enumerator, &shared_key, NULL, NULL))
{
DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
return status;
}
auth_data = build_shared_key_signature(ike_sa_init, my_nonce, shared_key,
other_id, this->ike_sa->get_skp_verify(this->ike_sa),
this->ike_sa->get_prf(this->ike_sa));
chunk_free_randomized(&shared_key);
recv_auth_data = auth_payload->get_data(auth_payload);
if (auth_data.len != recv_auth_data.len ||
!memeq(auth_data.ptr, recv_auth_data.ptr, auth_data.len))
{
DBG1(DBG_IKE, "PSK MAC verification failed");
keys_found++;
auth_data = build_shared_key_signature(ike_sa_init, my_nonce,
shared_key->get_key(shared_key), other_id,
this->ike_sa->get_skp_verify(this->ike_sa),
this->ike_sa->get_prf(this->ike_sa));
recv_auth_data = auth_payload->get_data(auth_payload);
if (auth_data.len == recv_auth_data.len &&
memeq(auth_data.ptr, recv_auth_data.ptr, auth_data.len))
{
DBG1(DBG_IKE, "authentication of '%D' with %N successful",
other_id, auth_method_names, AUTH_PSK);
authenticated = TRUE;
}
chunk_free(&auth_data);
}
enumerator->destroy(enumerator);
if (!authenticated)
{
if (keys_found == 0)
{
DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
return NOT_FOUND;
}
DBG1(DBG_IKE, "tried %d shared key%s for '%D' - '%D', but MAC mismatched",
keys_found, keys_found == 1 ? "" : "s", my_id, other_id);
return FAILED;
}
chunk_free(&auth_data);
DBG1(DBG_IKE, "authentication of '%D' with %N successful",
other_id, auth_method_names, AUTH_PSK);
return SUCCESS;
}
@@ -147,28 +153,27 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init,
chunk_t other_nonce, auth_payload_t **auth_payload)
{
chunk_t shared_key;
shared_key_t *shared_key;
chunk_t auth_data;
status_t status;
identification_t *my_id, *other_id;
my_id = this->ike_sa->get_my_id(this->ike_sa);
other_id = this->ike_sa->get_other_id(this->ike_sa);
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
my_id, auth_method_names, AUTH_PSK);
status = charon->credentials->get_shared_key(charon->credentials, my_id,
other_id, &shared_key);
if (status != SUCCESS)
shared_key = charon->credentials->get_shared(charon->credentials, SHARED_IKE,
my_id, other_id);
if (shared_key == NULL)
{
DBG1(DBG_IKE, "no shared key found for '%D' - '%D'", my_id, other_id);
return status;
return NOT_FOUND;
}
auth_data = build_shared_key_signature(ike_sa_init, other_nonce, shared_key,
my_id, this->ike_sa->get_skp_build(this->ike_sa),
this->ike_sa->get_prf(this->ike_sa));
auth_data = build_shared_key_signature(ike_sa_init, other_nonce,
shared_key->get_key(shared_key), my_id,
this->ike_sa->get_skp_build(this->ike_sa),
this->ike_sa->get_prf(this->ike_sa));
shared_key->destroy(shared_key);
DBG2(DBG_IKE, "successfully created shared key MAC");
chunk_free_randomized(&shared_key);
*auth_payload = auth_payload_create();
(*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
(*auth_payload)->set_data(*auth_payload, auth_data);
@@ -1,10 +1,3 @@
/**
* @file psk_authenticator.h
*
* @brief Interface of psk_authenticator_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup psk_authenticator psk_authenticator
* @{ @ingroup authenticators
*/
#ifndef PSK_AUTHENTICATOR_H_
@@ -28,13 +28,7 @@ typedef struct psk_authenticator_t psk_authenticator_t;
#include <sa/authenticators/authenticator.h>
/**
* @brief Implementation of the authenticator_t interface using AUTH_PSK.
*
* @b Constructors:
* - psk_authenticator_create()
* - authenticator_create() using auth_method AUTH_PSK
*
* @ingroup authenticators
* Implementation of the authenticator_t interface using AUTH_PSK.
*/
struct psk_authenticator_t {
@@ -45,13 +39,11 @@ struct psk_authenticator_t {
};
/**
* @brief Creates an authenticator for AUTH_PSK.
* Creates an authenticator for AUTH_PSK.
*
* @param ike_sa associated ike_sa
* @return psk_authenticator_t object
*
* @ingroup authenticators
*/
psk_authenticator_t *psk_authenticator_create(ike_sa_t *ike_sa);
#endif /* PSK_AUTHENTICATOR_H_ */
#endif /* PSK_AUTHENTICATOR_H_ @} */
@@ -1,10 +1,3 @@
/**
* @file rsa_authenticator.c
*
* @brief Implementation of rsa_authenticator_t.
*
*/
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include <string.h>
@@ -26,6 +21,7 @@
#include "rsa_authenticator.h"
#include <daemon.h>
#include <credentials/auth_info.h>
typedef struct private_rsa_authenticator_t private_rsa_authenticator_t;
@@ -58,11 +54,12 @@ extern chunk_t build_tbs_octets(chunk_t ike_sa_init, chunk_t nonce,
static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
chunk_t my_nonce, auth_payload_t *auth_payload)
{
status_t status;
public_key_t *public;
chunk_t auth_data, octets;
identification_t *other_id;
ca_info_t *issuer;
prf_t *prf;
auth_info_t *auth;
status_t status = FAILED;
other_id = this->ike_sa->get_other_id(this->ike_sa);
@@ -74,16 +71,27 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
prf = this->ike_sa->get_prf(this->ike_sa);
prf->set_key(prf, this->ike_sa->get_skp_verify(this->ike_sa));
octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, prf);
status = charon->credentials->verify_signature(charon->credentials,
octets, auth_data, other_id, &issuer);
chunk_free(&octets);
if (status == SUCCESS)
auth = this->ike_sa->get_other_auth(this->ike_sa);
public = charon->credentials->get_public(charon->credentials, KEY_RSA,
other_id, auth);
if (public)
{
this->ike_sa->set_other_ca(this->ike_sa, issuer);
DBG1(DBG_IKE, "authentication of '%D' with %N successful",
other_id, auth_method_names, AUTH_RSA);
/* We are currently fixed to SHA1 hashes.
* TODO: allow other hash algorithms and note it in "auth" */
if (public->verify(public, SIGN_RSA_EMSA_PKCS1_SHA1, octets, auth_data))
{
DBG1(DBG_IKE, "authentication of %D with %N successful",
other_id, auth_method_names, AUTH_RSA);
status = SUCCESS;
}
public->destroy(public);
}
else
{
DBG1(DBG_IKE, "no trusted public key found for %D", other_id);
}
chunk_free(&octets);
return status;
}
@@ -94,43 +102,47 @@ static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
chunk_t other_nonce, auth_payload_t **auth_payload)
{
chunk_t octets, auth_data;
status_t status;
rsa_public_key_t *my_pubkey;
status_t status = FAILED;
private_key_t *private;
identification_t *my_id;
prf_t *prf;
auth_info_t *auth;
my_id = this->ike_sa->get_my_id(this->ike_sa);
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
DBG1(DBG_IKE, "authentication of %D (myself) with %N",
my_id, auth_method_names, AUTH_RSA);
DBG2(DBG_IKE, "looking for RSA public key belonging to '%D'...", my_id);
my_pubkey = charon->credentials->get_rsa_public_key(charon->credentials, my_id);
if (my_pubkey == NULL)
auth = this->ike_sa->get_my_auth(this->ike_sa);
private = charon->credentials->get_private(charon->credentials, KEY_RSA,
my_id, auth);
if (private == NULL)
{
DBG1(DBG_IKE, "no RSA public key found for '%D'", my_id);
DBG1(DBG_IKE, "no RSA private key found for %D", my_id);
return NOT_FOUND;
}
DBG2(DBG_IKE, " matching RSA public key found");
prf = this->ike_sa->get_prf(this->ike_sa);
prf->set_key(prf, this->ike_sa->get_skp_build(this->ike_sa));
octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, prf);
status = charon->credentials->rsa_signature(charon->credentials,
my_pubkey, HASH_SHA1, octets, &auth_data);
chunk_free(&octets);
if (status != SUCCESS)
/* we currently use always SHA1 for signatures,
* TODO: support other hashes depending on configuration/auth */
if (private->sign(private, SIGN_RSA_EMSA_PKCS1_SHA1, octets, &auth_data))
{
DBG1(DBG_IKE, "building RSA signature with SHA-1 hash failed");
return status;
auth_payload_t *payload = auth_payload_create();
payload->set_auth_method(payload, AUTH_RSA);
payload->set_data(payload, auth_data);
*auth_payload = payload;
chunk_free(&auth_data);
status = SUCCESS;
DBG2(DBG_IKE, "successfully signed with RSA private key");
}
DBG2(DBG_IKE, "successfully signed with RSA private key");
else
{
DBG1(DBG_IKE, "building RSA signature failed");
}
chunk_free(&octets);
private->destroy(private);
*auth_payload = auth_payload_create();
(*auth_payload)->set_auth_method(*auth_payload, AUTH_RSA);
(*auth_payload)->set_data(*auth_payload, auth_data);
chunk_free(&auth_data);
return SUCCESS;
return status;
}
/**
@@ -1,10 +1,3 @@
/**
* @file rsa_authenticator.h
*
* @brief Interface of rsa_authenticator_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup rsa_authenticator rsa_authenticator
* @{ @ingroup authenticators
*/
#ifndef RSA_AUTHENTICATOR_H_
@@ -28,13 +28,7 @@ typedef struct rsa_authenticator_t rsa_authenticator_t;
#include <sa/authenticators/authenticator.h>
/**
* @brief Implementation of the authenticator_t interface using AUTH_RSA.
*
* @b Constructors:
* - rsa_authenticator_create()
* - authenticator_create() using auth_method AUTH_RSA
*
* @ingroup authenticators
* Implementation of the authenticator_t interface using AUTH_RSA.
*/
struct rsa_authenticator_t {
@@ -45,13 +39,11 @@ struct rsa_authenticator_t {
};
/**
* @brief Creates an authenticator for AUTH_RSA.
* Creates an authenticator for AUTH_RSA.
*
* @param ike_sa associated ike_sa
* @return rsa_authenticator_t object
*
* @ingroup authenticators
*/
rsa_authenticator_t *rsa_authenticator_create(ike_sa_t *ike_sa);
#endif /* RSA_AUTHENTICATOR_H_ */
#endif /* RSA_AUTHENTICATOR_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file child_sa.c
*
* @brief Implementation of child_sa_t.
*
*/
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
@@ -20,6 +13,8 @@
* 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.
*
* $Id$
*/
#define _GNU_SOURCE
+29 -55
View File
@@ -1,10 +1,3 @@
/**
* @file child_sa.h
*
* @brief Interface of child_sa_t.
*
*/
/*
* Copyright (C) 2006-2007 Martin Willi
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
@@ -19,8 +12,14 @@
* 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.
*
* $Id$
*/
/**
* @defgroup child_sa child_sa
* @{ @ingroup sa
*/
#ifndef CHILD_SA_H_
#define CHILD_SA_H_
@@ -35,7 +34,7 @@ typedef struct child_sa_t child_sa_t;
#include <config/child_cfg.h>
/**
* @brief States of a CHILD_SA
* States of a CHILD_SA
*/
enum child_sa_state_t {
@@ -71,7 +70,7 @@ enum child_sa_state_t {
extern enum_name_t *child_sa_state_names;
/**
* @brief Represents an IPsec SAs between two hosts.
* Represents an IPsec SAs between two hosts.
*
* A child_sa_t contains two SAs. SAs for both
* directions are managed in one child_sa_t object. Both
@@ -86,57 +85,47 @@ extern enum_name_t *child_sa_state_names;
* - A calls child_sa_t.update to update the already allocated SPIs with the chosen proposal
*
* Once SAs are set up, policies can be added using add_policies.
*
*
* @b Constructors:
* - child_sa_create()
*
* @ingroup sa
*/
struct child_sa_t {
/**
* @brief Get the name of the config this CHILD_SA uses.
* Get the name of the config this CHILD_SA uses.
*
* @param this calling object
* @return name
* @return name
*/
char* (*get_name) (child_sa_t *this);
/**
* @brief Get the reqid of the CHILD SA.
* Get the reqid of the CHILD SA.
*
* Every CHILD_SA has a reqid. The kernel uses this ID to
* identify it.
*
* @param this calling object
* @return reqid of the CHILD SA
*/
u_int32_t (*get_reqid)(child_sa_t *this);
/**
* @brief Get the SPI of this CHILD_SA.
* Get the SPI of this CHILD_SA.
*
* Set the boolean parameter inbound to TRUE to
* get the SPI for which we receive packets, use
* FALSE to get those we use for sending packets.
*
* @param this calling object
* @param inbound TRUE to get inbound SPI, FALSE for outbound.
* @return spi of the CHILD SA
*/
u_int32_t (*get_spi) (child_sa_t *this, bool inbound);
/**
* @brief Get the protocol which this CHILD_SA uses to protect traffic.
* Get the protocol which this CHILD_SA uses to protect traffic.
*
* @param this calling object
* @return AH | ESP
*/
protocol_id_t (*get_protocol) (child_sa_t *this);
/**
* @brief Get info and statistics about this CHILD_SA.
* Get info and statistics about this CHILD_SA.
*
* @param mode mode this IKE_SA uses
* @param encr_algo encryption algorithm used by this CHILD_SA.
@@ -155,7 +144,7 @@ struct child_sa_t {
u_int32_t *use_fwd);
/**
* @brief Allocate SPIs for given proposals.
* Allocate SPIs for given proposals.
*
* Since the kernel manages SPIs for us, we need
* to allocate them. If a proposal contains more
@@ -163,15 +152,13 @@ struct child_sa_t {
* allocated. SPIs are stored internally and written
* back to the proposal.
*
* @param this calling object
* @param proposals list of proposals for which SPIs are allocated
*/
status_t (*alloc)(child_sa_t *this, linked_list_t* proposals);
/**
* @brief Install the kernel SAs for a proposal, without previous SPI allocation.
* Install the kernel SAs for a proposal, without previous SPI allocation.
*
* @param this calling object
* @param proposal proposal for which SPIs are allocated
* @param mode mode for the CHILD_SA
* @param prf_plus key material to use for key derivation
@@ -181,11 +168,10 @@ struct child_sa_t {
prf_plus_t *prf_plus);
/**
* @brief Install the kernel SAs for a proposal, after SPIs have been allocated.
* Install the kernel SAs for a proposal, after SPIs have been allocated.
*
* Updates an SA, for which SPIs are already allocated via alloc().
*
* @param this calling object
* @param proposal proposal for which SPIs are allocated
* @param mode mode for the CHILD_SA
* @param prf_plus key material to use for key derivation
@@ -195,11 +181,10 @@ struct child_sa_t {
prf_plus_t *prf_plus);
/**
* @brief Update the hosts in the kernel SAs and policies.
* Update the hosts in the kernel SAs and policies.
*
* The CHILD must be INSTALLED to do this update.
*
* @param this calling object
* @param me the new local host
* @param other the new remote host
* @param TRUE to use UDP encapsulation for NAT traversal
@@ -209,12 +194,11 @@ struct child_sa_t {
bool encap);
/**
* @brief Install the policies using some traffic selectors.
* Install the policies using some traffic selectors.
*
* Supplied lists of traffic_selector_t's specify the policies
* to use for this child sa.
*
* @param this calling object
* @param my_ts traffic selectors for local site
* @param other_ts traffic selectors for remote site
* @param mode mode for the SA: tunnel/transport
@@ -224,18 +208,16 @@ struct child_sa_t {
linked_list_t *other_ts_list, mode_t mode);
/**
* @brief Get the traffic selectors of added policies of local host.
* Get the traffic selectors of added policies of local host.
*
* @param this calling object
* @param local TRUE for own traffic selectors, FALSE for remote
* @return list of traffic selectors
*/
linked_list_t* (*get_traffic_selectors) (child_sa_t *this, bool local);
/**
* @brief Get the time of this child_sa_t's last use (i.e. last use of any of its policies)
* Get the time of this child_sa_t's last use (i.e. last use of any of its policies)
*
* @param this calling object
* @param inbound query for in- or outbound usage
* @param use_time the time
* @return SUCCESS or FAILED
@@ -243,48 +225,42 @@ struct child_sa_t {
status_t (*get_use_time) (child_sa_t *this, bool inbound, time_t *use_time);
/**
* @brief Get the state of the CHILD_SA.
*
* @param this calling object
* Get the state of the CHILD_SA.
*/
child_sa_state_t (*get_state) (child_sa_t *this);
/**
* @brief Set the state of the CHILD_SA.
* Set the state of the CHILD_SA.
*
* @param this calling object
* @param state state to set on CHILD_SA
*/
void (*set_state) (child_sa_t *this, child_sa_state_t state);
/**
* @brief Get the config used to set up this child sa.
* Get the config used to set up this child sa.
*
* @param this calling object
* @return child_cfg
*/
child_cfg_t* (*get_config) (child_sa_t *this);
/**
* @brief Set the virtual IP used received from IRAS.
* Set the virtual IP used received from IRAS.
*
* To allow proper setup of firewall rules, the virtual IP is required
* for filtering.
*
* @param this calling object
* @param ip own virtual IP
*/
void (*set_virtual_ip) (child_sa_t *this, host_t *ip);
/**
* @brief Destroys a child_sa.
*
* @param this calling object
* Destroys a child_sa.
*/
void (*destroy) (child_sa_t *this);
};
/**
* @brief Constructor to create a new child_sa_t.
* Constructor to create a new child_sa_t.
*
* @param me own address
* @param other remote address
@@ -294,11 +270,9 @@ struct child_sa_t {
* @param reqid reqid of old CHILD_SA when rekeying, 0 otherwise
* @param encap TRUE to enable UDP encapsulation (NAT traversal)
* @return child_sa_t object
*
* @ingroup sa
*/
child_sa_t * child_sa_create(host_t *me, host_t *other,
identification_t *my_id, identification_t* other_id,
child_cfg_t *config, u_int32_t reqid, bool encap);
#endif /*CHILD_SA_H_*/
#endif /*CHILD_SA_H_ @} */
+10 -8
View File
@@ -1,10 +1,3 @@
/**
* @file connect_manager.c
*
* @brief Implementation of connect_manager_t.
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include "connect_manager.h"
@@ -1516,7 +1511,14 @@ connect_manager_t *connect_manager_create()
this->public.set_responder_data = (status_t(*)(connect_manager_t*,chunk_t,chunk_t,linked_list_t*))set_responder_data;
this->public.process_check = (void(*)(connect_manager_t*,message_t*))process_check;
this->hasher = hasher_create(HASH_SHA1);
this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
if (hasher == NULL)
{
DBG1(DBG_IKE, "unable to create connect manager, SHA1 not supported");
free(this);
return NULL;
}
this->checklists = linked_list_create();
this->initiated = linked_list_create();
+17 -32
View File
@@ -1,10 +1,3 @@
/**
* @file connect_manager.h
*
* @brief Interface of connect_manager_t.
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup connect_manager connect_manager
* @{ @ingroup sa
*/
#ifndef CONNECT_MANAGER_H_
@@ -31,21 +31,15 @@ typedef struct connect_manager_t connect_manager_t;
#include <utils/identification.h>
/**
* @brief The connection manager is responsible for establishing a direct
* The connection manager is responsible for establishing a direct
* connection with another peer.
*
* @b Constructors:
* - connect_manager_create()
*
* @ingroup sa
*/
struct connect_manager_t {
/**
* @brief Checks if a there is already a mediated connection registered
* Checks if a there is already a mediated connection registered
* between two peers.
*
* @param this the manager object
* @param id my id
* @param peer_id the other peer's id
* @param mediated_sa the IKE_SA ID of the mediated connection
@@ -59,10 +53,9 @@ struct connect_manager_t {
ike_sa_id_t *mediated_sa, child_cfg_t *child);
/**
* @brief Checks if there are waiting connections with a specific peer.
* Checks if there are waiting connections with a specific peer.
* If so, reinitiate them.
*
* @param this the manager object
* @param id my id
* @param peer_id the other peer's id
*/
@@ -70,9 +63,8 @@ struct connect_manager_t {
identification_t *id, identification_t *peer_id);
/**
* @brief Creates a checklist and sets the initiator's data.
* Creates a checklist and sets the initiator's data.
*
* @param this the manager object
* @param initiator ID of the initiator
* @param responder ID of the responder
* @param session_id the session ID provided by the initiator
@@ -80,18 +72,16 @@ struct connect_manager_t {
* @param endpoints the initiator's endpoints
* @param is_initiator TRUE, if the caller of this method is the initiator
* FALSE, otherwise
* @returns
* SUCCESS
* @returns SUCCESS
*/
status_t (*set_initiator_data) (connect_manager_t *this,
identification_t *initiator, identification_t *responder,
chunk_t session_id, chunk_t key, linked_list_t *endpoints, bool is_initiator);
/**
* @brief Updates a checklist and sets the responder's data. The checklist's
* Updates a checklist and sets the responder's data. The checklist's
* state is advanced to WAITING which means that checks will be sent.
*
* @param this the manager object
* @param session_id the session ID
* @param chunk_t the responder's key
* @param endpoints the responder's endpoints
@@ -104,28 +94,23 @@ struct connect_manager_t {
/**
* @brief Processes a connectivity check
* Processes a connectivity check
*
* @param this the manager object
* @param message the received message
*/
void (*process_check) (connect_manager_t *this, message_t *message);
/**
* @brief Destroys the manager with all data.
*
* @param this the manager object
* Destroys the manager with all data.
*/
void (*destroy) (connect_manager_t *this);
};
/**
* @brief Create a manager.
* Create a manager.
*
* @returns connect_manager_t object
*
* @ingroup sa
*/
connect_manager_t *connect_manager_create(void);
#endif /*CONNECT_MANAGER_H_*/
#endif /*CONNECT_MANAGER_H_ @} */
+71 -51
View File
@@ -1,10 +1,3 @@
/**
* @file ike_sa.c
*
* @brief Implementation of ike_sa_t.
*
*/
/*
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
@@ -21,6 +14,8 @@
* 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.
*
* $Id$
*/
#include <sys/time.h>
@@ -53,7 +48,8 @@
#include <sa/tasks/ike_auth.h>
#include <sa/tasks/ike_auth_lifetime.h>
#include <sa/tasks/ike_config.h>
#include <sa/tasks/ike_cert.h>
#include <sa/tasks/ike_cert_pre.h>
#include <sa/tasks/ike_cert_post.h>
#include <sa/tasks/ike_rekey.h>
#include <sa/tasks/ike_reauth.h>
#include <sa/tasks/ike_delete.h>
@@ -121,6 +117,16 @@ struct private_ike_sa_t {
*/
peer_cfg_t *peer_cfg;
/**
* associated authentication/authorization info for local peer
*/
auth_info_t *my_auth;
/**
* associated authentication/authorization info for remote peer
*/
auth_info_t *other_auth;
/**
* Juggles tasks to process messages
*/
@@ -153,11 +159,6 @@ struct private_ike_sa_t {
*/
identification_t *other_id;
/**
* CA that issued the certificate of other
*/
ca_info_t *other_ca;
/**
* set of extensions the peer supports
*/
@@ -425,6 +426,22 @@ static void set_peer_cfg(private_ike_sa_t *this, peer_cfg_t *peer_cfg)
}
}
/**
* Implementation of ike_sa_t.get_my_auth.
*/
static auth_info_t* get_my_auth(private_ike_sa_t *this)
{
return this->my_auth;
}
/**
* Implementation of ike_sa_t.get_other_auth.
*/
static auth_info_t* get_other_auth(private_ike_sa_t *this)
{
return this->other_auth;
}
/**
* Implementation of ike_sa_t.send_keepalive
*/
@@ -1020,10 +1037,12 @@ static status_t initiate(private_ike_sa_t *this, child_cfg_t *child_cfg)
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_natd_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_cert_create(&this->public, TRUE);
task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_auth_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_cert_post_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_config_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
@@ -1112,10 +1131,12 @@ static status_t acquire(private_ike_sa_t *this, u_int32_t reqid)
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_natd_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_cert_create(&this->public, TRUE);
task = (task_t*)ike_cert_pre_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_auth_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_cert_post_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_config_create(&this->public, TRUE);
this->task_manager->queue_task(this->task_manager, task);
task = (task_t*)ike_auth_lifetime_create(&this->public, TRUE);
@@ -1502,12 +1523,14 @@ static status_t retransmit(private_ike_sa_t *this, u_int32_t message_id)
new->task_manager->queue_task(new->task_manager, task);
task = (task_t*)ike_natd_create(&new->public, TRUE);
new->task_manager->queue_task(new->task_manager, task);
task = (task_t*)ike_cert_create(&new->public, TRUE);
task = (task_t*)ike_cert_pre_create(&new->public, TRUE);
new->task_manager->queue_task(new->task_manager, task);
task = (task_t*)ike_config_create(&new->public, TRUE);
new->task_manager->queue_task(new->task_manager, task);
task = (task_t*)ike_auth_create(&new->public, TRUE);
new->task_manager->queue_task(new->task_manager, task);
task = (task_t*)ike_cert_post_create(&new->public, TRUE);
new->task_manager->queue_task(new->task_manager, task);
while (to_restart->remove_last(to_restart, (void**)&child_cfg) == SUCCESS)
{
@@ -1606,22 +1629,6 @@ static void set_other_id(private_ike_sa_t *this, identification_t *other)
this->other_id = other;
}
/**
* Implementation of ike_sa_t.get_other_ca.
*/
static ca_info_t* get_other_ca(private_ike_sa_t *this)
{
return this->other_ca;
}
/**
* Implementation of ike_sa_t.set_other_ca.
*/
static void set_other_ca(private_ike_sa_t *this, ca_info_t *other_ca)
{
this->other_ca = other_ca;
}
/**
* Implementation of ike_sa_t.derive_keys.
*/
@@ -1643,14 +1650,16 @@ static status_t derive_keys(private_ike_sa_t *this,
/* Create SAs general purpose PRF first, we may use it here */
if (!proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo))
{
DBG1(DBG_IKE, "key derivation failed: no PSEUDO_RANDOM_FUNCTION");;
DBG1(DBG_IKE, "no %N selected",
transform_type_names, PSEUDO_RANDOM_FUNCTION);
return FAILED;
}
this->prf = prf_create(algo->algorithm);
this->prf = lib->crypto->create_prf(lib->crypto, algo->algorithm);
if (this->prf == NULL)
{
DBG1(DBG_IKE, "key derivation failed: PSEUDO_RANDOM_FUNCTION "
"%N not supported!", pseudo_random_function_names, algo->algorithm);
DBG1(DBG_IKE, "%N %N not supported!",
transform_type_names, PSEUDO_RANDOM_FUNCTION,
pseudo_random_function_names, algo->algorithm);
return FAILED;
}
@@ -1694,7 +1703,7 @@ static status_t derive_keys(private_ike_sa_t *this,
/* SK_d is used for generating CHILD_SA key mat => child_prf */
proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo);
this->child_prf = prf_create(algo->algorithm);
this->child_prf = lib->crypto->create_prf(lib->crypto, algo->algorithm);
key_size = this->child_prf->get_key_size(this->child_prf);
prf_plus->allocate_bytes(prf_plus, key_size, &key);
DBG4(DBG_IKE, "Sk_d secret %B", &key);
@@ -1704,15 +1713,18 @@ static status_t derive_keys(private_ike_sa_t *this,
/* SK_ai/SK_ar used for integrity protection => signer_in/signer_out */
if (!proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &algo))
{
DBG1(DBG_IKE, "key derivation failed: no INTEGRITY_ALGORITHM");
DBG1(DBG_IKE, "no %N selected",
transform_type_names, INTEGRITY_ALGORITHM);
return FAILED;
}
signer_i = signer_create(algo->algorithm);
signer_r = signer_create(algo->algorithm);
signer_i = lib->crypto->create_signer(lib->crypto, algo->algorithm);
signer_r = lib->crypto->create_signer(lib->crypto, algo->algorithm);
if (signer_i == NULL || signer_r == NULL)
{
DBG1(DBG_IKE, "key derivation failed: INTEGRITY_ALGORITHM "
"%N not supported!", integrity_algorithm_names ,algo->algorithm);
DBG1(DBG_IKE, "%N %N not supported!",
transform_type_names, INTEGRITY_ALGORITHM,
integrity_algorithm_names ,algo->algorithm);
prf_plus->destroy(prf_plus);
return FAILED;
}
key_size = signer_i->get_key_size(signer_i);
@@ -1741,16 +1753,21 @@ static status_t derive_keys(private_ike_sa_t *this,
/* SK_ei/SK_er used for encryption => crypter_in/crypter_out */
if (!proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &algo))
{
DBG1(DBG_IKE, "key derivation failed: no ENCRYPTION_ALGORITHM");
DBG1(DBG_IKE, "no %N selected",
transform_type_names, ENCRYPTION_ALGORITHM);
prf_plus->destroy(prf_plus);
return FAILED;
}
crypter_i = crypter_create(algo->algorithm, algo->key_size / 8);
crypter_r = crypter_create(algo->algorithm, algo->key_size / 8);
crypter_i = lib->crypto->create_crypter(lib->crypto, algo->algorithm,
algo->key_size / 8);
crypter_r = lib->crypto->create_crypter(lib->crypto, algo->algorithm,
algo->key_size / 8);
if (crypter_i == NULL || crypter_r == NULL)
{
DBG1(DBG_IKE, "key derivation failed: ENCRYPTION_ALGORITHM "
"%N (key size %d) not supported!",
encryption_algorithm_names, algo->algorithm, algo->key_size);
DBG1(DBG_IKE, "%N %N (key size %d) not supported!",
transform_type_names, ENCRYPTION_ALGORITHM,
encryption_algorithm_names, algo->algorithm, algo->key_size);
prf_plus->destroy(prf_plus);
return FAILED;
}
key_size = crypter_i->get_key_size(crypter_i);
@@ -2309,6 +2326,8 @@ static void destroy(private_ike_sa_t *this)
DESTROY_IF(this->ike_cfg);
DESTROY_IF(this->peer_cfg);
DESTROY_IF(this->my_auth);
DESTROY_IF(this->other_auth);
this->ike_sa_id->destroy(this->ike_sa_id);
this->task_manager->destroy(this->task_manager);
@@ -2337,6 +2356,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.set_ike_cfg = (void (*)(ike_sa_t*,ike_cfg_t*))set_ike_cfg;
this->public.get_peer_cfg = (peer_cfg_t* (*)(ike_sa_t*))get_peer_cfg;
this->public.set_peer_cfg = (void (*)(ike_sa_t*,peer_cfg_t*))set_peer_cfg;
this->public.get_my_auth = (auth_info_t*(*)(ike_sa_t*))get_my_auth;
this->public.get_other_auth = (auth_info_t*(*)(ike_sa_t*))get_other_auth;
this->public.get_id = (ike_sa_id_t* (*)(ike_sa_t*)) get_id;
this->public.get_my_host = (host_t* (*)(ike_sa_t*)) get_my_host;
this->public.set_my_host = (void (*)(ike_sa_t*,host_t*)) set_my_host;
@@ -2347,8 +2368,6 @@ 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_other_ca = (ca_info_t* (*)(ike_sa_t*)) get_other_ca;
this->public.set_other_ca = (void (*)(ike_sa_t*,ca_info_t*)) set_other_ca;
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;
@@ -2401,7 +2420,6 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->other_host = host_create_any(AF_INET);
this->my_id = identification_create_from_encoding(ID_ANY, chunk_empty);
this->other_id = identification_create_from_encoding(ID_ANY, chunk_empty);
this->other_ca = NULL;
this->extensions = 0;
this->conditions = 0;
this->crypter_in = NULL;
@@ -2420,6 +2438,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->time.delete = 0;
this->ike_cfg = NULL;
this->peer_cfg = NULL;
this->my_auth = auth_info_create();
this->other_auth = auth_info_create();
this->task_manager = task_manager_create(&this->public);
this->unique_id = ++unique_id;
this->my_virtual_ip = NULL;
+112 -191
View File
@@ -1,10 +1,3 @@
/**
* @file ike_sa.h
*
* @brief Interface of ike_sa_t.
*
*/
/*
* Copyright (C) 2006-2007 Tobias Brunner
* Copyright (C) 2006 Daniel Roethlisberger
@@ -21,6 +14,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_sa ike_sa
* @{ @ingroup sa
*/
#ifndef IKE_SA_H_
@@ -42,40 +42,32 @@ typedef struct ike_sa_t ike_sa_t;
#include <crypto/prfs/prf.h>
#include <crypto/crypters/crypter.h>
#include <crypto/signers/signer.h>
#include <crypto/ca.h>
#include <config/peer_cfg.h>
#include <config/ike_cfg.h>
#include <credentials/auth_info.h>
/**
* Timeout in milliseconds after that a half open IKE_SA gets deleted.
*
* @ingroup sa
*/
#define HALF_OPEN_IKE_SA_TIMEOUT 30000
/**
* Interval to send keepalives when NATed, in seconds.
*
* @ingroup sa
*/
#define KEEPALIVE_INTERVAL 20
/**
* After which time rekeying should be retried if it failed, in seconds.
*
* @ingroup sa
*/
#define RETRY_INTERVAL 30
/**
* Jitter to subtract from RETRY_INTERVAL to randomize rekey retry.
*
* @ingroup sa
*/
#define RETRY_JITTER 20
/**
* @brief Extensions (or optional features) the peer supports
* Extensions (or optional features) the peer supports
*/
enum ike_extension_t {
@@ -91,7 +83,7 @@ enum ike_extension_t {
};
/**
* @brief Conditions of an IKE_SA, change during its lifetime
* Conditions of an IKE_SA, change during its lifetime
*/
enum ike_condition_t {
@@ -119,6 +111,11 @@ enum ike_condition_t {
* peer has ben authenticated using EAP
*/
COND_EAP_AUTHENTICATED = (1<<4),
/**
* received a certificate request from the peer
*/
COND_CERTREQ_SEEN = (1<<4),
};
/**
@@ -138,7 +135,7 @@ enum statistic_t {
};
/**
* @brief State of an IKE_SA.
* State of an IKE_SA.
*
* An IKE_SA passes various states in its lifetime. A newly created
* SA is in the state CREATED.
@@ -173,8 +170,6 @@ enum statistic_t {
X
/ \
@endverbatim
*
* @ingroup sa
*/
enum ike_sa_state_t {
@@ -210,365 +205,323 @@ enum ike_sa_state_t {
extern enum_name_t *ike_sa_state_names;
/**
* @brief Class ike_sa_t representing an IKE_SA.
* Class ike_sa_t representing an IKE_SA.
*
* An IKE_SA contains crypto information related to a connection
* with a peer. It contains multiple IPsec CHILD_SA, for which
* it is responsible. All traffic is handled by an IKE_SA, using
* the task manager and its tasks.
*
* @b Constructors:
* - ike_sa_create()
*
* @ingroup sa
*/
struct ike_sa_t {
/**
* @brief Get the id of the SA.
* Get the id of the SA.
*
* Returned ike_sa_id_t object is not getting cloned!
*
* @param this calling object
* @return ike_sa's ike_sa_id_t
*/
ike_sa_id_t* (*get_id) (ike_sa_t *this);
/**
* @brief Get the numerical ID uniquely defining this IKE_SA.
* Get the numerical ID uniquely defining this IKE_SA.
*
* @param this calling object
* @return unique ID
*/
u_int32_t (*get_unique_id) (ike_sa_t *this);
/**
* @brief Get the state of the IKE_SA.
* Get the state of the IKE_SA.
*
* @param this calling object
* @return state of the IKE_SA
*/
ike_sa_state_t (*get_state) (ike_sa_t *this);
/**
* @brief Set the state of the IKE_SA.
* Set the state of the IKE_SA.
*
* @param this calling object
* @param state state to set for the IKE_SA
*/
void (*set_state) (ike_sa_t *this, ike_sa_state_t ike_sa);
/**
* @brief Get the name of the connection this IKE_SA uses.
* Get the name of the connection this IKE_SA uses.
*
* @param this calling object
* @return name
*/
char* (*get_name) (ike_sa_t *this);
/**
* @brief Get statistic values from the IKE_SA.
* Get statistic values from the IKE_SA.
*
* @param this calling object
* @param kind kind of requested value
* @return value as integer
*/
u_int32_t (*get_statistic)(ike_sa_t *this, statistic_t kind);
/**
* @brief Get the own host address.
* Get the own host address.
*
* @param this calling object
* @return host address
*/
host_t* (*get_my_host) (ike_sa_t *this);
/**
* @brief Set the own host address.
* Set the own host address.
*
* @param this calling object
* @param me host address
*/
void (*set_my_host) (ike_sa_t *this, host_t *me);
/**
* @brief Get the other peers host address.
* Get the other peers host address.
*
* @param this calling object
* @return host address
*/
host_t* (*get_other_host) (ike_sa_t *this);
/**
* @brief Set the others host address.
* Set the others host address.
*
* @param this calling object
* @param other host address
*/
void (*set_other_host) (ike_sa_t *this, host_t *other);
/**
* @brief Update the IKE_SAs host.
* Update the IKE_SAs host.
*
* Hosts may be NULL to use current host.
*
* @param this calling object
* @param me new local host address, or NULL
* @param other new remote host address, or NULL
*/
void (*update_hosts)(ike_sa_t *this, host_t *me, host_t *other);
/**
* @brief Get the own identification.
* Get the own identification.
*
* @param this calling object
* @return identification
*/
identification_t* (*get_my_id) (ike_sa_t *this);
/**
* @brief Set the own identification.
* Set the own identification.
*
* @param this calling object
* @param me identification
*/
void (*set_my_id) (ike_sa_t *this, identification_t *me);
/**
* @brief Get the other peer's identification.
* Get the other peer's identification.
*
* @param this calling object
* @return identification
*/
identification_t* (*get_other_id) (ike_sa_t *this);
/**
* @brief Set the other peer's identification.
* Set the other peer's identification.
*
* @param this calling object
* @param other identification
*/
void (*set_other_id) (ike_sa_t *this, identification_t *other);
/**
* @brief Get the other peer's certification authority
* Get the config used to setup this IKE_SA.
*
* @param this calling object
* @return ca_info_t record of other ca
*/
ca_info_t* (*get_other_ca) (ike_sa_t *this);
/**
* @brief Set the other peer's certification authority
*
* @param this calling object
* @param other_ca ca_info_t record of other ca
*/
void (*set_other_ca) (ike_sa_t *this, ca_info_t *other_ca);
/**
* @brief Get the config used to setup this IKE_SA.
*
* @param this calling object
* @return ike_config
*/
ike_cfg_t* (*get_ike_cfg) (ike_sa_t *this);
/**
* @brief Set the config to setup this IKE_SA.
* Set the config to setup this IKE_SA.
*
* @param this calling object
* @param config ike_config to use
*/
void (*set_ike_cfg) (ike_sa_t *this, ike_cfg_t* config);
/**
* @brief Get the peer config used by this IKE_SA.
* Get the peer config used by this IKE_SA.
*
* @param this calling object
* @return peer_config
*/
peer_cfg_t* (*get_peer_cfg) (ike_sa_t *this);
/**
* @brief Set the peer config to use with this IKE_SA.
* Set the peer config to use with this IKE_SA.
*
* @param this calling object
* @param config peer_config to use
*/
void (*set_peer_cfg) (ike_sa_t *this, peer_cfg_t *config);
/**
* @brief Add an additional address for the peer.
* Get authentication/authorization info for local peer.
*
* @return auth_info for me
*/
auth_info_t* (*get_my_auth)(ike_sa_t *this);
/**
* Get authentication/authorization info for remote peer.
*
* @return auth_info for me
*/
auth_info_t* (*get_other_auth)(ike_sa_t *this);
/**
* Add an additional address for the peer.
*
* In MOBIKE, a peer may transmit additional addresses where it is
* reachable. These are stored in the IKE_SA.
* The own list of addresses is not stored, they are queried from
* the kernel when required.
*
* @param this calling object
* @param host host to add to list
*/
void (*add_additional_address)(ike_sa_t *this, host_t *host);
/**
* @brief Create an iterator over all additional addresses of the peer.
* Create an iterator over all additional addresses of the peer.
*
* @param this calling object
* @return iterator over addresses
*/
iterator_t* (*create_additional_address_iterator)(ike_sa_t *this);
/**
* @brief Enable an extension the peer supports.
* Enable an extension the peer supports.
*
* If support for an IKE extension is detected, this method is called
* to enable that extension and behave accordingly.
*
* @param this calling object
* @param extension extension to enable
*/
void (*enable_extension)(ike_sa_t *this, ike_extension_t extension);
/**
* @brief Check if the peer supports an extension.
* Check if the peer supports an extension.
*
* @param this calling object
* @param extension extension to check for support
* @return TRUE if peer supports it, FALSE otherwise
*/
bool (*supports_extension)(ike_sa_t *this, ike_extension_t extension);
/**
* @brief Enable/disable a condition flag for this IKE_SA.
* Enable/disable a condition flag for this IKE_SA.
*
* @param this calling object
* @param condition condition to enable/disable
* @param enable TRUE to enable condition, FALSE to disable
*/
void (*set_condition) (ike_sa_t *this, ike_condition_t condition, bool enable);
/**
* @brief Check if a condition flag is set.
* Check if a condition flag is set.
*
* @param this calling object
* @param condition condition to check
* @return TRUE if condition flag set, FALSE otherwise
*/
bool (*has_condition) (ike_sa_t *this, ike_condition_t condition);
/**
* @brief Get the number of queued MOBIKE address updates.
* Get the number of queued MOBIKE address updates.
*
* @param this calling object
* @return number of pending updates
*/
u_int32_t (*get_pending_updates)(ike_sa_t *this);
/**
* @brief Set the number of queued MOBIKE address updates.
* Set the number of queued MOBIKE address updates.
*
* @param this calling object
* @param updates number of pending updates
*/
void (*set_pending_updates)(ike_sa_t *this, u_int32_t updates);
#ifdef P2P
/**
* @brief Get the server reflexive host.
* Get the server reflexive host.
*
* @param this calling object
* @return server reflexive host
*/
host_t* (*get_server_reflexive_host) (ike_sa_t *this);
/**
* @brief Set the server reflexive host.
* Set the server reflexive host.
*
* @param this calling object
* @param host server reflexive host
*/
void (*set_server_reflexive_host) (ike_sa_t *this, host_t *host);
/**
* @brief Initiate the mediation of a mediated connection (i.e. initiate a
* Initiate the mediation of a mediated connection (i.e. initiate a
* P2P_CONNECT exchange).
*
* @param this calling object
* @param mediated_cfg peer_cfg of the mediated connection
* @return
* - SUCCESS if initialization started
* - DESTROY_ME if initialization failed
* - SUCCESS if initialization started
* - DESTROY_ME if initialization failed
*/
status_t (*initiate_mediation) (ike_sa_t *this, peer_cfg_t *mediated_cfg);
/**
* @brief Initiate the mediated connection
* Initiate the mediated connection
*
* @param this calling object
* @param me local endpoint (gets cloned)
* @param other remote endpoint (gets cloned)
* @param childs linked list of child_cfg_t of CHILD_SAs (gets cloned)
* @return
* - SUCCESS if initialization started
* - DESTROY_ME if initialization failed
* - SUCCESS if initialization started
* - DESTROY_ME if initialization failed
*/
status_t (*initiate_mediated) (ike_sa_t *this, host_t *me, host_t *other,
linked_list_t *childs);
/**
* @brief Relay data from one peer to another (i.e. initiate a
* Relay data from one peer to another (i.e. initiate a
* P2P_CONNECT exchange).
*
* Data is cloned.
*
* @param this calling object
* @param requester ID of the requesting peer
* @param session_id data of the P2P_SESSIONID payload
* @param session_key data of the P2P_SESSIONKEY payload
* @param endpoints endpoints
* @param response TRUE if this is a response
* @return
* - SUCCESS if relay started
* - DESTROY_ME if relay failed
* - SUCCESS if relay started
* - DESTROY_ME if relay failed
*/
status_t (*relay) (ike_sa_t *this, identification_t *requester, chunk_t session_id,
chunk_t session_key, linked_list_t *endpoints, bool response);
/**
* @brief Send a callback to a peer.
* Send a callback to a peer.
*
* Data is cloned.
*
* @param this calling object
* @param peer_id ID of the other peer
* @return
* - SUCCESS if response started
* - DESTROY_ME if response failed
* - SUCCESS if response started
* - DESTROY_ME if response failed
*/
status_t (*callback) (ike_sa_t *this, identification_t *peer_id);
/**
* @brief Respond to a P2P_CONNECT request.
* Respond to a P2P_CONNECT request.
*
* Data is cloned.
*
* @param this calling object
* @param peer_id ID of the other peer
* @param session_id the session ID supplied by the initiator
* @return
* - SUCCESS if response started
* - DESTROY_ME if response failed
* - SUCCESS if response started
* - DESTROY_ME if response failed
*/
status_t (*respond) (ike_sa_t *this, identification_t *peer_id, chunk_t session_id);
#endif /* P2P */
/**
* @brief Initiate a new connection.
* Initiate a new connection.
*
* The configs are owned by the IKE_SA after the call.
*
* @param this calling object
* @param child_cfg child config to create CHILD from
* @return
* - SUCCESS if initialization started
@@ -577,12 +530,11 @@ struct ike_sa_t {
status_t (*initiate) (ike_sa_t *this, child_cfg_t *child_cfg);
/**
* @brief Route a policy in the kernel.
* Route a policy in the kernel.
*
* Installs the policies in the kernel. If traffic matches,
* the kernel requests connection setup from the IKE_SA via acquire().
*
* @param this calling object
* @param child_cfg child config to route
* @return
* - SUCCESS if routed successfully
@@ -591,9 +543,8 @@ struct ike_sa_t {
status_t (*route) (ike_sa_t *this, child_cfg_t *child_cfg);
/**
* @brief Unroute a policy in the kernel previously routed.
* Unroute a policy in the kernel previously routed.
*
* @param this calling object
* @param reqid reqid of CHILD_SA to unroute
* @return
* - SUCCESS if route removed
@@ -603,12 +554,11 @@ struct ike_sa_t {
status_t (*unroute) (ike_sa_t *this, u_int32_t reqid);
/**
* @brief Acquire connection setup for an installed kernel policy.
* Acquire connection setup for an installed kernel policy.
*
* If an installed policy raises an acquire, the kernel calls
* this function to establish the CHILD_SA (and maybe the IKE_SA).
*
* @param this calling object
* @param reqid reqid of the CHILD_SA the policy belongs to.
* @return
* - SUCCESS if initialization started
@@ -617,13 +567,12 @@ struct ike_sa_t {
status_t (*acquire) (ike_sa_t *this, u_int32_t reqid);
/**
* @brief Initiates the deletion of an IKE_SA.
* Initiates the deletion of an IKE_SA.
*
* Sends a delete message to the remote peer and waits for
* its response. If the response comes in, or a timeout occurs,
* the IKE SA gets deleted.
*
* @param this calling object
* @return
* - SUCCESS if deletion is initialized
* - INVALID_STATE, if the IKE_SA is not in
@@ -633,7 +582,7 @@ struct ike_sa_t {
status_t (*delete) (ike_sa_t *this);
/**
* @brief Update IKE_SAs after network interfaces have changed.
* Update IKE_SAs after network interfaces have changed.
*
* Whenever the network interface configuration changes, the kernel
* interface calls roam() on each IKE_SA. The IKE_SA then checks if
@@ -641,21 +590,19 @@ struct ike_sa_t {
* If MOBIKE is supported, addresses are updated; If not, the tunnel is
* restarted.
*
* @param this calling object
* @param address TRUE if address list changed, FALSE otherwise
* @return SUCCESS, FAILED, DESTROY_ME
*/
status_t (*roam)(ike_sa_t *this, bool address);
/**
* @brief Processes a incoming IKEv2-Message.
* Processes a incoming IKEv2-Message.
*
* Message processing may fail. If a critical failure occurs,
* process_message() return DESTROY_ME. Then the caller must
* destroy the IKE_SA immediatly, as it is unusable.
*
* @param this calling object
* @param message message to process
* @param message message to process
* @return
* - SUCCESS
* - FAILED
@@ -664,12 +611,11 @@ struct ike_sa_t {
status_t (*process_message) (ike_sa_t *this, message_t *message);
/**
* @brief Generate a IKE message to send it to the peer.
* Generate a IKE message to send it to the peer.
*
* This method generates all payloads in the message and encrypts/signs
* the packet.
*
* @param this calling object
* @param message message to generate
* @param packet generated output packet
* @return
@@ -681,9 +627,8 @@ struct ike_sa_t {
packet_t **packet);
/**
* @brief Retransmits a request.
* Retransmits a request.
*
* @param this calling object
* @param message_id ID of the request to retransmit
* @return
* - SUCCESS
@@ -692,13 +637,12 @@ struct ike_sa_t {
status_t (*retransmit) (ike_sa_t *this, u_int32_t message_id);
/**
* @brief Sends a DPD request to the peer.
* Sends a DPD request to the peer.
*
* To check if a peer is still alive, periodic
* empty INFORMATIONAL messages are sent if no
* other traffic was received.
*
* @param this calling object
* @return
* - SUCCESS
* - DESTROY_ME, if peer did not respond
@@ -706,19 +650,17 @@ struct ike_sa_t {
status_t (*send_dpd) (ike_sa_t *this);
/**
* @brief Sends a keep alive packet.
* Sends a keep alive packet.
*
* To refresh NAT tables in a NAT router
* between the peers, periodic empty
* UDP packets are sent if no other traffic
* was sent.
*
* @param this calling object
*/
void (*send_keepalive) (ike_sa_t *this);
/**
* @brief Derive all keys and create the transforms for IKE communication.
* Derive all keys and create the transforms for IKE communication.
*
* Keys are derived using the diffie hellman secret, nonces and internal
* stored SPIs.
@@ -726,7 +668,6 @@ struct ike_sa_t {
* existing IKE_SA (rekeying). The SK_d key from the old IKE_SA
* is included in the derivation process.
*
* @param this calling object
* @param proposal proposal which contains algorithms to use
* @param secret secret derived from DH exchange, gets freed
* @param nonce_i initiators nonce
@@ -740,49 +681,43 @@ struct ike_sa_t {
bool initiator, prf_t *child_prf, prf_t *old_prf);
/**
* @brief Get a multi purpose prf for the negotiated PRF function.
* Get a multi purpose prf for the negotiated PRF function.
*
* @param this calling object
* @return pointer to prf_t object
*/
prf_t *(*get_prf) (ike_sa_t *this);
/**
* @brief Get the prf-object, which is used to derive keys for child SAs.
* Get the prf-object, which is used to derive keys for child SAs.
*
* @param this calling object
* @return pointer to prf_t object
*/
prf_t *(*get_child_prf) (ike_sa_t *this);
/**
* @brief Get the key to build outgoing authentication data.
* Get the key to build outgoing authentication data.
*
* @param this calling object
* @return pointer to prf_t object
*/
chunk_t (*get_skp_build) (ike_sa_t *this);
/**
* @brief Get the key to verify incoming authentication data.
* Get the key to verify incoming authentication data.
*
* @param this calling object
* @return pointer to prf_t object
*/
chunk_t (*get_skp_verify) (ike_sa_t *this);
/**
* @brief Associates a child SA to this IKE SA
* Associates a child SA to this IKE SA
*
* @param this calling object
* @param child_sa child_sa to add
*/
void (*add_child_sa) (ike_sa_t *this, child_sa_t *child_sa);
/**
* @brief Get a CHILD_SA identified by protocol and SPI.
* Get a CHILD_SA identified by protocol and SPI.
*
* @param this calling object
* @param protocol protocol of the SA
* @param spi SPI of the CHILD_SA
* @param inbound TRUE if SPI is inbound, FALSE if outbound
@@ -792,19 +727,17 @@ struct ike_sa_t {
u_int32_t spi, bool inbound);
/**
* @brief Create an iterator over all CHILD_SAs.
* Create an iterator over all CHILD_SAs.
*
* @param this calling object
* @return iterator
*/
iterator_t* (*create_child_sa_iterator) (ike_sa_t *this);
/**
* @brief Rekey the CHILD SA with the specified reqid.
* Rekey the CHILD SA with the specified reqid.
*
* Looks for a CHILD SA owned by this IKE_SA, and start the rekeing.
*
* @param this calling object
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
@@ -814,13 +747,12 @@ struct ike_sa_t {
status_t (*rekey_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
/**
* @brief Close the CHILD SA with the specified protocol/SPI.
* Close the CHILD SA with the specified protocol/SPI.
*
* Looks for a CHILD SA owned by this IKE_SA, deletes it and
* notify's the remote peer about the delete. The associated
* states and policies in the kernel get deleted, if they exist.
*
* @param this calling object
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
@@ -830,11 +762,10 @@ struct ike_sa_t {
status_t (*delete_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
/**
* @brief Destroy a CHILD SA with the specified protocol/SPI.
* Destroy a CHILD SA with the specified protocol/SPI.
*
* Looks for a CHILD SA owned by this IKE_SA and destroys it.
*
* @param this calling object
* @param protocol protocol of the SA
* @param spi inbound SPI of the CHILD_SA
* @return
@@ -844,99 +775,89 @@ struct ike_sa_t {
status_t (*destroy_child_sa) (ike_sa_t *this, protocol_id_t protocol, u_int32_t spi);
/**
* @brief Rekey the IKE_SA.
* Rekey the IKE_SA.
*
* Sets up a new IKE_SA, moves all CHILDs to it and deletes this IKE_SA.
*
* @param this calling object
* @return - SUCCESS, if IKE_SA rekeying initiated
*/
status_t (*rekey) (ike_sa_t *this);
/**
* @brief Restablish the IKE_SA.
* Restablish the IKE_SA.
*
* Create a completely new IKE_SA with authentication, recreates all children
* within the IKE_SA, closes this IKE_SA.
*
* @param this calling object
* @return DESTROY_ME to destroy the IKE_SA
*/
status_t (*reestablish) (ike_sa_t *this);
/**
* @brief Set the lifetime limit received from a AUTH_LIFETIME notify.
* Set the lifetime limit received from a AUTH_LIFETIME notify.
*
* @param this calling object
* @param lifetime lifetime in seconds
*/
void (*set_auth_lifetime)(ike_sa_t *this, u_int32_t lifetime);
/**
* @brief Set the virtual IP to use for this IKE_SA and its children.
* Set the virtual IP to use for this IKE_SA and its children.
*
* The virtual IP is assigned per IKE_SA, not per CHILD_SA. It has the same
* lifetime as the IKE_SA.
*
* @param this calling object
* @param local TRUE to set local address, FALSE for remote
* @param ip IP to set as virtual IP
*/
void (*set_virtual_ip) (ike_sa_t *this, bool local, host_t *ip);
/**
* @brief Get the virtual IP configured.
* Get the virtual IP configured.
*
* @param this calling object
* @param local TRUE to get local virtual IP, FALSE for remote
* @return host_t *virtual IP
*/
host_t* (*get_virtual_ip) (ike_sa_t *this, bool local);
/**
* @brief Add a DNS server to the system.
* Add a DNS server to the system.
*
* An IRAS may send a DNS server. To use it, it is installed on the
* system. The DNS entry has a lifetime until the IKE_SA gets closed.
*
* @param this calling object
* @param dns DNS server to install on the system
*/
void (*add_dns_server) (ike_sa_t *this, host_t *dns);
/**
* @brief Inherit all attributes of other to this after rekeying.
* Inherit all attributes of other to this after rekeying.
*
* When rekeying is completed, all CHILD_SAs, the virtual IP and all
* outstanding tasks are moved from other to this.
* As this call may initiate inherited tasks, a status is returned.
*
* @param this calling object
* @param other other task to inherit from
* @return DESTROY_ME if initiation of inherited task failed
*/
status_t (*inherit) (ike_sa_t *this, ike_sa_t *other);
/**
* @brief Reset the IKE_SA, useable when initiating fails
*
* @param this calling object
* Reset the IKE_SA, useable when initiating fails
*/
void (*reset) (ike_sa_t *this);
/**
* @brief Destroys a ike_sa_t object.
*
* @param this calling object
* Destroys a ike_sa_t object.
*/
void (*destroy) (ike_sa_t *this);
};
/**
* @brief Creates an ike_sa_t object with a specific ID.
* Creates an ike_sa_t object with a specific ID.
*
* @param ike_sa_id ike_sa_id_t object to associate with new IKE_SA
* @return ike_sa_t object
*
* @ingroup sa
*/
ike_sa_t *ike_sa_create(ike_sa_id_t *ike_sa_id);
#endif /* IKE_SA_H_ */
#endif /* IKE_SA_H_ @} */
+2 -8
View File
@@ -1,10 +1,3 @@
/**
* @file ike_sa_id.c
*
* @brief Implementation of ike_sa_id_t.
*
*/
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,9 +12,10 @@
* 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.
*
* $Id$
*/
#include "ike_sa_id.h"
#include <stdio.h>
+21 -40
View File
@@ -1,10 +1,3 @@
/**
* @file ike_sa_id.h
*
* @brief Interface of ike_sa_id_t.
*
*/
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,8 +12,14 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_sa_id ike_sa_id
* @{ @ingroup sa
*/
#ifndef IKE_SA_ID_H_
#define IKE_SA_ID_H_
@@ -29,119 +28,101 @@ typedef struct ike_sa_id_t ike_sa_id_t;
#include <library.h>
/**
* @brief An object of type ike_sa_id_t is used to identify an IKE_SA.
* An object of type ike_sa_id_t is used to identify an IKE_SA.
*
* An IKE_SA is identified by its initiator and responder spi's.
* Additionaly it contains the role of the actual running IKEv2-Daemon
* for the specific IKE_SA (original initiator or responder).
*
* @b Constructors:
* - ike_sa_id_create()
*
* @ingroup sa
*/
struct ike_sa_id_t {
/**
* @brief Set the SPI of the responder.
* Set the SPI of the responder.
*
* This function is called when a request or reply of a IKE_SA_INIT is received.
*
* @param this calling object
* @param responder_spi SPI of responder to set
*/
void (*set_responder_spi) (ike_sa_id_t *this, u_int64_t responder_spi);
/**
* @brief Set the SPI of the initiator.
* Set the SPI of the initiator.
*
* @param this calling object
* @param initiator_spi SPI to set
*/
void (*set_initiator_spi) (ike_sa_id_t *this, u_int64_t initiator_spi);
/**
* @brief Get the initiator SPI.
* Get the initiator SPI.
*
* @param this calling object
* @return SPI of the initiator
*/
u_int64_t (*get_initiator_spi) (ike_sa_id_t *this);
/**
* @brief Get the responder SPI.
* Get the responder SPI.
*
* @param this calling object
* @return SPI of the responder
*/
u_int64_t (*get_responder_spi) (ike_sa_id_t *this);
/**
* @brief Check if two ike_sa_id_t objects are equal.
* Check if two ike_sa_id_t objects are equal.
*
* Two ike_sa_id_t objects are equal if both SPI values and the role matches.
*
* @param this calling object
* @param other ike_sa_id_t object to check if equal
* @return TRUE if given ike_sa_id_t are equal, FALSE otherwise
*/
bool (*equals) (ike_sa_id_t *this, ike_sa_id_t *other);
/**
* @brief Replace all values of a given ike_sa_id_t object with values.
* Replace all values of a given ike_sa_id_t object with values.
* from another ike_sa_id_t object.
*
* After calling this function, both objects are equal.
*
* @param this calling object
* @param other ike_sa_id_t object from which values will be taken
*/
void (*replace_values) (ike_sa_id_t *this, ike_sa_id_t *other);
/**
* @brief Get the initiator flag.
* Get the initiator flag.
*
* @param this calling object
* @return TRUE if we are the original initator
*/
bool (*is_initiator) (ike_sa_id_t *this);
/**
* @brief Switche the original initiator flag.
* Switche the original initiator flag.
*
* @param this calling object
* @return TRUE if we are the original initator after switch, FALSE otherwise
*/
bool (*switch_initiator) (ike_sa_id_t *this);
/**
* @brief Clones a given ike_sa_id_t object.
* Clones a given ike_sa_id_t object.
*
* @param this calling object
* @return cloned ike_sa_id_t object
*/
ike_sa_id_t *(*clone) (ike_sa_id_t *this);
/**
* @brief Destroys an ike_sa_id_t object.
*
* @param this calling object
* Destroys an ike_sa_id_t object.
*/
void (*destroy) (ike_sa_id_t *this);
};
/**
* @brief Creates an ike_sa_id_t object with specific SPI's and defined role.
* Creates an ike_sa_id_t object with specific SPI's and defined role.
*
* @param initiator_spi initiators SPI
* @param responder_spi responders SPI
* @param is_initiaor TRUE if we are the original initiator
* @return ike_sa_id_t object
*
* @ingroup sa
*/
ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi, bool is_initiaor);
ike_sa_id_t * ike_sa_id_create(u_int64_t initiator_spi, u_int64_t responder_spi,
bool is_initiaor);
#endif /*IKE_SA_ID_H_*/
#endif /*IKE_SA_ID_H_ @} */
+12 -12
View File
@@ -1,10 +1,3 @@
/**
* @file ike_sa_manager.c
*
* @brief Implementation of ike_sa_mananger_t.
*
*/
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include <pthread.h>
@@ -30,6 +25,7 @@
#include <sa/ike_sa_id.h>
#include <bus/bus.h>
#include <utils/linked_list.h>
#include <crypto/hashers/hasher.h>
typedef struct entry_t entry_t;
@@ -508,7 +504,6 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
{
identification_t *found_my_id, *found_other_id;
host_t *found_my_host, *found_other_host;
int wc;
if (!wait_for_entry(this, entry))
{
@@ -541,8 +536,8 @@ static ike_sa_t* checkout_by_config(private_ike_sa_manager_t *this,
my_host->ip_equals(my_host, found_my_host)) &&
(other_host->is_anyaddr(other_host) ||
other_host->ip_equals(other_host, found_other_host)) &&
found_my_id->matches(found_my_id, my_id, &wc) &&
found_other_id->matches(found_other_id, other_id, &wc) &&
found_my_id->matches(found_my_id, my_id) &&
found_other_id->matches(found_other_id, other_id) &&
streq(peer_cfg->get_name(peer_cfg),
entry->ike_sa->get_name(entry->ike_sa)))
{
@@ -920,10 +915,15 @@ ike_sa_manager_t *ike_sa_manager_create()
this->public.get_half_open_count = (int(*)(ike_sa_manager_t*,host_t*))get_half_open_count;
/* initialize private variables */
this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_PREFERRED);
if (this->hasher == NULL)
{
DBG1(DBG_MGR, "manager initialization failed, no hasher supported");
free(this);
return NULL;
}
this->ike_sa_list = linked_list_create();
pthread_mutex_init(&this->mutex, NULL);
this->randomizer = randomizer_create();
this->hasher = hasher_create(HASH_SHA1);
return &this->public;
}
+22 -41
View File
@@ -1,10 +1,3 @@
/**
* @file ike_sa_manager.h
*
* @brief Interface of ike_sa_manager_t.
*
*/
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_sa_manager ike_sa_manager
* @{ @ingroup sa
*/
#ifndef IKE_SA_MANAGER_H_
@@ -32,7 +32,7 @@ typedef struct ike_sa_manager_t ike_sa_manager_t;
#include <config/peer_cfg.h>
/**
* @brief The IKE_SA-Manager is responsible for managing all initiated and responded IKE_SA's.
* The IKE_SA-Manager is responsible for managing all initiated and responded IKE_SA's.
*
* To avoid access from multiple threads, IKE_SAs must be checked out from
* the manager, and checked in after usage.
@@ -42,18 +42,12 @@ typedef struct ike_sa_manager_t ike_sa_manager_t;
* This could be done by comparing thread-ids via pthread_self()...
*
* @todo Managing of ike_sa_t objects in a hash table instead of linked list.
*
* @b Constructors:
* - ike_sa_manager_create()
*
* @ingroup sa
*/
struct ike_sa_manager_t {
/**
* @brief Checkout an existing IKE_SA.
* Checkout an existing IKE_SA.
*
* @param this the manager object
* @param ike_sa_id the SA identifier, will be updated
* @returns
* - checked out IKE_SA if found
@@ -62,16 +56,15 @@ struct ike_sa_manager_t {
ike_sa_t* (*checkout) (ike_sa_manager_t* this, ike_sa_id_t *sa_id);
/**
* @brief Create and check out a new IKE_SA.
* Create and check out a new IKE_SA.
*
* @param this the manager object
* @param initiator TRUE for initiator, FALSE otherwise
* @returns created andchecked out IKE_SA
*/
ike_sa_t* (*checkout_new) (ike_sa_manager_t* this, bool initiator);
/**
* @brief Checkout an IKE_SA by a message.
* Checkout an IKE_SA by a message.
*
* In some situations, it is necessary that the manager knows the
* message to use for the checkout. This has the folloing reasons:
@@ -86,7 +79,6 @@ struct ike_sa_manager_t {
* If processing the message does not make sense (for the reasons above),
* NULL is returned.
*
* @param this the manager object
* @param ike_sa_id the SA identifier, will be updated
* @returns
* - checked out/created IKE_SA
@@ -95,7 +87,7 @@ struct ike_sa_manager_t {
ike_sa_t* (*checkout_by_message) (ike_sa_manager_t* this, message_t *message);
/**
* @brief Checkout an IKE_SA for initiation by a peer_config.
* Checkout an IKE_SA for initiation by a peer_config.
*
* To initiate, a CHILD_SA may be established within an existing IKE_SA.
* This call checks for an existing IKE_SA by comparing the configuration.
@@ -104,7 +96,6 @@ struct ike_sa_manager_t {
* If no IKE_SA is found, a new one is created. This is also the case when
* the found IKE_SA is in the DELETING state.
*
* @param this the manager object
* @param peer_cfg configuration used to find an existing IKE_SA
* @return checked out/created IKE_SA
*/
@@ -112,14 +103,13 @@ struct ike_sa_manager_t {
peer_cfg_t *peer_cfg);
/**
* @brief Check out an IKE_SA a unique ID.
* Check out an IKE_SA a unique ID.
*
* Every IKE_SA and every CHILD_SA is uniquely identified by an ID.
* These checkout function uses, depending
* on the child parameter, the unique ID of the IKE_SA or the reqid
* of one of a IKE_SAs CHILD_SA.
*
* @param this the manager object
* @param id unique ID of the object
* @param child TRUE to use CHILD, FALSE to use IKE_SA
* @return
@@ -130,12 +120,11 @@ struct ike_sa_manager_t {
bool child);
/**
* @brief Check out an IKE_SA by the policy/connection name.
* Check out an IKE_SA by the policy/connection name.
*
* Check out the IKE_SA by the connections name or by a CHILD_SAs policy
* name.
*
* @param this the manager object
* @param name name of the connection/policy
* @param child TRUE to use policy name, FALSE to use conn name
* @return
@@ -146,24 +135,22 @@ struct ike_sa_manager_t {
bool child);
/**
* @brief Create an iterator over all stored IKE_SAs.
* Create an iterator over all stored IKE_SAs.
*
* The avoid synchronization issues, the iterator locks access
* to the manager exclusively, until it gets destroyed.
* This iterator is for reading only! Writing will corrupt the manager.
*
* @param this the manager object
* @return iterator over all IKE_SAs.
*/
iterator_t *(*create_iterator) (ike_sa_manager_t* this);
/**
* @brief Checkin the SA after usage.
* Checkin the SA after usage.
*
* @warning the SA pointer MUST NOT be used after checkin!
* The SA must be checked out again!
*
* @param this the manager object
* @param ike_sa_id the SA identifier, will be updated
* @param ike_sa checked out SA
* @returns
@@ -173,7 +160,7 @@ struct ike_sa_manager_t {
status_t (*checkin) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
/**
* @brief Destroy a checked out SA.
* Destroy a checked out SA.
*
* The IKE SA is destroyed without notification of the remote peer.
* Use this only if the other peer doesn't respond or behaves not
@@ -182,7 +169,6 @@ struct ike_sa_manager_t {
* so this can be called if the SA is in a "unclean" state, without the
* risk that another thread can get the SA.
*
* @param this the manager object
* @param ike_sa SA to delete
* @returns
* - SUCCESS if found
@@ -191,7 +177,7 @@ struct ike_sa_manager_t {
status_t (*checkin_and_destroy) (ike_sa_manager_t* this, ike_sa_t *ike_sa);
/**
* @brief Get the number of IKE_SAs which are in the connecting state.
* Get the number of IKE_SAs which are in the connecting state.
*
* To prevent the server from resource exhaustion, cookies and other
* mechanisms are used. The number of half open IKE_SAs is a good
@@ -200,29 +186,24 @@ struct ike_sa_manager_t {
* from this IP are counted.
* Only SAs for which we are the responder are counted.
*
* @param this the manager object
* @param ip NULL for all, IP for half open IKE_SAs with IP
* @return number of half open IKE_SAs
*/
int (*get_half_open_count) (ike_sa_manager_t *this, host_t *ip);
/**
* @brief Destroys the manager with all associated SAs.
* Destroys the manager with all associated SAs.
*
* Threads will be driven out, so all SAs can be deleted cleanly.
*
* @param this the manager object
*/
void (*destroy) (ike_sa_manager_t *this);
};
/**
* @brief Create a manager.
* Create a manager.
*
* @returns ike_sa_manager_t object
*
* @ingroup sa
* @returns ike_sa_manager_t object, NULL if initialization fails
*/
ike_sa_manager_t *ike_sa_manager_create(void);
#endif /*IKE_SA_MANAGER_H_*/
#endif /*IKE_SA_MANAGER_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file mediation_manager.c
*
* @brief Implementation of mediation_manager_t.
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include "mediation_manager.h"
+15 -28
View File
@@ -1,10 +1,3 @@
/**
* @file mediation_manager.h
*
* @brief Interface of mediation_manager_t.
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup mediation_manager mediation_manager
* @{ @ingroup sa
*/
#ifndef MEDIATION_MANAGER_H_
@@ -29,29 +29,22 @@ typedef struct mediation_manager_t mediation_manager_t;
#include <utils/identification.h>
/**
* @brief The mediation manager is responsible for managing currently online
* The mediation manager is responsible for managing currently online
* peers and registered requests for offline peers on the mediation server.
*
* @b Constructors:
* - mediation_manager_create()
*
* @ingroup sa
*/
struct mediation_manager_t {
/**
* @brief Remove the IKE_SA of a peer.
* Remove the IKE_SA of a peer.
*
* @param this the manager object
* @param ike_sa_id the IKE_SA ID of the peer's SA
*/
void (*remove) (mediation_manager_t* this, ike_sa_id_t *ike_sa_id);
/**
* @brief Update the ike_sa_id that is assigned to a peer's ID. If the peer
* Update the ike_sa_id that is assigned to a peer's ID. If the peer
* is new, it gets a new record assigned.
*
* @param this the manager object
* @param peer_id the peer's ID
* @param ike_sa_id the IKE_SA ID of the peer's SA
*/
@@ -59,9 +52,8 @@ struct mediation_manager_t {
ike_sa_id_t *ike_sa_id);
/**
* @brief Checks if a specific peer is online.
* Checks if a specific peer is online.
*
* @param this the manager object
* @param peer_id the peer's ID
* @returns
* - IKE_SA ID of the peer's SA.
@@ -71,10 +63,9 @@ struct mediation_manager_t {
identification_t *peer_id);
/**
* @brief Checks if a specific peer is online and registers the requesting
* Checks if a specific peer is online and registers the requesting
* peer if it is not.
*
* @param this the manager object
* @param peer_id the peer's ID
* @param requester the requesters ID
* @returns
@@ -85,20 +76,16 @@ struct mediation_manager_t {
identification_t *peer_id, identification_t *requester);
/**
* @brief Destroys the manager with all data.
*
* @param this the manager object
* Destroys the manager with all data.
*/
void (*destroy) (mediation_manager_t *this);
};
/**
* @brief Create a manager.
* Create a manager.
*
* @returns mediation_manager_t object
*
* @ingroup sa
*/
mediation_manager_t *mediation_manager_create(void);
#endif /*MEDIATION_MANAGER_H_*/
#endif /*MEDIATION_MANAGER_H_ @} */
+9 -10
View File
@@ -1,10 +1,3 @@
/**
* @file task_manager.c
*
* @brief Implementation of task_manager_t.
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2007 Martin Willi
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include "task_manager.h"
@@ -31,7 +26,8 @@
#include <sa/tasks/ike_mobike.h>
#include <sa/tasks/ike_auth.h>
#include <sa/tasks/ike_auth_lifetime.h>
#include <sa/tasks/ike_cert.h>
#include <sa/tasks/ike_cert_pre.h>
#include <sa/tasks/ike_cert_post.h>
#include <sa/tasks/ike_rekey.h>
#include <sa/tasks/ike_delete.h>
#include <sa/tasks/ike_config.h>
@@ -328,7 +324,7 @@ static status_t build_request(private_task_manager_t *this)
this->initiating.mid = 0;
exchange = IKE_SA_INIT;
activate_task(this, IKE_NATD);
activate_task(this, IKE_CERT);
activate_task(this, IKE_CERT_PRE);
#ifdef P2P
/* this task has to be activated before the IKE_AUTHENTICATE
* task, because that task pregenerates the packet after
@@ -337,6 +333,7 @@ static status_t build_request(private_task_manager_t *this)
activate_task(this, IKE_P2P);
#endif /* P2P */
activate_task(this, IKE_AUTHENTICATE);
activate_task(this, IKE_CERT_POST);
activate_task(this, IKE_CONFIG);
activate_task(this, CHILD_CREATE);
activate_task(this, IKE_AUTH_LIFETIME);
@@ -687,7 +684,7 @@ static status_t process_request(private_task_manager_t *this,
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)ike_natd_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)ike_cert_create(this->ike_sa, FALSE);
task = (task_t*)ike_cert_pre_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
#ifdef P2P
task = (task_t*)ike_p2p_create(this->ike_sa, FALSE);
@@ -695,6 +692,8 @@ static status_t process_request(private_task_manager_t *this,
#endif /* P2P */
task = (task_t*)ike_auth_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)ike_cert_post_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)ike_config_create(this->ike_sa, FALSE);
this->passive_tasks->insert_last(this->passive_tasks, task);
task = (task_t*)child_create_create(this->ike_sa, NULL);
+18 -45
View File
@@ -1,10 +1,3 @@
/**
* @file task_manager.h
*
* @brief Interface of task_manager_t.
*
*/
/*
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup task_manager task_manager
* @{ @ingroup sa
*/
#ifndef TASK_MANAGER_H_
@@ -32,42 +32,32 @@ typedef struct task_manager_t task_manager_t;
/**
* First retransmit timeout in milliseconds.
*
* @ingroup sa
*/
#define RETRANSMIT_TIMEOUT 4000
/**
* Base which is raised to the power of the retransmission try.
*
* @ingroup sa
*/
#define RETRANSMIT_BASE 1.8
/**
* Number of retransmits done before giving up.
*
* @ingroup sa
*/
#define RETRANSMIT_TRIES 5
/**
* Interval for mobike routability checks in ms.
*
* @ingroup sa
*/
#define ROUTEABILITY_CHECK_INTERVAL 2500
/**
* Number of routability checks before giving up
*
* @ingroup sa
*/
#define ROUTEABILITY_CHECK_TRIES 10
/**
* @brief The task manager, juggles task and handles message exchanges.
* The task manager, juggles task and handles message exchanges.
*
* On incoming requests, the task manager creates new tasks on demand and
* juggles the request through all available tasks. Each task inspects the
@@ -97,18 +87,12 @@ typedef struct task_manager_t task_manager_t;
@endberbatim
* The peer is considered dead after 2min 45s when no reply comes in.
*
* @b Constructors:
* - task_manager_create()
*
* @ingroup sa
*/
struct task_manager_t {
/**
* @brief Process an incoming message.
* Process an incoming message.
*
* @param this calling object
* @param message message to add payloads to
* @return
* - DESTROY_ME if IKE_SA must be closed
@@ -117,28 +101,24 @@ struct task_manager_t {
status_t (*process_message) (task_manager_t *this, message_t *message);
/**
* @brief Initiate an exchange with the currently queued tasks.
*
* @param this calling object
* Initiate an exchange with the currently queued tasks.
*/
status_t (*initiate) (task_manager_t *this);
/**
* @brief Queue a task in the manager.
* Queue a task in the manager.
*
* @param this calling object
* @param task task to queue
*/
void (*queue_task) (task_manager_t *this, task_t *task);
/**
* @brief Retransmit a request if it hasn't been acknowledged yet.
* Retransmit a request if it hasn't been acknowledged yet.
*
* A return value of INVALID_STATE means that the message was already
* acknowledged and has not to be retransmitted. A return value of SUCCESS
* means retransmission was required and the message has been resent.
*
* @param this calling object
* @param message_id ID of the message to retransmit
* @return
* - INVALID_STATE if retransmission not required
@@ -147,52 +127,45 @@ struct task_manager_t {
status_t (*retransmit) (task_manager_t *this, u_int32_t message_id);
/**
* @brief Migrate all tasks from other to this.
* Migrate all tasks from other to this.
*
* To rekey or reestablish an IKE_SA completely, all queued or active
* tasks should get migrated to the new IKE_SA.
*
* @param this manager which gets all tasks
* @param other manager which gives away its tasks
*/
void (*adopt_tasks) (task_manager_t *this, task_manager_t *other);
/**
* @brief Reset message ID counters of the task manager.
* Reset message ID counters of the task manager.
*
* The IKEv2 protocol requires to restart exchanges with message IDs
* reset to zero (INVALID_KE_PAYLOAD, COOKIES, ...). The reset() method
* resets the message IDs and resets all active tasks using the migrate()
* method.
*
* @param this calling object
* @param other manager which gives away its tasks
*/
void (*reset) (task_manager_t *this);
/**
* @brief Check if we are currently waiting for a reply.
* Check if we are currently waiting for a reply.
*
* @param this calling object
* @return TRUE if we are waiting, FALSE otherwise
*/
bool (*busy) (task_manager_t *this);
/**
* @brief Destroy the task_manager_t.
*
* @param this calling object
* Destroy the task_manager_t.
*/
void (*destroy) (task_manager_t *this);
};
/**
* @brief Create an instance of the task manager.
* Create an instance of the task manager.
*
* @param ike_sa IKE_SA to manage.
*
* @ingroup sa
*/
task_manager_t *task_manager_create(ike_sa_t *ike_sa);
#endif /* TASK_MANAGER_H_ */
#endif /* TASK_MANAGER_H_ @} */
+4 -9
View File
@@ -1,10 +1,3 @@
/**
* @file child_create.c
*
* @brief Implementation of the child_create task.
*
*/
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include "child_create.h"
@@ -450,7 +445,7 @@ static void process_payloads(private_child_create_t *this, message_t *message)
if (!this->initiator)
{
this->dh_group = ke_payload->get_dh_group_number(ke_payload);
this->dh = diffie_hellman_create(this->dh_group);
this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
}
if (this->dh)
{
@@ -580,7 +575,7 @@ static status_t build_i(private_child_create_t *this, message_t *message)
if (this->dh_group != MODP_NONE)
{
this->dh = diffie_hellman_create(this->dh_group);
this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
}
build_payloads(this, message);
+13 -21
View File
@@ -1,10 +1,3 @@
/**
* @file child_create.h
*
* @brief Interface child_create_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup child_create child_create
* @{ @ingroup tasks
*/
#ifndef CHILD_CREATE_H_
@@ -31,15 +31,10 @@ typedef struct child_create_t child_create_t;
#include <config/child_cfg.h>
/**
* @brief Task of type CHILD_CREATE, established a new CHILD_SA.
* Task of type CHILD_CREATE, established a new CHILD_SA.
*
* This task may be included in the IKE_AUTH message or in a separate
* CREATE_CHILD_SA exchange.
*
* @b Constructors:
* - child_create_create()
*
* @ingroup tasks
*/
struct child_create_t {
@@ -49,35 +44,32 @@ struct child_create_t {
task_t task;
/**
* @brief Use a specific reqid for the CHILD_SA.
* Use a specific reqid for the CHILD_SA.
*
* When this task is used for rekeying, the same reqid is used
* for the new CHILD_SA.
*
* @param this calling object
* @param reqid reqid to use
*/
void (*use_reqid) (child_create_t *this, u_int32_t reqid);
/**
* @brief Get the lower of the two nonces, used for rekey collisions.
* Get the lower of the two nonces, used for rekey collisions.
*
* @param this calling object
* @return lower nonce
*/
chunk_t (*get_lower_nonce) (child_create_t *this);
/**
* @brief Get the CHILD_SA established/establishing by this task.
* Get the CHILD_SA established/establishing by this task.
*
* @param this calling object
* @return child_sa
*/
child_sa_t* (*get_child) (child_create_t *this);
};
/**
* @brief Create a new child_create task.
* Create a new child_create task.
*
* @param ike_sa IKE_SA this task works for
* @param config child_cfg if task initiator, NULL if responder
@@ -85,4 +77,4 @@ struct child_create_t {
*/
child_create_t *child_create_create(ike_sa_t *ike_sa, child_cfg_t *config);
#endif /* CHILD_CREATE_H_ */
#endif /* CHILD_CREATE_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file child_delete.c
*
* @brief Implementation of the child_delete task.
*
*/
/*
* Copyright (C) 2006-2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include "child_delete.h"
+11 -17
View File
@@ -1,10 +1,3 @@
/**
* @file child_delete.h
*
* @brief Interface child_delete_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup child_delete child_delete
* @{ @ingroup tasks
*/
#ifndef CHILD_DELETE_H_
@@ -31,12 +31,7 @@ typedef struct child_delete_t child_delete_t;
#include <sa/child_sa.h>
/**
* @brief Task of type child_delete, delete a CHILD_SA.
*
* @b Constructors:
* - child_delete_create()
*
* @ingroup tasks
* Task of type child_delete, delete a CHILD_SA.
*/
struct child_delete_t {
@@ -46,16 +41,15 @@ struct child_delete_t {
task_t task;
/**
* @brief Get the CHILD_SA to delete by this task.
* Get the CHILD_SA to delete by this task.
*
* @param this calling object
* @return child_sa
*/
child_sa_t* (*get_child) (child_delete_t *this);
};
/**
* @brief Create a new child_delete task.
* Create a new child_delete task.
*
* @param ike_sa IKE_SA this task works for
* @param child_sa CHILD_SA to delete, or NULL as responder
@@ -63,4 +57,4 @@ struct child_delete_t {
*/
child_delete_t *child_delete_create(ike_sa_t *ike_sa, child_sa_t *child_sa);
#endif /* CHILD_DELETE_H_ */
#endif /* CHILD_DELETE_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file child_rekey.c
*
* @brief Implementation of the child_rekey task.
*
*/
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include "child_rekey.h"
+11 -17
View File
@@ -1,10 +1,3 @@
/**
* @file child_rekey.h
*
* @brief Interface child_rekey_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup child_rekey child_rekey
* @{ @ingroup tasks
*/
#ifndef CHILD_REKEY_H_
@@ -31,12 +31,7 @@ typedef struct child_rekey_t child_rekey_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type CHILD_REKEY, rekey an established CHILD_SA.
*
* @b Constructors:
* - child_rekey_create()
*
* @ingroup tasks
* Task of type CHILD_REKEY, rekey an established CHILD_SA.
*/
struct child_rekey_t {
@@ -46,20 +41,19 @@ struct child_rekey_t {
task_t task;
/**
* @brief Register a rekeying task which collides with this one
* Register a rekeying task which collides with this one
*
* If two peers initiate rekeying at the same time, the collision must
* be handled gracefully. The task manager is aware of what exchanges
* are going on and notifies the outgoing task by passing the incoming.
*
* @param this task initated by us
* @param other incoming task
*/
void (*collide)(child_rekey_t* this, task_t *other);
};
/**
* @brief Create a new CHILD_REKEY task.
* Create a new CHILD_REKEY task.
*
* @param ike_sa IKE_SA this task works for
* @param child_sa child_sa to rekey, NULL if responder
@@ -67,4 +61,4 @@ struct child_rekey_t {
*/
child_rekey_t *child_rekey_create(ike_sa_t *ike_sa, child_sa_t *child_sa);
#endif /* CHILD_REKEY_H_ */
#endif /* CHILD_REKEY_H_ @} */
+24 -19
View File
@@ -1,10 +1,3 @@
/**
* @file ike_auth.c
*
* @brief Implementation of the ike_auth task.
*
*/
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -18,7 +11,9 @@
* 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.
* for more details
*
* $Id$
*/
#include "ike_auth.h"
@@ -231,7 +226,7 @@ static status_t process_id(private_ike_auth_t *this, message_t *message)
{
id = idr->get_identification(idr);
req = this->ike_sa->get_other_id(this->ike_sa);
if (!id->matches(id, req, NULL))
if (!id->matches(id, req))
{
SIG(IKE_UP_FAILED, "peer ID %D unacceptable, %D required", id, req);
id->destroy(id);
@@ -525,13 +520,13 @@ static status_t process_r(private_ike_auth_t *this, message_t *message)
this->eap_auth = eap_authenticator_create(this->ike_sa);
break;
default:
break;
return NEED_MORE;
}
config = charon->backends->get_peer_cfg(charon->backends,
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa),
this->ike_sa->get_other_ca(this->ike_sa));
this->ike_sa->get_other_auth(this->ike_sa));
if (config)
{
this->ike_sa->set_peer_cfg(this->ike_sa, config);
@@ -557,6 +552,13 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
return collect_my_init_data(this, message);
}
if (!this->peer_authenticated && this->eap_auth == NULL)
{
/* peer not authenticated, nor does it want to use EAP */
message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
return FAILED;
}
config = this->ike_sa->get_peer_cfg(this->ike_sa);
if (config == NULL)
{
@@ -587,13 +589,6 @@ static status_t build_r(private_ike_auth_t *this, message_t *message)
return SUCCESS;
}
if (this->eap_auth == NULL)
{
/* peer not authenticated, nor does it want to use EAP */
message->add_notify(message, TRUE, AUTHENTICATION_FAILED, chunk_empty);
return FAILED;
}
/* initiate EAP authenitcation */
eap_type = config->get_eap_type(config, &eap_vendor);
status = this->eap_auth->initiate(this->eap_auth, eap_type,
@@ -618,6 +613,8 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
{
iterator_t *iterator;
payload_t *payload;
peer_cfg_t *config;
auth_info_t *auth;
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
@@ -687,10 +684,18 @@ static status_t process_i(private_ike_auth_t *this, message_t *message)
return process_eap_i(this, message);
}
config = this->ike_sa->get_peer_cfg(this->ike_sa);
auth = this->ike_sa->get_other_auth(this->ike_sa);
if (!auth->complies(auth, config->get_auth(config)))
{
SIG(IKE_UP_FAILED, "authorization of %D for config %s failed",
this->ike_sa->get_other_id(this->ike_sa), config->get_name(config));
return FAILED;
}
this->ike_sa->set_state(this->ike_sa, IKE_ESTABLISHED);
SIG(IKE_UP_SUCCESS, "IKE_SA '%s' established between %D[%H]...[%H]%D",
this->ike_sa->get_name(this->ike_sa),
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_my_id(this->ike_sa),
this->ike_sa->get_my_host(this->ike_sa),
this->ike_sa->get_other_host(this->ike_sa),
this->ike_sa->get_other_id(this->ike_sa));
+10 -15
View File
@@ -1,10 +1,3 @@
/**
* @file ike_auth.h
*
* @brief Interface ike_auth_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_auth ike_auth
* @{ @ingroup tasks
*/
#ifndef IKE_AUTH_H_
@@ -30,7 +30,7 @@ typedef struct ike_auth_t ike_auth_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type ike_auth, authenticates an IKE_SA using authenticators.
* Task of type ike_auth, authenticates an IKE_SA using authenticators.
*
* The ike_auth task authenticates the IKE_SA using the IKE_AUTH
* exchange. It processes and build IDi and IDr payloads and also
@@ -38,11 +38,6 @@ typedef struct ike_auth_t ike_auth_t;
* which do the actual authentication process. If the ike_auth task is used
* with EAP authentication, it stays alive over multiple exchanges until
* EAP has completed.
*
* @b Constructors:
* - ike_auth_create()
*
* @ingroup tasks
*/
struct ike_auth_t {
@@ -53,7 +48,7 @@ struct ike_auth_t {
};
/**
* @brief Create a new task of type IKE_AUTHENTICATE.
* Create a new task of type IKE_AUTHENTICATE.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if thask is the initator of an exchange
@@ -61,4 +56,4 @@ struct ike_auth_t {
*/
ike_auth_t *ike_auth_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_AUTH_H_ */
#endif /* IKE_AUTH_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file ike_auth_lifetime.c
*
* @brief Implementation of the ike_auth_lifetime task.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include "ike_auth_lifetime.h"
+10 -16
View File
@@ -1,10 +1,3 @@
/**
* @file ike_auth_lifetime.h
*
* @brief Interface ike_auth_lifetime_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_auth_lifetime ike_auth_lifetime
* @{ @ingroup tasks
*/
#ifndef IKE_AUTH_LIFETIME_H_
@@ -30,15 +30,10 @@ typedef struct ike_auth_lifetime_t ike_auth_lifetime_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type IKE_AUTH_LIFETIME, implements RFC4478.
* Task of type IKE_AUTH_LIFETIME, implements RFC4478.
*
* This task exchanges lifetimes for IKE_AUTH to force a client to
* reauthenticate before the responders lifetime reaches the limit.
*
* @b Constructors:
* - ike_auth_lifetime_create()
*
* @ingroup tasks
*/
struct ike_auth_lifetime_t {
@@ -49,7 +44,7 @@ struct ike_auth_lifetime_t {
};
/**
* @brief Create a new IKE_AUTH_LIFETIME task.
* Create a new IKE_AUTH_LIFETIME task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if taks is initiated by us
@@ -57,5 +52,4 @@ struct ike_auth_lifetime_t {
*/
ike_auth_lifetime_t *ike_auth_lifetime_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_MOBIKE_H_ */
#endif /* IKE_MOBIKE_H_ @} */
-366
View File
@@ -1,366 +0,0 @@
/**
* @file ike_cert.c
*
* @brief Implementation of the ike_cert task.
*
*/
/*
* Copyright (C) 2006-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 "ike_cert.h"
#include <daemon.h>
#include <sa/ike_sa.h>
#include <crypto/hashers/hasher.h>
#include <encoding/payloads/cert_payload.h>
#include <encoding/payloads/certreq_payload.h>
typedef struct private_ike_cert_t private_ike_cert_t;
/**
* Private members of a ike_cert_t task.
*/
struct private_ike_cert_t {
/**
* Public methods and task_t interface.
*/
ike_cert_t public;
/**
* Assigned IKE_SA.
*/
ike_sa_t *ike_sa;
/**
* Are we the initiator?
*/
bool initiator;
/**
* list of CA cert hashes requested, items point to 20 byte chunk
*/
linked_list_t *cas;
/**
* have we seen a certificate request?
*/
bool certreq_seen;
};
/**
* read certificate requests
*/
static void process_certreqs(private_ike_cert_t *this, message_t *message)
{
iterator_t *iterator;
payload_t *payload;
iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
{
if (payload->get_type(payload) == CERTIFICATE_REQUEST)
{
certreq_payload_t *certreq = (certreq_payload_t*)payload;
cert_encoding_t encoding;
chunk_t keyids, keyid;
this->certreq_seen = TRUE;
encoding = certreq->get_cert_encoding(certreq);
if (encoding != CERT_X509_SIGNATURE)
{
DBG1(DBG_IKE, "certreq payload %N not supported - ignored",
cert_encoding_names, encoding);
continue;
}
keyids = certreq->get_data(certreq);
while (keyids.len >= HASH_SIZE_SHA1)
{
keyid = chunk_create(keyids.ptr, HASH_SIZE_SHA1);
keyid = chunk_clone(keyid);
this->cas->insert_last(this->cas, keyid.ptr);
keyids = chunk_skip(keyids, HASH_SIZE_SHA1);
}
}
}
iterator->destroy(iterator);
}
/**
* import certificates
*/
static void process_certs(private_ike_cert_t *this, message_t *message)
{
iterator_t *iterator;
payload_t *payload;
iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
{
if (payload->get_type(payload) == CERTIFICATE)
{
cert_encoding_t encoding;
x509_t *cert;
chunk_t cert_data;
bool found;
cert_payload_t *cert_payload = (cert_payload_t*)payload;
encoding = cert_payload->get_cert_encoding(cert_payload);
if (encoding != CERT_X509_SIGNATURE)
{
DBG1(DBG_IKE, "certificate payload %N not supported - ignored",
cert_encoding_names, encoding);
continue;
}
cert_data = cert_payload->get_data_clone(cert_payload);
cert = x509_create_from_chunk(cert_data, 0);
if (cert)
{
if (charon->credentials->verify(charon->credentials, cert, &found))
{
DBG2(DBG_IKE, "received end entity certificate is trusted - "
"added to store");
if (found)
{
cert->destroy(cert);
}
else
{
charon->credentials->add_end_certificate(charon->credentials, cert);
}
}
else
{
DBG1(DBG_IKE, "received end entity certificate is not trusted - "
"discarded");
cert->destroy(cert);
}
}
else
{
DBG1(DBG_IKE, "parsing of received certificate failed - discarded");
chunk_free(&cert_data);
}
}
}
iterator->destroy(iterator);
}
/**
* build certificate requests
*/
static void build_certreqs(private_ike_cert_t *this, message_t *message)
{
ike_cfg_t *ike_cfg;
peer_cfg_t *peer_cfg;
identification_t *ca;
certreq_payload_t *certreq;
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
if (ike_cfg->send_certreq(ike_cfg) != CERT_NEVER_SEND)
{
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
if (peer_cfg)
{
ca = peer_cfg->get_other_ca(peer_cfg);
if (ca && ca->get_type(ca) != ID_ANY)
{
certreq = certreq_payload_create_from_cacert(ca);
}
else
{
certreq = certreq_payload_create_from_cacerts();
}
}
else
{
certreq = certreq_payload_create_from_cacerts();
}
if (certreq)
{
message->add_payload(message, (payload_t*)certreq);
}
}
}
/**
* add certificates to message
*/
static void build_certs(private_ike_cert_t *this, message_t *message)
{
peer_cfg_t *peer_cfg;
x509_t *cert;
cert_payload_t *payload;
peer_cfg = this->ike_sa->get_peer_cfg(this->ike_sa);
if (peer_cfg && peer_cfg->get_auth_method(peer_cfg) == AUTH_RSA)
{
switch (peer_cfg->get_cert_policy(peer_cfg))
{
case CERT_NEVER_SEND:
break;
case CERT_SEND_IF_ASKED:
if (!this->certreq_seen)
{
break;
}
/* FALL */
case CERT_ALWAYS_SEND:
{
/* TODO: respect CA cert request */
cert = charon->credentials->get_certificate(charon->credentials,
peer_cfg->get_my_id(peer_cfg));
if (cert)
{
payload = cert_payload_create_from_x509(cert);
message->add_payload(message, (payload_t*)payload);
}
}
}
}
}
/**
* Implementation of task_t.process for initiator
*/
static status_t build_i(private_ike_cert_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return NEED_MORE;
}
build_certreqs(this, message);
build_certs(this, message);
return NEED_MORE;
}
/**
* Implementation of task_t.process for responder
*/
static status_t process_r(private_ike_cert_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return NEED_MORE;
}
process_certreqs(this, message);
process_certs(this, message);
return NEED_MORE;
}
/**
* Implementation of task_t.build for responder
*/
static status_t build_r(private_ike_cert_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
build_certreqs(this, message);
return NEED_MORE;
}
build_certs(this, message);
return SUCCESS;
}
/**
* Implementation of task_t.process for initiator
*/
static status_t process_i(private_ike_cert_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
process_certreqs(this, message);
return NEED_MORE;
}
process_certs(this, message);
return SUCCESS;
}
/**
* Implementation of task_t.get_type
*/
static task_type_t get_type(private_ike_cert_t *this)
{
return IKE_CERT;
}
/**
* Implementation of task_t.migrate
*/
static void migrate(private_ike_cert_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
this->cas->destroy_function(this->cas, free);
this->cas = linked_list_create();
this->certreq_seen = FALSE;
}
/**
* Implementation of task_t.destroy
*/
static void destroy(private_ike_cert_t *this)
{
this->cas->destroy_function(this->cas, free);
free(this);
}
/*
* Described in header.
*/
ike_cert_t *ike_cert_create(ike_sa_t *ike_sa, bool initiator)
{
private_ike_cert_t *this = malloc_thing(private_ike_cert_t);
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
this->public.task.destroy = (void(*)(task_t*))destroy;
if (initiator)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
}
else
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
}
this->ike_sa = ike_sa;
this->initiator = initiator;
this->cas = linked_list_create();
this->certreq_seen = FALSE;
return &this->public;
}
+210
View File
@@ -0,0 +1,210 @@
/*
* Copyright (C) 2006-2008 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.
*
* $Id$
*/
#include "ike_cert_post.h"
#include <daemon.h>
#include <sa/ike_sa.h>
#include <encoding/payloads/cert_payload.h>
#include <encoding/payloads/certreq_payload.h>
#include <credentials/certificates/x509.h>
typedef struct private_ike_cert_post_t private_ike_cert_post_t;
/**
* Private members of a ike_cert_post_t task.
*/
struct private_ike_cert_post_t {
/**
* Public methods and task_t interface.
*/
ike_cert_post_t public;
/**
* Assigned IKE_SA.
*/
ike_sa_t *ike_sa;
/**
* Are we the initiator?
*/
bool initiator;
};
/**
* add certificates to message
*/
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) == AUTH_RSA)
{
switch (peer_cfg->get_cert_policy(peer_cfg))
{
case CERT_NEVER_SEND:
break;
case CERT_SEND_IF_ASKED:
if (!this->ike_sa->has_condition(this->ike_sa, COND_CERTREQ_SEEN))
{
break;
}
/* FALL */
case CERT_ALWAYS_SEND:
{
cert_payload_t *payload;
enumerator_t *enumerator;
certificate_t *cert;
auth_info_t *auth;
auth_item_t item;
auth = this->ike_sa->get_my_auth(this->ike_sa);
/* get subject cert first, then issuing certificates */
if (!auth->get_item(auth, AUTHZ_SUBJECT_CERT, (void**)&cert))
{
break;
}
payload = cert_payload_create_from_cert(cert);
if (!payload)
{
break;
}
DBG1(DBG_IKE, "sending end entity cert %D",
cert->get_subject(cert));
message->add_payload(message, (payload_t*)payload);
enumerator = auth->create_item_enumerator(auth);
while (enumerator->enumerate(enumerator, &item, &cert))
{
if (item == AUTHZ_IM_CERT)
{
payload = cert_payload_create_from_cert(cert);
if (payload)
{
DBG1(DBG_IKE, "sending issuer cert %D",
cert->get_subject(cert));
message->add_payload(message, (payload_t*)payload);
}
}
}
enumerator->destroy(enumerator);
}
}
}
}
/**
* Implementation of task_t.process for initiator
*/
static status_t build_i(private_ike_cert_post_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return NEED_MORE;
}
build_certs(this, message);
return SUCCESS;
}
/**
* Implementation of task_t.process for responder
*/
static status_t process_r(private_ike_cert_post_t *this, message_t *message)
{
return NEED_MORE;
}
/**
* Implementation of task_t.build for responder
*/
static status_t build_r(private_ike_cert_post_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return NEED_MORE;
}
build_certs(this, message);
return SUCCESS;
}
/**
* Implementation of task_t.process for initiator
*/
static status_t process_i(private_ike_cert_post_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return NEED_MORE;
}
return SUCCESS;
}
/**
* Implementation of task_t.get_type
*/
static task_type_t get_type(private_ike_cert_post_t *this)
{
return IKE_CERT_POST;
}
/**
* Implementation of task_t.migrate
*/
static void migrate(private_ike_cert_post_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
}
/**
* Implementation of task_t.destroy
*/
static void destroy(private_ike_cert_post_t *this)
{
free(this);
}
/*
* Described in header.
*/
ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator)
{
private_ike_cert_post_t *this = malloc_thing(private_ike_cert_post_t);
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
this->public.task.destroy = (void(*)(task_t*))destroy;
if (initiator)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
}
else
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
}
this->ike_sa = ike_sa;
this->initiator = initiator;
return &this->public;
}
@@ -1,12 +1,5 @@
/**
* @file ike_cert.h
*
* @brief Interface ike_cert_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Copyright (C) 2007-2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -18,27 +11,28 @@
* 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.
*
* $Id$
*/
#ifndef IKE_CERT_H_
#define IKE_CERT_H_
/**
* @defgroup ike_cert_post ike_cert_post
* @{ @ingroup tasks
*/
typedef struct ike_cert_t ike_cert_t;
#ifndef IKE_CERT_POST_H_
#define IKE_CERT_POST_H_
typedef struct ike_cert_post_t ike_cert_post_t;
#include <library.h>
#include <sa/ike_sa.h>
#include <sa/tasks/task.h>
/**
* @brief Task of type ike_cert, exchanges certificates and
* certificate requests.
*
* @b Constructors:
* - ike_cert_create()
*
* @ingroup tasks
* Task of type ike_cert_post, certificate processing after authentication.
*/
struct ike_cert_t {
struct ike_cert_post_t {
/**
* Implements the task_t interface
@@ -47,15 +41,15 @@ struct ike_cert_t {
};
/**
* @brief Create a new ike_cert task.
* Create a new ike_cert_post task.
*
* The initiator parameter means the original initiator, not the initiator
* of the certificate request.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if thask is the original initator
* @return ike_cert task to handle by the task_manager
* @return ike_cert_post task to handle by the task_manager
*/
ike_cert_t *ike_cert_create(ike_sa_t *ike_sa, bool initiator);
ike_cert_post_t *ike_cert_post_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_CERT_H_ */
#endif /* IKE_CERT_POST_H_ @} */
+346
View File
@@ -0,0 +1,346 @@
/*
* Copyright (C) 2006-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.
*
* $Id$
*/
#include "ike_cert_pre.h"
#include <daemon.h>
#include <sa/ike_sa.h>
#include <encoding/payloads/cert_payload.h>
#include <encoding/payloads/certreq_payload.h>
#include <credentials/certificates/x509.h>
typedef struct private_ike_cert_pre_t private_ike_cert_pre_t;
/**
* Private members of a ike_cert_pre_t task.
*/
struct private_ike_cert_pre_t {
/**
* Public methods and task_t interface.
*/
ike_cert_pre_t public;
/**
* Assigned IKE_SA.
*/
ike_sa_t *ike_sa;
/**
* Are we the initiator?
*/
bool initiator;
};
/**
* read certificate requests
*/
static void process_certreqs(private_ike_cert_pre_t *this, message_t *message)
{
iterator_t *iterator;
payload_t *payload;
auth_info_t *auth;
bool ca_found = FALSE;
auth = this->ike_sa->get_my_auth(this->ike_sa);
iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
{
if (payload->get_type(payload) == CERTIFICATE_REQUEST)
{
certreq_payload_t *certreq = (certreq_payload_t*)payload;
chunk_t keyid;
enumerator_t *enumerator;
this->ike_sa->set_condition(this->ike_sa, COND_CERTREQ_SEEN, TRUE);
if (certreq->get_cert_type(certreq) != CERT_X509)
{
DBG1(DBG_IKE, "cert payload %N not supported - ignored",
certificate_type_names, certreq->get_cert_type(certreq));
continue;
}
enumerator = certreq->create_keyid_enumerator(certreq);
while (enumerator->enumerate(enumerator, &keyid))
{
identification_t *id;
certificate_t *cert;
id = identification_create_from_encoding(
ID_PUBKEY_INFO_SHA1, keyid);
cert = charon->credentials->get_cert(charon->credentials,
CERT_X509, KEY_ANY, id, TRUE);
if (cert)
{
DBG1(DBG_IKE, "received cert request for %D",
cert->get_subject(cert));
auth->add_item(auth, AUTHN_CA_CERT, cert);
cert->destroy(cert);
ca_found = TRUE;
}
id->destroy(id);
}
enumerator->destroy(enumerator);
}
}
iterator->destroy(iterator);
if (this->ike_sa->has_condition(this->ike_sa, COND_CERTREQ_SEEN) && !ca_found)
{
DBG1(DBG_IKE, "received cert request, but no such CA cert found");
}
}
/**
* import certificates
*/
static void process_certs(private_ike_cert_pre_t *this, message_t *message)
{
iterator_t *iterator;
payload_t *payload;
auth_info_t *auth;
bool first = TRUE;
auth = this->ike_sa->get_other_auth(this->ike_sa);
iterator = message->get_payload_iterator(message);
while (iterator->iterate(iterator, (void**)&payload))
{
if (payload->get_type(payload) == CERTIFICATE)
{
certificate_t *cert;
cert_payload_t *cert_payload = (cert_payload_t*)payload;
cert = cert_payload->get_cert(cert_payload);
if (cert)
{
if (first)
{ /* the first certificate MUST be an end entity one */
DBG1(DBG_IKE, "received end entity cert %D",
cert->get_subject(cert));
auth->add_item(auth, AUTHN_SUBJECT_CERT, cert);
first = FALSE;
}
else
{
DBG1(DBG_IKE, "received issuer cert %D",
cert->get_subject(cert));
auth->add_item(auth, AUTHN_IM_CERT, cert);
}
}
cert->destroy(cert);
}
}
iterator->destroy(iterator);
}
/**
* add a certificate request to the message, building request payload if required.
*/
static void add_certreq_payload(message_t *message, certreq_payload_t **reqp,
certificate_t *cert)
{
public_key_t *public;
certreq_payload_t *req;
public = cert->get_public_key(cert);
if (!public)
{
return;
}
switch (cert->get_type(cert))
{
case CERT_X509:
{
identification_t *keyid;
x509_t *x509 = (x509_t*)cert;
if (!(x509->get_flags(x509) & X509_CA))
{ /* no CA cert, skip */
break;
}
if (*reqp == NULL)
{
*reqp = certreq_payload_create_type(CERT_X509);
message->add_payload(message, (payload_t*)*reqp);
}
req = *reqp;
keyid = public->get_id(public, ID_PUBKEY_INFO_SHA1);
req->add_keyid(req, keyid->get_encoding(keyid));
DBG1(DBG_IKE, "sending cert request for %D",
cert->get_subject(cert));
break;
}
default:
break;
}
public->destroy(public);
}
/**
* build certificate requests
*/
static void build_certreqs(private_ike_cert_pre_t *this, message_t *message)
{
ike_cfg_t *ike_cfg;
enumerator_t *enumerator;
certificate_t *cert;
auth_info_t *auth;
bool restricted = FALSE;
auth_item_t item;
certreq_payload_t *x509_req = NULL;
ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
if (ike_cfg->send_certreq(ike_cfg) == CERT_NEVER_SEND)
{
return;
}
auth = this->ike_sa->get_other_auth(this->ike_sa);
/* check if we require a specific CA for that peer */
enumerator = auth->create_item_enumerator(auth);
while (enumerator->enumerate(enumerator, &item, &cert))
{
if (item == AUTHN_CA_CERT)
{
restricted = TRUE;
add_certreq_payload(message, &x509_req, cert);
}
}
enumerator->destroy(enumerator);
if (!restricted)
{
/* otherwise include all trusted CA certificates */
enumerator = charon->credentials->create_cert_enumerator(
charon->credentials, CERT_ANY, KEY_ANY, NULL, TRUE);
while (enumerator->enumerate(enumerator, &cert, TRUE))
{
add_certreq_payload(message, &x509_req, cert);
}
enumerator->destroy(enumerator);
}
}
/**
* Implementation of task_t.process for initiator
*/
static status_t build_i(private_ike_cert_pre_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return NEED_MORE;
}
build_certreqs(this, message);
return NEED_MORE;
}
/**
* Implementation of task_t.process for responder
*/
static status_t process_r(private_ike_cert_pre_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
return NEED_MORE;
}
process_certreqs(this, message);
process_certs(this, message);
return NEED_MORE;
}
/**
* Implementation of task_t.build for responder
*/
static status_t build_r(private_ike_cert_pre_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
build_certreqs(this, message);
return NEED_MORE;
}
return SUCCESS;
}
/**
* Implementation of task_t.process for initiator
*/
static status_t process_i(private_ike_cert_pre_t *this, message_t *message)
{
if (message->get_exchange_type(message) == IKE_SA_INIT)
{
process_certreqs(this, message);
return NEED_MORE;
}
process_certs(this, message);
return SUCCESS;
}
/**
* Implementation of task_t.get_type
*/
static task_type_t get_type(private_ike_cert_pre_t *this)
{
return IKE_CERT_PRE;
}
/**
* Implementation of task_t.migrate
*/
static void migrate(private_ike_cert_pre_t *this, ike_sa_t *ike_sa)
{
this->ike_sa = ike_sa;
}
/**
* Implementation of task_t.destroy
*/
static void destroy(private_ike_cert_pre_t *this)
{
free(this);
}
/*
* Described in header.
*/
ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator)
{
private_ike_cert_pre_t *this = malloc_thing(private_ike_cert_pre_t);
this->public.task.get_type = (task_type_t(*)(task_t*))get_type;
this->public.task.migrate = (void(*)(task_t*,ike_sa_t*))migrate;
this->public.task.destroy = (void(*)(task_t*))destroy;
if (initiator)
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_i;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_i;
}
else
{
this->public.task.build = (status_t(*)(task_t*,message_t*))build_r;
this->public.task.process = (status_t(*)(task_t*,message_t*))process_r;
}
this->ike_sa = ike_sa;
this->initiator = initiator;
return &this->public;
}
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2007-2008 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.
*
* $Id$
*/
/**
* @defgroup ike_cert_pre ike_cert_pre
* @{ @ingroup tasks
*/
#ifndef IKE_CERT_PRE_H_
#define IKE_CERT_PRE_H_
typedef struct ike_cert_pre_t ike_cert_pre_t;
#include <library.h>
#include <sa/ike_sa.h>
#include <sa/tasks/task.h>
/**
* Task of type ike_cert_post, certificate processing before authentication.
*/
struct ike_cert_pre_t {
/**
* Implements the task_t interface
*/
task_t task;
};
/**
* Create a new ike_cert_pre task.
*
* The initiator parameter means the original initiator, not the initiator
* of the certificate request.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if thask is the original initator
* @return ike_cert_pre task to handle by the task_manager
*/
ike_cert_pre_t *ike_cert_pre_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_CERT_PRE_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file ike_config.c
*
* @brief Implementation of the ike_config task.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include "ike_config.h"
+10 -15
View File
@@ -1,10 +1,3 @@
/**
* @file ike_config.h
*
* @brief Interface ike_config_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_config ike_config
* @{ @ingroup tasks
*/
#ifndef IKE_CONFIG_H_
@@ -30,13 +30,8 @@ typedef struct ike_config_t ike_config_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type IKE_CONFIG, sets up a virtual IP and other
* Task of type IKE_CONFIG, sets up a virtual IP and other
* configurations for an IKE_SA.
*
* @b Constructors:
* - ike_config_create()
*
* @ingroup tasks
*/
struct ike_config_t {
@@ -47,7 +42,7 @@ struct ike_config_t {
};
/**
* @brief Create a new ike_config task.
* Create a new ike_config task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE for initiator
@@ -55,4 +50,4 @@ struct ike_config_t {
*/
ike_config_t *ike_config_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_CONFIG_H_ */
#endif /* IKE_CONFIG_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file ike_delete.c
*
* @brief Implementation of the ike_delete task.
*
*/
/*
* Copyright (C) 2006-2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include "ike_delete.h"
+10 -15
View File
@@ -1,10 +1,3 @@
/**
* @file ike_delete.h
*
* @brief Interface ike_delete_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_delete ike_delete
* @{ @ingroup tasks
*/
#ifndef IKE_DELETE_H_
@@ -30,12 +30,7 @@ typedef struct ike_delete_t ike_delete_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type ike_delete, delete an IKE_SA.
*
* @b Constructors:
* - ike_delete_create()
*
* @ingroup tasks
* Task of type ike_delete, delete an IKE_SA.
*/
struct ike_delete_t {
@@ -46,7 +41,7 @@ struct ike_delete_t {
};
/**
* @brief Create a new ike_delete task.
* Create a new ike_delete task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if we initiate the delete
@@ -54,4 +49,4 @@ struct ike_delete_t {
*/
ike_delete_t *ike_delete_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_DELETE_H_ */
#endif /* IKE_DELETE_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file ike_dpd.c
*
* @brief Implementation of the ike_dpd task.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include "ike_dpd.h"
+10 -15
View File
@@ -1,10 +1,3 @@
/**
* @file ike_dpd.h
*
* @brief Interface ike_dpd_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_dpd ike_dpd
* @{ @ingroup tasks
*/
#ifndef IKE_DPD_H_
@@ -30,14 +30,9 @@ typedef struct ike_dpd_t ike_dpd_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type ike_dpd, detects dead peers.
* Task of type ike_dpd, detects dead peers.
*
* The DPD task actually does nothing, as a DPD has no associated payloads.
*
* @b Constructors:
* - ike_dpd_create()
*
* @ingroup tasks
*/
struct ike_dpd_t {
@@ -48,11 +43,11 @@ struct ike_dpd_t {
};
/**
* @brief Create a new ike_dpd task.
* Create a new ike_dpd task.
*
* @param initiator TRUE if thask is the original initator
* @return ike_dpd task to handle by the task_manager
*/
ike_dpd_t *ike_dpd_create(bool initiator);
#endif /* IKE_DPD_H_ */
#endif /* IKE_DPD_H_ @} */
+5 -10
View File
@@ -1,10 +1,3 @@
/**
* @file ike_init.c
*
* @brief Implementation of the ike_init task.
*
*/
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include "ike_init.h"
@@ -195,7 +190,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
this->dh_group = ke_payload->get_dh_group_number(ke_payload);
if (!this->initiator)
{
this->dh = diffie_hellman_create(this->dh_group);
this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
}
if (this->dh)
{
@@ -241,7 +236,7 @@ static status_t build_i(private_ike_init_t *this, message_t *message)
if (!this->dh)
{
this->dh_group = this->config->get_dh_group(this->config);
this->dh = diffie_hellman_create(this->dh_group);
this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
if (this->dh == NULL)
{
SIG(IKE_UP_FAILED, "configured DH group %N not supported",
@@ -532,7 +527,7 @@ static void migrate(private_ike_init_t *this, ike_sa_t *ike_sa)
this->ike_sa = ike_sa;
this->proposal = NULL;
this->dh = diffie_hellman_create(this->dh_group);
this->dh = lib->crypto->create_dh(lib->crypto, this->dh_group);
}
/**
+11 -17
View File
@@ -1,10 +1,3 @@
/**
* @file ike_init.h
*
* @brief Interface ike_init_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_init ike_init
* @{ @ingroup tasks
*/
#ifndef IKE_INIT_H_
@@ -30,14 +30,9 @@ typedef struct ike_init_t ike_init_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type IKE_INIT, creates an IKE_SA without authentication.
* Task of type IKE_INIT, creates an IKE_SA without authentication.
*
* The authentication of is handle in the ike_auth task.
*
* @b Constructors:
* - ike_init_create()
*
* @ingroup tasks
*/
struct ike_init_t {
@@ -47,16 +42,15 @@ struct ike_init_t {
task_t task;
/**
* @brief Get the lower of the two nonces, used for rekey collisions.
* Get the lower of the two nonces, used for rekey collisions.
*
* @param this calling object
* @return lower nonce
*/
chunk_t (*get_lower_nonce) (ike_init_t *this);
};
/**
* @brief Create a new IKE_INIT task.
* Create a new IKE_INIT task.
*
* @param ike_sa IKE_SA this task works for (new one when rekeying)
* @param initiator TRUE if thask is the original initator
@@ -65,4 +59,4 @@ struct ike_init_t {
*/
ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa);
#endif /* IKE_INIT_H_ */
#endif /* IKE_INIT_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file ike_mobike.c
*
* @brief Implementation of the ike_mobike task.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include "ike_mobike.h"
+13 -22
View File
@@ -1,10 +1,3 @@
/**
* @file ike_mobike.h
*
* @brief Interface ike_mobike_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_mobike ike_mobike
* @{ @ingroup tasks
*/
#ifndef IKE_MOBIKE_H_
@@ -31,7 +31,7 @@ typedef struct ike_mobike_t ike_mobike_t;
#include <network/packet.h>
/**
* @brief Task of type ike_mobike, detects and handles MOBIKE extension.
* Task of type ike_mobike, detects and handles MOBIKE extension.
*
* The MOBIKE extension is defined in RFC4555. It allows to update IKE
* and IPsec tunnel addresses.
@@ -39,11 +39,6 @@ typedef struct ike_mobike_t ike_mobike_t;
* support, allows the exchange of ADDITIONAL_*_ADDRESS to exchange additional
* endpoints and handles the UPDATE_SA_ADDRESS notify to finally update
* endpoints.
*
* @b Constructors:
* - ike_mobike_create()
*
* @ingroup tasks
*/
struct ike_mobike_t {
@@ -53,36 +48,33 @@ struct ike_mobike_t {
task_t task;
/**
* @brief Use the task to roam to other addresses.
* Use the task to roam to other addresses.
*
* @param this calling object
* @param address TRUE to include address list update
*/
void (*roam)(ike_mobike_t *this, bool address);
/**
* @brief Transmision hook, called by task manager.
* Transmision hook, called by task manager.
*
* The task manager calls this hook whenever it transmits a packet. It
* allows the mobike task to send the packet on multiple paths to do path
* probing.
*
* @param this calling object
* @param packet the packet to transmit
*/
void (*transmit)(ike_mobike_t *this, packet_t *packet);
/**
* @brief Check if this task is probing for routability.
* Check if this task is probing for routability.
*
* @param this calling object
* @return TRUE if task is probing
*/
bool (*is_probing)(ike_mobike_t *this);
};
/**
* @brief Create a new ike_mobike task.
* Create a new ike_mobike task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if taks is initiated by us
@@ -90,5 +82,4 @@ struct ike_mobike_t {
*/
ike_mobike_t *ike_mobike_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_MOBIKE_H_ */
#endif /* IKE_MOBIKE_H_ @} */
+16 -9
View File
@@ -1,10 +1,3 @@
/**
* @file ike_natd.c
*
* @brief Implementation of the ike_natd task.
*
*/
/*
* Copyright (C) 2006-2007 Martin Willi
* Copyright (C) 2006 Tobias Brunner, Daniel Roethlisberger
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include "ike_natd.h"
@@ -308,6 +303,12 @@ static status_t build_i(private_ike_natd_t *this, message_t *message)
iterator_t *iterator;
host_t *host;
if (this->hasher == NULL)
{
DBG1(DBG_IKE, "unable to build NATD payloads, SHA1 not supported");
return NEED_MORE;
}
/* destination is always set */
host = message->get_destination(message);
notify = build_natd_payload(this, NAT_DETECTION_DESTINATION_IP, host);
@@ -368,6 +369,12 @@ static status_t build_r(private_ike_natd_t *this, message_t *message)
if (this->src_seen && this->dst_seen)
{
if (this->hasher == NULL)
{
DBG1(DBG_IKE, "unable to build NATD payloads, SHA1 not supported");
return SUCCESS;
}
/* initiator seems to support NAT detection, add response */
me = message->get_source(message);
notify = build_natd_payload(this, NAT_DETECTION_SOURCE_IP, me);
@@ -415,7 +422,7 @@ static void migrate(private_ike_natd_t *this, ike_sa_t *ike_sa)
*/
static void destroy(private_ike_natd_t *this)
{
this->hasher->destroy(this->hasher);
DESTROY_IF(this->hasher);
free(this);
}
@@ -443,7 +450,7 @@ ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator)
this->ike_sa = ike_sa;
this->initiator = initiator;
this->hasher = hasher_create(HASH_SHA1);
this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
this->src_seen = FALSE;
this->dst_seen = FALSE;
this->src_matched = FALSE;
+10 -15
View File
@@ -1,10 +1,3 @@
/**
* @file ike_natd.h
*
* @brief Interface ike_natd_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_natd ike_natd
* @{ @ingroup tasks
*/
#ifndef IKE_NATD_H_
@@ -30,12 +30,7 @@ typedef struct ike_natd_t ike_natd_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type ike_natd, detects NAT situation in IKE_SA_INIT exchange.
*
* @b Constructors:
* - ike_natd_create()
*
* @ingroup tasks
* Task of type ike_natd, detects NAT situation in IKE_SA_INIT exchange.
*/
struct ike_natd_t {
@@ -46,7 +41,7 @@ struct ike_natd_t {
};
/**
* @brief Create a new ike_natd task.
* Create a new ike_natd task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if thask is the original initator
@@ -54,4 +49,4 @@ struct ike_natd_t {
*/
ike_natd_t *ike_natd_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_NATD_H_ */
#endif /* IKE_NATD_H_ @} */
+3 -8
View File
@@ -1,10 +1,3 @@
/**
* @file ike_p2p.c
*
* @brief Implementation of the ike_p2p task.
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,8 +11,10 @@
* 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.
*
* $Id$
*/
#include "ike_p2p.h"
#include <string.h>
+14 -24
View File
@@ -1,10 +1,3 @@
/**
* @file ike_p2p.h
*
* @brief Interface ike_p2p_t.
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_p2p ike_p2p
* @{ @ingroup tasks
*/
#ifndef IKE_P2P_H_
@@ -30,7 +30,7 @@ typedef struct ike_p2p_t ike_p2p_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type IKE_P2P, detects and handles P2P-NAT-T extensions.
* Task of type IKE_P2P, detects and handles P2P-NAT-T extensions.
*
* This tasks handles the P2P_MEDIATION notify exchange to setup a mediation
* connection, allows to initiate mediated connections using P2P_CONNECT
@@ -40,11 +40,6 @@ typedef struct ike_p2p_t ike_p2p_t;
* @note This task has to be activated before the IKE_AUTH task, because that
* task generates the IKE_SA_INIT message so that no more payloads can be added
* to it afterwards.
*
* @b Constructors:
* - ike_p2p_create()
*
* @ingroup tasks
*/
struct ike_p2p_t {
@@ -54,38 +49,34 @@ struct ike_p2p_t {
task_t task;
/**
* @brief Initiates a connection with another peer (i.e. sends a P2P_CONNECT
* Initiates a connection with another peer (i.e. sends a P2P_CONNECT
* to the mediation server)
*
* @param this object
* @param peer_id ID of the other peer (gets cloned)
*/
void (*connect)(ike_p2p_t *this, identification_t *peer_id);
/**
* @brief Responds to a P2P_CONNECT from another peer (i.e. sends a P2P_CONNECT
* Responds to a P2P_CONNECT from another peer (i.e. sends a P2P_CONNECT
* to the mediation server)
*
* @param this object
* @param peer_id ID of the other peer (gets cloned)
* @param session_id the session ID as provided by the initiator (gets cloned)
*/
void (*respond)(ike_p2p_t *this, identification_t *peer_id, chunk_t session_id);
/**
* @brief Sends a P2P_CALLBACK to a peer that previously requested another peer.
* Sends a P2P_CALLBACK to a peer that previously requested another peer.
*
* @param this object
* @param peer_id ID of the other peer (gets cloned)
*/
void (*callback)(ike_p2p_t *this, identification_t *peer_id);
/**
* @brief Relays data to another peer (i.e. sends a P2P_CONNECT to the peer)
* Relays data to another peer (i.e. sends a P2P_CONNECT to the peer)
*
* Data gets cloned.
*
* @param this object
* @param requester ID of the requesting peer
* @param session_id content of the P2P_SESSIONID notify
* @param session_key content of the P2P_SESSIONKEY notify
@@ -98,7 +89,7 @@ struct ike_p2p_t {
};
/**
* @brief Create a new ike_p2p task.
* Create a new ike_p2p task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE if taks is initiated by us
@@ -106,5 +97,4 @@ struct ike_p2p_t {
*/
ike_p2p_t *ike_p2p_create(ike_sa_t *ike_sa, bool initiator);
#endif /*IKE_P2P_H_*/
#endif /*IKE_P2P_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file ike_reauth.c
*
* @brief Implementation of the ike_reauth task.
*
*/
/*
* Copyright (C) 2006-2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,8 @@
* 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.
*
* $Id$
*/
#include "ike_reauth.h"
+10 -16
View File
@@ -1,10 +1,3 @@
/**
* @file ike_reauth.h
*
* @brief Interface ike_reauth_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_reauth ike_reauth
* @{ @ingroup tasks
*/
#ifndef IKE_REAUTH_H_
@@ -30,12 +30,7 @@ typedef struct ike_reauth_t ike_reauth_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type ike_reauth, reestablishes an IKE_SA.
*
* @b Constructors:
* - ike_reauth_create()
*
* @ingroup tasks
* Task of type ike_reauth, reestablishes an IKE_SA.
*/
struct ike_reauth_t {
@@ -46,7 +41,7 @@ struct ike_reauth_t {
};
/**
* @brief Create a new ike_reauth task.
* Create a new ike_reauth task.
*
* This task is initiator only.
*
@@ -55,5 +50,4 @@ struct ike_reauth_t {
*/
ike_reauth_t *ike_reauth_create(ike_sa_t *ike_sa);
#endif /* IKE_REAUTH_H_ */
#endif /* IKE_REAUTH_H_ @} */
+2 -7
View File
@@ -1,10 +1,3 @@
/**
* @file ike_rekey.c
*
* @brief Implementation of the ike_rekey task.
*
*/
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include "ike_rekey.h"
+11 -17
View File
@@ -1,10 +1,3 @@
/**
* @file ike_rekey.h
*
* @brief Interface ike_rekey_t.
*
*/
/*
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
@@ -18,6 +11,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup ike_rekey ike_rekey
* @{ @ingroup tasks
*/
#ifndef IKE_REKEY_H_
@@ -30,12 +30,7 @@ typedef struct ike_rekey_t ike_rekey_t;
#include <sa/tasks/task.h>
/**
* @brief Task of type IKE_REKEY, rekey an established IKE_SA.
*
* @b Constructors:
* - ike_rekey_create()
*
* @ingroup tasks
* Task of type IKE_REKEY, rekey an established IKE_SA.
*/
struct ike_rekey_t {
@@ -45,20 +40,19 @@ struct ike_rekey_t {
task_t task;
/**
* @brief Register a rekeying task which collides with this one.
* Register a rekeying task which collides with this one.
*
* If two peers initiate rekeying at the same time, the collision must
* be handled gracefully. The task manager is aware of what exchanges
* are going on and notifies the outgoing task by passing the incoming.
*
* @param this task initated by us
* @param other incoming task
*/
void (*collide)(ike_rekey_t* this, task_t *other);
};
/**
* @brief Create a new IKE_REKEY task.
* Create a new IKE_REKEY task.
*
* @param ike_sa IKE_SA this task works for
* @param initiator TRUE for initiator, FALSE for responder
@@ -66,4 +60,4 @@ struct ike_rekey_t {
*/
ike_rekey_t *ike_rekey_create(ike_sa_t *ike_sa, bool initiator);
#endif /* IKE_REKEY_H_ */
#endif /* IKE_REKEY_H_ @} */
+4 -8
View File
@@ -1,10 +1,3 @@
/**
* @file task.c
*
* @brief Enum values for task types
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2007 Martin Willi
@@ -19,6 +12,8 @@
* 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.
*
* $Id$
*/
#include "task.h"
@@ -29,7 +24,8 @@ ENUM(task_type_names, IKE_INIT, CHILD_REKEY,
"IKE_MOBIKE",
"IKE_AUTHENTICATE",
"IKE_AUTH_LIFETIME",
"IKE_CERT",
"IKE_CERT_PRE",
"IKE_CERT_POST",
"IKE_CONFIG",
"IKE_REKEY",
"IKE_REAUTH",
+19 -31
View File
@@ -1,10 +1,3 @@
/**
* @file task.h
*
* @brief Interface task_t.
*
*/
/*
* Copyright (C) 2007 Tobias Brunner
* Copyright (C) 2006 Martin Willi
@@ -19,6 +12,13 @@
* 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.
*
* $Id$
*/
/**
* @defgroup task task
* @{ @ingroup tasks
*/
#ifndef TASK_H_
@@ -32,9 +32,7 @@ typedef struct task_t task_t;
#include <encoding/message.h>
/**
* @brief Different kinds of tasks.
*
* @ingroup tasks
* Different kinds of tasks.
*/
enum task_type_t {
/** establish an unauthenticated IKE_SA */
@@ -47,8 +45,10 @@ enum task_type_t {
IKE_AUTHENTICATE,
/** AUTH_LIFETIME negotiation, RFC4478 */
IKE_AUTH_LIFETIME,
/** exchange certificates and requests */
IKE_CERT,
/** certificate processing before authentication (certreqs, cert parsing) */
IKE_CERT_PRE,
/** certificate processing after authentication (certs payload generation) */
IKE_CERT_POST,
/** Configuration payloads, virtual IP and such */
IKE_CONFIG,
/** rekey an IKE_SA */
@@ -77,7 +77,7 @@ enum task_type_t {
extern enum_name_t *task_type_names;
/**
* @brief Interface for a task, an operation handled within exchanges.
* Interface for a task, an operation handled within exchanges.
*
* A task is an elemantary operation. It may be handled by a single or by
* multiple exchanges. An exchange may even complete multiple tasks.
@@ -94,18 +94,12 @@ extern enum_name_t *task_type_names;
* the task needs further build()/process() calls to complete, the manager
* leaves the taks in the queue. A returned FAILED indicates a critical failure.
* The manager closes the IKE_SA whenever a task returns FAILED.
*
* @b Constructors:
* - None, use implementations specific constructors
*
* @ingroup tasks
*/
struct task_t {
/**
* @brief Build a request or response message for this task.
* Build a request or response message for this task.
*
* @param this calling object
* @param message message to add payloads to
* @return
* - FAILED if a critical error occured
@@ -115,9 +109,8 @@ struct task_t {
status_t (*build) (task_t *this, message_t *message);
/**
* @brief Process a request or response message for this task.
* Process a request or response message for this task.
*
* @param this calling object
* @param message message to read payloads from
* @return
* - FAILED if a critical error occured
@@ -127,14 +120,12 @@ struct task_t {
status_t (*process) (task_t *this, message_t *message);
/**
* @brief Get the type of the task implementation.
*
* @param this calling object
* Get the type of the task implementation.
*/
task_type_t (*get_type) (task_t *this);
/**
* @brief Migrate a task to a new IKE_SA.
* Migrate a task to a new IKE_SA.
*
* After migrating a task, it goes back to a state where it can be
* used again to initate an exchange. This is useful when a task
@@ -144,17 +135,14 @@ struct task_t {
* try.
* The ike_sa is the new IKE_SA this task belongs to and operates on.
*
* @param this calling object
* @param ike_sa new IKE_SA this task works for
*/
void (*migrate) (task_t *this, ike_sa_t *ike_sa);
/**
* @brief Destroys a task_t object.
*
* @param this calling object
* Destroys a task_t object.
*/
void (*destroy) (task_t *this);
};
#endif /* TASK_H_ */
#endif /* TASK_H_ @} */