2005-11-08 09:37:39 +00:00
/**
* @ file message . c
2005-11-09 09:11:06 +00:00
*
2005-11-28 16:55:46 +00:00
* @ brief Implementation of message_t .
2005-11-09 09:11:06 +00:00
*
2005-11-08 09:37:39 +00:00
*/
/*
* Copyright ( C ) 2005 Jan Hutter , 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 .
*/
2005-11-08 09:47:17 +00:00
# include <stdlib.h>
2005-11-11 13:31:52 +00:00
# include "message.h"
2005-11-23 09:24:35 +00:00
# include <types.h>
2005-11-29 10:25:07 +00:00
# include <daemon.h>
2005-11-23 10:11:50 +00:00
# include <sa/ike_sa_id.h>
2005-11-23 09:57:18 +00:00
# include <encoding/generator.h>
# include <encoding/parser.h>
2005-11-23 09:24:35 +00:00
# include <utils/linked_list.h>
# include <utils/allocator.h>
# include <utils/logger_manager.h>
2005-11-23 09:57:18 +00:00
# include <encoding/payloads/encodings.h>
# include <encoding/payloads/payload.h>
2005-11-28 15:43:05 +00:00
# include <encoding/payloads/encryption_payload.h>
2005-11-10 17:17:46 +00:00
2005-12-05 12:21:38 +00:00
/**
* Max number of notify payloads per IKEv2 Message
*/
# define MAX_NOTIFY_PAYLOADS 10
2005-11-17 08:46:05 +00:00
2005-11-24 09:17:51 +00:00
typedef struct supported_payload_entry_t supported_payload_entry_t ;
2005-11-17 08:46:05 +00:00
/**
2005-11-28 16:55:46 +00:00
* Supported payload entry used in message_rule_t .
2005-11-17 08:46:05 +00:00
*
*/
2005-11-24 09:17:51 +00:00
struct supported_payload_entry_t {
2005-11-17 08:46:05 +00:00
/**
2005-11-28 16:55:46 +00:00
* Payload type .
2005-11-17 08:46:05 +00:00
*/
payload_type_t payload_type ;
/**
2005-11-28 16:55:46 +00:00
* Minimal occurence of this payload .
2005-11-17 08:46:05 +00:00
*/
size_t min_occurence ;
/**
2005-11-28 16:55:46 +00:00
* Max occurence of this payload .
2005-11-17 08:46:05 +00:00
*/
size_t max_occurence ;
2005-11-29 17:19:59 +00:00
/**
* TRUE if payload has to get encrypted
*/
bool encrypted ;
2005-12-02 11:38:56 +00:00
/**
* Verifying can stop after checking this payload .
*/
bool can_be_last ;
2005-11-17 08:46:05 +00:00
} ;
2005-11-24 09:17:51 +00:00
typedef struct message_rule_t message_rule_t ;
2005-11-17 08:46:05 +00:00
/**
2005-11-28 16:55:46 +00:00
* Message Rule used to find out which payloads
* are supported by each message type .
2005-11-17 08:46:05 +00:00
*
*/
2005-11-24 09:17:51 +00:00
struct message_rule_t {
2005-11-17 08:46:05 +00:00
/**
2005-11-28 16:55:46 +00:00
* Type of message .
2005-11-17 08:46:05 +00:00
*/
exchange_type_t exchange_type ;
/**
2005-11-28 16:55:46 +00:00
* Is message a request or response .
2005-11-17 08:46:05 +00:00
*/
bool is_request ;
2005-11-30 08:32:23 +00:00
/**
* Message contains encrypted content .
*/
bool encrypted_content ;
2005-11-17 08:46:05 +00:00
/**
2005-11-28 16:55:46 +00:00
* Number of supported payloads .
2005-11-17 08:46:05 +00:00
*/
size_t supported_payloads_count ;
2005-11-30 08:32:23 +00:00
2005-11-17 08:46:05 +00:00
/**
2005-11-28 16:55:46 +00:00
* Pointer to first supported payload entry .
2005-11-17 08:46:05 +00:00
*/
supported_payload_entry_t * supported_payloads ;
} ;
2005-11-21 15:34:44 +00:00
/**
2005-11-28 16:55:46 +00:00
* Message rule for IKE_SA_INIT from initiator .
2005-11-21 15:34:44 +00:00
*/
2005-11-17 11:19:45 +00:00
static supported_payload_entry_t supported_ike_sa_init_i_payloads [ ] =
2005-11-17 08:46:05 +00:00
{
2005-12-05 12:21:38 +00:00
{ NOTIFY , 0 , MAX_NOTIFY_PAYLOADS , FALSE , FALSE } ,
2005-12-02 11:38:56 +00:00
{ SECURITY_ASSOCIATION , 1 , 1 , FALSE , FALSE } ,
{ KEY_EXCHANGE , 1 , 1 , FALSE , FALSE } ,
{ NONCE , 1 , 1 , FALSE , FALSE } ,
2005-11-17 08:46:05 +00:00
} ;
2005-11-21 15:34:44 +00:00
/**
2005-11-28 16:55:46 +00:00
* Message rule for IKE_SA_INIT from responder .
2005-11-21 15:34:44 +00:00
*/
2005-11-17 11:19:45 +00:00
static supported_payload_entry_t supported_ike_sa_init_r_payloads [ ] =
2005-11-17 08:46:05 +00:00
{
2005-12-05 12:21:38 +00:00
{ NOTIFY , 0 , MAX_NOTIFY_PAYLOADS , FALSE , TRUE } ,
2005-12-02 11:38:56 +00:00
{ SECURITY_ASSOCIATION , 1 , 1 , FALSE , FALSE } ,
{ KEY_EXCHANGE , 1 , 1 , FALSE , FALSE } ,
{ NONCE , 1 , 1 , FALSE , FALSE } ,
2005-11-17 08:46:05 +00:00
} ;
2005-11-29 17:19:59 +00:00
/**
* Message rule for IKE_AUTH from initiator .
*/
static supported_payload_entry_t supported_ike_auth_i_payloads [ ] =
{
2005-12-05 12:21:38 +00:00
{ NOTIFY , 0 , MAX_NOTIFY_PAYLOADS , TRUE , FALSE } ,
2005-12-02 11:38:56 +00:00
{ ID_INITIATOR , 1 , 1 , TRUE , FALSE } ,
{ CERTIFICATE , 0 , 1 , TRUE , FALSE } ,
{ CERTIFICATE_REQUEST , 0 , 1 , TRUE , FALSE } ,
{ ID_RESPONDER , 0 , 1 , TRUE , FALSE } ,
{ AUTHENTICATION , 1 , 1 , TRUE , FALSE } ,
{ SECURITY_ASSOCIATION , 1 , 1 , TRUE , FALSE } ,
{ TRAFFIC_SELECTOR_INITIATOR , 1 , 1 , TRUE , FALSE } ,
{ TRAFFIC_SELECTOR_RESPONDER , 1 , 1 , TRUE , FALSE } ,
2005-11-29 17:19:59 +00:00
} ;
/**
* Message rule for IKE_AUTH from responder .
*/
static supported_payload_entry_t supported_ike_auth_r_payloads [ ] =
{
2005-12-05 12:21:38 +00:00
{ NOTIFY , 0 , MAX_NOTIFY_PAYLOADS , TRUE , TRUE } ,
2005-12-02 11:38:56 +00:00
{ CERTIFICATE , 0 , 1 , TRUE , FALSE } ,
2005-12-02 16:09:04 +00:00
{ ID_RESPONDER , 1 , 1 , TRUE , FALSE } ,
2005-12-02 11:38:56 +00:00
{ AUTHENTICATION , 1 , 1 , TRUE , FALSE } ,
{ SECURITY_ASSOCIATION , 1 , 1 , TRUE , FALSE } ,
{ TRAFFIC_SELECTOR_INITIATOR , 1 , 1 , TRUE , FALSE } ,
{ TRAFFIC_SELECTOR_RESPONDER , 1 , 1 , TRUE , FALSE } ,
2005-11-29 17:19:59 +00:00
} ;
2005-11-21 15:34:44 +00:00
/**
2005-11-28 16:55:46 +00:00
* Message rules , defines allowed payloads .
2005-11-21 15:34:44 +00:00
*/
2005-11-17 11:19:45 +00:00
static message_rule_t message_rules [ ] = {
2005-11-30 08:32:23 +00:00
{ IKE_SA_INIT , TRUE , FALSE , ( sizeof ( supported_ike_sa_init_i_payloads ) / sizeof ( supported_payload_entry_t ) ) , supported_ike_sa_init_i_payloads } ,
{ IKE_SA_INIT , FALSE , FALSE , ( sizeof ( supported_ike_sa_init_r_payloads ) / sizeof ( supported_payload_entry_t ) ) , supported_ike_sa_init_r_payloads } ,
2005-11-30 08:46:56 +00:00
{ IKE_AUTH , TRUE , TRUE , ( sizeof ( supported_ike_auth_i_payloads ) / sizeof ( supported_payload_entry_t ) ) , supported_ike_auth_i_payloads } ,
{ IKE_AUTH , FALSE , TRUE , ( sizeof ( supported_ike_auth_r_payloads ) / sizeof ( supported_payload_entry_t ) ) , supported_ike_auth_r_payloads }
2005-11-17 08:46:05 +00:00
} ;
2005-11-24 11:30:19 +00:00
typedef struct payload_entry_t payload_entry_t ;
2005-11-10 17:17:46 +00:00
/**
2005-11-28 16:55:46 +00:00
* Entry for a payload in the internal used linked list .
2005-11-10 17:17:46 +00:00
*
*/
2005-11-24 11:30:19 +00:00
struct payload_entry_t {
2005-11-10 17:17:46 +00:00
/**
2005-11-28 16:55:46 +00:00
* Type of payload .
2005-11-10 17:17:46 +00:00
*/
payload_type_t payload_type ;
/**
2005-11-28 16:55:46 +00:00
* Data struct holding the data of given payload .
2005-11-10 17:17:46 +00:00
*/
void * data_struct ;
} ;
2005-11-08 09:47:17 +00:00
2005-11-24 11:30:19 +00:00
typedef struct private_message_t private_message_t ;
2005-11-08 09:47:17 +00:00
/**
2005-11-28 16:55:46 +00:00
* Private data of an message_t object .
2005-11-08 09:47:17 +00:00
*/
2005-11-24 11:30:19 +00:00
struct private_message_t {
2005-11-08 09:47:17 +00:00
/**
2005-11-28 16:55:46 +00:00
* Public part of a message_t object .
2005-11-08 09:47:17 +00:00
*/
message_t public ;
2005-11-09 09:11:06 +00:00
2005-11-17 08:46:05 +00:00
/**
2005-11-28 16:55:46 +00:00
* Minor version of message .
2005-11-17 08:46:05 +00:00
*/
u_int8_t major_version ;
/**
2005-11-28 16:55:46 +00:00
* Major version of message .
2005-11-17 08:46:05 +00:00
*/
u_int8_t minor_version ;
/**
2005-11-28 16:55:46 +00:00
* First Payload in message .
2005-11-17 08:46:05 +00:00
*/
payload_type_t first_payload ;
2005-11-10 17:17:46 +00:00
/**
2005-11-28 16:55:46 +00:00
* Assigned exchange type .
2005-11-10 17:17:46 +00:00
*/
2005-11-16 16:09:15 +00:00
exchange_type_t exchange_type ;
2005-11-18 12:01:53 +00:00
2005-11-10 17:17:46 +00:00
/**
* TRUE if message is request .
* FALSE if message is reply .
*/
bool is_request ;
2005-11-10 15:38:38 +00:00
2005-11-10 17:49:20 +00:00
/**
2005-11-28 16:55:46 +00:00
* Message ID of this message .
2005-11-10 17:49:20 +00:00
*/
u_int32_t message_id ;
/**
2005-11-28 16:55:46 +00:00
* ID of assigned IKE_SA .
2005-11-10 17:49:20 +00:00
*/
ike_sa_id_t * ike_sa_id ;
2005-11-10 15:38:38 +00:00
/**
* Assigned UDP packet .
*
* Stores incoming packet or last generated one .
*/
2005-11-16 16:09:15 +00:00
packet_t * packet ;
2005-11-10 15:38:38 +00:00
2005-11-16 16:09:15 +00:00
/**
2005-11-28 16:55:46 +00:00
* Linked List where payload data are stored in .
2005-11-16 16:09:15 +00:00
*/
2005-11-10 15:38:38 +00:00
linked_list_t * payloads ;
2005-11-16 16:09:15 +00:00
2005-11-16 16:50:13 +00:00
/**
2005-11-28 16:55:46 +00:00
* Assigned parser to parse Header and Body of this message .
2005-11-16 16:50:13 +00:00
*/
parser_t * parser ;
2005-11-16 16:09:15 +00:00
/**
2005-11-28 16:55:46 +00:00
* Assigned logger .
2005-11-16 16:09:15 +00:00
*/
logger_t * logger ;
2005-11-17 11:19:45 +00:00
/**
2005-11-30 12:58:57 +00:00
* Gets a list of supported payloads of this message type .
2005-11-17 11:19:45 +00:00
*
2005-11-30 12:58:57 +00:00
* @ param this calling object
* @ param [ out ] message_rule pointer is set to the message_rule
* of current message type
2005-11-17 11:19:45 +00:00
*
2005-11-28 16:55:46 +00:00
* @ return
2005-11-30 12:58:57 +00:00
* - SUCCESS
* - NOT_FOUND if no message rule
* for specific message type could be found
2005-11-17 11:19:45 +00:00
*/
2005-11-30 08:32:23 +00:00
status_t ( * get_message_rule ) ( private_message_t * this , message_rule_t * * message_rule ) ;
2005-11-30 12:58:57 +00:00
/**
* Gets the supported_payload_entry_t for a specific message_rule_t and payload type .
*
* @ param this calling object
* @ param message_rule message rule
* @ param payload_type payload type
* @ param [ out ] payload_entry returned payload_entry_t
*
* @ return
* - SUCCESS
* - NOT_FOUND if no message rule
* for specific message type could be found
*/
2005-11-30 08:32:23 +00:00
status_t ( * get_supported_payload_entry ) ( private_message_t * this , message_rule_t * message_rule , payload_type_t payload_type , supported_payload_entry_t * * payload_entry ) ;
2005-11-17 11:19:45 +00:00
2005-11-29 17:19:59 +00:00
/**
* Encrypts all payloads which has to get encrypted .
*
2005-11-30 12:58:57 +00:00
* Can also be called with messages not containing encrypted content .
*
* @ param this calling object
2005-11-30 08:32:23 +00:00
* @ param crypter crypter_t object
* @ param signer signer_t object
2005-11-29 17:19:59 +00:00
*/
status_t ( * encrypt_payloads ) ( private_message_t * this , crypter_t * crypter , signer_t * signer ) ;
2005-11-30 08:32:23 +00:00
/**
2005-11-30 12:58:57 +00:00
* Decrypts encrypted contents and also verifies all payloads .
2005-11-30 08:32:23 +00:00
*
* @ param this calling object
* @ param crypter crypter_t object
* @ param signer signer_t object
*/
2005-11-30 12:58:57 +00:00
status_t ( * decrypt_and_verify_payloads ) ( private_message_t * this , crypter_t * crypter , signer_t * signer ) ;
2005-11-08 09:47:17 +00:00
} ;
2005-11-17 11:19:45 +00:00
/**
2005-11-28 16:55:46 +00:00
* Implementation of private_message_t . get_supported_payloads .
2005-11-17 11:19:45 +00:00
*/
2005-11-30 08:32:23 +00:00
static status_t get_message_rule ( private_message_t * this , message_rule_t * * message_rule )
2005-11-17 11:19:45 +00:00
{
int i ;
2005-11-30 08:32:23 +00:00
2005-11-17 11:19:45 +00:00
for ( i = 0 ; i < ( sizeof ( message_rules ) / sizeof ( message_rule_t ) ) ; i + + )
{
2005-11-30 08:32:23 +00:00
if ( ( this - > exchange_type = = message_rules [ i ] . exchange_type ) & &
( this - > is_request = = message_rules [ i ] . is_request ) )
2005-11-17 11:19:45 +00:00
{
/* found rule for given exchange_type*/
2005-11-30 08:32:23 +00:00
* message_rule = & ( message_rules [ i ] ) ;
2005-11-17 11:19:45 +00:00
return SUCCESS ;
}
}
2005-11-30 08:32:23 +00:00
* message_rule = NULL ;
return NOT_FOUND ;
}
2005-11-30 12:58:57 +00:00
/**
* Implementation of private_message_t . get_supported_payload_entry .
*/
2005-11-30 08:32:23 +00:00
static status_t get_supported_payload_entry ( private_message_t * this , message_rule_t * message_rule , payload_type_t payload_type , supported_payload_entry_t * * payload_entry )
{
int i ;
for ( i = 0 ; i < message_rule - > supported_payloads_count ; i + + )
{
if ( message_rule - > supported_payloads [ i ] . payload_type = = payload_type )
{
* payload_entry = & ( message_rule - > supported_payloads [ i ] ) ;
return SUCCESS ;
}
}
* payload_entry = NULL ;
2005-11-17 11:19:45 +00:00
return NOT_FOUND ;
}
2005-11-10 17:49:20 +00:00
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . set_ike_sa_id .
2005-11-10 17:49:20 +00:00
*/
2005-11-28 16:55:46 +00:00
static void set_ike_sa_id ( private_message_t * this , ike_sa_id_t * ike_sa_id )
2005-11-10 17:49:20 +00:00
{
2005-11-28 20:29:47 +00:00
this - > ike_sa_id = ike_sa_id - > clone ( ike_sa_id ) ;
2005-11-10 17:49:20 +00:00
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . get_ike_sa_id .
2005-11-10 17:49:20 +00:00
*/
static status_t get_ike_sa_id ( private_message_t * this , ike_sa_id_t * * ike_sa_id )
{
if ( this - > ike_sa_id = = NULL )
{
return FAILED ;
}
2005-11-28 20:29:47 +00:00
* ike_sa_id = this - > ike_sa_id - > clone ( this - > ike_sa_id ) ;
2005-11-28 16:55:46 +00:00
return SUCCESS ;
2005-11-10 17:49:20 +00:00
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . set_message_id .
2005-11-10 17:49:20 +00:00
*/
2005-11-28 16:55:46 +00:00
static void set_message_id ( private_message_t * this , u_int32_t message_id )
2005-11-10 17:49:20 +00:00
{
this - > message_id = message_id ;
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . get_message_id .
2005-11-10 17:49:20 +00:00
*/
static u_int32_t get_message_id ( private_message_t * this )
{
return this - > message_id ;
}
2005-11-22 15:37:32 +00:00
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . get_responder_spi .
2005-11-22 15:37:32 +00:00
*/
static u_int64_t get_responder_spi ( private_message_t * this )
{
return ( this - > ike_sa_id - > get_responder_spi ( this - > ike_sa_id ) ) ;
}
2005-11-17 08:46:05 +00:00
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . set_major_version .
2005-11-17 08:46:05 +00:00
*/
2005-11-28 16:55:46 +00:00
static void set_major_version ( private_message_t * this , u_int8_t major_version )
2005-11-17 08:46:05 +00:00
{
this - > major_version = major_version ;
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . set_major_version .
2005-11-17 08:46:05 +00:00
*/
static u_int8_t get_major_version ( private_message_t * this )
{
return this - > major_version ;
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . set_minor_version .
2005-11-17 08:46:05 +00:00
*/
2005-11-28 16:55:46 +00:00
static void set_minor_version ( private_message_t * this , u_int8_t minor_version )
2005-11-17 08:46:05 +00:00
{
this - > minor_version = minor_version ;
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . get_minor_version .
2005-11-17 08:46:05 +00:00
*/
static u_int8_t get_minor_version ( private_message_t * this )
{
return this - > minor_version ;
}
2005-11-10 17:49:20 +00:00
2005-11-10 17:17:46 +00:00
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . set_exchange_type .
2005-11-10 17:17:46 +00:00
*/
2005-11-28 16:55:46 +00:00
static void set_exchange_type ( private_message_t * this , exchange_type_t exchange_type )
2005-11-10 17:17:46 +00:00
{
this - > exchange_type = exchange_type ;
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . get_exchange_type .
2005-11-10 17:17:46 +00:00
*/
static exchange_type_t get_exchange_type ( private_message_t * this )
{
return this - > exchange_type ;
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . set_request .
2005-11-10 17:17:46 +00:00
*/
2005-11-28 16:55:46 +00:00
static void set_request ( private_message_t * this , bool request )
2005-11-10 17:17:46 +00:00
{
this - > is_request = request ;
}
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . get_request .
2005-11-10 17:17:46 +00:00
*/
static exchange_type_t get_request ( private_message_t * this )
{
return this - > is_request ;
}
2005-11-28 16:55:46 +00:00
/**
* Implementation of message_t . add_payload .
*/
static void add_payload ( private_message_t * this , payload_t * payload )
2005-11-16 16:09:15 +00:00
{
2005-11-18 13:59:21 +00:00
payload_t * last_payload ;
2005-11-28 16:55:46 +00:00
if ( this - > payloads - > get_count ( this - > payloads ) > 0 )
2005-11-18 13:59:21 +00:00
{
2005-11-28 16:55:46 +00:00
this - > payloads - > get_last ( this - > payloads , ( void * * ) & last_payload ) ;
2005-11-30 09:11:48 +00:00
last_payload - > set_next_type ( last_payload , payload - > get_type ( payload ) ) ;
2005-11-18 13:59:21 +00:00
}
else
{
2005-11-30 09:11:48 +00:00
this - > first_payload = payload - > get_type ( payload ) ;
2005-11-18 13:59:21 +00:00
}
2005-11-30 09:11:48 +00:00
payload - > set_next_type ( payload , NO_PAYLOAD ) ;
this - > payloads - > insert_last ( this - > payloads , ( void * ) payload ) ;
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Added payload of type %s to message " ,
mapping_find ( payload_type_m , payload - > get_type ( payload ) ) ) ;
2005-11-16 16:09:15 +00:00
}
2005-11-28 16:55:46 +00:00
/**
* Implementation of message_t . set_source .
*/
static void set_source ( private_message_t * this , host_t * host )
2005-11-16 16:09:15 +00:00
{
if ( this - > packet - > source ! = NULL )
{
this - > packet - > source - > destroy ( this - > packet - > source ) ;
}
this - > packet - > source = host ;
}
2005-11-28 16:55:46 +00:00
/**
* Implementation of message_t . set_destination .
*/
static void set_destination ( private_message_t * this , host_t * host )
2005-11-16 16:09:15 +00:00
{
if ( this - > packet - > destination ! = NULL )
{
this - > packet - > destination - > destroy ( this - > packet - > destination ) ;
}
this - > packet - > destination = host ;
}
2005-11-28 16:55:46 +00:00
/**
* Implementation of message_t . get_source .
*/
2005-11-30 12:58:57 +00:00
static host_t * get_source ( private_message_t * this )
2005-11-16 16:09:15 +00:00
{
2005-11-30 12:58:57 +00:00
return this - > packet - > source ;
2005-11-16 16:09:15 +00:00
}
2005-11-28 16:55:46 +00:00
/**
* Implementation of message_t . get_destination .
*/
2005-11-30 12:58:57 +00:00
static host_t * get_destination ( private_message_t * this )
2005-11-16 16:09:15 +00:00
{
2005-11-30 12:58:57 +00:00
return this - > packet - > destination ;
2005-11-16 16:09:15 +00:00
}
2005-11-28 16:55:46 +00:00
/**
* Implementation of message_t . get_destination .
*/
2005-11-29 08:54:48 +00:00
static iterator_t * get_payload_iterator ( private_message_t * this )
2005-11-18 10:31:56 +00:00
{
2005-11-29 08:54:48 +00:00
return this - > payloads - > create_iterator ( this - > payloads , TRUE ) ;
2005-11-18 10:31:56 +00:00
}
2005-11-10 17:17:46 +00:00
/**
2005-11-28 16:55:46 +00:00
* Implementation of message_t . generate .
2005-11-10 17:17:46 +00:00
*/
2005-11-28 15:43:05 +00:00
static status_t generate ( private_message_t * this , crypter_t * crypter , signer_t * signer , packet_t * * packet )
2005-11-10 17:17:46 +00:00
{
2005-11-16 16:09:15 +00:00
generator_t * generator ;
ike_header_t * ike_header ;
payload_t * payload , * next_payload ;
2005-11-24 14:22:29 +00:00
iterator_t * iterator ;
2005-11-30 12:58:57 +00:00
message_rule_t * message_rule ;
2005-11-16 16:09:15 +00:00
status_t status ;
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL , " Generating message of type %s, contains %d payloads " ,
mapping_find ( exchange_type_m , this - > exchange_type ) ,
this - > payloads - > get_count ( this - > payloads ) ) ;
2005-11-21 15:34:44 +00:00
2005-11-16 16:09:15 +00:00
if ( this - > exchange_type = = EXCHANGE_TYPE_UNDEFINED )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Exchange type %s is not defined " , mapping_find ( exchange_type_m , this - > exchange_type ) ) ;
2005-11-16 16:09:15 +00:00
return INVALID_STATE ;
}
2005-11-30 12:58:57 +00:00
status = this - > get_message_rule ( this , & message_rule ) ;
if ( status ! = SUCCESS )
{
this - > logger - > log ( this - > logger , ERROR | MORE , " Message rule could not be found for exchange type %s " ,
mapping_find ( exchange_type_m , this - > exchange_type ) ) ;
return status ;
}
2005-11-16 16:09:15 +00:00
if ( this - > packet - > source = = NULL | |
this - > packet - > destination = = NULL )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Source/destination not defined " ) ;
2005-11-16 16:09:15 +00:00
return INVALID_STATE ;
}
2005-11-30 12:58:57 +00:00
/* going to encrypt all content which have to be encrypted */
2005-11-29 17:19:59 +00:00
status = this - > encrypt_payloads ( this , crypter , signer ) ;
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Could not encrypt payloads " ) ;
2005-11-29 17:19:59 +00:00
return status ;
}
2005-11-28 15:43:05 +00:00
/* build ike header */
2005-11-16 16:09:15 +00:00
ike_header = ike_header_create ( ) ;
2005-11-28 16:55:46 +00:00
2005-11-16 16:09:15 +00:00
ike_header - > set_exchange_type ( ike_header , this - > exchange_type ) ;
ike_header - > set_message_id ( ike_header , this - > message_id ) ;
ike_header - > set_response_flag ( ike_header , ! this - > is_request ) ;
2005-11-18 13:59:21 +00:00
ike_header - > set_initiator_flag ( ike_header , this - > ike_sa_id - > is_initiator ( this - > ike_sa_id ) ) ;
ike_header - > set_initiator_spi ( ike_header , this - > ike_sa_id - > get_initiator_spi ( this - > ike_sa_id ) ) ;
ike_header - > set_responder_spi ( ike_header , this - > ike_sa_id - > get_responder_spi ( this - > ike_sa_id ) ) ;
2005-11-29 17:19:59 +00:00
2005-11-16 16:09:15 +00:00
generator = generator_create ( ) ;
payload = ( payload_t * ) ike_header ;
2005-11-29 08:54:48 +00:00
iterator = this - > payloads - > create_iterator ( this - > payloads , TRUE ) ;
2005-11-28 16:55:46 +00:00
2005-11-30 12:58:57 +00:00
/* generate every payload expect last one*/
2005-11-16 16:09:15 +00:00
while ( iterator - > has_next ( iterator ) )
2005-11-10 17:17:46 +00:00
{
2005-11-16 16:09:15 +00:00
iterator - > current ( iterator , ( void * * ) & next_payload ) ;
payload - > set_next_type ( payload , next_payload - > get_type ( next_payload ) ) ;
2005-11-28 16:34:48 +00:00
generator - > generate_payload ( generator , payload ) ;
2005-11-16 16:09:15 +00:00
payload = next_payload ;
2005-11-10 17:17:46 +00:00
}
2005-11-16 16:09:15 +00:00
iterator - > destroy ( iterator ) ;
2005-11-30 12:58:57 +00:00
/* last payload has no next payload*/
2005-11-16 16:09:15 +00:00
payload - > set_next_type ( payload , NO_PAYLOAD ) ;
2005-11-29 17:19:59 +00:00
2005-11-28 16:34:48 +00:00
generator - > generate_payload ( generator , payload ) ;
2005-11-30 12:58:57 +00:00
2005-11-16 16:09:15 +00:00
ike_header - > destroy ( ike_header ) ;
2005-11-28 15:43:05 +00:00
/* build packet */
2005-11-16 16:09:15 +00:00
if ( this - > packet - > data . ptr ! = NULL )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Replace last generated packet data " ) ;
2005-11-16 16:09:15 +00:00
allocator_free ( this - > packet - > data . ptr ) ;
}
2005-11-28 16:34:48 +00:00
generator - > write_to_chunk ( generator , & ( this - > packet - > data ) ) ;
2005-11-28 15:43:05 +00:00
generator - > destroy ( generator ) ;
2005-11-16 16:09:15 +00:00
2005-11-30 12:58:57 +00:00
/* if last payload is of type encrypted, integrity checksum if necessary */
2005-11-28 15:43:05 +00:00
if ( payload - > get_type ( payload ) = = ENCRYPTED )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Build signature on whole message " ) ;
2005-11-28 15:43:05 +00:00
encryption_payload_t * encryption_payload = ( encryption_payload_t * ) payload ;
status = encryption_payload - > build_signature ( encryption_payload , this - > packet - > data ) ;
if ( status ! = SUCCESS )
{
return status ;
}
}
2005-11-21 15:34:44 +00:00
2005-11-29 08:08:03 +00:00
/* clone packet for caller */
* packet = this - > packet - > clone ( this - > packet ) ;
2005-11-21 15:34:44 +00:00
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL , " Message of type %s generated successfully " , mapping_find ( exchange_type_m , this - > exchange_type ) ) ;
2005-11-10 17:17:46 +00:00
return SUCCESS ;
}
2005-12-02 13:20:20 +00:00
/**
* Implementation of message_t . get_packet .
*/
static packet_t * get_packet ( private_message_t * this )
{
return this - > packet - > clone ( this - > packet ) ;
}
2005-12-03 14:47:58 +00:00
/**
* Implementation of message_t . get_packet_data .
*/
static chunk_t get_packet_data ( private_message_t * this )
{
return allocator_clone_chunk ( this - > packet - > data ) ;
}
2005-11-16 16:50:13 +00:00
/**
2005-11-30 12:58:57 +00:00
* Implementation of message_t . parse_header .
2005-11-16 16:50:13 +00:00
*/
2005-11-21 15:34:44 +00:00
static status_t parse_header ( private_message_t * this )
2005-11-16 16:50:13 +00:00
{
ike_header_t * ike_header ;
status_t status ;
2005-11-21 15:34:44 +00:00
2005-12-04 11:46:58 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " parsing Header of message " ) ;
2005-11-21 15:34:44 +00:00
2005-11-16 16:50:13 +00:00
this - > parser - > reset_context ( this - > parser ) ;
status = this - > parser - > parse_payload ( this - > parser , HEADER , ( payload_t * * ) & ike_header ) ;
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Header could not be parsed " ) ;
2005-11-16 16:50:13 +00:00
return status ;
}
2005-11-17 12:50:54 +00:00
/* verify payload */
status = ike_header - > payload_interface . verify ( & ( ike_header - > payload_interface ) ) ;
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Header verification failed " ) ;
2005-11-22 12:36:27 +00:00
ike_header - > destroy ( ike_header ) ;
2005-11-17 12:50:54 +00:00
return status ;
}
2005-11-16 17:20:03 +00:00
if ( this - > ike_sa_id ! = NULL )
{
this - > ike_sa_id - > destroy ( this - > ike_sa_id ) ;
}
2005-11-18 12:01:53 +00:00
this - > ike_sa_id = ike_sa_id_create ( ike_header - > get_initiator_spi ( ike_header ) ,
ike_header - > get_responder_spi ( ike_header ) ,
2005-11-21 15:34:44 +00:00
ike_header - > get_initiator_flag ( ike_header ) ) ;
2005-11-28 16:55:46 +00:00
2005-11-16 17:20:03 +00:00
this - > exchange_type = ike_header - > get_exchange_type ( ike_header ) ;
this - > message_id = ike_header - > get_message_id ( ike_header ) ;
2005-11-17 11:19:45 +00:00
this - > is_request = ( ! ( ike_header - > get_response_flag ( ike_header ) ) ) ;
2005-11-17 08:46:05 +00:00
this - > major_version = ike_header - > get_maj_version ( ike_header ) ;
this - > minor_version = ike_header - > get_min_version ( ike_header ) ;
this - > first_payload = ike_header - > payload_interface . get_next_type ( & ( ike_header - > payload_interface ) ) ;
2005-12-04 11:46:58 +00:00
this - > logger - > log ( this - > logger , CONTROL , " Parsed a %s %s " , mapping_find ( exchange_type_m , this - > exchange_type ) ,
this - > is_request ? " request " : " response " ) ;
2005-11-21 15:34:44 +00:00
2005-11-17 08:46:05 +00:00
ike_header - > destroy ( ike_header ) ;
return SUCCESS ;
}
/**
2005-11-30 12:58:57 +00:00
* Implementation of message_t . parse_body .
2005-11-17 08:46:05 +00:00
*/
2005-11-28 15:43:05 +00:00
static status_t parse_body ( private_message_t * this , crypter_t * crypter , signer_t * signer )
2005-11-17 08:46:05 +00:00
{
2005-11-18 16:29:14 +00:00
status_t status = SUCCESS ;
2005-11-17 08:46:05 +00:00
payload_type_t current_payload_type = this - > first_payload ;
2005-11-21 15:34:44 +00:00
2005-12-04 11:46:58 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Parsing body of message, first payload %s " ,
2005-11-30 12:58:57 +00:00
mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-30 08:32:23 +00:00
while ( ( current_payload_type ! = NO_PAYLOAD ) )
2005-11-16 17:20:03 +00:00
{
2005-11-17 08:46:05 +00:00
payload_t * current_payload ;
2005-11-21 13:45:07 +00:00
2005-12-04 11:46:58 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Start parsing payload of type %s " ,
2005-11-21 15:34:44 +00:00
mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-17 08:46:05 +00:00
status = this - > parser - > parse_payload ( this - > parser , current_payload_type , ( payload_t * * ) & current_payload ) ;
2005-11-17 11:19:45 +00:00
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR , " Payload type %s could not be parsed " , mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-28 15:43:05 +00:00
return status ;
2005-11-17 11:19:45 +00:00
}
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Verify payload of type %s " ,
mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-17 08:46:05 +00:00
2005-11-17 12:50:54 +00:00
status = current_payload - > verify ( current_payload ) ;
2005-11-17 11:19:45 +00:00
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR , " Payload type %s could not be verified " , mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-29 12:23:40 +00:00
current_payload - > destroy ( current_payload ) ;
2005-11-17 12:50:54 +00:00
status = VERIFY_ERROR ;
2005-11-28 15:43:05 +00:00
return status ;
}
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Payload verified. Adding to payload list " ,
mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-28 20:29:47 +00:00
this - > payloads - > insert_last ( this - > payloads , current_payload ) ;
2005-11-30 10:23:15 +00:00
2005-11-30 12:58:57 +00:00
/* stop if an encryption payload found */
2005-11-30 10:23:15 +00:00
if ( current_payload_type = = ENCRYPTED )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Payload of type encrypted found. Stop parsing. " ,
mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-30 10:23:15 +00:00
break ;
}
/* get next payload type */
current_payload_type = current_payload - > get_next_type ( current_payload ) ;
2005-11-16 17:20:03 +00:00
}
2005-12-04 11:46:58 +00:00
this - > logger - > log ( this - > logger , CONTROL , " Message a %s %s contains %d payloads " ,
mapping_find ( exchange_type_m , this - > exchange_type ) ,
this - > is_request ? " request " : " response " ,
this - > payloads - > get_count ( this - > payloads ) ) ;
2005-11-30 12:58:57 +00:00
status = this - > decrypt_and_verify_payloads ( this , crypter , signer ) ;
2005-11-30 08:32:23 +00:00
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR , " Could not decrypt and verify payloads " ) ;
2005-11-30 08:32:23 +00:00
return status ;
}
return SUCCESS ;
2005-11-28 15:43:05 +00:00
}
/**
2005-11-30 12:58:57 +00:00
* Implementation of message_t . verify .
2005-11-28 15:43:05 +00:00
*/
static status_t verify ( private_message_t * this )
{
int i ;
2005-11-30 08:32:23 +00:00
status_t status ;
iterator_t * iterator ;
message_rule_t * message_rule ;
2005-12-02 11:38:56 +00:00
size_t total_found_payloads = 0 ;
2005-11-28 15:43:05 +00:00
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Verifying message structure " ) ;
2005-11-28 15:43:05 +00:00
2005-11-30 08:32:23 +00:00
status = this - > get_message_rule ( this , & message_rule ) ;
2005-11-17 11:19:45 +00:00
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Message rule could not be found for exchange type %s " ,
mapping_find ( exchange_type_m , this - > exchange_type ) ) ;
2005-11-28 15:43:05 +00:00
return status ;
2005-11-17 11:19:45 +00:00
}
2005-12-02 11:38:56 +00:00
2005-11-29 08:54:48 +00:00
iterator = this - > payloads - > create_iterator ( this - > payloads , TRUE ) ;
2005-11-28 15:43:05 +00:00
/* check for payloads with wrong count*/
2005-11-30 08:32:23 +00:00
for ( i = 0 ; i < message_rule - > supported_payloads_count ; i + + )
2005-11-28 15:43:05 +00:00
{
size_t found_payloads = 0 ;
2005-11-17 11:19:45 +00:00
2005-11-30 12:58:57 +00:00
/* check all payloads for specific rule */
2005-11-28 15:43:05 +00:00
iterator - > reset ( iterator ) ;
while ( iterator - > has_next ( iterator ) )
{
payload_t * current_payload ;
2005-11-28 16:55:46 +00:00
iterator - > current ( iterator , ( void * * ) & current_payload ) ;
2005-11-29 08:54:48 +00:00
2005-11-30 12:58:57 +00:00
if ( current_payload - > get_type ( current_payload ) = = message_rule - > supported_payloads [ i ] . payload_type )
2005-11-17 11:19:45 +00:00
{
2005-11-28 15:43:05 +00:00
found_payloads + + ;
2005-12-02 11:38:56 +00:00
total_found_payloads + + ;
2005-11-30 10:23:15 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Found payload of type %s " ,
2005-11-30 12:58:57 +00:00
mapping_find ( payload_type_m , message_rule - > supported_payloads [ i ] . payload_type ) ) ;
2005-11-30 10:23:15 +00:00
2005-11-30 12:58:57 +00:00
/* as soon as ohe payload occures more then specified, the verification fails */
if ( found_payloads > message_rule - > supported_payloads [ i ] . max_occurence )
2005-11-28 15:43:05 +00:00
{
this - > logger - > log ( this - > logger , ERROR , " Payload of type %s more than %d times (%d) occured in current message " ,
2005-11-30 12:58:57 +00:00
mapping_find ( payload_type_m , current_payload - > get_type ( current_payload ) ) ,
message_rule - > supported_payloads [ i ] . max_occurence , found_payloads ) ;
2005-11-17 11:19:45 +00:00
iterator - > destroy ( iterator ) ;
2005-11-28 15:43:05 +00:00
return NOT_SUPPORTED ;
}
2005-11-17 11:19:45 +00:00
}
}
2005-11-30 12:58:57 +00:00
if ( found_payloads < message_rule - > supported_payloads [ i ] . min_occurence )
2005-11-28 15:43:05 +00:00
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR , " Payload of type %s not occured %d times (%d) " ,
mapping_find ( payload_type_m , message_rule - > supported_payloads [ i ] . payload_type ) ,
message_rule - > supported_payloads [ i ] . min_occurence , found_payloads ) ;
2005-11-28 15:43:05 +00:00
iterator - > destroy ( iterator ) ;
return NOT_SUPPORTED ;
}
2005-12-02 11:38:56 +00:00
if ( ( message_rule - > supported_payloads [ i ] . can_be_last ) & & ( this - > payloads - > get_count ( this - > payloads ) = = total_found_payloads ) )
{
iterator - > destroy ( iterator ) ;
return SUCCESS ;
}
2005-11-17 11:19:45 +00:00
}
2005-11-28 15:43:05 +00:00
iterator - > destroy ( iterator ) ;
return SUCCESS ;
2005-11-16 16:50:13 +00:00
}
2005-11-30 12:58:57 +00:00
/**
* Implementation of private_message_t . decrypt_and_verify_payloads .
*/
static status_t decrypt_and_verify_payloads ( private_message_t * this , crypter_t * crypter , signer_t * signer )
2005-11-30 08:32:23 +00:00
{
bool current_payload_was_encrypted = FALSE ;
2005-11-30 12:58:57 +00:00
payload_t * last_payload = NULL ;
2005-11-30 08:32:23 +00:00
message_rule_t * message_rule ;
int payload_number = 1 ;
2005-11-30 12:58:57 +00:00
iterator_t * iterator ;
status_t status ;
2005-11-30 08:32:23 +00:00
status = this - > get_message_rule ( this , & message_rule ) ;
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Message rule could not be found for exchange type %s " ,
mapping_find ( exchange_type_m , this - > exchange_type ) ) ;
2005-11-30 08:32:23 +00:00
return status ;
}
iterator = this - > payloads - > create_iterator ( this - > payloads , TRUE ) ;
2005-11-30 12:58:57 +00:00
/* process each payload and decrypt a encryption payload */
2005-11-30 08:32:23 +00:00
while ( iterator - > has_next ( iterator ) )
{
2005-11-30 12:58:57 +00:00
supported_payload_entry_t * supported_payload_entry ;
2005-11-30 10:23:15 +00:00
payload_type_t current_payload_type ;
2005-11-30 12:58:57 +00:00
payload_t * current_payload ;
2005-11-30 08:32:23 +00:00
/* get current payload */
iterator - > current ( iterator , ( void * * ) & current_payload ) ;
2005-11-30 12:58:57 +00:00
/* needed to check */
2005-11-30 10:23:15 +00:00
current_payload_type = current_payload - > get_type ( current_payload ) ;
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Process payload of type %s " , mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-30 09:00:30 +00:00
2005-11-30 10:23:15 +00:00
if ( current_payload_type = = ENCRYPTED )
2005-11-30 08:32:23 +00:00
{
encryption_payload_t * encryption_payload ;
payload_t * current_encrypted_payload ;
2005-11-30 10:23:15 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Found an encryption payload " ) ;
2005-11-30 09:00:30 +00:00
2005-11-30 08:32:23 +00:00
if ( ! message_rule - > encrypted_content )
{
this - > logger - > log ( this - > logger , ERROR | MORE , " Encrypted payload not allowed for this message type " ) ;
iterator - > destroy ( iterator ) ;
/* encrypted payload is not last one */
return FAILED ;
}
if ( payload_number ! = this - > payloads - > get_count ( this - > payloads ) )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Encrypted payload is not last payload " ) ;
2005-11-30 08:32:23 +00:00
iterator - > destroy ( iterator ) ;
/* encrypted payload is not last one */
return FAILED ;
}
2005-11-30 10:23:15 +00:00
iterator - > current ( iterator , ( void * * ) & encryption_payload ) ;
2005-11-30 08:32:23 +00:00
/* encrypt payload */
encryption_payload - > set_transforms ( encryption_payload , crypter , signer ) ;
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Verify signature of encryption payload " ) ;
2005-11-30 08:32:23 +00:00
status = encryption_payload - > verify_signature ( encryption_payload , this - > packet - > data ) ;
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " encryption payload signature invalid " ) ;
2005-11-30 08:32:23 +00:00
iterator - > destroy ( iterator ) ;
return status ;
}
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Decrypt content of encryption payload " ) ;
2005-11-30 08:32:23 +00:00
status = encryption_payload - > decrypt ( encryption_payload ) ;
if ( status ! = SUCCESS )
{
2005-12-02 12:38:55 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Encrypted payload could not be decrypted and parsed: %s " ,
mapping_find ( status_m , status ) ) ;
2005-11-30 08:32:23 +00:00
iterator - > destroy ( iterator ) ;
return status ;
}
2005-11-30 12:58:57 +00:00
/* needed to later find out if a payload has to be encrypted or not */
2005-11-30 08:32:23 +00:00
current_payload_was_encrypted = TRUE ;
2005-11-30 10:23:15 +00:00
if ( encryption_payload - > get_payload_count ( encryption_payload ) = = 0 )
2005-11-30 08:32:23 +00:00
{
2005-12-01 19:53:48 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Encrypted payload is empty " ) ;
2005-11-30 08:32:23 +00:00
iterator - > remove ( iterator ) ;
encryption_payload - > destroy ( encryption_payload ) ;
2005-11-30 12:58:57 +00:00
/* encrypted payload contains no other payload */
2005-11-30 10:23:15 +00:00
current_payload_type = NO_PAYLOAD ;
if ( last_payload = = NULL )
{
2005-11-30 12:58:57 +00:00
/* encrypted content was the only payload in IKEv2-Message
* Set the first payload to the first payload of encrypted ones */
2005-11-30 10:23:15 +00:00
this - > first_payload = current_payload_type ;
}
else
{
2005-11-30 12:58:57 +00:00
/* another payload was here before the encrypted content
* Set the next payload of proceeding payload
* to the first payload of encrypted ones */
2005-11-30 10:23:15 +00:00
last_payload - > set_next_type ( last_payload , current_payload_type ) ;
2005-12-01 19:53:48 +00:00
}
break ;
2005-11-30 12:58:57 +00:00
2005-11-30 08:32:23 +00:00
}
2005-11-30 12:58:57 +00:00
2005-12-01 19:53:48 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Encrypted payload is not empty " ) ;
2005-11-30 08:32:23 +00:00
/* encryption_payload is replaced with first encrypted payload*/
2005-11-30 10:23:15 +00:00
encryption_payload - > remove_first_payload ( encryption_payload , & current_encrypted_payload ) ;
this - > logger - > log ( this - > logger , CONTROL | MORE , " Replace encrypted payload with payload of type %s. " ,
mapping_find ( payload_type_m , current_encrypted_payload - > get_type ( current_encrypted_payload ) ) ) ;
2005-11-30 08:32:23 +00:00
iterator - > replace ( iterator , NULL , ( void * ) current_encrypted_payload ) ;
2005-11-30 10:23:15 +00:00
current_payload_type = current_encrypted_payload - > get_type ( current_encrypted_payload ) ;
if ( last_payload = = NULL )
{
2005-11-30 12:58:57 +00:00
/* encrypted content was the only payload in IKEv2-Message
* Set the first payload to the first payload of encrypted ones */
2005-11-30 10:23:15 +00:00
this - > first_payload = current_payload_type ;
}
else
{
2005-11-30 12:58:57 +00:00
/* another payload was here before the encrypted content
* Set the next payload of proceeding payload
* to the first payload of encrypted ones */
2005-11-30 10:23:15 +00:00
last_payload - > set_next_type ( last_payload , current_payload_type ) ;
}
2005-11-30 08:32:23 +00:00
/* all encrypted payloads are added to the payload list */
2005-11-30 10:23:15 +00:00
while ( encryption_payload - > get_payload_count ( encryption_payload ) > 0 )
2005-11-30 08:32:23 +00:00
{
2005-11-30 10:23:15 +00:00
encryption_payload - > remove_first_payload ( encryption_payload , & current_encrypted_payload ) ;
2005-11-30 08:57:02 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Insert unencrypted payload of type %s at end of list. " , mapping_find ( payload_type_m , current_encrypted_payload - > get_type ( current_encrypted_payload ) ) ) ;
2005-11-30 08:32:23 +00:00
this - > payloads - > insert_last ( this - > payloads , current_encrypted_payload ) ;
}
2005-11-30 12:58:57 +00:00
/* encryption payload is not needed anymore cause all payloads are
* moved to internal payload list */
2005-11-30 10:23:15 +00:00
encryption_payload - > destroy ( encryption_payload ) ;
2005-11-30 12:58:57 +00:00
2005-11-30 08:32:23 +00:00
}
2005-11-30 12:58:57 +00:00
status = this - > get_supported_payload_entry ( this , message_rule , current_payload_type , & supported_payload_entry ) ;
2005-11-30 08:32:23 +00:00
if ( status ! = SUCCESS )
{
/* payload type not supported */
2005-11-30 10:23:15 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Payload type %s not allowed " , mapping_find ( payload_type_m , current_payload_type ) ) ;
2005-11-30 08:32:23 +00:00
iterator - > destroy ( iterator ) ;
return status ;
}
2005-11-30 12:58:57 +00:00
if ( supported_payload_entry - > encrypted ! = current_payload_was_encrypted )
2005-11-30 08:32:23 +00:00
{
/* payload type not supported */
2005-11-30 08:46:56 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Payload type %s should be %s! " ,
2005-11-30 10:23:15 +00:00
mapping_find ( payload_type_m , current_payload_type ) ,
2005-11-30 12:58:57 +00:00
( supported_payload_entry - > encrypted ) ? " encrypted " : " not encrypted " ) ;
2005-11-30 08:32:23 +00:00
iterator - > destroy ( iterator ) ;
return status ;
}
payload_number + + ;
2005-11-30 12:58:57 +00:00
/* is stored to set next payload in case of found encryption payload */
2005-11-30 10:23:15 +00:00
last_payload = current_payload ;
2005-11-30 08:32:23 +00:00
}
iterator - > destroy ( iterator ) ;
return this - > public . verify ( & ( this - > public ) ) ;
}
2005-11-30 12:58:57 +00:00
/**
* Implementation of private_message_t . encrypt_payloads .
*/
2005-11-29 17:19:59 +00:00
static status_t encrypt_payloads ( private_message_t * this , crypter_t * crypter , signer_t * signer )
{
encryption_payload_t * encryption_payload = NULL ;
2005-11-30 12:58:57 +00:00
message_rule_t * message_rule ;
status_t status ;
2005-11-30 08:32:23 +00:00
linked_list_t * all_payloads ;
2005-11-29 17:19:59 +00:00
2005-11-30 08:32:23 +00:00
status = this - > get_message_rule ( this , & message_rule ) ;
2005-11-29 17:19:59 +00:00
if ( status ! = SUCCESS )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , ERROR | MORE , " Message rule could not be found for exchange type %s " ,
mapping_find ( exchange_type_m , this - > exchange_type ) ) ;
2005-11-29 17:19:59 +00:00
return status ;
}
2005-11-30 12:58:57 +00:00
2005-11-30 08:32:23 +00:00
if ( ! message_rule - > encrypted_content )
{
2005-11-30 09:26:06 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Message doesn't have to be encrypted " ) ;
2005-11-30 08:32:23 +00:00
/* message contains no content to encrypt */
return SUCCESS ;
}
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Copy all payloads to a temporary list " ) ;
2005-11-30 08:32:23 +00:00
all_payloads = linked_list_create ( ) ;
2005-11-29 17:19:59 +00:00
/* first copy all payloads in a temporary list */
while ( this - > payloads - > get_count ( this - > payloads ) > 0 )
{
void * current_payload ;
this - > payloads - > remove_first ( this - > payloads , & current_payload ) ;
all_payloads - > insert_last ( all_payloads , current_payload ) ;
}
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Check each payloads if they have to get encrypted " ) ;
2005-11-29 17:19:59 +00:00
while ( all_payloads - > get_count ( all_payloads ) > 0 )
{
2005-11-30 12:58:57 +00:00
supported_payload_entry_t * supported_payload_entry ;
2005-11-29 17:19:59 +00:00
payload_t * current_payload ;
bool to_encrypt = FALSE ;
all_payloads - > remove_first ( all_payloads , ( void * * ) & current_payload ) ;
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Get rule for payload %s " , mapping_find ( payload_type_m , current_payload - > get_type ( current_payload ) ) ) ;
2005-11-29 17:19:59 +00:00
2005-11-30 08:32:23 +00:00
status = this - > get_supported_payload_entry ( this , message_rule , current_payload - > get_type ( current_payload ) , & supported_payload_entry ) ;
/* for payload types which are not found in supported payload list, it is presumed
* that they don ' t have to be encrypted */
if ( ( status = = SUCCESS ) & & ( supported_payload_entry - > encrypted ) )
2005-11-29 17:19:59 +00:00
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Payload %s has to get encrypted " ,
mapping_find ( payload_type_m , current_payload - > get_type ( current_payload ) ) ) ;
2005-11-30 08:32:23 +00:00
to_encrypt = TRUE ;
2005-11-29 17:19:59 +00:00
}
2005-11-30 12:58:57 +00:00
else if ( status ! = SUCCESS )
{
this - > logger - > log ( this - > logger , CONTROL | MOST , " Payload %s not defined for exchange type %s. Handle it anyway " ,
mapping_find ( payload_type_m , current_payload - > get_type ( current_payload ) ) ,
mapping_find ( exchange_type_m , this - > exchange_type ) ) ;
}
2005-11-29 17:19:59 +00:00
if ( to_encrypt )
{
if ( encryption_payload = = NULL )
{
encryption_payload = encryption_payload_create ( ) ;
}
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Insert payload %s to encryption payload " ,
mapping_find ( payload_type_m , current_payload - > get_type ( current_payload ) ) ) ;
2005-11-29 17:19:59 +00:00
encryption_payload - > add_payload ( encryption_payload , current_payload ) ;
}
else
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Insert payload %s as payload wich does not have to be encrypted " ,
mapping_find ( payload_type_m , current_payload - > get_type ( current_payload ) ) ) ;
2005-11-30 10:23:15 +00:00
this - > public . add_payload ( & ( this - > public ) , ( payload_t * ) encryption_payload ) ;
2005-11-29 17:19:59 +00:00
}
}
status = SUCCESS ;
if ( encryption_payload ! = NULL )
{
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Set transforms for encryption payload " ) ;
2005-11-29 17:19:59 +00:00
encryption_payload - > set_transforms ( encryption_payload , crypter , signer ) ;
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MORE , " Encrypt all payloads of encrypted payload " ) ;
2005-11-29 17:19:59 +00:00
status = encryption_payload - > encrypt ( encryption_payload ) ;
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Add encrypted payload to payload list " ) ;
2005-11-30 09:11:48 +00:00
this - > public . add_payload ( & ( this - > public ) , ( payload_t * ) encryption_payload ) ;
2005-11-29 17:19:59 +00:00
}
all_payloads - > destroy ( all_payloads ) ;
return status ;
}
2005-11-30 12:58:57 +00:00
2005-11-08 09:47:17 +00:00
/**
2005-11-30 12:58:57 +00:00
* Implementation of message_t . destroy .
2005-11-08 09:47:17 +00:00
*/
2005-11-28 16:55:46 +00:00
static void destroy ( private_message_t * this )
2005-11-08 09:47:17 +00:00
{
2005-11-24 14:22:29 +00:00
iterator_t * iterator ;
2005-11-16 16:09:15 +00:00
2005-11-30 12:58:57 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Going to destroy message_t object " ) ;
2005-11-21 17:50:56 +00:00
this - > packet - > destroy ( this - > packet ) ;
2005-11-10 17:49:20 +00:00
if ( this - > ike_sa_id ! = NULL )
{
this - > ike_sa_id - > destroy ( this - > ike_sa_id ) ;
}
2005-11-16 16:09:15 +00:00
2005-11-29 08:54:48 +00:00
iterator = this - > payloads - > create_iterator ( this - > payloads , TRUE ) ;
2005-11-16 16:09:15 +00:00
while ( iterator - > has_next ( iterator ) )
{
payload_t * payload ;
iterator - > current ( iterator , ( void * * ) & payload ) ;
2005-11-21 15:34:44 +00:00
this - > logger - > log ( this - > logger , CONTROL | MOST , " Destroying payload of type %s " ,
mapping_find ( payload_type_m , payload - > get_type ( payload ) ) ) ;
2005-11-16 16:09:15 +00:00
payload - > destroy ( payload ) ;
}
iterator - > destroy ( iterator ) ;
2005-11-10 15:38:38 +00:00
this - > payloads - > destroy ( this - > payloads ) ;
2005-11-17 08:46:05 +00:00
this - > parser - > destroy ( this - > parser ) ;
2005-11-29 10:25:07 +00:00
charon - > logger_manager - > destroy_logger ( charon - > logger_manager , this - > logger ) ;
2005-11-17 11:19:45 +00:00
2005-11-21 10:58:52 +00:00
allocator_free ( this ) ;
2005-11-08 09:47:17 +00:00
}
/*
* Described in Header - File
*/
2005-11-10 15:38:38 +00:00
message_t * message_create_from_packet ( packet_t * packet )
2005-11-08 09:47:17 +00:00
{
2005-11-09 09:35:06 +00:00
private_message_t * this = allocator_alloc_thing ( private_message_t ) ;
2005-11-09 09:11:06 +00:00
2005-11-10 15:38:38 +00:00
/* public functions */
2005-11-28 16:55:46 +00:00
this - > public . set_major_version = ( void ( * ) ( message_t * , u_int8_t ) ) set_major_version ;
2005-11-17 08:46:05 +00:00
this - > public . get_major_version = ( u_int8_t ( * ) ( message_t * ) ) get_major_version ;
2005-11-28 16:55:46 +00:00
this - > public . set_minor_version = ( void ( * ) ( message_t * , u_int8_t ) ) set_minor_version ;
2005-11-17 08:46:05 +00:00
this - > public . get_minor_version = ( u_int8_t ( * ) ( message_t * ) ) get_minor_version ;
2005-11-28 16:55:46 +00:00
this - > public . set_message_id = ( void ( * ) ( message_t * , u_int32_t ) ) set_message_id ;
2005-11-10 17:49:20 +00:00
this - > public . get_message_id = ( u_int32_t ( * ) ( message_t * ) ) get_message_id ;
2005-11-22 15:37:32 +00:00
this - > public . get_responder_spi = ( u_int64_t ( * ) ( message_t * ) ) get_responder_spi ;
2005-11-28 16:55:46 +00:00
this - > public . set_ike_sa_id = ( void ( * ) ( message_t * , ike_sa_id_t * ) ) set_ike_sa_id ;
2005-11-10 17:49:20 +00:00
this - > public . get_ike_sa_id = ( status_t ( * ) ( message_t * , ike_sa_id_t * * ) ) get_ike_sa_id ;
2005-11-28 16:55:46 +00:00
this - > public . set_exchange_type = ( void ( * ) ( message_t * , exchange_type_t ) ) set_exchange_type ;
2005-11-10 17:17:46 +00:00
this - > public . get_exchange_type = ( exchange_type_t ( * ) ( message_t * ) ) get_exchange_type ;
2005-11-28 16:55:46 +00:00
this - > public . set_request = ( void ( * ) ( message_t * , bool ) ) set_request ;
2005-11-10 17:17:46 +00:00
this - > public . get_request = ( bool ( * ) ( message_t * ) ) get_request ;
2005-11-28 16:55:46 +00:00
this - > public . add_payload = ( void ( * ) ( message_t * , payload_t * ) ) add_payload ;
2005-11-28 15:43:05 +00:00
this - > public . generate = ( status_t ( * ) ( message_t * , crypter_t * , signer_t * , packet_t * * ) ) generate ;
2005-11-28 16:55:46 +00:00
this - > public . set_source = ( void ( * ) ( message_t * , host_t * ) ) set_source ;
2005-11-30 12:58:57 +00:00
this - > public . get_source = ( host_t * ( * ) ( message_t * ) ) get_source ;
2005-11-28 16:55:46 +00:00
this - > public . set_destination = ( void ( * ) ( message_t * , host_t * ) ) set_destination ;
2005-11-30 12:58:57 +00:00
this - > public . get_destination = ( host_t * ( * ) ( message_t * ) ) get_destination ;
2005-11-29 08:54:48 +00:00
this - > public . get_payload_iterator = ( iterator_t * ( * ) ( message_t * ) ) get_payload_iterator ;
2005-11-28 15:43:05 +00:00
this - > public . parse_header = ( status_t ( * ) ( message_t * ) ) parse_header ;
this - > public . parse_body = ( status_t ( * ) ( message_t * , crypter_t * , signer_t * ) ) parse_body ;
this - > public . verify = ( status_t ( * ) ( message_t * ) ) verify ;
2005-12-02 13:20:20 +00:00
this - > public . get_packet = ( packet_t * ( * ) ( message_t * ) ) get_packet ;
2005-12-03 14:47:58 +00:00
this - > public . get_packet_data = ( chunk_t ( * ) ( message_t * this ) ) get_packet_data ;
2005-11-28 16:55:46 +00:00
this - > public . destroy = ( void ( * ) ( message_t * ) ) destroy ;
2005-11-10 17:17:46 +00:00
2005-11-29 17:19:59 +00:00
/* private values */
2005-11-16 16:09:15 +00:00
this - > exchange_type = EXCHANGE_TYPE_UNDEFINED ;
2005-11-10 17:17:46 +00:00
this - > is_request = TRUE ;
2005-11-10 17:49:20 +00:00
this - > ike_sa_id = NULL ;
2005-11-17 08:46:05 +00:00
this - > first_payload = NO_PAYLOAD ;
2005-11-10 17:49:20 +00:00
this - > message_id = 0 ;
2005-11-08 09:47:17 +00:00
2005-11-17 11:19:45 +00:00
/* private functions */
2005-11-30 08:32:23 +00:00
this - > get_message_rule = get_message_rule ;
this - > get_supported_payload_entry = get_supported_payload_entry ;
2005-11-29 17:19:59 +00:00
this - > encrypt_payloads = encrypt_payloads ;
2005-11-30 12:58:57 +00:00
this - > decrypt_and_verify_payloads = decrypt_and_verify_payloads ;
2005-11-17 11:19:45 +00:00
2005-11-10 15:38:38 +00:00
/* private values */
2005-11-16 16:09:15 +00:00
if ( packet = = NULL )
{
packet = packet_create ( ) ;
}
2005-11-10 15:38:38 +00:00
this - > packet = packet ;
this - > payloads = linked_list_create ( ) ;
2005-11-16 16:50:13 +00:00
/* parser is created from data of packet */
this - > parser = parser_create ( this - > packet - > data ) ;
2005-11-16 16:09:15 +00:00
2005-11-29 10:25:07 +00:00
this - > logger = charon - > logger_manager - > create_logger ( charon - > logger_manager , MESSAGE , NULL ) ;
2005-11-09 09:11:06 +00:00
return ( & this - > public ) ;
2005-11-08 09:47:17 +00:00
}
2005-11-10 15:38:38 +00:00
/*
2005-11-30 12:58:57 +00:00
* Described in Header .
2005-11-10 15:38:38 +00:00
*/
message_t * message_create ( )
{
return message_create_from_packet ( NULL ) ;
}
2005-12-05 12:21:38 +00:00
/*
* Described in Header .
*/
message_t * message_create_notify_reply ( host_t * source , host_t * destination , exchange_type_t exchange_type , bool original_initiator , ike_sa_id_t * ike_sa_id , notify_message_type_t notify_type )
{
message_t * message = message_create_from_packet ( NULL ) ;
notify_payload_t * payload ;
message - > set_source ( message , source - > clone ( source ) ) ;
message - > set_destination ( message , destination - > clone ( destination ) ) ;
message - > set_exchange_type ( message , exchange_type ) ;
message - > set_request ( message , FALSE ) ;
message - > set_message_id ( message , 0 ) ;
message - > set_ike_sa_id ( message , ike_sa_id ) ;
payload = notify_payload_create_from_protocol_and_type ( IKE , notify_type ) ;
message - > add_payload ( message , ( payload_t * ) payload ) ;
return message ;
}