175537Sluigi/* $NetBSD$ */ 275537Sluigi 375537Sluigi/* 475537Sluigi * Copyright (c) 1999 - 2003 Kungliga Tekniska H��gskolan 575537Sluigi * (Royal Institute of Technology, Stockholm, Sweden). 675537Sluigi * All rights reserved. 775537Sluigi * 875537Sluigi * Redistribution and use in source and binary forms, with or without 975537Sluigi * modification, are permitted provided that the following conditions 1075537Sluigi * are met: 1175537Sluigi * 1275537Sluigi * 1. Redistributions of source code must retain the above copyright 1375537Sluigi * notice, this list of conditions and the following disclaimer. 1475537Sluigi * 1575537Sluigi * 2. Redistributions in binary form must reproduce the above copyright 1675537Sluigi * notice, this list of conditions and the following disclaimer in the 1775537Sluigi * documentation and/or other materials provided with the distribution. 1875537Sluigi * 1975537Sluigi * 3. Neither the name of the Institute nor the names of its contributors 2075537Sluigi * may be used to endorse or promote products derived from this software 2175537Sluigi * without specific prior written permission. 2275537Sluigi * 2375537Sluigi * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2475537Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2575537Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2675537Sluigi * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2775537Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2875537Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2975537Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3075537Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3175537Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3275537Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3375537Sluigi * SUCH DAMAGE. 3475537Sluigi */ 3575537Sluigi 3675537Sluigi#include "gsskrb5_locl.h" 3775537Sluigi 3875537SluigiOM_uint32 GSSAPI_CALLCONV 39159175Smotoyuki_gsskrb5_import_sec_context ( 4075537Sluigi OM_uint32 * minor_status, 4175537Sluigi const gss_buffer_t interprocess_token, 4275537Sluigi gss_ctx_id_t * context_handle 4375537Sluigi ) 4475537Sluigi{ 4575537Sluigi OM_uint32 ret = GSS_S_FAILURE; 4675537Sluigi krb5_context context; 4775537Sluigi krb5_error_code kret; 4875537Sluigi krb5_storage *sp; 4975537Sluigi krb5_auth_context ac; 5075537Sluigi krb5_address local, remote; 5175537Sluigi krb5_address *localp, *remotep; 5275537Sluigi krb5_data data; 5375537Sluigi gss_buffer_desc buffer; 5475537Sluigi krb5_keyblock keyblock; 5575537Sluigi int32_t flags, tmp; 5675537Sluigi gsskrb5_ctx ctx; 5775537Sluigi gss_name_t name; 5875537Sluigi 5975537Sluigi GSSAPI_KRB5_INIT (&context); 6075537Sluigi 6175537Sluigi *context_handle = GSS_C_NO_CONTEXT; 6275537Sluigi 6375537Sluigi localp = remotep = NULL; 6475537Sluigi 6575537Sluigi sp = krb5_storage_from_mem (interprocess_token->value, 6675537Sluigi interprocess_token->length); 6775537Sluigi if (sp == NULL) { 6875537Sluigi *minor_status = ENOMEM; 6975537Sluigi return GSS_S_FAILURE; 7075537Sluigi } 7175537Sluigi 7275537Sluigi ctx = calloc(1, sizeof(*ctx)); 7375537Sluigi if (ctx == NULL) { 7475537Sluigi *minor_status = ENOMEM; 7575537Sluigi krb5_storage_free (sp); 7675537Sluigi return GSS_S_FAILURE; 7775537Sluigi } 7875537Sluigi HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); 7975537Sluigi 8075537Sluigi kret = krb5_auth_con_init (context, 8175537Sluigi &ctx->auth_context); 8275537Sluigi if (kret) { 8375537Sluigi *minor_status = kret; 8475537Sluigi ret = GSS_S_FAILURE; 8575537Sluigi goto failure; 8675537Sluigi } 8775537Sluigi 8875537Sluigi /* flags */ 8975537Sluigi 90135639Sbrooks *minor_status = 0; 9175537Sluigi 9275537Sluigi if (krb5_ret_int32 (sp, &flags) != 0) 9375537Sluigi goto failure; 9475537Sluigi 9575537Sluigi /* retrieve the auth context */ 9675537Sluigi 9775537Sluigi ac = ctx->auth_context; 9875537Sluigi if (krb5_ret_int32 (sp, &tmp) != 0) 9975537Sluigi goto failure; 10075537Sluigi ac->flags = tmp; 10175537Sluigi if (flags & SC_LOCAL_ADDRESS) { 10275537Sluigi if (krb5_ret_address (sp, localp = &local) != 0) 10375537Sluigi goto failure; 10475537Sluigi } 10575537Sluigi 10675537Sluigi if (flags & SC_REMOTE_ADDRESS) { 10775537Sluigi if (krb5_ret_address (sp, remotep = &remote) != 0) 10875537Sluigi goto failure; 10975537Sluigi } 11075537Sluigi 11175537Sluigi krb5_auth_con_setaddrs (context, ac, localp, remotep); 11275537Sluigi if (localp) 11375537Sluigi krb5_free_address (context, localp); 11475537Sluigi if (remotep) 11575537Sluigi krb5_free_address (context, remotep); 11675537Sluigi localp = remotep = NULL; 11775537Sluigi 11875537Sluigi if (krb5_ret_int16 (sp, &ac->local_port) != 0) 11975537Sluigi goto failure; 12075537Sluigi 12175537Sluigi if (krb5_ret_int16 (sp, &ac->remote_port) != 0) 12275537Sluigi goto failure; 12375537Sluigi if (flags & SC_KEYBLOCK) { 12475537Sluigi if (krb5_ret_keyblock (sp, &keyblock) != 0) 12575537Sluigi goto failure; 12675537Sluigi krb5_auth_con_setkey (context, ac, &keyblock); 12775537Sluigi krb5_free_keyblock_contents (context, &keyblock); 12875537Sluigi } 12975537Sluigi if (flags & SC_LOCAL_SUBKEY) { 13075537Sluigi if (krb5_ret_keyblock (sp, &keyblock) != 0) 13175537Sluigi goto failure; 13275537Sluigi krb5_auth_con_setlocalsubkey (context, ac, &keyblock); 13375537Sluigi krb5_free_keyblock_contents (context, &keyblock); 13475537Sluigi } 13575537Sluigi if (flags & SC_REMOTE_SUBKEY) { 13675537Sluigi if (krb5_ret_keyblock (sp, &keyblock) != 0) 13775537Sluigi goto failure; 13875537Sluigi 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 _gsskrb5i_is_cfx(context, ctx, (ctx->more_flags & LOCAL) == 0); 208 209 *context_handle = (gss_ctx_id_t)ctx; 210 211 return GSS_S_COMPLETE; 212 213failure: 214 krb5_auth_con_free (context, 215 ctx->auth_context); 216 if (ctx->source != NULL) 217 krb5_free_principal(context, ctx->source); 218 if (ctx->target != NULL) 219 krb5_free_principal(context, ctx->target); 220 if (localp) 221 krb5_free_address (context, localp); 222 if (remotep) 223 krb5_free_address (context, remotep); 224 if(ctx->order) 225 _gssapi_msg_order_destroy(&ctx->order); 226 HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex); 227 krb5_storage_free (sp); 228 free (ctx); 229 *context_handle = GSS_C_NO_CONTEXT; 230 return ret; 231} 232