1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/init_ctx.c */
4 * Copyright 1994,1999,2000, 2002, 2003, 2007, 2008, 2009 by the Massachusetts Institute of Technology.
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.
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.
27 * Copyright (C) 1998 by the FundsXpress, INC.
29 * All rights reserved.
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.
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.
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.
53 #include "int-proto.h"
56 #include "../krb5_libinit.h"
58 /* The des-mdX entries are last for now, because it's easy to
59 configure KDCs to issue TGTs with des-mdX keys and then not accept
60 them. This'll be fixed, but for better compatibility, let's prefer
62 static krb5_enctype default_enctype_list[] = {
63 ENCTYPE_AES256_CTS_HMAC_SHA1_96, ENCTYPE_AES128_CTS_HMAC_SHA1_96,
64 ENCTYPE_DES3_CBC_SHA1,
66 ENCTYPE_DES_CBC_CRC, ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_MD4,
71 extern krb5_error_code krb5_vercheck();
72 extern void krb5_win_ccdll_load(krb5_context context);
75 #define DEFAULT_CLOCKSKEW 300 /* 5 min */
77 static krb5_error_code
78 get_integer(krb5_context ctx, const char *name, int def_val, int *int_out)
80 krb5_error_code retval;
82 retval = profile_get_integer(ctx->profile, KRB5_CONF_LIBDEFAULTS,
83 name, NULL, def_val, int_out);
85 TRACE_PROFILE_ERR(ctx, name, KRB5_CONF_LIBDEFAULTS, retval);
89 static krb5_error_code
90 get_boolean(krb5_context ctx, const char *name, int def_val, int *boolean_out)
92 krb5_error_code retval;
94 retval = profile_get_boolean(ctx->profile, KRB5_CONF_LIBDEFAULTS,
95 name, NULL, def_val, boolean_out);
97 TRACE_PROFILE_ERR(ctx, name, KRB5_CONF_LIBDEFAULTS, retval);
101 krb5_error_code KRB5_CALLCONV
102 krb5_init_context(krb5_context *context)
105 * This is rather silly, but should improve our chances of
106 * retaining the krb5_brand array in the final linked library,
107 * better than a static variable that's unreferenced after
108 * optimization, or even a non-static symbol that's not exported
109 * from the library nor referenced from anywhere else in the
112 * If someday we grow an API to actually return the string, we can
113 * get rid of this silliness.
115 int my_zero = (krb5_brand[0] == 0);
117 return krb5_init_context_profile(NULL, my_zero, context);
120 krb5_error_code KRB5_CALLCONV
121 krb5_init_secure_context(krb5_context *context)
123 return krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_SECURE, context);
127 krb5int_init_context_kdc(krb5_context *context)
129 return krb5_init_context_profile(NULL, KRB5_INIT_CONTEXT_KDC, context);
132 krb5_error_code KRB5_CALLCONV
133 krb5_init_context_profile(profile_t profile, krb5_flags flags,
134 krb5_context *context_out)
136 krb5_context ctx = 0;
137 krb5_error_code retval;
139 krb5_int32 now, now_usec;
145 /* Verify some assumptions. If the assumptions hold and the
146 compiler is optimizing, this should result in no code being
147 executed. If we're guessing "unsigned long long" instead
148 of using uint64_t, the possibility does exist that we're
152 assert(sizeof(i64) == 8);
153 i64 = 0, i64--, i64 >>= 62;
155 i64 = 1, i64 <<= 31, i64 <<= 31, i64 <<= 1;
161 retval = krb5int_initialize_library();
165 #if (defined(_WIN32))
167 * Load the krbcc32.dll if necessary. We do this here so that
168 * we know to use API: later on during initialization.
169 * The context being NULL is ok.
171 krb5_win_ccdll_load(ctx);
174 * krb5_vercheck() is defined in win_glue.c, and this is
175 * where we handle the timebomb and version server checks.
177 retval = krb5_vercheck();
184 ctx = calloc(1, sizeof(struct _krb5_context));
187 ctx->magic = KV5M_CONTEXT;
189 ctx->profile_secure = (flags & KRB5_INIT_CONTEXT_SECURE) != 0;
191 if ((retval = krb5_os_init_context(ctx, profile, flags)) != 0)
194 ctx->trace_callback = NULL;
195 #ifndef DISABLE_TRACING
196 if (!ctx->profile_secure)
197 krb5int_init_trace(ctx);
200 retval = get_boolean(ctx, KRB5_CONF_ALLOW_WEAK_CRYPTO, 0, &tmp);
203 ctx->allow_weak_crypto = tmp;
205 retval = get_boolean(ctx, KRB5_CONF_IGNORE_ACCEPTOR_HOSTNAME, 0, &tmp);
208 ctx->ignore_acceptor_hostname = tmp;
210 /* initialize the prng (not well, but passable) */
211 if ((retval = krb5_c_random_os_entropy( ctx, 0, NULL)) !=0)
213 if ((retval = krb5_crypto_us_timeofday(&seed_data.now, &seed_data.now_usec)))
215 seed_data.pid = getpid ();
216 seed.length = sizeof(seed_data);
217 seed.data = (char *) &seed_data;
218 if ((retval = krb5_c_random_add_entropy(ctx, KRB5_C_RANDSOURCE_TIMING, &seed)))
221 ctx->default_realm = 0;
222 get_integer(ctx, KRB5_CONF_CLOCKSKEW, DEFAULT_CLOCKSKEW, &tmp);
223 ctx->clockskew = tmp;
226 /* Default ticket lifetime is currently not supported */
227 profile_get_integer(ctx->profile, KRB5_CONF_LIBDEFAULTS, "tkt_lifetime",
228 0, 10 * 60 * 60, &tmp);
229 ctx->tkt_lifetime = tmp;
232 /* DCE 1.1 and below only support CKSUMTYPE_RSA_MD4 (2) */
233 /* DCE add kdc_req_checksum_type = 2 to krb5.conf */
234 get_integer(ctx, KRB5_CONF_KDC_REQ_CHECKSUM_TYPE, CKSUMTYPE_RSA_MD5,
236 ctx->kdc_req_sumtype = tmp;
238 get_integer(ctx, KRB5_CONF_AP_REQ_CHECKSUM_TYPE, 0, &tmp);
239 ctx->default_ap_req_sumtype = tmp;
241 get_integer(ctx, KRB5_CONF_SAFE_CHECKSUM_TYPE, CKSUMTYPE_RSA_MD5_DES,
243 ctx->default_safe_sumtype = tmp;
245 get_integer(ctx, KRB5_CONF_KDC_DEFAULT_OPTIONS, KDC_OPT_RENEWABLE_OK,
247 ctx->kdc_default_options = tmp;
248 #define DEFAULT_KDC_TIMESYNC 1
249 get_integer(ctx, KRB5_CONF_KDC_TIMESYNC, DEFAULT_KDC_TIMESYNC, &tmp);
250 ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0;
252 retval = profile_get_string(ctx->profile, KRB5_CONF_LIBDEFAULTS,
253 KRB5_CONF_PLUGIN_BASE_DIR, 0,
254 DEFAULT_PLUGIN_BASE_DIR,
255 &ctx->plugin_base_dir);
257 TRACE_PROFILE_ERR(ctx, KRB5_CONF_PLUGIN_BASE_DIR,
258 KRB5_CONF_LIBDEFAULTS, retval);
263 * We use a default file credentials cache of 3. See
264 * lib/krb5/krb/ccache/file/fcc.h for a description of the
265 * credentials cache types.
267 * Note: DCE 1.0.3a only supports a cache type of 1
268 * DCE 1.1 supports a cache type of 2.
270 #define DEFAULT_CCACHE_TYPE 4
271 get_integer(ctx, KRB5_CONF_CCACHE_TYPE, DEFAULT_CCACHE_TYPE, &tmp);
272 ctx->fcc_default_format = tmp + 0x0500;
273 ctx->prompt_types = 0;
274 ctx->use_conf_ktypes = 0;
275 ctx->udp_pref_limit = -1;
280 krb5_free_context(ctx);
285 krb5_free_context(krb5_context ctx)
289 krb5_os_free_context(ctx);
291 free(ctx->in_tkt_etypes);
292 ctx->in_tkt_etypes = NULL;
293 free(ctx->tgs_etypes);
294 ctx->tgs_etypes = NULL;
295 free(ctx->default_realm);
296 ctx->default_realm = 0;
297 if (ctx->ser_ctx_count && ctx->ser_ctx) {
302 krb5_clear_error_message(ctx);
304 #ifndef DISABLE_TRACING
305 if (ctx->trace_callback)
306 ctx->trace_callback(ctx, NULL, ctx->trace_callback_data);
309 k5_ccselect_free_context(ctx);
310 k5_plugin_free_context(ctx);
311 free(ctx->plugin_base_dir);
318 * Set the desired default ktypes, making sure they are valid.
320 static krb5_error_code
321 set_default_etype_var(krb5_context context, const krb5_enctype *etypes,
324 krb5_error_code code;
329 /* Empty list passed in. */
332 code = krb5int_copy_etypes(etypes, &list);
336 /* Filter list in place to exclude invalid and (optionally) weak
338 for (src = dst = 0; list[src]; src++) {
339 if (!krb5_c_valid_enctype(list[src]))
341 if (!context->allow_weak_crypto
342 && krb5int_c_weak_enctype(list[src]))
344 list[dst++] = list[src];
346 list[dst] = 0; /* Zero-terminate. */
349 return KRB5_CONFIG_ETYPE_NOSUPP;
361 krb5_set_default_in_tkt_ktypes(krb5_context context,
362 const krb5_enctype *etypes)
364 return set_default_etype_var(context, etypes, &context->in_tkt_etypes);
367 krb5_error_code KRB5_CALLCONV
368 krb5_set_default_tgs_enctypes(krb5_context context, const krb5_enctype *etypes)
370 return set_default_etype_var(context, etypes, &context->tgs_etypes);
373 /* Old name for above function. */
375 krb5_set_default_tgs_ktypes(krb5_context context, const krb5_enctype *etypes)
377 return set_default_etype_var(context, etypes, &context->tgs_etypes);
381 * Add etype to, or remove etype from, the zero-terminated list *list_ptr,
382 * reallocating if the list size changes. Filter out weak enctypes if
383 * allow_weak is false. If memory allocation fails, set *list_ptr to NULL and
384 * do nothing for subsequent operations.
387 mod_list(krb5_enctype etype, krb5_boolean add, krb5_boolean allow_weak,
388 krb5_enctype **list_ptr)
391 krb5_enctype *list = *list_ptr;
393 /* Stop now if a previous allocation failed or the enctype is filtered. */
394 if (list == NULL || (!allow_weak && krb5int_c_weak_enctype(etype)))
397 /* Count entries; do nothing if etype is a duplicate. */
398 for (i = 0; list[i] != 0; i++) {
399 if (list[i] == etype)
402 /* Make room for the new entry and add it. */
403 list = realloc(list, (i + 2) * sizeof(krb5_enctype));
409 /* Look for etype in the list. */
410 for (i = 0; list[i] != 0; i++) {
411 if (list[i] != etype)
413 /* Perform removal. */
414 for (; list[i + 1] != 0; i++)
415 list[i] = list[i + 1];
417 list = realloc(list, (i + 1) * sizeof(krb5_enctype));
421 /* Update *list_ptr, freeing the old value if realloc failed. */
428 * Set *result to a zero-terminated list of enctypes resulting from
429 * parsing profstr. profstr may be modified during parsing.
432 krb5int_parse_enctype_list(krb5_context context, const char *profkey,
433 char *profstr, krb5_enctype *default_list,
434 krb5_enctype **result)
436 char *token, *delim = " \t\r\n,", *save = NULL;
437 krb5_boolean sel, weak = context->allow_weak_crypto;
438 krb5_enctype etype, *list;
443 /* Set up an empty list. Allocation failure is detected at the end. */
444 list = malloc(sizeof(krb5_enctype));
448 /* Walk through the words in profstr. */
449 for (token = strtok_r(profstr, delim, &save); token;
450 token = strtok_r(NULL, delim, &save)) {
451 /* Determine if we are adding or removing enctypes. */
453 if (*token == '+' || *token == '-')
454 sel = (*token++ == '+');
456 if (strcasecmp(token, "DEFAULT") == 0) {
457 /* Set all enctypes in the default list. */
458 for (i = 0; default_list[i]; i++)
459 mod_list(default_list[i], sel, weak, &list);
460 } else if (strcasecmp(token, "des") == 0) {
461 mod_list(ENCTYPE_DES_CBC_CRC, sel, weak, &list);
462 mod_list(ENCTYPE_DES_CBC_MD5, sel, weak, &list);
463 mod_list(ENCTYPE_DES_CBC_MD4, sel, weak, &list);
464 } else if (strcasecmp(token, "des3") == 0) {
465 mod_list(ENCTYPE_DES3_CBC_SHA1, sel, weak, &list);
466 } else if (strcasecmp(token, "aes") == 0) {
467 mod_list(ENCTYPE_AES256_CTS_HMAC_SHA1_96, sel, weak, &list);
468 mod_list(ENCTYPE_AES128_CTS_HMAC_SHA1_96, sel, weak, &list);
469 } else if (strcasecmp(token, "rc4") == 0) {
470 mod_list(ENCTYPE_ARCFOUR_HMAC, sel, weak, &list);
472 } else if (strcasecmp(token, "camellia") == 0) {
473 mod_list(ENCTYPE_CAMELLIA256_CTS_CMAC, sel, weak, &list);
474 mod_list(ENCTYPE_CAMELLIA128_CTS_CMAC, sel, weak, &list);
476 } else if (krb5_string_to_enctype(token, &etype) == 0) {
477 /* Set a specific enctype. */
478 mod_list(etype, sel, weak, &list);
480 TRACE_ENCTYPE_LIST_UNKNOWN(context, profkey, token);
491 * Set *etypes_ptr to a zero-terminated list of enctypes. ctx_list
492 * (containing application-specified enctypes) is used if non-NULL;
493 * otherwise the libdefaults profile string specified by profkey is
494 * used. default_list is the default enctype list to be used while
495 * parsing profile strings, and is also used if the profile string is
498 static krb5_error_code
499 get_profile_etype_list(krb5_context context, krb5_enctype **etypes_ptr,
500 char *profkey, krb5_enctype *ctx_list,
501 krb5_enctype *default_list)
503 krb5_enctype *etypes;
504 krb5_error_code code;
510 /* Use application defaults. */
511 code = krb5int_copy_etypes(ctx_list, &etypes);
515 /* Parse profile setting, or "DEFAULT" if not specified. */
516 code = profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
517 profkey, NULL, "DEFAULT", &profstr);
520 code = krb5int_parse_enctype_list(context, profkey, profstr,
521 default_list, &etypes);
522 profile_release_string(profstr);
527 if (etypes[0] == 0) {
529 return KRB5_CONFIG_ETYPE_NOSUPP;
532 *etypes_ptr = etypes;
537 krb5_get_default_in_tkt_ktypes(krb5_context context, krb5_enctype **ktypes)
539 return get_profile_etype_list(context, ktypes,
540 KRB5_CONF_DEFAULT_TKT_ENCTYPES,
541 context->in_tkt_etypes,
542 default_enctype_list);
547 krb5_free_ktypes (krb5_context context, krb5_enctype *val)
554 krb5_get_tgs_ktypes(krb5_context context, krb5_const_principal princ, krb5_enctype **ktypes)
556 if (context->use_conf_ktypes)
557 /* This one is set *only* by reading the config file; it's not
558 set by the application. */
559 return get_profile_etype_list(context, ktypes,
560 KRB5_CONF_DEFAULT_TKT_ENCTYPES, NULL,
561 default_enctype_list);
563 return get_profile_etype_list(context, ktypes,
564 KRB5_CONF_DEFAULT_TGS_ENCTYPES,
566 default_enctype_list);
569 krb5_error_code KRB5_CALLCONV
570 krb5_get_permitted_enctypes(krb5_context context, krb5_enctype **ktypes)
572 return get_profile_etype_list(context, ktypes,
573 KRB5_CONF_PERMITTED_ENCTYPES,
574 context->tgs_etypes, default_enctype_list);
578 krb5_is_permitted_enctype(krb5_context context, krb5_enctype etype)
580 krb5_enctype *list, *ptr;
583 if (krb5_get_permitted_enctypes(context, &list))
589 for (ptr = list; *ptr; ptr++)
593 krb5_free_ktypes (context, list);
598 /* The same as krb5_is_permitted_enctype, but verifies multiple etype's
599 * Returns 0 is either the list of the permitted enc types is not available
600 * or all requested etypes are not permitted. Otherwise returns 1.
604 krb5_is_permitted_enctype_ext ( krb5_context context,
605 krb5_etypes_permitted *etypes)
607 krb5_enctype *list, *ptr;
608 krb5_boolean ret = 0;
611 if (krb5_get_permitted_enctypes(context, &list))
614 for ( i=0; i< etypes->etype_count; i++ )
616 for (ptr = list; *ptr; ptr++)
618 if (*ptr == etypes->etype[i])
620 etypes->etype_ok[i] = TRUE;
625 krb5_free_ktypes (context, list);