1/* $NetBSD: import_sec_context.c,v 1.1.1.1 2011/04/13 18:14:45 elric Exp $ */ 2 3/* 4 * Copyright (c) 1999 - 2003 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36#include "gsskrb5_locl.h" 37 38OM_uint32 GSSAPI_CALLCONV 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 flags, tmp; 56 gsskrb5_ctx ctx; 57 gss_name_t name; 58 59 GSSAPI_KRB5_INIT (&context); 60 61 *context_handle = GSS_C_NO_CONTEXT; 62 63 localp = remotep = NULL; 64 65 sp = krb5_storage_from_mem (interprocess_token->value, 66 interprocess_token->length); 67 if (sp == NULL) { 68 *minor_status = ENOMEM; 69 return GSS_S_FAILURE; 70 } 71 72 ctx = calloc(1, sizeof(*ctx)); 73 if (ctx == NULL) { 74 *minor_status = ENOMEM; 75 krb5_storage_free (sp); 76 return GSS_S_FAILURE; 77 } 78 HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex); 79 80 kret = krb5_auth_con_init (context, 81 &ctx->auth_context); 82 if (kret) { 83 *minor_status = kret; 84 ret = GSS_S_FAILURE; 85 goto failure; 86 } 87 88 /* flags */ 89 90 *minor_status = 0; 91 92 if (krb5_ret_int32 (sp, &flags) != 0) 93 goto failure; 94 95 /* retrieve the auth context */ 96 97 ac = ctx->auth_context; 98 if (krb5_ret_int32 (sp, &tmp) != 0) 99 goto failure; 100 ac->flags = tmp; 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 _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