/ lib / gssapi / krb5 / import_sec_context.c
import_sec_context.c
  1  /*
  2   * Copyright (c) 1999 - 2003 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 "gsskrb5_locl.h"
 35  
 36  OM_uint32 GSSAPI_CALLCONV
 37  _gsskrb5_import_sec_context (
 38      OM_uint32 * minor_status,
 39      const gss_buffer_t interprocess_token,
 40      gss_ctx_id_t * context_handle
 41      )
 42  {
 43      OM_uint32 ret = GSS_S_FAILURE;
 44      krb5_context context;
 45      krb5_error_code kret;
 46      krb5_storage *sp;
 47      krb5_auth_context ac;
 48      krb5_address local, remote;
 49      krb5_address *localp, *remotep;
 50      krb5_data data;
 51      gss_buffer_desc buffer;
 52      krb5_keyblock keyblock;
 53      int32_t flags, tmp;
 54      gsskrb5_ctx ctx;
 55      gss_name_t name;
 56  
 57      GSSAPI_KRB5_INIT (&context);
 58  
 59      *context_handle = GSS_C_NO_CONTEXT;
 60  
 61      localp = remotep = NULL;
 62  
 63      sp = krb5_storage_from_mem (interprocess_token->value,
 64  				interprocess_token->length);
 65      if (sp == NULL) {
 66  	*minor_status = ENOMEM;
 67  	return GSS_S_FAILURE;
 68      }
 69  
 70      ctx = calloc(1, sizeof(*ctx));
 71      if (ctx == NULL) {
 72  	*minor_status = ENOMEM;
 73  	krb5_storage_free (sp);
 74  	return GSS_S_FAILURE;
 75      }
 76      HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
 77  
 78      kret = krb5_auth_con_init (context,
 79  			       &ctx->auth_context);
 80      if (kret) {
 81  	*minor_status = kret;
 82  	ret = GSS_S_FAILURE;
 83  	goto failure;
 84      }
 85  
 86      /* flags */
 87  
 88      *minor_status = 0;
 89  
 90      if (krb5_ret_int32 (sp, &flags) != 0)
 91  	goto failure;
 92  
 93      /* retrieve the auth context */
 94  
 95      ac = ctx->auth_context;
 96      if (krb5_ret_int32 (sp, &tmp) != 0)
 97  	goto failure;
 98      ac->flags = tmp;
 99      if (flags & SC_LOCAL_ADDRESS) {
100  	if (krb5_ret_address (sp, localp = &local) != 0)
101  	    goto failure;
102      }
103  
104      if (flags & SC_REMOTE_ADDRESS) {
105  	if (krb5_ret_address (sp, remotep = &remote) != 0)
106  	    goto failure;
107      }
108  
109      krb5_auth_con_setaddrs (context, ac, localp, remotep);
110      if (localp)
111  	krb5_free_address (context, localp);
112      if (remotep)
113  	krb5_free_address (context, remotep);
114      localp = remotep = NULL;
115  
116      if (krb5_ret_int16 (sp, &ac->local_port) != 0)
117  	goto failure;
118  
119      if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
120  	goto failure;
121      if (flags & SC_KEYBLOCK) {
122  	if (krb5_ret_keyblock (sp, &keyblock) != 0)
123  	    goto failure;
124  	krb5_auth_con_setkey (context, ac, &keyblock);
125  	krb5_free_keyblock_contents (context, &keyblock);
126      }
127      if (flags & SC_LOCAL_SUBKEY) {
128  	if (krb5_ret_keyblock (sp, &keyblock) != 0)
129  	    goto failure;
130  	krb5_auth_con_setlocalsubkey (context, ac, &keyblock);
131  	krb5_free_keyblock_contents (context, &keyblock);
132      }
133      if (flags & SC_REMOTE_SUBKEY) {
134  	if (krb5_ret_keyblock (sp, &keyblock) != 0)
135  	    goto failure;
136  	krb5_auth_con_setremotesubkey (context, ac, &keyblock);
137  	krb5_free_keyblock_contents (context, &keyblock);
138      }
139      if (krb5_ret_uint32 (sp, &ac->local_seqnumber))
140  	goto failure;
141      if (krb5_ret_uint32 (sp, &ac->remote_seqnumber))
142  	goto failure;
143  
144      if (krb5_ret_int32 (sp, &tmp) != 0)
145  	goto failure;
146      ac->keytype = tmp;
147      if (krb5_ret_int32 (sp, &tmp) != 0)
148  	goto failure;
149      ac->cksumtype = tmp;
150  
151      /* names */
152  
153      if (krb5_ret_data (sp, &data))
154  	goto failure;
155      buffer.value  = data.data;
156      buffer.length = data.length;
157  
158      ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
159  				&name);
160      if (ret) {
161  	ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
162  				    &name);
163  	if (ret) {
164  	    krb5_data_free (&data);
165  	    goto failure;
166  	}
167      }
168      ctx->source = (krb5_principal)name;
169      krb5_data_free (&data);
170  
171      if (krb5_ret_data (sp, &data) != 0)
172  	goto failure;
173      buffer.value  = data.data;
174      buffer.length = data.length;
175  
176      ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
177  				&name);
178      if (ret) {
179  	ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
180  				    &name);
181  	if (ret) {
182  	    krb5_data_free (&data);
183  	    goto failure;
184  	}
185      }
186      ctx->target = (krb5_principal)name;
187      krb5_data_free (&data);
188  
189      if (krb5_ret_int32 (sp, &tmp))
190  	goto failure;
191      ctx->flags = tmp;
192      if (krb5_ret_int32 (sp, &tmp))
193  	goto failure;
194      ctx->more_flags = tmp;
195      if (krb5_ret_int32 (sp, &tmp))
196  	goto failure;
197      ctx->endtime = tmp;
198  
199      ret = _gssapi_msg_order_import(minor_status, sp, &ctx->gk5c.order);
200      if (ret)
201          goto failure;
202  
203      krb5_storage_free (sp);
204  
205      _gsskrb5i_is_cfx(context, ctx, (ctx->more_flags & LOCAL) == 0);
206  
207      *context_handle = (gss_ctx_id_t)ctx;
208  
209      return GSS_S_COMPLETE;
210  
211  failure:
212      krb5_auth_con_free (context,
213  			ctx->auth_context);
214      if (ctx->source != NULL)
215  	krb5_free_principal(context, ctx->source);
216      if (ctx->target != NULL)
217  	krb5_free_principal(context, ctx->target);
218      if (localp)
219  	krb5_free_address (context, localp);
220      if (remotep)
221  	krb5_free_address (context, remotep);
222      if(ctx->gk5c.order)
223  	_gssapi_msg_order_destroy(&ctx->gk5c.order);
224      HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
225      krb5_storage_free (sp);
226      free (ctx);
227      *context_handle = GSS_C_NO_CONTEXT;
228      return ret;
229  }