auth_context.c revision 102644
1259698Sdim/*
2259698Sdim * Copyright (c) 1997 - 2001 Kungliga Tekniska H�gskolan
3259698Sdim * (Royal Institute of Technology, Stockholm, Sweden).
4259698Sdim * All rights reserved.
5259698Sdim *
6259698Sdim * Redistribution and use in source and binary forms, with or without
7259698Sdim * modification, are permitted provided that the following conditions
8259698Sdim * are met:
9259698Sdim *
10259698Sdim * 1. Redistributions of source code must retain the above copyright
11259698Sdim *    notice, this list of conditions and the following disclaimer.
12259698Sdim *
13259698Sdim * 2. Redistributions in binary form must reproduce the above copyright
14259698Sdim *    notice, this list of conditions and the following disclaimer in the
15259698Sdim *    documentation and/or other materials provided with the distribution.
16259698Sdim *
17259698Sdim * 3. Neither the name of the Institute nor the names of its contributors
18259698Sdim *    may be used to endorse or promote products derived from this software
19259698Sdim *    without specific prior written permission.
20259698Sdim *
21259698Sdim * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22259698Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23259698Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24259698Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25259698Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26259698Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27259698Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28259698Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29259698Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30259698Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31259698Sdim * SUCH DAMAGE.
32259698Sdim */
33259698Sdim
34259698Sdim#include "krb5_locl.h"
35259698Sdim
36259698SdimRCSID("$Id: auth_context.c,v 1.58 2002/08/15 08:23:07 joda Exp $");
37259698Sdim
38259698Sdimkrb5_error_code
39259698Sdimkrb5_auth_con_init(krb5_context context,
40259698Sdim		   krb5_auth_context *auth_context)
41259698Sdim{
42259698Sdim    krb5_auth_context p;
43259698Sdim
44259698Sdim    ALLOC(p, 1);
45259698Sdim    if(!p) {
46259698Sdim	krb5_set_error_string(context, "malloc: out of memory");
47259698Sdim	return ENOMEM;
48259698Sdim    }
49259698Sdim    memset(p, 0, sizeof(*p));
50259698Sdim    ALLOC(p->authenticator, 1);
51259698Sdim    if (!p->authenticator) {
52259698Sdim	krb5_set_error_string(context, "malloc: out of memory");
53259698Sdim	free(p);
54259698Sdim	return ENOMEM;
55259698Sdim    }
56259698Sdim    memset (p->authenticator, 0, sizeof(*p->authenticator));
57259698Sdim    p->flags = KRB5_AUTH_CONTEXT_DO_TIME;
58259698Sdim
59259698Sdim    p->local_address  = NULL;
60259698Sdim    p->remote_address = NULL;
61259698Sdim    p->local_port     = 0;
62259698Sdim    p->remote_port    = 0;
63259698Sdim    p->keytype        = KEYTYPE_NULL;
64259698Sdim    p->cksumtype      = CKSUMTYPE_NONE;
65259698Sdim    *auth_context     = p;
66259698Sdim    return 0;
67259698Sdim}
68259698Sdim
69259698Sdimkrb5_error_code
70259698Sdimkrb5_auth_con_free(krb5_context context,
71259698Sdim		   krb5_auth_context auth_context)
72259698Sdim{
73259698Sdim    if (auth_context != NULL) {
74259698Sdim	krb5_free_authenticator(context, &auth_context->authenticator);
75259698Sdim	if(auth_context->local_address){
76259698Sdim	    free_HostAddress(auth_context->local_address);
77259698Sdim	    free(auth_context->local_address);
78259698Sdim	}
79259698Sdim	if(auth_context->remote_address){
80259698Sdim	    free_HostAddress(auth_context->remote_address);
81259698Sdim	    free(auth_context->remote_address);
82259698Sdim	}
83259698Sdim	krb5_free_keyblock(context, auth_context->keyblock);
84259698Sdim	krb5_free_keyblock(context, auth_context->remote_subkey);
85259698Sdim	krb5_free_keyblock(context, auth_context->local_subkey);
86259698Sdim	free (auth_context);
87259698Sdim    }
88259698Sdim    return 0;
89259698Sdim}
90259698Sdim
91259698Sdimkrb5_error_code
92259698Sdimkrb5_auth_con_setflags(krb5_context context,
93259698Sdim		       krb5_auth_context auth_context,
94259698Sdim		       int32_t flags)
95259698Sdim{
96259698Sdim    auth_context->flags = flags;
97259698Sdim    return 0;
98259698Sdim}
99259698Sdim
100259698Sdim
101259698Sdimkrb5_error_code
102259698Sdimkrb5_auth_con_getflags(krb5_context context,
103259698Sdim		       krb5_auth_context auth_context,
104259698Sdim		       int32_t *flags)
105259698Sdim{
106259698Sdim    *flags = auth_context->flags;
107259698Sdim    return 0;
108259698Sdim}
109259698Sdim
110259698Sdim
111259698Sdimkrb5_error_code
112259698Sdimkrb5_auth_con_setaddrs(krb5_context context,
113259698Sdim		       krb5_auth_context auth_context,
114259698Sdim		       krb5_address *local_addr,
115259698Sdim		       krb5_address *remote_addr)
116259698Sdim{
117259698Sdim    if (local_addr) {
118	if (auth_context->local_address)
119	    krb5_free_address (context, auth_context->local_address);
120	else
121	    auth_context->local_address = malloc(sizeof(krb5_address));
122	krb5_copy_address(context, local_addr, auth_context->local_address);
123    }
124    if (remote_addr) {
125	if (auth_context->remote_address)
126	    krb5_free_address (context, auth_context->remote_address);
127	else
128	    auth_context->remote_address = malloc(sizeof(krb5_address));
129	krb5_copy_address(context, remote_addr, auth_context->remote_address);
130    }
131    return 0;
132}
133
134krb5_error_code
135krb5_auth_con_genaddrs(krb5_context context,
136		       krb5_auth_context auth_context,
137		       int fd, int flags)
138{
139    krb5_error_code ret;
140    krb5_address local_k_address, remote_k_address;
141    krb5_address *lptr = NULL, *rptr = NULL;
142    struct sockaddr_storage ss_local, ss_remote;
143    struct sockaddr *local  = (struct sockaddr *)&ss_local;
144    struct sockaddr *remote = (struct sockaddr *)&ss_remote;
145    socklen_t len;
146
147    if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR) {
148	if (auth_context->local_address == NULL) {
149	    len = sizeof(ss_local);
150	    if(getsockname(fd, local, &len) < 0) {
151		ret = errno;
152		krb5_set_error_string (context, "getsockname: %s",
153				       strerror(ret));
154		goto out;
155	    }
156	    ret = krb5_sockaddr2address (context, local, &local_k_address);
157	    if(ret) goto out;
158	    if(flags & KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR) {
159		krb5_sockaddr2port (context, local, &auth_context->local_port);
160	    } else
161		auth_context->local_port = 0;
162	    lptr = &local_k_address;
163	}
164    }
165    if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_ADDR) {
166	len = sizeof(ss_remote);
167	if(getpeername(fd, remote, &len) < 0) {
168	    ret = errno;
169	    krb5_set_error_string (context, "getpeername: %s", strerror(ret));
170	    goto out;
171	}
172	ret = krb5_sockaddr2address (context, remote, &remote_k_address);
173	if(ret) goto out;
174	if(flags & KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR) {
175	    krb5_sockaddr2port (context, remote, &auth_context->remote_port);
176	} else
177	    auth_context->remote_port = 0;
178	rptr = &remote_k_address;
179    }
180    ret = krb5_auth_con_setaddrs (context,
181				  auth_context,
182				  lptr,
183				  rptr);
184  out:
185    if (lptr)
186	krb5_free_address (context, lptr);
187    if (rptr)
188	krb5_free_address (context, rptr);
189    return ret;
190
191}
192
193krb5_error_code
194krb5_auth_con_setaddrs_from_fd (krb5_context context,
195				krb5_auth_context auth_context,
196				void *p_fd)
197{
198    int fd = *(int*)p_fd;
199    int flags = 0;
200    if(auth_context->local_address == NULL)
201	flags |= KRB5_AUTH_CONTEXT_GENERATE_LOCAL_FULL_ADDR;
202    if(auth_context->remote_address == NULL)
203	flags |= KRB5_AUTH_CONTEXT_GENERATE_REMOTE_FULL_ADDR;
204    return krb5_auth_con_genaddrs(context, auth_context, fd, flags);
205}
206
207krb5_error_code
208krb5_auth_con_getaddrs(krb5_context context,
209		       krb5_auth_context auth_context,
210		       krb5_address **local_addr,
211		       krb5_address **remote_addr)
212{
213    if(*local_addr)
214	krb5_free_address (context, *local_addr);
215    *local_addr = malloc (sizeof(**local_addr));
216    if (*local_addr == NULL) {
217	krb5_set_error_string(context, "malloc: out of memory");
218	return ENOMEM;
219    }
220    krb5_copy_address(context,
221		      auth_context->local_address,
222		      *local_addr);
223
224    if(*remote_addr)
225	krb5_free_address (context, *remote_addr);
226    *remote_addr = malloc (sizeof(**remote_addr));
227    if (*remote_addr == NULL) {
228	krb5_set_error_string(context, "malloc: out of memory");
229	krb5_free_address (context, *local_addr);
230	*local_addr = NULL;
231	return ENOMEM;
232    }
233    krb5_copy_address(context,
234		      auth_context->remote_address,
235		      *remote_addr);
236    return 0;
237}
238
239static krb5_error_code
240copy_key(krb5_context context,
241	 krb5_keyblock *in,
242	 krb5_keyblock **out)
243{
244    if(in)
245	return krb5_copy_keyblock(context, in, out);
246    *out = NULL; /* is this right? */
247    return 0;
248}
249
250krb5_error_code
251krb5_auth_con_getkey(krb5_context context,
252		     krb5_auth_context auth_context,
253		     krb5_keyblock **keyblock)
254{
255    return copy_key(context, auth_context->keyblock, keyblock);
256}
257
258krb5_error_code
259krb5_auth_con_getlocalsubkey(krb5_context context,
260			     krb5_auth_context auth_context,
261			     krb5_keyblock **keyblock)
262{
263    return copy_key(context, auth_context->local_subkey, keyblock);
264}
265
266krb5_error_code
267krb5_auth_con_getremotesubkey(krb5_context context,
268			      krb5_auth_context auth_context,
269			      krb5_keyblock **keyblock)
270{
271    return copy_key(context, auth_context->remote_subkey, keyblock);
272}
273
274krb5_error_code
275krb5_auth_con_setkey(krb5_context context,
276		     krb5_auth_context auth_context,
277		     krb5_keyblock *keyblock)
278{
279    if(auth_context->keyblock)
280	krb5_free_keyblock(context, auth_context->keyblock);
281    return copy_key(context, keyblock, &auth_context->keyblock);
282}
283
284krb5_error_code
285krb5_auth_con_setlocalsubkey(krb5_context context,
286			     krb5_auth_context auth_context,
287			     krb5_keyblock *keyblock)
288{
289    if(auth_context->local_subkey)
290	krb5_free_keyblock(context, auth_context->local_subkey);
291    return copy_key(context, keyblock, &auth_context->local_subkey);
292}
293
294krb5_error_code
295krb5_auth_con_setremotesubkey(krb5_context context,
296			      krb5_auth_context auth_context,
297			      krb5_keyblock *keyblock)
298{
299    if(auth_context->remote_subkey)
300	krb5_free_keyblock(context, auth_context->remote_subkey);
301    return copy_key(context, keyblock, &auth_context->remote_subkey);
302}
303
304krb5_error_code
305krb5_auth_con_setcksumtype(krb5_context context,
306			   krb5_auth_context auth_context,
307			   krb5_cksumtype cksumtype)
308{
309    auth_context->cksumtype = cksumtype;
310    return 0;
311}
312
313krb5_error_code
314krb5_auth_con_getcksumtype(krb5_context context,
315			   krb5_auth_context auth_context,
316			   krb5_cksumtype *cksumtype)
317{
318    *cksumtype = auth_context->cksumtype;
319    return 0;
320}
321
322krb5_error_code
323krb5_auth_con_setkeytype (krb5_context context,
324			  krb5_auth_context auth_context,
325			  krb5_keytype keytype)
326{
327    auth_context->keytype = keytype;
328    return 0;
329}
330
331krb5_error_code
332krb5_auth_con_getkeytype (krb5_context context,
333			  krb5_auth_context auth_context,
334			  krb5_keytype *keytype)
335{
336    *keytype = auth_context->keytype;
337    return 0;
338}
339
340#if 0
341krb5_error_code
342krb5_auth_con_setenctype(krb5_context context,
343			 krb5_auth_context auth_context,
344			 krb5_enctype etype)
345{
346    if(auth_context->keyblock)
347	krb5_free_keyblock(context, auth_context->keyblock);
348    ALLOC(auth_context->keyblock, 1);
349    if(auth_context->keyblock == NULL)
350	return ENOMEM;
351    auth_context->keyblock->keytype = etype;
352    return 0;
353}
354
355krb5_error_code
356krb5_auth_con_getenctype(krb5_context context,
357			 krb5_auth_context auth_context,
358			 krb5_enctype *etype)
359{
360    krb5_abortx(context, "unimplemented krb5_auth_getenctype called");
361}
362#endif
363
364krb5_error_code
365krb5_auth_con_getlocalseqnumber(krb5_context context,
366			    krb5_auth_context auth_context,
367			    int32_t *seqnumber)
368{
369  *seqnumber = auth_context->local_seqnumber;
370  return 0;
371}
372
373krb5_error_code
374krb5_auth_con_setlocalseqnumber (krb5_context context,
375			     krb5_auth_context auth_context,
376			     int32_t seqnumber)
377{
378  auth_context->local_seqnumber = seqnumber;
379  return 0;
380}
381
382krb5_error_code
383krb5_auth_getremoteseqnumber(krb5_context context,
384			     krb5_auth_context auth_context,
385			     int32_t *seqnumber)
386{
387  *seqnumber = auth_context->remote_seqnumber;
388  return 0;
389}
390
391krb5_error_code
392krb5_auth_con_setremoteseqnumber (krb5_context context,
393			      krb5_auth_context auth_context,
394			      int32_t seqnumber)
395{
396  auth_context->remote_seqnumber = seqnumber;
397  return 0;
398}
399
400
401krb5_error_code
402krb5_auth_con_getauthenticator(krb5_context context,
403			   krb5_auth_context auth_context,
404			   krb5_authenticator *authenticator)
405{
406    *authenticator = malloc(sizeof(**authenticator));
407    if (*authenticator == NULL) {
408	krb5_set_error_string(context, "malloc: out of memory");
409	return ENOMEM;
410    }
411
412    copy_Authenticator(auth_context->authenticator,
413		       *authenticator);
414    return 0;
415}
416
417
418void
419krb5_free_authenticator(krb5_context context,
420			krb5_authenticator *authenticator)
421{
422    free_Authenticator (*authenticator);
423    free (*authenticator);
424    *authenticator = NULL;
425}
426
427
428krb5_error_code
429krb5_auth_con_setuserkey(krb5_context context,
430			 krb5_auth_context auth_context,
431			 krb5_keyblock *keyblock)
432{
433    if(auth_context->keyblock)
434	krb5_free_keyblock(context, auth_context->keyblock);
435    return krb5_copy_keyblock(context, keyblock, &auth_context->keyblock);
436}
437
438krb5_error_code
439krb5_auth_con_getrcache(krb5_context context,
440			krb5_auth_context auth_context,
441			krb5_rcache *rcache)
442{
443    *rcache = auth_context->rcache;
444    return 0;
445}
446
447krb5_error_code
448krb5_auth_con_setrcache(krb5_context context,
449			krb5_auth_context auth_context,
450			krb5_rcache rcache)
451{
452    auth_context->rcache = rcache;
453    return 0;
454}
455
456#if 0 /* not implemented */
457
458krb5_error_code
459krb5_auth_con_initivector(krb5_context context,
460			  krb5_auth_context auth_context)
461{
462    krb5_abortx(context, "unimplemented krb5_auth_con_initivector called");
463}
464
465
466krb5_error_code
467krb5_auth_con_setivector(krb5_context context,
468			 krb5_auth_context auth_context,
469			 krb5_pointer ivector)
470{
471    krb5_abortx(context, "unimplemented krb5_auth_con_setivector called");
472}
473
474#endif /* not implemented */
475