1 /* 2 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 #pragma ident "%Z%%M% %I% %E% SMI" 7 8 /* 9 * lib/krb5/krb/init_ctx.c 10 * 11 * Copyright 1994,1999,2000 by the Massachusetts Institute of Technology. 12 * All Rights Reserved. 13 * 14 * Export of this software from the United States of America may 15 * require a specific license from the United States Government. 16 * It is the responsibility of any person or organization contemplating 17 * export to obtain such a license before exporting. 18 * 19 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 20 * distribute this software and its documentation for any purpose and 21 * without fee is hereby granted, provided that the above copyright 22 * notice appear in all copies and that both that copyright notice and 23 * this permission notice appear in supporting documentation, and that 24 * the name of M.I.T. not be used in advertising or publicity pertaining 25 * to distribution of the software without specific, written prior 26 * permission. Furthermore if you modify this software you must label 27 * your software as modified software and not distribute it in such a 28 * fashion that it might be confused with the original M.I.T. software. 29 * M.I.T. makes no representations about the suitability of 30 * this software for any purpose. It is provided "as is" without express 31 * or implied warranty. 32 * 33 * krb5_init_contex() 34 */ 35 36 /* 37 * Copyright (C) 1998 by the FundsXpress, INC. 38 * 39 * All rights reserved. 40 * 41 * Export of this software from the United States of America may require 42 * a specific license from the United States Government. It is the 43 * responsibility of any person or organization contemplating export to 44 * obtain such a license before exporting. 45 * 46 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 47 * distribute this software and its documentation for any purpose and 48 * without fee is hereby granted, provided that the above copyright 49 * notice appear in all copies and that both that copyright notice and 50 * this permission notice appear in supporting documentation, and that 51 * the name of FundsXpress. not be used in advertising or publicity pertaining 52 * to distribution of the software without specific, written prior 53 * permission. FundsXpress makes no representations about the suitability of 54 * this software for any purpose. It is provided "as is" without express 55 * or implied warranty. 56 * 57 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 58 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 59 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 60 */ 61 62 #include <k5-int.h> 63 64 /* 65 * Solaris Kerberos: the code related to EF/pkcs11 and fork safety are mods Sun 66 * has made to the MIT code. 67 */ 68 69 #ifndef _KERNEL 70 #include <ctype.h> 71 72 pid_t __krb5_current_pid; /* fork safety: contains the current process ID */ 73 #endif 74 75 /* The only functions that are needed from this file when in kernel are 76 * krb5_init_context and krb5_free_context. 77 * In krb5_init_context we need only os_init_context since we don'it need the 78 * profile info unless we do init/accept in kernel. Currently only mport, 79 * delete , sign/verify, wrap/unwrap routines are ported to the kernel. 80 */ 81 82 #if (defined(_MSDOS) || defined(_WIN32)) 83 extern krb5_error_code krb5_vercheck(); 84 extern void krb5_win_ccdll_load(krb5_context context); 85 #endif 86 87 static krb5_error_code init_common (); 88 89 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 90 krb5_init_context(context) 91 krb5_context *context; 92 { 93 return init_common (context, FALSE); 94 } 95 96 KRB5_DLLIMP krb5_error_code KRB5_CALLCONV 97 krb5_init_secure_context(context) 98 krb5_context *context; 99 { 100 return init_common (context, TRUE); 101 } 102 103 #ifndef _KERNEL 104 krb5_error_code 105 krb5_open_pkcs11_session(CK_SESSION_HANDLE *hSession) 106 { 107 krb5_error_code retval = 0; 108 CK_RV rv; 109 CK_SLOT_ID_PTR slotlist = NULL_PTR; 110 CK_ULONG slotcount; 111 CK_ULONG i; 112 113 /* List of all Slots */ 114 rv = C_GetSlotList(FALSE, NULL_PTR, &slotcount); 115 if (rv != CKR_OK) { 116 KRB5_LOG(KRB5_ERR, "C_GetSlotList failed with 0x%x.", rv); 117 retval = PKCS_ERR; 118 goto cleanup; 119 } 120 121 if (slotcount == 0) { 122 KRB5_LOG0(KRB5_ERR, "No slot is found in PKCS11."); 123 retval = PKCS_ERR; 124 goto cleanup; 125 } 126 127 slotlist = (CK_SLOT_ID_PTR)malloc(slotcount * sizeof(CK_SLOT_ID)); 128 if (slotlist == NULL) { 129 KRB5_LOG0(KRB5_ERR, "malloc failed for slotcount."); 130 retval = PKCS_ERR; 131 goto cleanup; 132 } 133 134 rv = C_GetSlotList(FALSE, slotlist, &slotcount); 135 if (rv != CKR_OK) { 136 KRB5_LOG(KRB5_ERR, "C_GetSlotList failed with 0x%x", rv); 137 retval = PKCS_ERR; 138 goto cleanup; 139 } 140 for (i = 0; i < slotcount; i++) { 141 if (slot_supports_krb5(slotlist + i)) 142 break; 143 } 144 if (i == slotcount){ 145 KRB5_LOG0(KRB5_ERR, "Could not find slot which supports " 146 "Kerberos"); 147 retval = PKCS_ERR; 148 goto cleanup; 149 } 150 rv = C_OpenSession(slotlist[i], CKF_SERIAL_SESSION, NULL_PTR, NULL_PTR, 151 hSession); 152 if (rv != CKR_OK) { 153 retval = PKCS_ERR; 154 } 155 cleanup: 156 if (slotlist != NULL) 157 free(slotlist); 158 return(retval); 159 } 160 161 /* 162 * krb5_reinit_ef_handle() 163 * 164 * deal with fork safety issue regarding the krb ctx and the pkcs11 hSession 165 * field. This function is called if it is determined that the krb ctx hSession 166 * is being accessed in a child process after a fork(). This function 167 * re-initilizes the pkcs11 session and returns the session handle. 168 */ 169 CK_SESSION_HANDLE 170 krb5_reinit_ef_handle(krb5_context ctx) 171 { 172 ctx->cryptoki_initialized = FALSE; 173 174 if (krb5_init_ef_handle(ctx) != 0) { 175 /* 176 * krb5_free_ef_handle() not needed here -- we assume that an equivalent 177 * of C_Finalize() was done in the child-side of the fork(), so all EF 178 * resources in this context will be invalid. 179 */ 180 return(CK_INVALID_HANDLE); 181 } 182 183 /* reset the ctx pid since we're in a new process (child) */ 184 ctx->pid = __krb5_current_pid; 185 186 /* If the RC4 handles were initialized, reset them here */ 187 if (ctx->arcfour_ctx.initialized) { 188 krb5_error_code ret; 189 ret = krb5_open_pkcs11_session(&ctx->arcfour_ctx.eSession); 190 if (ret) { 191 ctx->arcfour_ctx.initialized = 0; 192 ctx->arcfour_ctx.eSession = CK_INVALID_HANDLE; 193 C_CloseSession(ctx->hSession); 194 ctx->hSession = CK_INVALID_HANDLE; 195 } 196 ret = krb5_open_pkcs11_session(&ctx->arcfour_ctx.dSession); 197 if (ret) { 198 ctx->arcfour_ctx.initialized = 0; 199 ctx->arcfour_ctx.eSession = CK_INVALID_HANDLE; 200 ctx->arcfour_ctx.dSession = CK_INVALID_HANDLE; 201 C_CloseSession(ctx->hSession); 202 ctx->hSession = CK_INVALID_HANDLE; 203 } 204 } 205 206 /* 207 * It is safe for this function to access ctx->hSession directly. Do 208 * NOT use the krb_ctx_hSession() here. 209 */ 210 return(ctx->hSession); 211 } 212 213 /* 214 * krb5_pthread_atfork_child_handler() sets a global that indicates the current 215 * PID. This is an optimization to keep getpid() from being called a zillion 216 * times. 217 */ 218 void 219 krb5_pthread_atfork_child_handler() 220 { 221 /* 222 * __krb5_current_pid should always be set to current process ID, see the 223 * definition of krb_ctx_hSession() for more info 224 */ 225 __krb5_current_pid = getpid(); 226 } 227 228 /* 229 * krb5_ld_init() contains code that will be executed at load time (via the 230 * ld -zinitarray directive). 231 */ 232 void 233 krb5_ld_init() 234 { 235 /* 236 * fork safety: __krb5_current_pid should always be set to current process 237 * ID, see the definition of krb_ctx_hSession() for more info 238 */ 239 __krb5_current_pid = getpid(); 240 /* 241 * The child handler below will help reduce the number of times getpid() is 242 * called by updating a global PID var. with the current PID whenever a fork 243 * occurrs. 244 */ 245 (void) pthread_atfork(NULL, NULL, krb5_pthread_atfork_child_handler); 246 } 247 #endif /* !_KERNEL */ 248 249 krb5_error_code 250 krb5_init_ef_handle(krb5_context ctx) 251 { 252 krb5_error_code retval = 0; 253 #ifndef _KERNEL 254 CK_RV rv = C_Initialize(NULL_PTR); 255 if ((rv != CKR_OK) && (rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 256 KRB5_LOG(KRB5_ERR, "C_Initialize failed with 0x%x.", rv); 257 return (PKCS_ERR); 258 259 } 260 /* 261 * It is safe for this function to access ctx->hSession directly. Do 262 * NOT use the krb_ctx_hSession() here. 263 */ 264 retval = krb5_open_pkcs11_session(&ctx->hSession); 265 if (retval != 0) 266 return (retval); 267 268 ctx->cryptoki_initialized = TRUE; 269 #else /* ! _KERNEL */ 270 ctx->kef_cipher_mt = CRYPTO_MECH_INVALID; 271 ctx->kef_hash_mt = CRYPTO_MECH_INVALID; 272 ctx->kef_cksum_mt = CRYPTO_MECH_INVALID; 273 274 setup_kef_keytypes(); 275 setup_kef_cksumtypes(); 276 277 #endif /* ! _KERNEL */ 278 return(retval); 279 } 280 281 #ifndef _KERNEL 282 krb5_error_code 283 krb5_free_ef_handle(krb5_context ctx) 284 { 285 /* 286 * fork safety: Don't free any PKCS state if we've forked since 287 * allocating the pkcs handles. 288 */ 289 if (ctx->cryptoki_initialized == TRUE && 290 ctx->pid == __krb5_current_pid) { 291 /* 292 * It is safe for this function to access ctx->hSession 293 * directly. Do NOT use the krb_ctx_hSession() here. 294 */ 295 if (ctx->hSession) { 296 C_CloseSession(ctx->hSession); 297 ctx->hSession = 0; 298 } 299 if (ctx->arcfour_ctx.dKey) { 300 C_DestroyObject(ctx->arcfour_ctx.dSession, 301 ctx->arcfour_ctx.dKey); 302 ctx->arcfour_ctx.dKey = 0; 303 } 304 if (ctx->arcfour_ctx.eKey) { 305 C_DestroyObject(ctx->arcfour_ctx.eSession, 306 ctx->arcfour_ctx.eKey); 307 ctx->arcfour_ctx.eKey = 0; 308 } 309 if (ctx->arcfour_ctx.eSession) { 310 C_CloseSession(ctx->arcfour_ctx.eSession); 311 ctx->arcfour_ctx.eSession = 0; 312 } 313 if (ctx->arcfour_ctx.dSession) { 314 C_CloseSession(ctx->arcfour_ctx.dSession); 315 ctx->arcfour_ctx.eSession = 0; 316 } 317 ctx->arcfour_ctx.initialized = 0; 318 319 ctx->cryptoki_initialized = FALSE; 320 } 321 return(0); 322 } 323 #endif /* !_KERNEL */ 324 325 static krb5_error_code 326 init_common (context, secure) 327 krb5_context *context; 328 krb5_boolean secure; 329 { 330 krb5_context ctx = 0; 331 krb5_error_code retval; 332 #ifndef _KERNEL 333 struct { 334 krb5_int32 now, now_usec; 335 long pid; 336 } seed_data; 337 krb5_data seed; 338 int tmp; 339 #endif 340 341 #if (defined(_MSDOS) || defined(_WIN32)) 342 /* 343 * Load the krbcc32.dll if necessary. We do this here so that 344 * we know to use API: later on during initialization. 345 * The context being NULL is ok. 346 */ 347 krb5_win_ccdll_load(ctx); 348 349 /* 350 * krb5_vercheck() is defined in win_glue.c, and this is 351 * where we handle the timebomb and version server checks. 352 */ 353 retval = krb5_vercheck(); 354 if (retval) 355 return retval; 356 #endif 357 358 *context = 0; 359 360 ctx = MALLOC(sizeof(struct _krb5_context)); 361 if (!ctx) 362 return ENOMEM; 363 (void) memset(ctx, 0, sizeof(struct _krb5_context)); 364 ctx->magic = KV5M_CONTEXT; 365 366 ctx->profile_secure = secure; 367 368 if ((retval = krb5_os_init_context(ctx))) 369 goto cleanup; 370 371 /* 372 * Initialize the EF handle, its needed before doing 373 * the random seed. 374 */ 375 if ((retval = krb5_init_ef_handle(ctx))) 376 goto cleanup; 377 378 #ifndef _KERNEL 379 380 /* fork safety: set pid to current process ID for later checking */ 381 ctx->pid = __krb5_current_pid; 382 383 /* Set the default encryption types, possible defined in krb5/conf */ 384 if ((retval = krb5_set_default_in_tkt_ktypes(ctx, NULL))) 385 goto cleanup; 386 387 if ((retval = krb5_set_default_tgs_ktypes(ctx, NULL))) 388 goto cleanup; 389 390 ctx->conf_tgs_ktypes = MALLOC(ctx->tgs_ktype_count * sizeof(krb5_enctype)); 391 if (ctx->conf_tgs_ktypes == NULL && ctx->tgs_ktype_count != 0) 392 goto cleanup; 393 394 (void) memcpy(ctx->conf_tgs_ktypes, ctx->tgs_ktypes, 395 sizeof(krb5_enctype) * ctx->tgs_ktype_count); 396 397 ctx->conf_tgs_ktypes_count = ctx->tgs_ktype_count; 398 399 400 /* initialize the prng (not well, but passable) */ 401 if ((retval = krb5_crypto_us_timeofday(&seed_data.now, &seed_data.now_usec))) 402 goto cleanup; 403 seed_data.pid = getpid (); 404 seed.length = sizeof(seed_data); 405 seed.data = (char *) &seed_data; 406 if ((retval = krb5_c_random_seed(ctx, &seed))) 407 /* 408 * Solaris Kerberos: we use /dev/urandom, which is 409 * automatically seeded, so its OK if this fails. 410 */ 411 retval = 0; 412 413 ctx->default_realm = 0; 414 profile_get_integer(ctx->profile, "libdefaults", "clockskew", 415 0, 5 * 60, &tmp); 416 ctx->clockskew = tmp; 417 418 #if 0 419 /* Default ticket lifetime is currently not supported */ 420 profile_get_integer(ctx->profile, "libdefaults", "tkt_lifetime", 421 0, 10 * 60 * 60, &tmp); 422 ctx->tkt_lifetime = tmp; 423 #endif 424 425 /* DCE 1.1 and below only support CKSUMTYPE_RSA_MD4 (2) */ 426 /* DCE add kdc_req_checksum_type = 2 to krb5.conf */ 427 profile_get_integer(ctx->profile, "libdefaults", 428 "kdc_req_checksum_type", 0, CKSUMTYPE_RSA_MD5, 429 &tmp); 430 ctx->kdc_req_sumtype = tmp; 431 432 profile_get_integer(ctx->profile, "libdefaults", 433 "ap_req_checksum_type", 0, CKSUMTYPE_RSA_MD5, 434 &tmp); 435 ctx->default_ap_req_sumtype = tmp; 436 437 profile_get_integer(ctx->profile, "libdefaults", 438 "safe_checksum_type", 0, 439 CKSUMTYPE_RSA_MD5_DES, &tmp); 440 ctx->default_safe_sumtype = tmp; 441 442 profile_get_integer(ctx->profile, "libdefaults", 443 "kdc_default_options", 0, 444 KDC_OPT_RENEWABLE_OK, &tmp); 445 ctx->kdc_default_options = KDC_OPT_RENEWABLE_OK; 446 #ifdef macintosh 447 #define DEFAULT_KDC_TIMESYNC 1 448 #else 449 #define DEFAULT_KDC_TIMESYNC 0 450 #endif 451 profile_get_integer(ctx->profile, "libdefaults", 452 "kdc_timesync", 0, DEFAULT_KDC_TIMESYNC, 453 &tmp); 454 ctx->library_options = tmp ? KRB5_LIBOPT_SYNC_KDCTIME : 0; 455 456 /* 457 * We use a default file credentials cache of 3. See 458 * lib/krb5/krb/ccache/file/fcc.h for a description of the 459 * credentials cache types. 460 * 461 * Note: DCE 1.0.3a only supports a cache type of 1 462 * DCE 1.1 supports a cache type of 2. 463 */ 464 #ifdef macintosh 465 #define DEFAULT_CCACHE_TYPE 4 466 #else 467 #define DEFAULT_CCACHE_TYPE 3 468 #endif 469 profile_get_integer(ctx->profile, "libdefaults", "ccache_type", 470 0, DEFAULT_CCACHE_TYPE, &tmp); 471 ctx->fcc_default_format = tmp + 0x0500; 472 ctx->scc_default_format = tmp + 0x0500; 473 ctx->prompt_types = 0; 474 ctx->use_conf_ktypes = 0; 475 476 /* 477 * Solaris Kerberos: simplifying config by hard-coding udp_pref_limit 478 */ 479 ctx->udp_pref_limit = DEFAULT_UDP_PREF_LIMIT; 480 481 #endif /* !_KERNEL */ 482 483 *context = ctx; 484 return 0; 485 486 cleanup: 487 krb5_free_context(ctx); 488 return retval; 489 } 490 491 KRB5_DLLIMP void KRB5_CALLCONV 492 krb5_free_context(ctx) 493 krb5_context ctx; 494 { 495 KRB5_LOG0(KRB5_INFO,"krb5_free_context() start"); 496 497 #ifndef _KERNEL 498 krb5_free_ef_handle(ctx); 499 500 if (ctx->conf_tgs_ktypes) { 501 FREE(ctx->conf_tgs_ktypes, sizeof(krb5_enctype) *(ctx->conf_tgs_ktypes_count)); 502 ctx->conf_tgs_ktypes = 0; 503 ctx->conf_tgs_ktypes_count = 0; 504 } 505 506 #endif 507 krb5_os_free_context(ctx); 508 509 if (ctx->in_tkt_ktypes) { 510 FREE(ctx->in_tkt_ktypes, sizeof(krb5_enctype) *(ctx->in_tkt_ktype_count+1) ); 511 ctx->in_tkt_ktypes = 0; 512 } 513 514 if (ctx->tgs_ktypes) { 515 FREE(ctx->tgs_ktypes, sizeof(krb5_enctype) *(ctx->tgs_ktype_count+1)); 516 ctx->tgs_ktypes = 0; 517 } 518 519 if (ctx->default_realm) { 520 FREE(ctx->default_realm, strlen(ctx->default_realm) + 1); 521 ctx->default_realm = 0; 522 } 523 524 if (ctx->ser_ctx_count && ctx->ser_ctx) { 525 FREE(ctx->ser_ctx,sizeof(krb5_ser_entry) * (ctx->ser_ctx_count) ); 526 ctx->ser_ctx = 0; 527 ctx->ser_ctx_count = 0; 528 } 529 530 ctx->magic = 0; 531 FREE(ctx, sizeof(struct _krb5_context)); 532 533 } 534 535 #ifndef _KERNEL 536 /* 537 * Set the desired default ktypes, making sure they are valid. 538 */ 539 krb5_error_code 540 krb5_set_default_in_tkt_ktypes(context, ktypes) 541 krb5_context context; 542 const krb5_enctype *ktypes; 543 { 544 krb5_enctype * new_ktypes; 545 int i; 546 547 if (ktypes) { 548 for (i = 0; ktypes[i]; i++) { 549 if (!valid_enctype(ktypes[i])) 550 return KRB5_PROG_ETYPE_NOSUPP; 551 } 552 553 /* Now copy the default ktypes into the context pointer */ 554 if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i))) 555 (void) memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i); 556 else 557 return ENOMEM; 558 559 } else { 560 i = 0; 561 new_ktypes = 0; 562 } 563 564 if (context->in_tkt_ktypes) 565 free(context->in_tkt_ktypes); 566 context->in_tkt_ktypes = new_ktypes; 567 context->in_tkt_ktype_count = i; 568 return 0; 569 } 570 571 static krb5_error_code 572 get_profile_etype_list(context, ktypes, profstr, ctx_count, ctx_list) 573 krb5_context context; 574 krb5_enctype **ktypes; 575 char *profstr; 576 int ctx_count; 577 krb5_enctype *ctx_list; 578 { 579 krb5_enctype *old_ktypes = NULL; 580 581 if (ctx_count) { 582 /* application-set defaults */ 583 if ((old_ktypes = 584 (krb5_enctype *)malloc(sizeof(krb5_enctype) * 585 (ctx_count + 1)))) { 586 (void) memcpy(old_ktypes, ctx_list, 587 sizeof(krb5_enctype) * ctx_count); 588 old_ktypes[ctx_count] = 0; 589 } else { 590 return ENOMEM; 591 } 592 } else { 593 /* 594 XXX - For now, we only support libdefaults 595 Perhaps this should be extended to allow for per-host / per-realm 596 session key types. 597 */ 598 599 char *retval; 600 char *sp, *ep; 601 int j, checked_enctypes, count; 602 krb5_error_code code; 603 604 code = profile_get_string(context->profile, "libdefaults", profstr, 605 NULL, 606 "aes256-cts-hmac-sha1-96 " 607 "aes128-cts-hmac-sha1-96 " 608 "des3-hmac-sha1 " 609 "arcfour-hmac-md5 " 610 "des-cbc-md5 " 611 "des-cbc-crc", 612 &retval); 613 if (code) 614 return code; 615 616 count = 0; 617 sp = retval; 618 while (sp) { 619 for (ep = sp; *ep && (*ep != ',') && !isspace(*ep); ep++) 620 ; 621 if (*ep) { 622 *ep++ = '\0'; 623 while (isspace(*ep)) 624 ep++; 625 } else 626 ep = (char *) NULL; 627 628 count++; 629 sp = ep; 630 } 631 632 if ((old_ktypes = 633 (krb5_enctype *)malloc(sizeof(krb5_enctype) * (count + 1))) == 634 (krb5_enctype *) NULL) 635 return ENOMEM; 636 637 sp = retval; 638 j = checked_enctypes = 0; 639 /*CONSTCOND*/ 640 while (TRUE) { 641 checked_enctypes++; 642 if (krb5_string_to_enctype(sp, &old_ktypes[j])) 643 old_ktypes[j] = (unsigned int)ENCTYPE_UNKNOWN; 644 645 /* 646 * If 'null' has been specified as a tkt_enctype in 647 * krb5.conf, we need to assign an ENCTYPE_UNKNOWN 648 * value to the corresponding old_ktypes[j] entry. 649 */ 650 if (old_ktypes[j] == (unsigned int)ENCTYPE_NULL) 651 old_ktypes[j] = (unsigned int)ENCTYPE_UNKNOWN; 652 653 /* Only include known/valid enctypes in the final list */ 654 if (old_ktypes[j] != ENCTYPE_UNKNOWN) { 655 j++; 656 } 657 /* If we checked all the enctypes, we are done */ 658 if (checked_enctypes == count) { 659 break; 660 } 661 662 /* skip to next token */ 663 while (*sp) sp++; 664 while (!*sp) sp++; 665 } 666 667 old_ktypes[j] = (krb5_enctype) 0; 668 profile_release_string(retval); 669 } 670 671 if (old_ktypes[0] == 0) { 672 free (old_ktypes); 673 *ktypes = 0; 674 return KRB5_CONFIG_ETYPE_NOSUPP; 675 } 676 677 678 679 *ktypes = old_ktypes; 680 return 0; 681 } 682 683 krb5_error_code 684 krb5_get_default_in_tkt_ktypes(context, ktypes) 685 krb5_context context; 686 krb5_enctype **ktypes; 687 { 688 return(get_profile_etype_list(context, ktypes, "default_tkt_enctypes", 689 context->in_tkt_ktype_count, 690 context->in_tkt_ktypes)); 691 } 692 693 krb5_error_code 694 krb5_set_default_tgs_enctypes(context, ktypes) 695 krb5_context context; 696 const krb5_enctype *ktypes; 697 { 698 krb5_enctype * new_ktypes; 699 int i; 700 701 if (ktypes) { 702 for (i = 0; ktypes[i]; i++) { 703 if (!valid_enctype(ktypes[i])) 704 return KRB5_PROG_ETYPE_NOSUPP; 705 } 706 707 /* Now copy the default ktypes into the context pointer */ 708 if ((new_ktypes = (krb5_enctype *)malloc(sizeof(krb5_enctype) * i))) 709 (void) memcpy(new_ktypes, ktypes, sizeof(krb5_enctype) * i); 710 else 711 return ENOMEM; 712 713 } else { 714 i = 0; 715 new_ktypes = (krb5_enctype *)NULL; 716 } 717 718 if (context->tgs_ktypes) 719 krb5_free_ktypes(context, context->tgs_ktypes); 720 context->tgs_ktypes = new_ktypes; 721 context->tgs_ktype_count = i; 722 return 0; 723 } 724 725 krb5_error_code krb5_set_default_tgs_ktypes 726 (krb5_context context, const krb5_enctype *etypes) 727 { 728 return (krb5_set_default_tgs_enctypes (context, etypes)); 729 } 730 731 732 733 734 /*ARGSUSED*/ 735 void 736 KRB5_CALLCONV 737 krb5_free_ktypes (context, val) 738 krb5_context context; 739 krb5_enctype FAR *val; 740 { 741 free (val); 742 } 743 744 /*ARGSUSED*/ 745 krb5_error_code 746 KRB5_CALLCONV 747 krb5_get_tgs_ktypes(context, princ, ktypes) 748 krb5_context context; 749 krb5_const_principal princ; 750 krb5_enctype **ktypes; 751 { 752 if (context->use_conf_ktypes) 753 /* This one is set *only* by reading the config file; it's not 754 set by the application. */ 755 return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes", 756 context->conf_tgs_ktypes_count, 757 context->conf_tgs_ktypes)); 758 else 759 return(get_profile_etype_list(context, ktypes, "default_tgs_enctypes", 760 context->tgs_ktype_count, 761 context->tgs_ktypes)); 762 } 763 764 krb5_error_code 765 krb5_get_permitted_enctypes(context, ktypes) 766 krb5_context context; 767 krb5_enctype **ktypes; 768 { 769 return(get_profile_etype_list(context, ktypes, "permitted_enctypes", 770 context->tgs_ktype_count, 771 context->tgs_ktypes)); 772 } 773 774 krb5_boolean 775 krb5_is_permitted_enctype(context, etype) 776 krb5_context context; 777 krb5_enctype etype; 778 { 779 krb5_enctype *list, *ptr; 780 krb5_boolean ret; 781 782 if (krb5_get_permitted_enctypes(context, &list)) 783 return(0); 784 785 786 ret = 0; 787 788 for (ptr = list; *ptr; ptr++) 789 if (*ptr == etype) 790 ret = 1; 791 792 krb5_free_ktypes (context, list); 793 794 return(ret); 795 } 796 #endif /* !KERNEL */ 797