1 /* $NetBSD: auth_context.c,v 1.3 2014/04/24 13:45:34 pettai Exp $ */ 2 3 /* 4 * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * 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 "krb5_locl.h" 37 38 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 39 krb5_auth_con_init(krb5_context context, 40 krb5_auth_context *auth_context) 41 { 42 krb5_auth_context p; 43 44 ALLOC(p, 1); 45 if(!p) { 46 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 47 return ENOMEM; 48 } 49 memset(p, 0, sizeof(*p)); 50 ALLOC(p->authenticator, 1); 51 if (!p->authenticator) { 52 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 53 free(p); 54 return ENOMEM; 55 } 56 memset (p->authenticator, 0, sizeof(*p->authenticator)); 57 p->flags = KRB5_AUTH_CONTEXT_DO_TIME; 58 59 p->local_address = NULL; 60 p->remote_address = NULL; 61 p->local_port = 0; 62 p->remote_port = 0; 63 p->keytype = ENCTYPE_NULL; 64 p->cksumtype = CKSUMTYPE_NONE; 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 free (auth_context); 87 } 88 return 0; 89 } 90 91 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 92 krb5_auth_con_setflags(krb5_context context, 93 krb5_auth_context auth_context, 94 int32_t flags) 95 { 96 auth_context->flags = flags; 97 return 0; 98 } 99 100 101 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 102 krb5_auth_con_getflags(krb5_context context, 103 krb5_auth_context auth_context, 104 int32_t *flags) 105 { 106 *flags = auth_context->flags; 107 return 0; 108 } 109 110 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 111 krb5_auth_con_addflags(krb5_context context, 112 krb5_auth_context auth_context, 113 int32_t addflags, 114 int32_t *flags) 115 { 116 if (flags) 117 *flags = auth_context->flags; 118 auth_context->flags |= addflags; 119 return 0; 120 } 121 122 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 123 krb5_auth_con_removeflags(krb5_context context, 124 krb5_auth_context auth_context, 125 int32_t removeflags, 126 int32_t *flags) 127 { 128 if (flags) 129 *flags = auth_context->flags; 130 auth_context->flags &= ~removeflags; 131 return 0; 132 } 133 134 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 135 krb5_auth_con_setaddrs(krb5_context context, 136 krb5_auth_context auth_context, 137 krb5_address *local_addr, 138 krb5_address *remote_addr) 139 { 140 if (local_addr) { 141 if (auth_context->local_address) 142 krb5_free_address (context, auth_context->local_address); 143 else 144 if ((auth_context->local_address = malloc(sizeof(krb5_address))) == NULL) 145 return ENOMEM; 146 krb5_copy_address(context, local_addr, auth_context->local_address); 147 } 148 if (remote_addr) { 149 if (auth_context->remote_address) 150 krb5_free_address (context, auth_context->remote_address); 151 else 152 if ((auth_context->remote_address = malloc(sizeof(krb5_address))) == NULL) 153 return ENOMEM; 154 krb5_copy_address(context, remote_addr, auth_context->remote_address); 155 } 156 return 0; 157 } 158 159 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 160 krb5_auth_con_genaddrs(krb5_context context, 161 krb5_auth_context auth_context, 162 krb5_socket_t fd, int flags) 163 { 164 krb5_error_code ret; 165 krb5_address local_k_address, remote_k_address; 166 krb5_address *lptr = NULL, *rptr = NULL; 167 struct sockaddr_storage ss_local, ss_remote; 168 struct sockaddr *local = (struct sockaddr *)&ss_local; 169 struct sockaddr *remote = (struct sockaddr *)&ss_remote; 170 socklen_t len; 171 172 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) { 173 if (auth_context->local_address == NULL) { 174 len = sizeof(ss_local); 175 if(rk_IS_SOCKET_ERROR(getsockname(fd, local, &len))) { 176 char buf[128]; 177 ret = rk_SOCK_ERRNO; 178 rk_strerror_r(ret, buf, sizeof(buf)); 179 krb5_set_error_message(context, ret, "getsockname: %s", buf); 180 goto out; 181 } 182 ret = krb5_sockaddr2address (context, local, &local_k_address); 183 if(ret) goto out; 184 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) { 185 krb5_sockaddr2port (context, local, &auth_context->local_port); 186 } else 187 auth_context->local_port = 0; 188 lptr = &local_k_address; 189 } 190 } 191 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) { 192 len = sizeof(ss_remote); 193 if(rk_IS_SOCKET_ERROR(getpeername(fd, remote, &len))) { 194 char buf[128]; 195 ret = rk_SOCK_ERRNO; 196 rk_strerror_r(ret, buf, sizeof(buf)); 197 krb5_set_error_message(context, ret, "getpeername: %s", buf); 198 goto out; 199 } 200 ret = krb5_sockaddr2address (context, remote, &remote_k_address); 201 if(ret) goto out; 202 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) { 203 krb5_sockaddr2port (context, remote, &auth_context->remote_port); 204 } else 205 auth_context->remote_port = 0; 206 rptr = &remote_k_address; 207 } 208 ret = krb5_auth_con_setaddrs (context, 209 auth_context, 210 lptr, 211 rptr); 212 out: 213 if (lptr) 214 krb5_free_address (context, lptr); 215 if (rptr) 216 krb5_free_address (context, rptr); 217 return ret; 218 219 } 220 221 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 222 krb5_auth_con_setaddrs_from_fd (krb5_context context, 223 krb5_auth_context auth_context, 224 void *p_fd) 225 { 226 krb5_socket_t fd = *(krb5_socket_t *)p_fd; 227 int flags = 0; 228 if(auth_context->local_address == NULL) 229 flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR; 230 if(auth_context->remote_address == NULL) 231 flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR; 232 return krb5_auth_con_genaddrs(context, auth_context, fd, flags); 233 } 234 235 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 236 krb5_auth_con_getaddrs(krb5_context context, 237 krb5_auth_context auth_context, 238 krb5_address **local_addr, 239 krb5_address **remote_addr) 240 { 241 if(*local_addr) 242 krb5_free_address (context, *local_addr); 243 *local_addr = malloc (sizeof(**local_addr)); 244 if (*local_addr == NULL) { 245 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 246 return ENOMEM; 247 } 248 krb5_copy_address(context, 249 auth_context->local_address, 250 *local_addr); 251 252 if(*remote_addr) 253 krb5_free_address (context, *remote_addr); 254 *remote_addr = malloc (sizeof(**remote_addr)); 255 if (*remote_addr == NULL) { 256 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 257 krb5_free_address (context, *local_addr); 258 *local_addr = NULL; 259 return ENOMEM; 260 } 261 krb5_copy_address(context, 262 auth_context->remote_address, 263 *remote_addr); 264 return 0; 265 } 266 267 /* coverity[+alloc : arg-*2] */ 268 static krb5_error_code 269 copy_key(krb5_context context, 270 krb5_keyblock *in, 271 krb5_keyblock **out) 272 { 273 if(in) 274 return krb5_copy_keyblock(context, in, out); 275 *out = NULL; /* is this right? */ 276 return 0; 277 } 278 279 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 280 krb5_auth_con_getkey(krb5_context context, 281 krb5_auth_context auth_context, 282 krb5_keyblock **keyblock) 283 { 284 return copy_key(context, auth_context->keyblock, keyblock); 285 } 286 287 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 288 krb5_auth_con_getlocalsubkey(krb5_context context, 289 krb5_auth_context auth_context, 290 krb5_keyblock **keyblock) 291 { 292 return copy_key(context, auth_context->local_subkey, keyblock); 293 } 294 295 /* coverity[+alloc : arg-*2] */ 296 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 297 krb5_auth_con_getremotesubkey(krb5_context context, 298 krb5_auth_context auth_context, 299 krb5_keyblock **keyblock) 300 { 301 return copy_key(context, auth_context->remote_subkey, keyblock); 302 } 303 304 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 305 krb5_auth_con_setkey(krb5_context context, 306 krb5_auth_context auth_context, 307 krb5_keyblock *keyblock) 308 { 309 if(auth_context->keyblock) 310 krb5_free_keyblock(context, auth_context->keyblock); 311 return copy_key(context, keyblock, &auth_context->keyblock); 312 } 313 314 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 315 krb5_auth_con_setlocalsubkey(krb5_context context, 316 krb5_auth_context auth_context, 317 krb5_keyblock *keyblock) 318 { 319 if(auth_context->local_subkey) 320 krb5_free_keyblock(context, auth_context->local_subkey); 321 return copy_key(context, keyblock, &auth_context->local_subkey); 322 } 323 324 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 325 krb5_auth_con_generatelocalsubkey(krb5_context context, 326 krb5_auth_context auth_context, 327 krb5_keyblock *key) 328 { 329 krb5_error_code ret; 330 krb5_keyblock *subkey; 331 332 ret = krb5_generate_subkey_extended (context, key, 333 auth_context->keytype, 334 &subkey); 335 if(ret) 336 return ret; 337 if(auth_context->local_subkey) 338 krb5_free_keyblock(context, auth_context->local_subkey); 339 auth_context->local_subkey = subkey; 340 return 0; 341 } 342 343 344 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 345 krb5_auth_con_setremotesubkey(krb5_context context, 346 krb5_auth_context auth_context, 347 krb5_keyblock *keyblock) 348 { 349 if(auth_context->remote_subkey) 350 krb5_free_keyblock(context, auth_context->remote_subkey); 351 return copy_key(context, keyblock, &auth_context->remote_subkey); 352 } 353 354 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 355 krb5_auth_con_setcksumtype(krb5_context context, 356 krb5_auth_context auth_context, 357 krb5_cksumtype cksumtype) 358 { 359 auth_context->cksumtype = cksumtype; 360 return 0; 361 } 362 363 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 364 krb5_auth_con_getcksumtype(krb5_context context, 365 krb5_auth_context auth_context, 366 krb5_cksumtype *cksumtype) 367 { 368 *cksumtype = auth_context->cksumtype; 369 return 0; 370 } 371 372 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 373 krb5_auth_con_setkeytype (krb5_context context, 374 krb5_auth_context auth_context, 375 krb5_keytype keytype) 376 { 377 auth_context->keytype = keytype; 378 return 0; 379 } 380 381 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 382 krb5_auth_con_getkeytype (krb5_context context, 383 krb5_auth_context auth_context, 384 krb5_keytype *keytype) 385 { 386 *keytype = auth_context->keytype; 387 return 0; 388 } 389 390 #if 0 391 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 392 krb5_auth_con_setenctype(krb5_context context, 393 krb5_auth_context auth_context, 394 krb5_enctype etype) 395 { 396 if(auth_context->keyblock) 397 krb5_free_keyblock(context, auth_context->keyblock); 398 ALLOC(auth_context->keyblock, 1); 399 if(auth_context->keyblock == NULL) 400 return ENOMEM; 401 auth_context->keyblock->keytype = etype; 402 return 0; 403 } 404 405 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 406 krb5_auth_con_getenctype(krb5_context context, 407 krb5_auth_context auth_context, 408 krb5_enctype *etype) 409 { 410 krb5_abortx(context, "unimplemented krb5_auth_getenctype called"); 411 } 412 #endif 413 414 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 415 krb5_auth_con_getlocalseqnumber(krb5_context context, 416 krb5_auth_context auth_context, 417 int32_t *seqnumber) 418 { 419 *seqnumber = auth_context->local_seqnumber; 420 return 0; 421 } 422 423 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 424 krb5_auth_con_setlocalseqnumber (krb5_context context, 425 krb5_auth_context auth_context, 426 int32_t seqnumber) 427 { 428 auth_context->local_seqnumber = seqnumber; 429 return 0; 430 } 431 432 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 433 krb5_auth_con_getremoteseqnumber(krb5_context context, 434 krb5_auth_context auth_context, 435 int32_t *seqnumber) 436 { 437 *seqnumber = auth_context->remote_seqnumber; 438 return 0; 439 } 440 441 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 442 krb5_auth_con_setremoteseqnumber (krb5_context context, 443 krb5_auth_context auth_context, 444 int32_t seqnumber) 445 { 446 auth_context->remote_seqnumber = seqnumber; 447 return 0; 448 } 449 450 451 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 452 krb5_auth_con_getauthenticator(krb5_context context, 453 krb5_auth_context auth_context, 454 krb5_authenticator *authenticator) 455 { 456 *authenticator = malloc(sizeof(**authenticator)); 457 if (*authenticator == NULL) { 458 krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); 459 return ENOMEM; 460 } 461 462 copy_Authenticator(auth_context->authenticator, 463 *authenticator); 464 return 0; 465 } 466 467 468 KRB5_LIB_FUNCTION void KRB5_LIB_CALL 469 krb5_free_authenticator(krb5_context context, 470 krb5_authenticator *authenticator) 471 { 472 free_Authenticator (*authenticator); 473 free (*authenticator); 474 *authenticator = NULL; 475 } 476 477 478 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 479 krb5_auth_con_setuserkey(krb5_context context, 480 krb5_auth_context auth_context, 481 krb5_keyblock *keyblock) 482 { 483 if(auth_context->keyblock) 484 krb5_free_keyblock(context, auth_context->keyblock); 485 return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock); 486 } 487 488 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 489 krb5_auth_con_getrcache(krb5_context context, 490 krb5_auth_context auth_context, 491 krb5_rcache *rcache) 492 { 493 *rcache = auth_context->rcache; 494 return 0; 495 } 496 497 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 498 krb5_auth_con_setrcache(krb5_context context, 499 krb5_auth_context auth_context, 500 krb5_rcache rcache) 501 { 502 auth_context->rcache = rcache; 503 return 0; 504 } 505 506 #if 0 /* not implemented */ 507 508 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 509 krb5_auth_con_initivector(krb5_context context, 510 krb5_auth_context auth_context) 511 { 512 krb5_abortx(context, "unimplemented krb5_auth_con_initivector called"); 513 } 514 515 516 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 517 krb5_auth_con_setivector(krb5_context context, 518 krb5_auth_context auth_context, 519 krb5_pointer ivector) 520 { 521 krb5_abortx(context, "unimplemented krb5_auth_con_setivector called"); 522 } 523 524 #endif /* not implemented */ 525