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: import_sec_context.c 19031 2006-11-13 18:02:57Z lha $"); 37 38 OM_uint32 39 _gsskrb5_import_sec_context ( 40 OM_uint32 * minor_status, 41 const gss_buffer_t interprocess_token, 42 gss_ctx_id_t * context_handle 43 ) 44 { 45 OM_uint32 ret = GSS_S_FAILURE; 46 krb5_context context; 47 krb5_error_code kret; 48 krb5_storage *sp; 49 krb5_auth_context ac; 50 krb5_address local, remote; 51 krb5_address *localp, *remotep; 52 krb5_data data; 53 gss_buffer_desc buffer; 54 krb5_keyblock keyblock; 55 int32_t tmp; 56 int32_t flags; 57 gsskrb5_ctx ctx; 58 gss_name_t name; 59 60 GSSAPI_KRB5_INIT (&context); 61 62 *context_handle = GSS_C_NO_CONTEXT; 63 64 localp = remotep = NULL; 65 66 sp = krb5_storage_from_mem (interprocess_token->value, 67 interprocess_token->length); 68 if (sp == NULL) { 69 *minor_status = ENOMEM; 70 return GSS_S_FAILURE; 71 } 72 73 ctx = calloc(1, sizeof(*ctx)); 74 if (ctx == NULL) { 75 *minor_status = ENOMEM; 76 krb5_storage_free (sp); 77 return GSS_S_FAILURE; 78 } 79 HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); 80 81 kret = krb5_auth_con_init (context, 82 &ctx->auth_context); 83 if (kret) { 84 *minor_status = kret; 85 ret = GSS_S_FAILURE; 86 goto failure; 87 } 88 89 /* flags */ 90 91 *minor_status = 0; 92 93 if (krb5_ret_int32 (sp, &flags) != 0) 94 goto failure; 95 96 /* retrieve the auth context */ 97 98 ac = ctx->auth_context; 99 if (krb5_ret_uint32 (sp, &ac->flags) != 0) 100 goto failure; 101 if (flags & SC_LOCAL_ADDRESS) { 102 if (krb5_ret_address (sp, localp = &local) != 0) 103 goto failure; 104 } 105 106 if (flags & SC_REMOTE_ADDRESS) { 107 if (krb5_ret_address (sp, remotep = &remote) != 0) 108 goto failure; 109 } 110 111 krb5_auth_con_setaddrs (context, ac, localp, remotep); 112 if (localp) 113 krb5_free_address (context, localp); 114 if (remotep) 115 krb5_free_address (context, remotep); 116 localp = remotep = NULL; 117 118 if (krb5_ret_int16 (sp, &ac->local_port) != 0) 119 goto failure; 120 121 if (krb5_ret_int16 (sp, &ac->remote_port) != 0) 122 goto failure; 123 if (flags & SC_KEYBLOCK) { 124 if (krb5_ret_keyblock (sp, &keyblock) != 0) 125 goto failure; 126 krb5_auth_con_setkey (context, ac, &keyblock); 127 krb5_free_keyblock_contents (context, &keyblock); 128 } 129 if (flags & SC_LOCAL_SUBKEY) { 130 if (krb5_ret_keyblock (sp, &keyblock) != 0) 131 goto failure; 132 krb5_auth_con_setlocalsubkey (context, ac, &keyblock); 133 krb5_free_keyblock_contents (context, &keyblock); 134 } 135 if (flags & SC_REMOTE_SUBKEY) { 136 if (krb5_ret_keyblock (sp, &keyblock) != 0) 137 goto failure; 138 krb5_auth_con_setremotesubkey (context, ac, &keyblock); 139 krb5_free_keyblock_contents (context, &keyblock); 140 } 141 if (krb5_ret_uint32 (sp, &ac->local_seqnumber)) 142 goto failure; 143 if (krb5_ret_uint32 (sp, &ac->remote_seqnumber)) 144 goto failure; 145 146 if (krb5_ret_int32 (sp, &tmp) != 0) 147 goto failure; 148 ac->keytype = tmp; 149 if (krb5_ret_int32 (sp, &tmp) != 0) 150 goto failure; 151 ac->cksumtype = tmp; 152 153 /* names */ 154 155 if (krb5_ret_data (sp, &data)) 156 goto failure; 157 buffer.value = data.data; 158 buffer.length = data.length; 159 160 ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME, 161 &name); 162 if (ret) { 163 ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID, 164 &name); 165 if (ret) { 166 krb5_data_free (&data); 167 goto failure; 168 } 169 } 170 ctx->source = (krb5_principal)name; 171 krb5_data_free (&data); 172 173 if (krb5_ret_data (sp, &data) != 0) 174 goto failure; 175 buffer.value = data.data; 176 buffer.length = data.length; 177 178 ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NT_EXPORT_NAME, 179 &name); 180 if (ret) { 181 ret = _gsskrb5_import_name (minor_status, &buffer, GSS_C_NO_OID, 182 &name); 183 if (ret) { 184 krb5_data_free (&data); 185 goto failure; 186 } 187 } 188 ctx->target = (krb5_principal)name; 189 krb5_data_free (&data); 190 191 if (krb5_ret_int32 (sp, &tmp)) 192 goto failure; 193 ctx->flags = tmp; 194 if (krb5_ret_int32 (sp, &tmp)) 195 goto failure; 196 ctx->more_flags = tmp; 197 if (krb5_ret_int32 (sp, &tmp)) 198 goto failure; 199 ctx->lifetime = tmp; 200 201 ret = _gssapi_msg_order_import(minor_status, sp, &ctx->order); 202 if (ret) 203 goto failure; 204 205 krb5_storage_free (sp); 206 207 *context_handle = (gss_ctx_id_t)ctx; 208 209 return GSS_S_COMPLETE; 210 211 failure: 212 krb5_auth_con_free (context, 213 ctx->auth_context); 214 if (ctx->source != NULL) 215 krb5_free_principal(context, ctx->source); 216 if (ctx->target != NULL) 217 krb5_free_principal(context, ctx->target); 218 if (localp) 219 krb5_free_address (context, localp); 220 if (remotep) 221 krb5_free_address (context, remotep); 222 if(ctx->order) 223 _gssapi_msg_order_destroy(&ctx->order); 224 HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); 225 krb5_storage_free (sp); 226 free (ctx); 227 *context_handle = GSS_C_NO_CONTEXT; 228 return ret; 229 } 230