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