/src/krb5/src/lib/krb5/krb/init_ctx.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | | /* lib/krb5/krb/init_ctx.c */ |
3 | | /* |
4 | | * Copyright 1994,1999,2000, 2002, 2003, 2007, 2008, 2009 by the Massachusetts Institute of Technology. |
5 | | * All Rights Reserved. |
6 | | * |
7 | | * Export of this software from the United States of America may |
8 | | * require a specific license from the United States Government. |
9 | | * It is the responsibility of any person or organization contemplating |
10 | | * export to obtain such a license before exporting. |
11 | | * |
12 | | * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and |
13 | | * distribute this software and its documentation for any purpose and |
14 | | * without fee is hereby granted, provided that the above copyright |
15 | | * notice appear in all copies and that both that copyright notice and |
16 | | * this permission notice appear in supporting documentation, and that |
17 | | * the name of M.I.T. not be used in advertising or publicity pertaining |
18 | | * to distribution of the software without specific, written prior |
19 | | * permission. Furthermore if you modify this software you must label |
20 | | * your software as modified software and not distribute it in such a |
21 | | * fashion that it might be confused with the original M.I.T. software. |
22 | | * M.I.T. makes no representations about the suitability of |
23 | | * this software for any purpose. It is provided "as is" without express |
24 | | * or implied warranty. |
25 | | */ |
26 | | /* |
27 | | * Copyright (C) 1998 by the FundsXpress, INC. |
28 | | * |
29 | | * All rights reserved. |
30 | | * |
31 | | * Export of this software from the United States of America may require |
32 | | * a specific license from the United States Government. It is the |
33 | | * responsibility of any person or organization contemplating export to |
34 | | * obtain such a license before exporting. |
35 | | * |
36 | | * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and |
37 | | * distribute this software and its documentation for any purpose and |
38 | | * without fee is hereby granted, provided that the above copyright |
39 | | * notice appear in all copies and that both that copyright notice and |
40 | | * this permission notice appear in supporting documentation, and that |
41 | | * the name of FundsXpress. not be used in advertising or publicity pertaining |
42 | | * to distribution of the software without specific, written prior |
43 | | * permission. FundsXpress makes no representations about the suitability of |
44 | | * this software for any purpose. It is provided "as is" without express |
45 | | * or implied warranty. |
46 | | * |
47 | | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR |
48 | | * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED |
49 | | * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
50 | | */ |
51 | | |
52 | | #include "k5-int.h" |
53 | | #include "int-proto.h" |
54 | | #include "os-proto.h" |
55 | | #include <ctype.h> |
56 | | #include "brand.c" |
57 | | #include "../krb5_libinit.h" |
58 | | |
59 | | static krb5_enctype default_enctype_list[] = { |
60 | | ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96, |
61 | | ENCTYPE_AES256_CTS_HMAC_SHA384_192, ENCTYPE_AES128_CTS_HMAC_SHA256_128, |
62 | | ENCTYPE_DES3_CBC_SHA1, |
63 | | ENCTYPE_ARCFOUR_HMAC, |
64 | | ENCTYPE_CAMELLIA128_CTS_CMAC, ENCTYPE_CAMELLIA256_CTS_CMAC, |
65 | | 0 |
66 | | }; |
67 | | |
68 | | #if (defined(_WIN32)) |
69 | | extern krb5_error_code krb5_vercheck(); |
70 | | extern void krb5_win_ccdll_load(krb5_context context); |
71 | | #endif |
72 | | |
73 | 2.72k | #define DEFAULT_CLOCKSKEW 300 /* 5 min */ |
74 | | |
75 | | static krb5_error_code |
76 | | get_integer(krb5_context ctx, const char *name, int def_val, int *int_out) |
77 | 10.8k | { |
78 | 10.8k | krb5_error_code retval; |
79 | | |
80 | 10.8k | retval = profile_get_integer(ctx->profile, KRB5_CONF_LIBDEFAULTS, |
81 | 10.8k | name, NULL, def_val, int_out); |
82 | 10.8k | if (retval) |
83 | 10.8k | TRACE_PROFILE_ERR(ctx, name, KRB5_CONF_LIBDEFAULTS, retval); |
84 | 10.8k | return retval; |
85 | 10.8k | } |
86 | | |
87 | | static krb5_error_code |
88 | | get_boolean(krb5_context ctx, const char *name, int def_val, int *boolean_out) |
89 | 13.6k | { |
90 | 13.6k | krb5_error_code retval; |
91 | | |
92 | 13.6k | retval = profile_get_boolean(ctx->profile, KRB5_CONF_LIBDEFAULTS, |
93 | 13.6k | name, NULL, def_val, boolean_out); |
94 | 13.6k | if (retval) |
95 | 13.6k | TRACE_PROFILE_ERR(ctx, name, KRB5_CONF_LIBDEFAULTS, retval); |
96 | 13.6k | return retval; |
97 | 13.6k | } |
98 | | |
99 | | static krb5_error_code |
100 | | get_tristate(krb5_context ctx, const char *name, const char *third_option, |
101 | | int third_option_val, int def_val, int *val_out) |
102 | 2.72k | { |
103 | 2.72k | krb5_error_code retval; |
104 | 2.72k | char *str; |
105 | 2.72k | int match; |
106 | | |
107 | 2.72k | retval = profile_get_boolean(ctx->profile, KRB5_CONF_LIBDEFAULTS, name, |
108 | 2.72k | NULL, def_val, val_out); |
109 | 2.72k | if (retval != PROF_BAD_BOOLEAN) |
110 | 2.72k | return retval; |
111 | 0 | retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS, name, |
112 | 0 | NULL, NULL, &str); |
113 | 0 | if (retval) |
114 | 0 | return retval; |
115 | 0 | match = (strcasecmp(third_option, str) == 0); |
116 | 0 | free(str); |
117 | 0 | if (!match) |
118 | 0 | return EINVAL; |
119 | 0 | *val_out = third_option_val; |
120 | 0 | return 0; |
121 | 0 | } |
122 | | |
123 | | krb5_error_code KRB5_CALLCONV |
124 | | krb5_init_context(krb5_context *context) |
125 | 2.72k | { |
126 | | /* |
127 | | * This is rather silly, but should improve our chances of |
128 | | * retaining the krb5_brand array in the final linked library, |
129 | | * better than a static variable that's unreferenced after |
130 | | * optimization, or even a non-static symbol that's not exported |
131 | | * from the library nor referenced from anywhere else in the |
132 | | * library. |
133 | | * |
134 | | * If someday we grow an API to actually return the string, we can |
135 | | * get rid of this silliness. |
136 | | */ |
137 | 2.72k | int my_zero = (krb5_brand[0] == 0); |
138 | | |
139 | 2.72k | return krb5_init_context_profile(NULL, my_zero, context); |
140 | 2.72k | } |
141 | | |
142 | | krb5_error_code KRB5_CALLCONV |
143 | | krb5_init_secure_context(krb5_context *context) |
144 | 0 | { |
145 | 0 | return krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_SECURE, context); |
146 | 0 | } |
147 | | |
148 | | krb5_error_code |
149 | | krb5int_init_context_kdc(krb5_context *context) |
150 | 0 | { |
151 | 0 | return krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, context); |
152 | 0 | } |
153 | | |
154 | | krb5_error_code KRB5_CALLCONV |
155 | | krb5_init_context_profile(profile_t profile, krb5_flags flags, |
156 | | krb5_context *context_out) |
157 | 2.72k | { |
158 | 2.72k | krb5_context ctx = 0; |
159 | 2.72k | krb5_error_code retval; |
160 | 2.72k | int tmp; |
161 | 2.72k | char *plugin_dir = NULL, *timeout_str = NULL; |
162 | | |
163 | | /* Verify some assumptions. If the assumptions hold and the |
164 | | compiler is optimizing, this should result in no code being |
165 | | executed. If we're guessing "unsigned long long" instead |
166 | | of using uint64_t, the possibility does exist that we're |
167 | | wrong. */ |
168 | 2.72k | { |
169 | 2.72k | uint64_t i64; |
170 | 2.72k | assert(sizeof(i64) == 8); |
171 | 2.72k | i64 = 0, i64--, i64 >>= 62; |
172 | 2.72k | assert(i64 == 3); |
173 | 2.72k | i64 = 1, i64 <<= 31, i64 <<= 31, i64 <<= 1; |
174 | 2.72k | assert(i64 != 0); |
175 | 2.72k | i64 <<= 1; |
176 | 2.72k | assert(i64 == 0); |
177 | 2.72k | } |
178 | | |
179 | 2.72k | retval = krb5int_initialize_library(); |
180 | 2.72k | if (retval) |
181 | 0 | return retval; |
182 | | |
183 | | #if (defined(_WIN32)) |
184 | | /* |
185 | | * Load the krbcc32.dll if necessary. We do this here so that |
186 | | * we know to use API: later on during initialization. |
187 | | * The context being NULL is ok. |
188 | | */ |
189 | | krb5_win_ccdll_load(ctx); |
190 | | |
191 | | /* |
192 | | * krb5_vercheck() is defined in win_glue.c, and this is |
193 | | * where we handle the timebomb and version server checks. |
194 | | */ |
195 | | retval = krb5_vercheck(); |
196 | | if (retval) |
197 | | return retval; |
198 | | #endif |
199 | | |
200 | 2.72k | *context_out = NULL; |
201 | | |
202 | 2.72k | ctx = calloc(1, sizeof(struct _krb5_context)); |
203 | 2.72k | if (!ctx) |
204 | 0 | return ENOMEM; |
205 | 2.72k | ctx->magic = KV5M_CONTEXT; |
206 | | |
207 | 2.72k | ctx->profile_secure = (flags & KRB5_INIT_CONTEXT_SECURE) != 0; |
208 | | |
209 | 2.72k | retval = k5_os_init_context(ctx, profile, flags); |
210 | 2.72k | if (retval) |
211 | 0 | goto cleanup; |
212 | | |
213 | 2.72k | ctx->trace_callback = NULL; |
214 | 2.72k | #ifndef DISABLE_TRACING |
215 | 2.72k | if (!ctx->profile_secure) |
216 | 2.72k | k5_init_trace(ctx); |
217 | 2.72k | #endif |
218 | | |
219 | 2.72k | retval = get_boolean(ctx, KRB5_CONF_ALLOW_WEAK_CRYPTO, 0, &tmp); |
220 | 2.72k | if (retval) |
221 | 0 | goto cleanup; |
222 | 2.72k | ctx->allow_weak_crypto = tmp; |
223 | | |
224 | 2.72k | retval = get_boolean(ctx, KRB5_CONF_ALLOW_DES3, 0, &tmp); |
225 | 2.72k | if (retval) |
226 | 0 | goto cleanup; |
227 | 2.72k | ctx->allow_des3 = tmp; |
228 | | |
229 | 2.72k | retval = get_boolean(ctx, KRB5_CONF_ALLOW_RC4, 0, &tmp); |
230 | 2.72k | if (retval) |
231 | 0 | goto cleanup; |
232 | 2.72k | ctx->allow_rc4 = tmp; |
233 | | |
234 | 2.72k | retval = get_boolean(ctx, KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME, 0, &tmp); |
235 | 2.72k | if (retval) |
236 | 0 | goto cleanup; |
237 | 2.72k | ctx->ignore_acceptor_hostname = tmp; |
238 | | |
239 | 2.72k | retval = get_boolean(ctx, KRB5_CONF_ENFORCE_OK_AS_DELEGATE, 0, &tmp); |
240 | 2.72k | if (retval) |
241 | 0 | goto cleanup; |
242 | 2.72k | ctx->enforce_ok_as_delegate = tmp; |
243 | | |
244 | 2.72k | retval = get_tristate(ctx, KRB5_CONF_DNS_CANONICALIZE_HOSTNAME, "fallback", |
245 | 2.72k | CANONHOST_FALLBACK, 1, &tmp); |
246 | 2.72k | if (retval) |
247 | 0 | goto cleanup; |
248 | 2.72k | ctx->dns_canonicalize_hostname = tmp; |
249 | | |
250 | 2.72k | ctx->default_realm = 0; |
251 | 2.72k | get_integer(ctx, KRB5_CONF_CLOCKSKEW, DEFAULT_CLOCKSKEW, &tmp); |
252 | 2.72k | ctx->clockskew = tmp; |
253 | | |
254 | 2.72k | retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS, |
255 | 2.72k | KRB5_CONF_REQUEST_TIMEOUT, NULL, NULL, |
256 | 2.72k | &timeout_str); |
257 | 2.72k | if (retval) |
258 | 0 | goto cleanup; |
259 | 2.72k | if (timeout_str != NULL) { |
260 | 0 | retval = krb5_string_to_deltat(timeout_str, &ctx->req_timeout); |
261 | 0 | if (retval) |
262 | 0 | goto cleanup; |
263 | 0 | } |
264 | | |
265 | 2.72k | get_integer(ctx, KRB5_CONF_KDC_DEFAULT_OPTIONS, KDC_OPT_RENEWABLE_OK, |
266 | 2.72k | &tmp); |
267 | 2.72k | ctx->kdc_default_options = tmp; |
268 | 2.72k | #define DEFAULT_KDC_TIMESYNC 1 |
269 | 2.72k | get_integer(ctx, KRB5_CONF_KDC_TIMESYNC, DEFAULT_KDC_TIMESYNC, &tmp); |
270 | 2.72k | ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0; |
271 | | |
272 | 2.72k | retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS, |
273 | 2.72k | KRB5_CONF_PLUGIN_BASE_DIR, 0, |
274 | 2.72k | DEFAULT_PLUGIN_BASE_DIR, &plugin_dir); |
275 | 2.72k | if (!retval) |
276 | 2.72k | retval = k5_expand_path_tokens(ctx, plugin_dir, &ctx->plugin_base_dir); |
277 | 2.72k | if (retval) { |
278 | 0 | TRACE_PROFILE_ERR(ctx, KRB5_CONF_PLUGIN_BASE_DIR, |
279 | 0 | KRB5_CONF_LIBDEFAULTS, retval); |
280 | 0 | goto cleanup; |
281 | 0 | } |
282 | | |
283 | | /* |
284 | | * We use a default file credentials cache of 3. See |
285 | | * lib/krb5/krb/ccache/file/fcc.h for a description of the |
286 | | * credentials cache types. |
287 | | * |
288 | | * Note: DCE 1.0.3a only supports a cache type of 1 |
289 | | * DCE 1.1 supports a cache type of 2. |
290 | | */ |
291 | 2.72k | #define DEFAULT_CCACHE_TYPE 4 |
292 | 2.72k | get_integer(ctx, KRB5_CONF_CCACHE_TYPE, DEFAULT_CCACHE_TYPE, &tmp); |
293 | 2.72k | ctx->fcc_default_format = tmp + 0x0500; |
294 | 2.72k | ctx->prompt_types = 0; |
295 | 2.72k | ctx->use_conf_ktypes = 0; |
296 | 2.72k | ctx->udp_pref_limit = -1; |
297 | | |
298 | | /* It's OK if this fails */ |
299 | 2.72k | (void)profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS, |
300 | 2.72k | KRB5_CONF_ERR_FMT, NULL, NULL, &ctx->err_fmt); |
301 | 2.72k | *context_out = ctx; |
302 | 2.72k | ctx = NULL; |
303 | | |
304 | 2.72k | cleanup: |
305 | 2.72k | profile_release_string(plugin_dir); |
306 | 2.72k | profile_release_string(timeout_str); |
307 | 2.72k | krb5_free_context(ctx); |
308 | 2.72k | return retval; |
309 | 2.72k | } |
310 | | |
311 | | void KRB5_CALLCONV |
312 | | krb5_free_context(krb5_context ctx) |
313 | 5.47k | { |
314 | 5.47k | if (ctx == NULL) |
315 | 2.75k | return; |
316 | 2.72k | k5_os_free_context(ctx); |
317 | | |
318 | 2.72k | free(ctx->tgs_etypes); |
319 | 2.72k | ctx->tgs_etypes = NULL; |
320 | 2.72k | free(ctx->default_realm); |
321 | 2.72k | ctx->default_realm = 0; |
322 | | |
323 | 2.72k | krb5_clear_error_message(ctx); |
324 | 2.72k | free(ctx->err_fmt); |
325 | | |
326 | 2.72k | #ifndef DISABLE_TRACING |
327 | 2.72k | if (ctx->trace_callback) |
328 | 0 | ctx->trace_callback(ctx, NULL, ctx->trace_callback_data); |
329 | 2.72k | #endif |
330 | | |
331 | 2.72k | k5_ccselect_free_context(ctx); |
332 | 2.72k | k5_hostrealm_free_context(ctx); |
333 | 2.72k | k5_localauth_free_context(ctx); |
334 | 2.72k | k5_plugin_free_context(ctx); |
335 | 2.72k | free(ctx->plugin_base_dir); |
336 | 2.72k | free(ctx->tls); |
337 | | |
338 | 2.72k | ctx->magic = 0; |
339 | 2.72k | free(ctx); |
340 | 2.72k | } |
341 | | |
342 | | /* |
343 | | * Set the desired default ktypes, making sure they are valid. |
344 | | */ |
345 | | krb5_error_code KRB5_CALLCONV |
346 | | krb5_set_default_tgs_enctypes(krb5_context context, const krb5_enctype *etypes) |
347 | 0 | { |
348 | 0 | krb5_error_code code; |
349 | 0 | krb5_enctype *list; |
350 | 0 | size_t src, dst; |
351 | |
|
352 | 0 | if (etypes) { |
353 | | /* Empty list passed in. */ |
354 | 0 | if (etypes[0] == 0) |
355 | 0 | return EINVAL; |
356 | 0 | code = k5_copy_etypes(etypes, &list); |
357 | 0 | if (code) |
358 | 0 | return code; |
359 | | |
360 | | /* Filter list in place to exclude invalid and (optionally) weak |
361 | | * enctypes. */ |
362 | 0 | for (src = dst = 0; list[src]; src++) { |
363 | 0 | if (!krb5_c_valid_enctype(list[src])) |
364 | 0 | continue; |
365 | 0 | if (!context->allow_weak_crypto |
366 | 0 | && krb5int_c_weak_enctype(list[src])) |
367 | 0 | continue; |
368 | 0 | list[dst++] = list[src]; |
369 | 0 | } |
370 | 0 | list[dst] = 0; /* Zero-terminate. */ |
371 | 0 | if (dst == 0) { |
372 | 0 | free(list); |
373 | 0 | return KRB5_CONFIG_ETYPE_NOSUPP; |
374 | 0 | } |
375 | 0 | } else { |
376 | 0 | list = NULL; |
377 | 0 | } |
378 | | |
379 | 0 | free(context->tgs_etypes); |
380 | 0 | context->tgs_etypes = list; |
381 | 0 | return 0; |
382 | 0 | } |
383 | | |
384 | | /* Old name for above function. This is not a public API, but Samba (as of |
385 | | * 2021-02-12) uses this name if it finds it in the library. */ |
386 | | krb5_error_code |
387 | | krb5_set_default_tgs_ktypes(krb5_context context, const krb5_enctype *etypes); |
388 | | |
389 | | krb5_error_code |
390 | | krb5_set_default_tgs_ktypes(krb5_context context, const krb5_enctype *etypes) |
391 | 0 | { |
392 | 0 | return krb5_set_default_tgs_enctypes(context, etypes); |
393 | 0 | } |
394 | | |
395 | | /* |
396 | | * Add etype to, or remove etype from, the zero-terminated list *list_ptr, |
397 | | * reallocating if the list size changes. Filter out weak enctypes if |
398 | | * allow_weak is false. If memory allocation fails, set *list_ptr to NULL and |
399 | | * do nothing for subsequent operations. |
400 | | */ |
401 | | static void |
402 | | mod_list(krb5_enctype etype, krb5_boolean add, krb5_boolean allow_weak, |
403 | | krb5_enctype **list_ptr) |
404 | 0 | { |
405 | 0 | size_t i; |
406 | 0 | krb5_enctype *list = *list_ptr; |
407 | | |
408 | | /* Stop now if a previous allocation failed or the enctype is filtered. */ |
409 | 0 | if (list == NULL || (!allow_weak && krb5int_c_weak_enctype(etype))) |
410 | 0 | return; |
411 | 0 | if (add) { |
412 | | /* Count entries; do nothing if etype is a duplicate. */ |
413 | 0 | for (i = 0; list[i] != 0; i++) { |
414 | 0 | if (list[i] == etype) |
415 | 0 | return; |
416 | 0 | } |
417 | | /* Make room for the new entry and add it. */ |
418 | 0 | list = realloc(list, (i + 2) * sizeof(krb5_enctype)); |
419 | 0 | if (list != NULL) { |
420 | 0 | list[i] = etype; |
421 | 0 | list[i + 1] = 0; |
422 | 0 | } |
423 | 0 | } else { |
424 | | /* Look for etype in the list. */ |
425 | 0 | for (i = 0; list[i] != 0; i++) { |
426 | 0 | if (list[i] != etype) |
427 | 0 | continue; |
428 | | /* Perform removal. */ |
429 | 0 | for (; list[i + 1] != 0; i++) |
430 | 0 | list[i] = list[i + 1]; |
431 | 0 | list[i] = 0; |
432 | 0 | list = realloc(list, (i + 1) * sizeof(krb5_enctype)); |
433 | 0 | break; |
434 | 0 | } |
435 | 0 | } |
436 | | /* Update *list_ptr, freeing the old value if realloc failed. */ |
437 | 0 | if (list == NULL) |
438 | 0 | free(*list_ptr); |
439 | 0 | *list_ptr = list; |
440 | 0 | } |
441 | | |
442 | | /* |
443 | | * Set *result to a zero-terminated list of enctypes resulting from |
444 | | * parsing profstr. profstr may be modified during parsing. |
445 | | */ |
446 | | krb5_error_code |
447 | | krb5int_parse_enctype_list(krb5_context context, const char *profkey, |
448 | | char *profstr, krb5_enctype *default_list, |
449 | | krb5_enctype **result) |
450 | 0 | { |
451 | 0 | char *token, *delim = " \t\r\n,", *save = NULL; |
452 | 0 | krb5_boolean sel, weak = context->allow_weak_crypto; |
453 | 0 | krb5_enctype etype, *list; |
454 | 0 | unsigned int i; |
455 | |
|
456 | 0 | *result = NULL; |
457 | | |
458 | | /* Set up an empty list. Allocation failure is detected at the end. */ |
459 | 0 | list = malloc(sizeof(krb5_enctype)); |
460 | 0 | if (list != NULL) |
461 | 0 | list[0] = 0; |
462 | | |
463 | | /* Walk through the words in profstr. */ |
464 | 0 | for (token = strtok_r(profstr, delim, &save); token; |
465 | 0 | token = strtok_r(NULL, delim, &save)) { |
466 | | /* Determine if we are adding or removing enctypes. */ |
467 | 0 | sel = TRUE; |
468 | 0 | if (*token == '+' || *token == '-') |
469 | 0 | sel = (*token++ == '+'); |
470 | |
|
471 | 0 | if (strcasecmp(token, "DEFAULT") == 0) { |
472 | | /* Set all enctypes in the default list. */ |
473 | 0 | for (i = 0; default_list[i]; i++) |
474 | 0 | mod_list(default_list[i], sel, weak, &list); |
475 | 0 | } else if (strcasecmp(token, "des3") == 0) { |
476 | 0 | mod_list(ENCTYPE_DES3_CBC_SHA1, sel, weak, &list); |
477 | 0 | } else if (strcasecmp(token, "aes") == 0) { |
478 | 0 | mod_list(ENCTYPE_AES256_CTS_HMAC_SHA1_96, sel, weak, &list); |
479 | 0 | mod_list(ENCTYPE_AES128_CTS_HMAC_SHA1_96, sel, weak, &list); |
480 | 0 | mod_list(ENCTYPE_AES256_CTS_HMAC_SHA384_192, sel, weak, &list); |
481 | 0 | mod_list(ENCTYPE_AES128_CTS_HMAC_SHA256_128, sel, weak, &list); |
482 | 0 | } else if (strcasecmp(token, "rc4") == 0) { |
483 | 0 | mod_list(ENCTYPE_ARCFOUR_HMAC, sel, weak, &list); |
484 | 0 | } else if (strcasecmp(token, "camellia") == 0) { |
485 | 0 | mod_list(ENCTYPE_CAMELLIA256_CTS_CMAC, sel, weak, &list); |
486 | 0 | mod_list(ENCTYPE_CAMELLIA128_CTS_CMAC, sel, weak, &list); |
487 | 0 | } else if (krb5_string_to_enctype(token, &etype) == 0) { |
488 | | /* Set a specific enctype. */ |
489 | 0 | mod_list(etype, sel, weak, &list); |
490 | 0 | } else { |
491 | 0 | TRACE_ENCTYPE_LIST_UNKNOWN(context, profkey, token); |
492 | 0 | } |
493 | 0 | } |
494 | |
|
495 | 0 | if (list == NULL) |
496 | 0 | return ENOMEM; |
497 | 0 | if (list[0] == ENCTYPE_NULL) { |
498 | 0 | free(list); |
499 | 0 | return KRB5_CONFIG_ETYPE_NOSUPP; |
500 | 0 | } |
501 | 0 | *result = list; |
502 | 0 | return 0; |
503 | 0 | } |
504 | | |
505 | | krb5_error_code |
506 | | krb5_get_default_in_tkt_ktypes(krb5_context context, krb5_enctype **ktypes) |
507 | 0 | { |
508 | 0 | krb5_error_code ret; |
509 | 0 | char *profstr = NULL; |
510 | 0 | const char *profkey; |
511 | |
|
512 | 0 | *ktypes = NULL; |
513 | |
|
514 | 0 | profkey = KRB5_CONF_DEFAULT_TKT_ENCTYPES; |
515 | 0 | ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, |
516 | 0 | profkey, NULL, NULL, &profstr); |
517 | 0 | if (ret) |
518 | 0 | return ret; |
519 | 0 | if (profstr == NULL) { |
520 | 0 | profkey = KRB5_CONF_PERMITTED_ENCTYPES; |
521 | 0 | ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, |
522 | 0 | profkey, NULL, "DEFAULT", &profstr); |
523 | 0 | if (ret) |
524 | 0 | return ret; |
525 | 0 | } |
526 | | |
527 | 0 | ret = krb5int_parse_enctype_list(context, profkey, profstr, |
528 | 0 | default_enctype_list, ktypes); |
529 | 0 | profile_release_string(profstr); |
530 | 0 | return ret; |
531 | 0 | } |
532 | | |
533 | | void |
534 | | KRB5_CALLCONV |
535 | | krb5_free_enctypes(krb5_context context, krb5_enctype *val) |
536 | 0 | { |
537 | 0 | free (val); |
538 | 0 | } |
539 | | |
540 | | krb5_error_code KRB5_CALLCONV |
541 | | krb5_get_tgs_ktypes(krb5_context context, krb5_const_principal princ, |
542 | | krb5_enctype **ktypes) |
543 | 0 | { |
544 | 0 | krb5_error_code ret; |
545 | 0 | char *profstr = NULL; |
546 | 0 | const char *profkey; |
547 | |
|
548 | 0 | *ktypes = NULL; |
549 | | |
550 | | /* Use only profile configuration when use_conf_ktypes is set. */ |
551 | 0 | if (!context->use_conf_ktypes && context->tgs_etypes != NULL) |
552 | 0 | return k5_copy_etypes(context->tgs_etypes, ktypes); |
553 | | |
554 | 0 | profkey = KRB5_CONF_DEFAULT_TGS_ENCTYPES; |
555 | 0 | ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, |
556 | 0 | profkey, NULL, NULL, &profstr); |
557 | 0 | if (ret) |
558 | 0 | return ret; |
559 | 0 | if (profstr == NULL) { |
560 | 0 | profkey = KRB5_CONF_PERMITTED_ENCTYPES; |
561 | 0 | ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, |
562 | 0 | profkey, NULL, "DEFAULT", &profstr); |
563 | 0 | if (ret) |
564 | 0 | return ret; |
565 | 0 | } |
566 | | |
567 | 0 | ret = krb5int_parse_enctype_list(context, profkey, profstr, |
568 | 0 | default_enctype_list, ktypes); |
569 | 0 | profile_release_string(profstr); |
570 | 0 | return ret; |
571 | 0 | } |
572 | | |
573 | | krb5_error_code KRB5_CALLCONV |
574 | | krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes) |
575 | 0 | { |
576 | 0 | krb5_error_code ret; |
577 | 0 | char *profstr = NULL; |
578 | 0 | const char *profkey; |
579 | |
|
580 | 0 | *ktypes = NULL; |
581 | |
|
582 | 0 | if (context->tgs_etypes != NULL) |
583 | 0 | return k5_copy_etypes(context->tgs_etypes, ktypes); |
584 | | |
585 | 0 | profkey = KRB5_CONF_PERMITTED_ENCTYPES; |
586 | 0 | ret = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, |
587 | 0 | profkey, NULL, "DEFAULT", &profstr); |
588 | 0 | if (ret) |
589 | 0 | return ret; |
590 | | |
591 | 0 | ret = krb5int_parse_enctype_list(context, profkey, profstr, |
592 | 0 | default_enctype_list, ktypes); |
593 | 0 | profile_release_string(profstr); |
594 | 0 | return ret; |
595 | 0 | } |
596 | | |
597 | | krb5_boolean |
598 | | krb5_is_permitted_enctype(krb5_context context, krb5_enctype etype) |
599 | 0 | { |
600 | 0 | krb5_enctype *list; |
601 | 0 | krb5_boolean ret; |
602 | |
|
603 | 0 | if (krb5_get_permitted_enctypes(context, &list)) |
604 | 0 | return FALSE; |
605 | 0 | ret = k5_etypes_contains(list, etype); |
606 | 0 | krb5_free_enctypes(context, list); |
607 | 0 | return ret; |
608 | 0 | } |