Home | History | Annotate | Line # | Download | only in krb5
      1 /*	$NetBSD: export_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_export_sec_context(
     40     OM_uint32 *minor_status,
     41     gss_ctx_id_t *context_handle,
     42     gss_buffer_t interprocess_token
     43     )
     44 {
     45     krb5_context context;
     46     const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle;
     47     krb5_storage *sp;
     48     krb5_auth_context ac;
     49     OM_uint32 ret = GSS_S_COMPLETE;
     50     krb5_data data;
     51     gss_buffer_desc buffer;
     52     int flags;
     53     OM_uint32 minor;
     54     krb5_error_code kret;
     55 
     56     GSSAPI_KRB5_INIT (&context);
     57 
     58     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     59 
     60     if (!(ctx->flags & GSS_C_TRANS_FLAG)) {
     61 	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     62 	*minor_status = 0;
     63 	return GSS_S_UNAVAILABLE;
     64     }
     65 
     66     sp = krb5_storage_emem ();
     67     if (sp == NULL) {
     68 	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
     69 	*minor_status = ENOMEM;
     70 	return GSS_S_FAILURE;
     71     }
     72     ac = ctx->auth_context;
     73 
     74     /* flagging included fields */
     75 
     76     flags = 0;
     77     if (ac->local_address)
     78 	flags |= SC_LOCAL_ADDRESS;
     79     if (ac->remote_address)
     80 	flags |= SC_REMOTE_ADDRESS;
     81     if (ac->keyblock)
     82 	flags |= SC_KEYBLOCK;
     83     if (ac->local_subkey)
     84 	flags |= SC_LOCAL_SUBKEY;
     85     if (ac->remote_subkey)
     86 	flags |= SC_REMOTE_SUBKEY;
     87 
     88     kret = krb5_store_int32 (sp, flags);
     89     if (kret) {
     90 	*minor_status = kret;
     91 	goto failure;
     92     }
     93 
     94     /* marshall auth context */
     95 
     96     kret = krb5_store_int32 (sp, ac->flags);
     97     if (kret) {
     98 	*minor_status = kret;
     99 	goto failure;
    100     }
    101     if (ac->local_address) {
    102 	kret = krb5_store_address (sp, *ac->local_address);
    103 	if (kret) {
    104 	    *minor_status = kret;
    105 	    goto failure;
    106 	}
    107     }
    108     if (ac->remote_address) {
    109 	kret = krb5_store_address (sp, *ac->remote_address);
    110 	if (kret) {
    111 	    *minor_status = kret;
    112 	    goto failure;
    113 	}
    114     }
    115     kret = krb5_store_int16 (sp, ac->local_port);
    116     if (kret) {
    117 	*minor_status = kret;
    118 	goto failure;
    119     }
    120     kret = krb5_store_int16 (sp, ac->remote_port);
    121     if (kret) {
    122 	*minor_status = kret;
    123 	goto failure;
    124     }
    125     if (ac->keyblock) {
    126 	kret = krb5_store_keyblock (sp, *ac->keyblock);
    127 	if (kret) {
    128 	    *minor_status = kret;
    129 	    goto failure;
    130 	}
    131     }
    132     if (ac->local_subkey) {
    133 	kret = krb5_store_keyblock (sp, *ac->local_subkey);
    134 	if (kret) {
    135 	    *minor_status = kret;
    136 	    goto failure;
    137 	}
    138     }
    139     if (ac->remote_subkey) {
    140 	kret = krb5_store_keyblock (sp, *ac->remote_subkey);
    141 	if (kret) {
    142 	    *minor_status = kret;
    143 	    goto failure;
    144 	}
    145     }
    146     kret = krb5_store_int32 (sp, ac->local_seqnumber);
    147 	if (kret) {
    148 	    *minor_status = kret;
    149 	    goto failure;
    150 	}
    151     kret = krb5_store_int32 (sp, ac->remote_seqnumber);
    152 	if (kret) {
    153 	    *minor_status = kret;
    154 	    goto failure;
    155 	}
    156 
    157     kret = krb5_store_int32 (sp, ac->keytype);
    158     if (kret) {
    159 	*minor_status = kret;
    160 	goto failure;
    161     }
    162     kret = krb5_store_int32 (sp, ac->cksumtype);
    163     if (kret) {
    164 	*minor_status = kret;
    165 	goto failure;
    166     }
    167 
    168     /* names */
    169 
    170     ret = _gsskrb5_export_name (minor_status,
    171 				(gss_name_t)ctx->source, &buffer);
    172     if (ret)
    173 	goto failure;
    174     data.data   = buffer.value;
    175     data.length = buffer.length;
    176     kret = krb5_store_data (sp, data);
    177     _gsskrb5_release_buffer (&minor, &buffer);
    178     if (kret) {
    179 	*minor_status = kret;
    180 	goto failure;
    181     }
    182 
    183     ret = _gsskrb5_export_name (minor_status,
    184 				(gss_name_t)ctx->target, &buffer);
    185     if (ret)
    186 	goto failure;
    187     data.data   = buffer.value;
    188     data.length = buffer.length;
    189 
    190     ret = GSS_S_FAILURE;
    191 
    192     kret = krb5_store_data (sp, data);
    193     _gsskrb5_release_buffer (&minor, &buffer);
    194     if (kret) {
    195 	*minor_status = kret;
    196 	goto failure;
    197     }
    198 
    199     kret = krb5_store_int32 (sp, ctx->flags);
    200     if (kret) {
    201 	*minor_status = kret;
    202 	goto failure;
    203     }
    204     kret = krb5_store_int32 (sp, ctx->more_flags);
    205     if (kret) {
    206 	*minor_status = kret;
    207 	goto failure;
    208     }
    209     /*
    210      * XXX We should put a 64-bit int here, but we don't have a
    211      * krb5_store_int64() yet.
    212      */
    213     kret = krb5_store_int32 (sp, ctx->endtime);
    214     if (kret) {
    215 	*minor_status = kret;
    216 	goto failure;
    217     }
    218     kret = _gssapi_msg_order_export(sp, ctx->order);
    219     if (kret ) {
    220         *minor_status = kret;
    221         goto failure;
    222     }
    223 
    224     kret = krb5_storage_to_data (sp, &data);
    225     krb5_storage_free (sp);
    226     if (kret) {
    227 	HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    228 	*minor_status = kret;
    229 	return GSS_S_FAILURE;
    230     }
    231     interprocess_token->length = data.length;
    232     interprocess_token->value  = data.data;
    233     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    234     ret = _gsskrb5_delete_sec_context (minor_status, context_handle,
    235 				       GSS_C_NO_BUFFER);
    236     if (ret != GSS_S_COMPLETE)
    237 	_gsskrb5_release_buffer (NULL, interprocess_token);
    238     *minor_status = 0;
    239     return ret;
    240  failure:
    241     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    242     krb5_storage_free (sp);
    243     return ret;
    244 }
    245