init_sec_context.c

来自「samba最新软件」· C语言 代码 · 共 814 行 · 第 1/2 页

C
814
字号
/* * Copyright (c) 1997 - 2008 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden).  * All rights reserved.  * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met:  * * 1. Redistributions of source code must retain the above copyright  *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright  *    notice, this list of conditions and the following disclaimer in the  *    documentation and/or other materials provided with the distribution.  * * 3. Neither the name of the Institute nor the names of its contributors  *    may be used to endorse or promote products derived from this software  *    without specific prior written permission.  * * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF  * SUCH DAMAGE.  */#include "krb5/gsskrb5_locl.h"RCSID("$Id: init_sec_context.c 22671 2008-03-09 23:57:54Z lha $");/* * copy the addresses from `input_chan_bindings' (if any) to * the auth context `ac' */static OM_uint32set_addresses (krb5_context context,	       krb5_auth_context ac,	       const gss_channel_bindings_t input_chan_bindings)	       {    /* Port numbers are expected to be in application_data.value,      * initator's port first */     krb5_address initiator_addr, acceptor_addr;    krb5_error_code kret;           if (input_chan_bindings == GSS_C_NO_CHANNEL_BINDINGS	|| input_chan_bindings->application_data.length !=	2 * sizeof(ac->local_port))	return 0;    memset(&initiator_addr, 0, sizeof(initiator_addr));    memset(&acceptor_addr, 0, sizeof(acceptor_addr));           ac->local_port =	*(int16_t *) input_chan_bindings->application_data.value;           ac->remote_port =	*((int16_t *) input_chan_bindings->application_data.value + 1);           kret = _gsskrb5i_address_to_krb5addr(context,					 input_chan_bindings->acceptor_addrtype,					 &input_chan_bindings->acceptor_address,					 ac->remote_port,					 &acceptor_addr);    if (kret)	return kret;               kret = _gsskrb5i_address_to_krb5addr(context,					 input_chan_bindings->initiator_addrtype,					 &input_chan_bindings->initiator_address,					 ac->local_port,					 &initiator_addr);    if (kret) {	krb5_free_address (context, &acceptor_addr);	return kret;    }           kret = krb5_auth_con_setaddrs(context,				  ac,				  &initiator_addr,  /* local address */				  &acceptor_addr);  /* remote address */           krb5_free_address (context, &initiator_addr);    krb5_free_address (context, &acceptor_addr);       #if 0    free(input_chan_bindings->application_data.value);    input_chan_bindings->application_data.value = NULL;    input_chan_bindings->application_data.length = 0;#endif    return kret;}OM_uint32_gsskrb5_create_ctx(        OM_uint32 * minor_status,	gss_ctx_id_t * context_handle,	krb5_context context, 	const gss_channel_bindings_t input_chan_bindings, 	enum gss_ctx_id_t_state state){    krb5_error_code kret;    gsskrb5_ctx ctx;    *context_handle = NULL;    ctx = malloc(sizeof(*ctx));    if (ctx == NULL) {	*minor_status = ENOMEM;	return GSS_S_FAILURE;    }    ctx->auth_context		= NULL;    ctx->source			= NULL;    ctx->target			= NULL;    ctx->state			= state;    ctx->flags			= 0;    ctx->more_flags		= 0;    ctx->service_keyblock	= NULL;    ctx->ticket			= NULL;    krb5_data_zero(&ctx->fwd_data);    ctx->lifetime		= GSS_C_INDEFINITE;    ctx->order			= NULL;    HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);    kret = krb5_auth_con_init (context, &ctx->auth_context);    if (kret) {	*minor_status = kret;	HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);			return GSS_S_FAILURE;    }    kret = set_addresses(context, ctx->auth_context, input_chan_bindings);    if (kret) {	*minor_status = kret;	HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);	krb5_auth_con_free(context, ctx->auth_context);	return GSS_S_BAD_BINDINGS;    }    /*     * We need a sequence number     */    krb5_auth_con_addflags(context,			   ctx->auth_context,			   KRB5_AUTH_CONTEXT_DO_SEQUENCE |			   KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED,			   NULL);    *context_handle = (gss_ctx_id_t)ctx;    return GSS_S_COMPLETE;}static OM_uint32gsskrb5_get_creds(        OM_uint32 * minor_status,	krb5_context context,	krb5_ccache ccache,	gsskrb5_ctx ctx,	krb5_const_principal target_name,	OM_uint32 time_req,	OM_uint32 * time_rec,	krb5_creds ** cred){    OM_uint32 ret;    krb5_error_code kret;    krb5_creds this_cred;    OM_uint32 lifetime_rec;    *cred = NULL;    memset(&this_cred, 0, sizeof(this_cred));    this_cred.client = ctx->source;    this_cred.server = ctx->target;    if (time_req && time_req != GSS_C_INDEFINITE) {	krb5_timestamp ts;	krb5_timeofday (context, &ts);	this_cred.times.endtime = ts + time_req;    } else {	this_cred.times.endtime   = 0;    }    this_cred.session.keytype = KEYTYPE_NULL;    kret = krb5_get_credentials(context,				0,				ccache,				&this_cred,				cred);    if (kret) {	*minor_status = kret;	return GSS_S_FAILURE;    }    ctx->lifetime = (*cred)->times.endtime;    ret = _gsskrb5_lifetime_left(minor_status, context,				 ctx->lifetime, &lifetime_rec);    if (ret) return ret;    if (lifetime_rec == 0) {	*minor_status = 0;	return GSS_S_CONTEXT_EXPIRED;    }    if (time_rec) *time_rec = lifetime_rec;    return GSS_S_COMPLETE;}static OM_uint32gsskrb5_initiator_ready(	OM_uint32 * minor_status,	gsskrb5_ctx ctx,	krb5_context context){	OM_uint32 ret;	int32_t seq_number;	int is_cfx = 0;	OM_uint32 flags = ctx->flags;	krb5_auth_getremoteseqnumber (context,				      ctx->auth_context,				      &seq_number);	_gsskrb5i_is_cfx(ctx, &is_cfx);	ret = _gssapi_msg_order_create(minor_status,				       &ctx->order,				       _gssapi_msg_order_f(flags),				       seq_number, 0, is_cfx);	if (ret) return ret;	ctx->state	= INITIATOR_READY;	ctx->more_flags	|= OPEN;	return GSS_S_COMPLETE;}/* * handle delegated creds in init-sec-context */static voiddo_delegation (krb5_context context,	       krb5_auth_context ac,	       krb5_ccache ccache,	       krb5_creds *cred,	       krb5_const_principal name,	       krb5_data *fwd_data,	       uint32_t *flags){    krb5_creds creds;    KDCOptions fwd_flags;    krb5_error_code kret;           memset (&creds, 0, sizeof(creds));    krb5_data_zero (fwd_data);           kret = krb5_cc_get_principal(context, ccache, &creds.client);    if (kret) 	goto out;           kret = krb5_build_principal(context,				&creds.server,				strlen(creds.client->realm),				creds.client->realm,				KRB5_TGS_NAME,				creds.client->realm,				NULL);    if (kret)	goto out;            creds.times.endtime = 0;           memset(&fwd_flags, 0, sizeof(fwd_flags));    fwd_flags.forwarded = 1;    fwd_flags.forwardable = 1;           if ( /*target_name->name.name_type != KRB5_NT_SRV_HST ||*/	name->name.name_string.len < 2) 	goto out;           kret = krb5_get_forwarded_creds(context,				    ac,				    ccache,				    KDCOptions2int(fwd_flags),				    name->name.name_string.val[1],				    &creds,				    fwd_data);        out:    if (kret)	*flags &= ~GSS_C_DELEG_FLAG;    else	*flags |= GSS_C_DELEG_FLAG;           if (creds.client)	krb5_free_principal(context, creds.client);    if (creds.server)	krb5_free_principal(context, creds.server);}/* * first stage of init-sec-context */static OM_uint32init_auth(OM_uint32 * minor_status, gsskrb5_cred cred, gsskrb5_ctx ctx, krb5_context context, krb5_const_principal name, const gss_OID mech_type, OM_uint32 req_flags, OM_uint32 time_req, const gss_channel_bindings_t input_chan_bindings, const gss_buffer_t input_token, gss_OID * actual_mech_type, gss_buffer_t output_token, OM_uint32 * ret_flags, OM_uint32 * time_rec    ){    OM_uint32 ret = GSS_S_FAILURE;    krb5_error_code kret;    krb5_flags ap_options;    krb5_creds *kcred = NULL;    krb5_data outbuf;    krb5_ccache ccache = NULL;    uint32_t flags;    krb5_data authenticator;    Checksum cksum;    krb5_enctype enctype;    krb5_data fwd_data;    OM_uint32 lifetime_rec;    krb5_data_zero(&outbuf);    krb5_data_zero(&fwd_data);    *minor_status = 0;    if (actual_mech_type)	*actual_mech_type = GSS_KRB5_MECHANISM;    if (cred == NULL) {	kret = krb5_cc_default (context, &ccache);	if (kret) {	    *minor_status = kret;	    ret = GSS_S_FAILURE;	    goto failure;	}    } else	ccache = cred->ccache;    kret = krb5_cc_get_principal (context, ccache, &ctx->source);    if (kret) {	*minor_status = kret;	ret = GSS_S_FAILURE;	goto failure;    }    kret = krb5_copy_principal (context, name, &ctx->target);    if (kret) {	*minor_status = kret;	ret = GSS_S_FAILURE;	goto failure;    }    ret = _gss_DES3_get_mic_compat(minor_status, ctx, context);    if (ret)	goto failure;    /*     * This is hideous glue for (NFS) clients that wants to limit the     * available enctypes to what it can support (encryption in     * kernel). If there is no enctypes selected for this credential,     * reset it to the default set of enctypes.     */    {	krb5_enctype *enctypes = NULL;	if (cred && cred->enctypes)	    enctypes = cred->enctypes;	krb5_set_default_in_tkt_etypes(context, enctypes);    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?