1/* $NetBSD$ */ 2 3/* 4 * Copyright (c) 1999 - 2003 Kungliga Tekniska H��gskolan 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 38OM_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 kret = krb5_store_int32 (sp, ctx->lifetime); 210 if (kret) { 211 *minor_status = kret; 212 goto failure; 213 } 214 kret = _gssapi_msg_order_export(sp, ctx->order); 215 if (kret ) { 216 *minor_status = kret; 217 goto failure; 218 } 219 220 kret = krb5_storage_to_data (sp, &data); 221 krb5_storage_free (sp); 222 if (kret) { 223 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 224 *minor_status = kret; 225 return GSS_S_FAILURE; 226 } 227 interprocess_token->length = data.length; 228 interprocess_token->value = data.data; 229 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 230 ret = _gsskrb5_delete_sec_context (minor_status, context_handle, 231 GSS_C_NO_BUFFER); 232 if (ret != GSS_S_COMPLETE) 233 _gsskrb5_release_buffer (NULL, interprocess_token); 234 *minor_status = 0; 235 return ret; 236 failure: 237 HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex); 238 krb5_storage_free (sp); 239 return ret; 240} 241