Coverage Report

Created: 2023-11-19 06:40

/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
}