identification: Optionally match RDNs in any order and accept missing RDNs
This commit is contained in:
@@ -296,6 +296,22 @@ charon.processor.priority_threads {}
|
|||||||
Section to configure the number of reserved threads per priority class
|
Section to configure the number of reserved threads per priority class
|
||||||
see JOB PRIORITY MANAGEMENT in **strongswan.conf**(5).
|
see JOB PRIORITY MANAGEMENT in **strongswan.conf**(5).
|
||||||
|
|
||||||
|
charon.rdn_matching = strict
|
||||||
|
How RDNs in subject DNs of certificates are matched against configured
|
||||||
|
identities (_strict_, _reordered_, or _relaxed_).
|
||||||
|
|
||||||
|
How RDNs in subject DNs of certificates are matched against configured
|
||||||
|
identities. Possible values are _strict_ (the default), _reordered_, and
|
||||||
|
_relaxed_. With _strict_ the number, type and order of all RDNs has to
|
||||||
|
match, wildcards (*) for the values of RDNs are allowed (that's the case
|
||||||
|
for all three variants). Using _reordered_ also matches DNs if the RDNs
|
||||||
|
appear in a different order, the number and type still has to match.
|
||||||
|
Finally, _relaxed_ also allows matches of DNs that contain more RDNs than
|
||||||
|
the configured identity (missing RDNs are treated like a wildcard match).
|
||||||
|
|
||||||
|
Note that _reordered_ and _relaxed_ impose a considerable overhead on memory
|
||||||
|
usage and runtime, in particular, for mismatches, compared to _static_.
|
||||||
|
|
||||||
charon.receive_delay = 0
|
charon.receive_delay = 0
|
||||||
Delay in ms for receiving packets, to simulate larger RTT.
|
Delay in ms for receiving packets, to simulate larger RTT.
|
||||||
|
|
||||||
|
|||||||
@@ -626,23 +626,111 @@ static bool id_matches(identification_t *a, char *b_str, id_match_t expected)
|
|||||||
return match == expected;
|
return match == expected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char* rdn_matching[] = { NULL, "reordered", "relaxed" };
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
char *id;
|
||||||
|
id_match_t match[3];
|
||||||
|
} matches_data[] = {
|
||||||
|
/* C=CH, [email protected], CN=moon */
|
||||||
|
{ "C=CH, [email protected], CN=moon", {
|
||||||
|
ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
|
||||||
|
{ "C=CH, [email protected], CN=moon", {
|
||||||
|
ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
|
||||||
|
{ "C=CH, [email protected], CN=moon", {
|
||||||
|
ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
|
||||||
|
{ "CN=moon, C=CH, [email protected]", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
|
||||||
|
{ "C=CH, E=*@strongswan.org, CN=moon", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_NONE }},
|
||||||
|
{ "C=CH, E=*, CN=moon", {
|
||||||
|
ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
|
||||||
|
{ "C=CH, E=*, CN=*", {
|
||||||
|
ID_MATCH_ONE_WILDCARD - 1, ID_MATCH_ONE_WILDCARD - 1, ID_MATCH_ONE_WILDCARD - 1 }},
|
||||||
|
{ "C=*, E=*, CN=*", {
|
||||||
|
ID_MATCH_ONE_WILDCARD - 2, ID_MATCH_ONE_WILDCARD - 2, ID_MATCH_ONE_WILDCARD - 2 }},
|
||||||
|
{ "C=*, E=*, CN=*, O=BADInc", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_NONE }},
|
||||||
|
{ "C=CH, CN=*", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD - 1 }},
|
||||||
|
{ "C=*, E=*", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD - 2 }},
|
||||||
|
{ "C=*, [email protected], CN=*", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_NONE }},
|
||||||
|
{ "C=CH, O=strongSwan, E=*, CN=*", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_NONE }},
|
||||||
|
{ "", {
|
||||||
|
ID_MATCH_ANY, ID_MATCH_ANY, ID_MATCH_ANY }},
|
||||||
|
{ "%any", {
|
||||||
|
ID_MATCH_ANY, ID_MATCH_ANY, ID_MATCH_ANY }},
|
||||||
|
};
|
||||||
|
|
||||||
START_TEST(test_matches)
|
START_TEST(test_matches)
|
||||||
{
|
{
|
||||||
identification_t *a;
|
identification_t *a;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (rdn_matching[_i])
|
||||||
|
{
|
||||||
|
lib->settings->set_str(lib->settings, "%s.rdn_matching",
|
||||||
|
rdn_matching[_i], lib->ns);
|
||||||
|
}
|
||||||
|
|
||||||
a = identification_create_from_string("C=CH, [email protected], CN=moon");
|
a = identification_create_from_string("C=CH, [email protected], CN=moon");
|
||||||
|
|
||||||
ck_assert(id_matches(a, "C=CH, [email protected], CN=moon", ID_MATCH_PERFECT));
|
for (i = 0; i < countof(matches_data); i++)
|
||||||
ck_assert(id_matches(a, "C=CH, [email protected], CN=moon", ID_MATCH_PERFECT));
|
{
|
||||||
ck_assert(id_matches(a, "C=CH, [email protected], CN=moon", ID_MATCH_PERFECT));
|
ck_assert(id_matches(a, matches_data[i].id, matches_data[i].match[_i]));
|
||||||
ck_assert(id_matches(a, "C=CH, E=*@strongswan.org, CN=moon", ID_MATCH_NONE));
|
}
|
||||||
ck_assert(id_matches(a, "C=CH, E=*, CN=moon", ID_MATCH_ONE_WILDCARD));
|
|
||||||
ck_assert(id_matches(a, "C=CH, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 1));
|
a->destroy(a);
|
||||||
ck_assert(id_matches(a, "C=*, E=*, CN=*", ID_MATCH_ONE_WILDCARD - 2));
|
}
|
||||||
ck_assert(id_matches(a, "C=*, E=*, CN=*, O=BADInc", ID_MATCH_NONE));
|
END_TEST
|
||||||
ck_assert(id_matches(a, "C=*, E=*", ID_MATCH_NONE));
|
|
||||||
ck_assert(id_matches(a, "C=*, [email protected], CN=*", ID_MATCH_NONE));
|
static struct {
|
||||||
ck_assert(id_matches(a, "%any", ID_MATCH_ANY));
|
char *id;
|
||||||
|
id_match_t match[3];
|
||||||
|
} matches_two_ou_data[] = {
|
||||||
|
/* C=CH, OU=Research, OU=Floor A, CN=moon */
|
||||||
|
{ "C=CH, OU=Research, OU=Floor A, CN=moon", {
|
||||||
|
ID_MATCH_PERFECT, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
|
||||||
|
{ "C=CH, OU=Floor A, CN=moon", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD }},
|
||||||
|
{ "C=CH, CN=moon", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD - 1 }},
|
||||||
|
{ "C=CH, OU=*, CN=moon", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD - 1 }},
|
||||||
|
{ "C=CH, OU=*, OU=*, CN=moon", {
|
||||||
|
ID_MATCH_ONE_WILDCARD - 1, ID_MATCH_ONE_WILDCARD - 1, ID_MATCH_ONE_WILDCARD - 1 }},
|
||||||
|
{ "C=CH, OU=Research, OU=*, CN=moon", {
|
||||||
|
ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
|
||||||
|
{ "C=CH, OU=*, OU=Floor A, CN=moon", {
|
||||||
|
ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
|
||||||
|
{ "C=CH, OU=*, OU=Research, CN=moon", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
|
||||||
|
{ "C=CH, OU=Floor A, OU=*, CN=moon", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_ONE_WILDCARD, ID_MATCH_ONE_WILDCARD }},
|
||||||
|
{ "C=CH, OU=Floor A, OU=Research, CN=moon", {
|
||||||
|
ID_MATCH_NONE, ID_MATCH_PERFECT, ID_MATCH_PERFECT }},
|
||||||
|
};
|
||||||
|
|
||||||
|
START_TEST(test_matches_two_ou)
|
||||||
|
{
|
||||||
|
identification_t *a;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (rdn_matching[_i])
|
||||||
|
{
|
||||||
|
lib->settings->set_str(lib->settings, "%s.rdn_matching",
|
||||||
|
rdn_matching[_i], lib->ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
a = identification_create_from_string("C=CH, OU=Research, OU=Floor A, CN=moon");
|
||||||
|
|
||||||
|
for (i = 0; i < countof(matches_two_ou_data); i++)
|
||||||
|
{
|
||||||
|
ck_assert(id_matches(a, matches_two_ou_data[i].id, matches_two_ou_data[i].match[_i]));
|
||||||
|
}
|
||||||
|
|
||||||
a->destroy(a);
|
a->destroy(a);
|
||||||
}
|
}
|
||||||
@@ -1094,7 +1182,8 @@ Suite *identification_suite_create()
|
|||||||
suite_add_tcase(s, tc);
|
suite_add_tcase(s, tc);
|
||||||
|
|
||||||
tc = tcase_create("matches");
|
tc = tcase_create("matches");
|
||||||
tcase_add_test(tc, test_matches);
|
tcase_add_loop_test(tc, test_matches, 0, countof(rdn_matching));
|
||||||
|
tcase_add_loop_test(tc, test_matches_two_ou, 0, countof(rdn_matching));
|
||||||
tcase_add_test(tc, test_matches_any);
|
tcase_add_test(tc, test_matches_any);
|
||||||
tcase_add_test(tc, test_matches_binary);
|
tcase_add_test(tc, test_matches_binary);
|
||||||
tcase_add_test(tc, test_matches_range);
|
tcase_add_test(tc, test_matches_range);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016 Andreas Steffen
|
* Copyright (C) 2016 Andreas Steffen
|
||||||
* Copyright (C) 2009-2015 Tobias Brunner
|
* Copyright (C) 2009-2019 Tobias Brunner
|
||||||
* Copyright (C) 2005-2009 Martin Willi
|
* Copyright (C) 2005-2009 Martin Willi
|
||||||
* Copyright (C) 2005 Jan Hutter
|
* Copyright (C) 2005 Jan Hutter
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
#include <asn1/oid.h>
|
#include <asn1/oid.h>
|
||||||
#include <asn1/asn1.h>
|
#include <asn1/asn1.h>
|
||||||
#include <crypto/hashers/hasher.h>
|
#include <crypto/hashers/hasher.h>
|
||||||
|
#include <collections/array.h>
|
||||||
|
|
||||||
ENUM_BEGIN(id_match_names, ID_MATCH_NONE, ID_MATCH_MAX_WILDCARDS,
|
ENUM_BEGIN(id_match_names, ID_MATCH_NONE, ID_MATCH_MAX_WILDCARDS,
|
||||||
"MATCH_NONE",
|
"MATCH_NONE",
|
||||||
@@ -567,6 +568,14 @@ METHOD(identification_t, get_type, id_type_t,
|
|||||||
return this->type;
|
return this->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if this is a wildcard value
|
||||||
|
*/
|
||||||
|
static inline bool is_wildcard(chunk_t data)
|
||||||
|
{
|
||||||
|
return data.len == 1 && data.ptr[0] == '*';
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(identification_t, contains_wildcards_dn, bool,
|
METHOD(identification_t, contains_wildcards_dn, bool,
|
||||||
private_identification_t *this)
|
private_identification_t *this)
|
||||||
{
|
{
|
||||||
@@ -578,7 +587,7 @@ METHOD(identification_t, contains_wildcards_dn, bool,
|
|||||||
enumerator = create_part_enumerator(this);
|
enumerator = create_part_enumerator(this);
|
||||||
while (enumerator->enumerate(enumerator, &type, &data))
|
while (enumerator->enumerate(enumerator, &type, &data))
|
||||||
{
|
{
|
||||||
if (data.len == 1 && data.ptr[0] == '*')
|
if (is_wildcard(data))
|
||||||
{
|
{
|
||||||
contains = TRUE;
|
contains = TRUE;
|
||||||
break;
|
break;
|
||||||
@@ -622,7 +631,172 @@ METHOD(identification_t, equals_binary, bool,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare to DNs, for equality if wc == NULL, for match otherwise
|
* Compare two RDNs for equality, comparing some string types case insensitive
|
||||||
|
*/
|
||||||
|
static bool rdn_equals(chunk_t oid, u_char a_type, chunk_t a, u_char b_type,
|
||||||
|
chunk_t b)
|
||||||
|
{
|
||||||
|
if (a_type == b_type &&
|
||||||
|
(a_type == ASN1_PRINTABLESTRING ||
|
||||||
|
(a_type == ASN1_IA5STRING &&
|
||||||
|
asn1_known_oid(oid) == OID_EMAIL_ADDRESS)))
|
||||||
|
{ /* ignore case for printableStrings and email RDNs */
|
||||||
|
return strncaseeq(a.ptr, b.ptr, a.len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* respect case and length for everything else */
|
||||||
|
return memeq(a.ptr, b.ptr, a.len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RDNs when matching DNs
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
chunk_t oid;
|
||||||
|
u_char type;
|
||||||
|
chunk_t data;
|
||||||
|
bool matched;
|
||||||
|
} rdn_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match DNs (o_dn may contain wildcards and RDNs in a different order, if
|
||||||
|
* allow_unmatched is TRUE, t_dn may contain unmatched RDNs)
|
||||||
|
*/
|
||||||
|
static bool match_dn(chunk_t t_dn, chunk_t o_dn, int *wc, bool allow_unmatched)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
array_t *rdns;
|
||||||
|
rdn_t *rdn, *found;
|
||||||
|
chunk_t oid, data;
|
||||||
|
u_char type;
|
||||||
|
bool finished = FALSE;
|
||||||
|
int i, regular = 0;
|
||||||
|
|
||||||
|
*wc = 0;
|
||||||
|
|
||||||
|
/* try a binary compare */
|
||||||
|
if (chunk_equals(t_dn, o_dn))
|
||||||
|
{
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rdns = array_create(0, 8);
|
||||||
|
|
||||||
|
enumerator = create_rdn_enumerator(o_dn);
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (!enumerator->enumerate(enumerator, &oid, &type, &data))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
INIT(rdn,
|
||||||
|
.oid = oid,
|
||||||
|
.type = type,
|
||||||
|
.data = data,
|
||||||
|
);
|
||||||
|
if (is_wildcard(data))
|
||||||
|
{
|
||||||
|
/* insert wildcards at the end, to perform exact matches first */
|
||||||
|
array_insert(rdns, ARRAY_TAIL, rdn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
array_insert(rdns, regular++, rdn);
|
||||||
|
}
|
||||||
|
/* the enumerator returns FALSE on parse error, we are finished
|
||||||
|
* if we have reached the end of the DN only */
|
||||||
|
if ((data.ptr + data.len == o_dn.ptr + o_dn.len))
|
||||||
|
{
|
||||||
|
finished = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
if (!finished)
|
||||||
|
{ /* invalid DN */
|
||||||
|
array_destroy_function(rdns, (void*)free, NULL);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
finished = FALSE;
|
||||||
|
|
||||||
|
enumerator = create_rdn_enumerator(t_dn);
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (!enumerator->enumerate(enumerator, &oid, &type, &data))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (i = 0, found = NULL; i < array_count(rdns); i++)
|
||||||
|
{
|
||||||
|
array_get(rdns, i, &rdn);
|
||||||
|
if (!rdn->matched && chunk_equals(rdn->oid, oid))
|
||||||
|
{
|
||||||
|
if (is_wildcard(rdn->data))
|
||||||
|
{
|
||||||
|
(*wc)++;
|
||||||
|
}
|
||||||
|
else if (data.len != rdn->data.len ||
|
||||||
|
!rdn_equals(oid, type, data, rdn->type, rdn->data))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
rdn->matched = TRUE;
|
||||||
|
found = rdn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
{
|
||||||
|
/* treat unmatched RDNs like wildcards if allowed */
|
||||||
|
if (!allow_unmatched)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(*wc)++;
|
||||||
|
}
|
||||||
|
/* the enumerator returns FALSE on parse error, we are finished
|
||||||
|
* if we have reached the end of the DN only */
|
||||||
|
if ((data.ptr + data.len == t_dn.ptr + t_dn.len))
|
||||||
|
{
|
||||||
|
finished = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
if (finished)
|
||||||
|
{
|
||||||
|
for (i = 0; i < array_count(rdns); i++)
|
||||||
|
{
|
||||||
|
array_get(rdns, i, &rdn);
|
||||||
|
if (!rdn->matched)
|
||||||
|
{
|
||||||
|
finished = FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
array_destroy_function(rdns, (void*)free, NULL);
|
||||||
|
return finished;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reordered RDNs are fine, but match all
|
||||||
|
*/
|
||||||
|
static bool match_dn_reordered(chunk_t t_dn, chunk_t o_dn, int *wc)
|
||||||
|
{
|
||||||
|
return match_dn(t_dn, o_dn, wc, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* t_dn may contain more RDNs than o_dn
|
||||||
|
*/
|
||||||
|
static bool match_dn_relaxed(chunk_t t_dn, chunk_t o_dn, int *wc)
|
||||||
|
{
|
||||||
|
return match_dn(t_dn, o_dn, wc, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two DNs, for equality if wc == NULL, with wildcard matching otherwise
|
||||||
*/
|
*/
|
||||||
static bool compare_dn(chunk_t t_dn, chunk_t o_dn, int *wc)
|
static bool compare_dn(chunk_t t_dn, chunk_t o_dn, int *wc)
|
||||||
{
|
{
|
||||||
@@ -635,14 +809,11 @@ static bool compare_dn(chunk_t t_dn, chunk_t o_dn, int *wc)
|
|||||||
{
|
{
|
||||||
*wc = 0;
|
*wc = 0;
|
||||||
}
|
}
|
||||||
else
|
else if (t_dn.len != o_dn.len)
|
||||||
{
|
{
|
||||||
if (t_dn.len != o_dn.len)
|
return FALSE;
|
||||||
{
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* try a binary compare */
|
|
||||||
if (chunk_equals(t_dn, o_dn))
|
if (chunk_equals(t_dn, o_dn))
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@@ -668,7 +839,7 @@ static bool compare_dn(chunk_t t_dn, chunk_t o_dn, int *wc)
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (wc && o_data.len == 1 && o_data.ptr[0] == '*')
|
if (wc && is_wildcard(o_data))
|
||||||
{
|
{
|
||||||
(*wc)++;
|
(*wc)++;
|
||||||
}
|
}
|
||||||
@@ -678,22 +849,9 @@ static bool compare_dn(chunk_t t_dn, chunk_t o_dn, int *wc)
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (t_type == o_type &&
|
if (!rdn_equals(t_oid, t_type, t_data, o_type, o_data))
|
||||||
(t_type == ASN1_PRINTABLESTRING ||
|
{
|
||||||
(t_type == ASN1_IA5STRING &&
|
break;
|
||||||
asn1_known_oid(t_oid) == OID_EMAIL_ADDRESS)))
|
|
||||||
{ /* ignore case for printableStrings and email RDNs */
|
|
||||||
if (strncasecmp(t_data.ptr, o_data.ptr, t_data.len) != 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ /* respect case and length for everything else */
|
|
||||||
if (!memeq(t_data.ptr, o_data.ptr, t_data.len))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* the enumerator returns FALSE on parse error, we are finished
|
/* the enumerator returns FALSE on parse error, we are finished
|
||||||
@@ -817,8 +975,12 @@ METHOD(identification_t, matches_any, id_match_t,
|
|||||||
return ID_MATCH_NONE;
|
return ID_MATCH_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(identification_t, matches_dn, id_match_t,
|
/**
|
||||||
private_identification_t *this, identification_t *other)
|
* Match DNs given the matching function
|
||||||
|
*/
|
||||||
|
static id_match_t matches_dn_internal(private_identification_t *this,
|
||||||
|
identification_t *other,
|
||||||
|
bool (*match)(chunk_t,chunk_t,int*))
|
||||||
{
|
{
|
||||||
int wc;
|
int wc;
|
||||||
|
|
||||||
@@ -829,7 +991,7 @@ METHOD(identification_t, matches_dn, id_match_t,
|
|||||||
|
|
||||||
if (this->type == other->get_type(other))
|
if (this->type == other->get_type(other))
|
||||||
{
|
{
|
||||||
if (compare_dn(this->encoded, other->get_encoding(other), &wc))
|
if (match(this->encoded, other->get_encoding(other), &wc))
|
||||||
{
|
{
|
||||||
wc = min(wc, ID_MATCH_ONE_WILDCARD - ID_MATCH_MAX_WILDCARDS);
|
wc = min(wc, ID_MATCH_ONE_WILDCARD - ID_MATCH_MAX_WILDCARDS);
|
||||||
return ID_MATCH_PERFECT - wc;
|
return ID_MATCH_PERFECT - wc;
|
||||||
@@ -838,6 +1000,24 @@ METHOD(identification_t, matches_dn, id_match_t,
|
|||||||
return ID_MATCH_NONE;
|
return ID_MATCH_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(identification_t, matches_dn, id_match_t,
|
||||||
|
private_identification_t *this, identification_t *other)
|
||||||
|
{
|
||||||
|
return matches_dn_internal(this, other, compare_dn);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(identification_t, matches_dn_reordered, id_match_t,
|
||||||
|
private_identification_t *this, identification_t *other)
|
||||||
|
{
|
||||||
|
return matches_dn_internal(this, other, match_dn_reordered);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(identification_t, matches_dn_relaxed, id_match_t,
|
||||||
|
private_identification_t *this, identification_t *other)
|
||||||
|
{
|
||||||
|
return matches_dn_internal(this, other, match_dn_relaxed);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transform netmask to CIDR bits
|
* Transform netmask to CIDR bits
|
||||||
*/
|
*/
|
||||||
@@ -1150,6 +1330,7 @@ METHOD(identification_t, destroy, void,
|
|||||||
static private_identification_t *identification_create(id_type_t type)
|
static private_identification_t *identification_create(id_type_t type)
|
||||||
{
|
{
|
||||||
private_identification_t *this;
|
private_identification_t *this;
|
||||||
|
char *rdn_matching;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
@@ -1182,6 +1363,17 @@ static private_identification_t *identification_create(id_type_t type)
|
|||||||
this->public.equals = _equals_dn;
|
this->public.equals = _equals_dn;
|
||||||
this->public.matches = _matches_dn;
|
this->public.matches = _matches_dn;
|
||||||
this->public.contains_wildcards = _contains_wildcards_dn;
|
this->public.contains_wildcards = _contains_wildcards_dn;
|
||||||
|
/* check for more relaxed matching config */
|
||||||
|
rdn_matching = lib->settings->get_str(lib->settings,
|
||||||
|
"%s.rdn_matching", NULL, lib->ns);
|
||||||
|
if (streq("reordered", rdn_matching))
|
||||||
|
{
|
||||||
|
this->public.matches = _matches_dn_reordered;
|
||||||
|
}
|
||||||
|
else if (streq("relaxed", rdn_matching))
|
||||||
|
{
|
||||||
|
this->public.matches = _matches_dn_relaxed;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ID_IPV4_ADDR:
|
case ID_IPV4_ADDR:
|
||||||
case ID_IPV6_ADDR:
|
case ID_IPV6_ADDR:
|
||||||
|
|||||||
Reference in New Issue
Block a user