OM_uint32 _gsskrb5_process_context_token (
	OM_uint32          *minor_status,
	const gss_ctx_id_t context_handle,
	const gss_buffer_t token_buffer
    )
{
    OM_uint32 ret = GSS_S_FAILURE;
    gss_buffer_desc empty_buffer;
    gss_qop_t qop_state;

    empty_buffer.length = 0;
    empty_buffer.value = NULL;

    qop_state = GSS_C_QOP_DEFAULT;

    ret = _gsskrb5_verify_mic_internal(minor_status, 
				       (gsskrb5_ctx)context_handle,
				       token_buffer, &empty_buffer,
				       GSS_C_QOP_DEFAULT, "\x01\x02");

    if (ret == GSS_S_COMPLETE)
	ret = _gsskrb5_delete_sec_context(minor_status,
					  rk_UNCONST(&context_handle),
					  GSS_C_NO_BUFFER);
    if (ret == GSS_S_COMPLETE)
	*minor_status = 0;

    return ret;
}
示例#2
0
OM_uint32 GSSAPI_CALLCONV
_gsskrb5_export_sec_context (
    OM_uint32 * minor_status,
    gss_ctx_id_t * context_handle,
    gss_buffer_t interprocess_token
)
{
    krb5_context context;
    const gsskrb5_ctx ctx = (const gsskrb5_ctx) *context_handle;
    krb5_storage *sp;
    krb5_auth_context ac;
    OM_uint32 ret = GSS_S_COMPLETE;
    krb5_data data;
    gss_buffer_desc buffer;
    int flags;
    OM_uint32 minor;
    krb5_error_code kret;

    GSSAPI_KRB5_INIT (&context);

    HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);

    if (!(ctx->flags & GSS_C_TRANS_FLAG)) {
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        *minor_status = 0;
        return GSS_S_UNAVAILABLE;
    }

    sp = krb5_storage_emem ();
    if (sp == NULL) {
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        *minor_status = ENOMEM;
        return GSS_S_FAILURE;
    }
    ac = ctx->auth_context;

    /* flagging included fields */

    flags = 0;
    if (ac->local_address)
        flags |= SC_LOCAL_ADDRESS;
    if (ac->remote_address)
        flags |= SC_REMOTE_ADDRESS;
    if (ac->keyblock)
        flags |= SC_KEYBLOCK;
    if (ac->local_subkey)
        flags |= SC_LOCAL_SUBKEY;
    if (ac->remote_subkey)
        flags |= SC_REMOTE_SUBKEY;

    kret = krb5_store_int32 (sp, flags);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    /* marshall auth context */

    kret = krb5_store_int32 (sp, ac->flags);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    if (ac->local_address) {
        kret = krb5_store_address (sp, *ac->local_address);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    if (ac->remote_address) {
        kret = krb5_store_address (sp, *ac->remote_address);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    kret = krb5_store_int16 (sp, ac->local_port);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int16 (sp, ac->remote_port);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    if (ac->keyblock) {
        kret = krb5_store_keyblock (sp, *ac->keyblock);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    if (ac->local_subkey) {
        kret = krb5_store_keyblock (sp, *ac->local_subkey);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    if (ac->remote_subkey) {
        kret = krb5_store_keyblock (sp, *ac->remote_subkey);
        if (kret) {
            *minor_status = kret;
            goto failure;
        }
    }
    kret = krb5_store_int32 (sp, ac->local_seqnumber);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int32 (sp, ac->remote_seqnumber);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    kret = krb5_store_int32 (sp, ac->keytype);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int32 (sp, ac->cksumtype);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    /* names */

    ret = _gsskrb5_export_name (minor_status,
                                (gss_name_t)ctx->source, &buffer);
    if (ret)
        goto failure;
    data.data   = buffer.value;
    data.length = buffer.length;
    kret = krb5_store_data (sp, data);
    _gsskrb5_release_buffer (&minor, &buffer);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    ret = _gsskrb5_export_name (minor_status,
                                (gss_name_t)ctx->target, &buffer);
    if (ret)
        goto failure;
    data.data   = buffer.value;
    data.length = buffer.length;

    ret = GSS_S_FAILURE;

    kret = krb5_store_data (sp, data);
    _gsskrb5_release_buffer (&minor, &buffer);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }

    kret = krb5_store_int32 (sp, ctx->flags);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int32 (sp, ctx->more_flags);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = krb5_store_int32 (sp, ctx->lifetime);
    if (kret) {
        *minor_status = kret;
        goto failure;
    }
    kret = _gssapi_msg_order_export(sp, ctx->order);
    if (kret ) {
        *minor_status = kret;
        goto failure;
    }

    kret = krb5_storage_to_data (sp, &data);
    krb5_storage_free (sp);
    if (kret) {
        HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
        *minor_status = kret;
        return GSS_S_FAILURE;
    }
    interprocess_token->length = data.length;
    interprocess_token->value  = data.data;
    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    ret = _gsskrb5_delete_sec_context (minor_status, context_handle,
                                       GSS_C_NO_BUFFER);
    if (ret != GSS_S_COMPLETE)
        _gsskrb5_release_buffer (NULL, interprocess_token);
    *minor_status = 0;
    return ret;
failure:
    HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
    krb5_storage_free (sp);
    return ret;
}
示例#3
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;
}
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;

}
示例#5
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;
}