peer-cfg: Consider security labels when selecting child configs
This commit is contained in:
@@ -386,13 +386,28 @@ METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
|
|||||||
/**
|
/**
|
||||||
* Check how good a list of TS matches a given child config
|
* Check how good a list of TS matches a given child config
|
||||||
*/
|
*/
|
||||||
static int get_ts_match(child_cfg_t *cfg, bool local,
|
static u_int get_ts_match(child_cfg_t *cfg, bool local,
|
||||||
linked_list_t *sup_list, linked_list_t *hosts)
|
linked_list_t *sup_list, linked_list_t *hosts,
|
||||||
|
linked_list_t *sup_labels)
|
||||||
{
|
{
|
||||||
linked_list_t *cfg_list;
|
linked_list_t *cfg_list;
|
||||||
enumerator_t *sup_enum, *cfg_enum;
|
enumerator_t *sup_enum, *cfg_enum;
|
||||||
traffic_selector_t *sup_ts, *cfg_ts, *subset;
|
traffic_selector_t *sup_ts, *cfg_ts, *subset;
|
||||||
int match = 0, round;
|
sec_label_t *label;
|
||||||
|
u_int match = 0, round;
|
||||||
|
bool exact = FALSE;
|
||||||
|
|
||||||
|
if (cfg->select_label(cfg, sup_labels, TRUE, &label, &exact))
|
||||||
|
{
|
||||||
|
if (label)
|
||||||
|
{
|
||||||
|
match += exact ? 500 : 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* label config doesn't match, no need to check TS */
|
||||||
|
return match;
|
||||||
|
}
|
||||||
|
|
||||||
/* fetch configured TS list, narrowing dynamic TS */
|
/* fetch configured TS list, narrowing dynamic TS */
|
||||||
cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts, TRUE);
|
cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts, TRUE);
|
||||||
@@ -432,24 +447,29 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
|
|||||||
|
|
||||||
METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
|
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,
|
private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts,
|
||||||
linked_list_t *my_hosts, linked_list_t *other_hosts)
|
linked_list_t *my_hosts, linked_list_t *other_hosts,
|
||||||
|
linked_list_t *my_labels, linked_list_t *other_labels)
|
||||||
{
|
{
|
||||||
child_cfg_t *current, *found = NULL;
|
child_cfg_t *current, *found = NULL;
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
int best = 0;
|
u_int best = 0;
|
||||||
|
|
||||||
DBG2(DBG_CFG, "looking for a child config for %#R === %#R", my_ts, other_ts);
|
DBG2(DBG_CFG, "looking for a child config for %#R === %#R", my_ts, other_ts);
|
||||||
enumerator = create_child_cfg_enumerator(this);
|
enumerator = create_child_cfg_enumerator(this);
|
||||||
while (enumerator->enumerate(enumerator, ¤t))
|
while (enumerator->enumerate(enumerator, ¤t))
|
||||||
{
|
{
|
||||||
int my_prio, other_prio;
|
u_int my_prio, other_prio;
|
||||||
|
|
||||||
my_prio = get_ts_match(current, TRUE, my_ts, my_hosts);
|
my_prio = get_ts_match(current, TRUE, my_ts, my_hosts, my_labels);
|
||||||
other_prio = get_ts_match(current, FALSE, other_ts, other_hosts);
|
if (!my_prio)
|
||||||
|
|
||||||
if (my_prio && other_prio)
|
|
||||||
{
|
{
|
||||||
DBG2(DBG_CFG, " candidate \"%s\" with prio %d+%d",
|
continue;
|
||||||
|
}
|
||||||
|
other_prio = get_ts_match(current, FALSE, other_ts, other_hosts,
|
||||||
|
other_labels);
|
||||||
|
if (other_prio)
|
||||||
|
{
|
||||||
|
DBG2(DBG_CFG, " candidate \"%s\" with prio %u+%u",
|
||||||
current->get_name(current), my_prio, other_prio);
|
current->get_name(current), my_prio, other_prio);
|
||||||
if (my_prio + other_prio > best)
|
if (my_prio + other_prio > best)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -174,17 +174,20 @@ struct peer_cfg_t {
|
|||||||
enumerator_t* (*create_child_cfg_enumerator) (peer_cfg_t *this);
|
enumerator_t* (*create_child_cfg_enumerator) (peer_cfg_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select a CHILD config from traffic selectors.
|
* Select a CHILD config from received traffic selectors.
|
||||||
*
|
*
|
||||||
* @param my_ts TS for local side
|
* @param my_ts TS for local side
|
||||||
* @param other_ts TS for remote side
|
* @param other_ts TS for remote side
|
||||||
* @param my_hosts hosts to narrow down dynamic TS for local side
|
* @param my_hosts hosts to narrow down dynamic TS for local side
|
||||||
* @param other_hosts hosts to narrow down dynamic TS for remote side
|
* @param other_hosts hosts to narrow down dynamic TS for remote side
|
||||||
* @return selected CHILD config, or NULL if no match found
|
* @param my_labels optional local security labels
|
||||||
|
* @param other_labels optional remove security labels
|
||||||
|
* @return selected CHILD config, or NULL if no match found
|
||||||
*/
|
*/
|
||||||
child_cfg_t* (*select_child_cfg) (peer_cfg_t *this,
|
child_cfg_t* (*select_child_cfg)(peer_cfg_t *this,
|
||||||
linked_list_t *my_ts, linked_list_t *other_ts,
|
linked_list_t *my_ts, linked_list_t *other_ts,
|
||||||
linked_list_t *my_hosts, linked_list_t *other_hosts);
|
linked_list_t *my_hosts, linked_list_t *other_hosts,
|
||||||
|
linked_list_t *my_labels, linked_list_t *other_labels);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an authentication config to the peer configuration.
|
* Add an authentication config to the peer configuration.
|
||||||
|
|||||||
@@ -1096,7 +1096,7 @@ METHOD(task_t, process_r, status_t,
|
|||||||
hostsi = get_dynamic_hosts(this->ike_sa, FALSE);
|
hostsi = get_dynamic_hosts(this->ike_sa, FALSE);
|
||||||
hostsr = get_dynamic_hosts(this->ike_sa, TRUE);
|
hostsr = get_dynamic_hosts(this->ike_sa, TRUE);
|
||||||
this->config = peer_cfg->select_child_cfg(peer_cfg, tsr, tsi,
|
this->config = peer_cfg->select_child_cfg(peer_cfg, tsr, tsi,
|
||||||
hostsr, hostsi);
|
hostsr, hostsi, NULL, NULL);
|
||||||
hostsi->destroy(hostsi);
|
hostsi->destroy(hostsi);
|
||||||
hostsr->destroy(hostsr);
|
hostsr->destroy(hostsr);
|
||||||
if (this->config)
|
if (this->config)
|
||||||
|
|||||||
@@ -1414,7 +1414,7 @@ static child_cfg_t* select_child_cfg(private_child_create_t *this)
|
|||||||
listi = get_dynamic_hosts(this->ike_sa, FALSE);
|
listi = get_dynamic_hosts(this->ike_sa, FALSE);
|
||||||
child_cfg = peer_cfg->select_child_cfg(peer_cfg,
|
child_cfg = peer_cfg->select_child_cfg(peer_cfg,
|
||||||
tsr ?: this->tsr, tsi ?: this->tsi,
|
tsr ?: this->tsr, tsi ?: this->tsi,
|
||||||
listr, listi);
|
listr, listi, NULL, NULL);
|
||||||
if ((tsi || tsr) && child_cfg &&
|
if ((tsi || tsr) && child_cfg &&
|
||||||
child_cfg->get_mode(child_cfg) != MODE_TRANSPORT)
|
child_cfg->get_mode(child_cfg) != MODE_TRANSPORT)
|
||||||
{
|
{
|
||||||
@@ -1426,7 +1426,8 @@ static child_cfg_t* select_child_cfg(private_child_create_t *this)
|
|||||||
{
|
{
|
||||||
/* no match for the substituted NAT selectors, try it without */
|
/* no match for the substituted NAT selectors, try it without */
|
||||||
child_cfg = peer_cfg->select_child_cfg(peer_cfg,
|
child_cfg = peer_cfg->select_child_cfg(peer_cfg,
|
||||||
this->tsr, this->tsi, listr, listi);
|
this->tsr, this->tsi,
|
||||||
|
listr, listi, NULL, NULL);
|
||||||
}
|
}
|
||||||
listr->destroy(listr);
|
listr->destroy(listr);
|
||||||
listi->destroy(listi);
|
listi->destroy(listi);
|
||||||
|
|||||||
Reference in New Issue
Block a user