|
|
377657 |
From a2b9a84460429181f2a4fa7e2bb5ab49fd561274 Mon Sep 17 00:00:00 2001
|
|
|
377657 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
377657 |
Date: Mon, 9 Dec 2019 11:31:14 +0100
|
|
|
377657 |
Subject: [PATCH] certmap: sanitize LDAP search filter
|
|
|
377657 |
|
|
|
377657 |
The sss_certmap_get_search_filter() will now sanitize the values read
|
|
|
377657 |
from the certificates before adding them to a search filter. To be able
|
|
|
377657 |
to get the plain values as well sss_certmap_expand_mapping_rule() is
|
|
|
377657 |
added.
|
|
|
377657 |
|
|
|
377657 |
Resolves:
|
|
|
377657 |
https://github.com/SSSD/sssd/issues/5135
|
|
|
377657 |
|
|
|
377657 |
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
|
|
|
377657 |
---
|
|
|
377657 |
Makefile.am | 2 +-
|
|
|
377657 |
src/lib/certmap/sss_certmap.c | 42 ++++++++++--
|
|
|
377657 |
src/lib/certmap/sss_certmap.exports | 5 ++
|
|
|
377657 |
src/lib/certmap/sss_certmap.h | 35 ++++++++--
|
|
|
377657 |
src/responder/pam/pamsrv_p11.c | 5 +-
|
|
|
377657 |
src/tests/cmocka/test_certmap.c | 98 +++++++++++++++++++++++++++-
|
|
|
377657 |
src/util/util.c | 94 ---------------------------
|
|
|
377657 |
src/util/util_ext.c | 99 +++++++++++++++++++++++++++++
|
|
|
377657 |
8 files changed, 272 insertions(+), 108 deletions(-)
|
|
|
377657 |
|
|
|
377657 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
377657 |
index 059e1eaf6..4bacabdda 100644
|
|
|
377657 |
--- a/Makefile.am
|
|
|
377657 |
+++ b/Makefile.am
|
|
|
377657 |
@@ -2163,7 +2163,7 @@ libsss_certmap_la_LIBADD = \
|
|
|
377657 |
$(NULL)
|
|
|
377657 |
libsss_certmap_la_LDFLAGS = \
|
|
|
377657 |
-Wl,--version-script,$(srcdir)/src/lib/certmap/sss_certmap.exports \
|
|
|
377657 |
- -version-info 1:0:1
|
|
|
377657 |
+ -version-info 2:0:2
|
|
|
377657 |
|
|
|
377657 |
if HAVE_NSS
|
|
|
377657 |
libsss_certmap_la_SOURCES += \
|
|
|
377657 |
diff --git a/src/lib/certmap/sss_certmap.c b/src/lib/certmap/sss_certmap.c
|
|
|
377657 |
index 703782b53..f19e57732 100644
|
|
|
377657 |
--- a/src/lib/certmap/sss_certmap.c
|
|
|
377657 |
+++ b/src/lib/certmap/sss_certmap.c
|
|
|
377657 |
@@ -441,10 +441,12 @@ static int expand_san(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
static int expand_template(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
struct parsed_template *parsed_template,
|
|
|
377657 |
struct sss_cert_content *cert_content,
|
|
|
377657 |
+ bool sanitize,
|
|
|
377657 |
char **expanded)
|
|
|
377657 |
{
|
|
|
377657 |
int ret;
|
|
|
377657 |
char *exp = NULL;
|
|
|
377657 |
+ char *exp_sanitized = NULL;
|
|
|
377657 |
|
|
|
377657 |
if (strcmp("issuer_dn", parsed_template->name) == 0) {
|
|
|
377657 |
ret = rdn_list_2_dn_str(ctx, parsed_template->conversion,
|
|
|
377657 |
@@ -455,6 +457,8 @@ static int expand_template(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
} else if (strncmp("subject_", parsed_template->name, 8) == 0) {
|
|
|
377657 |
ret = expand_san(ctx, parsed_template, cert_content->san_list, &exp);
|
|
|
377657 |
} else if (strcmp("cert", parsed_template->name) == 0) {
|
|
|
377657 |
+ /* cert blob is already sanitized */
|
|
|
377657 |
+ sanitize = false;
|
|
|
377657 |
ret = expand_cert(ctx, parsed_template, cert_content, &exp);
|
|
|
377657 |
} else {
|
|
|
377657 |
CM_DEBUG(ctx, "Unsupported template name.");
|
|
|
377657 |
@@ -471,6 +475,16 @@ static int expand_template(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
goto done;
|
|
|
377657 |
}
|
|
|
377657 |
|
|
|
377657 |
+ if (sanitize) {
|
|
|
377657 |
+ ret = sss_filter_sanitize(ctx, exp, &exp_sanitized);
|
|
|
377657 |
+ if (ret != EOK) {
|
|
|
377657 |
+ CM_DEBUG(ctx, "Failed to sanitize expanded template.");
|
|
|
377657 |
+ goto done;
|
|
|
377657 |
+ }
|
|
|
377657 |
+ talloc_free(exp);
|
|
|
377657 |
+ exp = exp_sanitized;
|
|
|
377657 |
+ }
|
|
|
377657 |
+
|
|
|
377657 |
ret = 0;
|
|
|
377657 |
|
|
|
377657 |
done:
|
|
|
377657 |
@@ -485,7 +499,7 @@ done:
|
|
|
377657 |
|
|
|
377657 |
static int get_filter(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
struct ldap_mapping_rule *parsed_mapping_rule,
|
|
|
377657 |
- struct sss_cert_content *cert_content,
|
|
|
377657 |
+ struct sss_cert_content *cert_content, bool sanitize,
|
|
|
377657 |
char **filter)
|
|
|
377657 |
{
|
|
|
377657 |
struct ldap_mapping_rule_comp *comp;
|
|
|
377657 |
@@ -503,7 +517,7 @@ static int get_filter(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
result = talloc_strdup_append(result, comp->val);
|
|
|
377657 |
} else if (comp->type == comp_template) {
|
|
|
377657 |
ret = expand_template(ctx, comp->parsed_template, cert_content,
|
|
|
377657 |
- &expanded);
|
|
|
377657 |
+ sanitize, &expanded);
|
|
|
377657 |
if (ret != 0) {
|
|
|
377657 |
CM_DEBUG(ctx, "Failed to expanded template.");
|
|
|
377657 |
goto done;
|
|
|
377657 |
@@ -791,8 +805,9 @@ done:
|
|
|
377657 |
return ret;
|
|
|
377657 |
}
|
|
|
377657 |
|
|
|
377657 |
-int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
+static int expand_mapping_rule_ex(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
const uint8_t *der_cert, size_t der_size,
|
|
|
377657 |
+ bool sanitize,
|
|
|
377657 |
char **_filter, char ***_domains)
|
|
|
377657 |
{
|
|
|
377657 |
int ret;
|
|
|
377657 |
@@ -819,7 +834,8 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
return EINVAL;
|
|
|
377657 |
}
|
|
|
377657 |
|
|
|
377657 |
- ret = get_filter(ctx, ctx->default_mapping_rule, cert_content, &filter);
|
|
|
377657 |
+ ret = get_filter(ctx, ctx->default_mapping_rule, cert_content, sanitize,
|
|
|
377657 |
+ &filter);
|
|
|
377657 |
goto done;
|
|
|
377657 |
}
|
|
|
377657 |
|
|
|
377657 |
@@ -829,7 +845,7 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
if (ret == 0) {
|
|
|
377657 |
/* match */
|
|
|
377657 |
ret = get_filter(ctx, r->parsed_mapping_rule, cert_content,
|
|
|
377657 |
- &filter);
|
|
|
377657 |
+ sanitize, &filter);
|
|
|
377657 |
if (ret != 0) {
|
|
|
377657 |
CM_DEBUG(ctx, "Failed to get filter");
|
|
|
377657 |
goto done;
|
|
|
377657 |
@@ -873,6 +889,22 @@ done:
|
|
|
377657 |
return ret;
|
|
|
377657 |
}
|
|
|
377657 |
|
|
|
377657 |
+int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
+ const uint8_t *der_cert, size_t der_size,
|
|
|
377657 |
+ char **_filter, char ***_domains)
|
|
|
377657 |
+{
|
|
|
377657 |
+ return expand_mapping_rule_ex(ctx, der_cert, der_size, true,
|
|
|
377657 |
+ _filter, _domains);
|
|
|
377657 |
+}
|
|
|
377657 |
+
|
|
|
377657 |
+int sss_certmap_expand_mapping_rule(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
+ const uint8_t *der_cert, size_t der_size,
|
|
|
377657 |
+ char **_expanded, char ***_domains)
|
|
|
377657 |
+{
|
|
|
377657 |
+ return expand_mapping_rule_ex(ctx, der_cert, der_size, false,
|
|
|
377657 |
+ _expanded, _domains);
|
|
|
377657 |
+}
|
|
|
377657 |
+
|
|
|
377657 |
int sss_certmap_init(TALLOC_CTX *mem_ctx,
|
|
|
377657 |
sss_certmap_ext_debug *debug, void *debug_priv,
|
|
|
377657 |
struct sss_certmap_ctx **ctx)
|
|
|
377657 |
diff --git a/src/lib/certmap/sss_certmap.exports b/src/lib/certmap/sss_certmap.exports
|
|
|
377657 |
index a9e48d6d0..7d7667738 100644
|
|
|
377657 |
--- a/src/lib/certmap/sss_certmap.exports
|
|
|
377657 |
+++ b/src/lib/certmap/sss_certmap.exports
|
|
|
377657 |
@@ -16,3 +16,8 @@ SSS_CERTMAP_0.1 {
|
|
|
377657 |
global:
|
|
|
377657 |
sss_certmap_display_cert_content;
|
|
|
377657 |
} SSS_CERTMAP_0.0;
|
|
|
377657 |
+
|
|
|
377657 |
+SSS_CERTMAP_0.2 {
|
|
|
377657 |
+ global:
|
|
|
377657 |
+ sss_certmap_expand_mapping_rule;
|
|
|
377657 |
+} SSS_CERTMAP_0.1;
|
|
|
377657 |
diff --git a/src/lib/certmap/sss_certmap.h b/src/lib/certmap/sss_certmap.h
|
|
|
377657 |
index 7da2d1c58..058d4f9e4 100644
|
|
|
377657 |
--- a/src/lib/certmap/sss_certmap.h
|
|
|
377657 |
+++ b/src/lib/certmap/sss_certmap.h
|
|
|
377657 |
@@ -103,7 +103,7 @@ int sss_certmap_add_rule(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
*
|
|
|
377657 |
* @param[in] ctx certmap context previously initialized with
|
|
|
377657 |
* @ref sss_certmap_init
|
|
|
377657 |
- * @param[in] der_cert binary blog with the DER encoded certificate
|
|
|
377657 |
+ * @param[in] der_cert binary blob with the DER encoded certificate
|
|
|
377657 |
* @param[in] der_size size of the certificate blob
|
|
|
377657 |
*
|
|
|
377657 |
* @return
|
|
|
377657 |
@@ -119,10 +119,11 @@ int sss_certmap_match_cert(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
*
|
|
|
377657 |
* @param[in] ctx certmap context previously initialized with
|
|
|
377657 |
* @ref sss_certmap_init
|
|
|
377657 |
- * @param[in] der_cert binary blog with the DER encoded certificate
|
|
|
377657 |
+ * @param[in] der_cert binary blob with the DER encoded certificate
|
|
|
377657 |
* @param[in] der_size size of the certificate blob
|
|
|
377657 |
- * @param[out] filter LDAP filter string, caller should free the data by
|
|
|
377657 |
- * calling sss_certmap_free_filter_and_domains
|
|
|
377657 |
+ * @param[out] filter LDAP filter string, expanded templates are sanitized,
|
|
|
377657 |
+ * caller should free the data by calling
|
|
|
377657 |
+ * sss_certmap_free_filter_and_domains
|
|
|
377657 |
* @param[out] domains NULL-terminated array of strings with the domains the
|
|
|
377657 |
* rule applies, caller should free the data by calling
|
|
|
377657 |
* sss_certmap_free_filter_and_domains
|
|
|
377657 |
@@ -136,8 +137,32 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
const uint8_t *der_cert, size_t der_size,
|
|
|
377657 |
char **filter, char ***domains);
|
|
|
377657 |
|
|
|
377657 |
+/**
|
|
|
377657 |
+ * @brief Expand the mapping rule by replacing the templates
|
|
|
377657 |
+ *
|
|
|
377657 |
+ * @param[in] ctx certmap context previously initialized with
|
|
|
377657 |
+ * @ref sss_certmap_init
|
|
|
377657 |
+ * @param[in] der_cert binary blob with the DER encoded certificate
|
|
|
377657 |
+ * @param[in] der_size size of the certificate blob
|
|
|
377657 |
+ * @param[out] expanded expanded mapping rule, templates are filled in
|
|
|
377657 |
+ * verbatim in contrast to sss_certmap_get_search_filter,
|
|
|
377657 |
+ * caller should free the data by
|
|
|
377657 |
+ * calling sss_certmap_free_filter_and_domains
|
|
|
377657 |
+ * @param[out] domains NULL-terminated array of strings with the domains the
|
|
|
377657 |
+ * rule applies, caller should free the data by calling
|
|
|
377657 |
+ * sss_certmap_free_filter_and_domains
|
|
|
377657 |
+ *
|
|
|
377657 |
+ * @return
|
|
|
377657 |
+ * - 0: certificate matches a rule
|
|
|
377657 |
+ * - ENOENT: certificate does not match
|
|
|
377657 |
+ * - EINVAL: internal error
|
|
|
377657 |
+ */
|
|
|
377657 |
+int sss_certmap_expand_mapping_rule(struct sss_certmap_ctx *ctx,
|
|
|
377657 |
+ const uint8_t *der_cert, size_t der_size,
|
|
|
377657 |
+ char **_expanded, char ***_domains);
|
|
|
377657 |
/**
|
|
|
377657 |
* @brief Free data returned by @ref sss_certmap_get_search_filter
|
|
|
377657 |
+ * and @ref sss_certmap_expand_mapping_rule
|
|
|
377657 |
*
|
|
|
377657 |
* @param[in] filter LDAP filter strings returned by
|
|
|
377657 |
* sss_certmap_get_search_filter
|
|
|
377657 |
@@ -150,7 +175,7 @@ void sss_certmap_free_filter_and_domains(char *filter, char **domains);
|
|
|
377657 |
* @brief Get a string with the content of the certificate used by the library
|
|
|
377657 |
*
|
|
|
377657 |
* @param[in] mem_ctx Talloc memory context, may be NULL
|
|
|
377657 |
- * @param[in] der_cert binary blog with the DER encoded certificate
|
|
|
377657 |
+ * @param[in] der_cert binary blob with the DER encoded certificate
|
|
|
377657 |
* @param[in] der_size size of the certificate blob
|
|
|
377657 |
* @param[out] desc Multiline string showing the certificate content
|
|
|
377657 |
* which is used by libsss_certmap
|
|
|
377657 |
diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c
|
|
|
377657 |
index 3f0afaeff..cdf239e07 100644
|
|
|
377657 |
--- a/src/responder/pam/pamsrv_p11.c
|
|
|
377657 |
+++ b/src/responder/pam/pamsrv_p11.c
|
|
|
377657 |
@@ -1049,9 +1049,10 @@ static char *get_cert_prompt(TALLOC_CTX *mem_ctx,
|
|
|
377657 |
goto done;
|
|
|
377657 |
}
|
|
|
377657 |
|
|
|
377657 |
- ret = sss_certmap_get_search_filter(ctx, der, der_size, &filter, &domains);
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, der, der_size,
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
if (ret != 0) {
|
|
|
377657 |
- DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_get_search_filter failed.\n");
|
|
|
377657 |
+ DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_expand_mapping_rule failed.\n");
|
|
|
377657 |
goto done;
|
|
|
377657 |
}
|
|
|
377657 |
|
|
|
377657 |
diff --git a/src/tests/cmocka/test_certmap.c b/src/tests/cmocka/test_certmap.c
|
|
|
377657 |
index c882202a0..232ff7878 100644
|
|
|
377657 |
--- a/src/tests/cmocka/test_certmap.c
|
|
|
377657 |
+++ b/src/tests/cmocka/test_certmap.c
|
|
|
377657 |
@@ -1431,6 +1431,15 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
&filter, &domains);
|
|
|
377657 |
assert_int_equal(ret, 0);
|
|
|
377657 |
assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "rule100=CN=Certificate\\20Authority,O=IPA.DEVEL"
|
|
|
377657 |
+ "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
|
|
|
377657 |
+ assert_null(domains);
|
|
|
377657 |
+
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
|
|
|
377657 |
+ sizeof(test_cert_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
assert_string_equal(filter, "rule100=CN=Certificate Authority,O=IPA.DEVEL"
|
|
|
377657 |
"<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
|
|
|
377657 |
assert_null(domains);
|
|
|
377657 |
@@ -1445,6 +1454,17 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
&filter, &domains);
|
|
|
377657 |
assert_int_equal(ret, 0);
|
|
|
377657 |
assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "rule99=CN=Certificate\\20Authority,O=IPA.DEVEL"
|
|
|
377657 |
+ "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
|
|
|
377657 |
+ assert_non_null(domains);
|
|
|
377657 |
+ assert_string_equal(domains[0], "test.dom");
|
|
|
377657 |
+ assert_null(domains[1]);
|
|
|
377657 |
+
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
|
|
|
377657 |
+ sizeof(test_cert_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
assert_string_equal(filter, "rule99=CN=Certificate Authority,O=IPA.DEVEL"
|
|
|
377657 |
"<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
|
|
|
377657 |
assert_non_null(domains);
|
|
|
377657 |
@@ -1466,6 +1486,16 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
assert_string_equal(domains[0], "test.dom");
|
|
|
377657 |
assert_null(domains[1]);
|
|
|
377657 |
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
|
|
|
377657 |
+ sizeof(test_cert_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "rule98=userCertificate;binary=" TEST_CERT_BIN);
|
|
|
377657 |
+ assert_non_null(domains);
|
|
|
377657 |
+ assert_string_equal(domains[0], "test.dom");
|
|
|
377657 |
+ assert_null(domains[1]);
|
|
|
377657 |
+
|
|
|
377657 |
ret = sss_certmap_add_rule(ctx, 97,
|
|
|
377657 |
"KRB5:<ISSUER>CN=Certificate Authority,O=IPA.DEVEL",
|
|
|
377657 |
"LDAP:rule97={issuer_dn!nss_x500}<S>{subject_dn}",
|
|
|
377657 |
@@ -1476,6 +1506,17 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
&filter, &domains);
|
|
|
377657 |
assert_int_equal(ret, 0);
|
|
|
377657 |
assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "rule97=O=IPA.DEVEL,CN=Certificate\\20Authority"
|
|
|
377657 |
+ "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
|
|
|
377657 |
+ assert_non_null(domains);
|
|
|
377657 |
+ assert_string_equal(domains[0], "test.dom");
|
|
|
377657 |
+ assert_null(domains[1]);
|
|
|
377657 |
+
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
|
|
|
377657 |
+ sizeof(test_cert_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
assert_string_equal(filter, "rule97=O=IPA.DEVEL,CN=Certificate Authority"
|
|
|
377657 |
"<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL");
|
|
|
377657 |
assert_non_null(domains);
|
|
|
377657 |
@@ -1492,6 +1533,17 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
&filter, &domains);
|
|
|
377657 |
assert_int_equal(ret, 0);
|
|
|
377657 |
assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "rule96=O=IPA.DEVEL,CN=Certificate\\20Authority"
|
|
|
377657 |
+ "<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel");
|
|
|
377657 |
+ assert_non_null(domains);
|
|
|
377657 |
+ assert_string_equal(domains[0], "test.dom");
|
|
|
377657 |
+ assert_null(domains[1]);
|
|
|
377657 |
+
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
|
|
|
377657 |
+ sizeof(test_cert_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
assert_string_equal(filter, "rule96=O=IPA.DEVEL,CN=Certificate Authority"
|
|
|
377657 |
"<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel");
|
|
|
377657 |
assert_non_null(domains);
|
|
|
377657 |
@@ -1510,6 +1562,14 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
assert_string_equal(filter, "(userCertificate;binary=" TEST_CERT_BIN ")");
|
|
|
377657 |
assert_null(domains);
|
|
|
377657 |
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
|
|
|
377657 |
+ sizeof(test_cert_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "(userCertificate;binary=" TEST_CERT_BIN ")");
|
|
|
377657 |
+ assert_null(domains);
|
|
|
377657 |
+
|
|
|
377657 |
ret = sss_certmap_add_rule(ctx, 94,
|
|
|
377657 |
"KRB5:<ISSUER>CN=Certificate Authority,O=IPA.DEVEL",
|
|
|
377657 |
"LDAP:rule94={issuer_dn!ad_x500}<S>{subject_dn!ad_x500}",
|
|
|
377657 |
@@ -1520,12 +1580,22 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
&filter, &domains);
|
|
|
377657 |
assert_int_equal(ret, 0);
|
|
|
377657 |
assert_non_null(filter);
|
|
|
377657 |
- assert_string_equal(filter, "rule94=O=IPA.DEVEL,CN=Certificate Authority"
|
|
|
377657 |
+ assert_string_equal(filter, "rule94=O=IPA.DEVEL,CN=Certificate\\20Authority"
|
|
|
377657 |
"<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel");
|
|
|
377657 |
assert_non_null(domains);
|
|
|
377657 |
assert_string_equal(domains[0], "test.dom");
|
|
|
377657 |
assert_null(domains[1]);
|
|
|
377657 |
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der),
|
|
|
377657 |
+ sizeof(test_cert_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "rule94=O=IPA.DEVEL,CN=Certificate Authority"
|
|
|
377657 |
+ "<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel");
|
|
|
377657 |
+ assert_non_null(domains);
|
|
|
377657 |
+ assert_string_equal(domains[0], "test.dom");
|
|
|
377657 |
+ assert_null(domains[1]);
|
|
|
377657 |
|
|
|
377657 |
ret = sss_certmap_add_rule(ctx, 89, NULL,
|
|
|
377657 |
"(rule89={subject_nt_principal})",
|
|
|
377657 |
@@ -1539,6 +1609,14 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
assert_string_equal(filter, "(rule89=tu1@ad.devel)");
|
|
|
377657 |
assert_null(domains);
|
|
|
377657 |
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der),
|
|
|
377657 |
+ sizeof(test_cert2_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "(rule89=tu1@ad.devel)");
|
|
|
377657 |
+ assert_null(domains);
|
|
|
377657 |
+
|
|
|
377657 |
ret = sss_certmap_add_rule(ctx, 88, NULL,
|
|
|
377657 |
"(rule88={subject_nt_principal.short_name})",
|
|
|
377657 |
NULL);
|
|
|
377657 |
@@ -1560,6 +1638,15 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
&filter, &domains);
|
|
|
377657 |
assert_int_equal(ret, 0);
|
|
|
377657 |
assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "rule87=DC=devel,DC=ad,CN=ad-AD-SERVER-CA"
|
|
|
377657 |
+ "<S>DC=devel,DC=ad,CN=Users,CN=t\\20u,E=test.user@email.domain");
|
|
|
377657 |
+ assert_null(domains);
|
|
|
377657 |
+
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der),
|
|
|
377657 |
+ sizeof(test_cert2_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
assert_string_equal(filter, "rule87=DC=devel,DC=ad,CN=ad-AD-SERVER-CA"
|
|
|
377657 |
"<S>DC=devel,DC=ad,CN=Users,CN=t u,E=test.user@email.domain");
|
|
|
377657 |
assert_null(domains);
|
|
|
377657 |
@@ -1573,6 +1660,15 @@ static void test_sss_certmap_get_search_filter(void **state)
|
|
|
377657 |
&filter, &domains);
|
|
|
377657 |
assert_int_equal(ret, 0);
|
|
|
377657 |
assert_non_null(filter);
|
|
|
377657 |
+ assert_string_equal(filter, "rule86=DC=devel,DC=ad,CN=ad-AD-SERVER-CA"
|
|
|
377657 |
+ "<S>DC=devel,DC=ad,CN=Users,CN=t\\20u,E=test.user@email.domain");
|
|
|
377657 |
+ assert_null(domains);
|
|
|
377657 |
+
|
|
|
377657 |
+ ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der),
|
|
|
377657 |
+ sizeof(test_cert2_der),
|
|
|
377657 |
+ &filter, &domains);
|
|
|
377657 |
+ assert_int_equal(ret, 0);
|
|
|
377657 |
+ assert_non_null(filter);
|
|
|
377657 |
assert_string_equal(filter, "rule86=DC=devel,DC=ad,CN=ad-AD-SERVER-CA"
|
|
|
377657 |
"<S>DC=devel,DC=ad,CN=Users,CN=t u,E=test.user@email.domain");
|
|
|
377657 |
assert_null(domains);
|
|
|
377657 |
diff --git a/src/util/util.c b/src/util/util.c
|
|
|
377657 |
index d9bd3cb59..19d447328 100644
|
|
|
377657 |
--- a/src/util/util.c
|
|
|
377657 |
+++ b/src/util/util.c
|
|
|
377657 |
@@ -436,100 +436,6 @@ errno_t sss_hash_create(TALLOC_CTX *mem_ctx, unsigned long count,
|
|
|
377657 |
return sss_hash_create_ex(mem_ctx, count, tbl, 0, 0, 0, 0, NULL, NULL);
|
|
|
377657 |
}
|
|
|
377657 |
|
|
|
377657 |
-errno_t sss_filter_sanitize_ex(TALLOC_CTX *mem_ctx,
|
|
|
377657 |
- const char *input,
|
|
|
377657 |
- char **sanitized,
|
|
|
377657 |
- const char *ignore)
|
|
|
377657 |
-{
|
|
|
377657 |
- char *output;
|
|
|
377657 |
- size_t i = 0;
|
|
|
377657 |
- size_t j = 0;
|
|
|
377657 |
- char *allowed;
|
|
|
377657 |
-
|
|
|
377657 |
- /* Assume the worst-case. We'll resize it later, once */
|
|
|
377657 |
- output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1);
|
|
|
377657 |
- if (!output) {
|
|
|
377657 |
- return ENOMEM;
|
|
|
377657 |
- }
|
|
|
377657 |
-
|
|
|
377657 |
- while (input[i]) {
|
|
|
377657 |
- /* Even though this character might have a special meaning, if it's
|
|
|
377657 |
- * explicitly allowed, just copy it and move on
|
|
|
377657 |
- */
|
|
|
377657 |
- if (ignore == NULL) {
|
|
|
377657 |
- allowed = NULL;
|
|
|
377657 |
- } else {
|
|
|
377657 |
- allowed = strchr(ignore, input[i]);
|
|
|
377657 |
- }
|
|
|
377657 |
- if (allowed) {
|
|
|
377657 |
- output[j++] = input[i++];
|
|
|
377657 |
- continue;
|
|
|
377657 |
- }
|
|
|
377657 |
-
|
|
|
377657 |
- switch(input[i]) {
|
|
|
377657 |
- case '\t':
|
|
|
377657 |
- output[j++] = '\\';
|
|
|
377657 |
- output[j++] = '0';
|
|
|
377657 |
- output[j++] = '9';
|
|
|
377657 |
- break;
|
|
|
377657 |
- case ' ':
|
|
|
377657 |
- output[j++] = '\\';
|
|
|
377657 |
- output[j++] = '2';
|
|
|
377657 |
- output[j++] = '0';
|
|
|
377657 |
- break;
|
|
|
377657 |
- case '*':
|
|
|
377657 |
- output[j++] = '\\';
|
|
|
377657 |
- output[j++] = '2';
|
|
|
377657 |
- output[j++] = 'a';
|
|
|
377657 |
- break;
|
|
|
377657 |
- case '(':
|
|
|
377657 |
- output[j++] = '\\';
|
|
|
377657 |
- output[j++] = '2';
|
|
|
377657 |
- output[j++] = '8';
|
|
|
377657 |
- break;
|
|
|
377657 |
- case ')':
|
|
|
377657 |
- output[j++] = '\\';
|
|
|
377657 |
- output[j++] = '2';
|
|
|
377657 |
- output[j++] = '9';
|
|
|
377657 |
- break;
|
|
|
377657 |
- case '\\':
|
|
|
377657 |
- output[j++] = '\\';
|
|
|
377657 |
- output[j++] = '5';
|
|
|
377657 |
- output[j++] = 'c';
|
|
|
377657 |
- break;
|
|
|
377657 |
- case '\r':
|
|
|
377657 |
- output[j++] = '\\';
|
|
|
377657 |
- output[j++] = '0';
|
|
|
377657 |
- output[j++] = 'd';
|
|
|
377657 |
- break;
|
|
|
377657 |
- case '\n':
|
|
|
377657 |
- output[j++] = '\\';
|
|
|
377657 |
- output[j++] = '0';
|
|
|
377657 |
- output[j++] = 'a';
|
|
|
377657 |
- break;
|
|
|
377657 |
- default:
|
|
|
377657 |
- output[j++] = input[i];
|
|
|
377657 |
- }
|
|
|
377657 |
-
|
|
|
377657 |
- i++;
|
|
|
377657 |
- }
|
|
|
377657 |
- output[j] = '\0';
|
|
|
377657 |
- *sanitized = talloc_realloc(mem_ctx, output, char, j+1);
|
|
|
377657 |
- if (!*sanitized) {
|
|
|
377657 |
- talloc_free(output);
|
|
|
377657 |
- return ENOMEM;
|
|
|
377657 |
- }
|
|
|
377657 |
-
|
|
|
377657 |
- return EOK;
|
|
|
377657 |
-}
|
|
|
377657 |
-
|
|
|
377657 |
-errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
|
|
|
377657 |
- const char *input,
|
|
|
377657 |
- char **sanitized)
|
|
|
377657 |
-{
|
|
|
377657 |
- return sss_filter_sanitize_ex(mem_ctx, input, sanitized, NULL);
|
|
|
377657 |
-}
|
|
|
377657 |
-
|
|
|
377657 |
char *
|
|
|
377657 |
sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr)
|
|
|
377657 |
{
|
|
|
377657 |
diff --git a/src/util/util_ext.c b/src/util/util_ext.c
|
|
|
377657 |
index 04dc02a8a..a89b60f76 100644
|
|
|
377657 |
--- a/src/util/util_ext.c
|
|
|
377657 |
+++ b/src/util/util_ext.c
|
|
|
377657 |
@@ -29,6 +29,11 @@
|
|
|
377657 |
|
|
|
377657 |
#define EOK 0
|
|
|
377657 |
|
|
|
377657 |
+#ifndef HAVE_ERRNO_T
|
|
|
377657 |
+#define HAVE_ERRNO_T
|
|
|
377657 |
+typedef int errno_t;
|
|
|
377657 |
+#endif
|
|
|
377657 |
+
|
|
|
377657 |
int split_on_separator(TALLOC_CTX *mem_ctx, const char *str,
|
|
|
377657 |
const char sep, bool trim, bool skip_empty,
|
|
|
377657 |
char ***_list, int *size)
|
|
|
377657 |
@@ -141,3 +146,97 @@ bool string_in_list(const char *string, char **list, bool case_sensitive)
|
|
|
377657 |
|
|
|
377657 |
return false;
|
|
|
377657 |
}
|
|
|
377657 |
+
|
|
|
377657 |
+errno_t sss_filter_sanitize_ex(TALLOC_CTX *mem_ctx,
|
|
|
377657 |
+ const char *input,
|
|
|
377657 |
+ char **sanitized,
|
|
|
377657 |
+ const char *ignore)
|
|
|
377657 |
+{
|
|
|
377657 |
+ char *output;
|
|
|
377657 |
+ size_t i = 0;
|
|
|
377657 |
+ size_t j = 0;
|
|
|
377657 |
+ char *allowed;
|
|
|
377657 |
+
|
|
|
377657 |
+ /* Assume the worst-case. We'll resize it later, once */
|
|
|
377657 |
+ output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1);
|
|
|
377657 |
+ if (!output) {
|
|
|
377657 |
+ return ENOMEM;
|
|
|
377657 |
+ }
|
|
|
377657 |
+
|
|
|
377657 |
+ while (input[i]) {
|
|
|
377657 |
+ /* Even though this character might have a special meaning, if it's
|
|
|
377657 |
+ * explicitly allowed, just copy it and move on
|
|
|
377657 |
+ */
|
|
|
377657 |
+ if (ignore == NULL) {
|
|
|
377657 |
+ allowed = NULL;
|
|
|
377657 |
+ } else {
|
|
|
377657 |
+ allowed = strchr(ignore, input[i]);
|
|
|
377657 |
+ }
|
|
|
377657 |
+ if (allowed) {
|
|
|
377657 |
+ output[j++] = input[i++];
|
|
|
377657 |
+ continue;
|
|
|
377657 |
+ }
|
|
|
377657 |
+
|
|
|
377657 |
+ switch(input[i]) {
|
|
|
377657 |
+ case '\t':
|
|
|
377657 |
+ output[j++] = '\\';
|
|
|
377657 |
+ output[j++] = '0';
|
|
|
377657 |
+ output[j++] = '9';
|
|
|
377657 |
+ break;
|
|
|
377657 |
+ case ' ':
|
|
|
377657 |
+ output[j++] = '\\';
|
|
|
377657 |
+ output[j++] = '2';
|
|
|
377657 |
+ output[j++] = '0';
|
|
|
377657 |
+ break;
|
|
|
377657 |
+ case '*':
|
|
|
377657 |
+ output[j++] = '\\';
|
|
|
377657 |
+ output[j++] = '2';
|
|
|
377657 |
+ output[j++] = 'a';
|
|
|
377657 |
+ break;
|
|
|
377657 |
+ case '(':
|
|
|
377657 |
+ output[j++] = '\\';
|
|
|
377657 |
+ output[j++] = '2';
|
|
|
377657 |
+ output[j++] = '8';
|
|
|
377657 |
+ break;
|
|
|
377657 |
+ case ')':
|
|
|
377657 |
+ output[j++] = '\\';
|
|
|
377657 |
+ output[j++] = '2';
|
|
|
377657 |
+ output[j++] = '9';
|
|
|
377657 |
+ break;
|
|
|
377657 |
+ case '\\':
|
|
|
377657 |
+ output[j++] = '\\';
|
|
|
377657 |
+ output[j++] = '5';
|
|
|
377657 |
+ output[j++] = 'c';
|
|
|
377657 |
+ break;
|
|
|
377657 |
+ case '\r':
|
|
|
377657 |
+ output[j++] = '\\';
|
|
|
377657 |
+ output[j++] = '0';
|
|
|
377657 |
+ output[j++] = 'd';
|
|
|
377657 |
+ break;
|
|
|
377657 |
+ case '\n':
|
|
|
377657 |
+ output[j++] = '\\';
|
|
|
377657 |
+ output[j++] = '0';
|
|
|
377657 |
+ output[j++] = 'a';
|
|
|
377657 |
+ break;
|
|
|
377657 |
+ default:
|
|
|
377657 |
+ output[j++] = input[i];
|
|
|
377657 |
+ }
|
|
|
377657 |
+
|
|
|
377657 |
+ i++;
|
|
|
377657 |
+ }
|
|
|
377657 |
+ output[j] = '\0';
|
|
|
377657 |
+ *sanitized = talloc_realloc(mem_ctx, output, char, j+1);
|
|
|
377657 |
+ if (!*sanitized) {
|
|
|
377657 |
+ talloc_free(output);
|
|
|
377657 |
+ return ENOMEM;
|
|
|
377657 |
+ }
|
|
|
377657 |
+
|
|
|
377657 |
+ return EOK;
|
|
|
377657 |
+}
|
|
|
377657 |
+
|
|
|
377657 |
+errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx,
|
|
|
377657 |
+ const char *input,
|
|
|
377657 |
+ char **sanitized)
|
|
|
377657 |
+{
|
|
|
377657 |
+ return sss_filter_sanitize_ex(mem_ctx, input, sanitized, NULL);
|
|
|
377657 |
+}
|
|
|
377657 |
--
|
|
|
377657 |
2.21.3
|
|
|
377657 |
|