diff options
Diffstat (limited to 'src/charon/config/policies/local_policy_store.c')
-rw-r--r-- | src/charon/config/policies/local_policy_store.c | 69 |
1 files changed, 56 insertions, 13 deletions
diff --git a/src/charon/config/policies/local_policy_store.c b/src/charon/config/policies/local_policy_store.c index 2054b9df5..0c3e0ee04 100644 --- a/src/charon/config/policies/local_policy_store.c +++ b/src/charon/config/policies/local_policy_store.c @@ -67,9 +67,42 @@ static void add_policy(private_local_policy_store_t *this, policy_t *policy) } /** - * Implementation of policy_store_t.get_policy_by_ids. + * Check if a policy contains traffic selectors */ -static policy_t *get_policy_by_ids(private_local_policy_store_t *this, identification_t *my_id, identification_t *other_id) +static bool contains_traffic_selectors(policy_t *policy, bool mine, + linked_list_t *ts, host_t *host) +{ + linked_list_t *selected; + bool contains = FALSE; + traffic_selector_t *to; + + if (mine) + { + selected = policy->select_my_traffic_selectors(policy, ts, host); + } + else + { + selected = policy->select_other_traffic_selectors(policy, ts, host); + } + if (selected->get_count(selected)) + { + contains = TRUE; + } + while (selected->remove_last(selected, (void**)&to) == SUCCESS) + { + to->destroy(to); + } + selected->destroy(selected); + return contains; +} + +/** + * Implementation of policy_store_t.get_policy. + */ +static policy_t *get_policy(private_local_policy_store_t *this, + identification_t *my_id, identification_t *other_id, + linked_list_t *my_ts, linked_list_t *other_ts, + host_t *my_host, host_t *other_host) { typedef enum { PRIO_UNDEFINED = 0x00, @@ -111,9 +144,22 @@ static policy_t *get_policy_by_ids(private_local_policy_store_t *this, identific { prio = PRIO_ID_MATCH - wildcards; } + + /* only accept if traffic selectors match */ + if (!contains_traffic_selectors(candidate, TRUE, my_ts, my_host) || + !contains_traffic_selectors(candidate, FALSE, other_ts, other_host)) + { + this->logger->log(this->logger, CONTROL|LEVEL2, + "candidate '%s' inacceptable due traffic selector mismatch", + candidate->get_name(candidate), + candidate_my_id->get_string(candidate_my_id), + candidate_other_id->get_string(candidate_other_id), + prio); + continue; + } this->logger->log(this->logger, CONTROL|LEVEL2, - "candidate policy \"%s\": %s...%s (prio=%d)", + "candidate policy '%s': %s...%s (prio=%d)", candidate->get_name(candidate), candidate_my_id->get_string(candidate_my_id), candidate_other_id->get_string(candidate_other_id), @@ -134,18 +180,13 @@ static policy_t *get_policy_by_ids(private_local_policy_store_t *this, identific identification_t *found_other_id = found->get_other_id(found); this->logger->log(this->logger, CONTROL|LEVEL1, - "found matching policy \"%s\": %s...%s (prio=%d)", + "found matching policy '%s': %s...%s (prio=%d)", found->get_name(found), found_my_id->get_string(found_my_id), found_other_id->get_string(found_other_id), best_prio); - - found = found->clone(found); - if (best_prio != PRIO_ID_MATCH) - { - /* replace %any/wildcards by the peer's address */ - found->update_other_id(found, other_id->clone(other_id)); - } + /* give out a new reference to it */ + found->get_ref(found); } pthread_mutex_unlock(&(this->mutex)); return found; @@ -168,12 +209,14 @@ static policy_t *get_policy_by_name(private_local_policy_store_t *this, char *na iterator->current(iterator, (void **)¤t); if (strcmp(current->get_name(current), name) == 0) { - found = current->clone(current); + found = current; } } iterator->destroy(iterator); pthread_mutex_unlock(&(this->mutex)); + /* give out a new reference */ + found->get_ref(found); return found; } @@ -234,7 +277,7 @@ local_policy_store_t *local_policy_store_create(void) private_local_policy_store_t *this = malloc_thing(private_local_policy_store_t); this->public.policy_store.add_policy = (void(*)(policy_store_t*,policy_t*))add_policy; - this->public.policy_store.get_policy_by_ids = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*))get_policy_by_ids; + this->public.policy_store.get_policy = (policy_t*(*)(policy_store_t*,identification_t*,identification_t*,linked_list_t*,linked_list_t*,host_t*,host_t*))get_policy; this->public.policy_store.get_policy_by_name = (policy_t*(*)(policy_store_t*,char*))get_policy_by_name; this->public.policy_store.delete_policy = (status_t(*)(policy_store_t*,char*))delete_policy; this->public.policy_store.destroy = (void(*)(policy_store_t*))destroy; |