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