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