예제 #1
0
OM_uint32 _gsskrb5_init_sec_context
(OM_uint32 * minor_status,
 const gss_cred_id_t initiator_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
    )
{
    gsskrb5_cred cred = (gsskrb5_cred)initiator_cred_handle;
    krb5_const_principal name = (krb5_const_principal)target_name;
    gsskrb5_ctx ctx;
    OM_uint32 ret;

    GSSAPI_KRB5_INIT ();

    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,
				  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,
			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,
			  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;

}
예제 #2
0
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_accept_sec_context(OM_uint32 * minor_status,
			    gss_ctx_id_t * context_handle,
			    const gss_cred_id_t acceptor_cred_handle,
			    const gss_buffer_t input_token_buffer,
			    const gss_channel_bindings_t input_chan_bindings,
			    gss_name_t * src_name,
			    gss_OID * mech_type,
			    gss_buffer_t output_token,
			    OM_uint32 * ret_flags,
			    OM_uint32 * time_rec,
			    gss_cred_id_t * delegated_cred_handle)
{
    krb5_context context;
    OM_uint32 ret;
    gsskrb5_ctx ctx;

    GSSAPI_KRB5_INIT(&context);

    output_token->length = 0;
    output_token->value = NULL;

    if (src_name != NULL)
	*src_name = NULL;
    if (mech_type)
	*mech_type = GSS_KRB5_MECHANISM;

    if (*context_handle == GSS_C_NO_CONTEXT) {
	ret = _gsskrb5_create_ctx(minor_status,
				  context_handle,
				  context,
				  input_chan_bindings,
				  ACCEPTOR_START);
	if (ret)
	    return ret;
    }

    ctx = (gsskrb5_ctx)*context_handle;


    /*
     * TODO: check the channel_bindings
     * (above just sets them to krb5 layer)
     */

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);

    switch (ctx->state) {
    case ACCEPTOR_START:
	ret = gsskrb5_acceptor_start(minor_status,
				     ctx,
				     context,
				     acceptor_cred_handle,
				     input_token_buffer,
				     input_chan_bindings,
				     src_name,
				     mech_type,
				     output_token,
				     ret_flags,
				     time_rec,
				     delegated_cred_handle);
	break;
    case ACCEPTOR_WAIT_FOR_DCESTYLE:
	ret = acceptor_wait_for_dcestyle(minor_status,
					 ctx,
					 context,
					 acceptor_cred_handle,
					 input_token_buffer,
					 input_chan_bindings,
					 src_name,
					 mech_type,
					 output_token,
					 ret_flags,
					 time_rec,
					 delegated_cred_handle);
	break;
    case ACCEPTOR_READY:
	/*
	 * If we get there, the caller have called
	 * gss_accept_sec_context() one time too many.
	 */
	ret =  GSS_S_BAD_STATUS;
	break;
    default:
	/* TODO: is this correct here? --metze */
	ret =  GSS_S_BAD_STATUS;
	break;
    }

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);

    if (GSS_ERROR(ret)) {
	OM_uint32 min2;
	_gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
    }

    return ret;
}
예제 #3
0
static OM_uint32
accept_sec_context(OM_uint32 * minor_status,
		   gss_ctx_id_t * context_handle,
		   const gss_cred_id_t acceptor_cred_handle,
		   const gss_buffer_t input_token_buffer,
		   const gss_channel_bindings_t input_chan_bindings,
		   gss_name_t * src_name,
		   gss_OID * mech_type,
		   gss_buffer_t output_token,
		   OM_uint32 * ret_flags,
		   OM_uint32 * time_rec,
		   gss_cred_id_t * delegated_cred_handle,
		   gss_OID mech,
		   gsskrb5_acceptor_state acceptor_state)
{
    krb5_context context;
    OM_uint32 ret;
    gsskrb5_ctx ctx;

    GSSAPI_KRB5_INIT(&context);

    output_token->length = 0;
    output_token->value = NULL;

    if (src_name != NULL)
	*src_name = NULL;
    if (mech_type)
	*mech_type = mech;

    if (*context_handle == GSS_C_NO_CONTEXT) {
	ret = _gsskrb5_create_ctx(minor_status,
				  context_handle,
				  context,
				  input_chan_bindings,
				  mech);
	if (ret)
	    return ret;

	/* mark as acceptor */
	ctx = (gsskrb5_ctx)*context_handle;
	ctx->gk5c.flags |= GK5C_ACCEPTOR;

	ctx->acceptor_state = acceptor_state;
    } else {
	ctx = (gsskrb5_ctx)*context_handle;
    }

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);

    do {
	ret = ctx->acceptor_state(minor_status, ctx, context, acceptor_cred_handle,
				  input_token_buffer, input_chan_bindings,
				  src_name, mech_type, output_token, ret_flags,
				  time_rec, delegated_cred_handle);
    } while (output_token->length == 0
	     && ret == GSS_S_COMPLETE &&
	     ctx->acceptor_state != step_acceptor_completed);

    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);

    if (GSS_ERROR(ret)) {
	OM_uint32 min2;
	_gsskrb5_delete_sec_context(&min2, context_handle, GSS_C_NO_BUFFER);
    }

    return ret;
}