auth_context.c
1 /* 2 * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "krb5_locl.h" 35 36 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 37 krb5_auth_con_init(krb5_context context, 38 krb5_auth_context *auth_context) 39 { 40 krb5_auth_context p; 41 42 ALLOC(p, 1); 43 if(!p) { 44 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 45 return ENOMEM; 46 } 47 memset(p, 0, sizeof(*p)); 48 ALLOC(p->authenticator, 1); 49 if (!p->authenticator) { 50 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 51 free(p); 52 return ENOMEM; 53 } 54 memset (p->authenticator, 0, sizeof(*p->authenticator)); 55 p->flags = KRB5_AUTH_CONTEXT_DO_TIME; 56 57 p->local_address = NULL; 58 p->remote_address = NULL; 59 p->local_port = 0; 60 p->remote_port = 0; 61 p->keytype = KRB5_ENCTYPE_NULL; 62 p->cksumtype = CKSUMTYPE_NONE; 63 p->auth_data = NULL; 64 p->pfs = NULL; 65 *auth_context = p; 66 return 0; 67 } 68 69 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 70 krb5_auth_con_free(krb5_context context, 71 krb5_auth_context auth_context) 72 { 73 if (auth_context != NULL) { 74 krb5_free_authenticator(context, &auth_context->authenticator); 75 if(auth_context->local_address){ 76 free_HostAddress(auth_context->local_address); 77 free(auth_context->local_address); 78 } 79 if(auth_context->remote_address){ 80 free_HostAddress(auth_context->remote_address); 81 free(auth_context->remote_address); 82 } 83 krb5_free_keyblock(context, auth_context->keyblock); 84 krb5_free_keyblock(context, auth_context->remote_subkey); 85 krb5_free_keyblock(context, auth_context->local_subkey); 86 if (auth_context->auth_data) { 87 free_AuthorizationData(auth_context->auth_data); 88 free(auth_context->auth_data); 89 } 90 if (auth_context->pfs) 91 _krb5_auth_con_free_pfs(context, auth_context); 92 memset(auth_context, 0, sizeof(*auth_context)); 93 free (auth_context); 94 } 95 return 0; 96 } 97 98 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 99 krb5_auth_con_setflags(krb5_context context, 100 krb5_auth_context auth_context, 101 int32_t flags) 102 { 103 auth_context->flags = flags; 104 return 0; 105 } 106 107 108 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 109 krb5_auth_con_getflags(krb5_context context, 110 krb5_auth_context auth_context, 111 int32_t *flags) 112 { 113 *flags = auth_context->flags; 114 return 0; 115 } 116 117 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 118 krb5_auth_con_addflags(krb5_context context, 119 krb5_auth_context auth_context, 120 int32_t addflags, 121 int32_t *flags) 122 { 123 if (flags) 124 *flags = auth_context->flags; 125 auth_context->flags |= addflags; 126 return 0; 127 } 128 129 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 130 krb5_auth_con_removeflags(krb5_context context, 131 krb5_auth_context auth_context, 132 int32_t removeflags, 133 int32_t *flags) 134 { 135 if (flags) 136 *flags = auth_context->flags; 137 auth_context->flags &= ~removeflags; 138 return 0; 139 } 140 141 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 142 krb5_auth_con_clear(krb5_context context, 143 krb5_auth_context auth_context, 144 unsigned int flags) 145 { 146 if ((flags & KRB5_AUTH_CONTEXT_CLEAR_LOCAL_ADDR) && auth_context->local_address) { 147 krb5_free_address(context, auth_context->local_address); 148 free(auth_context->local_address); 149 auth_context->local_address = NULL; 150 } 151 if ((flags & KRB5_AUTH_CONTEXT_CLEAR_REMOTE_ADDR) && auth_context->remote_address) { 152 krb5_free_address(context, auth_context->remote_address); 153 free(auth_context->remote_address); 154 auth_context->remote_address = NULL; 155 } 156 } 157 158 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 159 krb5_auth_con_setaddrs(krb5_context context, 160 krb5_auth_context auth_context, 161 krb5_address *local_addr, 162 krb5_address *remote_addr) 163 { 164 if (local_addr) { 165 if (auth_context->local_address) 166 krb5_free_address (context, auth_context->local_address); 167 else 168 if ((auth_context->local_address = malloc(sizeof(krb5_address))) == NULL) 169 return ENOMEM; 170 krb5_copy_address(context, local_addr, auth_context->local_address); 171 } 172 if (remote_addr) { 173 if (auth_context->remote_address) 174 krb5_free_address (context, auth_context->remote_address); 175 else 176 if ((auth_context->remote_address = malloc(sizeof(krb5_address))) == NULL) 177 return ENOMEM; 178 krb5_copy_address(context, remote_addr, auth_context->remote_address); 179 } 180 return 0; 181 } 182 183 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 184 krb5_auth_con_genaddrs(krb5_context context, 185 krb5_auth_context auth_context, 186 krb5_socket_t fd, int flags) 187 { 188 krb5_error_code ret; 189 krb5_address local_k_address, remote_k_address; 190 krb5_address *lptr = NULL, *rptr = NULL; 191 struct sockaddr_storage ss_local, ss_remote; 192 struct sockaddr *local = (struct sockaddr *)&ss_local; 193 struct sockaddr *remote = (struct sockaddr *)&ss_remote; 194 socklen_t len; 195 196 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) { 197 if (auth_context->local_address == NULL) { 198 len = sizeof(ss_local); 199 if(rk_IS_SOCKET_ERROR(getsockname(fd, local, &len))) { 200 char buf[128]; 201 ret = rk_SOCK_ERRNO; 202 rk_strerror_r(ret, buf, sizeof(buf)); 203 krb5_set_error_message(context, ret, "getsockname: %s", buf); 204 goto out; 205 } 206 ret = krb5_sockaddr2address (context, local, &local_k_address); 207 if(ret) goto out; 208 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) { 209 krb5_sockaddr2port (context, local, &auth_context->local_port); 210 } else 211 auth_context->local_port = 0; 212 lptr = &local_k_address; 213 } 214 } 215 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) { 216 len = sizeof(ss_remote); 217 if(rk_IS_SOCKET_ERROR(getpeername(fd, remote, &len))) { 218 char buf[128]; 219 ret = rk_SOCK_ERRNO; 220 rk_strerror_r(ret, buf, sizeof(buf)); 221 krb5_set_error_message(context, ret, "getpeername: %s", buf); 222 goto out; 223 } 224 ret = krb5_sockaddr2address (context, remote, &remote_k_address); 225 if(ret) goto out; 226 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) { 227 krb5_sockaddr2port (context, remote, &auth_context->remote_port); 228 } else 229 auth_context->remote_port = 0; 230 rptr = &remote_k_address; 231 } 232 ret = krb5_auth_con_setaddrs (context, 233 auth_context, 234 lptr, 235 rptr); 236 out: 237 if (lptr) 238 krb5_free_address (context, lptr); 239 if (rptr) 240 krb5_free_address (context, rptr); 241 return ret; 242 243 } 244 245 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 246 krb5_auth_con_setaddrs_from_fd (krb5_context context, 247 krb5_auth_context auth_context, 248 void *p_fd) 249 { 250 krb5_socket_t fd = *(krb5_socket_t *)p_fd; 251 int flags = 0; 252 if(auth_context->local_address == NULL) 253 flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR; 254 if(auth_context->remote_address == NULL) 255 flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR; 256 return krb5_auth_con_genaddrs(context, auth_context, fd, flags); 257 } 258 259 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 260 krb5_auth_con_getaddrs(krb5_context context, 261 krb5_auth_context auth_context, 262 krb5_address **local_addr, 263 krb5_address **remote_addr) 264 { 265 if(*local_addr) 266 krb5_free_address (context, *local_addr); 267 *local_addr = malloc (sizeof(**local_addr)); 268 if (*local_addr == NULL) { 269 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 270 return ENOMEM; 271 } 272 krb5_copy_address(context, 273 auth_context->local_address, 274 *local_addr); 275 276 if(*remote_addr) 277 krb5_free_address (context, *remote_addr); 278 *remote_addr = malloc (sizeof(**remote_addr)); 279 if (*remote_addr == NULL) { 280 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 281 krb5_free_address (context, *local_addr); 282 *local_addr = NULL; 283 return ENOMEM; 284 } 285 krb5_copy_address(context, 286 auth_context->remote_address, 287 *remote_addr); 288 return 0; 289 } 290 291 /* coverity[+alloc : arg-*2] */ 292 static krb5_error_code 293 copy_key(krb5_context context, 294 krb5_keyblock *in, 295 krb5_keyblock **out) 296 { 297 if(in) 298 return krb5_copy_keyblock(context, in, out); 299 *out = NULL; /* is this right? */ 300 return 0; 301 } 302 303 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 304 krb5_auth_con_getkey(krb5_context context, 305 krb5_auth_context auth_context, 306 krb5_keyblock **keyblock) 307 { 308 return copy_key(context, auth_context->keyblock, keyblock); 309 } 310 311 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 312 krb5_auth_con_getlocalsubkey(krb5_context context, 313 krb5_auth_context auth_context, 314 krb5_keyblock **keyblock) 315 { 316 return copy_key(context, auth_context->local_subkey, keyblock); 317 } 318 319 /* coverity[+alloc : arg-*2] */ 320 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 321 krb5_auth_con_getremotesubkey(krb5_context context, 322 krb5_auth_context auth_context, 323 krb5_keyblock **keyblock) 324 { 325 return copy_key(context, auth_context->remote_subkey, keyblock); 326 } 327 328 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 329 krb5_auth_con_setkey(krb5_context context, 330 krb5_auth_context auth_context, 331 krb5_keyblock *keyblock) 332 { 333 if(auth_context->keyblock) 334 krb5_free_keyblock(context, auth_context->keyblock); 335 return copy_key(context, keyblock, &auth_context->keyblock); 336 } 337 338 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 339 krb5_auth_con_setlocalsubkey(krb5_context context, 340 krb5_auth_context auth_context, 341 krb5_keyblock *keyblock) 342 { 343 if(auth_context->local_subkey) 344 krb5_free_keyblock(context, auth_context->local_subkey); 345 return copy_key(context, keyblock, &auth_context->local_subkey); 346 } 347 348 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 349 krb5_auth_con_generatelocalsubkey(krb5_context context, 350 krb5_auth_context auth_context, 351 krb5_keyblock *key) 352 { 353 krb5_error_code ret; 354 krb5_keyblock *subkey; 355 356 ret = krb5_generate_subkey_extended (context, key, 357 (krb5_enctype)auth_context->keytype, 358 &subkey); 359 if(ret) 360 return ret; 361 if(auth_context->local_subkey) 362 krb5_free_keyblock(context, auth_context->local_subkey); 363 auth_context->local_subkey = subkey; 364 return 0; 365 } 366 367 368 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 369 krb5_auth_con_setremotesubkey(krb5_context context, 370 krb5_auth_context auth_context, 371 krb5_keyblock *keyblock) 372 { 373 if(auth_context->remote_subkey) 374 krb5_free_keyblock(context, auth_context->remote_subkey); 375 return copy_key(context, keyblock, &auth_context->remote_subkey); 376 } 377 378 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 379 krb5_auth_con_setcksumtype(krb5_context context, 380 krb5_auth_context auth_context, 381 krb5_cksumtype cksumtype) 382 { 383 auth_context->cksumtype = cksumtype; 384 return 0; 385 } 386 387 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 388 krb5_auth_con_getcksumtype(krb5_context context, 389 krb5_auth_context auth_context, 390 krb5_cksumtype *cksumtype) 391 { 392 *cksumtype = auth_context->cksumtype; 393 return 0; 394 } 395 396 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 397 krb5_auth_con_setkeytype (krb5_context context, 398 krb5_auth_context auth_context, 399 krb5_keytype keytype) 400 { 401 auth_context->keytype = keytype; 402 return 0; 403 } 404 405 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 406 krb5_auth_con_getkeytype (krb5_context context, 407 krb5_auth_context auth_context, 408 krb5_keytype *keytype) 409 { 410 *keytype = auth_context->keytype; 411 return 0; 412 } 413 414 #if 0 415 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 416 krb5_auth_con_setenctype(krb5_context context, 417 krb5_auth_context auth_context, 418 krb5_enctype etype) 419 { 420 if(auth_context->keyblock) 421 krb5_free_keyblock(context, auth_context->keyblock); 422 ALLOC(auth_context->keyblock, 1); 423 if(auth_context->keyblock == NULL) 424 return ENOMEM; 425 auth_context->keyblock->keytype = etype; 426 return 0; 427 } 428 429 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 430 krb5_auth_con_getenctype(krb5_context context, 431 krb5_auth_context auth_context, 432 krb5_enctype *etype) 433 { 434 krb5_abortx(context, "unimplemented krb5_auth_getenctype called"); 435 } 436 #endif 437 438 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 439 krb5_auth_con_getlocalseqnumber(krb5_context context, 440 krb5_auth_context auth_context, 441 int32_t *seqnumber) 442 { 443 *seqnumber = auth_context->local_seqnumber; 444 return 0; 445 } 446 447 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 448 krb5_auth_con_setlocalseqnumber (krb5_context context, 449 krb5_auth_context auth_context, 450 int32_t seqnumber) 451 { 452 auth_context->local_seqnumber = seqnumber; 453 return 0; 454 } 455 456 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 457 krb5_auth_con_getremoteseqnumber(krb5_context context, 458 krb5_auth_context auth_context, 459 int32_t *seqnumber) 460 { 461 *seqnumber = auth_context->remote_seqnumber; 462 return 0; 463 } 464 465 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 466 krb5_auth_con_setremoteseqnumber (krb5_context context, 467 krb5_auth_context auth_context, 468 int32_t seqnumber) 469 { 470 auth_context->remote_seqnumber = seqnumber; 471 return 0; 472 } 473 474 475 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 476 krb5_auth_con_getauthenticator(krb5_context context, 477 krb5_auth_context auth_context, 478 krb5_authenticator *authenticator) 479 { 480 *authenticator = malloc(sizeof(**authenticator)); 481 if (*authenticator == NULL) { 482 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 483 return ENOMEM; 484 } 485 486 return copy_Authenticator(auth_context->authenticator, 487 *authenticator); 488 } 489 490 491 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 492 krb5_free_authenticator(krb5_context context, 493 krb5_authenticator *authenticator) 494 { 495 if (authenticator) { 496 free_Authenticator (*authenticator); 497 memset(*authenticator, 0, sizeof(**authenticator)); 498 free (*authenticator); 499 *authenticator = NULL; 500 } 501 } 502 503 504 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 505 krb5_auth_con_setuserkey(krb5_context context, 506 krb5_auth_context auth_context, 507 krb5_keyblock *keyblock) 508 { 509 if(auth_context->keyblock) 510 krb5_free_keyblock(context, auth_context->keyblock); 511 return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock); 512 } 513 514 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 515 krb5_auth_con_getrcache(krb5_context context, 516 krb5_auth_context auth_context, 517 krb5_rcache *rcache) 518 { 519 *rcache = auth_context->rcache; 520 return 0; 521 } 522 523 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 524 krb5_auth_con_setrcache(krb5_context context, 525 krb5_auth_context auth_context, 526 krb5_rcache rcache) 527 { 528 auth_context->rcache = rcache; 529 return 0; 530 } 531 532 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 533 krb5_auth_con_add_AuthorizationData(krb5_context context, 534 krb5_auth_context auth_context, 535 int type, 536 krb5_data *data) 537 { 538 AuthorizationDataElement el; 539 540 if (auth_context->auth_data == NULL) { 541 auth_context->auth_data = calloc(1, sizeof(*auth_context->auth_data)); 542 if (auth_context->auth_data == NULL) 543 return krb5_enomem(context); 544 } 545 el.ad_type = type; 546 el.ad_data.data = data->data; 547 el.ad_data.length = data->length; 548 549 return add_AuthorizationData(auth_context->auth_data, &el); 550 } 551 552 553 #if 0 /* not implemented */ 554 555 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 556 krb5_auth_con_initivector(krb5_context context, 557 krb5_auth_context auth_context) 558 { 559 krb5_abortx(context, "unimplemented krb5_auth_con_initivector called"); 560 } 561 562 563 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 564 krb5_auth_con_setivector(krb5_context context, 565 krb5_auth_context auth_context, 566 krb5_pointer ivector) 567 { 568 krb5_abortx(context, "unimplemented krb5_auth_con_setivector called"); 569 } 570 571 #endif /* not implemented */