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,v 1.59 2002/09/02 17:11:02 joda Exp $"); 37 38 krb5_error_code 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 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 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 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 111 krb5_error_code 112 krb5_auth_con_setaddrs(krb5_context context, 113 krb5_auth_context auth_context, 114 krb5_address *local_addr, 115 krb5_address *remote_addr) 116 { 117 if (local_addr) { 118 if (auth_context->local_address) 119 krb5_free_address (context, auth_context->local_address); 120 else 121 auth_context->local_address = malloc(sizeof(krb5_address)); 122 krb5_copy_address(context, local_addr, auth_context->local_address); 123 } 124 if (remote_addr) { 125 if (auth_context->remote_address) 126 krb5_free_address (context, auth_context->remote_address); 127 else 128 auth_context->remote_address = malloc(sizeof(krb5_address)); 129 krb5_copy_address(context, remote_addr, auth_context->remote_address); 130 } 131 return 0; 132 } 133 134 krb5_error_code 135 krb5_auth_con_genaddrs(krb5_context context, 136 krb5_auth_context auth_context, 137 int fd, int flags) 138 { 139 krb5_error_code ret; 140 krb5_address local_k_address, remote_k_address; 141 krb5_address *lptr = NULL, *rptr = NULL; 142 struct sockaddr_storage ss_local, ss_remote; 143 struct sockaddr *local = (struct sockaddr *)&ss_local; 144 struct sockaddr *remote = (struct sockaddr *)&ss_remote; 145 socklen_t len; 146 147 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) { 148 if (auth_context->local_address == NULL) { 149 len = sizeof(ss_local); 150 if(getsockname(fd, local, &len) < 0) { 151 ret = errno; 152 krb5_set_error_string (context, "getsockname: %s", 153 strerror(ret)); 154 goto out; 155 } 156 ret = krb5_sockaddr2address (context, local, &local_k_address); 157 if(ret) goto out; 158 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) { 159 krb5_sockaddr2port (context, local, &auth_context->local_port); 160 } else 161 auth_context->local_port = 0; 162 lptr = &local_k_address; 163 } 164 } 165 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) { 166 len = sizeof(ss_remote); 167 if(getpeername(fd, remote, &len) < 0) { 168 ret = errno; 169 krb5_set_error_string (context, "getpeername: %s", strerror(ret)); 170 goto out; 171 } 172 ret = krb5_sockaddr2address (context, remote, &remote_k_address); 173 if(ret) goto out; 174 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) { 175 krb5_sockaddr2port (context, remote, &auth_context->remote_port); 176 } else 177 auth_context->remote_port = 0; 178 rptr = &remote_k_address; 179 } 180 ret = krb5_auth_con_setaddrs (context, 181 auth_context, 182 lptr, 183 rptr); 184 out: 185 if (lptr) 186 krb5_free_address (context, lptr); 187 if (rptr) 188 krb5_free_address (context, rptr); 189 return ret; 190 191 } 192 193 krb5_error_code 194 krb5_auth_con_setaddrs_from_fd (krb5_context context, 195 krb5_auth_context auth_context, 196 void *p_fd) 197 { 198 int fd = *(int*)p_fd; 199 int flags = 0; 200 if(auth_context->local_address == NULL) 201 flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR; 202 if(auth_context->remote_address == NULL) 203 flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR; 204 return krb5_auth_con_genaddrs(context, auth_context, fd, flags); 205 } 206 207 krb5_error_code 208 krb5_auth_con_getaddrs(krb5_context context, 209 krb5_auth_context auth_context, 210 krb5_address **local_addr, 211 krb5_address **remote_addr) 212 { 213 if(*local_addr) 214 krb5_free_address (context, *local_addr); 215 *local_addr = malloc (sizeof(**local_addr)); 216 if (*local_addr == NULL) { 217 krb5_set_error_string(context, "malloc: out of memory"); 218 return ENOMEM; 219 } 220 krb5_copy_address(context, 221 auth_context->local_address, 222 *local_addr); 223 224 if(*remote_addr) 225 krb5_free_address (context, *remote_addr); 226 *remote_addr = malloc (sizeof(**remote_addr)); 227 if (*remote_addr == NULL) { 228 krb5_set_error_string(context, "malloc: out of memory"); 229 krb5_free_address (context, *local_addr); 230 *local_addr = NULL; 231 return ENOMEM; 232 } 233 krb5_copy_address(context, 234 auth_context->remote_address, 235 *remote_addr); 236 return 0; 237 } 238 239 static krb5_error_code 240 copy_key(krb5_context context, 241 krb5_keyblock *in, 242 krb5_keyblock **out) 243 { 244 if(in) 245 return krb5_copy_keyblock(context, in, out); 246 *out = NULL; /* is this right? */ 247 return 0; 248 } 249 250 krb5_error_code 251 krb5_auth_con_getkey(krb5_context context, 252 krb5_auth_context auth_context, 253 krb5_keyblock **keyblock) 254 { 255 return copy_key(context, auth_context->keyblock, keyblock); 256 } 257 258 krb5_error_code 259 krb5_auth_con_getlocalsubkey(krb5_context context, 260 krb5_auth_context auth_context, 261 krb5_keyblock **keyblock) 262 { 263 return copy_key(context, auth_context->local_subkey, keyblock); 264 } 265 266 krb5_error_code 267 krb5_auth_con_getremotesubkey(krb5_context context, 268 krb5_auth_context auth_context, 269 krb5_keyblock **keyblock) 270 { 271 return copy_key(context, auth_context->remote_subkey, keyblock); 272 } 273 274 krb5_error_code 275 krb5_auth_con_setkey(krb5_context context, 276 krb5_auth_context auth_context, 277 krb5_keyblock *keyblock) 278 { 279 if(auth_context->keyblock) 280 krb5_free_keyblock(context, auth_context->keyblock); 281 return copy_key(context, keyblock, &auth_context->keyblock); 282 } 283 284 krb5_error_code 285 krb5_auth_con_setlocalsubkey(krb5_context context, 286 krb5_auth_context auth_context, 287 krb5_keyblock *keyblock) 288 { 289 if(auth_context->local_subkey) 290 krb5_free_keyblock(context, auth_context->local_subkey); 291 return copy_key(context, keyblock, &auth_context->local_subkey); 292 } 293 294 krb5_error_code 295 krb5_auth_con_generatelocalsubkey(krb5_context context, 296 krb5_auth_context auth_context, 297 krb5_keyblock *key) 298 { 299 krb5_error_code ret; 300 krb5_keyblock *subkey; 301 302 ret = krb5_generate_subkey (context, key, &subkey); 303 if(ret) 304 return ret; 305 if(auth_context->local_subkey) 306 krb5_free_keyblock(context, auth_context->local_subkey); 307 auth_context->local_subkey = subkey; 308 return 0; 309 } 310 311 312 krb5_error_code 313 krb5_auth_con_setremotesubkey(krb5_context context, 314 krb5_auth_context auth_context, 315 krb5_keyblock *keyblock) 316 { 317 if(auth_context->remote_subkey) 318 krb5_free_keyblock(context, auth_context->remote_subkey); 319 return copy_key(context, keyblock, &auth_context->remote_subkey); 320 } 321 322 krb5_error_code 323 krb5_auth_con_setcksumtype(krb5_context context, 324 krb5_auth_context auth_context, 325 krb5_cksumtype cksumtype) 326 { 327 auth_context->cksumtype = cksumtype; 328 return 0; 329 } 330 331 krb5_error_code 332 krb5_auth_con_getcksumtype(krb5_context context, 333 krb5_auth_context auth_context, 334 krb5_cksumtype *cksumtype) 335 { 336 *cksumtype = auth_context->cksumtype; 337 return 0; 338 } 339 340 krb5_error_code 341 krb5_auth_con_setkeytype (krb5_context context, 342 krb5_auth_context auth_context, 343 krb5_keytype keytype) 344 { 345 auth_context->keytype = keytype; 346 return 0; 347 } 348 349 krb5_error_code 350 krb5_auth_con_getkeytype (krb5_context context, 351 krb5_auth_context auth_context, 352 krb5_keytype *keytype) 353 { 354 *keytype = auth_context->keytype; 355 return 0; 356 } 357 358 #if 0 359 krb5_error_code 360 krb5_auth_con_setenctype(krb5_context context, 361 krb5_auth_context auth_context, 362 krb5_enctype etype) 363 { 364 if(auth_context->keyblock) 365 krb5_free_keyblock(context, auth_context->keyblock); 366 ALLOC(auth_context->keyblock, 1); 367 if(auth_context->keyblock == NULL) 368 return ENOMEM; 369 auth_context->keyblock->keytype = etype; 370 return 0; 371 } 372 373 krb5_error_code 374 krb5_auth_con_getenctype(krb5_context context, 375 krb5_auth_context auth_context, 376 krb5_enctype *etype) 377 { 378 krb5_abortx(context, "unimplemented krb5_auth_getenctype called"); 379 } 380 #endif 381 382 krb5_error_code 383 krb5_auth_con_getlocalseqnumber(krb5_context context, 384 krb5_auth_context auth_context, 385 int32_t *seqnumber) 386 { 387 *seqnumber = auth_context->local_seqnumber; 388 return 0; 389 } 390 391 krb5_error_code 392 krb5_auth_con_setlocalseqnumber (krb5_context context, 393 krb5_auth_context auth_context, 394 int32_t seqnumber) 395 { 396 auth_context->local_seqnumber = seqnumber; 397 return 0; 398 } 399 400 krb5_error_code 401 krb5_auth_getremoteseqnumber(krb5_context context, 402 krb5_auth_context auth_context, 403 int32_t *seqnumber) 404 { 405 *seqnumber = auth_context->remote_seqnumber; 406 return 0; 407 } 408 409 krb5_error_code 410 krb5_auth_con_setremoteseqnumber (krb5_context context, 411 krb5_auth_context auth_context, 412 int32_t seqnumber) 413 { 414 auth_context->remote_seqnumber = seqnumber; 415 return 0; 416 } 417 418 419 krb5_error_code 420 krb5_auth_con_getauthenticator(krb5_context context, 421 krb5_auth_context auth_context, 422 krb5_authenticator *authenticator) 423 { 424 *authenticator = malloc(sizeof(**authenticator)); 425 if (*authenticator == NULL) { 426 krb5_set_error_string(context, "malloc: out of memory"); 427 return ENOMEM; 428 } 429 430 copy_Authenticator(auth_context->authenticator, 431 *authenticator); 432 return 0; 433 } 434 435 436 void 437 krb5_free_authenticator(krb5_context context, 438 krb5_authenticator *authenticator) 439 { 440 free_Authenticator (*authenticator); 441 free (*authenticator); 442 *authenticator = NULL; 443 } 444 445 446 krb5_error_code 447 krb5_auth_con_setuserkey(krb5_context context, 448 krb5_auth_context auth_context, 449 krb5_keyblock *keyblock) 450 { 451 if(auth_context->keyblock) 452 krb5_free_keyblock(context, auth_context->keyblock); 453 return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock); 454 } 455 456 krb5_error_code 457 krb5_auth_con_getrcache(krb5_context context, 458 krb5_auth_context auth_context, 459 krb5_rcache *rcache) 460 { 461 *rcache = auth_context->rcache; 462 return 0; 463 } 464 465 krb5_error_code 466 krb5_auth_con_setrcache(krb5_context context, 467 krb5_auth_context auth_context, 468 krb5_rcache rcache) 469 { 470 auth_context->rcache = rcache; 471 return 0; 472 } 473 474 #if 0 /* not implemented */ 475 476 krb5_error_code 477 krb5_auth_con_initivector(krb5_context context, 478 krb5_auth_context auth_context) 479 { 480 krb5_abortx(context, "unimplemented krb5_auth_con_initivector called"); 481 } 482 483 484 krb5_error_code 485 krb5_auth_con_setivector(krb5_context context, 486 krb5_auth_context auth_context, 487 krb5_pointer ivector) 488 { 489 krb5_abortx(context, "unimplemented krb5_auth_con_setivector called"); 490 } 491 492 #endif /* not implemented */ 493