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