- installing of child sa works
- need correct IP adresses to actually use IPsec
This commit is contained in:
@@ -285,10 +285,8 @@ static void load_default_config (private_configuration_manager_t *this)
|
|||||||
/* IKE proposals for alice */
|
/* IKE proposals for alice */
|
||||||
proposal = proposal_create(1);
|
proposal = proposal_create(1);
|
||||||
proposal->add_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
proposal->add_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
||||||
POS;
|
proposal->add_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
|
||||||
proposal->add_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 16);
|
proposal->add_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0);
|
||||||
POS;
|
|
||||||
proposal->add_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 16);
|
|
||||||
proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
||||||
proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
|
proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
|
||||||
init_config_a->add_proposal(init_config_a, proposal);
|
init_config_a->add_proposal(init_config_a, proposal);
|
||||||
@@ -296,8 +294,8 @@ static void load_default_config (private_configuration_manager_t *this)
|
|||||||
/* IKE proposals for bob */
|
/* IKE proposals for bob */
|
||||||
proposal = proposal_create(1);
|
proposal = proposal_create(1);
|
||||||
proposal->add_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
proposal->add_algorithm(proposal, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
||||||
proposal->add_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 16);
|
proposal->add_algorithm(proposal, IKE, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
|
||||||
proposal->add_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 16);
|
proposal->add_algorithm(proposal, IKE, PSEUDO_RANDOM_FUNCTION, PRF_HMAC_MD5, 0);
|
||||||
proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
|
proposal->add_algorithm(proposal, IKE, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
|
||||||
init_config_b->add_proposal(init_config_b, proposal);
|
init_config_b->add_proposal(init_config_b, proposal);
|
||||||
|
|
||||||
@@ -322,16 +320,17 @@ static void load_default_config (private_configuration_manager_t *this)
|
|||||||
/* child proposal for alice */
|
/* child proposal for alice */
|
||||||
proposal = proposal_create(1);
|
proposal = proposal_create(1);
|
||||||
|
|
||||||
proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
|
// proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
|
||||||
proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
|
// proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
|
||||||
proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
// proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
||||||
proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
|
// proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
|
||||||
proposal->add_algorithm(proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
|
// proposal->add_algorithm(proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
|
||||||
|
|
||||||
proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
||||||
proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 32);
|
proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_3DES, 0);
|
||||||
proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
|
proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
|
||||||
proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
|
proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
|
||||||
|
proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_2048_BIT, 0);
|
||||||
proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
||||||
proposal->add_algorithm(proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
|
proposal->add_algorithm(proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
|
||||||
|
|
||||||
@@ -340,12 +339,14 @@ static void load_default_config (private_configuration_manager_t *this)
|
|||||||
/* child proposal for bob */
|
/* child proposal for bob */
|
||||||
proposal = proposal_create(1);
|
proposal = proposal_create(1);
|
||||||
|
|
||||||
proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 20);
|
// proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
|
||||||
proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
// proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_AES_XCBC_96, 0);
|
||||||
proposal->add_algorithm(proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
|
// proposal->add_algorithm(proposal, AH, INTEGRITY_ALGORITHM, AUTH_DES_MAC, 0);
|
||||||
|
// proposal->add_algorithm(proposal, AH, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
||||||
|
// proposal->add_algorithm(proposal, AH, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
|
||||||
|
|
||||||
proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
proposal->add_algorithm(proposal, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
||||||
proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 20);
|
proposal->add_algorithm(proposal, ESP, INTEGRITY_ALGORITHM, AUTH_HMAC_MD5_96, 0);
|
||||||
proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
proposal->add_algorithm(proposal, ESP, DIFFIE_HELLMAN_GROUP, MODP_1024_BIT, 0);
|
||||||
proposal->add_algorithm(proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
|
proposal->add_algorithm(proposal, ESP, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -339,6 +339,7 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
|
|||||||
protocol_proposal_t *this_prop, *other_prop;
|
protocol_proposal_t *this_prop, *other_prop;
|
||||||
protocol_id_t proto;
|
protocol_id_t proto;
|
||||||
bool add;
|
bool add;
|
||||||
|
u_int64_t spi;
|
||||||
|
|
||||||
/* empty proposal? no match */
|
/* empty proposal? no match */
|
||||||
if (this->protocol_proposals->get_count(this->protocol_proposals) == 0 ||
|
if (this->protocol_proposals->get_count(this->protocol_proposals) == 0 ||
|
||||||
@@ -443,6 +444,19 @@ static proposal_t *select_proposal(private_proposal_t *this, private_proposal_t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
|
/* apply spis from "other" */
|
||||||
|
spi = other->public.get_spi(&(other->public), AH);
|
||||||
|
if (spi)
|
||||||
|
{
|
||||||
|
selected->set_spi(selected, AH, spi);
|
||||||
|
}
|
||||||
|
spi = other->public.get_spi(&(other->public), ESP);
|
||||||
|
if (spi)
|
||||||
|
{
|
||||||
|
selected->set_spi(selected, ESP, spi);
|
||||||
|
}
|
||||||
|
|
||||||
/* everything matched, return new proposal */
|
/* everything matched, return new proposal */
|
||||||
return selected;
|
return selected;
|
||||||
}
|
}
|
||||||
@@ -487,7 +501,7 @@ static void set_spi(private_proposal_t *this, protocol_id_t proto, u_int64_t spi
|
|||||||
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
|
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
|
||||||
if (proto_proposal)
|
if (proto_proposal)
|
||||||
{
|
{
|
||||||
if (proto == IKE)
|
if (proto == AH || proto == ESP)
|
||||||
{
|
{
|
||||||
*((u_int32_t*)proto_proposal->spi.ptr) = (u_int32_t)spi;
|
*((u_int32_t*)proto_proposal->spi.ptr) = (u_int32_t)spi;
|
||||||
}
|
}
|
||||||
@@ -495,7 +509,6 @@ static void set_spi(private_proposal_t *this, protocol_id_t proto, u_int64_t spi
|
|||||||
{
|
{
|
||||||
*((u_int64_t*)proto_proposal->spi.ptr) = spi;
|
*((u_int64_t*)proto_proposal->spi.ptr) = spi;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -507,7 +520,7 @@ static u_int64_t get_spi(private_proposal_t *this, protocol_id_t proto)
|
|||||||
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
|
protocol_proposal_t *proto_proposal = get_protocol_proposal(this, proto, FALSE);
|
||||||
if (proto_proposal)
|
if (proto_proposal)
|
||||||
{
|
{
|
||||||
if (proto == IKE)
|
if (proto == AH || proto == ESP)
|
||||||
{
|
{
|
||||||
return (u_int64_t)*((u_int32_t*)proto_proposal->spi.ptr);
|
return (u_int64_t)*((u_int32_t*)proto_proposal->spi.ptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
|
|||||||
u_int8_t low_val = *(this->out_position) & 0x0F;
|
u_int8_t low_val = *(this->out_position) & 0x0F;
|
||||||
/* highval is set, low_val is not changed */
|
/* highval is set, low_val is not changed */
|
||||||
*(this->out_position) = high_val | low_val;
|
*(this->out_position) = high_val | low_val;
|
||||||
this->logger->log(this->logger, RAW|LEVEL2, " => 0x%x", *(this->out_position));
|
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position));
|
||||||
/* write position is not changed, just bit position is moved */
|
/* write position is not changed, just bit position is moved */
|
||||||
this->current_bit = 4;
|
this->current_bit = 4;
|
||||||
}
|
}
|
||||||
@@ -352,7 +352,7 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
|
|||||||
/* lowval of current byte in buffer has to be set to the new value*/
|
/* lowval of current byte in buffer has to be set to the new value*/
|
||||||
u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
|
u_int low_val = *((u_int8_t *)(this->data_struct + offset)) & 0x0F;
|
||||||
*(this->out_position) = high_val | low_val;
|
*(this->out_position) = high_val | low_val;
|
||||||
this->logger->log(this->logger, RAW|LEVEL2, " => 0x%x", *(this->out_position));
|
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position));
|
||||||
this->out_position++;
|
this->out_position++;
|
||||||
this->current_bit = 0;
|
this->current_bit = 0;
|
||||||
|
|
||||||
@@ -370,7 +370,7 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
|
|||||||
{
|
{
|
||||||
/* 8 bit values are written as they are */
|
/* 8 bit values are written as they are */
|
||||||
*this->out_position = *((u_int8_t *)(this->data_struct + offset));
|
*this->out_position = *((u_int8_t *)(this->data_struct + offset));
|
||||||
this->logger->log(this->logger, RAW|LEVEL2, " => 0x%x", *(this->out_position));
|
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position));
|
||||||
this->out_position++;
|
this->out_position++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@ static void generate_u_int_type (private_generator_t *this,encoding_type_t int_t
|
|||||||
int16_val = int16_val & 0xFF7F;
|
int16_val = int16_val & 0xFF7F;
|
||||||
|
|
||||||
int16_val = int16_val | attribute_format_flag;
|
int16_val = int16_val | attribute_format_flag;
|
||||||
this->logger->log(this->logger, RAW|LEVEL2, " => 0x%x", int16_val);
|
this->logger->log(this->logger, RAW|LEVEL2, " => %d", int16_val);
|
||||||
/* write bytes to buffer (set bit is overwritten)*/
|
/* write bytes to buffer (set bit is overwritten)*/
|
||||||
this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
|
this->write_bytes_to_buffer(this,&int16_val,sizeof(u_int16_t));
|
||||||
this->current_bit = 0;
|
this->current_bit = 0;
|
||||||
@@ -516,7 +516,7 @@ static void generate_flag (private_generator_t *this,u_int32_t offset)
|
|||||||
*(this->out_position) = *(this->out_position) | flag;
|
*(this->out_position) = *(this->out_position) | flag;
|
||||||
|
|
||||||
|
|
||||||
this->logger->log(this->logger, RAW|LEVEL2, " => 0x0%x", *(this->out_position));
|
this->logger->log(this->logger, RAW|LEVEL2, " => %d", *(this->out_position));
|
||||||
|
|
||||||
this->current_bit++;
|
this->current_bit++;
|
||||||
if (this->current_bit >= 8)
|
if (this->current_bit >= 8)
|
||||||
@@ -1017,6 +1017,8 @@ static void generate_payload (private_generator_t *this,payload_t *payload)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL2, "generating %s payload finished.",
|
||||||
|
mapping_find(payload_type_m, payload_type));
|
||||||
this->logger->log_bytes(this->logger, RAW|LEVEL3, "generated data for this payload",
|
this->logger->log_bytes(this->logger, RAW|LEVEL3, "generated data for this payload",
|
||||||
payload_start, this->out_position-payload_start);
|
payload_start, this->out_position-payload_start);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ static status_t encrypt(private_encryption_payload_t *this)
|
|||||||
this->generate(this);
|
this->generate(this);
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2, "encrypting payloads");
|
this->logger->log(this->logger, CONTROL|LEVEL2, "encrypting payloads");
|
||||||
|
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data to encrypt", &this->decrypted);
|
||||||
|
|
||||||
/* build padding */
|
/* build padding */
|
||||||
block_size = this->crypter->get_block_size(this->crypter);
|
block_size = this->crypter->get_block_size(this->crypter);
|
||||||
@@ -308,6 +309,8 @@ static status_t encrypt(private_encryption_payload_t *this)
|
|||||||
randomizer->allocate_pseudo_random_bytes(randomizer, iv.len, &iv);
|
randomizer->allocate_pseudo_random_bytes(randomizer, iv.len, &iv);
|
||||||
randomizer->destroy(randomizer);
|
randomizer->destroy(randomizer);
|
||||||
|
|
||||||
|
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before encryption with padding", &to_crypt);
|
||||||
|
|
||||||
/* encrypt to_crypt chunk */
|
/* encrypt to_crypt chunk */
|
||||||
allocator_free(this->encrypted.ptr);
|
allocator_free(this->encrypted.ptr);
|
||||||
status = this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
|
status = this->crypter->encrypt(this->crypter, to_crypt, iv, &result);
|
||||||
@@ -319,6 +322,8 @@ static status_t encrypt(private_encryption_payload_t *this)
|
|||||||
allocator_free(iv.ptr);
|
allocator_free(iv.ptr);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after encryption", &result);
|
||||||
|
|
||||||
|
|
||||||
/* build encrypted result with iv and signature */
|
/* build encrypted result with iv and signature */
|
||||||
this->encrypted.len = iv.len + result.len + this->signer->get_block_size(this->signer);
|
this->encrypted.len = iv.len + result.len + this->signer->get_block_size(this->signer);
|
||||||
@@ -331,6 +336,8 @@ static status_t encrypt(private_encryption_payload_t *this)
|
|||||||
|
|
||||||
allocator_free(result.ptr);
|
allocator_free(result.ptr);
|
||||||
allocator_free(iv.ptr);
|
allocator_free(iv.ptr);
|
||||||
|
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after encryption with IV and (invalid) signature", &this->encrypted);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,6 +352,8 @@ static status_t decrypt(private_encryption_payload_t *this)
|
|||||||
|
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2, "decrypting encryption payload");
|
this->logger->log(this->logger, CONTROL|LEVEL2, "decrypting encryption payload");
|
||||||
|
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before decryption with IV and (invalid) signature", &this->encrypted);
|
||||||
|
|
||||||
|
|
||||||
if (this->signer == NULL || this->crypter == NULL)
|
if (this->signer == NULL || this->crypter == NULL)
|
||||||
{
|
{
|
||||||
@@ -373,12 +382,16 @@ static status_t decrypt(private_encryption_payload_t *this)
|
|||||||
/* free previus data, if any */
|
/* free previus data, if any */
|
||||||
allocator_free(this->decrypted.ptr);
|
allocator_free(this->decrypted.ptr);
|
||||||
|
|
||||||
|
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data before decryption", &concatenated);
|
||||||
|
|
||||||
status = this->crypter->decrypt(this->crypter, concatenated, iv, &(this->decrypted));
|
status = this->crypter->decrypt(this->crypter, concatenated, iv, &(this->decrypted));
|
||||||
if (status != SUCCESS)
|
if (status != SUCCESS)
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, ERROR|LEVEL1, "could not decrypt, decryption failed");
|
this->logger->log(this->logger, ERROR|LEVEL1, "could not decrypt, decryption failed");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after decryption with padding", &this->decrypted);
|
||||||
|
|
||||||
|
|
||||||
/* get padding length, sits just bevore signature */
|
/* get padding length, sits just bevore signature */
|
||||||
padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
|
padding_length = *(this->decrypted.ptr + this->decrypted.len - 1);
|
||||||
@@ -396,6 +409,7 @@ static status_t decrypt(private_encryption_payload_t *this)
|
|||||||
|
|
||||||
/* free padding */
|
/* free padding */
|
||||||
this->decrypted.ptr = allocator_realloc(this->decrypted.ptr, this->decrypted.len);
|
this->decrypted.ptr = allocator_realloc(this->decrypted.ptr, this->decrypted.len);
|
||||||
|
this->logger->log_chunk(this->logger, RAW|LEVEL2, "data after decryption without padding", &this->decrypted);
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2, "decryption successful, trying to parse content");
|
this->logger->log(this->logger, CONTROL|LEVEL2, "decryption successful, trying to parse content");
|
||||||
return (this->parse(this));
|
return (this->parse(this));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,6 +226,7 @@ static void set_next_type(private_proposal_substructure_t *this,payload_type_t t
|
|||||||
*/
|
*/
|
||||||
static size_t get_length(private_proposal_substructure_t *this)
|
static size_t get_length(private_proposal_substructure_t *this)
|
||||||
{
|
{
|
||||||
|
this->compute_length(this);
|
||||||
return this->proposal_length;
|
return this->proposal_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,9 +385,8 @@ static void compute_length (private_proposal_substructure_t *this)
|
|||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
length += this->spi.len;
|
length += this->spi.len;
|
||||||
this->transforms_count= transforms_count;
|
this->transforms_count = transforms_count;
|
||||||
this->proposal_length = length;
|
this->proposal_length = length;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -411,8 +411,8 @@ static size_t get_spi_size (private_proposal_substructure_t *this)
|
|||||||
void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal)
|
void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal)
|
||||||
{
|
{
|
||||||
iterator_t *iterator = this->transforms->create_iterator(this->transforms, TRUE);
|
iterator_t *iterator = this->transforms->create_iterator(this->transforms, TRUE);
|
||||||
|
u_int32_t spi;
|
||||||
|
|
||||||
proposal->set_spi(proposal, this->protocol_id, *((u_int32_t*)this->spi.ptr));
|
|
||||||
|
|
||||||
while (iterator->has_next(iterator))
|
while (iterator->has_next(iterator))
|
||||||
{
|
{
|
||||||
@@ -430,6 +430,10 @@ void add_to_proposal(private_proposal_substructure_t *this, proposal_t *proposal
|
|||||||
proposal->add_algorithm(proposal, this->protocol_id, transform_type, transform_id, key_length);
|
proposal->add_algorithm(proposal, this->protocol_id, transform_type, transform_id, key_length);
|
||||||
}
|
}
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
|
spi = *((u_int32_t*)this->spi.ptr);
|
||||||
|
|
||||||
|
proposal->set_spi(proposal, this->protocol_id, spi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -561,14 +565,6 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
|
|||||||
algorithm_t *algo;
|
algorithm_t *algo;
|
||||||
transform_substructure_t *transform;
|
transform_substructure_t *transform;
|
||||||
|
|
||||||
/* take over general infos */
|
|
||||||
this->spi_size = proto == IKE ? 8 : 4;
|
|
||||||
this->spi.len = this->spi_size;
|
|
||||||
this->spi.ptr = allocator_alloc(this->spi_size);
|
|
||||||
*((u_int32_t*)this->spi.ptr) = proposal->get_spi(proposal, proto);
|
|
||||||
this->proposal_number = proposal->get_number(proposal);
|
|
||||||
this->protocol_id = proto;
|
|
||||||
|
|
||||||
/* encryption algorithm is only availble in ESP */
|
/* encryption algorithm is only availble in ESP */
|
||||||
iterator = proposal->create_algorithm_iterator(proposal, proto, ENCRYPTION_ALGORITHM);
|
iterator = proposal->create_algorithm_iterator(proposal, proto, ENCRYPTION_ALGORITHM);
|
||||||
while (iterator->has_next(iterator))
|
while (iterator->has_next(iterator))
|
||||||
@@ -623,5 +619,13 @@ proposal_substructure_t *proposal_substructure_create_from_proposal(proposal_t *
|
|||||||
}
|
}
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
|
/* take over general infos */
|
||||||
|
this->spi_size = proto == IKE ? 8 : 4;
|
||||||
|
this->spi.len = this->spi_size;
|
||||||
|
this->spi.ptr = allocator_alloc(this->spi_size);
|
||||||
|
*((u_int32_t*)this->spi.ptr) = proposal->get_spi(proposal, proto);
|
||||||
|
this->proposal_number = proposal->get_number(proposal);
|
||||||
|
this->protocol_id = proto;
|
||||||
|
|
||||||
return &(this->public);
|
return &(this->public);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -343,7 +343,6 @@ static void compute_length (private_transform_substructure_t *this)
|
|||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
this->transform_length = length;
|
this->transform_length = length;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -476,20 +475,13 @@ transform_substructure_t *transform_substructure_create_type(transform_type_t tr
|
|||||||
transform->set_transform_type(transform,transform_type);
|
transform->set_transform_type(transform,transform_type);
|
||||||
transform->set_transform_id(transform,transform_id);
|
transform->set_transform_id(transform,transform_id);
|
||||||
|
|
||||||
switch (transform_type)
|
/* a keylength attribute is only created for AES encryption */
|
||||||
|
if (transform_type == ENCRYPTION_ALGORITHM &&
|
||||||
|
transform_id == ENCR_AES_CBC)
|
||||||
{
|
{
|
||||||
case ENCRYPTION_ALGORITHM:
|
transform_attribute_t *attribute = transform_attribute_create_key_length(key_length);
|
||||||
case PSEUDO_RANDOM_FUNCTION:
|
transform->add_transform_attribute(transform,attribute);
|
||||||
case INTEGRITY_ALGORITHM:
|
|
||||||
{
|
|
||||||
transform_attribute_t *attribute = transform_attribute_create_key_length(key_length);
|
|
||||||
transform->add_transform_attribute(transform,attribute);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
/* no keylength attribute is created */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|||||||
+265
-44
@@ -38,15 +38,30 @@ struct private_child_sa_t {
|
|||||||
*/
|
*/
|
||||||
child_sa_t public;
|
child_sa_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP of this peer
|
||||||
|
*/
|
||||||
|
host_t *me;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP of other peer
|
||||||
|
*/
|
||||||
|
host_t *other;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security parameter index for AH protocol, 0 if not used
|
||||||
|
*/
|
||||||
|
u_int32_t ah_spi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Security parameter index for ESP protocol, 0 if not used
|
||||||
|
*/
|
||||||
|
u_int32_t esp_spi;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CHILD_SAs own logger
|
* CHILD_SAs own logger
|
||||||
*/
|
*/
|
||||||
logger_t *logger;
|
logger_t *logger;
|
||||||
|
|
||||||
/**
|
|
||||||
* Protocols used in this SA
|
|
||||||
*/
|
|
||||||
protocol_id_t protocols[2];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -58,6 +73,243 @@ static u_int32_t get_spi(private_child_sa_t *this)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements child_sa_t.alloc
|
||||||
|
*/
|
||||||
|
static status_t alloc(private_child_sa_t *this, linked_list_t *proposals)
|
||||||
|
{
|
||||||
|
protocol_id_t protocols[2];
|
||||||
|
iterator_t *iterator;
|
||||||
|
proposal_t *proposal;
|
||||||
|
status_t status;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
/* iterator through proposals */
|
||||||
|
iterator = proposals->create_iterator(proposals, TRUE);
|
||||||
|
while(iterator->has_next(iterator))
|
||||||
|
{
|
||||||
|
iterator->current(iterator, (void**)&proposal);
|
||||||
|
proposal->get_protocols(proposal, protocols);
|
||||||
|
|
||||||
|
/* check all protocols */
|
||||||
|
for (i = 0; i<2; i++)
|
||||||
|
{
|
||||||
|
switch (protocols[i])
|
||||||
|
{
|
||||||
|
case AH:
|
||||||
|
/* do we already have an spi for AH?*/
|
||||||
|
if (this->ah_spi == 0)
|
||||||
|
{
|
||||||
|
/* nope, get one */
|
||||||
|
status = charon->kernel_interface->get_spi(
|
||||||
|
charon->kernel_interface,
|
||||||
|
this->me, this->other,
|
||||||
|
AH, FALSE,
|
||||||
|
&(this->ah_spi));
|
||||||
|
}
|
||||||
|
/* update proposal */
|
||||||
|
proposal->set_spi(proposal, AH, (u_int64_t)this->ah_spi);
|
||||||
|
break;
|
||||||
|
case ESP:
|
||||||
|
/* do we already have an spi for ESP?*/
|
||||||
|
if (this->esp_spi == 0)
|
||||||
|
{
|
||||||
|
/* nope, get one */
|
||||||
|
status = charon->kernel_interface->get_spi(
|
||||||
|
charon->kernel_interface,
|
||||||
|
this->me, this->other,
|
||||||
|
ESP, FALSE,
|
||||||
|
&(this->esp_spi));
|
||||||
|
}
|
||||||
|
/* update proposal */
|
||||||
|
proposal->set_spi(proposal, ESP, (u_int64_t)this->esp_spi);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (status != SUCCESS)
|
||||||
|
{
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterator->destroy(iterator);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus, bool mine)
|
||||||
|
{
|
||||||
|
protocol_id_t protocols[2];
|
||||||
|
u_int32_t spi;
|
||||||
|
encryption_algorithm_t enc_algo;
|
||||||
|
integrity_algorithm_t int_algo;
|
||||||
|
chunk_t enc_key, int_key;
|
||||||
|
algorithm_t *algo;
|
||||||
|
crypter_t *crypter;
|
||||||
|
signer_t *signer;
|
||||||
|
size_t key_size;
|
||||||
|
host_t *src;
|
||||||
|
host_t *dst;
|
||||||
|
status_t status;
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
/* we must assign the roles to correctly set up the SAs */
|
||||||
|
if (mine)
|
||||||
|
{
|
||||||
|
src = this->me;
|
||||||
|
dst = this->other;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst = this->me;
|
||||||
|
src = this->other;
|
||||||
|
}
|
||||||
|
|
||||||
|
proposal->get_protocols(proposal, protocols);
|
||||||
|
/* derive keys in order as protocols appear */
|
||||||
|
for (i = 0; i<2; i++)
|
||||||
|
{
|
||||||
|
if (protocols[i] != UNDEFINED_PROTOCOL_ID)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* now we have to decide which spi to use. Use self allocated, if "mine",
|
||||||
|
* or the one in the proposal, if not "mine" (others). */
|
||||||
|
if (mine)
|
||||||
|
{
|
||||||
|
if (protocols[i] == AH)
|
||||||
|
{
|
||||||
|
spi = this->ah_spi;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
spi = this->esp_spi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else /* use proposals spi */
|
||||||
|
{
|
||||||
|
spi = proposal->get_spi(proposal, protocols[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* derive encryption key first */
|
||||||
|
if (proposal->get_algorithm(proposal, protocols[i], ENCRYPTION_ALGORITHM, &algo))
|
||||||
|
{
|
||||||
|
enc_algo = algo->algorithm;
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL1, "%s for %s: using %s %s, ",
|
||||||
|
mapping_find(protocol_id_m, protocols[i]),
|
||||||
|
mine ? "me" : "other",
|
||||||
|
mapping_find(transform_type_m, ENCRYPTION_ALGORITHM),
|
||||||
|
mapping_find(encryption_algorithm_m, enc_algo));
|
||||||
|
|
||||||
|
/* we must create a (unused) crypter, since its the only way to get the size
|
||||||
|
* of the key. This is not so nice, since charon must support all algorithms
|
||||||
|
* the kernel supports...
|
||||||
|
* TODO: build something of a encryption algorithm lookup function
|
||||||
|
*/
|
||||||
|
crypter = crypter_create(enc_algo, algo->key_size);
|
||||||
|
key_size = crypter->get_key_size(crypter);
|
||||||
|
crypter->destroy(crypter);
|
||||||
|
prf_plus->allocate_bytes(prf_plus, key_size, &enc_key);
|
||||||
|
this->logger->log_chunk(this->logger, PRIVATE, "key:", &enc_key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enc_algo = ENCR_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* derive integrity key */
|
||||||
|
if (proposal->get_algorithm(proposal, protocols[i], INTEGRITY_ALGORITHM, &algo))
|
||||||
|
{
|
||||||
|
int_algo = algo->algorithm;
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL1, "%s for %s: using %s %s,",
|
||||||
|
mapping_find(protocol_id_m, protocols[i]),
|
||||||
|
mine ? "me" : "other",
|
||||||
|
mapping_find(transform_type_m, INTEGRITY_ALGORITHM),
|
||||||
|
mapping_find(integrity_algorithm_m, algo->algorithm));
|
||||||
|
|
||||||
|
signer = signer_create(int_algo);
|
||||||
|
key_size = signer->get_key_size(signer);
|
||||||
|
signer->destroy(signer);
|
||||||
|
prf_plus->allocate_bytes(prf_plus, key_size, &int_key);
|
||||||
|
this->logger->log_chunk(this->logger, PRIVATE, "key:", &int_key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int_algo = AUTH_UNDEFINED;
|
||||||
|
}
|
||||||
|
/* send keys down to kernel */
|
||||||
|
this->logger->log(this->logger, CONTROL|LEVEL1,
|
||||||
|
"installing 0x%.8x for %s, src %s dst %s",
|
||||||
|
ntohl(spi), mapping_find(protocol_id_m, protocols[i]),
|
||||||
|
src->get_address(src), dst->get_address(dst));
|
||||||
|
status = charon->kernel_interface->add_sa(charon->kernel_interface,
|
||||||
|
src, dst,
|
||||||
|
spi, protocols[i], FALSE,
|
||||||
|
enc_algo, enc_key,
|
||||||
|
int_algo, int_key, mine);
|
||||||
|
/* clean up for next round */
|
||||||
|
if (enc_algo != ENCR_UNDEFINED)
|
||||||
|
{
|
||||||
|
allocator_free_chunk(&enc_key);
|
||||||
|
}
|
||||||
|
if (int_algo != AUTH_UNDEFINED)
|
||||||
|
{
|
||||||
|
allocator_free_chunk(&int_key);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != SUCCESS)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static status_t add(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus)
|
||||||
|
{
|
||||||
|
linked_list_t *list;
|
||||||
|
|
||||||
|
/* install others (initiators) SAs*/
|
||||||
|
if (install(this, proposal, prf_plus, FALSE) != SUCCESS)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get SPIs for our SAs */
|
||||||
|
list = linked_list_create();
|
||||||
|
list->insert_last(list, proposal);
|
||||||
|
if (alloc(this, list) != SUCCESS)
|
||||||
|
{
|
||||||
|
list->destroy(list);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
list->destroy(list);
|
||||||
|
|
||||||
|
/* install our (responders) SAs */
|
||||||
|
if (install(this, proposal, prf_plus, TRUE) != SUCCESS)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static status_t update(private_child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus)
|
||||||
|
{
|
||||||
|
/* install our (initator) SAs */
|
||||||
|
if (install(this, proposal, prf_plus, TRUE) != SUCCESS)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
/* install his (responder) SAs */
|
||||||
|
if (install(this, proposal, prf_plus, FALSE) != SUCCESS)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of child_sa_t.destroy.
|
* Implementation of child_sa_t.destroy.
|
||||||
*/
|
*/
|
||||||
@@ -70,54 +322,23 @@ static void destroy(private_child_sa_t *this)
|
|||||||
/*
|
/*
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
child_sa_t * child_sa_create(proposal_t *proposal, prf_plus_t *prf_plus)
|
child_sa_t * child_sa_create(host_t *me, host_t* other)
|
||||||
{
|
{
|
||||||
private_child_sa_t *this = allocator_alloc_thing(private_child_sa_t);
|
private_child_sa_t *this = allocator_alloc_thing(private_child_sa_t);
|
||||||
u_int i;
|
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
this->public.get_spi = (u_int32_t(*)(child_sa_t*))get_spi;
|
this->public.get_spi = (u_int32_t(*)(child_sa_t*))get_spi;
|
||||||
|
this->public.alloc = (status_t(*)(child_sa_t*,linked_list_t*))alloc;
|
||||||
|
this->public.add = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))add;
|
||||||
|
this->public.update = (status_t(*)(child_sa_t*,proposal_t*,prf_plus_t*))update;
|
||||||
this->public.destroy = (void(*)(child_sa_t*))destroy;
|
this->public.destroy = (void(*)(child_sa_t*))destroy;
|
||||||
|
|
||||||
/* private data */
|
/* private data */
|
||||||
this->logger = charon->logger_manager->create_logger(charon->logger_manager, CHILD_SA, NULL);
|
this->logger = charon->logger_manager->create_logger(charon->logger_manager, CHILD_SA, NULL);
|
||||||
proposal->get_protocols(proposal, this->protocols);
|
this->me = me;
|
||||||
|
this->other = other;
|
||||||
/* derive keys */
|
this->ah_spi = 0;
|
||||||
for (i = 0; i<2; i++)
|
this->esp_spi = 0;
|
||||||
{
|
|
||||||
if (this->protocols[i] != UNDEFINED_PROTOCOL_ID)
|
|
||||||
{
|
|
||||||
algorithm_t *algo;
|
|
||||||
chunk_t key;
|
|
||||||
|
|
||||||
/* get encryption key */
|
|
||||||
if (proposal->get_algorithm(proposal, this->protocols[i], ENCRYPTION_ALGORITHM, &algo))
|
|
||||||
{
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL1, "%s: using %s %s, ",
|
|
||||||
mapping_find(protocol_id_m, this->protocols[i]),
|
|
||||||
mapping_find(transform_type_m, ENCRYPTION_ALGORITHM),
|
|
||||||
mapping_find(encryption_algorithm_m, algo->algorithm));
|
|
||||||
|
|
||||||
prf_plus->allocate_bytes(prf_plus, algo->key_size, &key);
|
|
||||||
this->logger->log_chunk(this->logger, PRIVATE, "key:", &key);
|
|
||||||
allocator_free_chunk(&key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get integrity key */
|
|
||||||
if (proposal->get_algorithm(proposal, this->protocols[i], INTEGRITY_ALGORITHM, &algo))
|
|
||||||
{
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL1, "%s: using %s %s,",
|
|
||||||
mapping_find(protocol_id_m, this->protocols[i]),
|
|
||||||
mapping_find(transform_type_m, INTEGRITY_ALGORITHM),
|
|
||||||
mapping_find(integrity_algorithm_m, algo->algorithm));
|
|
||||||
|
|
||||||
prf_plus->allocate_bytes(prf_plus, algo->key_size, &key);
|
|
||||||
this->logger->log_chunk(this->logger, PRIVATE, "key:", &key);
|
|
||||||
allocator_free_chunk(&key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (&this->public);
|
return (&this->public);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ struct child_sa_t {
|
|||||||
*/
|
*/
|
||||||
u_int32_t (*get_spi) (child_sa_t *this);
|
u_int32_t (*get_spi) (child_sa_t *this);
|
||||||
|
|
||||||
|
|
||||||
|
status_t (*alloc)(child_sa_t *this, linked_list_t* proposals);
|
||||||
|
status_t (*add)(child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus);
|
||||||
|
status_t (*update)(child_sa_t *this, proposal_t *proposal, prf_plus_t *prf_plus);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Destroys a child_sa.
|
* @brief Destroys a child_sa.
|
||||||
*
|
*
|
||||||
@@ -67,6 +72,6 @@ struct child_sa_t {
|
|||||||
* @return child_sa_t object
|
* @return child_sa_t object
|
||||||
* @ingroup sa
|
* @ingroup sa
|
||||||
*/
|
*/
|
||||||
child_sa_t * child_sa_create(proposal_t *proposal, prf_plus_t *prf_plus);
|
child_sa_t * child_sa_create(host_t *me, host_t *other);
|
||||||
|
|
||||||
#endif /*_CHILD_SA_H_*/
|
#endif /*_CHILD_SA_H_*/
|
||||||
|
|||||||
@@ -417,7 +417,7 @@ status_t retransmit_request (private_ike_sa_t *this, u_int32_t message_id)
|
|||||||
*/
|
*/
|
||||||
static void set_new_state (private_ike_sa_t *this, state_t *state)
|
static void set_new_state (private_ike_sa_t *this, state_t *state)
|
||||||
{
|
{
|
||||||
this->logger->log(this->logger, CONTROL, "Change current state %s to %s",
|
this->logger->log(this->logger, CONTROL, "statechange: %s => %s",
|
||||||
mapping_find(ike_sa_state_m,this->current_state->get_state(this->current_state)),
|
mapping_find(ike_sa_state_m,this->current_state->get_state(this->current_state)),
|
||||||
mapping_find(ike_sa_state_m,state->get_state(state)));
|
mapping_find(ike_sa_state_m,state->get_state(state)));
|
||||||
this->current_state = state;
|
this->current_state = state;
|
||||||
@@ -963,6 +963,14 @@ static ike_sa_state_t get_state (private_ike_sa_t *this)
|
|||||||
return this->current_state->get_state(this->current_state);
|
return this->current_state->get_state(this->current_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of protected_ike_sa_t.get_state.
|
||||||
|
*/
|
||||||
|
static void add_child_sa (private_ike_sa_t *this, child_sa_t *child_sa)
|
||||||
|
{
|
||||||
|
this->child_sas->insert_last(this->child_sas, child_sa);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of protected_ike_sa_t.reset_message_buffers.
|
* Implementation of protected_ike_sa_t.reset_message_buffers.
|
||||||
*/
|
*/
|
||||||
@@ -1008,21 +1016,17 @@ static void create_delete_established_ike_sa_job (private_ike_sa_t *this,u_int32
|
|||||||
*/
|
*/
|
||||||
static void destroy (private_ike_sa_t *this)
|
static void destroy (private_ike_sa_t *this)
|
||||||
{
|
{
|
||||||
|
child_sa_t *child_sa;
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2, "Going to destroy IKE SA %llu:%llu, role %s",
|
this->logger->log(this->logger, CONTROL|LEVEL2, "Going to destroy IKE SA %llu:%llu, role %s",
|
||||||
this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
|
this->ike_sa_id->get_initiator_spi(this->ike_sa_id),
|
||||||
this->ike_sa_id->get_responder_spi(this->ike_sa_id),
|
this->ike_sa_id->get_responder_spi(this->ike_sa_id),
|
||||||
this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder");
|
this->ike_sa_id->is_initiator(this->ike_sa_id) ? "initiator" : "responder");
|
||||||
|
|
||||||
/* destroy child sa's */
|
/* destroy child sa's */
|
||||||
this->logger->log(this->logger, CONTROL | LEVEL3, "Destroy all child_sa's");
|
while (this->child_sas->remove_last(this->child_sas, (void**)&child_sa) == SUCCESS)
|
||||||
while (this->child_sas->get_count(this->child_sas) > 0)
|
|
||||||
{
|
{
|
||||||
void *child_sa;
|
child_sa->destroy(child_sa);
|
||||||
if (this->child_sas->remove_first(this->child_sas, &child_sa) != SUCCESS)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* destroy child sa */
|
|
||||||
}
|
}
|
||||||
this->child_sas->destroy(this->child_sas);
|
this->child_sas->destroy(this->child_sas);
|
||||||
|
|
||||||
@@ -1134,6 +1138,7 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
|
|||||||
this->protected.get_child_prf = (prf_t *(*) (protected_ike_sa_t *)) get_child_prf;
|
this->protected.get_child_prf = (prf_t *(*) (protected_ike_sa_t *)) get_child_prf;
|
||||||
this->protected.get_prf_auth_i = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_i;
|
this->protected.get_prf_auth_i = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_i;
|
||||||
this->protected.get_prf_auth_r = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_r;
|
this->protected.get_prf_auth_r = (prf_t *(*) (protected_ike_sa_t *)) get_prf_auth_r;
|
||||||
|
this->protected.add_child_sa = (void (*) (protected_ike_sa_t*,child_sa_t*)) add_child_sa;
|
||||||
this->protected.get_logger = (logger_t *(*) (protected_ike_sa_t *)) get_logger;
|
this->protected.get_logger = (logger_t *(*) (protected_ike_sa_t *)) get_logger;
|
||||||
this->protected.set_init_config = (void (*) (protected_ike_sa_t *,init_config_t *)) set_init_config;
|
this->protected.set_init_config = (void (*) (protected_ike_sa_t *,init_config_t *)) set_init_config;
|
||||||
this->protected.get_init_config = (init_config_t *(*) (protected_ike_sa_t *)) get_init_config;
|
this->protected.get_init_config = (init_config_t *(*) (protected_ike_sa_t *)) get_init_config;
|
||||||
|
|||||||
@@ -27,10 +27,11 @@
|
|||||||
#include <encoding/message.h>
|
#include <encoding/message.h>
|
||||||
#include <encoding/payloads/proposal_substructure.h>
|
#include <encoding/payloads/proposal_substructure.h>
|
||||||
#include <sa/ike_sa_id.h>
|
#include <sa/ike_sa_id.h>
|
||||||
|
#include <sa/child_sa.h>
|
||||||
|
#include <sa/states/state.h>
|
||||||
#include <config/configuration_manager.h>
|
#include <config/configuration_manager.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
#include <utils/randomizer.h>
|
#include <utils/randomizer.h>
|
||||||
#include <sa/states/state.h>
|
|
||||||
#include <transforms/prfs/prf.h>
|
#include <transforms/prfs/prf.h>
|
||||||
#include <transforms/crypters/crypter.h>
|
#include <transforms/crypters/crypter.h>
|
||||||
#include <transforms/signers/signer.h>
|
#include <transforms/signers/signer.h>
|
||||||
@@ -387,6 +388,14 @@ struct protected_ike_sa_t {
|
|||||||
*/
|
*/
|
||||||
prf_t *(*get_prf_auth_r) (protected_ike_sa_t *this);
|
prf_t *(*get_prf_auth_r) (protected_ike_sa_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Associates a child SA to this IKE SA
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @param child_sa child_sa to add
|
||||||
|
*/
|
||||||
|
void (*add_child_sa) (protected_ike_sa_t *this, child_sa_t *child_sa);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the last responded message.
|
* @brief Get the last responded message.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -72,6 +72,11 @@ struct private_ike_auth_requested_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t ike_sa_init_reply_data;
|
chunk_t ike_sa_init_reply_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Child sa created in ike_sa_init_requested
|
||||||
|
*/
|
||||||
|
child_sa_t *child_sa;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigned Logger.
|
* Assigned Logger.
|
||||||
*
|
*
|
||||||
@@ -136,6 +141,16 @@ struct private_ike_auth_requested_t {
|
|||||||
* - DELETE_ME
|
* - DELETE_ME
|
||||||
*/
|
*/
|
||||||
status_t (*process_notify_payload) (private_ike_auth_requested_t *this, notify_payload_t *notify_payload);
|
status_t (*process_notify_payload) (private_ike_auth_requested_t *this, notify_payload_t *notify_payload);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy function called internally of this class after state change to
|
||||||
|
* state IKE_SA_ESTABLISHED succeeded.
|
||||||
|
*
|
||||||
|
* This destroy function does not destroy objects which were passed to the new state.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
*/
|
||||||
|
void (*destroy_after_state_change) (private_ike_auth_requested_t *this);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -288,7 +303,7 @@ static status_t process_message(private_ike_auth_requested_t *this, message_t *i
|
|||||||
|
|
||||||
this->ike_sa->create_delete_established_ike_sa_job(this->ike_sa,this->sa_config->get_ike_sa_lifetime(this->sa_config));
|
this->ike_sa->create_delete_established_ike_sa_job(this->ike_sa,this->sa_config->get_ike_sa_lifetime(this->sa_config));
|
||||||
this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa));
|
this->ike_sa->set_new_state(this->ike_sa, (state_t*)ike_sa_established_create(this->ike_sa));
|
||||||
this->public.state_interface.destroy(&(this->public.state_interface));
|
this->destroy_after_state_change(this);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,7 +343,6 @@ static status_t process_sa_payload(private_ike_auth_requested_t *this, sa_payloa
|
|||||||
{
|
{
|
||||||
proposal_t *proposal, *proposal_tmp;
|
proposal_t *proposal, *proposal_tmp;
|
||||||
linked_list_t *proposal_list;
|
linked_list_t *proposal_list;
|
||||||
child_sa_t *child_sa;
|
|
||||||
chunk_t seed;
|
chunk_t seed;
|
||||||
prf_plus_t *prf_plus;
|
prf_plus_t *prf_plus;
|
||||||
|
|
||||||
@@ -377,10 +391,19 @@ static status_t process_sa_payload(private_ike_auth_requested_t *this, sa_payloa
|
|||||||
prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
|
prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
|
||||||
allocator_free_chunk(&seed);
|
allocator_free_chunk(&seed);
|
||||||
|
|
||||||
child_sa = child_sa_create(proposal, prf_plus);
|
if (this->child_sa)
|
||||||
prf_plus->destroy(prf_plus);
|
{
|
||||||
child_sa->destroy(child_sa);
|
if (this->child_sa->update(this->child_sa, proposal, prf_plus) != SUCCESS)
|
||||||
|
{
|
||||||
|
this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
|
||||||
|
prf_plus->destroy(prf_plus);
|
||||||
|
proposal->destroy(proposal);
|
||||||
|
return DELETE_ME;
|
||||||
|
}
|
||||||
|
this->ike_sa->add_child_sa(this->ike_sa, this->child_sa);
|
||||||
|
}
|
||||||
|
|
||||||
|
prf_plus->destroy(prf_plus);
|
||||||
proposal->destroy(proposal);
|
proposal->destroy(proposal);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
@@ -521,6 +544,20 @@ static ike_sa_state_t get_state(private_ike_auth_requested_t *this)
|
|||||||
* Implements state_t.get_state
|
* Implements state_t.get_state
|
||||||
*/
|
*/
|
||||||
static void destroy(private_ike_auth_requested_t *this)
|
static void destroy(private_ike_auth_requested_t *this)
|
||||||
|
{
|
||||||
|
allocator_free_chunk(&(this->received_nonce));
|
||||||
|
allocator_free_chunk(&(this->sent_nonce));
|
||||||
|
allocator_free_chunk(&(this->ike_sa_init_reply_data));
|
||||||
|
if (this->child_sa)
|
||||||
|
{
|
||||||
|
this->child_sa->destroy(this->child_sa);
|
||||||
|
}
|
||||||
|
allocator_free(this);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Implements protected_ike_sa_t.destroy_after_state_change
|
||||||
|
*/
|
||||||
|
static void destroy_after_state_change(private_ike_auth_requested_t *this)
|
||||||
{
|
{
|
||||||
allocator_free_chunk(&(this->received_nonce));
|
allocator_free_chunk(&(this->received_nonce));
|
||||||
allocator_free_chunk(&(this->sent_nonce));
|
allocator_free_chunk(&(this->sent_nonce));
|
||||||
@@ -531,7 +568,7 @@ static void destroy(private_ike_auth_requested_t *this)
|
|||||||
/*
|
/*
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,chunk_t sent_nonce,chunk_t received_nonce,chunk_t ike_sa_init_reply_data)
|
ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,chunk_t sent_nonce,chunk_t received_nonce,chunk_t ike_sa_init_reply_data, child_sa_t *child_sa)
|
||||||
{
|
{
|
||||||
private_ike_auth_requested_t *this = allocator_alloc_thing(private_ike_auth_requested_t);
|
private_ike_auth_requested_t *this = allocator_alloc_thing(private_ike_auth_requested_t);
|
||||||
|
|
||||||
@@ -541,12 +578,12 @@ ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,chunk
|
|||||||
this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
|
this->public.state_interface.destroy = (void (*) (state_t *)) destroy;
|
||||||
|
|
||||||
/* private functions */
|
/* private functions */
|
||||||
|
|
||||||
this->process_idr_payload = process_idr_payload;
|
this->process_idr_payload = process_idr_payload;
|
||||||
this->process_sa_payload = process_sa_payload;
|
this->process_sa_payload = process_sa_payload;
|
||||||
this->process_auth_payload = process_auth_payload;
|
this->process_auth_payload = process_auth_payload;
|
||||||
this->process_ts_payload = process_ts_payload;
|
this->process_ts_payload = process_ts_payload;
|
||||||
this->process_notify_payload = process_notify_payload;
|
this->process_notify_payload = process_notify_payload;
|
||||||
|
this->destroy_after_state_change = destroy_after_state_change;
|
||||||
|
|
||||||
/* private data */
|
/* private data */
|
||||||
this->ike_sa = ike_sa;
|
this->ike_sa = ike_sa;
|
||||||
@@ -554,6 +591,7 @@ ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,chunk
|
|||||||
this->sent_nonce = sent_nonce;
|
this->sent_nonce = sent_nonce;
|
||||||
this->ike_sa_init_reply_data = ike_sa_init_reply_data;
|
this->ike_sa_init_reply_data = ike_sa_init_reply_data;
|
||||||
this->logger = this->ike_sa->get_logger(this->ike_sa);
|
this->logger = this->ike_sa->get_logger(this->ike_sa);
|
||||||
|
this->child_sa = child_sa;
|
||||||
|
|
||||||
return &(this->public);
|
return &(this->public);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,6 @@ typedef struct ike_auth_requested_t ike_auth_requested_t;
|
|||||||
*
|
*
|
||||||
* @todo handle certificate payloads
|
* @todo handle certificate payloads
|
||||||
*
|
*
|
||||||
* @todo setup child SAs, if requested
|
|
||||||
*
|
|
||||||
* @ingroup states
|
* @ingroup states
|
||||||
*/
|
*/
|
||||||
struct ike_auth_requested_t {
|
struct ike_auth_requested_t {
|
||||||
@@ -60,6 +58,7 @@ struct ike_auth_requested_t {
|
|||||||
* @param sent_nonce Sent nonce value in IKE_SA_INIT request
|
* @param sent_nonce Sent nonce value in IKE_SA_INIT request
|
||||||
* @param received_nonce Received nonce value in IKE_SA_INIT response
|
* @param received_nonce Received nonce value in IKE_SA_INIT response
|
||||||
* @param ike_sa_init_reply_data binary representation of IKE_SA_INIT reply
|
* @param ike_sa_init_reply_data binary representation of IKE_SA_INIT reply
|
||||||
|
* @param child_sa opened but not completed child_sa
|
||||||
* @return created ike_auth_requested_t object
|
* @return created ike_auth_requested_t object
|
||||||
*
|
*
|
||||||
* @ingroup states
|
* @ingroup states
|
||||||
@@ -67,6 +66,7 @@ struct ike_auth_requested_t {
|
|||||||
ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,
|
ike_auth_requested_t *ike_auth_requested_create(protected_ike_sa_t *ike_sa,
|
||||||
chunk_t sent_nonce,
|
chunk_t sent_nonce,
|
||||||
chunk_t received_nonce,
|
chunk_t received_nonce,
|
||||||
chunk_t ike_sa_init_reply_data);
|
chunk_t ike_sa_init_reply_data,
|
||||||
|
child_sa_t *child_sa);
|
||||||
|
|
||||||
#endif /*IKE_AUTH_REQUESTED_H_*/
|
#endif /*IKE_AUTH_REQUESTED_H_*/
|
||||||
|
|||||||
@@ -79,6 +79,11 @@ struct private_ike_sa_init_requested_t {
|
|||||||
*/
|
*/
|
||||||
chunk_t ike_sa_init_request_data;
|
chunk_t ike_sa_init_request_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created child sa, if any
|
||||||
|
*/
|
||||||
|
child_sa_t *child_sa;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assigned logger
|
* Assigned logger
|
||||||
*
|
*
|
||||||
@@ -187,8 +192,6 @@ struct private_ike_sa_init_requested_t {
|
|||||||
* Destroy function called internally of this class after state change to
|
* Destroy function called internally of this class after state change to
|
||||||
* state IKE_AUTH_REQUESTED succeeded.
|
* state IKE_AUTH_REQUESTED succeeded.
|
||||||
*
|
*
|
||||||
* In case of state change to INITIATOR_INIT the default destroy function gets called.
|
|
||||||
*
|
|
||||||
* This destroy function does not destroy objects which were passed to the new state.
|
* This destroy function does not destroy objects which were passed to the new state.
|
||||||
*
|
*
|
||||||
* @param this calling object
|
* @param this calling object
|
||||||
@@ -383,7 +386,8 @@ static status_t process_message(private_ike_sa_init_requested_t *this, message_t
|
|||||||
ike_sa_init_reply_data = ike_sa_init_reply->get_packet_data(ike_sa_init_reply);
|
ike_sa_init_reply_data = ike_sa_init_reply->get_packet_data(ike_sa_init_reply);
|
||||||
|
|
||||||
/* state can now be changed */
|
/* state can now be changed */
|
||||||
next_state = ike_auth_requested_create(this->ike_sa,this->sent_nonce,this->received_nonce,ike_sa_init_reply_data);
|
next_state = ike_auth_requested_create(this->ike_sa, this->sent_nonce, this->received_nonce,
|
||||||
|
ike_sa_init_reply_data, this->child_sa);
|
||||||
this->ike_sa->set_new_state(this->ike_sa,(state_t *) next_state);
|
this->ike_sa->set_new_state(this->ike_sa,(state_t *) next_state);
|
||||||
|
|
||||||
this->destroy_after_state_change(this);
|
this->destroy_after_state_change(this);
|
||||||
@@ -512,9 +516,21 @@ static status_t build_sa_payload (private_ike_sa_init_requested_t *this, message
|
|||||||
/* get proposals form config, add to payload */
|
/* get proposals form config, add to payload */
|
||||||
sa_config = this->ike_sa->get_sa_config(this->ike_sa);
|
sa_config = this->ike_sa->get_sa_config(this->ike_sa);
|
||||||
proposal_list = sa_config->get_proposals(sa_config);
|
proposal_list = sa_config->get_proposals(sa_config);
|
||||||
sa_payload = sa_payload_create_from_proposal_list(proposal_list);
|
/* build child sa */
|
||||||
|
this->child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
|
||||||
|
this->ike_sa->get_other_host(this->ike_sa));
|
||||||
|
if (this->child_sa->alloc(this->child_sa, proposal_list) != SUCCESS)
|
||||||
|
{
|
||||||
|
this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
|
||||||
|
return DELETE_ME;
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO child sa stuff */
|
/* TODO:
|
||||||
|
* Huston, we've got a problem here. Since SPIs are stored in
|
||||||
|
* the proposal, and these proposals are shared across configs,
|
||||||
|
* there may be some threading issues... fix it!
|
||||||
|
*/
|
||||||
|
sa_payload = sa_payload_create_from_proposal_list(proposal_list);
|
||||||
|
|
||||||
this->logger->log(this->logger, CONTROL|LEVEL2, "Add SA payload to message");
|
this->logger->log(this->logger, CONTROL|LEVEL2, "Add SA payload to message");
|
||||||
request->add_payload(request,(payload_t *) sa_payload);
|
request->add_payload(request,(payload_t *) sa_payload);
|
||||||
@@ -705,6 +721,10 @@ static void destroy(private_ike_sa_init_requested_t *this)
|
|||||||
allocator_free(this->sent_nonce.ptr);
|
allocator_free(this->sent_nonce.ptr);
|
||||||
allocator_free(this->received_nonce.ptr);
|
allocator_free(this->received_nonce.ptr);
|
||||||
allocator_free_chunk(&(this->ike_sa_init_request_data));
|
allocator_free_chunk(&(this->ike_sa_init_request_data));
|
||||||
|
if (this->child_sa)
|
||||||
|
{
|
||||||
|
this->child_sa->destroy(this->child_sa);
|
||||||
|
}
|
||||||
if (this->proposal)
|
if (this->proposal)
|
||||||
{
|
{
|
||||||
this->proposal->destroy(this->proposal);
|
this->proposal->destroy(this->proposal);
|
||||||
@@ -743,6 +763,7 @@ ike_sa_init_requested_t *ike_sa_init_requested_create(protected_ike_sa_t *ike_sa
|
|||||||
this->diffie_hellman = diffie_hellman;
|
this->diffie_hellman = diffie_hellman;
|
||||||
this->proposal = NULL;
|
this->proposal = NULL;
|
||||||
this->sent_nonce = sent_nonce;
|
this->sent_nonce = sent_nonce;
|
||||||
|
this->child_sa = NULL;
|
||||||
this->ike_sa_init_request_data = ike_sa_init_request_data;
|
this->ike_sa_init_request_data = ike_sa_init_request_data;
|
||||||
|
|
||||||
return &(this->public);
|
return &(this->public);
|
||||||
|
|||||||
@@ -425,10 +425,6 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
|
|||||||
return DELETE_ME;
|
return DELETE_ME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create payload with selected propsal */
|
|
||||||
sa_response = sa_payload_create_from_proposal(proposal);
|
|
||||||
response->add_payload(response, (payload_t*)sa_response);
|
|
||||||
|
|
||||||
/* install child SAs for AH and esp */
|
/* install child SAs for AH and esp */
|
||||||
seed = allocator_alloc_as_chunk(this->received_nonce.len + this->sent_nonce.len);
|
seed = allocator_alloc_as_chunk(this->received_nonce.len + this->sent_nonce.len);
|
||||||
memcpy(seed.ptr, this->received_nonce.ptr, this->received_nonce.len);
|
memcpy(seed.ptr, this->received_nonce.ptr, this->received_nonce.len);
|
||||||
@@ -436,10 +432,22 @@ static status_t build_sa_payload(private_ike_sa_init_responded_t *this, sa_paylo
|
|||||||
prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
|
prf_plus = prf_plus_create(this->ike_sa->get_child_prf(this->ike_sa), seed);
|
||||||
allocator_free_chunk(&seed);
|
allocator_free_chunk(&seed);
|
||||||
|
|
||||||
child_sa = child_sa_create(proposal, prf_plus);
|
child_sa = child_sa_create(this->ike_sa->get_my_host(this->ike_sa),
|
||||||
prf_plus->destroy(prf_plus);
|
this->ike_sa->get_other_host(this->ike_sa));
|
||||||
child_sa->destroy(child_sa);
|
if (child_sa->add(child_sa, proposal, prf_plus) != SUCCESS)
|
||||||
|
{
|
||||||
|
this->logger->log(this->logger, AUDIT, "Could not install CHILD_SA! Deleting IKE_SA");
|
||||||
|
prf_plus->destroy(prf_plus);
|
||||||
|
proposal->destroy(proposal);
|
||||||
|
return DELETE_ME;
|
||||||
|
}
|
||||||
|
this->ike_sa->add_child_sa(this->ike_sa, child_sa);
|
||||||
|
|
||||||
|
/* create payload with selected propsal */
|
||||||
|
sa_response = sa_payload_create_from_proposal(proposal);
|
||||||
|
response->add_payload(response, (payload_t*)sa_response);
|
||||||
|
|
||||||
|
prf_plus->destroy(prf_plus);
|
||||||
proposal->destroy(proposal);
|
proposal->destroy(proposal);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,3 +128,7 @@ TEST_OBJS+= $(BUILD_DIR)kernel_interface_test.o
|
|||||||
$(BUILD_DIR)kernel_interface_test.o : $(TESTCASES_DIR)kernel_interface_test.c $(TESTCASES_DIR)kernel_interface_test.h
|
$(BUILD_DIR)kernel_interface_test.o : $(TESTCASES_DIR)kernel_interface_test.c $(TESTCASES_DIR)kernel_interface_test.h
|
||||||
$(CC) $(CFLAGS) -c -o $@ $<
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
|
TEST_OBJS+= $(BUILD_DIR)child_sa_test.o
|
||||||
|
$(BUILD_DIR)child_sa_test.o : $(TESTCASES_DIR)child_sa_test.c $(TESTCASES_DIR)child_sa_test.h
|
||||||
|
$(CC) $(CFLAGS) -c -o $@ $<
|
||||||
|
|
||||||
@@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
* @file child_sa_test.c
|
||||||
|
*
|
||||||
|
* @brief Tests for the child_sa_t class.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "child_sa_test.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
#include <sa/child_sa.h>
|
||||||
|
#include <utils/allocator.h>
|
||||||
|
#include <utils/logger.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
void test_child_sa(protected_tester_t *tester)
|
||||||
|
{
|
||||||
|
proposal_t *proposal1, *proposal2;
|
||||||
|
linked_list_t *list;
|
||||||
|
host_t *local_me, *remote_me;
|
||||||
|
host_t *local_other, *remote_other;
|
||||||
|
child_sa_t *local_sa, *remote_sa;
|
||||||
|
prf_plus_t *local_prf_plus, *remote_prf_plus;
|
||||||
|
prf_t *local_prf, *remote_prf;
|
||||||
|
u_int8_t key_buffer[] = {0x01,0x02,0x03,0x04};
|
||||||
|
chunk_t key = {key_buffer, sizeof(key_buffer)};
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
/* setup test data */
|
||||||
|
local_me = host_create(AF_INET, "192.168.0.1", 0);
|
||||||
|
local_other = host_create(AF_INET, "192.168.0.2", 0);
|
||||||
|
remote_me = host_create(AF_INET, "192.168.0.3", 0);
|
||||||
|
remote_other = host_create(AF_INET, "192.168.0.4", 0);
|
||||||
|
|
||||||
|
local_sa = child_sa_create(local_me, local_other);
|
||||||
|
remote_sa = child_sa_create(remote_me, remote_other);
|
||||||
|
|
||||||
|
proposal1 = proposal_create(1);
|
||||||
|
proposal1->add_algorithm(proposal1, ESP, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 16);
|
||||||
|
|
||||||
|
proposal2 = proposal_create(2);
|
||||||
|
proposal2->add_algorithm(proposal2, AH, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96, 0);
|
||||||
|
|
||||||
|
list = linked_list_create();
|
||||||
|
list->insert_last(list, proposal1);
|
||||||
|
list->insert_last(list, proposal2);
|
||||||
|
|
||||||
|
local_prf = prf_create(PRF_HMAC_SHA1);
|
||||||
|
remote_prf = prf_create(PRF_HMAC_SHA1);
|
||||||
|
local_prf->set_key(local_prf, key);
|
||||||
|
remote_prf->set_key(remote_prf, key);
|
||||||
|
local_prf_plus = prf_plus_create(local_prf, key);
|
||||||
|
remote_prf_plus = prf_plus_create(remote_prf, key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* local plays initiator
|
||||||
|
***********************
|
||||||
|
*/
|
||||||
|
status = local_sa->alloc(local_sa, list);
|
||||||
|
tester->assert_true(tester, status == SUCCESS, "spi allocation");
|
||||||
|
|
||||||
|
status = remote_sa->add(remote_sa, proposal1, remote_prf_plus);
|
||||||
|
tester->assert_true(tester, status == SUCCESS, "sa add");
|
||||||
|
|
||||||
|
status = local_sa->update(local_sa, proposal1, local_prf_plus);
|
||||||
|
tester->assert_true(tester, status == SUCCESS, "sa update");
|
||||||
|
|
||||||
|
/* cleanup */
|
||||||
|
proposal1->destroy(proposal1);
|
||||||
|
proposal2->destroy(proposal2);
|
||||||
|
list->destroy(list);
|
||||||
|
local_prf->destroy(local_prf);
|
||||||
|
local_prf_plus->destroy(local_prf_plus);
|
||||||
|
remote_prf->destroy(remote_prf);
|
||||||
|
remote_prf_plus->destroy(remote_prf_plus);
|
||||||
|
local_sa->destroy(local_sa);
|
||||||
|
remote_sa->destroy(remote_sa);
|
||||||
|
local_me->destroy(local_me);
|
||||||
|
local_other->destroy(local_other);
|
||||||
|
remote_me->destroy(remote_me);
|
||||||
|
remote_other->destroy(remote_other);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* @file child_sa_test.h
|
||||||
|
*
|
||||||
|
* @brief Tests for the child_sa_t class.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef CHILD_SA_TEST_H_
|
||||||
|
#define CHILD_SA_TEST_H_
|
||||||
|
|
||||||
|
#include <utils/tester.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Test function used to test the child_sa_t functionality.
|
||||||
|
*
|
||||||
|
* @param tester associated protected_tester_t object
|
||||||
|
*
|
||||||
|
* @ingroup testcases
|
||||||
|
*/
|
||||||
|
void test_child_sa(protected_tester_t *tester);
|
||||||
|
|
||||||
|
#endif //CHILD_SA_TEST_H_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -32,9 +32,9 @@
|
|||||||
void test_init_config(protected_tester_t *tester)
|
void test_init_config(protected_tester_t *tester)
|
||||||
{
|
{
|
||||||
init_config_t *init_config = init_config_create("192.168.0.1","192.168.0.2",500,500);
|
init_config_t *init_config = init_config_create("192.168.0.1","192.168.0.2",500,500);
|
||||||
proposal_t *prop1, *prop2, *prop3, *prop4, *selected_one;
|
proposal_t *prop1, *prop2, *prop3, *prop4;//, *selected_one;
|
||||||
linked_list_t *list;
|
linked_list_t *list;
|
||||||
status_t status;
|
//status_t status;
|
||||||
|
|
||||||
prop1 = proposal_create(1);
|
prop1 = proposal_create(1);
|
||||||
prop1->add_algorithm(prop1, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
|
prop1->add_algorithm(prop1, IKE, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 20);
|
||||||
|
|||||||
@@ -65,10 +65,10 @@ void test_kernel_interface(protected_tester_t *tester)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//status = kernel_interface->get_spi(kernel_interface, me, other, 50, TRUE, &spi);
|
status = kernel_interface->get_spi(kernel_interface, me, other, 50, FALSE, &spi);
|
||||||
//tester->assert_true(tester, status == SUCCESS, "spi get");
|
tester->assert_true(tester, status == SUCCESS, "spi get");
|
||||||
|
|
||||||
status = kernel_interface->add_sa(kernel_interface, me, other, spi, 50, TRUE, ENCR_AES_CBC, enc_key,AUTH_HMAC_MD5_96,inc_key,TRUE);
|
status = kernel_interface->add_sa(kernel_interface, me, other, spi, 50, FALSE, ENCR_AES_CBC, enc_key,AUTH_UNDEFINED,inc_key,TRUE);
|
||||||
tester->assert_true(tester, status == SUCCESS, "build sa");
|
tester->assert_true(tester, status == SUCCESS, "build sa");
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -61,6 +61,7 @@
|
|||||||
#include <testcases/proposal_test.h>
|
#include <testcases/proposal_test.h>
|
||||||
#include <testcases/rsa_test.h>
|
#include <testcases/rsa_test.h>
|
||||||
#include <testcases/kernel_interface_test.h>
|
#include <testcases/kernel_interface_test.h>
|
||||||
|
#include <testcases/child_sa_test.h>
|
||||||
|
|
||||||
/* output for test messages */
|
/* output for test messages */
|
||||||
extern FILE * stderr;
|
extern FILE * stderr;
|
||||||
@@ -126,6 +127,7 @@ test_t sa_config_test = {test_sa_config, "sa_config_t test"};
|
|||||||
test_t proposal_test = {test_proposal, "proposal_t test"};
|
test_t proposal_test = {test_proposal, "proposal_t test"};
|
||||||
test_t rsa_test = {test_rsa, "RSA private/public key test"};
|
test_t rsa_test = {test_rsa, "RSA private/public key test"};
|
||||||
test_t kernel_interface_test = {test_kernel_interface, "Kernel Interface"};
|
test_t kernel_interface_test = {test_kernel_interface, "Kernel Interface"};
|
||||||
|
test_t child_sa_test = {test_child_sa, "Child SA"};
|
||||||
|
|
||||||
|
|
||||||
daemon_t* charon;
|
daemon_t* charon;
|
||||||
@@ -138,6 +140,7 @@ static void daemon_kill(daemon_t *this, char* none)
|
|||||||
this->job_queue->destroy(this->job_queue);
|
this->job_queue->destroy(this->job_queue);
|
||||||
this->event_queue->destroy(this->event_queue);
|
this->event_queue->destroy(this->event_queue);
|
||||||
this->send_queue->destroy(this->send_queue);
|
this->send_queue->destroy(this->send_queue);
|
||||||
|
this->kernel_interface->destroy(this->kernel_interface);
|
||||||
//this->configuration_manager->destroy(this->configuration_manager);
|
//this->configuration_manager->destroy(this->configuration_manager);
|
||||||
allocator_free(charon);
|
allocator_free(charon);
|
||||||
}
|
}
|
||||||
@@ -160,6 +163,7 @@ daemon_t *daemon_create()
|
|||||||
charon->job_queue = job_queue_create();
|
charon->job_queue = job_queue_create();
|
||||||
charon->event_queue = event_queue_create();
|
charon->event_queue = event_queue_create();
|
||||||
charon->send_queue = send_queue_create();
|
charon->send_queue = send_queue_create();
|
||||||
|
charon->kernel_interface = kernel_interface_create();
|
||||||
//charon->configuration_manager = configuration_manager_create(RETRANSMIT_TIMEOUT,MAX_RETRANSMIT_COUNT,HALF_OPEN_IKE_SA_TIMEOUT);
|
//charon->configuration_manager = configuration_manager_create(RETRANSMIT_TIMEOUT,MAX_RETRANSMIT_COUNT,HALF_OPEN_IKE_SA_TIMEOUT);
|
||||||
charon->sender = NULL;
|
charon->sender = NULL;
|
||||||
charon->receiver = NULL;
|
charon->receiver = NULL;
|
||||||
@@ -237,6 +241,8 @@ int main()
|
|||||||
&rsa_test,
|
&rsa_test,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
/* get rid of compiler warning ;-) */
|
||||||
|
*all_tests = *all_tests;
|
||||||
|
|
||||||
/* allocator needs initialization */
|
/* allocator needs initialization */
|
||||||
allocator_init();
|
allocator_init();
|
||||||
@@ -244,13 +250,14 @@ int main()
|
|||||||
daemon_create();
|
daemon_create();
|
||||||
|
|
||||||
charon->logger_manager->disable_logger_level(charon->logger_manager,TESTER,FULL);
|
charon->logger_manager->disable_logger_level(charon->logger_manager,TESTER,FULL);
|
||||||
|
charon->logger_manager->enable_logger_level(charon->logger_manager,CHILD_SA,FULL);
|
||||||
/* charon->logger_manager->enable_logger_level(charon->logger_manager,TESTER,RAW); */
|
/* charon->logger_manager->enable_logger_level(charon->logger_manager,TESTER,RAW); */
|
||||||
|
|
||||||
tester_t *tester = tester_create(test_output, FALSE);
|
tester_t *tester = tester_create(test_output, FALSE);
|
||||||
|
|
||||||
|
|
||||||
tester->perform_tests(tester,all_tests);
|
//tester->perform_tests(tester,all_tests);
|
||||||
//tester->perform_test(tester,&kernel_interface_test);
|
tester->perform_test(tester,&child_sa_test);
|
||||||
|
|
||||||
|
|
||||||
tester->destroy(tester);
|
tester->destroy(tester);
|
||||||
|
|||||||
@@ -40,6 +40,10 @@
|
|||||||
#include <utils/linked_list.h>
|
#include <utils/linked_list.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define KERNEL_ESP 50
|
||||||
|
#define KERNEL_AH 51
|
||||||
|
|
||||||
|
|
||||||
typedef struct netlink_message_t netlink_message_t;
|
typedef struct netlink_message_t netlink_message_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,48 +87,48 @@ struct private_kernel_interface_t {
|
|||||||
/**
|
/**
|
||||||
* Public part of the kernel_interface_t object.
|
* Public part of the kernel_interface_t object.
|
||||||
*/
|
*/
|
||||||
kernel_interface_t public;
|
kernel_interface_t public;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Netlink communication socket.
|
* Netlink communication socket.
|
||||||
*/
|
*/
|
||||||
int socket;
|
int socket;
|
||||||
|
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
/**
|
/**
|
||||||
* Sequence number for messages.
|
* Sequence number for messages.
|
||||||
*/
|
*/
|
||||||
u_int32_t seq;
|
u_int32_t seq;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of responded messages.
|
* List of responded messages.
|
||||||
*/
|
*/
|
||||||
linked_list_t *responses;
|
linked_list_t *responses;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Thread which receives messages.
|
* Thread which receives messages.
|
||||||
*/
|
*/
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mutex locks access to replies list.
|
* Mutex locks access to replies list.
|
||||||
*/
|
*/
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Condvar allows signaling of threads waiting for a reply.
|
* Condvar allows signaling of threads waiting for a reply.
|
||||||
*/
|
*/
|
||||||
pthread_cond_t condvar;
|
pthread_cond_t condvar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function for the thread, receives messages.
|
* Function for the thread, receives messages.
|
||||||
*/
|
*/
|
||||||
void (*receive_messages) (private_kernel_interface_t *this);
|
void (*receive_messages) (private_kernel_interface_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a netlink_message_t down to the kernel and wait for reply.
|
* Sends a netlink_message_t down to the kernel and wait for reply.
|
||||||
*/
|
*/
|
||||||
status_t (*send_message) (private_kernel_interface_t *this, netlink_message_t *request, netlink_message_t **response);
|
status_t (*send_message) (private_kernel_interface_t *this, netlink_message_t *request, netlink_message_t **response);
|
||||||
};
|
};
|
||||||
|
|
||||||
mapping_t kernel_encryption_algs_m[] = {
|
mapping_t kernel_encryption_algs_m[] = {
|
||||||
@@ -157,41 +161,42 @@ static status_t get_spi(private_kernel_interface_t *this, host_t *src, host_t *d
|
|||||||
{
|
{
|
||||||
netlink_message_t request, *response;
|
netlink_message_t request, *response;
|
||||||
|
|
||||||
memset(&request, 0, sizeof(request));
|
memset(&request, 0, sizeof(request));
|
||||||
request.hdr.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(request.spi)));
|
request.hdr.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(request.spi)));
|
||||||
request.hdr.nlmsg_flags = NLM_F_REQUEST;
|
request.hdr.nlmsg_flags = NLM_F_REQUEST;
|
||||||
request.hdr.nlmsg_type = XFRM_MSG_ALLOCSPI;
|
request.hdr.nlmsg_type = XFRM_MSG_ALLOCSPI;
|
||||||
request.spi.info.saddr = src->get_xfrm_addr(src);
|
request.spi.info.saddr = src->get_xfrm_addr(src);
|
||||||
request.spi.info.id.daddr = dest->get_xfrm_addr(dest);
|
request.spi.info.id.daddr = dest->get_xfrm_addr(dest);
|
||||||
request.spi.info.mode = tunnel_mode;
|
request.spi.info.mode = tunnel_mode;
|
||||||
request.spi.info.id.proto = protocol;
|
/* TODO: this should be done with getprotobyname() */
|
||||||
request.spi.info.family = PF_INET;
|
request.spi.info.id.proto = (protocol == ESP) ? KERNEL_ESP : KERNEL_AH;
|
||||||
request.spi.min = 100;
|
request.spi.info.family = PF_INET;
|
||||||
request.spi.max = 200;
|
request.spi.min = 100;
|
||||||
|
request.spi.max = 200;
|
||||||
|
|
||||||
if (this->send_message(this, &request, &response) != SUCCESS)
|
if (this->send_message(this, &request, &response) != SUCCESS)
|
||||||
{
|
{
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response->hdr.nlmsg_type == NLMSG_ERROR)
|
|
||||||
{
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response->hdr.nlmsg_type != XFRM_MSG_NEWSA)
|
|
||||||
{
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
else if (response->hdr.nlmsg_len < NLMSG_LENGTH(sizeof(response->sa)))
|
|
||||||
{
|
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response->hdr.nlmsg_type == NLMSG_ERROR)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response->hdr.nlmsg_type != XFRM_MSG_NEWSA)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
else if (response->hdr.nlmsg_len < NLMSG_LENGTH(sizeof(response->sa)))
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
*spi = response->sa.id.spi;
|
*spi = response->sa.id.spi;
|
||||||
allocator_free(response);
|
allocator_free(response);
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static status_t add_sa( private_kernel_interface_t *this,
|
static status_t add_sa( private_kernel_interface_t *this,
|
||||||
@@ -206,34 +211,35 @@ static status_t add_sa( private_kernel_interface_t *this,
|
|||||||
chunk_t integrity_key,
|
chunk_t integrity_key,
|
||||||
bool replace)
|
bool replace)
|
||||||
{
|
{
|
||||||
netlink_message_t request, *response;
|
netlink_message_t request, *response;
|
||||||
POS;
|
memset(&request, 0, sizeof(request));
|
||||||
memset(&request, 0, sizeof(request));
|
|
||||||
|
|
||||||
request.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
|
||||||
request.hdr.nlmsg_type = replace ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
|
|
||||||
|
|
||||||
request.sa.saddr = me->get_xfrm_addr(me);
|
request.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||||
request.sa.id.daddr = other->get_xfrm_addr(other);
|
request.hdr.nlmsg_type = replace ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
|
||||||
|
|
||||||
request.sa.id.spi = spi;
|
request.sa.saddr = me->get_xfrm_addr(me);
|
||||||
request.sa.id.proto = protocol;
|
request.sa.id.daddr = other->get_xfrm_addr(other);
|
||||||
request.sa.family = me->get_family(me);
|
|
||||||
request.sa.mode = tunnel_mode;
|
|
||||||
request.sa.replay_window = 0; //sa->replay_window; ???
|
|
||||||
request.sa.reqid = 0; //sa->reqid; ???
|
|
||||||
request.sa.lft.soft_byte_limit = XFRM_INF;
|
|
||||||
request.sa.lft.soft_packet_limit = XFRM_INF;
|
|
||||||
request.sa.lft.hard_byte_limit = XFRM_INF;
|
|
||||||
request.sa.lft.hard_packet_limit = XFRM_INF;
|
|
||||||
|
|
||||||
request.hdr.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(request.sa)));
|
request.sa.id.spi = spi;
|
||||||
|
/* TODO: this should be done with getprotobyname() */
|
||||||
|
request.sa.id.proto = (protocol == ESP) ? KERNEL_ESP : KERNEL_AH;
|
||||||
|
request.sa.family = me->get_family(me);
|
||||||
|
request.sa.mode = tunnel_mode;
|
||||||
|
request.sa.replay_window = 0; //sa->replay_window; ???
|
||||||
|
request.sa.reqid = 0; //sa->reqid; ???
|
||||||
|
request.sa.lft.soft_byte_limit = XFRM_INF;
|
||||||
|
request.sa.lft.soft_packet_limit = XFRM_INF;
|
||||||
|
request.sa.lft.hard_byte_limit = XFRM_INF;
|
||||||
|
request.sa.lft.hard_packet_limit = XFRM_INF;
|
||||||
|
|
||||||
if (enc_alg != ENCR_UNDEFINED)
|
request.hdr.nlmsg_len = NLMSG_ALIGN(NLMSG_LENGTH(sizeof(request.sa)));
|
||||||
{
|
|
||||||
|
if (enc_alg != ENCR_UNDEFINED)
|
||||||
|
{
|
||||||
netlink_algo_t *nla = (netlink_algo_t*)(((u_int8_t*)&request) + request.hdr.nlmsg_len);
|
netlink_algo_t *nla = (netlink_algo_t*)(((u_int8_t*)&request) + request.hdr.nlmsg_len);
|
||||||
|
|
||||||
nla->type = XFRMA_ALG_CRYPT;
|
nla->type = XFRMA_ALG_CRYPT;
|
||||||
nla->length = sizeof(netlink_algo_t) + encryption_key.len;
|
nla->length = sizeof(netlink_algo_t) + encryption_key.len;
|
||||||
nla->algo.alg_key_len = encryption_key.len * 8;
|
nla->algo.alg_key_len = encryption_key.len * 8;
|
||||||
|
|
||||||
@@ -241,10 +247,10 @@ static status_t add_sa( private_kernel_interface_t *this,
|
|||||||
memcpy(nla->algo.alg_key, encryption_key.ptr, encryption_key.len);
|
memcpy(nla->algo.alg_key, encryption_key.ptr, encryption_key.len);
|
||||||
|
|
||||||
request.hdr.nlmsg_len += nla->length;
|
request.hdr.nlmsg_len += nla->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (int_alg != AUTH_UNDEFINED)
|
if (int_alg != AUTH_UNDEFINED)
|
||||||
{
|
{
|
||||||
netlink_algo_t *nla = (netlink_algo_t*)(((u_int8_t*)&request) + request.hdr.nlmsg_len);
|
netlink_algo_t *nla = (netlink_algo_t*)(((u_int8_t*)&request) + request.hdr.nlmsg_len);
|
||||||
|
|
||||||
nla->type = XFRMA_ALG_AUTH;
|
nla->type = XFRMA_ALG_AUTH;
|
||||||
@@ -254,18 +260,18 @@ static status_t add_sa( private_kernel_interface_t *this,
|
|||||||
memcpy(nla->algo.alg_key, integrity_key.ptr, integrity_key.len);
|
memcpy(nla->algo.alg_key, integrity_key.ptr, integrity_key.len);
|
||||||
|
|
||||||
request.hdr.nlmsg_len += nla->length;
|
request.hdr.nlmsg_len += nla->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add IPComp */
|
/* add IPComp here*/
|
||||||
|
|
||||||
if (this->send_message(this, &request, &response) != SUCCESS)
|
if (this->send_message(this, &request, &response) != SUCCESS)
|
||||||
{
|
{
|
||||||
allocator_free(response);
|
allocator_free(response);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
allocator_free(response);
|
allocator_free(response);
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -308,17 +314,17 @@ static status_t send_message(private_kernel_interface_t *this, netlink_message_t
|
|||||||
if (listed_response->hdr.nlmsg_seq == request->hdr.nlmsg_seq)
|
if (listed_response->hdr.nlmsg_seq == request->hdr.nlmsg_seq)
|
||||||
{
|
{
|
||||||
/* matches our request, this is the reply */
|
/* matches our request, this is the reply */
|
||||||
*response = listed_response;
|
*response = listed_response;
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
iterator->destroy(iterator);
|
iterator->destroy(iterator);
|
||||||
|
|
||||||
if (found)
|
if (found)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* we should time out, if something goes wrong */
|
/* we should time out, if something goes wrong */
|
||||||
pthread_cond_wait(&(this->condvar), &(this->mutex));
|
pthread_cond_wait(&(this->condvar), &(this->mutex));
|
||||||
}
|
}
|
||||||
@@ -336,7 +342,7 @@ static void receive_messages(private_kernel_interface_t *this)
|
|||||||
netlink_message_t response, *listed_response;
|
netlink_message_t response, *listed_response;
|
||||||
while (TRUE)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
struct sockaddr_nl addr;
|
struct sockaddr_nl addr;
|
||||||
socklen_t addr_length;
|
socklen_t addr_length;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
@@ -347,11 +353,11 @@ static void receive_messages(private_kernel_interface_t *this)
|
|||||||
if (length < 0)
|
if (length < 0)
|
||||||
{
|
{
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
{
|
{
|
||||||
/* interrupted, try again */
|
/* interrupted, try again */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
charon->kill(charon, "receiving from netlink socket failed");
|
charon->kill(charon, "receiving from netlink socket failed");
|
||||||
}
|
}
|
||||||
if (!NLMSG_OK(&response.hdr, length))
|
if (!NLMSG_OK(&response.hdr, length))
|
||||||
{
|
{
|
||||||
@@ -361,7 +367,7 @@ static void receive_messages(private_kernel_interface_t *this)
|
|||||||
if (addr.nl_pid != 0)
|
if (addr.nl_pid != 0)
|
||||||
{
|
{
|
||||||
/* not from kernel. not interested, try another one */
|
/* not from kernel. not interested, try another one */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ struct kernel_interface_t {
|
|||||||
* @todo Cleanup method params
|
* @todo Cleanup method params
|
||||||
*/
|
*/
|
||||||
status_t (*add_sa)(kernel_interface_t *this,
|
status_t (*add_sa)(kernel_interface_t *this,
|
||||||
host_t *me,
|
host_t *src,
|
||||||
host_t *other,
|
host_t *dst,
|
||||||
u_int32_t spi,
|
u_int32_t spi,
|
||||||
int protocol,
|
int protocol,
|
||||||
bool tunnel_mode,
|
bool tunnel_mode,
|
||||||
|
|||||||
@@ -175,11 +175,10 @@ static logger_t *create_logger(private_logger_manager_t *this, logger_context_t
|
|||||||
log_thread_ids = TRUE;
|
log_thread_ids = TRUE;
|
||||||
break;
|
break;
|
||||||
case IKE_SA:
|
case IKE_SA:
|
||||||
logger_level |= LEVEL1;
|
|
||||||
log_thread_ids = TRUE;
|
log_thread_ids = TRUE;
|
||||||
break;
|
break;
|
||||||
case CHILD_SA:
|
case CHILD_SA:
|
||||||
logger_level |= LEVEL1|PRIVATE;
|
logger_level |= LEVEL1;
|
||||||
log_thread_ids = TRUE;
|
log_thread_ids = TRUE;
|
||||||
break;
|
break;
|
||||||
case CONFIGURATION_MANAGER:
|
case CONFIGURATION_MANAGER:
|
||||||
|
|||||||
Reference in New Issue
Block a user