init_sec_context.c

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

C
814
字号
    ret = gsskrb5_get_creds(minor_status,			    context,			    ccache,			    ctx,			    ctx->target,			    time_req,			    time_rec,			    &kcred);    if (ret)	goto failure;    ctx->lifetime = kcred->times.endtime;    ret = _gsskrb5_lifetime_left(minor_status,				 context,				 ctx->lifetime,				 &lifetime_rec);    if (ret) {	goto failure;    }    if (lifetime_rec == 0) {	*minor_status = 0;	ret = GSS_S_CONTEXT_EXPIRED;	goto failure;    }    krb5_auth_con_setkey(context, 			 ctx->auth_context, 			 &kcred->session);    kret = krb5_auth_con_generatelocalsubkey(context, 					     ctx->auth_context,					     &kcred->session);    if(kret) {	*minor_status = kret;	ret = GSS_S_FAILURE;	goto failure;    }        /*      * If the credential doesn't have ok-as-delegate, check what local     * policy say about ok-as-delegate, default is FALSE that makes     * code ignore the KDC setting and follow what the application     * requested. If it is TRUE, strip of the GSS_C_DELEG_FLAG if the     * KDC doesn't set ok-as-delegate.     */    if (!kcred->flags.b.ok_as_delegate) {	krb5_boolean delegate;    	krb5_appdefault_boolean(context,				"gssapi", name->realm,				"ok-as-delegate", FALSE, &delegate);	if (delegate)	    req_flags &= ~GSS_C_DELEG_FLAG;    }    flags = 0;    ap_options = 0;    if (req_flags & GSS_C_DELEG_FLAG)	do_delegation (context,		       ctx->auth_context,		       ccache, kcred, name, &fwd_data, &flags);        if (req_flags & GSS_C_MUTUAL_FLAG) {	flags |= GSS_C_MUTUAL_FLAG;	ap_options |= AP_OPTS_MUTUAL_REQUIRED;    }        if (req_flags & GSS_C_REPLAY_FLAG)	flags |= GSS_C_REPLAY_FLAG;    if (req_flags & GSS_C_SEQUENCE_FLAG)	flags |= GSS_C_SEQUENCE_FLAG;    if (req_flags & GSS_C_ANON_FLAG)	;                               /* XXX */    if (req_flags & GSS_C_DCE_STYLE) {	/* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */	flags |= GSS_C_DCE_STYLE | GSS_C_MUTUAL_FLAG;	ap_options |= AP_OPTS_MUTUAL_REQUIRED;    }    if (req_flags & GSS_C_IDENTIFY_FLAG)	flags |= GSS_C_IDENTIFY_FLAG;    if (req_flags & GSS_C_EXTENDED_ERROR_FLAG)	flags |= GSS_C_EXTENDED_ERROR_FLAG;    if (cred == NULL || !(cred->cred_flags & GSS_CF_NO_CI_FLAGS)) {	flags |= GSS_C_CONF_FLAG;	flags |= GSS_C_INTEG_FLAG;    }    flags |= GSS_C_TRANS_FLAG;        if (ret_flags)	*ret_flags = flags;    ctx->flags = flags;    ctx->more_flags |= LOCAL;        ret = _gsskrb5_create_8003_checksum (minor_status,					 input_chan_bindings,					 flags,					 &fwd_data,					 &cksum);    krb5_data_free (&fwd_data);    if (ret)	goto failure;    enctype = ctx->auth_context->keyblock->keytype;    kret = krb5_build_authenticator (context,				     ctx->auth_context,				     enctype,				     kcred,				     &cksum,				     NULL,				     &authenticator,				     KRB5_KU_AP_REQ_AUTH);    if (kret) {	*minor_status = kret;	ret = GSS_S_FAILURE;	goto failure;    }    kret = krb5_build_ap_req (context,			      enctype,			      kcred,			      ap_options,			      authenticator,			      &outbuf);    if (kret) {	*minor_status = kret;	ret = GSS_S_FAILURE;	goto failure;    }    ret = _gsskrb5_encapsulate (minor_status, &outbuf, output_token,				   (u_char *)"\x01\x00", GSS_KRB5_MECHANISM);    if (ret)	goto failure;    krb5_data_free (&outbuf);    krb5_free_creds(context, kcred);    free_Checksum(&cksum);    if (cred == NULL)	krb5_cc_close(context, ccache);    if (flags & GSS_C_MUTUAL_FLAG) {	ctx->state = INITIATOR_WAIT_FOR_MUTAL;	return GSS_S_CONTINUE_NEEDED;    }    return gsskrb5_initiator_ready(minor_status, ctx, context);failure:    if(kcred)	krb5_free_creds(context, kcred);    if (ccache && cred == NULL)	krb5_cc_close(context, ccache);    return ret;}static OM_uint32repl_mutual(OM_uint32 * minor_status, gsskrb5_ctx ctx, krb5_context context, 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;    krb5_error_code kret;    krb5_data indata;    krb5_ap_rep_enc_part *repl;    int is_cfx = 0;    output_token->length = 0;    output_token->value = NULL;    if (actual_mech_type)	*actual_mech_type = GSS_KRB5_MECHANISM;    if (ctx->flags & GSS_C_DCE_STYLE) {	/* There is no OID wrapping. */	indata.length	= input_token->length;	indata.data	= input_token->value;    } else {	ret = _gsskrb5_decapsulate (minor_status,				    input_token,				    &indata,				    "\x02\x00",				    GSS_KRB5_MECHANISM);	if (ret) {	    /* XXX - Handle AP_ERROR */	    return ret;	}    }    kret = krb5_rd_rep (context,			ctx->auth_context,			&indata,			&repl);    if (kret) {	*minor_status = kret;	return GSS_S_FAILURE;    }    krb5_free_ap_rep_enc_part (context,			       repl);        _gsskrb5i_is_cfx(ctx, &is_cfx);    if (is_cfx) {	krb5_keyblock *key = NULL;	kret = krb5_auth_con_getremotesubkey(context,					     ctx->auth_context, 					     &key);	if (kret == 0 && key != NULL) {    	    ctx->more_flags |= ACCEPTOR_SUBKEY;	    krb5_free_keyblock (context, key);	}    }    *minor_status = 0;    if (time_rec) {	ret = _gsskrb5_lifetime_left(minor_status,				     context,				     ctx->lifetime,				     time_rec);    } else {	ret = GSS_S_COMPLETE;    }    if (ret_flags)	*ret_flags = ctx->flags;    if (req_flags & GSS_C_DCE_STYLE) {	int32_t con_flags;	krb5_data outbuf;	/* Do don't do sequence number for the mk-rep */	krb5_auth_con_removeflags(context,				  ctx->auth_context,				  KRB5_AUTH_CONTEXT_DO_SEQUENCE,				  &con_flags);	kret = krb5_mk_rep(context,			   ctx->auth_context,			   &outbuf);	if (kret) {	    *minor_status = kret;	    return GSS_S_FAILURE;	}		output_token->length = outbuf.length;	output_token->value  = outbuf.data;	krb5_auth_con_removeflags(context,				  ctx->auth_context,				  KRB5_AUTH_CONTEXT_DO_SEQUENCE,				  NULL);    }    return gsskrb5_initiator_ready(minor_status, ctx, context);}/* * gss_init_sec_context */OM_uint32 _gsskrb5_init_sec_context(OM_uint32 * minor_status, const gss_cred_id_t cred_handle, gss_ctx_id_t * context_handle, const gss_name_t target_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    ){    krb5_context context;    gsskrb5_cred cred = (gsskrb5_cred)cred_handle;    krb5_const_principal name = (krb5_const_principal)target_name;    gsskrb5_ctx ctx;    OM_uint32 ret;    GSSAPI_KRB5_INIT (&context);    output_token->length = 0;    output_token->value  = NULL;    if (context_handle == NULL) {	*minor_status = 0;	return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;    }    if (ret_flags)	*ret_flags = 0;    if (time_rec)	*time_rec = 0;    if (target_name == GSS_C_NO_NAME) {	if (actual_mech_type)	    *actual_mech_type = GSS_C_NO_OID;	*minor_status = 0;	return GSS_S_BAD_NAME;    }    if (mech_type != GSS_C_NO_OID && 	!gss_oid_equal(mech_type, GSS_KRB5_MECHANISM))	return GSS_S_BAD_MECH;    if (input_token == GSS_C_NO_BUFFER || input_token->length == 0) {	OM_uint32 ret;	if (*context_handle != GSS_C_NO_CONTEXT) {	    *minor_status = 0;	    return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;	}    	ret = _gsskrb5_create_ctx(minor_status,				  context_handle,				  context,				  input_chan_bindings,				  INITIATOR_START);	if (ret)	    return ret;    }    if (*context_handle == GSS_C_NO_CONTEXT) {	*minor_status = 0;	return GSS_S_FAILURE | GSS_S_CALL_BAD_STRUCTURE;    }    ctx = (gsskrb5_ctx) *context_handle;    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);    switch (ctx->state) {    case INITIATOR_START:	ret = init_auth(minor_status,			cred,			ctx,			context,			name,			mech_type,			req_flags,			time_req,			input_chan_bindings,			input_token,			actual_mech_type,			output_token,			ret_flags,			time_rec);	break;    case INITIATOR_WAIT_FOR_MUTAL:	ret = repl_mutual(minor_status,			  ctx,			  context,			  mech_type,			  req_flags,			  time_req,			  input_chan_bindings,			  input_token,			  actual_mech_type,			  output_token,			  ret_flags,			  time_rec);	break;    case INITIATOR_READY:	/* 	 * If we get there, the caller have called	 * gss_init_sec_context() one time too many.	 */	*minor_status = 0;	ret = GSS_S_BAD_STATUS;	break;    default:	*minor_status = 0;	ret = GSS_S_BAD_STATUS;	break;    }    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);    /* destroy context in case of error */    if (GSS_ERROR(ret)) {	OM_uint32 min2;	_gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);    }    return ret;}

⌨️ 快捷键说明

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