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 RCSID("$Id: auth_context.c 21745 2007-07-31 16:11:25Z lha $"); 37 38 krb5_error_code KRB5_LIB_FUNCTION 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_string(context, "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_string(context, "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 = KEYTYPE_NULL; 64 p->cksumtype = CKSUMTYPE_NONE; 65 *auth_context = p; 66 return 0; 67 } 68 69 krb5_error_code KRB5_LIB_FUNCTION 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_error_code KRB5_LIB_FUNCTION 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_error_code KRB5_LIB_FUNCTION 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_error_code KRB5_LIB_FUNCTION 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_error_code KRB5_LIB_FUNCTION 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_error_code KRB5_LIB_FUNCTION 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_error_code KRB5_LIB_FUNCTION 160 krb5_auth_con_genaddrs(krb5_context context, 161 krb5_auth_context auth_context, 162 int 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(getsockname(fd, local, &len) < 0) { 176 ret = errno; 177 krb5_set_error_string (context, "getsockname: %s", 178 strerror(ret)); 179 goto out; 180 } 181 ret = krb5_sockaddr2address (context, local, &local_k_address); 182 if(ret) goto out; 183 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) { 184 krb5_sockaddr2port (context, local, &auth_context->local_port); 185 } else 186 auth_context->local_port = 0; 187 lptr = &local_k_address; 188 } 189 } 190 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) { 191 len = sizeof(ss_remote); 192 if(getpeername(fd, remote, &len) < 0) { 193 ret = errno; 194 krb5_set_error_string (context, "getpeername: %s", strerror(ret)); 195 goto out; 196 } 197 ret = krb5_sockaddr2address (context, remote, &remote_k_address); 198 if(ret) goto out; 199 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) { 200 krb5_sockaddr2port (context, remote, &auth_context->remote_port); 201 } else 202 auth_context->remote_port = 0; 203 rptr = &remote_k_address; 204 } 205 ret = krb5_auth_con_setaddrs (context, 206 auth_context, 207 lptr, 208 rptr); 209 out: 210 if (lptr) 211 krb5_free_address (context, lptr); 212 if (rptr) 213 krb5_free_address (context, rptr); 214 return ret; 215 216 } 217 218 krb5_error_code KRB5_LIB_FUNCTION 219 krb5_auth_con_setaddrs_from_fd (krb5_context context, 220 krb5_auth_context auth_context, 221 void *p_fd) 222 { 223 int fd = *(int*)p_fd; 224 int flags = 0; 225 if(auth_context->local_address == NULL) 226 flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR; 227 if(auth_context->remote_address == NULL) 228 flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR; 229 return krb5_auth_con_genaddrs(context, auth_context, fd, flags); 230 } 231 232 krb5_error_code KRB5_LIB_FUNCTION 233 krb5_auth_con_getaddrs(krb5_context context, 234 krb5_auth_context auth_context, 235 krb5_address **local_addr, 236 krb5_address **remote_addr) 237 { 238 if(*local_addr) 239 krb5_free_address (context, *local_addr); 240 *local_addr = malloc (sizeof(**local_addr)); 241 if (*local_addr == NULL) { 242 krb5_set_error_string(context, "malloc: out of memory"); 243 return ENOMEM; 244 } 245 krb5_copy_address(context, 246 auth_context->local_address, 247 *local_addr); 248 249 if(*remote_addr) 250 krb5_free_address (context, *remote_addr); 251 *remote_addr = malloc (sizeof(**remote_addr)); 252 if (*remote_addr == NULL) { 253 krb5_set_error_string(context, "malloc: out of memory"); 254 krb5_free_address (context, *local_addr); 255 *local_addr = NULL; 256 return ENOMEM; 257 } 258 krb5_copy_address(context, 259 auth_context->remote_address, 260 *remote_addr); 261 return 0; 262 } 263 264 static krb5_error_code 265 copy_key(krb5_context context, 266 krb5_keyblock *in, 267 krb5_keyblock **out) 268 { 269 if(in) 270 return krb5_copy_keyblock(context, in, out); 271 *out = NULL; /* is this right? */ 272 return 0; 273 } 274 275 krb5_error_code KRB5_LIB_FUNCTION 276 krb5_auth_con_getkey(krb5_context context, 277 krb5_auth_context auth_context, 278 krb5_keyblock **keyblock) 279 { 280 return copy_key(context, auth_context->keyblock, keyblock); 281 } 282 283 krb5_error_code KRB5_LIB_FUNCTION 284 krb5_auth_con_getlocalsubkey(krb5_context context, 285 krb5_auth_context auth_context, 286 krb5_keyblock **keyblock) 287 { 288 return copy_key(context, auth_context->local_subkey, keyblock); 289 } 290 291 krb5_error_code KRB5_LIB_FUNCTION 292 krb5_auth_con_getremotesubkey(krb5_context context, 293 krb5_auth_context auth_context, 294 krb5_keyblock **keyblock) 295 { 296 return copy_key(context, auth_context->remote_subkey, keyblock); 297 } 298 299 krb5_error_code KRB5_LIB_FUNCTION 300 krb5_auth_con_setkey(krb5_context context, 301 krb5_auth_context auth_context, 302 krb5_keyblock *keyblock) 303 { 304 if(auth_context->keyblock) 305 krb5_free_keyblock(context, auth_context->keyblock); 306 return copy_key(context, keyblock, &auth_context->keyblock); 307 } 308 309 krb5_error_code KRB5_LIB_FUNCTION 310 krb5_auth_con_setlocalsubkey(krb5_context context, 311 krb5_auth_context auth_context, 312 krb5_keyblock *keyblock) 313 { 314 if(auth_context->local_subkey) 315 krb5_free_keyblock(context, auth_context->local_subkey); 316 return copy_key(context, keyblock, &auth_context->local_subkey); 317 } 318 319 krb5_error_code KRB5_LIB_FUNCTION 320 krb5_auth_con_generatelocalsubkey(krb5_context context, 321 krb5_auth_context auth_context, 322 krb5_keyblock *key) 323 { 324 krb5_error_code ret; 325 krb5_keyblock *subkey; 326 327 ret = krb5_generate_subkey_extended (context, key, 328 auth_context->keytype, 329 &subkey); 330 if(ret) 331 return ret; 332 if(auth_context->local_subkey) 333 krb5_free_keyblock(context, auth_context->local_subkey); 334 auth_context->local_subkey = subkey; 335 return 0; 336 } 337 338 339 krb5_error_code KRB5_LIB_FUNCTION 340 krb5_auth_con_setremotesubkey(krb5_context context, 341 krb5_auth_context auth_context, 342 krb5_keyblock *keyblock) 343 { 344 if(auth_context->remote_subkey) 345 krb5_free_keyblock(context, auth_context->remote_subkey); 346 return copy_key(context, keyblock, &auth_context->remote_subkey); 347 } 348 349 krb5_error_code KRB5_LIB_FUNCTION 350 krb5_auth_con_setcksumtype(krb5_context context, 351 krb5_auth_context auth_context, 352 krb5_cksumtype cksumtype) 353 { 354 auth_context->cksumtype = cksumtype; 355 return 0; 356 } 357 358 krb5_error_code KRB5_LIB_FUNCTION 359 krb5_auth_con_getcksumtype(krb5_context context, 360 krb5_auth_context auth_context, 361 krb5_cksumtype *cksumtype) 362 { 363 *cksumtype = auth_context->cksumtype; 364 return 0; 365 } 366 367 krb5_error_code KRB5_LIB_FUNCTION 368 krb5_auth_con_setkeytype (krb5_context context, 369 krb5_auth_context auth_context, 370 krb5_keytype keytype) 371 { 372 auth_context->keytype = keytype; 373 return 0; 374 } 375 376 krb5_error_code KRB5_LIB_FUNCTION 377 krb5_auth_con_getkeytype (krb5_context context, 378 krb5_auth_context auth_context, 379 krb5_keytype *keytype) 380 { 381 *keytype = auth_context->keytype; 382 return 0; 383 } 384 385 #if 0 386 krb5_error_code KRB5_LIB_FUNCTION 387 krb5_auth_con_setenctype(krb5_context context, 388 krb5_auth_context auth_context, 389 krb5_enctype etype) 390 { 391 if(auth_context->keyblock) 392 krb5_free_keyblock(context, auth_context->keyblock); 393 ALLOC(auth_context->keyblock, 1); 394 if(auth_context->keyblock == NULL) 395 return ENOMEM; 396 auth_context->keyblock->keytype = etype; 397 return 0; 398 } 399 400 krb5_error_code KRB5_LIB_FUNCTION 401 krb5_auth_con_getenctype(krb5_context context, 402 krb5_auth_context auth_context, 403 krb5_enctype *etype) 404 { 405 krb5_abortx(context, "unimplemented krb5_auth_getenctype called"); 406 } 407 #endif 408 409 krb5_error_code KRB5_LIB_FUNCTION 410 krb5_auth_con_getlocalseqnumber(krb5_context context, 411 krb5_auth_context auth_context, 412 int32_t *seqnumber) 413 { 414 *seqnumber = auth_context->local_seqnumber; 415 return 0; 416 } 417 418 krb5_error_code KRB5_LIB_FUNCTION 419 krb5_auth_con_setlocalseqnumber (krb5_context context, 420 krb5_auth_context auth_context, 421 int32_t seqnumber) 422 { 423 auth_context->local_seqnumber = seqnumber; 424 return 0; 425 } 426 427 krb5_error_code KRB5_LIB_FUNCTION 428 krb5_auth_getremoteseqnumber(krb5_context context, 429 krb5_auth_context auth_context, 430 int32_t *seqnumber) 431 { 432 *seqnumber = auth_context->remote_seqnumber; 433 return 0; 434 } 435 436 krb5_error_code KRB5_LIB_FUNCTION 437 krb5_auth_con_setremoteseqnumber (krb5_context context, 438 krb5_auth_context auth_context, 439 int32_t seqnumber) 440 { 441 auth_context->remote_seqnumber = seqnumber; 442 return 0; 443 } 444 445 446 krb5_error_code KRB5_LIB_FUNCTION 447 krb5_auth_con_getauthenticator(krb5_context context, 448 krb5_auth_context auth_context, 449 krb5_authenticator *authenticator) 450 { 451 *authenticator = malloc(sizeof(**authenticator)); 452 if (*authenticator == NULL) { 453 krb5_set_error_string(context, "malloc: out of memory"); 454 return ENOMEM; 455 } 456 457 copy_Authenticator(auth_context->authenticator, 458 *authenticator); 459 return 0; 460 } 461 462 463 void KRB5_LIB_FUNCTION 464 krb5_free_authenticator(krb5_context context, 465 krb5_authenticator *authenticator) 466 { 467 free_Authenticator (*authenticator); 468 free (*authenticator); 469 *authenticator = NULL; 470 } 471 472 473 krb5_error_code KRB5_LIB_FUNCTION 474 krb5_auth_con_setuserkey(krb5_context context, 475 krb5_auth_context auth_context, 476 krb5_keyblock *keyblock) 477 { 478 if(auth_context->keyblock) 479 krb5_free_keyblock(context, auth_context->keyblock); 480 return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock); 481 } 482 483 krb5_error_code KRB5_LIB_FUNCTION 484 krb5_auth_con_getrcache(krb5_context context, 485 krb5_auth_context auth_context, 486 krb5_rcache *rcache) 487 { 488 *rcache = auth_context->rcache; 489 return 0; 490 } 491 492 krb5_error_code KRB5_LIB_FUNCTION 493 krb5_auth_con_setrcache(krb5_context context, 494 krb5_auth_context auth_context, 495 krb5_rcache rcache) 496 { 497 auth_context->rcache = rcache; 498 return 0; 499 } 500 501 #if 0 /* not implemented */ 502 503 krb5_error_code KRB5_LIB_FUNCTION 504 krb5_auth_con_initivector(krb5_context context, 505 krb5_auth_context auth_context) 506 { 507 krb5_abortx(context, "unimplemented krb5_auth_con_initivector called"); 508 } 509 510 511 krb5_error_code KRB5_LIB_FUNCTION 512 krb5_auth_con_setivector(krb5_context context, 513 krb5_auth_context auth_context, 514 krb5_pointer ivector) 515 { 516 krb5_abortx(context, "unimplemented krb5_auth_con_setivector called"); 517 } 518 519 #endif /* not implemented */ 520