Home | History | Annotate | Line # | Download | only in krb5
      1 /*	$NetBSD: import_sec_context.c,v 1.2 2017/01/28 21:31:46 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1999 - 2003 Kungliga Tekniska Hgskolan
      5  * (Royal Institute of Technology, Stockholm, Sweden).
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * 3. Neither the name of the Institute nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #include "gsskrb5_locl.h"
     37 
     38 OM_uint32 GSSAPI_CALLCONV
     39 _gsskrb5_import_sec_context (
     40     OM_uint32 * minor_status,
     41     const gss_buffer_t interprocess_token,
     42     gss_ctx_id_t * context_handle
     43     )
     44 {
     45     OM_uint32 ret = GSS_S_FAILURE;
     46     krb5_context context;
     47     krb5_error_code kret;
     48     krb5_storage *sp;
     49     krb5_auth_context ac;
     50     krb5_address local, remote;
     51     krb5_address *localp, *remotep;
     52     krb5_data data;
     53     gss_buffer_desc buffer;
     54     krb5_keyblock keyblock;
     55     int32_t flags, tmp;
     56     gsskrb5_ctx ctx;
     57     gss_name_t name;
     58 
     59     GSSAPI_KRB5_INIT (&context);
     60 
     61     *context_handle = GSS_C_NO_CONTEXT;
     62 
     63     localp = remotep = NULL;
     64 
     65     sp = krb5_storage_from_mem (interprocess_token->value,
     66 				interprocess_token->length);
     67     if (sp == NULL) {
     68 	*minor_status = ENOMEM;
     69 	return GSS_S_FAILURE;
     70     }
     71 
     72     ctx = calloc(1, sizeof(*ctx));
     73     if (ctx == NULL) {
     74 	*minor_status = ENOMEM;
     75 	krb5_storage_free (sp);
     76 	return GSS_S_FAILURE;
     77     }
     78     HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
     79 
     80     kret = krb5_auth_con_init (context,
     81 			       &ctx->auth_context);
     82     if (kret) {
     83 	*minor_status = kret;
     84 	ret = GSS_S_FAILURE;
     85 	goto failure;
     86     }
     87 
     88     /* flags */
     89 
     90     *minor_status = 0;
     91 
     92     if (krb5_ret_int32 (sp, &flags) != 0)
     93 	goto failure;
     94 
     95     /* retrieve the auth context */
     96 
     97     ac = ctx->auth_context;
     98     if (krb5_ret_int32 (sp, &tmp) != 0)
     99 	goto failure;
    100     ac->flags = tmp;
    101     if (flags & SC_LOCAL_ADDRESS) {
    102 	if (krb5_ret_address (sp, localp = &local) != 0)
    103 	    goto failure;
    104     }
    105 
    106     if (flags & SC_REMOTE_ADDRESS) {
    107 	if (krb5_ret_address (sp, remotep = &remote) != 0)
    108 	    goto failure;
    109     }
    110 
    111     krb5_auth_con_setaddrs (context, ac, localp, remotep);
    112     if (localp)
    113 	krb5_free_address (context, localp);
    114     if (remotep)
    115 	krb5_free_address (context, remotep);
    116     localp = remotep = NULL;
    117 
    118     if (krb5_ret_int16 (sp, &ac->local_port) != 0)
    119 	goto failure;
    120 
    121     if (krb5_ret_int16 (sp, &ac->remote_port) != 0)
    122 	goto failure;
    123     if (flags & SC_KEYBLOCK) {
    124 	if (krb5_ret_keyblock (sp, &keyblock) != 0)
    125 	    goto failure;
    126 	krb5_auth_con_setkey (context, ac, &keyblock);
    127 	krb5_free_keyblock_contents (context, &keyblock);
    128     }
    129     if (flags & SC_LOCAL_SUBKEY) {
    130 	if (krb5_ret_keyblock (sp, &keyblock) != 0)
    131 	    goto failure;
    132 	krb5_auth_con_setlocalsubkey (context, ac, &keyblock);
    133 	krb5_free_keyblock_contents (context, &keyblock);
    134     }
    135     if (flags & SC_REMOTE_SUBKEY) {
    136 	if (krb5_ret_keyblock (sp, &keyblock) != 0)
    137 	    goto failure;
    138 	krb5_auth_con_setremotesubkey (context, ac, &keyblock);
    139 	krb5_free_keyblock_contents (context, &keyblock);
    140     }
    141     if (krb5_ret_uint32 (sp, &ac->local_seqnumber))
    142 	goto failure;
    143     if (krb5_ret_uint32 (sp, &ac->remote_seqnumber))
    144 	goto failure;
    145 
    146     if (krb5_ret_int32 (sp, &tmp) != 0)
    147 	goto failure;
    148     ac->keytype = tmp;
    149     if (krb5_ret_int32 (sp, &tmp) != 0)
    150 	goto failure;
    151     ac->cksumtype = tmp;
    152 
    153     /* names */
    154 
    155     if (krb5_ret_data (sp, &data))
    156 	goto failure;
    157     buffer.value  = data.data;
    158     buffer.length = data.length;
    159 
    160     ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
    161 				&name);
    162     if (ret) {
    163 	ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
    164 				    &name);
    165 	if (ret) {
    166 	    krb5_data_free (&data);
    167 	    goto failure;
    168 	}
    169     }
    170     ctx->source = (krb5_principal)name;
    171     krb5_data_free (&data);
    172 
    173     if (krb5_ret_data (sp, &data) != 0)
    174 	goto failure;
    175     buffer.value  = data.data;
    176     buffer.length = data.length;
    177 
    178     ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME,
    179 				&name);
    180     if (ret) {
    181 	ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID,
    182 				    &name);
    183 	if (ret) {
    184 	    krb5_data_free (&data);
    185 	    goto failure;
    186 	}
    187     }
    188     ctx->target = (krb5_principal)name;
    189     krb5_data_free (&data);
    190 
    191     if (krb5_ret_int32 (sp, &tmp))
    192 	goto failure;
    193     ctx->flags = tmp;
    194     if (krb5_ret_int32 (sp, &tmp))
    195 	goto failure;
    196     ctx->more_flags = tmp;
    197     /*
    198      * XXX endtime should be a 64-bit int, but we don't have
    199      * krb5_ret_int64() yet.
    200      */
    201     if (krb5_ret_int32 (sp, &tmp))
    202 	goto failure;
    203     ctx->endtime = tmp;
    204 
    205     ret = _gssapi_msg_order_import(minor_status, sp, &ctx->order);
    206     if (ret)
    207         goto failure;
    208 
    209     krb5_storage_free (sp);
    210 
    211     _gsskrb5i_is_cfx(context, ctx, (ctx->more_flags & LOCAL) == 0);
    212 
    213     *context_handle = (gss_ctx_id_t)ctx;
    214 
    215     return GSS_S_COMPLETE;
    216 
    217 failure:
    218     krb5_auth_con_free (context,
    219 			ctx->auth_context);
    220     if (ctx->source != NULL)
    221 	krb5_free_principal(context, ctx->source);
    222     if (ctx->target != NULL)
    223 	krb5_free_principal(context, ctx->target);
    224     if (localp)
    225 	krb5_free_address (context, localp);
    226     if (remotep)
    227 	krb5_free_address (context, remotep);
    228     if(ctx->order)
    229 	_gssapi_msg_order_destroy(&ctx->order);
    230     HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);
    231     krb5_storage_free (sp);
    232     free (ctx);
    233     *context_handle = GSS_C_NO_CONTEXT;
    234     return ret;
    235 }
    236