1/* 2 * Copyright (c) 2008-2010 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Portions Copyright (c) 2008-2010 Apple Inc. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "heim.h" 37#include <string.h> 38#include <errno.h> 39#include <stdio.h> 40#include <stdarg.h> 41#include <stdlib.h> 42#include <pthread.h> 43 44#include <dispatch/dispatch.h> 45 46#include <CommonCrypto/CommonDigest.h> 47#include <CoreFoundation/CoreFoundation.h> 48#include <Heimdal/gkrb5_err.h> 49#include <Heimdal/wind_err.h> 50#include <Heimdal/krb_err.h> 51#include <Heimdal/hx509_err.h> 52 53const char *__KerberosInternal_krb5_defkeyname = "FILE:/etc/krb5.keytab"; 54 55int krb5_use_broken_arcfour_string2key = 0; 56 57static int do_log = 0; 58 59static CFTypeRef 60CopyKeyFromFile(CFStringRef domain, CFStringRef key) 61{ 62 CFReadStreamRef s; 63 CFDictionaryRef d; 64 CFStringRef file; 65 CFErrorRef e; 66 CFURLRef url; 67 CFTypeRef val; 68 69 file = CFStringCreateWithFormat(NULL, 0, CFSTR("/Library/Preferences/%@.plist"), domain); 70 if (file == NULL) 71 return NULL; 72 73 url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, domain, kCFURLPOSIXPathStyle, false); 74 CFRelease(file); 75 if (url == NULL) 76 return NULL; 77 78 s = CFReadStreamCreateWithFile(kCFAllocatorDefault, url); 79 CFRelease(url); 80 if (s == NULL) 81 return NULL; 82 83 if (!CFReadStreamOpen(s)) { 84 CFRelease(s); 85 return NULL; 86 } 87 88 d = (CFDictionaryRef)CFPropertyListCreateWithStream (kCFAllocatorDefault, s, 0, kCFPropertyListImmutable, NULL, &e); 89 CFRelease(s); 90 if (d == NULL) 91 return NULL; 92 93 if (CFGetTypeID(d) != CFDictionaryGetTypeID()) { 94 CFRelease(d); 95 return NULL; 96 } 97 98 val = CFDictionaryGetValue(d, key); 99 if (val) 100 CFRetain(val); 101 CFRelease(d); 102 return val; 103} 104 105static void 106init_log(void) 107{ 108 static dispatch_once_t once = 0; 109 dispatch_once(&once, ^{ 110 CFBooleanRef b; 111 b = CopyKeyFromFile(CFSTR("com.apple.MITKerberosShim"), 112 CFSTR("EnableDebugging")); 113 if (b && CFGetTypeID(b) == CFBooleanGetTypeID()) 114 do_log = CFBooleanGetValue(b); 115 if (b) 116 CFRelease(b); 117 }); 118} 119 120void 121mshim_log_entry(const char *msg, ...) 122{ 123 init_log(); 124 125 if (do_log) { 126 va_list ap; 127 va_start(ap, msg); 128 vsyslog(LOG_DEBUG, msg, ap); 129 va_end(ap); 130 } 131} 132 133int 134mshim_failure(const char *func, int error, const char *subsystem) 135{ 136 init_log(); 137 138 if (do_log && error) 139 syslog(LOG_DEBUG, "%s failed with %d for '%s'", func, error, subsystem); 140 return error; 141} 142 143static void 144destroy_ctx(void *ptr) 145{ 146 heim_krb5_free_context(ptr); 147} 148 149krb5_context 150mshim_ctx(void) 151{ 152 static dispatch_once_t once; 153 static pthread_key_t key; 154 krb5_context ctx = NULL; 155 156 dispatch_once(&once, ^{ 157 if (pthread_key_create(&key, destroy_ctx) != 0) 158 abort(); 159 }); 160 161 ctx = pthread_getspecific(key); 162 if (ctx == NULL) { 163 krb5_error_code ret; 164 165 ret = heim_krb5_init_context(&ctx); 166 if (ret) 167 ret = heim_krb5_init_context_flags(KRB5_CONTEXT_FLAG_NO_CONFIG, &ctx); 168 169 if (ret) { 170 syslog(LOG_ERR, "Failed to create kerberos context for thread (milcontext): %d", ret); 171 abort(); 172 } 173 174 pthread_setspecific(key, ctx); 175 } 176 return ctx; 177} 178 179 180void * 181mshim_malloc(size_t size) 182{ 183 void *ptr = malloc(size); 184 if (ptr == NULL) { 185 syslog(LOG_DEBUG, "mshim_malloc: can't allocate %d", (int)size); 186 abort(); 187 } 188 memset(ptr, 0, size); 189 return ptr; 190} 191 192krb5_error_code 193mshim_hdata2mdata(const krb5_data *h, mit_krb5_data *m) 194{ 195 m->magic = MIT_KV5M_DATA; 196 m->length = h->length; 197 m->data = mshim_malloc(h->length); 198 memcpy(m->data, h->data, h->length); 199 return 0; 200} 201 202 203krb5_error_code 204mshim_mdata2hdata(const mit_krb5_data *m, krb5_data *h) 205{ 206 h->length = m->length; 207 h->data = mshim_malloc(m->length); 208 memcpy(h->data, m->data, m->length); 209 return 0; 210} 211 212void 213mshim_hkeyblock2mkeyblock(const krb5_keyblock *h, mit_krb5_keyblock *m) 214{ 215 m->magic = MIT_KV5M_KEYBLOCK; 216 m->enctype = h->keytype; 217 m->length = h->keyvalue.length; 218 m->contents = mshim_malloc(h->keyvalue.length); 219 memcpy(m->contents, h->keyvalue.data, h->keyvalue.length); 220} 221 222void 223mshim_mkeyblock2hkeyblock(const mit_krb5_keyblock *m, krb5_keyblock *h) 224{ 225 h->keytype = m->enctype; 226 h->keyvalue.length = m->length; 227 h->keyvalue.data = mshim_malloc(h->keyvalue.length); 228 memcpy(h->keyvalue.data, m->contents, h->keyvalue.length); 229} 230 231 232mit_krb5_error_code KRB5_CALLCONV 233krb5_copy_keyblock_contents(mit_krb5_context context, 234 const mit_krb5_keyblock *from, 235 mit_krb5_keyblock *to) 236{ 237 LOG_ENTRY(); 238 to->magic = MIT_KV5M_KEYBLOCK; 239 to->enctype = from->enctype; 240 to->length = from->length; 241 to->contents = mshim_malloc(from->length); 242 memcpy(to->contents, from->contents, from->length); 243 return 0; 244} 245 246mit_krb5_error_code KRB5_CALLCONV 247krb5_copy_keyblock(mit_krb5_context context, 248 const mit_krb5_keyblock *from, 249 mit_krb5_keyblock **to) 250{ 251 LOG_ENTRY(); 252 *to = mshim_malloc(sizeof(**to)); 253 return krb5_copy_keyblock_contents(context, from, *to); 254} 255 256 257 258void 259mshim_mcred2hcred(krb5_context context, mit_krb5_creds *m, krb5_creds *h) 260{ 261 struct comb_principal *p; 262 memset(h, 0, sizeof(*h)); 263 264 p = (struct comb_principal *)m->client; 265 if (p) 266 heim_krb5_copy_principal(context, p->heim, &h->client); 267 p = (struct comb_principal *)m->server; 268 if (p) 269 heim_krb5_copy_principal(context, p->heim, &h->server); 270 271 h->session.keytype = m->keyblock.enctype; 272 heim_krb5_data_copy(&h->session.keyvalue, m->keyblock.contents, m->keyblock.length); 273 274 heim_krb5_data_copy(&h->ticket, m->ticket.data, m->ticket.length); 275 276 h->times.authtime = m->times.authtime; 277 h->times.starttime = m->times.starttime; 278 h->times.endtime = m->times.endtime; 279 h->times.renew_till = m->times.renew_till; 280 281 h->flags.i = 0; 282 if (m->ticket_flags & MIT_TKT_FLG_FORWARDABLE) 283 h->flags.b.forwardable = 1; 284 if (m->ticket_flags & MIT_TKT_FLG_FORWARDED) 285 h->flags.b.forwarded = 1; 286 if (m->ticket_flags & MIT_TKT_FLG_PROXIABLE) 287 h->flags.b.proxiable = 1; 288 if (m->ticket_flags & MIT_TKT_FLG_PROXY) 289 h->flags.b.proxy = 1; 290 if (m->ticket_flags & MIT_TKT_FLG_MAY_POSTDATE) 291 h->flags.b.may_postdate = 1; 292 if (m->ticket_flags & MIT_TKT_FLG_POSTDATED) 293 h->flags.b.postdated = 1; 294 if (m->ticket_flags & MIT_TKT_FLG_INVALID) 295 h->flags.b.invalid = 1; 296 if (m->ticket_flags & MIT_TKT_FLG_RENEWABLE) 297 h->flags.b.renewable = 1; 298 if (m->ticket_flags & MIT_TKT_FLG_INITIAL) 299 h->flags.b.initial = 1; 300 if (m->ticket_flags & MIT_TKT_FLG_PRE_AUTH) 301 h->flags.b.pre_authent = 1; 302 if (m->ticket_flags & MIT_TKT_FLG_HW_AUTH) 303 h->flags.b.hw_authent = 1; 304 if (m->ticket_flags & MIT_TKT_FLG_TRANSIT_POLICY_CHECKED) 305 h->flags.b.transited_policy_checked = 1; 306 if (m->ticket_flags & MIT_TKT_FLG_OK_AS_DELEGATE) 307 h->flags.b.ok_as_delegate = 1; 308 if (m->ticket_flags & MIT_TKT_FLG_ANONYMOUS) 309 h->flags.b.anonymous = 1; 310 311} 312 313void 314mshim_hcred2mcred(krb5_context context, krb5_creds *h, mit_krb5_creds *m) 315{ 316 memset(m, 0, sizeof(*m)); 317 318 m->magic = MIT_KV5M_CREDS; 319 if (h->client) 320 m->client = mshim_hprinc2mprinc(context, h->client); 321 if (h->server) 322 m->server = mshim_hprinc2mprinc(context, h->server); 323 324 mshim_hkeyblock2mkeyblock(&h->session, &m->keyblock); 325 326 mshim_hdata2mdata(&h->ticket, &m->ticket); 327 328 m->times.authtime = h->times.authtime; 329 m->times.starttime = h->times.starttime; 330 m->times.endtime = h->times.endtime; 331 m->times.renew_till = h->times.renew_till; 332 333 m->ticket_flags = 0; 334 if (h->flags.b.forwardable) 335 m->ticket_flags |= MIT_TKT_FLG_FORWARDABLE; 336 if (h->flags.b.forwarded) 337 m->ticket_flags |= MIT_TKT_FLG_FORWARDED; 338 if (h->flags.b.proxiable) 339 m->ticket_flags |= MIT_TKT_FLG_PROXIABLE; 340 if (h->flags.b.proxy) 341 m->ticket_flags |= MIT_TKT_FLG_PROXY; 342 if (h->flags.b.may_postdate) 343 m->ticket_flags |= MIT_TKT_FLG_MAY_POSTDATE; 344 if (h->flags.b.postdated) 345 m->ticket_flags |= MIT_TKT_FLG_POSTDATED; 346 if (h->flags.b.invalid) 347 m->ticket_flags |= MIT_TKT_FLG_INVALID; 348 if (h->flags.b.renewable) 349 m->ticket_flags |= MIT_TKT_FLG_RENEWABLE; 350 if (h->flags.b.initial) 351 m->ticket_flags |= MIT_TKT_FLG_INITIAL; 352 if (h->flags.b.pre_authent) 353 m->ticket_flags |= MIT_TKT_FLG_PRE_AUTH; 354 if (h->flags.b.hw_authent) 355 m->ticket_flags |= MIT_TKT_FLG_HW_AUTH; 356 if (h->flags.b.transited_policy_checked) 357 m->ticket_flags |= MIT_TKT_FLG_TRANSIT_POLICY_CHECKED; 358 if (h->flags.b.ok_as_delegate) 359 m->ticket_flags |= MIT_TKT_FLG_OK_AS_DELEGATE; 360 if (h->flags.b.anonymous) 361 m->ticket_flags |= MIT_TKT_FLG_ANONYMOUS; 362} 363 364void 365mshim_haprepencpart2maprepencpart(const krb5_ap_rep_enc_part *h, 366 mit_krb5_ap_rep_enc_part *m) 367{ 368 m->magic = MIT_KV5M_AP_REP_ENC_PART; 369 m->ctime = h->ctime; 370 m->cusec = h->cusec; 371 372 if (h->subkey) { 373 m->subkey = mshim_malloc(sizeof(*m->subkey)); 374 mshim_hkeyblock2mkeyblock(h->subkey, m->subkey); 375 } else 376 m->subkey = NULL; 377 378 if (h->seq_number) { 379 m->seq_number = *h->seq_number; 380 } else 381 m->seq_number = 0; 382} 383 384void 385mshim_hreplay2mreplay(const krb5_replay_data *h, mit_krb5_replay_data *m) 386{ 387 m->timestamp = h->timestamp; 388 m->usec = h->usec; 389 m->seq = h->seq; 390} 391 392 393void KRB5_CALLCONV 394krb5_free_ap_rep_enc_part(mit_krb5_context context, 395 mit_krb5_ap_rep_enc_part *enc_part) 396{ 397 LOG_ENTRY(); 398 if (enc_part->subkey) 399 krb5_free_keyblock(context, enc_part->subkey); 400 free(enc_part); 401} 402 403void KRB5_CALLCONV 404krb5_free_error(mit_krb5_context context, mit_krb5_error *error) 405{ 406 LOG_ENTRY(); 407 krb5_free_principal(context, error->client); 408 krb5_free_principal(context, error->server); 409 krb5_free_data_contents(context, &error->text); 410 krb5_free_data_contents(context, &error->e_data); 411 free(error); 412} 413 414void 415mshim_herror2merror(krb5_context context, const krb5_error *h, mit_krb5_error *m) 416{ 417 LOG_ENTRY(); 418 memset(m, 0, sizeof(*m)); 419 420 m->magic = MIT_KV5M_ERROR; 421 if (h->ctime) 422 m->ctime = *h->ctime; 423 if (h->cusec) 424 m->cusec = *h->cusec; 425 m->stime = h->stime; 426 m->susec = h->susec; 427#if 0 428 m->client = mshim_hprinc2mprinc(context, h->client); 429 m->server = mshim_hprinc2mprinc(context, h->server); 430#endif 431 m->error = h->error_code; 432 if (h->e_text) { 433 m->text.magic = MIT_KV5M_DATA; 434 m->text.data = strdup(*(h->e_text)); 435 m->text.length = strlen(*(h->e_text)); 436 } 437 if (h->e_data) 438 mshim_hdata2mdata(h->e_data, &m->e_data); 439#if 0 440 krb5_principal client; /* client's principal identifier; 441 optional */ 442 krb5_principal server; /* server's principal identifier */ 443#endif 444} 445 446unsigned long 447mshim_remap_flags(unsigned long in, const struct mshim_map_flags *table) 448{ 449 unsigned long out = 0; 450 while(table->in) { 451 if (table->in & in) 452 out |= table->out; 453 table++; 454 } 455 return out; 456} 457 458 459mit_krb5_error_code 460krb5_init_context(mit_krb5_context *context) 461{ 462 LOG_ENTRY(); 463 return heim_krb5_init_context((krb5_context *)context); 464} 465 466mit_krb5_error_code 467krb5_init_secure_context(mit_krb5_context *context) 468{ 469 LOG_ENTRY(); 470 return heim_krb5_init_context((krb5_context *)context); 471} 472 473void 474krb5_free_context(mit_krb5_context context) 475{ 476 LOG_ENTRY(); 477 heim_krb5_free_context(HC(context)); 478} 479 480const char * 481error_message(errcode_t code) 482{ 483 static dispatch_once_t once = 0; 484 static struct et_list *et_list = NULL; 485 static char buffer[1024]; 486 const char *str; 487 488 dispatch_once(&once, ^{ 489 initialize_asn1_error_table_r(&et_list); 490 initialize_gk5_error_table_r(&et_list); 491 initialize_wind_error_table_r(&et_list); 492 initialize_krb5_error_table_r(&et_list); 493 initialize_krb_error_table_r(&et_list); 494 initialize_k524_error_table_r(&et_list); 495 initialize_heim_error_table_r(&et_list); 496 initialize_hx_error_table_r(&et_list); 497 }); 498 499 str = heim_com_right_r(et_list, code, buffer, sizeof(buffer)); 500 if (str == NULL) { 501 snprintf(buffer, sizeof(buffer), "Unknown error %d", (int)code); 502 str = buffer; 503 } 504 return str; 505} 506 507void KRB5_CALLCONV 508krb5_free_keyblock(mit_krb5_context context, mit_krb5_keyblock *keyblock) 509{ 510 LOG_ENTRY(); 511 krb5_free_keyblock_contents(context, keyblock); 512 free(keyblock); 513} 514 515void KRB5_CALLCONV 516krb5_free_keyblock_contents(mit_krb5_context context, mit_krb5_keyblock *keyblock) 517{ 518 LOG_ENTRY(); 519 memset(keyblock->contents, 0, keyblock->length); 520 free(keyblock->contents); 521 memset(keyblock, 0, sizeof(*keyblock)); 522} 523 524void KRB5_CALLCONV 525krb5_free_data(mit_krb5_context context, mit_krb5_data *data) 526{ 527 LOG_ENTRY(); 528 krb5_free_data_contents(context, data); 529 free(data); 530} 531 532void KRB5_CALLCONV 533krb5_free_data_contents(mit_krb5_context context, mit_krb5_data *data) 534{ 535 LOG_ENTRY(); 536 free(data->data); 537 memset(data, 0, sizeof(*data)); 538} 539 540mit_krb5_error_code KRB5_CALLCONV 541krb5_copy_data(mit_krb5_context context, 542 const mit_krb5_data *from, 543 mit_krb5_data **to) 544{ 545 *to = mshim_malloc(sizeof(**to)); 546 (*to)->magic = MIT_KV5M_DATA; 547 (*to)->length = from->length; 548 (*to)->data = mshim_malloc(from->length); 549 memcpy((*to)->data, from->data, from->length); 550 return 0; 551} 552 553void KRB5_CALLCONV 554krb5_free_cred_contents(mit_krb5_context context, mit_krb5_creds *cred) 555{ 556 LOG_ENTRY(); 557 if (cred == NULL) 558 return; 559 krb5_free_principal(context, cred->client); 560 krb5_free_principal(context, cred->server); 561 krb5_free_keyblock_contents(context, &cred->keyblock); 562 krb5_free_data_contents(context, &cred->ticket); 563 krb5_free_data_contents(context, &cred->second_ticket); 564 /* 565 mit_krb5_address **addresses; 566 mit_krb5_authdata **authdata; 567 */ 568 memset(cred, 0, sizeof(*cred)); 569} 570 571void KRB5_CALLCONV 572krb5_free_creds(mit_krb5_context context, mit_krb5_creds *cred) 573{ 574 LOG_ENTRY(); 575 krb5_free_cred_contents(context, cred); 576 free(cred); 577} 578 579void KRB5_CALLCONV 580krb5_free_enc_tkt_part(mit_krb5_context context, krb5_enc_tkt_part *enc_part2) 581{ 582 if (enc_part2->session) 583 krb5_free_keyblock(context, enc_part2->session); 584 if (enc_part2->client) 585 krb5_free_principal(context, enc_part2->client); 586 memset(enc_part2, 0, sizeof(*enc_part2)); 587 free(enc_part2); 588} 589 590void KRB5_CALLCONV 591krb5_free_ticket(mit_krb5_context context, mit_krb5_ticket *ticket) 592{ 593 LOG_ENTRY(); 594 if (ticket == NULL) 595 return; 596 if (ticket->server) 597 krb5_free_principal(context, ticket->server); 598 if (ticket->enc_part.ciphertext.data) 599 krb5_free_data_contents(context, &ticket->enc_part.ciphertext); 600 if (ticket->enc_part2) 601 krb5_free_enc_tkt_part(context, ticket->enc_part2); 602 memset(ticket, 0, sizeof(*ticket)); 603 free(ticket); 604} 605 606void KRB5_CALLCONV 607krb5_free_authdata(mit_krb5_context context, 608 mit_krb5_authdata **val) 609{ 610 mit_krb5_authdata **ptr; 611 612 for (ptr = val; ptr && *ptr; ptr++) { 613 free((*ptr)->contents); 614 free(*ptr); 615 } 616 free(val); 617} 618 619mit_krb5_error_code KRB5_CALLCONV 620krb5_us_timeofday(mit_krb5_context context, 621 mit_krb5_timestamp *outsec, 622 mit_krb5_int32 *outusec) 623{ 624 krb5_timestamp sec; 625 int32_t usec; 626 LOG_ENTRY(); 627 heim_krb5_us_timeofday((krb5_context)context, &sec, &usec); 628 *outsec = sec; 629 *outusec = usec; 630 return 0; 631} 632 633mit_krb5_error_code KRB5_CALLCONV 634krb5_timeofday(mit_krb5_context context, 635 mit_krb5_timestamp *out) 636{ 637 krb5_timestamp ts; 638 LOG_ENTRY(); 639 heim_krb5_timeofday((krb5_context)context, &ts); 640 *out = ts; 641 return 0; 642} 643 644char * 645krb5_pkinit_cert_hash_str(const mit_krb5_data *cert) 646{ 647 CC_SHA1_CTX ctx; 648 char *outstr, *cpOut; 649 unsigned char digest[CC_SHA1_DIGEST_LENGTH]; 650 unsigned i; 651 652 LOG_ENTRY(); 653 654 CC_SHA1_Init(&ctx); 655 CC_SHA1_Update(&ctx, cert->data, cert->length); 656 CC_SHA1_Final(digest, &ctx); 657 658 cpOut = outstr = (char *)malloc((2 * CC_SHA1_DIGEST_LENGTH) + 1); 659 if(outstr == NULL) 660 return NULL; 661 662 for(i = 0; i < CC_SHA1_DIGEST_LENGTH; i++, cpOut += 2) 663 sprintf(cpOut, "%02X", (unsigned)digest[i]); 664 *cpOut = '\0'; 665 return outstr; 666} 667 668mit_krb5_error_code KRB5_CALLCONV 669krb5_enctype_to_string(mit_krb5_enctype enctype, 670 char *str, 671 size_t size) 672{ 673 snprintf(str, size, "enctype-%d", enctype); 674 return 0; 675} 676 677void KRB5_CALLCONV 678krb5_free_addresses(mit_krb5_context context, mit_krb5_address **addrs) 679{ 680 unsigned int i; 681 for (i = 0; addrs && addrs[i] ; i++) { 682 free(addrs[i]->contents); 683 free(addrs[i]); 684 } 685 memset(addrs, 0, sizeof(*addrs)); 686 free(addrs); 687} 688 689mit_krb5_error_code KRB5_CALLCONV 690krb5_get_server_rcache(mit_krb5_context context, 691 const mit_krb5_data *foo, 692 mit_krb5_rcache *rcache) 693{ 694 *rcache = NULL; 695 return 0; 696} 697 698mit_krb5_error_code KRB5_CALLCONV 699krb5_os_localaddr(mit_krb5_context context, mit_krb5_address ***addresses) 700{ 701 mit_krb5_address **a; 702 krb5_addresses addrs; 703 krb5_error_code ret; 704 unsigned i; 705 706 *addresses = NULL; 707 708 addrs.len = 0; 709 addrs.val = NULL; 710 711 ret = heim_krb5_get_all_client_addrs(HC(context), &addrs); 712 if (ret) 713 return ret; 714 715 a = calloc(addrs.len + 1, sizeof(a[0])); 716 for (i = 0; i < addrs.len; i++) { 717 a[i] = calloc(1, sizeof(mit_krb5_address)); 718 a[i]->addrtype = addrs.val[i].addr_type; 719 a[i]->length = addrs.val[i].address.length; 720 a[i]->contents = mshim_malloc(addrs.val[i].address.length); 721 memcpy(a[i]->contents, addrs.val[i].address.data, addrs.val[i].address.length); 722 } 723 a[i] = NULL; 724 725 *addresses = a; 726 727 return 0; 728} 729 730mit_krb5_error_code KRB5_CALLCONV 731krb5_string_to_deltat(char *str, mit_krb5_deltat *t) 732{ 733 krb5_error_code ret; 734 krb5_deltat ht; 735 736 ret = heim_krb5_string_to_deltat(str, &ht); 737 if (ret) 738 return ret; 739 *t = ht; 740 return 0; 741} 742 743mit_krb5_error_code KRB5_CALLCONV 744krb5_prompter_posix(mit_krb5_context context, 745 void *data, 746 const char *name, 747 const char *banner, 748 int num_prompts, 749 mit_krb5_prompt prompts[]) 750{ 751 return EINVAL; 752} 753 754mit_krb5_error_code KRB5_CALLCONV 755krb5_get_validated_creds(mit_krb5_context context, 756 mit_krb5_creds *creds, 757 mit_krb5_principal client, 758 mit_krb5_ccache ccache, 759 char *in_tkt_service) 760{ 761 struct comb_principal *p = (struct comb_principal *)client; 762 krb5_error_code ret; 763 krb5_creds hcreds; 764 765 mshim_mcred2hcred(HC(context), creds, &hcreds); 766 767 ret = heim_krb5_get_validated_creds(HC(context), &hcreds, p->heim, (krb5_ccache)ccache, in_tkt_service); 768 heim_krb5_free_cred_contents(HC(context), &hcreds); 769 return ret; 770} 771 772mit_krb5_error_code KRB5_CALLCONV 773krb5_get_renewed_creds (mit_krb5_context context, 774 mit_krb5_creds *creds, 775 mit_krb5_principal client, 776 mit_krb5_ccache ccache, 777 char *in_tkt_service) 778{ 779 struct comb_principal *p = (struct comb_principal *)client; 780 krb5_error_code ret; 781 krb5_creds hcreds; 782 783 mshim_mcred2hcred(HC(context), creds, &hcreds); 784 785 ret = heim_krb5_get_renewed_creds(HC(context), &hcreds, p->heim, (krb5_ccache)ccache, in_tkt_service); 786 heim_krb5_free_cred_contents(HC(context), &hcreds); 787 return ret; 788} 789 790mit_krb5_error_code KRB5_CALLCONV 791krb5_set_real_time(mit_krb5_context context, 792 mit_krb5_timestamp ts, 793 mit_krb5_int32 usec) 794{ 795 LOG_ENTRY(); 796 return heim_krb5_set_real_time(HC(context), ts, usec); 797} 798 799#include "Kerberos/kim_library.h" 800 801kim_error 802kim_library_set_ui_environment(kim_ui_environment in_ui_environment) 803{ 804 LOG_ENTRY(); 805 return 0; 806} 807 808mit_krb5_boolean KRB5_CALLCONV 809krb5_kuserok(mit_krb5_context context, 810 mit_krb5_principal client, 811 const char *luser) 812{ 813 struct comb_principal *p = (struct comb_principal *)client; 814 LOG_ENTRY(); 815 return heim_krb5_kuserok(HC(context), p->heim, luser); 816} 817 818void KRB5_CALLCONV 819krb5_appdefault_string(mit_krb5_context context, 820 const char *appname, 821 const mit_krb5_data *realm, 822 const char *option, 823 const char *default_value, 824 char ** ret_value) 825{ 826 char *hrealm; 827 828 *ret_value = (char *)default_value; 829 830 if (realm->length > 5000) 831 return; 832 833 hrealm = mshim_malloc(realm->length + 1); 834 memcpy(hrealm, realm->data, realm->length); 835 hrealm[realm->length] = '\0'; 836 837 (void)heim_krb5_appdefault_string(HC(context), 838 appname, 839 hrealm, 840 option, 841 default_value, 842 ret_value); 843 free(hrealm); 844} 845 846void KRB5_CALLCONV 847krb5_appdefault_boolean(mit_krb5_context context, 848 const char *appname, 849 const mit_krb5_data *realm, 850 const char *option, 851 int default_value, 852 int *ret_value) 853{ 854 char *hrealm; 855 856 *ret_value = default_value; 857 858 if (realm->length > 5000) 859 return; 860 861 hrealm = mshim_malloc(realm->length + 1); 862 memcpy(hrealm, realm->data, realm->length); 863 hrealm[realm->length] = '\0'; 864 865 (void)heim_krb5_appdefault_boolean(HC(context), 866 appname, 867 hrealm, 868 option, 869 default_value, 870 ret_value); 871 free(hrealm); 872} 873 874/* 875 * Debug macros 876 */ 877 878#define ddebuglevel __KerberosDebugLogLevel 879#define dprintf __KerberosDebugPrint 880#define dvprintf __KerberosDebugVAPrint 881#define dprintmem __KerberosDebugPrintMemory 882#define dprintsession __KerberosDebugPrintSession 883 884int ddebuglevel (void); 885void dprintf (const char *in_format, ...) __attribute__ ((format (printf, 1, 2))); 886void dvprintf (const char *in_format, va_list in_args); 887void dprintmem (const void *in_data, size_t in_length); 888void dprintsession (void); 889 890 891int ddebuglevel (void) 892{ 893 return 0; 894} 895 896void dprintf (const char *in_format, ...) 897{ 898} 899 900void dvprintf (const char *in_format, va_list in_args) 901{ 902} 903 904void dprintmem (const void *in_data, size_t in_length) 905{ 906} 907 908void dprintsession (void) 909{ 910} 911 912const char * KRB5_CALLCONV 913krb5_get_error_message(mit_krb5_context context, mit_krb5_error_code code) 914{ 915 LOG_ENTRY(); 916 return heim_krb5_get_error_message(HC(context), code); 917} 918