static OM_uint32
gsskrb5_initiator_ready(
	OM_uint32 * minor_status,
	gsskrb5_ctx ctx)
{
	OM_uint32 ret;
	int32_t seq_number;
	int is_cfx = 0;
	OM_uint32 flags = ctx->flags;

	krb5_auth_getremoteseqnumber (_gsskrb5_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;
}
static OM_uint32
export_lucid_sec_context_v1(OM_uint32 *minor_status,
			    gsskrb5_ctx context_handle,
			    krb5_context context,
			    gss_buffer_set_t *data_set)
{
    krb5_storage *sp = NULL;
    OM_uint32 major_status = GSS_S_COMPLETE;
    krb5_error_code ret;
    krb5_keyblock *key = NULL;
    int32_t number;
    int is_cfx;
    krb5_data data;

    *minor_status = 0;

    HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);

    _gsskrb5i_is_cfx(context_handle, &is_cfx);

    sp = krb5_storage_emem();
    if (sp == NULL) {
	_gsskrb5_clear_status();
	ret = ENOMEM;
	goto out;
    }

    ret = krb5_store_int32(sp, 1);
    if (ret) goto out;
    ret = krb5_store_int32(sp, (context_handle->more_flags & LOCAL) ? 1 : 0);
    if (ret) goto out;
    ret = krb5_store_int32(sp, context_handle->lifetime);
    if (ret) goto out;
    krb5_auth_con_getlocalseqnumber (context,
				     context_handle->auth_context,
				     &number);
    ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
    if (ret) goto out;
    ret = krb5_store_uint32(sp, (uint32_t)number);
    if (ret) goto out;
    krb5_auth_getremoteseqnumber (context,
				  context_handle->auth_context,
				  &number);
    ret = krb5_store_uint32(sp, (uint32_t)0); /* store top half as zero */
    if (ret) goto out;
    ret = krb5_store_uint32(sp, (uint32_t)number);
    if (ret) goto out;
    ret = krb5_store_int32(sp, (is_cfx) ? 1 : 0);
    if (ret) goto out;

    ret = _gsskrb5i_get_token_key(context_handle, context, &key);
    if (ret) goto out;

    if (is_cfx == 0) {
	int sign_alg, seal_alg;

	switch (key->keytype) {
	case ETYPE_DES_CBC_CRC:
	case ETYPE_DES_CBC_MD4:
	case ETYPE_DES_CBC_MD5:
	    sign_alg = 0;
	    seal_alg = 0;
	    break;
	case ETYPE_DES3_CBC_MD5:
	case ETYPE_DES3_CBC_SHA1:
	    sign_alg = 4;
	    seal_alg = 2;
	    break;
	case ETYPE_ARCFOUR_HMAC_MD5:
	case ETYPE_ARCFOUR_HMAC_MD5_56:
	    sign_alg = 17;
	    seal_alg = 16;
	    break;
	default:
	    sign_alg = -1;
	    seal_alg = -1;
	    break;
	}
	ret = krb5_store_int32(sp, sign_alg);
	if (ret) goto out;
	ret = krb5_store_int32(sp, seal_alg);
	if (ret) goto out;
	/* ctx_key */
	ret = krb5_store_keyblock(sp, *key);
	if (ret) goto out;
    } else {
	int subkey_p = (context_handle->more_flags & ACCEPTOR_SUBKEY) ? 1 : 0;

	/* have_acceptor_subkey */
	ret = krb5_store_int32(sp, subkey_p);
	if (ret) goto out;
	/* ctx_key */
	ret = krb5_store_keyblock(sp, *key);
	if (ret) goto out;
	/* acceptor_subkey */
	if (subkey_p) {
	    ret = krb5_store_keyblock(sp, *key);
	    if (ret) goto out;
	}
    }
    ret = krb5_storage_to_data(sp, &data);
    if (ret) goto out;

    {
	gss_buffer_desc ad_data;

	ad_data.value = data.data;
	ad_data.length = data.length;

	ret = gss_add_buffer_set_member(minor_status, &ad_data, data_set);
	krb5_data_free(&data);
	if (ret)
	    goto out;
    }

out:
    if (key)
	krb5_free_keyblock (context, key);
    if (sp)
	krb5_storage_free(sp);
    if (ret) {
	*minor_status = ret;
	major_status = GSS_S_FAILURE;
    }
    HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
    return major_status;
}
Example #3
0
static void
test_ap(krb5_context context,
        krb5_principal sprincipal,
        krb5_keytab keytab,
        krb5_ccache ccache,
        const krb5_flags client_flags)
{
    krb5_error_code ret;
    krb5_auth_context client_ac = NULL, server_ac = NULL;
    krb5_data data;
    krb5_flags server_flags;
    krb5_ticket *ticket = NULL;
    int32_t server_seq, client_seq;

    ret = krb5_mk_req_exact(context,
                            &client_ac,
                            client_flags,
                            sprincipal,
                            NULL,
                            ccache,
                            &data);
    if (ret)
        krb5_err(context, 1, ret, "krb5_mk_req_exact");

    ret = krb5_rd_req(context,
                      &server_ac,
                      &data,
                      sprincipal,
                      keytab,
                      &server_flags,
                      &ticket);
    if (ret)
        krb5_err(context, 1, ret, "krb5_rd_req");


    if (server_flags & AP_OPTS_MUTUAL_REQUIRED) {
        krb5_ap_rep_enc_part *repl;

        krb5_data_free(&data);

        if ((client_flags & AP_OPTS_MUTUAL_REQUIRED) == 0)
            krb5_errx(context, 1, "client flag missing mutual req");

        ret = krb5_mk_rep (context, server_ac, &data);
        if (ret)
            krb5_err(context, 1, ret, "krb5_mk_rep");

        ret = krb5_rd_rep (context,
                           client_ac,
                           &data,
                           &repl);
        if (ret)
            krb5_err(context, 1, ret, "krb5_rd_rep");

        krb5_free_ap_rep_enc_part (context, repl);
    } else {
        if (client_flags & AP_OPTS_MUTUAL_REQUIRED)
            krb5_errx(context, 1, "server flag missing mutual req");
    }

    krb5_auth_getremoteseqnumber(context, server_ac, &server_seq);
    krb5_auth_getremoteseqnumber(context, client_ac, &client_seq);
    if (server_seq != client_seq)
        krb5_errx(context, 1, "seq num differ");

    krb5_auth_con_getlocalseqnumber(context, server_ac, &server_seq);
    krb5_auth_con_getlocalseqnumber(context, client_ac, &client_seq);
    if (server_seq != client_seq)
        krb5_errx(context, 1, "seq num differ");

    krb5_data_free(&data);
    krb5_auth_con_free(context, client_ac);
    krb5_auth_con_free(context, server_ac);

    if (verify_pac) {
        krb5_pac pac;

        ret = krb5_ticket_get_authorization_data_type(context,
                ticket,
                KRB5_AUTHDATA_WIN2K_PAC,
                &data);
        if (ret)
            krb5_err(context, 1, ret, "get pac");

        ret = krb5_pac_parse(context, data.data, data.length, &pac);
        if (ret)
            krb5_err(context, 1, ret, "pac parse");

        krb5_pac_free(context, pac);
    }

    krb5_free_ticket(context, ticket);
}