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
krb5_auth_con_init(krb5_context context,krb5_auth_context * auth_context)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
krb5_auth_con_free(krb5_context context,krb5_auth_context auth_context)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
krb5_auth_con_setflags(krb5_context context,krb5_auth_context auth_context,int32_t flags)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
krb5_auth_con_getflags(krb5_context context,krb5_auth_context auth_context,int32_t * flags)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
krb5_auth_con_addflags(krb5_context context,krb5_auth_context auth_context,int32_t addflags,int32_t * flags)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
krb5_auth_con_removeflags(krb5_context context,krb5_auth_context auth_context,int32_t removeflags,int32_t * flags)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
krb5_auth_con_setaddrs(krb5_context context,krb5_auth_context auth_context,krb5_address * local_addr,krb5_address * remote_addr)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
krb5_auth_con_genaddrs(krb5_context context,krb5_auth_context auth_context,krb5_socket_t fd,int flags)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
krb5_auth_con_setaddrs_from_fd(krb5_context context,krb5_auth_context auth_context,void * p_fd)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
krb5_auth_con_getaddrs(krb5_context context,krb5_auth_context auth_context,krb5_address ** local_addr,krb5_address ** remote_addr)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
copy_key(krb5_context context,krb5_keyblock * in,krb5_keyblock ** out)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
krb5_auth_con_getkey(krb5_context context,krb5_auth_context auth_context,krb5_keyblock ** keyblock)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
krb5_auth_con_getlocalsubkey(krb5_context context,krb5_auth_context auth_context,krb5_keyblock ** keyblock)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
krb5_auth_con_getremotesubkey(krb5_context context,krb5_auth_context auth_context,krb5_keyblock ** keyblock)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
krb5_auth_con_setkey(krb5_context context,krb5_auth_context auth_context,krb5_keyblock * keyblock)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
krb5_auth_con_setlocalsubkey(krb5_context context,krb5_auth_context auth_context,krb5_keyblock * keyblock)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
krb5_auth_con_generatelocalsubkey(krb5_context context,krb5_auth_context auth_context,krb5_keyblock * key)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
krb5_auth_con_setremotesubkey(krb5_context context,krb5_auth_context auth_context,krb5_keyblock * keyblock)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
krb5_auth_con_setcksumtype(krb5_context context,krb5_auth_context auth_context,krb5_cksumtype cksumtype)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
krb5_auth_con_getcksumtype(krb5_context context,krb5_auth_context auth_context,krb5_cksumtype * cksumtype)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
krb5_auth_con_setkeytype(krb5_context context,krb5_auth_context auth_context,krb5_keytype keytype)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
krb5_auth_con_getkeytype(krb5_context context,krb5_auth_context auth_context,krb5_keytype * keytype)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
krb5_auth_con_getlocalseqnumber(krb5_context context,krb5_auth_context auth_context,int32_t * seqnumber)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
krb5_auth_con_setlocalseqnumber(krb5_context context,krb5_auth_context auth_context,int32_t seqnumber)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
krb5_auth_con_getremoteseqnumber(krb5_context context,krb5_auth_context auth_context,int32_t * seqnumber)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
krb5_auth_con_setremoteseqnumber(krb5_context context,krb5_auth_context auth_context,int32_t seqnumber)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
krb5_auth_con_getauthenticator(krb5_context context,krb5_auth_context auth_context,krb5_authenticator * authenticator)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
krb5_free_authenticator(krb5_context context,krb5_authenticator * authenticator)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
krb5_auth_con_setuserkey(krb5_context context,krb5_auth_context auth_context,krb5_keyblock * keyblock)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
krb5_auth_con_getrcache(krb5_context context,krb5_auth_context auth_context,krb5_rcache * rcache)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
krb5_auth_con_setrcache(krb5_context context,krb5_auth_context auth_context,krb5_rcache rcache)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