diff options
Diffstat (limited to 'recipes-security/sssd')
-rw-r--r-- | recipes-security/sssd/files/CVE-2022-4254-1.patch | 515 | ||||
-rw-r--r-- | recipes-security/sssd/files/CVE-2022-4254-2.patch | 655 | ||||
-rw-r--r-- | recipes-security/sssd/sssd_1.16.4.bb | 2 |
3 files changed, 1172 insertions, 0 deletions
diff --git a/recipes-security/sssd/files/CVE-2022-4254-1.patch b/recipes-security/sssd/files/CVE-2022-4254-1.patch new file mode 100644 index 0000000..a52ce1a --- /dev/null +++ b/recipes-security/sssd/files/CVE-2022-4254-1.patch | |||
@@ -0,0 +1,515 @@ | |||
1 | From 1c40208aa1e0f9a17cc4f336c99bcaa6977592d3 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sumit Bose <sbose@redhat.com> | ||
3 | Date: Tue, 27 Nov 2018 16:40:01 +0100 | ||
4 | Subject: [PATCH] certmap: add sss_certmap_display_cert_content() | ||
5 | |||
6 | To make debugging and writing certificate mapping and matching rules | ||
7 | more easy a new function is added to libsss_certmap to display the | ||
8 | certificate content as seen by libsss_certmap. Please note that the | ||
9 | actual output might change in future. | ||
10 | |||
11 | Reviewed-by: Jakub Hrozek <jhrozek@redhat.com> | ||
12 | |||
13 | CVE: CVE-2022-4254 | ||
14 | Upstream-Status: Backport [https://github.com/SSSD/sssd/commit/1c40208aa1e0f9a17cc4f336c99bcaa6977592d3] | ||
15 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
16 | --- | ||
17 | Makefile.am | 2 +- | ||
18 | src/lib/certmap/sss_certmap.c | 142 ++++++++++++++++++++++ | ||
19 | src/lib/certmap/sss_certmap.exports | 5 + | ||
20 | src/lib/certmap/sss_certmap.h | 18 +++ | ||
21 | src/lib/certmap/sss_certmap_int.h | 31 ++++- | ||
22 | src/lib/certmap/sss_certmap_krb5_match.c | 145 +++++++++++------------ | ||
23 | 6 files changed, 261 insertions(+), 82 deletions(-) | ||
24 | |||
25 | diff --git a/Makefile.am b/Makefile.am | ||
26 | index 4475b3d..29cd93c 100644 | ||
27 | --- a/Makefile.am | ||
28 | +++ b/Makefile.am | ||
29 | @@ -1835,7 +1835,7 @@ libsss_certmap_la_LIBADD = \ | ||
30 | $(NULL) | ||
31 | libsss_certmap_la_LDFLAGS = \ | ||
32 | -Wl,--version-script,$(srcdir)/src/lib/certmap/sss_certmap.exports \ | ||
33 | - -version-info 0:0:0 | ||
34 | + -version-info 1:0:1 | ||
35 | |||
36 | if HAVE_NSS | ||
37 | libsss_certmap_la_SOURCES += \ | ||
38 | diff --git a/src/lib/certmap/sss_certmap.c b/src/lib/certmap/sss_certmap.c | ||
39 | index f6f6f98..c60ac24 100644 | ||
40 | --- a/src/lib/certmap/sss_certmap.c | ||
41 | +++ b/src/lib/certmap/sss_certmap.c | ||
42 | @@ -914,3 +914,145 @@ void sss_certmap_free_filter_and_domains(char *filter, char **domains) | ||
43 | talloc_free(filter); | ||
44 | talloc_free(domains); | ||
45 | } | ||
46 | + | ||
47 | +static const char *sss_eku_oid2name(const char *oid) | ||
48 | +{ | ||
49 | + size_t c; | ||
50 | + | ||
51 | + for (c = 0; sss_ext_key_usage[c].name != NULL; c++) { | ||
52 | + if (strcmp(sss_ext_key_usage[c].oid, oid) == 0) { | ||
53 | + return sss_ext_key_usage[c].name; | ||
54 | + } | ||
55 | + } | ||
56 | + | ||
57 | + return NULL; | ||
58 | +} | ||
59 | + | ||
60 | +struct parsed_template san_parsed_template[] = { | ||
61 | + { NULL, NULL, NULL }, /* SAN_OTHER_NAME handled separately */ | ||
62 | + { "subject_rfc822_name", NULL, NULL}, | ||
63 | + { "subject_dns_name", NULL, NULL}, | ||
64 | + { "subject_x400_address", NULL, NULL}, | ||
65 | + { "subject_directory_name", NULL, NULL}, | ||
66 | + { "subject_ediparty_name", NULL, NULL}, | ||
67 | + { "subject_uri", NULL, NULL}, | ||
68 | + { "subject_ip_address", NULL, NULL}, | ||
69 | + { "subject_registered_id", NULL, NULL}, | ||
70 | + { "subject_pkinit_principal", NULL, NULL}, | ||
71 | + { "subject_nt_principal", NULL, NULL}, | ||
72 | + { "subject_principal", NULL, NULL}, | ||
73 | + { NULL, NULL, NULL }, /* SAN_STRING_OTHER_NAME handled separately */ | ||
74 | + { NULL, NULL, NULL } /* SAN_END */ | ||
75 | +}; | ||
76 | + | ||
77 | +int sss_cert_dump_content(TALLOC_CTX *mem_ctx, struct sss_cert_content *c, | ||
78 | + char **content_str) | ||
79 | +{ | ||
80 | + char *out = NULL; | ||
81 | + size_t o; | ||
82 | + struct san_list *s; | ||
83 | + struct sss_certmap_ctx *ctx = NULL; | ||
84 | + char *expanded = NULL; | ||
85 | + int ret; | ||
86 | + char *b64 = NULL; | ||
87 | + const char *eku_str = NULL; | ||
88 | + | ||
89 | + ret = sss_certmap_init(mem_ctx, NULL, NULL, &ctx); | ||
90 | + if (ret != EOK) { | ||
91 | + return ret; | ||
92 | + } | ||
93 | + | ||
94 | + out = talloc_strdup(mem_ctx, "sss cert content (format might change):\n"); | ||
95 | + if (out == NULL) return ENOMEM; | ||
96 | + | ||
97 | + out = talloc_asprintf_append(out, "Issuer: %s\n", c->issuer_str != NULL | ||
98 | + ? c->issuer_str | ||
99 | + : "- not available -"); | ||
100 | + if (out == NULL) return ENOMEM; | ||
101 | + out = talloc_asprintf_append(out, "Subject: %s\n", c->subject_str != NULL | ||
102 | + ? c->subject_str | ||
103 | + : "- not available -"); | ||
104 | + if (out == NULL) return ENOMEM; | ||
105 | + | ||
106 | + out = talloc_asprintf_append(out, "Key Usage: %u(0x%04x)", c->key_usage, | ||
107 | + c->key_usage); | ||
108 | + if (out == NULL) return ENOMEM; | ||
109 | + | ||
110 | + if (c->key_usage != 0) { | ||
111 | + out = talloc_asprintf_append(out, " ("); | ||
112 | + if (out == NULL) return ENOMEM; | ||
113 | + for (o = 0; sss_key_usage[o].name != NULL; o++) { | ||
114 | + if ((c->key_usage & sss_key_usage[o].flag) != 0) { | ||
115 | + out = talloc_asprintf_append(out, "%s%s", | ||
116 | + o == 0 ? "" : ",", | ||
117 | + sss_key_usage[o].name); | ||
118 | + if (out == NULL) return ENOMEM; | ||
119 | + } | ||
120 | + } | ||
121 | + out = talloc_asprintf_append(out, ")"); | ||
122 | + if (out == NULL) return ENOMEM; | ||
123 | + } | ||
124 | + out = talloc_asprintf_append(out, "\n"); | ||
125 | + if (out == NULL) return ENOMEM; | ||
126 | + | ||
127 | + for (o = 0; c->extended_key_usage_oids[o] != NULL; o++) { | ||
128 | + eku_str = sss_eku_oid2name(c->extended_key_usage_oids[o]); | ||
129 | + out = talloc_asprintf_append(out, "Extended Key Usage #%zu: %s%s%s%s\n", | ||
130 | + o, c->extended_key_usage_oids[o], | ||
131 | + eku_str == NULL ? "" : " (", | ||
132 | + eku_str == NULL ? "" : eku_str, | ||
133 | + eku_str == NULL ? "" : ")"); | ||
134 | + if (out == NULL) return ENOMEM; | ||
135 | + } | ||
136 | + | ||
137 | + DLIST_FOR_EACH(s, c->san_list) { | ||
138 | + out = talloc_asprintf_append(out, "SAN type: %s\n", | ||
139 | + s->san_opt < SAN_END | ||
140 | + ? sss_san_names[s->san_opt].name | ||
141 | + : "- unsupported -"); | ||
142 | + if (out == NULL) return ENOMEM; | ||
143 | + | ||
144 | + if (san_parsed_template[s->san_opt].name != NULL) { | ||
145 | + ret = expand_san(ctx, &san_parsed_template[s->san_opt], c->san_list, | ||
146 | + &expanded); | ||
147 | + if (ret != EOK) { | ||
148 | + return ret; | ||
149 | + } | ||
150 | + out = talloc_asprintf_append(out, " %s=%s\n\n", | ||
151 | + san_parsed_template[s->san_opt].name, | ||
152 | + expanded); | ||
153 | + talloc_free(expanded); | ||
154 | + if (out == NULL) return ENOMEM; | ||
155 | + } else if (s->san_opt == SAN_STRING_OTHER_NAME) { | ||
156 | + b64 = sss_base64_encode(mem_ctx, s->bin_val, s->bin_val_len); | ||
157 | + out = talloc_asprintf_append(out, " %s=%s\n\n", s->other_name_oid, | ||
158 | + b64 != NULL ? b64 | ||
159 | + : "- cannot encode -"); | ||
160 | + talloc_free(b64); | ||
161 | + } | ||
162 | + } | ||
163 | + | ||
164 | + *content_str = out; | ||
165 | + | ||
166 | + return EOK; | ||
167 | +} | ||
168 | + | ||
169 | +int sss_certmap_display_cert_content(TALLOC_CTX *mem_cxt, | ||
170 | + const uint8_t *der_cert, size_t der_size, | ||
171 | + char **desc) | ||
172 | +{ | ||
173 | + int ret; | ||
174 | + struct sss_cert_content *content; | ||
175 | + | ||
176 | + ret = sss_cert_get_content(mem_cxt, der_cert, der_size, &content); | ||
177 | + if (ret != EOK) { | ||
178 | + return ret; | ||
179 | + } | ||
180 | + | ||
181 | + ret = sss_cert_dump_content(mem_cxt, content, desc); | ||
182 | + if (ret != EOK) { | ||
183 | + return ret; | ||
184 | + } | ||
185 | + | ||
186 | + return 0; | ||
187 | +} | ||
188 | diff --git a/src/lib/certmap/sss_certmap.exports b/src/lib/certmap/sss_certmap.exports | ||
189 | index 8b5d536..a9e48d6 100644 | ||
190 | --- a/src/lib/certmap/sss_certmap.exports | ||
191 | +++ b/src/lib/certmap/sss_certmap.exports | ||
192 | @@ -11,3 +11,8 @@ SSS_CERTMAP_0.0 { | ||
193 | local: | ||
194 | *; | ||
195 | }; | ||
196 | + | ||
197 | +SSS_CERTMAP_0.1 { | ||
198 | + global: | ||
199 | + sss_certmap_display_cert_content; | ||
200 | +} SSS_CERTMAP_0.0; | ||
201 | diff --git a/src/lib/certmap/sss_certmap.h b/src/lib/certmap/sss_certmap.h | ||
202 | index 646e0f3..7da2d1c 100644 | ||
203 | --- a/src/lib/certmap/sss_certmap.h | ||
204 | +++ b/src/lib/certmap/sss_certmap.h | ||
205 | @@ -146,6 +146,24 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx, | ||
206 | */ | ||
207 | void sss_certmap_free_filter_and_domains(char *filter, char **domains); | ||
208 | |||
209 | +/** | ||
210 | + * @brief Get a string with the content of the certificate used by the library | ||
211 | + * | ||
212 | + * @param[in] mem_ctx Talloc memory context, may be NULL | ||
213 | + * @param[in] der_cert binary blog with the DER encoded certificate | ||
214 | + * @param[in] der_size size of the certificate blob | ||
215 | + * @param[out] desc Multiline string showing the certificate content | ||
216 | + * which is used by libsss_certmap | ||
217 | + * | ||
218 | + * @return | ||
219 | + * - 0: success | ||
220 | + * - EINVAL: certificate cannot be parsed | ||
221 | + * - ENOMEM: memory allocation failure | ||
222 | + */ | ||
223 | +int sss_certmap_display_cert_content(TALLOC_CTX *mem_cxt, | ||
224 | + const uint8_t *der_cert, size_t der_size, | ||
225 | + char **desc); | ||
226 | + | ||
227 | /** | ||
228 | * @} | ||
229 | */ | ||
230 | diff --git a/src/lib/certmap/sss_certmap_int.h b/src/lib/certmap/sss_certmap_int.h | ||
231 | index 479cc16..b1155e2 100644 | ||
232 | --- a/src/lib/certmap/sss_certmap_int.h | ||
233 | +++ b/src/lib/certmap/sss_certmap_int.h | ||
234 | @@ -101,9 +101,9 @@ enum comp_type { | ||
235 | }; | ||
236 | |||
237 | struct parsed_template { | ||
238 | - char *name; | ||
239 | - char *attr_name; | ||
240 | - char *conversion; | ||
241 | + const char *name; | ||
242 | + const char *attr_name; | ||
243 | + const char *conversion; | ||
244 | }; | ||
245 | |||
246 | struct ldap_mapping_rule_comp { | ||
247 | @@ -166,6 +166,28 @@ struct san_list { | ||
248 | #define SSS_KU_ENCIPHER_ONLY 0x0001 | ||
249 | #define SSS_KU_DECIPHER_ONLY 0x8000 | ||
250 | |||
251 | +struct sss_key_usage { | ||
252 | + const char *name; | ||
253 | + uint32_t flag; | ||
254 | +}; | ||
255 | + | ||
256 | +extern const struct sss_key_usage sss_key_usage[]; | ||
257 | + | ||
258 | +struct sss_ext_key_usage { | ||
259 | + const char *name; | ||
260 | + const char *oid; | ||
261 | +}; | ||
262 | + | ||
263 | +extern const struct sss_ext_key_usage sss_ext_key_usage[]; | ||
264 | + | ||
265 | +struct sss_san_name { | ||
266 | + const char *name; | ||
267 | + enum san_opt san_opt; | ||
268 | + bool is_string; | ||
269 | +}; | ||
270 | + | ||
271 | +extern const struct sss_san_name sss_san_names[]; | ||
272 | + | ||
273 | struct sss_cert_content { | ||
274 | char *issuer_str; | ||
275 | const char **issuer_rdn_list; | ||
276 | @@ -183,6 +205,9 @@ int sss_cert_get_content(TALLOC_CTX *mem_ctx, | ||
277 | const uint8_t *der_blob, size_t der_size, | ||
278 | struct sss_cert_content **content); | ||
279 | |||
280 | +int sss_cert_dump_content(TALLOC_CTX *mem_ctx, struct sss_cert_content *c, | ||
281 | + char **content_str); | ||
282 | + | ||
283 | char *check_ad_attr_name(TALLOC_CTX *mem_ctx, const char *rdn); | ||
284 | |||
285 | char *openssl_2_nss_attr_name(const char *attr); | ||
286 | diff --git a/src/lib/certmap/sss_certmap_krb5_match.c b/src/lib/certmap/sss_certmap_krb5_match.c | ||
287 | index 125e925..398d3d2 100644 | ||
288 | --- a/src/lib/certmap/sss_certmap_krb5_match.c | ||
289 | +++ b/src/lib/certmap/sss_certmap_krb5_match.c | ||
290 | @@ -29,6 +29,59 @@ | ||
291 | #include "lib/certmap/sss_certmap.h" | ||
292 | #include "lib/certmap/sss_certmap_int.h" | ||
293 | |||
294 | +const struct sss_key_usage sss_key_usage[] = { | ||
295 | + {"digitalSignature" , SSS_KU_DIGITAL_SIGNATURE}, | ||
296 | + {"nonRepudiation" , SSS_KU_NON_REPUDIATION}, | ||
297 | + {"keyEncipherment" , SSS_KU_KEY_ENCIPHERMENT}, | ||
298 | + {"dataEncipherment" , SSS_KU_DATA_ENCIPHERMENT}, | ||
299 | + {"keyAgreement" , SSS_KU_KEY_AGREEMENT}, | ||
300 | + {"keyCertSign" , SSS_KU_KEY_CERT_SIGN}, | ||
301 | + {"cRLSign" , SSS_KU_CRL_SIGN}, | ||
302 | + {"encipherOnly" , SSS_KU_ENCIPHER_ONLY}, | ||
303 | + {"decipherOnly" , SSS_KU_DECIPHER_ONLY}, | ||
304 | + {NULL ,0} | ||
305 | +}; | ||
306 | + | ||
307 | +const struct sss_ext_key_usage sss_ext_key_usage[] = { | ||
308 | + /* RFC 3280 section 4.2.1.13 */ | ||
309 | + {"serverAuth", "1.3.6.1.5.5.7.3.1"}, | ||
310 | + {"clientAuth", "1.3.6.1.5.5.7.3.2"}, | ||
311 | + {"codeSigning", "1.3.6.1.5.5.7.3.3"}, | ||
312 | + {"emailProtection", "1.3.6.1.5.5.7.3.4"}, | ||
313 | + {"timeStamping", "1.3.6.1.5.5.7.3.8"}, | ||
314 | + {"OCSPSigning", "1.3.6.1.5.5.7.3.9"}, | ||
315 | + | ||
316 | + /* RFC 4556 section 3.2.2 */ | ||
317 | + {"KPClientAuth", "1.3.6.1.5.2.3.4"}, | ||
318 | + {"pkinit", "1.3.6.1.5.2.3.4"}, | ||
319 | + | ||
320 | + /* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography*/ | ||
321 | + {"msScLogin", "1.3.6.1.4.1.311.20.2.2"}, | ||
322 | + | ||
323 | + {NULL ,0} | ||
324 | +}; | ||
325 | + | ||
326 | +const struct sss_san_name sss_san_names[] = { | ||
327 | + /* https://www.ietf.org/rfc/rfc3280.txt section 4.2.1.7 */ | ||
328 | + {"otherName", SAN_OTHER_NAME, false}, | ||
329 | + {"rfc822Name", SAN_RFC822_NAME, true}, | ||
330 | + {"dNSName", SAN_DNS_NAME, true}, | ||
331 | + {"x400Address", SAN_X400_ADDRESS, false}, | ||
332 | + {"directoryName", SAN_DIRECTORY_NAME, true}, | ||
333 | + {"ediPartyName", SAN_EDIPART_NAME, false}, | ||
334 | + {"uniformResourceIdentifier", SAN_URI, true}, | ||
335 | + {"iPAddress", SAN_IP_ADDRESS, true}, | ||
336 | + {"registeredID", SAN_REGISTERED_ID, true}, | ||
337 | + /* https://www.ietf.org/rfc/rfc4556.txt section 3.2.2 */ | ||
338 | + {"pkinitSAN", SAN_PKINIT, true}, | ||
339 | + /* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography */ | ||
340 | + {"ntPrincipalName", SAN_NT, true}, | ||
341 | + /* both previous principal types */ | ||
342 | + {"Principal", SAN_PRINCIPAL, true}, | ||
343 | + {"stringOtherName", SAN_STRING_OTHER_NAME, true}, | ||
344 | + {NULL, SAN_END, false} | ||
345 | +}; | ||
346 | + | ||
347 | static bool is_dotted_decimal(const char *s, size_t len) | ||
348 | { | ||
349 | size_t c = 0; | ||
350 | @@ -145,28 +198,6 @@ static int parse_krb5_get_eku_value(TALLOC_CTX *mem_ctx, | ||
351 | size_t e = 0; | ||
352 | int eku_list_size; | ||
353 | |||
354 | - struct ext_key_usage { | ||
355 | - const char *name; | ||
356 | - const char *oid; | ||
357 | - } ext_key_usage[] = { | ||
358 | - /* RFC 3280 section 4.2.1.13 */ | ||
359 | - {"serverAuth", "1.3.6.1.5.5.7.3.1"}, | ||
360 | - {"clientAuth", "1.3.6.1.5.5.7.3.2"}, | ||
361 | - {"codeSigning", "1.3.6.1.5.5.7.3.3"}, | ||
362 | - {"emailProtection", "1.3.6.1.5.5.7.3.4"}, | ||
363 | - {"timeStamping", "1.3.6.1.5.5.7.3.8"}, | ||
364 | - {"OCSPSigning", "1.3.6.1.5.5.7.3.9"}, | ||
365 | - | ||
366 | - /* RFC 4556 section 3.2.2 */ | ||
367 | - {"KPClientAuth", "1.3.6.1.5.2.3.4"}, | ||
368 | - {"pkinit", "1.3.6.1.5.2.3.4"}, | ||
369 | - | ||
370 | - /* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography*/ | ||
371 | - {"msScLogin", "1.3.6.1.4.1.311.20.2.2"}, | ||
372 | - | ||
373 | - {NULL ,0} | ||
374 | - }; | ||
375 | - | ||
376 | ret = get_comp_value(mem_ctx, ctx, cur, &comp); | ||
377 | if (ret != 0) { | ||
378 | CM_DEBUG(ctx, "Failed to parse regexp."); | ||
379 | @@ -188,11 +219,11 @@ static int parse_krb5_get_eku_value(TALLOC_CTX *mem_ctx, | ||
380 | } | ||
381 | |||
382 | for (c = 0; eku_list[c] != NULL; c++) { | ||
383 | - for (k = 0; ext_key_usage[k].name != NULL; k++) { | ||
384 | -CM_DEBUG(ctx, "[%s][%s].", eku_list[c], ext_key_usage[k].name); | ||
385 | - if (strcasecmp(eku_list[c], ext_key_usage[k].name) == 0) { | ||
386 | + for (k = 0; sss_ext_key_usage[k].name != NULL; k++) { | ||
387 | +CM_DEBUG(ctx, "[%s][%s].", eku_list[c], sss_ext_key_usage[k].name); | ||
388 | + if (strcasecmp(eku_list[c], sss_ext_key_usage[k].name) == 0) { | ||
389 | comp->eku_oid_list[e] = talloc_strdup(comp->eku_oid_list, | ||
390 | - ext_key_usage[k].oid); | ||
391 | + sss_ext_key_usage[k].oid); | ||
392 | if (comp->eku_oid_list[e] == NULL) { | ||
393 | ret = ENOMEM; | ||
394 | goto done; | ||
395 | @@ -202,7 +233,7 @@ CM_DEBUG(ctx, "[%s][%s].", eku_list[c], ext_key_usage[k].name); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | - if (ext_key_usage[k].name == NULL) { | ||
400 | + if (sss_ext_key_usage[k].name == NULL) { | ||
401 | /* check for an dotted-decimal OID */ | ||
402 | if (*(eku_list[c]) != '.') { | ||
403 | o = eku_list[c]; | ||
404 | @@ -252,23 +283,6 @@ static int parse_krb5_get_ku_value(TALLOC_CTX *mem_ctx, | ||
405 | size_t c; | ||
406 | size_t k; | ||
407 | |||
408 | - struct key_usage { | ||
409 | - const char *name; | ||
410 | - uint32_t flag; | ||
411 | - } key_usage[] = { | ||
412 | - {"digitalSignature" , SSS_KU_DIGITAL_SIGNATURE}, | ||
413 | - {"nonRepudiation" , SSS_KU_NON_REPUDIATION}, | ||
414 | - {"keyEncipherment" , SSS_KU_KEY_ENCIPHERMENT}, | ||
415 | - {"dataEncipherment" , SSS_KU_DATA_ENCIPHERMENT}, | ||
416 | - {"keyAgreement" , SSS_KU_KEY_AGREEMENT}, | ||
417 | - {"keyCertSign" , SSS_KU_KEY_CERT_SIGN}, | ||
418 | - {"cRLSign" , SSS_KU_CRL_SIGN}, | ||
419 | - {"encipherOnly" , SSS_KU_ENCIPHER_ONLY}, | ||
420 | - {"decipherOnly" , SSS_KU_DECIPHER_ONLY}, | ||
421 | - {NULL ,0} | ||
422 | - }; | ||
423 | - | ||
424 | - | ||
425 | ret = get_comp_value(mem_ctx, ctx, cur, &comp); | ||
426 | if (ret != 0) { | ||
427 | CM_DEBUG(ctx, "Failed to get value."); | ||
428 | @@ -283,14 +297,14 @@ static int parse_krb5_get_ku_value(TALLOC_CTX *mem_ctx, | ||
429 | } | ||
430 | |||
431 | for (c = 0; ku_list[c] != NULL; c++) { | ||
432 | - for (k = 0; key_usage[k].name != NULL; k++) { | ||
433 | - if (strcasecmp(ku_list[c], key_usage[k].name) == 0) { | ||
434 | - comp->ku |= key_usage[k].flag; | ||
435 | + for (k = 0; sss_key_usage[k].name != NULL; k++) { | ||
436 | + if (strcasecmp(ku_list[c], sss_key_usage[k].name) == 0) { | ||
437 | + comp->ku |= sss_key_usage[k].flag; | ||
438 | break; | ||
439 | } | ||
440 | } | ||
441 | |||
442 | - if (key_usage[k].name == NULL) { | ||
443 | + if (sss_key_usage[k].name == NULL) { | ||
444 | /* FIXME: add check for numerical ku */ | ||
445 | CM_DEBUG(ctx, "No matching key usage found."); | ||
446 | ret = EINVAL; | ||
447 | @@ -342,31 +356,6 @@ done: | ||
448 | return ret; | ||
449 | } | ||
450 | |||
451 | -struct san_name { | ||
452 | - const char *name; | ||
453 | - enum san_opt san_opt; | ||
454 | - bool is_string; | ||
455 | -} san_names[] = { | ||
456 | - /* https://www.ietf.org/rfc/rfc3280.txt section 4.2.1.7 */ | ||
457 | - {"otherName", SAN_OTHER_NAME, false}, | ||
458 | - {"rfc822Name", SAN_RFC822_NAME,true}, | ||
459 | - {"dNSName", SAN_DNS_NAME, true}, | ||
460 | - {"x400Address", SAN_X400_ADDRESS, false}, | ||
461 | - {"directoryName", SAN_DIRECTORY_NAME, true}, | ||
462 | - {"ediPartyName", SAN_EDIPART_NAME, false}, | ||
463 | - {"uniformResourceIdentifier", SAN_URI, true}, | ||
464 | - {"iPAddress", SAN_IP_ADDRESS, true}, | ||
465 | - {"registeredID", SAN_REGISTERED_ID, true}, | ||
466 | - /* https://www.ietf.org/rfc/rfc4556.txt section 3.2.2 */ | ||
467 | - {"pkinitSAN", SAN_PKINIT, true}, | ||
468 | - /* https://support.microsoft.com/en-us/help/287547/object-ids-associated-with-microsoft-cryptography */ | ||
469 | - {"ntPrincipalName", SAN_NT, true}, | ||
470 | - /* both previous principal types */ | ||
471 | - {"Principal", SAN_PRINCIPAL, true}, | ||
472 | - {"stringOtherName", SAN_STRING_OTHER_NAME, true}, | ||
473 | - {NULL, SAN_END, false} | ||
474 | -}; | ||
475 | - | ||
476 | static int parse_krb5_get_san_option(TALLOC_CTX *mem_ctx, | ||
477 | struct sss_certmap_ctx *ctx, | ||
478 | const char **cur, | ||
479 | @@ -388,12 +377,12 @@ static int parse_krb5_get_san_option(TALLOC_CTX *mem_ctx, | ||
480 | if (len == 0) { | ||
481 | c= SAN_PRINCIPAL; | ||
482 | } else { | ||
483 | - for (c = 0; san_names[c].name != NULL; c++) { | ||
484 | - if (strncasecmp(*cur, san_names[c].name, len) == 0) { | ||
485 | + for (c = 0; sss_san_names[c].name != NULL; c++) { | ||
486 | + if (strncasecmp(*cur, sss_san_names[c].name, len) == 0) { | ||
487 | break; | ||
488 | } | ||
489 | } | ||
490 | - if (san_names[c].name == NULL) { | ||
491 | + if (sss_san_names[c].name == NULL) { | ||
492 | if (is_dotted_decimal(*cur, len)) { | ||
493 | c = SAN_STRING_OTHER_NAME; | ||
494 | *str_other_name_oid = talloc_strndup(mem_ctx, *cur, len); | ||
495 | @@ -408,7 +397,7 @@ static int parse_krb5_get_san_option(TALLOC_CTX *mem_ctx, | ||
496 | } | ||
497 | } | ||
498 | |||
499 | - *option = san_names[c].san_opt; | ||
500 | + *option = sss_san_names[c].san_opt; | ||
501 | *cur = end + 1; | ||
502 | |||
503 | return 0; | ||
504 | @@ -432,7 +421,7 @@ static int parse_krb5_get_san_value(TALLOC_CTX *mem_ctx, | ||
505 | } | ||
506 | } | ||
507 | |||
508 | - if (san_names[san_opt].is_string) { | ||
509 | + if (sss_san_names[san_opt].is_string) { | ||
510 | ret = parse_krb5_get_component_value(mem_ctx, ctx, cur, &comp); | ||
511 | if (ret != 0) { | ||
512 | goto done; | ||
513 | -- | ||
514 | 2.25.1 | ||
515 | |||
diff --git a/recipes-security/sssd/files/CVE-2022-4254-2.patch b/recipes-security/sssd/files/CVE-2022-4254-2.patch new file mode 100644 index 0000000..018b95c --- /dev/null +++ b/recipes-security/sssd/files/CVE-2022-4254-2.patch | |||
@@ -0,0 +1,655 @@ | |||
1 | From a2b9a84460429181f2a4fa7e2bb5ab49fd561274 Mon Sep 17 00:00:00 2001 | ||
2 | From: Sumit Bose <sbose@redhat.com> | ||
3 | Date: Mon, 9 Dec 2019 11:31:14 +0100 | ||
4 | Subject: [PATCH] certmap: sanitize LDAP search filter | ||
5 | |||
6 | The sss_certmap_get_search_filter() will now sanitize the values read | ||
7 | from the certificates before adding them to a search filter. To be able | ||
8 | to get the plain values as well sss_certmap_expand_mapping_rule() is | ||
9 | added. | ||
10 | |||
11 | Resolves: | ||
12 | https://github.com/SSSD/sssd/issues/5135 | ||
13 | |||
14 | Reviewed-by: Alexey Tikhonov <atikhono@redhat.com> | ||
15 | |||
16 | CVE: CVE-2022-4254 | ||
17 | Upstream-Status: Backport [https://github.com/SSSD/sssd/commit/a2b9a84460429181f2a4fa7e2bb5ab49fd561274] | ||
18 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
19 | --- | ||
20 | Makefile.am | 2 +- | ||
21 | src/lib/certmap/sss_certmap.c | 42 ++++++++++-- | ||
22 | src/lib/certmap/sss_certmap.exports | 5 ++ | ||
23 | src/lib/certmap/sss_certmap.h | 35 ++++++++-- | ||
24 | src/responder/pam/pamsrv_p11.c | 5 +- | ||
25 | src/tests/cmocka/test_certmap.c | 98 +++++++++++++++++++++++++++- | ||
26 | src/util/util.c | 94 --------------------------- | ||
27 | src/util/util_ext.c | 99 +++++++++++++++++++++++++++++ | ||
28 | 8 files changed, 272 insertions(+), 108 deletions(-) | ||
29 | |||
30 | diff --git a/Makefile.am b/Makefile.am | ||
31 | index 29cd93c..dd6add2 100644 | ||
32 | --- a/Makefile.am | ||
33 | +++ b/Makefile.am | ||
34 | @@ -1835,7 +1835,7 @@ libsss_certmap_la_LIBADD = \ | ||
35 | $(NULL) | ||
36 | libsss_certmap_la_LDFLAGS = \ | ||
37 | -Wl,--version-script,$(srcdir)/src/lib/certmap/sss_certmap.exports \ | ||
38 | - -version-info 1:0:1 | ||
39 | + -version-info 2:0:2 | ||
40 | |||
41 | if HAVE_NSS | ||
42 | libsss_certmap_la_SOURCES += \ | ||
43 | diff --git a/src/lib/certmap/sss_certmap.c b/src/lib/certmap/sss_certmap.c | ||
44 | index c60ac24..d7bc992 100644 | ||
45 | --- a/src/lib/certmap/sss_certmap.c | ||
46 | +++ b/src/lib/certmap/sss_certmap.c | ||
47 | @@ -441,10 +441,12 @@ static int expand_san(struct sss_certmap_ctx *ctx, | ||
48 | static int expand_template(struct sss_certmap_ctx *ctx, | ||
49 | struct parsed_template *parsed_template, | ||
50 | struct sss_cert_content *cert_content, | ||
51 | + bool sanitize, | ||
52 | char **expanded) | ||
53 | { | ||
54 | int ret; | ||
55 | char *exp = NULL; | ||
56 | + char *exp_sanitized = NULL; | ||
57 | |||
58 | if (strcmp("issuer_dn", parsed_template->name) == 0) { | ||
59 | ret = rdn_list_2_dn_str(ctx, parsed_template->conversion, | ||
60 | @@ -455,6 +457,8 @@ static int expand_template(struct sss_certmap_ctx *ctx, | ||
61 | } else if (strncmp("subject_", parsed_template->name, 8) == 0) { | ||
62 | ret = expand_san(ctx, parsed_template, cert_content->san_list, &exp); | ||
63 | } else if (strcmp("cert", parsed_template->name) == 0) { | ||
64 | + /* cert blob is already sanitized */ | ||
65 | + sanitize = false; | ||
66 | ret = expand_cert(ctx, parsed_template, cert_content, &exp); | ||
67 | } else { | ||
68 | CM_DEBUG(ctx, "Unsupported template name."); | ||
69 | @@ -471,6 +475,16 @@ static int expand_template(struct sss_certmap_ctx *ctx, | ||
70 | goto done; | ||
71 | } | ||
72 | |||
73 | + if (sanitize) { | ||
74 | + ret = sss_filter_sanitize(ctx, exp, &exp_sanitized); | ||
75 | + if (ret != EOK) { | ||
76 | + CM_DEBUG(ctx, "Failed to sanitize expanded template."); | ||
77 | + goto done; | ||
78 | + } | ||
79 | + talloc_free(exp); | ||
80 | + exp = exp_sanitized; | ||
81 | + } | ||
82 | + | ||
83 | ret = 0; | ||
84 | |||
85 | done: | ||
86 | @@ -485,7 +499,7 @@ done: | ||
87 | |||
88 | static int get_filter(struct sss_certmap_ctx *ctx, | ||
89 | struct ldap_mapping_rule *parsed_mapping_rule, | ||
90 | - struct sss_cert_content *cert_content, | ||
91 | + struct sss_cert_content *cert_content, bool sanitize, | ||
92 | char **filter) | ||
93 | { | ||
94 | struct ldap_mapping_rule_comp *comp; | ||
95 | @@ -503,7 +517,7 @@ static int get_filter(struct sss_certmap_ctx *ctx, | ||
96 | result = talloc_strdup_append(result, comp->val); | ||
97 | } else if (comp->type == comp_template) { | ||
98 | ret = expand_template(ctx, comp->parsed_template, cert_content, | ||
99 | - &expanded); | ||
100 | + sanitize, &expanded); | ||
101 | if (ret != 0) { | ||
102 | CM_DEBUG(ctx, "Failed to expanded template."); | ||
103 | goto done; | ||
104 | @@ -791,8 +805,9 @@ done: | ||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | -int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx, | ||
109 | +static int expand_mapping_rule_ex(struct sss_certmap_ctx *ctx, | ||
110 | const uint8_t *der_cert, size_t der_size, | ||
111 | + bool sanitize, | ||
112 | char **_filter, char ***_domains) | ||
113 | { | ||
114 | int ret; | ||
115 | @@ -819,7 +834,8 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx, | ||
116 | return EINVAL; | ||
117 | } | ||
118 | |||
119 | - ret = get_filter(ctx, ctx->default_mapping_rule, cert_content, &filter); | ||
120 | + ret = get_filter(ctx, ctx->default_mapping_rule, cert_content, sanitize, | ||
121 | + &filter); | ||
122 | goto done; | ||
123 | } | ||
124 | |||
125 | @@ -829,7 +845,7 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx, | ||
126 | if (ret == 0) { | ||
127 | /* match */ | ||
128 | ret = get_filter(ctx, r->parsed_mapping_rule, cert_content, | ||
129 | - &filter); | ||
130 | + sanitize, &filter); | ||
131 | if (ret != 0) { | ||
132 | CM_DEBUG(ctx, "Failed to get filter"); | ||
133 | goto done; | ||
134 | @@ -873,6 +889,22 @@ done: | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | +int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx, | ||
139 | + const uint8_t *der_cert, size_t der_size, | ||
140 | + char **_filter, char ***_domains) | ||
141 | +{ | ||
142 | + return expand_mapping_rule_ex(ctx, der_cert, der_size, true, | ||
143 | + _filter, _domains); | ||
144 | +} | ||
145 | + | ||
146 | +int sss_certmap_expand_mapping_rule(struct sss_certmap_ctx *ctx, | ||
147 | + const uint8_t *der_cert, size_t der_size, | ||
148 | + char **_expanded, char ***_domains) | ||
149 | +{ | ||
150 | + return expand_mapping_rule_ex(ctx, der_cert, der_size, false, | ||
151 | + _expanded, _domains); | ||
152 | +} | ||
153 | + | ||
154 | int sss_certmap_init(TALLOC_CTX *mem_ctx, | ||
155 | sss_certmap_ext_debug *debug, void *debug_priv, | ||
156 | struct sss_certmap_ctx **ctx) | ||
157 | diff --git a/src/lib/certmap/sss_certmap.exports b/src/lib/certmap/sss_certmap.exports | ||
158 | index a9e48d6..7d76677 100644 | ||
159 | --- a/src/lib/certmap/sss_certmap.exports | ||
160 | +++ b/src/lib/certmap/sss_certmap.exports | ||
161 | @@ -16,3 +16,8 @@ SSS_CERTMAP_0.1 { | ||
162 | global: | ||
163 | sss_certmap_display_cert_content; | ||
164 | } SSS_CERTMAP_0.0; | ||
165 | + | ||
166 | +SSS_CERTMAP_0.2 { | ||
167 | + global: | ||
168 | + sss_certmap_expand_mapping_rule; | ||
169 | +} SSS_CERTMAP_0.1; | ||
170 | diff --git a/src/lib/certmap/sss_certmap.h b/src/lib/certmap/sss_certmap.h | ||
171 | index 7da2d1c..058d4f9 100644 | ||
172 | --- a/src/lib/certmap/sss_certmap.h | ||
173 | +++ b/src/lib/certmap/sss_certmap.h | ||
174 | @@ -103,7 +103,7 @@ int sss_certmap_add_rule(struct sss_certmap_ctx *ctx, | ||
175 | * | ||
176 | * @param[in] ctx certmap context previously initialized with | ||
177 | * @ref sss_certmap_init | ||
178 | - * @param[in] der_cert binary blog with the DER encoded certificate | ||
179 | + * @param[in] der_cert binary blob with the DER encoded certificate | ||
180 | * @param[in] der_size size of the certificate blob | ||
181 | * | ||
182 | * @return | ||
183 | @@ -119,10 +119,11 @@ int sss_certmap_match_cert(struct sss_certmap_ctx *ctx, | ||
184 | * | ||
185 | * @param[in] ctx certmap context previously initialized with | ||
186 | * @ref sss_certmap_init | ||
187 | - * @param[in] der_cert binary blog with the DER encoded certificate | ||
188 | + * @param[in] der_cert binary blob with the DER encoded certificate | ||
189 | * @param[in] der_size size of the certificate blob | ||
190 | - * @param[out] filter LDAP filter string, caller should free the data by | ||
191 | - * calling sss_certmap_free_filter_and_domains | ||
192 | + * @param[out] filter LDAP filter string, expanded templates are sanitized, | ||
193 | + * caller should free the data by calling | ||
194 | + * sss_certmap_free_filter_and_domains | ||
195 | * @param[out] domains NULL-terminated array of strings with the domains the | ||
196 | * rule applies, caller should free the data by calling | ||
197 | * sss_certmap_free_filter_and_domains | ||
198 | @@ -136,8 +137,32 @@ int sss_certmap_get_search_filter(struct sss_certmap_ctx *ctx, | ||
199 | const uint8_t *der_cert, size_t der_size, | ||
200 | char **filter, char ***domains); | ||
201 | |||
202 | +/** | ||
203 | + * @brief Expand the mapping rule by replacing the templates | ||
204 | + * | ||
205 | + * @param[in] ctx certmap context previously initialized with | ||
206 | + * @ref sss_certmap_init | ||
207 | + * @param[in] der_cert binary blob with the DER encoded certificate | ||
208 | + * @param[in] der_size size of the certificate blob | ||
209 | + * @param[out] expanded expanded mapping rule, templates are filled in | ||
210 | + * verbatim in contrast to sss_certmap_get_search_filter, | ||
211 | + * caller should free the data by | ||
212 | + * calling sss_certmap_free_filter_and_domains | ||
213 | + * @param[out] domains NULL-terminated array of strings with the domains the | ||
214 | + * rule applies, caller should free the data by calling | ||
215 | + * sss_certmap_free_filter_and_domains | ||
216 | + * | ||
217 | + * @return | ||
218 | + * - 0: certificate matches a rule | ||
219 | + * - ENOENT: certificate does not match | ||
220 | + * - EINVAL: internal error | ||
221 | + */ | ||
222 | +int sss_certmap_expand_mapping_rule(struct sss_certmap_ctx *ctx, | ||
223 | + const uint8_t *der_cert, size_t der_size, | ||
224 | + char **_expanded, char ***_domains); | ||
225 | /** | ||
226 | * @brief Free data returned by @ref sss_certmap_get_search_filter | ||
227 | + * and @ref sss_certmap_expand_mapping_rule | ||
228 | * | ||
229 | * @param[in] filter LDAP filter strings returned by | ||
230 | * sss_certmap_get_search_filter | ||
231 | @@ -150,7 +175,7 @@ void sss_certmap_free_filter_and_domains(char *filter, char **domains); | ||
232 | * @brief Get a string with the content of the certificate used by the library | ||
233 | * | ||
234 | * @param[in] mem_ctx Talloc memory context, may be NULL | ||
235 | - * @param[in] der_cert binary blog with the DER encoded certificate | ||
236 | + * @param[in] der_cert binary blob with the DER encoded certificate | ||
237 | * @param[in] der_size size of the certificate blob | ||
238 | * @param[out] desc Multiline string showing the certificate content | ||
239 | * which is used by libsss_certmap | ||
240 | diff --git a/src/responder/pam/pamsrv_p11.c b/src/responder/pam/pamsrv_p11.c | ||
241 | index c7e57be..b9f6787 100644 | ||
242 | --- a/src/responder/pam/pamsrv_p11.c | ||
243 | +++ b/src/responder/pam/pamsrv_p11.c | ||
244 | @@ -1023,9 +1023,10 @@ static char *get_cert_prompt(TALLOC_CTX *mem_ctx, | ||
245 | goto done; | ||
246 | } | ||
247 | |||
248 | - ret = sss_certmap_get_search_filter(ctx, der, der_size, &filter, &domains); | ||
249 | + ret = sss_certmap_expand_mapping_rule(ctx, der, der_size, | ||
250 | + &filter, &domains); | ||
251 | if (ret != 0) { | ||
252 | - DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_get_search_filter failed.\n"); | ||
253 | + DEBUG(SSSDBG_OP_FAILURE, "sss_certmap_expand_mapping_rule failed.\n"); | ||
254 | goto done; | ||
255 | } | ||
256 | |||
257 | diff --git a/src/tests/cmocka/test_certmap.c b/src/tests/cmocka/test_certmap.c | ||
258 | index 3091e1a..abf1dba 100644 | ||
259 | --- a/src/tests/cmocka/test_certmap.c | ||
260 | +++ b/src/tests/cmocka/test_certmap.c | ||
261 | @@ -1387,6 +1387,15 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
262 | &filter, &domains); | ||
263 | assert_int_equal(ret, 0); | ||
264 | assert_non_null(filter); | ||
265 | + assert_string_equal(filter, "rule100=<I>CN=Certificate\\20Authority,O=IPA.DEVEL" | ||
266 | + "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL"); | ||
267 | + assert_null(domains); | ||
268 | + | ||
269 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der), | ||
270 | + sizeof(test_cert_der), | ||
271 | + &filter, &domains); | ||
272 | + assert_int_equal(ret, 0); | ||
273 | + assert_non_null(filter); | ||
274 | assert_string_equal(filter, "rule100=<I>CN=Certificate Authority,O=IPA.DEVEL" | ||
275 | "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL"); | ||
276 | assert_null(domains); | ||
277 | @@ -1401,6 +1410,17 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
278 | &filter, &domains); | ||
279 | assert_int_equal(ret, 0); | ||
280 | assert_non_null(filter); | ||
281 | + assert_string_equal(filter, "rule99=<I>CN=Certificate\\20Authority,O=IPA.DEVEL" | ||
282 | + "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL"); | ||
283 | + assert_non_null(domains); | ||
284 | + assert_string_equal(domains[0], "test.dom"); | ||
285 | + assert_null(domains[1]); | ||
286 | + | ||
287 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der), | ||
288 | + sizeof(test_cert_der), | ||
289 | + &filter, &domains); | ||
290 | + assert_int_equal(ret, 0); | ||
291 | + assert_non_null(filter); | ||
292 | assert_string_equal(filter, "rule99=<I>CN=Certificate Authority,O=IPA.DEVEL" | ||
293 | "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL"); | ||
294 | assert_non_null(domains); | ||
295 | @@ -1422,6 +1442,16 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
296 | assert_string_equal(domains[0], "test.dom"); | ||
297 | assert_null(domains[1]); | ||
298 | |||
299 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der), | ||
300 | + sizeof(test_cert_der), | ||
301 | + &filter, &domains); | ||
302 | + assert_int_equal(ret, 0); | ||
303 | + assert_non_null(filter); | ||
304 | + assert_string_equal(filter, "rule98=userCertificate;binary=" TEST_CERT_BIN); | ||
305 | + assert_non_null(domains); | ||
306 | + assert_string_equal(domains[0], "test.dom"); | ||
307 | + assert_null(domains[1]); | ||
308 | + | ||
309 | ret = sss_certmap_add_rule(ctx, 97, | ||
310 | "KRB5:<ISSUER>CN=Certificate Authority,O=IPA.DEVEL", | ||
311 | "LDAP:rule97=<I>{issuer_dn!nss_x500}<S>{subject_dn}", | ||
312 | @@ -1432,6 +1462,17 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
313 | &filter, &domains); | ||
314 | assert_int_equal(ret, 0); | ||
315 | assert_non_null(filter); | ||
316 | + assert_string_equal(filter, "rule97=<I>O=IPA.DEVEL,CN=Certificate\\20Authority" | ||
317 | + "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL"); | ||
318 | + assert_non_null(domains); | ||
319 | + assert_string_equal(domains[0], "test.dom"); | ||
320 | + assert_null(domains[1]); | ||
321 | + | ||
322 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der), | ||
323 | + sizeof(test_cert_der), | ||
324 | + &filter, &domains); | ||
325 | + assert_int_equal(ret, 0); | ||
326 | + assert_non_null(filter); | ||
327 | assert_string_equal(filter, "rule97=<I>O=IPA.DEVEL,CN=Certificate Authority" | ||
328 | "<S>CN=ipa-devel.ipa.devel,O=IPA.DEVEL"); | ||
329 | assert_non_null(domains); | ||
330 | @@ -1448,6 +1489,17 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
331 | &filter, &domains); | ||
332 | assert_int_equal(ret, 0); | ||
333 | assert_non_null(filter); | ||
334 | + assert_string_equal(filter, "rule96=<I>O=IPA.DEVEL,CN=Certificate\\20Authority" | ||
335 | + "<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel"); | ||
336 | + assert_non_null(domains); | ||
337 | + assert_string_equal(domains[0], "test.dom"); | ||
338 | + assert_null(domains[1]); | ||
339 | + | ||
340 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der), | ||
341 | + sizeof(test_cert_der), | ||
342 | + &filter, &domains); | ||
343 | + assert_int_equal(ret, 0); | ||
344 | + assert_non_null(filter); | ||
345 | assert_string_equal(filter, "rule96=<I>O=IPA.DEVEL,CN=Certificate Authority" | ||
346 | "<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel"); | ||
347 | assert_non_null(domains); | ||
348 | @@ -1466,6 +1518,14 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
349 | assert_string_equal(filter, "(userCertificate;binary=" TEST_CERT_BIN ")"); | ||
350 | assert_null(domains); | ||
351 | |||
352 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der), | ||
353 | + sizeof(test_cert_der), | ||
354 | + &filter, &domains); | ||
355 | + assert_int_equal(ret, 0); | ||
356 | + assert_non_null(filter); | ||
357 | + assert_string_equal(filter, "(userCertificate;binary=" TEST_CERT_BIN ")"); | ||
358 | + assert_null(domains); | ||
359 | + | ||
360 | ret = sss_certmap_add_rule(ctx, 94, | ||
361 | "KRB5:<ISSUER>CN=Certificate Authority,O=IPA.DEVEL", | ||
362 | "LDAP:rule94=<I>{issuer_dn!ad_x500}<S>{subject_dn!ad_x500}", | ||
363 | @@ -1476,12 +1536,22 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
364 | &filter, &domains); | ||
365 | assert_int_equal(ret, 0); | ||
366 | assert_non_null(filter); | ||
367 | - assert_string_equal(filter, "rule94=<I>O=IPA.DEVEL,CN=Certificate Authority" | ||
368 | + assert_string_equal(filter, "rule94=<I>O=IPA.DEVEL,CN=Certificate\\20Authority" | ||
369 | "<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel"); | ||
370 | assert_non_null(domains); | ||
371 | assert_string_equal(domains[0], "test.dom"); | ||
372 | assert_null(domains[1]); | ||
373 | |||
374 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert_der), | ||
375 | + sizeof(test_cert_der), | ||
376 | + &filter, &domains); | ||
377 | + assert_int_equal(ret, 0); | ||
378 | + assert_non_null(filter); | ||
379 | + assert_string_equal(filter, "rule94=<I>O=IPA.DEVEL,CN=Certificate Authority" | ||
380 | + "<S>O=IPA.DEVEL,CN=ipa-devel.ipa.devel"); | ||
381 | + assert_non_null(domains); | ||
382 | + assert_string_equal(domains[0], "test.dom"); | ||
383 | + assert_null(domains[1]); | ||
384 | |||
385 | ret = sss_certmap_add_rule(ctx, 89, NULL, | ||
386 | "(rule89={subject_nt_principal})", | ||
387 | @@ -1495,6 +1565,14 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
388 | assert_string_equal(filter, "(rule89=tu1@ad.devel)"); | ||
389 | assert_null(domains); | ||
390 | |||
391 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der), | ||
392 | + sizeof(test_cert2_der), | ||
393 | + &filter, &domains); | ||
394 | + assert_int_equal(ret, 0); | ||
395 | + assert_non_null(filter); | ||
396 | + assert_string_equal(filter, "(rule89=tu1@ad.devel)"); | ||
397 | + assert_null(domains); | ||
398 | + | ||
399 | ret = sss_certmap_add_rule(ctx, 88, NULL, | ||
400 | "(rule88={subject_nt_principal.short_name})", | ||
401 | NULL); | ||
402 | @@ -1516,6 +1594,15 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
403 | &filter, &domains); | ||
404 | assert_int_equal(ret, 0); | ||
405 | assert_non_null(filter); | ||
406 | + assert_string_equal(filter, "rule87=<I>DC=devel,DC=ad,CN=ad-AD-SERVER-CA" | ||
407 | + "<S>DC=devel,DC=ad,CN=Users,CN=t\\20u,E=test.user@email.domain"); | ||
408 | + assert_null(domains); | ||
409 | + | ||
410 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der), | ||
411 | + sizeof(test_cert2_der), | ||
412 | + &filter, &domains); | ||
413 | + assert_int_equal(ret, 0); | ||
414 | + assert_non_null(filter); | ||
415 | assert_string_equal(filter, "rule87=<I>DC=devel,DC=ad,CN=ad-AD-SERVER-CA" | ||
416 | "<S>DC=devel,DC=ad,CN=Users,CN=t u,E=test.user@email.domain"); | ||
417 | assert_null(domains); | ||
418 | @@ -1529,6 +1616,15 @@ static void test_sss_certmap_get_search_filter(void **state) | ||
419 | &filter, &domains); | ||
420 | assert_int_equal(ret, 0); | ||
421 | assert_non_null(filter); | ||
422 | + assert_string_equal(filter, "rule86=<I>DC=devel,DC=ad,CN=ad-AD-SERVER-CA" | ||
423 | + "<S>DC=devel,DC=ad,CN=Users,CN=t\\20u,E=test.user@email.domain"); | ||
424 | + assert_null(domains); | ||
425 | + | ||
426 | + ret = sss_certmap_expand_mapping_rule(ctx, discard_const(test_cert2_der), | ||
427 | + sizeof(test_cert2_der), | ||
428 | + &filter, &domains); | ||
429 | + assert_int_equal(ret, 0); | ||
430 | + assert_non_null(filter); | ||
431 | assert_string_equal(filter, "rule86=<I>DC=devel,DC=ad,CN=ad-AD-SERVER-CA" | ||
432 | "<S>DC=devel,DC=ad,CN=Users,CN=t u,E=test.user@email.domain"); | ||
433 | assert_null(domains); | ||
434 | diff --git a/src/util/util.c b/src/util/util.c | ||
435 | index e3efa7f..0653638 100644 | ||
436 | --- a/src/util/util.c | ||
437 | +++ b/src/util/util.c | ||
438 | @@ -436,100 +436,6 @@ errno_t sss_hash_create(TALLOC_CTX *mem_ctx, unsigned long count, | ||
439 | return sss_hash_create_ex(mem_ctx, count, tbl, 0, 0, 0, 0, NULL, NULL); | ||
440 | } | ||
441 | |||
442 | -errno_t sss_filter_sanitize_ex(TALLOC_CTX *mem_ctx, | ||
443 | - const char *input, | ||
444 | - char **sanitized, | ||
445 | - const char *ignore) | ||
446 | -{ | ||
447 | - char *output; | ||
448 | - size_t i = 0; | ||
449 | - size_t j = 0; | ||
450 | - char *allowed; | ||
451 | - | ||
452 | - /* Assume the worst-case. We'll resize it later, once */ | ||
453 | - output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1); | ||
454 | - if (!output) { | ||
455 | - return ENOMEM; | ||
456 | - } | ||
457 | - | ||
458 | - while (input[i]) { | ||
459 | - /* Even though this character might have a special meaning, if it's | ||
460 | - * expliticly allowed, just copy it and move on | ||
461 | - */ | ||
462 | - if (ignore == NULL) { | ||
463 | - allowed = NULL; | ||
464 | - } else { | ||
465 | - allowed = strchr(ignore, input[i]); | ||
466 | - } | ||
467 | - if (allowed) { | ||
468 | - output[j++] = input[i++]; | ||
469 | - continue; | ||
470 | - } | ||
471 | - | ||
472 | - switch(input[i]) { | ||
473 | - case '\t': | ||
474 | - output[j++] = '\\'; | ||
475 | - output[j++] = '0'; | ||
476 | - output[j++] = '9'; | ||
477 | - break; | ||
478 | - case ' ': | ||
479 | - output[j++] = '\\'; | ||
480 | - output[j++] = '2'; | ||
481 | - output[j++] = '0'; | ||
482 | - break; | ||
483 | - case '*': | ||
484 | - output[j++] = '\\'; | ||
485 | - output[j++] = '2'; | ||
486 | - output[j++] = 'a'; | ||
487 | - break; | ||
488 | - case '(': | ||
489 | - output[j++] = '\\'; | ||
490 | - output[j++] = '2'; | ||
491 | - output[j++] = '8'; | ||
492 | - break; | ||
493 | - case ')': | ||
494 | - output[j++] = '\\'; | ||
495 | - output[j++] = '2'; | ||
496 | - output[j++] = '9'; | ||
497 | - break; | ||
498 | - case '\\': | ||
499 | - output[j++] = '\\'; | ||
500 | - output[j++] = '5'; | ||
501 | - output[j++] = 'c'; | ||
502 | - break; | ||
503 | - case '\r': | ||
504 | - output[j++] = '\\'; | ||
505 | - output[j++] = '0'; | ||
506 | - output[j++] = 'd'; | ||
507 | - break; | ||
508 | - case '\n': | ||
509 | - output[j++] = '\\'; | ||
510 | - output[j++] = '0'; | ||
511 | - output[j++] = 'a'; | ||
512 | - break; | ||
513 | - default: | ||
514 | - output[j++] = input[i]; | ||
515 | - } | ||
516 | - | ||
517 | - i++; | ||
518 | - } | ||
519 | - output[j] = '\0'; | ||
520 | - *sanitized = talloc_realloc(mem_ctx, output, char, j+1); | ||
521 | - if (!*sanitized) { | ||
522 | - talloc_free(output); | ||
523 | - return ENOMEM; | ||
524 | - } | ||
525 | - | ||
526 | - return EOK; | ||
527 | -} | ||
528 | - | ||
529 | -errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx, | ||
530 | - const char *input, | ||
531 | - char **sanitized) | ||
532 | -{ | ||
533 | - return sss_filter_sanitize_ex(mem_ctx, input, sanitized, NULL); | ||
534 | -} | ||
535 | - | ||
536 | char * | ||
537 | sss_escape_ip_address(TALLOC_CTX *mem_ctx, int family, const char *addr) | ||
538 | { | ||
539 | diff --git a/src/util/util_ext.c b/src/util/util_ext.c | ||
540 | index 04dc02a..a89b60f 100644 | ||
541 | --- a/src/util/util_ext.c | ||
542 | +++ b/src/util/util_ext.c | ||
543 | @@ -29,6 +29,11 @@ | ||
544 | |||
545 | #define EOK 0 | ||
546 | |||
547 | +#ifndef HAVE_ERRNO_T | ||
548 | +#define HAVE_ERRNO_T | ||
549 | +typedef int errno_t; | ||
550 | +#endif | ||
551 | + | ||
552 | int split_on_separator(TALLOC_CTX *mem_ctx, const char *str, | ||
553 | const char sep, bool trim, bool skip_empty, | ||
554 | char ***_list, int *size) | ||
555 | @@ -141,3 +146,97 @@ bool string_in_list(const char *string, char **list, bool case_sensitive) | ||
556 | |||
557 | return false; | ||
558 | } | ||
559 | + | ||
560 | +errno_t sss_filter_sanitize_ex(TALLOC_CTX *mem_ctx, | ||
561 | + const char *input, | ||
562 | + char **sanitized, | ||
563 | + const char *ignore) | ||
564 | +{ | ||
565 | + char *output; | ||
566 | + size_t i = 0; | ||
567 | + size_t j = 0; | ||
568 | + char *allowed; | ||
569 | + | ||
570 | + /* Assume the worst-case. We'll resize it later, once */ | ||
571 | + output = talloc_array(mem_ctx, char, strlen(input) * 3 + 1); | ||
572 | + if (!output) { | ||
573 | + return ENOMEM; | ||
574 | + } | ||
575 | + | ||
576 | + while (input[i]) { | ||
577 | + /* Even though this character might have a special meaning, if it's | ||
578 | + * explicitly allowed, just copy it and move on | ||
579 | + */ | ||
580 | + if (ignore == NULL) { | ||
581 | + allowed = NULL; | ||
582 | + } else { | ||
583 | + allowed = strchr(ignore, input[i]); | ||
584 | + } | ||
585 | + if (allowed) { | ||
586 | + output[j++] = input[i++]; | ||
587 | + continue; | ||
588 | + } | ||
589 | + | ||
590 | + switch(input[i]) { | ||
591 | + case '\t': | ||
592 | + output[j++] = '\\'; | ||
593 | + output[j++] = '0'; | ||
594 | + output[j++] = '9'; | ||
595 | + break; | ||
596 | + case ' ': | ||
597 | + output[j++] = '\\'; | ||
598 | + output[j++] = '2'; | ||
599 | + output[j++] = '0'; | ||
600 | + break; | ||
601 | + case '*': | ||
602 | + output[j++] = '\\'; | ||
603 | + output[j++] = '2'; | ||
604 | + output[j++] = 'a'; | ||
605 | + break; | ||
606 | + case '(': | ||
607 | + output[j++] = '\\'; | ||
608 | + output[j++] = '2'; | ||
609 | + output[j++] = '8'; | ||
610 | + break; | ||
611 | + case ')': | ||
612 | + output[j++] = '\\'; | ||
613 | + output[j++] = '2'; | ||
614 | + output[j++] = '9'; | ||
615 | + break; | ||
616 | + case '\\': | ||
617 | + output[j++] = '\\'; | ||
618 | + output[j++] = '5'; | ||
619 | + output[j++] = 'c'; | ||
620 | + break; | ||
621 | + case '\r': | ||
622 | + output[j++] = '\\'; | ||
623 | + output[j++] = '0'; | ||
624 | + output[j++] = 'd'; | ||
625 | + break; | ||
626 | + case '\n': | ||
627 | + output[j++] = '\\'; | ||
628 | + output[j++] = '0'; | ||
629 | + output[j++] = 'a'; | ||
630 | + break; | ||
631 | + default: | ||
632 | + output[j++] = input[i]; | ||
633 | + } | ||
634 | + | ||
635 | + i++; | ||
636 | + } | ||
637 | + output[j] = '\0'; | ||
638 | + *sanitized = talloc_realloc(mem_ctx, output, char, j+1); | ||
639 | + if (!*sanitized) { | ||
640 | + talloc_free(output); | ||
641 | + return ENOMEM; | ||
642 | + } | ||
643 | + | ||
644 | + return EOK; | ||
645 | +} | ||
646 | + | ||
647 | +errno_t sss_filter_sanitize(TALLOC_CTX *mem_ctx, | ||
648 | + const char *input, | ||
649 | + char **sanitized) | ||
650 | +{ | ||
651 | + return sss_filter_sanitize_ex(mem_ctx, input, sanitized, NULL); | ||
652 | +} | ||
653 | -- | ||
654 | 2.25.1 | ||
655 | |||
diff --git a/recipes-security/sssd/sssd_1.16.4.bb b/recipes-security/sssd/sssd_1.16.4.bb index 186c9e0..e512dbf 100644 --- a/recipes-security/sssd/sssd_1.16.4.bb +++ b/recipes-security/sssd/sssd_1.16.4.bb | |||
@@ -18,6 +18,8 @@ SRC_URI = "https://releases.pagure.org/SSSD/${BPN}/${BP}.tar.gz \ | |||
18 | file://volatiles.99_sssd \ | 18 | file://volatiles.99_sssd \ |
19 | file://fix-ldblibdir.patch \ | 19 | file://fix-ldblibdir.patch \ |
20 | file://0001-build-Don-t-use-AC_CHECK_FILE-when-building-manpages.patch \ | 20 | file://0001-build-Don-t-use-AC_CHECK_FILE-when-building-manpages.patch \ |
21 | file://CVE-2022-4254-1.patch \ | ||
22 | file://CVE-2022-4254-2.patch \ | ||
21 | " | 23 | " |
22 | 24 | ||
23 | SRC_URI[md5sum] = "757bbb6f15409d8d075f4f06cb678d50" | 25 | SRC_URI[md5sum] = "757bbb6f15409d8d075f4f06cb678d50" |