merged the modularization branch (credentials) back to trunk
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
@@ -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_ @}*/
|
||||
@@ -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_ */
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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_ @} */
|
||||
|
||||
@@ -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
@@ -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_ @} */
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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_ @} */
|
||||
|
||||
@@ -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
@@ -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_ @} */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_ @} */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_ @} */
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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_ @} */
|
||||
|
||||
@@ -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
@@ -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_ @} */
|
||||
|
||||
Reference in New Issue
Block a user