1178825Sdfr/* 2233294Sstas * Copyright (c) 1999 - 2003 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 5178825Sdfr * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 9178825Sdfr * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 12178825Sdfr * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 16178825Sdfr * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 20178825Sdfr * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 32178825Sdfr */ 33178825Sdfr 34233294Sstas#include "gsskrb5_locl.h" 35178825Sdfr 36233294SstasOM_uint32 GSSAPI_CALLCONV 37178825Sdfr_gsskrb5_export_sec_context ( 38178825Sdfr OM_uint32 * minor_status, 39178825Sdfr gss_ctx_id_t * context_handle, 40178825Sdfr gss_buffer_t interprocess_token 41178825Sdfr ) 42178825Sdfr{ 43178825Sdfr krb5_context context; 44178825Sdfr const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle; 45178825Sdfr krb5_storage *sp; 46178825Sdfr krb5_auth_context ac; 47178825Sdfr OM_uint32 ret = GSS_S_COMPLETE; 48178825Sdfr krb5_data data; 49178825Sdfr gss_buffer_desc buffer; 50178825Sdfr int flags; 51178825Sdfr OM_uint32 minor; 52178825Sdfr krb5_error_code kret; 53178825Sdfr 54178825Sdfr GSSAPI_KRB5_INIT (&context); 55178825Sdfr 56178825Sdfr HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex); 57178825Sdfr 58178825Sdfr if (!(ctx->flags & GSS_C_TRANS_FLAG)) { 59178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 60178825Sdfr *minor_status = 0; 61178825Sdfr return GSS_S_UNAVAILABLE; 62178825Sdfr } 63178825Sdfr 64178825Sdfr sp = krb5_storage_emem (); 65178825Sdfr if (sp == NULL) { 66178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 67178825Sdfr *minor_status = ENOMEM; 68178825Sdfr return GSS_S_FAILURE; 69178825Sdfr } 70178825Sdfr ac = ctx->auth_context; 71178825Sdfr 72178825Sdfr /* flagging included fields */ 73178825Sdfr 74178825Sdfr flags = 0; 75178825Sdfr if (ac->local_address) 76178825Sdfr flags |= SC_LOCAL_ADDRESS; 77178825Sdfr if (ac->remote_address) 78178825Sdfr flags |= SC_REMOTE_ADDRESS; 79178825Sdfr if (ac->keyblock) 80178825Sdfr flags |= SC_KEYBLOCK; 81178825Sdfr if (ac->local_subkey) 82178825Sdfr flags |= SC_LOCAL_SUBKEY; 83178825Sdfr if (ac->remote_subkey) 84178825Sdfr flags |= SC_REMOTE_SUBKEY; 85178825Sdfr 86178825Sdfr kret = krb5_store_int32 (sp, flags); 87178825Sdfr if (kret) { 88178825Sdfr *minor_status = kret; 89178825Sdfr goto failure; 90178825Sdfr } 91178825Sdfr 92178825Sdfr /* marshall auth context */ 93178825Sdfr 94178825Sdfr kret = krb5_store_int32 (sp, ac->flags); 95178825Sdfr if (kret) { 96178825Sdfr *minor_status = kret; 97178825Sdfr goto failure; 98178825Sdfr } 99178825Sdfr if (ac->local_address) { 100178825Sdfr kret = krb5_store_address (sp, *ac->local_address); 101178825Sdfr if (kret) { 102178825Sdfr *minor_status = kret; 103178825Sdfr goto failure; 104178825Sdfr } 105178825Sdfr } 106178825Sdfr if (ac->remote_address) { 107178825Sdfr kret = krb5_store_address (sp, *ac->remote_address); 108178825Sdfr if (kret) { 109178825Sdfr *minor_status = kret; 110178825Sdfr goto failure; 111178825Sdfr } 112178825Sdfr } 113178825Sdfr kret = krb5_store_int16 (sp, ac->local_port); 114178825Sdfr if (kret) { 115178825Sdfr *minor_status = kret; 116178825Sdfr goto failure; 117178825Sdfr } 118178825Sdfr kret = krb5_store_int16 (sp, ac->remote_port); 119178825Sdfr if (kret) { 120178825Sdfr *minor_status = kret; 121178825Sdfr goto failure; 122178825Sdfr } 123178825Sdfr if (ac->keyblock) { 124178825Sdfr kret = krb5_store_keyblock (sp, *ac->keyblock); 125178825Sdfr if (kret) { 126178825Sdfr *minor_status = kret; 127178825Sdfr goto failure; 128178825Sdfr } 129178825Sdfr } 130178825Sdfr if (ac->local_subkey) { 131178825Sdfr kret = krb5_store_keyblock (sp, *ac->local_subkey); 132178825Sdfr if (kret) { 133178825Sdfr *minor_status = kret; 134178825Sdfr goto failure; 135178825Sdfr } 136178825Sdfr } 137178825Sdfr if (ac->remote_subkey) { 138178825Sdfr kret = krb5_store_keyblock (sp, *ac->remote_subkey); 139178825Sdfr if (kret) { 140178825Sdfr *minor_status = kret; 141178825Sdfr goto failure; 142178825Sdfr } 143178825Sdfr } 144178825Sdfr kret = krb5_store_int32 (sp, ac->local_seqnumber); 145178825Sdfr if (kret) { 146178825Sdfr *minor_status = kret; 147178825Sdfr goto failure; 148178825Sdfr } 149178825Sdfr kret = krb5_store_int32 (sp, ac->remote_seqnumber); 150178825Sdfr if (kret) { 151178825Sdfr *minor_status = kret; 152178825Sdfr goto failure; 153178825Sdfr } 154178825Sdfr 155178825Sdfr kret = krb5_store_int32 (sp, ac->keytype); 156178825Sdfr if (kret) { 157178825Sdfr *minor_status = kret; 158178825Sdfr goto failure; 159178825Sdfr } 160178825Sdfr kret = krb5_store_int32 (sp, ac->cksumtype); 161178825Sdfr if (kret) { 162178825Sdfr *minor_status = kret; 163178825Sdfr goto failure; 164178825Sdfr } 165178825Sdfr 166178825Sdfr /* names */ 167178825Sdfr 168178825Sdfr ret = _gsskrb5_export_name (minor_status, 169178825Sdfr (gss_name_t)ctx->source, &buffer); 170178825Sdfr if (ret) 171178825Sdfr goto failure; 172178825Sdfr data.data = buffer.value; 173178825Sdfr data.length = buffer.length; 174178825Sdfr kret = krb5_store_data (sp, data); 175178825Sdfr _gsskrb5_release_buffer (&minor, &buffer); 176178825Sdfr if (kret) { 177178825Sdfr *minor_status = kret; 178178825Sdfr goto failure; 179178825Sdfr } 180178825Sdfr 181178825Sdfr ret = _gsskrb5_export_name (minor_status, 182178825Sdfr (gss_name_t)ctx->target, &buffer); 183178825Sdfr if (ret) 184178825Sdfr goto failure; 185178825Sdfr data.data = buffer.value; 186178825Sdfr data.length = buffer.length; 187178825Sdfr 188178825Sdfr ret = GSS_S_FAILURE; 189178825Sdfr 190178825Sdfr kret = krb5_store_data (sp, data); 191178825Sdfr _gsskrb5_release_buffer (&minor, &buffer); 192178825Sdfr if (kret) { 193178825Sdfr *minor_status = kret; 194178825Sdfr goto failure; 195178825Sdfr } 196178825Sdfr 197178825Sdfr kret = krb5_store_int32 (sp, ctx->flags); 198178825Sdfr if (kret) { 199178825Sdfr *minor_status = kret; 200178825Sdfr goto failure; 201178825Sdfr } 202178825Sdfr kret = krb5_store_int32 (sp, ctx->more_flags); 203178825Sdfr if (kret) { 204178825Sdfr *minor_status = kret; 205178825Sdfr goto failure; 206178825Sdfr } 207178825Sdfr kret = krb5_store_int32 (sp, ctx->lifetime); 208178825Sdfr if (kret) { 209178825Sdfr *minor_status = kret; 210178825Sdfr goto failure; 211178825Sdfr } 212178825Sdfr kret = _gssapi_msg_order_export(sp, ctx->order); 213178825Sdfr if (kret ) { 214178825Sdfr *minor_status = kret; 215178825Sdfr goto failure; 216178825Sdfr } 217178825Sdfr 218178825Sdfr kret = krb5_storage_to_data (sp, &data); 219178825Sdfr krb5_storage_free (sp); 220178825Sdfr if (kret) { 221178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 222178825Sdfr *minor_status = kret; 223178825Sdfr return GSS_S_FAILURE; 224178825Sdfr } 225178825Sdfr interprocess_token->length = data.length; 226178825Sdfr interprocess_token->value = data.data; 227178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 228178825Sdfr ret = _gsskrb5_delete_sec_context (minor_status, context_handle, 229178825Sdfr GSS_C_NO_BUFFER); 230178825Sdfr if (ret != GSS_S_COMPLETE) 231178825Sdfr _gsskrb5_release_buffer (NULL, interprocess_token); 232178825Sdfr *minor_status = 0; 233178825Sdfr return ret; 234178825Sdfr failure: 235178825Sdfr HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 236178825Sdfr krb5_storage_free (sp); 237178825Sdfr return ret; 238178825Sdfr} 239