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