1 /* 2 * Copyright (c) 1997 - 2000 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.55 2000/12/10 20:01:05 assar 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 return ENOMEM; 47 memset(p, 0, sizeof(*p)); 48 ALLOC(p->authenticator, 1); 49 if (!p->authenticator) { 50 free(p); 51 return ENOMEM; 52 } 53 memset (p->authenticator, 0, sizeof(*p->authenticator)); 54 p->flags = KRB5_AUTH_CONTEXT_DO_TIME; 55 56 p->local_address = NULL; 57 p->remote_address = NULL; 58 p->local_port = 0; 59 p->remote_port = 0; 60 p->keytype = KEYTYPE_NULL; 61 p->cksumtype = CKSUMTYPE_NONE; 62 *auth_context = p; 63 return 0; 64 } 65 66 krb5_error_code 67 krb5_auth_con_free(krb5_context context, 68 krb5_auth_context auth_context) 69 { 70 if (auth_context != NULL) { 71 krb5_free_authenticator(context, &auth_context->authenticator); 72 if(auth_context->local_address){ 73 free_HostAddress(auth_context->local_address); 74 free(auth_context->local_address); 75 } 76 if(auth_context->remote_address){ 77 free_HostAddress(auth_context->remote_address); 78 free(auth_context->remote_address); 79 } 80 krb5_free_keyblock(context, auth_context->keyblock); 81 krb5_free_keyblock(context, auth_context->remote_subkey); 82 krb5_free_keyblock(context, auth_context->local_subkey); 83 free (auth_context); 84 } 85 return 0; 86 } 87 88 krb5_error_code 89 krb5_auth_con_setflags(krb5_context context, 90 krb5_auth_context auth_context, 91 int32_t flags) 92 { 93 auth_context->flags = flags; 94 return 0; 95 } 96 97 98 krb5_error_code 99 krb5_auth_con_getflags(krb5_context context, 100 krb5_auth_context auth_context, 101 int32_t *flags) 102 { 103 *flags = auth_context->flags; 104 return 0; 105 } 106 107 108 krb5_error_code 109 krb5_auth_con_setaddrs(krb5_context context, 110 krb5_auth_context auth_context, 111 krb5_address *local_addr, 112 krb5_address *remote_addr) 113 { 114 if (local_addr) { 115 if (auth_context->local_address) 116 krb5_free_address (context, auth_context->local_address); 117 else 118 auth_context->local_address = malloc(sizeof(krb5_address)); 119 krb5_copy_address(context, local_addr, auth_context->local_address); 120 } 121 if (remote_addr) { 122 if (auth_context->remote_address) 123 krb5_free_address (context, auth_context->remote_address); 124 else 125 auth_context->remote_address = malloc(sizeof(krb5_address)); 126 krb5_copy_address(context, remote_addr, auth_context->remote_address); 127 } 128 return 0; 129 } 130 131 krb5_error_code 132 krb5_auth_con_genaddrs(krb5_context context, 133 krb5_auth_context auth_context, 134 int fd, int flags) 135 { 136 krb5_error_code ret; 137 krb5_address local_k_address, remote_k_address; 138 krb5_address *lptr = NULL, *rptr = NULL; 139 struct sockaddr_storage ss_local, ss_remote; 140 struct sockaddr *local = (struct sockaddr *)&ss_local; 141 struct sockaddr *remote = (struct sockaddr *)&ss_remote; 142 socklen_t len; 143 144 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) { 145 if (auth_context->local_address == NULL) { 146 len = sizeof(ss_local); 147 if(getsockname(fd, local, &len) < 0) { 148 ret = errno; 149 goto out; 150 } 151 krb5_sockaddr2address (local, &local_k_address); 152 if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) { 153 krb5_sockaddr2port (local, &auth_context->local_port); 154 } else 155 auth_context->local_port = 0; 156 lptr = &local_k_address; 157 } 158 } 159 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) { 160 len = sizeof(ss_remote); 161 if(getpeername(fd, remote, &len) < 0) { 162 ret = errno; 163 goto out; 164 } 165 krb5_sockaddr2address (remote, &remote_k_address); 166 if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) { 167 krb5_sockaddr2port (remote, &auth_context->remote_port); 168 } else 169 auth_context->remote_port = 0; 170 rptr = &remote_k_address; 171 } 172 ret = krb5_auth_con_setaddrs (context, 173 auth_context, 174 lptr, 175 rptr); 176 out: 177 if (lptr) 178 krb5_free_address (context, lptr); 179 if (rptr) 180 krb5_free_address (context, rptr); 181 return ret; 182 183 } 184 185 krb5_error_code 186 krb5_auth_con_setaddrs_from_fd (krb5_context context, 187 krb5_auth_context auth_context, 188 void *p_fd) 189 { 190 int fd = *(int*)p_fd; 191 int flags = 0; 192 if(auth_context->local_address == NULL) 193 flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR; 194 if(auth_context->remote_address == NULL) 195 flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR; 196 return krb5_auth_con_genaddrs(context, auth_context, fd, flags); 197 } 198 199 krb5_error_code 200 krb5_auth_con_getaddrs(krb5_context context, 201 krb5_auth_context auth_context, 202 krb5_address **local_addr, 203 krb5_address **remote_addr) 204 { 205 if(*local_addr) 206 krb5_free_address (context, *local_addr); 207 *local_addr = malloc (sizeof(**local_addr)); 208 if (*local_addr == NULL) 209 return ENOMEM; 210 krb5_copy_address(context, 211 auth_context->local_address, 212 *local_addr); 213 214 if(*remote_addr) 215 krb5_free_address (context, *remote_addr); 216 *remote_addr = malloc (sizeof(**remote_addr)); 217 if (*remote_addr == NULL) 218 return ENOMEM; 219 krb5_copy_address(context, 220 auth_context->remote_address, 221 *remote_addr); 222 return 0; 223 } 224 225 static krb5_error_code 226 copy_key(krb5_context context, 227 krb5_keyblock *in, 228 krb5_keyblock **out) 229 { 230 if(in) 231 return krb5_copy_keyblock(context, in, out); 232 *out = NULL; /* is this right? */ 233 return 0; 234 } 235 236 krb5_error_code 237 krb5_auth_con_getkey(krb5_context context, 238 krb5_auth_context auth_context, 239 krb5_keyblock **keyblock) 240 { 241 return copy_key(context, auth_context->keyblock, keyblock); 242 } 243 244 krb5_error_code 245 krb5_auth_con_getlocalsubkey(krb5_context context, 246 krb5_auth_context auth_context, 247 krb5_keyblock **keyblock) 248 { 249 return copy_key(context, auth_context->local_subkey, keyblock); 250 } 251 252 krb5_error_code 253 krb5_auth_con_getremotesubkey(krb5_context context, 254 krb5_auth_context auth_context, 255 krb5_keyblock **keyblock) 256 { 257 return copy_key(context, auth_context->remote_subkey, keyblock); 258 } 259 260 krb5_error_code 261 krb5_auth_con_setkey(krb5_context context, 262 krb5_auth_context auth_context, 263 krb5_keyblock *keyblock) 264 { 265 if(auth_context->keyblock) 266 krb5_free_keyblock(context, auth_context->keyblock); 267 return copy_key(context, keyblock, &auth_context->keyblock); 268 } 269 270 krb5_error_code 271 krb5_auth_con_setlocalsubkey(krb5_context context, 272 krb5_auth_context auth_context, 273 krb5_keyblock *keyblock) 274 { 275 if(auth_context->local_subkey) 276 krb5_free_keyblock(context, auth_context->local_subkey); 277 return copy_key(context, keyblock, &auth_context->local_subkey); 278 } 279 280 krb5_error_code 281 krb5_auth_con_setremotesubkey(krb5_context context, 282 krb5_auth_context auth_context, 283 krb5_keyblock *keyblock) 284 { 285 if(auth_context->remote_subkey) 286 krb5_free_keyblock(context, auth_context->remote_subkey); 287 return copy_key(context, keyblock, &auth_context->remote_subkey); 288 } 289 290 krb5_error_code 291 krb5_auth_setcksumtype(krb5_context context, 292 krb5_auth_context auth_context, 293 krb5_cksumtype cksumtype) 294 { 295 auth_context->cksumtype = cksumtype; 296 return 0; 297 } 298 299 krb5_error_code 300 krb5_auth_getcksumtype(krb5_context context, 301 krb5_auth_context auth_context, 302 krb5_cksumtype *cksumtype) 303 { 304 *cksumtype = auth_context->cksumtype; 305 return 0; 306 } 307 308 krb5_error_code 309 krb5_auth_setkeytype (krb5_context context, 310 krb5_auth_context auth_context, 311 krb5_keytype keytype) 312 { 313 auth_context->keytype = keytype; 314 return 0; 315 } 316 317 krb5_error_code 318 krb5_auth_getkeytype (krb5_context context, 319 krb5_auth_context auth_context, 320 krb5_keytype *keytype) 321 { 322 *keytype = auth_context->keytype; 323 return 0; 324 } 325 326 #if 0 327 krb5_error_code 328 krb5_auth_setenctype(krb5_context context, 329 krb5_auth_context auth_context, 330 krb5_enctype etype) 331 { 332 if(auth_context->keyblock) 333 krb5_free_keyblock(context, auth_context->keyblock); 334 ALLOC(auth_context->keyblock, 1); 335 if(auth_context->keyblock == NULL) 336 return ENOMEM; 337 auth_context->keyblock->keytype = etype; 338 return 0; 339 } 340 341 krb5_error_code 342 krb5_auth_getenctype(krb5_context context, 343 krb5_auth_context auth_context, 344 krb5_enctype *etype) 345 { 346 krb5_abortx(context, "unimplemented krb5_auth_getenctype called"); 347 } 348 #endif 349 350 krb5_error_code 351 krb5_auth_getlocalseqnumber(krb5_context context, 352 krb5_auth_context auth_context, 353 int32_t *seqnumber) 354 { 355 *seqnumber = auth_context->local_seqnumber; 356 return 0; 357 } 358 359 krb5_error_code 360 krb5_auth_setlocalseqnumber (krb5_context context, 361 krb5_auth_context auth_context, 362 int32_t seqnumber) 363 { 364 auth_context->local_seqnumber = seqnumber; 365 return 0; 366 } 367 368 krb5_error_code 369 krb5_auth_getremoteseqnumber(krb5_context context, 370 krb5_auth_context auth_context, 371 int32_t *seqnumber) 372 { 373 *seqnumber = auth_context->remote_seqnumber; 374 return 0; 375 } 376 377 krb5_error_code 378 krb5_auth_setremoteseqnumber (krb5_context context, 379 krb5_auth_context auth_context, 380 int32_t seqnumber) 381 { 382 auth_context->remote_seqnumber = seqnumber; 383 return 0; 384 } 385 386 387 krb5_error_code 388 krb5_auth_getauthenticator(krb5_context context, 389 krb5_auth_context auth_context, 390 krb5_authenticator *authenticator) 391 { 392 *authenticator = malloc(sizeof(**authenticator)); 393 if (*authenticator == NULL) 394 return ENOMEM; 395 396 copy_Authenticator(auth_context->authenticator, 397 *authenticator); 398 return 0; 399 } 400 401 402 void 403 krb5_free_authenticator(krb5_context context, 404 krb5_authenticator *authenticator) 405 { 406 free_Authenticator (*authenticator); 407 free (*authenticator); 408 *authenticator = NULL; 409 } 410 411 412 krb5_error_code 413 krb5_auth_con_setuserkey(krb5_context context, 414 krb5_auth_context auth_context, 415 krb5_keyblock *keyblock) 416 { 417 if(auth_context->keyblock) 418 krb5_free_keyblock(context, auth_context->keyblock); 419 return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock); 420 } 421 422 krb5_error_code 423 krb5_auth_con_getrcache(krb5_context context, 424 krb5_auth_context auth_context, 425 krb5_rcache *rcache) 426 { 427 *rcache = auth_context->rcache; 428 return 0; 429 } 430 431 krb5_error_code 432 krb5_auth_con_setrcache(krb5_context context, 433 krb5_auth_context auth_context, 434 krb5_rcache rcache) 435 { 436 auth_context->rcache = rcache; 437 return 0; 438 } 439 440 #if 0 /* not implemented */ 441 442 krb5_error_code 443 krb5_auth_con_initivector(krb5_context context, 444 krb5_auth_context auth_context) 445 { 446 krb5_abortx(context, "unimplemented krb5_auth_con_initivector called"); 447 } 448 449 450 krb5_error_code 451 krb5_auth_con_setivector(krb5_context context, 452 krb5_auth_context auth_context, 453 krb5_pointer ivector) 454 { 455 krb5_abortx(context, "unimplemented krb5_auth_con_setivector called"); 456 } 457 458 #endif /* not implemented */ 459