2007-04-10 06:01:03 +00:00
|
|
|
/*
|
2008-06-10 09:08:27 +00:00
|
|
|
* Copyright (C) 2007-2008 Tobias Brunner
|
2009-04-14 10:34:24 +00:00
|
|
|
* Copyright (C) 2005-2009 Martin Willi
|
2007-04-10 06:01:03 +00:00
|
|
|
* Copyright (C) 2005 Jan Hutter
|
|
|
|
* Hochschule fuer Technik Rapperswil
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
|
|
* under the terms of the GNU General Public License as published by the
|
|
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful, but
|
|
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
|
|
* for more details.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "peer_cfg.h"
|
|
|
|
|
2008-11-11 06:37:37 +00:00
|
|
|
#include <daemon.h>
|
|
|
|
|
2009-12-08 15:53:01 +00:00
|
|
|
#include <threading/mutex.h>
|
2007-04-10 06:01:03 +00:00
|
|
|
#include <utils/linked_list.h>
|
|
|
|
#include <utils/identification.h>
|
|
|
|
|
|
|
|
ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
|
|
|
|
"CERT_ALWAYS_SEND",
|
|
|
|
"CERT_SEND_IF_ASKED",
|
2008-06-10 09:08:27 +00:00
|
|
|
"CERT_NEVER_SEND",
|
|
|
|
);
|
|
|
|
|
|
|
|
ENUM(unique_policy_names, UNIQUE_NO, UNIQUE_KEEP,
|
|
|
|
"UNIQUE_NO",
|
|
|
|
"UNIQUE_REPLACE",
|
|
|
|
"UNIQUE_KEEP",
|
|
|
|
);
|
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
typedef struct private_peer_cfg_t private_peer_cfg_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Private data of an peer_cfg_t object
|
|
|
|
*/
|
|
|
|
struct private_peer_cfg_t {
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Public part
|
|
|
|
*/
|
|
|
|
peer_cfg_t public;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
|
|
|
* Number of references hold by others to this peer_cfg
|
|
|
|
*/
|
|
|
|
refcount_t refcount;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
|
|
|
* Name of the peer_cfg, used to query it
|
|
|
|
*/
|
|
|
|
char *name;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
|
|
|
* IKE config associated to this peer config
|
|
|
|
*/
|
|
|
|
ike_cfg_t *ike_cfg;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
|
|
|
* list of child configs associated to this peer config
|
|
|
|
*/
|
|
|
|
linked_list_t *child_cfgs;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
|
|
|
* mutex to lock access to list of child_cfgs
|
|
|
|
*/
|
2008-11-05 11:29:56 +00:00
|
|
|
mutex_t *mutex;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
|
|
|
* should we send a certificate
|
|
|
|
*/
|
|
|
|
cert_policy_t cert_policy;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2008-04-14 13:23:24 +00:00
|
|
|
/**
|
|
|
|
* uniqueness of an IKE_SA
|
|
|
|
*/
|
|
|
|
unique_policy_t unique;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
|
|
|
* number of tries after giving up if peer does not respond
|
|
|
|
*/
|
|
|
|
u_int32_t keyingtries;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
2007-11-20 12:06:40 +00:00
|
|
|
* enable support for MOBIKE
|
2007-04-10 06:01:03 +00:00
|
|
|
*/
|
2007-11-20 12:06:40 +00:00
|
|
|
bool use_mobike;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-01-09 16:32:41 +00:00
|
|
|
/**
|
|
|
|
* Use aggressive mode?
|
|
|
|
*/
|
|
|
|
bool aggressive;
|
|
|
|
|
2007-08-29 12:11:25 +00:00
|
|
|
/**
|
2007-11-20 12:06:40 +00:00
|
|
|
* Time before starting rekeying
|
2007-08-29 12:11:25 +00:00
|
|
|
*/
|
2007-11-20 12:06:40 +00:00
|
|
|
u_int32_t rekey_time;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
2007-11-20 12:06:40 +00:00
|
|
|
* Time before starting reauthentication
|
2007-04-10 06:01:03 +00:00
|
|
|
*/
|
2007-11-20 12:06:40 +00:00
|
|
|
u_int32_t reauth_time;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
2011-07-20 13:57:53 +00:00
|
|
|
* Time, which specifies the range of a random value subtracted from above.
|
2007-04-10 06:01:03 +00:00
|
|
|
*/
|
2007-11-20 12:06:40 +00:00
|
|
|
u_int32_t jitter_time;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
2007-11-20 12:06:40 +00:00
|
|
|
* Delay before deleting a rekeying/reauthenticating SA
|
2007-04-10 06:01:03 +00:00
|
|
|
*/
|
2007-11-20 12:06:40 +00:00
|
|
|
u_int32_t over_time;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
2008-04-11 08:14:48 +00:00
|
|
|
* DPD check intervall
|
2007-04-10 06:01:03 +00:00
|
|
|
*/
|
2008-04-11 08:14:48 +00:00
|
|
|
u_int32_t dpd;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-05-17 17:49:22 +00:00
|
|
|
/**
|
|
|
|
* DPD timeout intervall (used for IKEv1 only)
|
|
|
|
*/
|
|
|
|
u_int32_t dpd_timeout;
|
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
2012-08-21 11:50:32 +00:00
|
|
|
* List of virtual IPs (host_t*) to request
|
2007-04-10 06:01:03 +00:00
|
|
|
*/
|
2012-08-21 11:50:32 +00:00
|
|
|
linked_list_t *vips;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-04-10 06:01:03 +00:00
|
|
|
/**
|
2012-08-24 12:31:24 +00:00
|
|
|
* List of pool names to use for virtual IP lookup
|
2007-04-10 06:01:03 +00:00
|
|
|
*/
|
2012-08-24 12:31:24 +00:00
|
|
|
linked_list_t *pools;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2008-03-13 14:14:44 +00:00
|
|
|
/**
|
2009-04-14 10:34:24 +00:00
|
|
|
* local authentication configs (rulesets)
|
2008-03-13 14:14:44 +00:00
|
|
|
*/
|
2009-04-14 10:34:24 +00:00
|
|
|
linked_list_t *local_auth;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
/**
|
|
|
|
* remote authentication configs (constraints)
|
|
|
|
*/
|
|
|
|
linked_list_t *remote_auth;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-09-02 15:26:36 +00:00
|
|
|
#ifdef ME
|
2007-10-03 15:10:41 +00:00
|
|
|
/**
|
|
|
|
* Is this a mediation connection?
|
|
|
|
*/
|
2008-03-26 18:40:19 +00:00
|
|
|
bool mediation;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-10-03 15:10:41 +00:00
|
|
|
/**
|
|
|
|
* Name of the mediation connection to mediate through
|
|
|
|
*/
|
2008-03-26 18:40:19 +00:00
|
|
|
peer_cfg_t *mediated_by;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-10-03 15:10:41 +00:00
|
|
|
/**
|
|
|
|
* ID of our peer at the mediation server (= leftid of the peer's conn with
|
|
|
|
* the mediation server)
|
|
|
|
*/
|
|
|
|
identification_t *peer_id;
|
2008-03-26 18:40:19 +00:00
|
|
|
#endif /* ME */
|
2007-04-10 06:01:03 +00:00
|
|
|
};
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_name, char*,
|
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
|
|
|
return this->name;
|
|
|
|
}
|
|
|
|
|
2011-11-16 16:28:06 +00:00
|
|
|
METHOD(peer_cfg_t, get_ike_version, ike_version_t,
|
2011-07-11 09:18:15 +00:00
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2012-10-16 12:31:02 +00:00
|
|
|
return this->ike_cfg->get_version(this->ike_cfg);
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_ike_cfg, ike_cfg_t*,
|
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
|
|
|
return this->ike_cfg;
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, add_child_cfg, void,
|
|
|
|
private_peer_cfg_t *this, child_cfg_t *child_cfg)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2008-11-05 11:29:56 +00:00
|
|
|
this->mutex->lock(this->mutex);
|
2007-04-10 06:01:03 +00:00
|
|
|
this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
|
2008-11-05 11:29:56 +00:00
|
|
|
this->mutex->unlock(this->mutex);
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
|
|
|
|
2009-05-06 09:09:57 +00:00
|
|
|
/**
|
|
|
|
* child_cfg enumerator
|
|
|
|
*/
|
|
|
|
typedef struct {
|
|
|
|
enumerator_t public;
|
|
|
|
enumerator_t *wrapped;
|
|
|
|
mutex_t *mutex;
|
|
|
|
} child_cfg_enumerator_t;
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, remove_child_cfg, void,
|
|
|
|
private_peer_cfg_t *this, child_cfg_enumerator_t *enumerator)
|
2009-05-06 09:09:57 +00:00
|
|
|
{
|
|
|
|
this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped);
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(enumerator_t, child_cfg_enumerator_destroy, void,
|
|
|
|
child_cfg_enumerator_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2008-11-05 11:29:56 +00:00
|
|
|
this->mutex->unlock(this->mutex);
|
2009-05-06 09:09:57 +00:00
|
|
|
this->wrapped->destroy(this->wrapped);
|
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(enumerator_t, child_cfg_enumerate, bool,
|
|
|
|
child_cfg_enumerator_t *this, child_cfg_t **chd)
|
2009-05-06 09:09:57 +00:00
|
|
|
{
|
|
|
|
return this->wrapped->enumerate(this->wrapped, chd);
|
2008-03-13 14:14:44 +00:00
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
|
|
|
|
private_peer_cfg_t *this)
|
2008-03-13 14:14:44 +00:00
|
|
|
{
|
2011-07-11 09:18:15 +00:00
|
|
|
child_cfg_enumerator_t *enumerator;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
INIT(enumerator,
|
|
|
|
.public = {
|
|
|
|
.enumerate = (void*)_child_cfg_enumerate,
|
|
|
|
.destroy = (void*)_child_cfg_enumerator_destroy,
|
|
|
|
},
|
|
|
|
.mutex = this->mutex,
|
|
|
|
.wrapped = this->child_cfgs->create_enumerator(this->child_cfgs),
|
|
|
|
);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2008-11-05 11:29:56 +00:00
|
|
|
this->mutex->lock(this->mutex);
|
2009-05-06 09:09:57 +00:00
|
|
|
return &enumerator->public;
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2009-07-07 12:38:19 +00:00
|
|
|
* Check how good a list of TS matches a given child config
|
2007-04-10 06:01:03 +00:00
|
|
|
*/
|
2009-07-07 12:38:19 +00:00
|
|
|
static int get_ts_match(child_cfg_t *cfg, bool local,
|
2012-09-18 10:46:36 +00:00
|
|
|
linked_list_t *sup_list, linked_list_t *hosts)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2009-07-07 12:38:19 +00:00
|
|
|
linked_list_t *cfg_list;
|
|
|
|
enumerator_t *sup_enum, *cfg_enum;
|
|
|
|
traffic_selector_t *sup_ts, *cfg_ts;
|
|
|
|
int match = 0, round;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-07-07 12:38:19 +00:00
|
|
|
/* fetch configured TS list, narrowing dynamic TS */
|
2012-09-18 10:46:36 +00:00
|
|
|
cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-07-07 12:38:19 +00:00
|
|
|
/* use a round counter to rate leading TS with higher priority */
|
|
|
|
round = sup_list->get_count(sup_list);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-07-07 12:38:19 +00:00
|
|
|
sup_enum = sup_list->create_enumerator(sup_list);
|
|
|
|
while (sup_enum->enumerate(sup_enum, &sup_ts))
|
2008-11-11 06:37:37 +00:00
|
|
|
{
|
2009-07-07 12:38:19 +00:00
|
|
|
cfg_enum = cfg_list->create_enumerator(cfg_list);
|
|
|
|
while (cfg_enum->enumerate(cfg_enum, &cfg_ts))
|
|
|
|
{
|
|
|
|
if (cfg_ts->equals(cfg_ts, sup_ts))
|
|
|
|
{ /* equality is honored better than matches */
|
|
|
|
match += round * 5;
|
|
|
|
}
|
|
|
|
else if (cfg_ts->is_contained_in(cfg_ts, sup_ts) ||
|
|
|
|
sup_ts->is_contained_in(sup_ts, cfg_ts))
|
|
|
|
{
|
|
|
|
match += round * 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cfg_enum->destroy(cfg_enum);
|
|
|
|
round--;
|
2008-11-11 06:37:37 +00:00
|
|
|
}
|
2009-07-07 12:38:19 +00:00
|
|
|
sup_enum->destroy(sup_enum);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-07-07 12:38:19 +00:00
|
|
|
cfg_list->destroy_offset(cfg_list, offsetof(traffic_selector_t, destroy));
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-07-07 12:38:19 +00:00
|
|
|
return match;
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
|
|
|
|
private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts,
|
2012-09-18 10:46:36 +00:00
|
|
|
linked_list_t *my_hosts, linked_list_t *other_hosts)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
|
|
|
child_cfg_t *current, *found = NULL;
|
2008-03-13 14:14:44 +00:00
|
|
|
enumerator_t *enumerator;
|
2008-11-11 06:37:37 +00:00
|
|
|
int best = 0;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-07-07 12:38:19 +00:00
|
|
|
DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts);
|
2008-03-13 14:14:44 +00:00
|
|
|
enumerator = create_child_cfg_enumerator(this);
|
|
|
|
while (enumerator->enumerate(enumerator, ¤t))
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2009-07-07 12:38:19 +00:00
|
|
|
int my_prio, other_prio;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-09-18 10:46:36 +00:00
|
|
|
my_prio = get_ts_match(current, TRUE, my_ts, my_hosts);
|
|
|
|
other_prio = get_ts_match(current, FALSE, other_ts, other_hosts);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-07-07 12:38:19 +00:00
|
|
|
if (my_prio && other_prio)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2009-07-07 12:38:19 +00:00
|
|
|
DBG2(DBG_CFG, " candidate \"%s\" with prio %d+%d",
|
|
|
|
current->get_name(current), my_prio, other_prio);
|
|
|
|
if (my_prio + other_prio > best)
|
2008-11-11 06:37:37 +00:00
|
|
|
{
|
2009-07-07 12:38:19 +00:00
|
|
|
best = my_prio + other_prio;
|
2008-11-11 06:37:37 +00:00
|
|
|
DESTROY_IF(found);
|
|
|
|
found = current->get_ref(current);
|
|
|
|
}
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
|
|
|
}
|
2008-03-13 14:14:44 +00:00
|
|
|
enumerator->destroy(enumerator);
|
2008-11-11 06:37:37 +00:00
|
|
|
if (found)
|
|
|
|
{
|
|
|
|
DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d",
|
|
|
|
found->get_name(found), best);
|
|
|
|
}
|
2007-04-10 06:01:03 +00:00
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_cert_policy, cert_policy_t,
|
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
|
|
|
return this->cert_policy;
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_unique_policy, unique_policy_t,
|
|
|
|
private_peer_cfg_t *this)
|
2008-04-14 13:23:24 +00:00
|
|
|
{
|
|
|
|
return this->unique;
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_keyingtries, u_int32_t,
|
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
|
|
|
return this->keyingtries;
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_rekey_time, u_int32_t,
|
2011-11-24 10:38:37 +00:00
|
|
|
private_peer_cfg_t *this, bool jitter)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2007-11-20 12:06:40 +00:00
|
|
|
if (this->rekey_time == 0)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2007-11-20 12:06:40 +00:00
|
|
|
return 0;
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
2011-11-24 10:38:37 +00:00
|
|
|
if (this->jitter_time == 0 || !jitter)
|
2007-11-20 12:06:40 +00:00
|
|
|
{
|
|
|
|
return this->rekey_time;
|
|
|
|
}
|
|
|
|
return this->rekey_time - (random() % this->jitter_time);
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
2007-11-20 12:06:40 +00:00
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_reauth_time, u_int32_t,
|
2011-11-24 10:38:37 +00:00
|
|
|
private_peer_cfg_t *this, bool jitter)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2007-11-20 12:06:40 +00:00
|
|
|
if (this->reauth_time == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2011-11-24 10:38:37 +00:00
|
|
|
if (this->jitter_time == 0 || !jitter)
|
2007-11-20 12:06:40 +00:00
|
|
|
{
|
|
|
|
return this->reauth_time;
|
|
|
|
}
|
|
|
|
return this->reauth_time - (random() % this->jitter_time);
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
2007-11-20 12:06:40 +00:00
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_over_time, u_int32_t,
|
|
|
|
private_peer_cfg_t *this)
|
2007-11-20 12:06:40 +00:00
|
|
|
{
|
|
|
|
return this->over_time;
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, use_mobike, bool,
|
|
|
|
private_peer_cfg_t *this)
|
2007-08-29 12:11:25 +00:00
|
|
|
{
|
|
|
|
return this->use_mobike;
|
|
|
|
}
|
2007-04-10 06:01:03 +00:00
|
|
|
|
2012-01-09 16:32:41 +00:00
|
|
|
METHOD(peer_cfg_t, use_aggressive, bool,
|
|
|
|
private_peer_cfg_t *this)
|
|
|
|
{
|
|
|
|
return this->aggressive;
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_dpd, u_int32_t,
|
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2008-04-11 08:14:48 +00:00
|
|
|
return this->dpd;
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
|
|
|
|
2012-05-17 17:49:22 +00:00
|
|
|
METHOD(peer_cfg_t, get_dpd_timeout, u_int32_t,
|
|
|
|
private_peer_cfg_t *this)
|
|
|
|
{
|
|
|
|
return this->dpd_timeout;
|
|
|
|
}
|
|
|
|
|
2012-08-21 11:50:32 +00:00
|
|
|
METHOD(peer_cfg_t, add_virtual_ip, void,
|
|
|
|
private_peer_cfg_t *this, host_t *vip)
|
|
|
|
{
|
|
|
|
this->vips->insert_last(this->vips, vip);
|
|
|
|
}
|
|
|
|
|
|
|
|
METHOD(peer_cfg_t, create_virtual_ip_enumerator, enumerator_t*,
|
2011-07-11 09:18:15 +00:00
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2012-08-21 11:50:32 +00:00
|
|
|
return this->vips->create_enumerator(this->vips);
|
2007-05-22 13:49:31 +00:00
|
|
|
}
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-08-24 12:31:24 +00:00
|
|
|
METHOD(peer_cfg_t, add_pool, void,
|
|
|
|
private_peer_cfg_t *this, char *name)
|
|
|
|
{
|
|
|
|
this->pools->insert_last(this->pools, strdup(name));
|
|
|
|
}
|
|
|
|
|
|
|
|
METHOD(peer_cfg_t, create_pool_enumerator, enumerator_t*,
|
2011-07-11 09:18:15 +00:00
|
|
|
private_peer_cfg_t *this)
|
2007-05-22 13:49:31 +00:00
|
|
|
{
|
2012-08-24 12:31:24 +00:00
|
|
|
return this->pools->create_enumerator(this->pools);
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
2009-04-14 10:34:24 +00:00
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, add_auth_cfg, void,
|
|
|
|
private_peer_cfg_t *this, auth_cfg_t *cfg, bool local)
|
2008-03-13 14:14:44 +00:00
|
|
|
{
|
2009-04-14 10:34:24 +00:00
|
|
|
if (local)
|
|
|
|
{
|
|
|
|
this->local_auth->insert_last(this->local_auth, cfg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->remote_auth->insert_last(this->remote_auth, cfg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, create_auth_cfg_enumerator, enumerator_t*,
|
|
|
|
private_peer_cfg_t *this, bool local)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
if (local)
|
|
|
|
{
|
|
|
|
return this->local_auth->create_enumerator(this->local_auth);
|
|
|
|
}
|
|
|
|
return this->remote_auth->create_enumerator(this->remote_auth);
|
2008-03-13 14:14:44 +00:00
|
|
|
}
|
2007-04-10 06:01:03 +00:00
|
|
|
|
2008-03-26 18:40:19 +00:00
|
|
|
#ifdef ME
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, is_mediation, bool,
|
|
|
|
private_peer_cfg_t *this)
|
2007-10-03 15:10:41 +00:00
|
|
|
{
|
2008-03-26 18:40:19 +00:00
|
|
|
return this->mediation;
|
2007-10-03 15:10:41 +00:00
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_mediated_by, peer_cfg_t*,
|
|
|
|
private_peer_cfg_t *this)
|
2007-10-03 15:10:41 +00:00
|
|
|
{
|
2008-04-03 15:13:25 +00:00
|
|
|
return this->mediated_by;
|
2007-10-03 15:10:41 +00:00
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_peer_id, identification_t*,
|
|
|
|
private_peer_cfg_t *this)
|
2007-10-03 15:10:41 +00:00
|
|
|
{
|
|
|
|
return this->peer_id;
|
|
|
|
}
|
2008-03-26 18:40:19 +00:00
|
|
|
#endif /* ME */
|
2007-10-03 15:10:41 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
/**
|
|
|
|
* check auth configs for equality
|
|
|
|
*/
|
|
|
|
static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
|
|
|
|
{
|
|
|
|
enumerator_t *e1, *e2;
|
|
|
|
auth_cfg_t *cfg1, *cfg2;
|
|
|
|
bool equal = TRUE;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
if (this->local_auth->get_count(this->local_auth) !=
|
|
|
|
other->local_auth->get_count(other->local_auth))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
if (this->remote_auth->get_count(this->remote_auth) !=
|
|
|
|
other->remote_auth->get_count(other->remote_auth))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
e1 = this->local_auth->create_enumerator(this->local_auth);
|
|
|
|
e2 = other->local_auth->create_enumerator(other->local_auth);
|
|
|
|
while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
|
|
|
|
{
|
|
|
|
if (!cfg1->equals(cfg1, cfg2))
|
|
|
|
{
|
|
|
|
equal = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e1->destroy(e1);
|
|
|
|
e2->destroy(e2);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
if (!equal)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
e1 = this->remote_auth->create_enumerator(this->remote_auth);
|
|
|
|
e2 = other->remote_auth->create_enumerator(other->remote_auth);
|
|
|
|
while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
|
|
|
|
{
|
|
|
|
if (!cfg1->equals(cfg1, cfg2))
|
|
|
|
{
|
|
|
|
equal = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e1->destroy(e1);
|
|
|
|
e2->destroy(e2);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
return equal;
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, equals, bool,
|
|
|
|
private_peer_cfg_t *this, private_peer_cfg_t *other)
|
2008-03-26 10:06:45 +00:00
|
|
|
{
|
2012-08-21 11:50:32 +00:00
|
|
|
enumerator_t *e1, *e2;
|
|
|
|
host_t *vip1, *vip2;
|
2012-08-24 12:31:24 +00:00
|
|
|
char *pool1, *pool2;
|
2012-08-21 11:50:32 +00:00
|
|
|
|
2008-03-26 10:06:45 +00:00
|
|
|
if (this == other)
|
|
|
|
{
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
if (this->public.equals != other->public.equals)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-08-21 11:50:32 +00:00
|
|
|
if (this->vips->get_count(this->vips) != other->vips->get_count(other->vips))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
e1 = create_virtual_ip_enumerator(this);
|
|
|
|
e2 = create_virtual_ip_enumerator(other);
|
|
|
|
if (e1->enumerate(e1, &vip1) && e2->enumerate(e2, &vip2))
|
|
|
|
{
|
|
|
|
if (!vip1->ip_equals(vip1, vip2))
|
|
|
|
{
|
|
|
|
e1->destroy(e1);
|
|
|
|
e2->destroy(e2);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e1->destroy(e1);
|
|
|
|
e2->destroy(e2);
|
|
|
|
|
2012-08-24 12:31:24 +00:00
|
|
|
if (this->pools->get_count(this->pools) !=
|
|
|
|
other->pools->get_count(other->pools))
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
e1 = create_pool_enumerator(this);
|
|
|
|
e2 = create_pool_enumerator(other);
|
|
|
|
if (e1->enumerate(e1, &pool1) && e2->enumerate(e2, &pool2))
|
|
|
|
{
|
|
|
|
if (!streq(pool1, pool2))
|
|
|
|
{
|
|
|
|
e1->destroy(e1);
|
|
|
|
e2->destroy(e2);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e1->destroy(e1);
|
|
|
|
e2->destroy(e2);
|
|
|
|
|
2008-03-26 10:06:45 +00:00
|
|
|
return (
|
2012-10-16 12:31:02 +00:00
|
|
|
get_ike_version(this) == get_ike_version(other) &&
|
2008-03-26 10:06:45 +00:00
|
|
|
this->cert_policy == other->cert_policy &&
|
2008-04-14 13:23:24 +00:00
|
|
|
this->unique == other->unique &&
|
2008-03-26 10:06:45 +00:00
|
|
|
this->keyingtries == other->keyingtries &&
|
|
|
|
this->use_mobike == other->use_mobike &&
|
|
|
|
this->rekey_time == other->rekey_time &&
|
|
|
|
this->reauth_time == other->reauth_time &&
|
|
|
|
this->jitter_time == other->jitter_time &&
|
|
|
|
this->over_time == other->over_time &&
|
2008-04-11 08:14:48 +00:00
|
|
|
this->dpd == other->dpd &&
|
2009-04-14 10:34:24 +00:00
|
|
|
auth_cfg_equal(this, other)
|
2008-03-26 18:40:19 +00:00
|
|
|
#ifdef ME
|
|
|
|
&& this->mediation == other->mediation &&
|
|
|
|
this->mediated_by == other->mediated_by &&
|
2008-03-26 10:06:45 +00:00
|
|
|
(this->peer_id == other->peer_id ||
|
|
|
|
(this->peer_id && other->peer_id &&
|
|
|
|
this->peer_id->equals(this->peer_id, other->peer_id)))
|
2008-03-26 18:40:19 +00:00
|
|
|
#endif /* ME */
|
2008-03-26 10:06:45 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, get_ref, peer_cfg_t*,
|
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
|
|
|
ref_get(&this->refcount);
|
2008-05-06 10:55:42 +00:00
|
|
|
return &this->public;
|
2007-04-10 06:01:03 +00:00
|
|
|
}
|
|
|
|
|
2011-07-11 09:18:15 +00:00
|
|
|
METHOD(peer_cfg_t, destroy, void,
|
|
|
|
private_peer_cfg_t *this)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
|
|
|
if (ref_put(&this->refcount))
|
|
|
|
{
|
|
|
|
this->ike_cfg->destroy(this->ike_cfg);
|
2009-04-14 10:34:24 +00:00
|
|
|
this->child_cfgs->destroy_offset(this->child_cfgs,
|
|
|
|
offsetof(child_cfg_t, destroy));
|
|
|
|
this->local_auth->destroy_offset(this->local_auth,
|
|
|
|
offsetof(auth_cfg_t, destroy));
|
|
|
|
this->remote_auth->destroy_offset(this->remote_auth,
|
|
|
|
offsetof(auth_cfg_t, destroy));
|
2012-08-21 11:50:32 +00:00
|
|
|
this->vips->destroy_offset(this->vips, offsetof(host_t, destroy));
|
2012-08-24 12:31:24 +00:00
|
|
|
this->pools->destroy_function(this->pools, free);
|
2008-03-26 18:40:19 +00:00
|
|
|
#ifdef ME
|
|
|
|
DESTROY_IF(this->mediated_by);
|
2007-10-03 15:10:41 +00:00
|
|
|
DESTROY_IF(this->peer_id);
|
2008-03-26 18:40:19 +00:00
|
|
|
#endif /* ME */
|
2008-11-05 11:29:56 +00:00
|
|
|
this->mutex->destroy(this->mutex);
|
2007-04-10 06:01:03 +00:00
|
|
|
free(this->name);
|
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Described in header-file
|
|
|
|
*/
|
2012-10-16 12:31:02 +00:00
|
|
|
peer_cfg_t *peer_cfg_create(char *name,
|
2011-11-16 16:28:06 +00:00
|
|
|
ike_cfg_t *ike_cfg, cert_policy_t cert_policy,
|
|
|
|
unique_policy_t unique, u_int32_t keyingtries,
|
|
|
|
u_int32_t rekey_time, u_int32_t reauth_time,
|
|
|
|
u_int32_t jitter_time, u_int32_t over_time,
|
2012-01-09 16:32:41 +00:00
|
|
|
bool mobike, bool aggressive, u_int32_t dpd,
|
2012-08-24 12:31:24 +00:00
|
|
|
u_int32_t dpd_timeout,
|
2012-08-21 11:50:32 +00:00
|
|
|
bool mediation, peer_cfg_t *mediated_by,
|
2012-05-17 17:49:22 +00:00
|
|
|
identification_t *peer_id)
|
2007-04-10 06:01:03 +00:00
|
|
|
{
|
2011-07-11 09:18:15 +00:00
|
|
|
private_peer_cfg_t *this;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2007-11-20 12:06:40 +00:00
|
|
|
if (rekey_time && jitter_time > rekey_time)
|
|
|
|
{
|
|
|
|
jitter_time = rekey_time;
|
|
|
|
}
|
|
|
|
if (reauth_time && jitter_time > reauth_time)
|
|
|
|
{
|
|
|
|
jitter_time = reauth_time;
|
|
|
|
}
|
2011-07-11 09:18:15 +00:00
|
|
|
|
|
|
|
INIT(this,
|
|
|
|
.public = {
|
|
|
|
.get_name = _get_name,
|
|
|
|
.get_ike_version = _get_ike_version,
|
|
|
|
.get_ike_cfg = _get_ike_cfg,
|
|
|
|
.add_child_cfg = _add_child_cfg,
|
|
|
|
.remove_child_cfg = (void*)_remove_child_cfg,
|
|
|
|
.create_child_cfg_enumerator = _create_child_cfg_enumerator,
|
|
|
|
.select_child_cfg = _select_child_cfg,
|
|
|
|
.get_cert_policy = _get_cert_policy,
|
|
|
|
.get_unique_policy = _get_unique_policy,
|
|
|
|
.get_keyingtries = _get_keyingtries,
|
|
|
|
.get_rekey_time = _get_rekey_time,
|
|
|
|
.get_reauth_time = _get_reauth_time,
|
|
|
|
.get_over_time = _get_over_time,
|
|
|
|
.use_mobike = _use_mobike,
|
2012-01-09 16:32:41 +00:00
|
|
|
.use_aggressive = _use_aggressive,
|
2011-07-11 09:18:15 +00:00
|
|
|
.get_dpd = _get_dpd,
|
2012-05-17 17:49:22 +00:00
|
|
|
.get_dpd_timeout = _get_dpd_timeout,
|
2012-08-21 11:50:32 +00:00
|
|
|
.add_virtual_ip = _add_virtual_ip,
|
|
|
|
.create_virtual_ip_enumerator = _create_virtual_ip_enumerator,
|
2012-08-24 12:31:24 +00:00
|
|
|
.add_pool = _add_pool,
|
|
|
|
.create_pool_enumerator = _create_pool_enumerator,
|
2011-07-11 09:18:15 +00:00
|
|
|
.add_auth_cfg = _add_auth_cfg,
|
|
|
|
.create_auth_cfg_enumerator = _create_auth_cfg_enumerator,
|
|
|
|
.equals = (void*)_equals,
|
|
|
|
.get_ref = _get_ref,
|
|
|
|
.destroy = _destroy,
|
|
|
|
#ifdef ME
|
|
|
|
.is_mediation = _is_mediation,
|
|
|
|
.get_mediated_by = _get_mediated_by,
|
|
|
|
.get_peer_id = _get_peer_id,
|
|
|
|
#endif /* ME */
|
|
|
|
},
|
|
|
|
.name = strdup(name),
|
|
|
|
.ike_cfg = ike_cfg,
|
|
|
|
.child_cfgs = linked_list_create(),
|
|
|
|
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
|
|
|
.cert_policy = cert_policy,
|
|
|
|
.unique = unique,
|
|
|
|
.keyingtries = keyingtries,
|
|
|
|
.rekey_time = rekey_time,
|
|
|
|
.reauth_time = reauth_time,
|
|
|
|
.jitter_time = jitter_time,
|
|
|
|
.over_time = over_time,
|
|
|
|
.use_mobike = mobike,
|
2012-01-09 16:32:41 +00:00
|
|
|
.aggressive = aggressive,
|
2011-07-11 09:18:15 +00:00
|
|
|
.dpd = dpd,
|
2012-05-17 17:49:22 +00:00
|
|
|
.dpd_timeout = dpd_timeout,
|
2012-08-21 11:50:32 +00:00
|
|
|
.vips = linked_list_create(),
|
2012-08-24 12:31:24 +00:00
|
|
|
.pools = linked_list_create(),
|
2011-07-11 09:18:15 +00:00
|
|
|
.local_auth = linked_list_create(),
|
|
|
|
.remote_auth = linked_list_create(),
|
|
|
|
.refcount = 1,
|
|
|
|
);
|
|
|
|
|
2008-03-26 18:40:19 +00:00
|
|
|
#ifdef ME
|
|
|
|
this->mediation = mediation;
|
|
|
|
this->mediated_by = mediated_by;
|
2007-10-03 15:10:41 +00:00
|
|
|
this->peer_id = peer_id;
|
2008-03-26 18:40:19 +00:00
|
|
|
#else /* ME */
|
|
|
|
DESTROY_IF(mediated_by);
|
2008-03-13 14:14:44 +00:00
|
|
|
DESTROY_IF(peer_id);
|
2008-03-26 18:40:19 +00:00
|
|
|
#endif /* ME */
|
2007-04-10 06:01:03 +00:00
|
|
|
|
|
|
|
return &this->public;
|
|
|
|
}
|