workaround for peers rekeying at the same time
loading lifetime policies from ipsec.conf
This commit is contained in:
parent
695723d4e8
commit
a2a3fb3e25
|
@ -213,7 +213,7 @@ static diffie_hellman_group_t get_dh_group(private_connection_t *this)
|
|||
}
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
return MODP_UNDEFINED;
|
||||
return MODP_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "policy.h"
|
||||
|
||||
|
@ -80,7 +81,23 @@ struct private_policy_t {
|
|||
* list for traffic selectors for others site
|
||||
*/
|
||||
linked_list_t *other_ts;
|
||||
|
||||
|
||||
/**
|
||||
* Time before an SA gets invalid
|
||||
*/
|
||||
u_int32_t soft_lifetime;
|
||||
|
||||
/**
|
||||
* Time before an SA gets rekeyed
|
||||
*/
|
||||
u_int32_t hard_lifetime;
|
||||
|
||||
/**
|
||||
* Time, which specifies the range of a random value
|
||||
* substracted from soft_lifetime.
|
||||
*/
|
||||
u_int32_t jitter;
|
||||
|
||||
/**
|
||||
* select_traffic_selectors for both
|
||||
*/
|
||||
|
@ -313,18 +330,18 @@ static void add_proposal(private_policy_t *this, proposal_t *proposal)
|
|||
/**
|
||||
* Implementation of policy_t.get_soft_lifetime
|
||||
*/
|
||||
static u_int32_t get_soft_lifetime(policy_t *this)
|
||||
static u_int32_t get_soft_lifetime(private_policy_t *this)
|
||||
{
|
||||
srandom(time(NULL)+getpid());
|
||||
return 5 + (random() % 10);
|
||||
return this->soft_lifetime - (random() % this->jitter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of policy_t.get_hard_lifetime
|
||||
*/
|
||||
static u_int32_t get_hard_lifetime(policy_t *this)
|
||||
static u_int32_t get_hard_lifetime(private_policy_t *this)
|
||||
{
|
||||
return 20;
|
||||
return this->hard_lifetime;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -334,7 +351,9 @@ static policy_t *clone(private_policy_t *this)
|
|||
{
|
||||
private_policy_t *clone = (private_policy_t*)policy_create(this->name,
|
||||
this->my_id->clone(this->my_id),
|
||||
this->other_id->clone(this->other_id));
|
||||
this->other_id->clone(this->other_id),
|
||||
this->hard_lifetime, this->soft_lifetime,
|
||||
this->jitter);
|
||||
iterator_t *iterator;
|
||||
proposal_t *proposal;
|
||||
traffic_selector_t *ts;
|
||||
|
@ -434,7 +453,9 @@ static status_t destroy(private_policy_t *this)
|
|||
/*
|
||||
* Described in header-file
|
||||
*/
|
||||
policy_t *policy_create(char *name, identification_t *my_id, identification_t *other_id)
|
||||
policy_t *policy_create(char *name, identification_t *my_id, identification_t *other_id,
|
||||
u_int32_t hard_lifetime, u_int32_t soft_lifetime,
|
||||
u_int32_t jitter)
|
||||
{
|
||||
private_policy_t *this = malloc_thing(private_policy_t);
|
||||
|
||||
|
@ -465,6 +486,9 @@ policy_t *policy_create(char *name, identification_t *my_id, identification_t *o
|
|||
this->name = strdup(name);
|
||||
this->my_id = my_id;
|
||||
this->other_id = other_id;
|
||||
this->hard_lifetime = hard_lifetime;
|
||||
this->soft_lifetime = soft_lifetime;
|
||||
this->jitter = jitter;
|
||||
|
||||
/* initialize private members*/
|
||||
this->my_ca = NULL;
|
||||
|
|
|
@ -277,14 +277,23 @@ struct policy_t {
|
|||
* @brief Create a configuration object for IKE_AUTH and later.
|
||||
*
|
||||
* name-string gets cloned, ID's not.
|
||||
* Lifetimes are in seconds. To prevent to peers to start rekeying at the
|
||||
* same time, a jitter may be specified. Rekeying of an SA starts at
|
||||
* (soft_lifetime - random(0, jitter)). After a successful rekeying,
|
||||
* the hard_lifetime limit counter is reset. You should specify
|
||||
* hard_lifetime > soft_lifetime > jitter.
|
||||
*
|
||||
* @param name name of the policy
|
||||
* @param my_id identification_t for ourselves
|
||||
* @param other_id identification_t for the remote guy
|
||||
* @param hard_lifetime lifetime before deleting an SA
|
||||
* @param soft_lifetime lifetime before rekeying an SA
|
||||
* @param jitter range of randomization time
|
||||
* @return policy_t object
|
||||
*
|
||||
* @ingroup config
|
||||
*/
|
||||
policy_t *policy_create(char *name, identification_t *my_id, identification_t *other_id);
|
||||
policy_t *policy_create(char *name, identification_t *my_id, identification_t *other_id,
|
||||
u_int32_t hard_lifetime, u_int32_t soft_lifetime, u_int32_t jitter);
|
||||
|
||||
#endif /* POLICY_H_ */
|
||||
|
|
|
@ -82,6 +82,11 @@ struct private_child_sa_t {
|
|||
*/
|
||||
u_int32_t reqid;
|
||||
|
||||
/**
|
||||
* time, on which SA was installed
|
||||
*/
|
||||
time_t install_time;
|
||||
|
||||
/**
|
||||
* Lifetime before rekeying
|
||||
*/
|
||||
|
@ -239,6 +244,8 @@ static status_t install(private_child_sa_t *this, proposal_t *proposal, prf_plus
|
|||
mine ? 0 : this->soft_lifetime,
|
||||
this->hard_lifetime,
|
||||
enc_algo, int_algo, prf_plus, mine);
|
||||
|
||||
this->install_time = time(NULL);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -406,11 +413,12 @@ static void log_status(private_child_sa_t *this, logger_t *logger, char* name)
|
|||
{
|
||||
logger = this->logger;
|
||||
}
|
||||
logger->log(logger, CONTROL|LEVEL1, " \"%s\": protected with %s (0x%x/0x%x), reqid %d:",
|
||||
logger->log(logger, CONTROL|LEVEL1, " \"%s\": protected with %s (0x%x/0x%x), reqid %d, rekeying in %ds:",
|
||||
name,
|
||||
this->protocol == PROTO_ESP ? "ESP" : "AH",
|
||||
htonl(this->me.spi), htonl(this->other.spi),
|
||||
this->reqid);
|
||||
this->reqid,
|
||||
this->soft_lifetime - (time(NULL) - this->install_time));
|
||||
iterator = this->policies->create_iterator(this->policies, TRUE);
|
||||
while (iterator->has_next(iterator))
|
||||
{
|
||||
|
|
|
@ -223,7 +223,15 @@ static status_t process_message(private_create_child_sa_requested_t *this, messa
|
|||
if (response->get_request(response))
|
||||
{
|
||||
this->logger->log(this->logger, ERROR | LEVEL1, "CREATE_CHILD_SA requests not allowed state create_child_sa_requested");
|
||||
return FAILED;
|
||||
/* TODO: our state implementation currently can not handle incoming requests cleanly here.
|
||||
* If a request comes in before an outstanding reply, we can not handle it the correct way.
|
||||
* Currently, we create a ESTABLISHED state and let it process the message... But we
|
||||
* need changes in the whole state mechanism.
|
||||
*/
|
||||
state_t *state = (state_t*)ike_sa_established_create(this->ike_sa);
|
||||
state->process_message(state, response);
|
||||
state->destroy(state);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* get signer for verification and crypter for decryption */
|
||||
|
|
|
@ -80,7 +80,15 @@ static status_t process_message(private_delete_child_sa_requested_t *this, messa
|
|||
if (response->get_request(response))
|
||||
{
|
||||
this->logger->log(this->logger, ERROR | LEVEL1, "INFORMATIONAL requests not allowed state delete_child_sa_requested");
|
||||
return FAILED;
|
||||
/* TODO: our state implementation currently can not handle incoming requests cleanly here.
|
||||
* If a request comes in before an outstanding reply, we can not handle it cleanly.
|
||||
* Currently, we create a ESTABLISHED state and let it process the message... But we
|
||||
* need changes in the whole state mechanism.
|
||||
*/
|
||||
state_t *state = (state_t*)ike_sa_established_create(this->ike_sa);
|
||||
state->process_message(state, response);
|
||||
state->destroy(state);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
/* get signer for verification and crypter for decryption */
|
||||
|
|
|
@ -274,6 +274,17 @@ static status_t process_create_child_sa(private_ike_sa_established_t *this, mess
|
|||
nonce_request = (nonce_payload_t*)payload;
|
||||
break;
|
||||
}
|
||||
case KEY_EXCHANGE:
|
||||
{
|
||||
/* we currently do not support a diffie hellman exchange
|
||||
* for CHILD_SAs. */
|
||||
u_int16_t no_group[1];
|
||||
no_group[0] = htons(MODP_NONE);
|
||||
chunk_t no_group_chunk = chunk_from_buf(no_group);
|
||||
this->ike_sa->send_notify(this->ike_sa, CREATE_CHILD_SA, INVALID_KE_PAYLOAD, no_group_chunk);
|
||||
payloads->destroy(payloads);
|
||||
return FAILED;
|
||||
}
|
||||
case NOTIFY:
|
||||
{
|
||||
notify = (notify_payload_t*)payload;
|
||||
|
|
|
@ -369,7 +369,7 @@ static status_t build_ke_payload(private_responder_init_t *this,ke_payload_t *ke
|
|||
this->logger->log(this->logger, CONTROL | LEVEL2, "Process received KE payload");
|
||||
group = ke_request->get_dh_group_number(ke_request);
|
||||
|
||||
if (group == MODP_UNDEFINED)
|
||||
if (group == MODP_NONE)
|
||||
{
|
||||
this->logger->log(this->logger, AUDIT, "No diffie hellman group to select. Deleting IKE_SA");
|
||||
return DESTROY_ME;
|
||||
|
@ -560,7 +560,7 @@ responder_init_t *responder_init_create(protected_ike_sa_t *ike_sa)
|
|||
this->logger = logger_manager->get_logger(logger_manager, IKE_SA);
|
||||
this->sent_nonce = CHUNK_INITIALIZER;
|
||||
this->received_nonce = CHUNK_INITIALIZER;
|
||||
this->dh_group_number = MODP_UNDEFINED;
|
||||
this->dh_group_number = MODP_NONE;
|
||||
this->diffie_hellman = NULL;
|
||||
this->proposal = NULL;
|
||||
|
||||
|
|
|
@ -332,7 +332,10 @@ static void stroke_add_conn(private_stroke_t *this, stroke_msg_t *msg)
|
|||
other_host->get_address(other_host),
|
||||
other_id->get_string(other_id));
|
||||
|
||||
policy = policy_create(msg->add_conn.name, my_id, other_id);
|
||||
policy = policy_create(msg->add_conn.name, my_id, other_id,
|
||||
msg->add_conn.rekey.ipsec_lifetime,
|
||||
msg->add_conn.rekey.ipsec_lifetime - msg->add_conn.rekey.margin,
|
||||
msg->add_conn.rekey.margin * msg->add_conn.rekey.fuzz / 100);
|
||||
proposal = proposal_create(PROTO_ESP);
|
||||
proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 128);
|
||||
proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, ENCR_AES_CBC, 256);
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
* String mappings for diffie_hellman_group_t.
|
||||
*/
|
||||
mapping_t diffie_hellman_group_m[] = {
|
||||
{MODP_UNDEFINED, "MODP_UNDEFINED"},
|
||||
{MODP_NONE, "MODP_NONE"},
|
||||
{MODP_768_BIT, "MODP_768_BIT"},
|
||||
{MODP_1024_BIT, "MODP_1024_BIT"},
|
||||
{MODP_1536_BIT, "MODP_1536_BIT"},
|
||||
|
|
|
@ -38,7 +38,7 @@ typedef enum diffie_hellman_group_t diffie_hellman_group_t;
|
|||
* @ingroup transforms
|
||||
*/
|
||||
enum diffie_hellman_group_t {
|
||||
MODP_UNDEFINED = 1024,
|
||||
MODP_NONE = 0,
|
||||
MODP_768_BIT = 1,
|
||||
MODP_1024_BIT = 2,
|
||||
MODP_1536_BIT = 5,
|
||||
|
|
|
@ -125,6 +125,11 @@ int starter_stroke_add_conn(starter_conn_t *conn)
|
|||
msg.length = offsetof(stroke_msg_t, buffer);
|
||||
msg.add_conn.ikev2 = conn->keyexchange == KEY_EXCHANGE_IKEV2;
|
||||
msg.add_conn.name = push_string(&msg, connection_name(conn));
|
||||
msg.add_conn.rekey.ipsec_lifetime = conn->sa_ipsec_life_seconds;
|
||||
msg.add_conn.rekey.ike_lifetime = conn->sa_ike_life_seconds;
|
||||
msg.add_conn.rekey.margin = conn->sa_rekey_margin;
|
||||
msg.add_conn.rekey.tries = conn->sa_keying_tries;
|
||||
msg.add_conn.rekey.fuzz = conn->sa_rekey_fuzz;
|
||||
|
||||
starter_stroke_add_end(&msg, &msg.add_conn.me, &conn->right);
|
||||
starter_stroke_add_end(&msg, &msg.add_conn.other, &conn->left);
|
||||
|
|
|
@ -28,8 +28,6 @@
|
|||
|
||||
#include "stroke.h"
|
||||
|
||||
#define streq(a, b) (strcmp((a), (b)) == 0) /* clearer shorthand */
|
||||
|
||||
static char* push_string(stroke_msg_t *msg, char *string)
|
||||
{
|
||||
u_int string_start = msg->length;
|
||||
|
@ -103,6 +101,12 @@ static int add_connection(char *name,
|
|||
msg.add_conn.name = push_string(&msg, name);
|
||||
msg.add_conn.ikev2 = 1;
|
||||
|
||||
msg.add_conn.rekey.ipsec_lifetime = 0;
|
||||
msg.add_conn.rekey.ike_lifetime = 0;
|
||||
msg.add_conn.rekey.margin = 0;
|
||||
msg.add_conn.rekey.tries = 0;
|
||||
msg.add_conn.rekey.fuzz = 0;
|
||||
|
||||
msg.add_conn.me.id = push_string(&msg, my_id);
|
||||
msg.add_conn.me.address = push_string(&msg, my_addr);
|
||||
msg.add_conn.me.subnet = push_string(&msg, my_net);
|
||||
|
|
|
@ -86,6 +86,13 @@ struct stroke_msg_t {
|
|||
struct {
|
||||
char *name;
|
||||
bool ikev2;
|
||||
struct {
|
||||
time_t ipsec_lifetime;
|
||||
time_t ike_lifetime;
|
||||
time_t margin;
|
||||
unsigned long tries;
|
||||
unsigned long fuzz;
|
||||
} rekey;
|
||||
stroke_end_t me, other;
|
||||
} add_conn;
|
||||
|
||||
|
|
Loading…
Reference in New Issue