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