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 "krb5/gsskrb5_locl.h" 35 36 RCSID("$Id: export_sec_context.c 19031 2006-11-13 18:02:57Z lha $"); 37 38 OM_uint32 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