/*
 * Tests for the NTLM security provider
 *
 * Copyright 2005, 2006 Kai Blin
 * Copyright 2006 Dmitry Timoshkov
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * The code that tests for the behaviour of ISC_REQ_ALLOCATE_MEMORY is based
 * on code written by Dmitry Timoshkov.
 
 */

#include <stdarg.h>
#include <stdio.h>
#include <assert.h>
#include <windef.h>
#include <winbase.h>
#define SECURITY_WIN32
#include <sspi.h>
#include <rpc.h>
#include <rpcdce.h>

#include "wine/test.h"

static HMODULE secdll;
static PSecurityFunctionTableA (SEC_ENTRY * pInitSecurityInterfaceA)(void);
static SECURITY_STATUS (SEC_ENTRY * pFreeContextBuffer)(PVOID pv);
static SECURITY_STATUS (SEC_ENTRY * pQuerySecurityPackageInfoA)(SEC_CHAR*, PSecPkgInfoA*);
static SECURITY_STATUS (SEC_ENTRY * pAcquireCredentialsHandleA)(SEC_CHAR*, SEC_CHAR*,
                            ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
static SECURITY_STATUS (SEC_ENTRY * pInitializeSecurityContextA)(PCredHandle, PCtxtHandle,
                            SEC_CHAR*, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG, 
                            PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
static SECURITY_STATUS (SEC_ENTRY * pCompleteAuthToken)(PCtxtHandle, PSecBufferDesc);
static SECURITY_STATUS (SEC_ENTRY * pAcceptSecurityContext)(PCredHandle, PCtxtHandle,
                            PSecBufferDesc, ULONG, ULONG, PCtxtHandle, PSecBufferDesc,
                            PULONG, PTimeStamp);
static SECURITY_STATUS (SEC_ENTRY * pFreeCredentialsHandle)(PCredHandle);
static SECURITY_STATUS (SEC_ENTRY * pDeleteSecurityContext)(PCtxtHandle);
static SECURITY_STATUS (SEC_ENTRY * pQueryContextAttributesA)(PCtxtHandle, ULONG, PVOID);
static SECURITY_STATUS (SEC_ENTRY * pMakeSignature)(PCtxtHandle, ULONG,
                            PSecBufferDesc, ULONG);
static SECURITY_STATUS (SEC_ENTRY * pVerifySignature)(PCtxtHandle, PSecBufferDesc,
                            ULONG, PULONG);
static SECURITY_STATUS (SEC_ENTRY * pEncryptMessage)(PCtxtHandle, ULONG,
                            PSecBufferDesc, ULONG);
static SECURITY_STATUS (SEC_ENTRY * pDecryptMessage)(PCtxtHandle, PSecBufferDesc,
                            ULONG, PULONG);

typedef struct _SspiData {
    PCredHandle cred;
    PCtxtHandle ctxt;
    PSecBufferDesc in_buf;
    PSecBufferDesc out_buf;
    PSEC_WINNT_AUTH_IDENTITY id;
    ULONG max_token;
} SspiData;

static BYTE network_challenge[] = 
   {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
    0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
    0x05, 0x82, 0x82, 0xa0, 0xe9, 0x58, 0x7f, 0x14, 0xa2, 0x86,
    0x3b, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
    0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
    0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
    0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
    0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
    0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};

static BYTE native_challenge[] = 
   {0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00,
    0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0x30, 0x00, 0x00, 0x00,
    0x05, 0x82, 0x82, 0xa0, 0xb5, 0x60, 0x8e, 0x95, 0xb5, 0x3c,
    0xee, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x54, 0x00, 0x54, 0x00, 0x40, 0x00, 0x00, 0x00, 0x43, 0x00,
    0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x02, 0x00, 0x10, 0x00, 0x43, 0x00,
    0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x01, 0x00, 0x10, 0x00, 0x43, 0x00,
    0x41, 0x00, 0x53, 0x00, 0x49, 0x00, 0x4e, 0x00, 0x4f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x04, 0x00, 0x10, 0x00, 0x63, 0x00,
    0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x03, 0x00, 0x10, 0x00, 0x63, 0x00,
    0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x6f, 0x00,
    0x30, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00};

static BYTE message_signature[] =
   {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

static BYTE message_binary[] =
   {0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x77, 0x6f, 0x72,
    0x6c, 0x64, 0x21};

static char message[] = "Hello, world!";

static char message_header[] = "Header Test";

static BYTE crypt_trailer_client[] =
   {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xc7,
    0xaa, 0x26, 0x16, 0x39, 0x07, 0x4e};

static BYTE crypt_message_client[] =
   {0x86, 0x9c, 0x5a, 0x10, 0x78, 0xb3, 0x30, 0x98, 0x46, 0x15,
    0xa0, 0x31, 0xd9};

static BYTE crypt_trailer_client2[] =
   {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc5, 0xa7,
    0xf7, 0x0f, 0x5b, 0x25, 0xbe, 0xa4};

static BYTE crypt_message_client2[] =
   {0x20, 0x6c, 0x01, 0xab, 0xb0, 0x4c, 0x93, 0xe4, 0x1e, 0xfc,
    0xe1, 0xfa, 0xfe};

static BYTE crypt_trailer_server[] =
   {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x46,
    0x2e, 0x77, 0xeb, 0xf0, 0xf6, 0x9e};

static BYTE crypt_message_server[] =
   {0xf6, 0xb7, 0x92, 0x0c, 0xac, 0xea, 0x98, 0xe6, 0xef, 0xa0,
    0x29, 0x66, 0xfd};

static BYTE crypt_trailer_server2[] =
   {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x4e,
    0x46, 0xb7, 0xca, 0xf7, 0x7f, 0xb3};

static BYTE crypt_message_server2[] =
   {0xc8, 0xf2, 0x39, 0x7f, 0x0c, 0xaf, 0xf5, 0x5d, 0xef, 0x0c,
    0x8b, 0x5f, 0x82};

static void InitFunctionPtrs(void)
{
    secdll = LoadLibraryA("secur32.dll");
    if(!secdll)
        secdll = LoadLibraryA("security.dll");
    if(secdll)
    {
        pInitSecurityInterfaceA = (PVOID)GetProcAddress(secdll, "InitSecurityInterfaceA");
        pFreeContextBuffer = (PVOID)GetProcAddress(secdll, "FreeContextBuffer");
        pQuerySecurityPackageInfoA = (PVOID)GetProcAddress(secdll, "QuerySecurityPackageInfoA");
        pAcquireCredentialsHandleA = (PVOID)GetProcAddress(secdll, "AcquireCredentialsHandleA");
        pInitializeSecurityContextA = (PVOID)GetProcAddress(secdll, "InitializeSecurityContextA");
        pCompleteAuthToken = (PVOID)GetProcAddress(secdll, "CompleteAuthToken");
        pAcceptSecurityContext = (PVOID)GetProcAddress(secdll, "AcceptSecurityContext");
        pFreeCredentialsHandle = (PVOID)GetProcAddress(secdll, "FreeCredentialsHandle");
        pDeleteSecurityContext = (PVOID)GetProcAddress(secdll, "DeleteSecurityContext");
        pQueryContextAttributesA = (PVOID)GetProcAddress(secdll, "QueryContextAttributesA");
        pMakeSignature = (PVOID)GetProcAddress(secdll, "MakeSignature");
        pVerifySignature = (PVOID)GetProcAddress(secdll, "VerifySignature");
        pEncryptMessage = (PVOID)GetProcAddress(secdll, "EncryptMessage");
        pDecryptMessage = (PVOID)GetProcAddress(secdll, "DecryptMessage");
    }
}

static const char* getSecError(SECURITY_STATUS status)
{
    static char buf[20];

#define _SEC_ERR(x) case (x): return #x;
    switch(status)
    {
        _SEC_ERR(SEC_E_OK);
        _SEC_ERR(SEC_E_INSUFFICIENT_MEMORY);
        _SEC_ERR(SEC_E_INVALID_HANDLE);
        _SEC_ERR(SEC_E_UNSUPPORTED_FUNCTION);
        _SEC_ERR(SEC_E_TARGET_UNKNOWN);
        _SEC_ERR(SEC_E_INTERNAL_ERROR);
        _SEC_ERR(SEC_E_SECPKG_NOT_FOUND);
        _SEC_ERR(SEC_E_NOT_OWNER);
        _SEC_ERR(SEC_E_CANNOT_INSTALL);
        _SEC_ERR(SEC_E_INVALID_TOKEN);
        _SEC_ERR(SEC_E_CANNOT_PACK);
        _SEC_ERR(SEC_E_QOP_NOT_SUPPORTED);
        _SEC_ERR(SEC_E_NO_IMPERSONATION);
        _SEC_ERR(SEC_I_CONTINUE_NEEDED);
        _SEC_ERR(SEC_E_BUFFER_TOO_SMALL);
        _SEC_ERR(SEC_E_ILLEGAL_MESSAGE);
        _SEC_ERR(SEC_E_LOGON_DENIED);
        _SEC_ERR(SEC_E_NO_CREDENTIALS);
        _SEC_ERR(SEC_E_OUT_OF_SEQUENCE);
        _SEC_ERR(SEC_E_MESSAGE_ALTERED);
        default:
            sprintf(buf, "%08x\n", status);
            return buf;
    }
#undef _SEC_ERR
}

/**********************************************************************/

static SECURITY_STATUS setupBuffers(SspiData *sspi_data, SecPkgInfoA *sec_pkg_info)
{
    
    sspi_data->in_buf  = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
    sspi_data->out_buf = HeapAlloc(GetProcessHeap(), 0, sizeof(SecBufferDesc));
    sspi_data->max_token = sec_pkg_info->cbMaxToken;

    if(sspi_data->in_buf != NULL)
    {
        PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
                sizeof(SecBuffer));
        if(sec_buffer == NULL){
            trace("in_buf: sec_buffer == NULL\n");
            return SEC_E_INSUFFICIENT_MEMORY;
        }
        
        sspi_data->in_buf->ulVersion = SECBUFFER_VERSION;
        sspi_data->in_buf->cBuffers = 1;
        sspi_data->in_buf->pBuffers = sec_buffer;

        sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
        sec_buffer->BufferType = SECBUFFER_TOKEN;
        if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0, 
                        sec_pkg_info->cbMaxToken)) == NULL)
        {
            trace("in_buf: sec_buffer->pvBuffer == NULL\n");
            return SEC_E_INSUFFICIENT_MEMORY;
        }
    }
    else
    {
        trace("HeapAlloc in_buf returned NULL\n");
        return SEC_E_INSUFFICIENT_MEMORY;
    }
    
    if(sspi_data->out_buf != NULL)
    {
        PSecBuffer sec_buffer = HeapAlloc(GetProcessHeap(), 0,
                sizeof(SecBuffer));
        
        if(sec_buffer == NULL){
            trace("out_buf: sec_buffer == NULL\n");
            return SEC_E_INSUFFICIENT_MEMORY;
        }

        sspi_data->out_buf->ulVersion = SECBUFFER_VERSION;
        sspi_data->out_buf->cBuffers = 1;
        sspi_data->out_buf->pBuffers = sec_buffer;

        sec_buffer->cbBuffer = sec_pkg_info->cbMaxToken;
        sec_buffer->BufferType = SECBUFFER_TOKEN;
        if((sec_buffer->pvBuffer = HeapAlloc(GetProcessHeap(), 0, 
                        sec_pkg_info->cbMaxToken)) == NULL){
            trace("out_buf: sec_buffer->pvBuffer == NULL\n");
            return SEC_E_INSUFFICIENT_MEMORY;
        }
    }
    else
    {
        trace("HeapAlloc out_buf returned NULL\n");
        return SEC_E_INSUFFICIENT_MEMORY;
    }

    return SEC_E_OK;
}

/**********************************************************************/

static void cleanupBuffers(SspiData *sspi_data)
{
    ULONG i;

    if(sspi_data->in_buf != NULL)
    {
        for(i = 0; i < sspi_data->in_buf->cBuffers; ++i)
        {
            HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers[i].pvBuffer);
        }
        HeapFree(GetProcessHeap(), 0, sspi_data->in_buf->pBuffers);
        HeapFree(GetProcessHeap(), 0, sspi_data->in_buf);
    }
    
    if(sspi_data->out_buf != NULL)
    {
        for(i = 0; i < sspi_data->out_buf->cBuffers; ++i)
        {
            HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers[i].pvBuffer);
        }
        HeapFree(GetProcessHeap(), 0, sspi_data->out_buf->pBuffers);
        HeapFree(GetProcessHeap(), 0, sspi_data->out_buf);
    }
}

/**********************************************************************/

static SECURITY_STATUS setupClient(SspiData *sspi_data, SEC_CHAR *provider)
{
    SECURITY_STATUS ret;
    TimeStamp ttl;
    SecPkgInfoA *sec_pkg_info;

    trace("Running setupClient\n");
    
    sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
    sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));
    
    ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);

    ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));

    setupBuffers(sspi_data, sec_pkg_info);
    
    if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_OUTBOUND,
            NULL, sspi_data->id, NULL, NULL, sspi_data->cred, &ttl))
            != SEC_E_OK)
    {
        trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
    }

    ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n", 
            getSecError(ret));

    return ret;
}
/**********************************************************************/

static SECURITY_STATUS setupServer(SspiData *sspi_data, SEC_CHAR *provider)
{
    SECURITY_STATUS ret;
    TimeStamp ttl;
    SecPkgInfoA *sec_pkg_info;

    trace("Running setupServer\n");

    sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
    sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));

    ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);

    ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));

    setupBuffers(sspi_data, sec_pkg_info);

    if((ret = pAcquireCredentialsHandleA(NULL, provider, SECPKG_CRED_INBOUND, 
            NULL, NULL, NULL, NULL, sspi_data->cred, &ttl)) != SEC_E_OK)
    {
        trace("AcquireCredentialsHandle() returned %s\n", getSecError(ret));
    }

    ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
            getSecError(ret));

    return ret;
}

/**********************************************************************/

static SECURITY_STATUS setupFakeServer(SspiData *sspi_data, SEC_CHAR *provider)
{
    SECURITY_STATUS ret;
    SecPkgInfoA *sec_pkg_info;

    trace("Running setupFakeServer\n");

    sspi_data->cred = HeapAlloc(GetProcessHeap(), 0, sizeof(CredHandle));
    sspi_data->ctxt = HeapAlloc(GetProcessHeap(), 0, sizeof(CtxtHandle));

    ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);

    ok(ret == SEC_E_OK, "QuerySecurityPackageInfo returned %s\n", getSecError(ret));

    ret = setupBuffers(sspi_data, sec_pkg_info);
    
    return ret;
}


/**********************************************************************/

static SECURITY_STATUS runClient(SspiData *sspi_data, BOOL first, ULONG data_rep)
{
    SECURITY_STATUS ret;
    ULONG req_attr = 0;
    ULONG ctxt_attr;
    TimeStamp ttl;
    PSecBufferDesc in_buf = sspi_data->in_buf;
    PSecBufferDesc out_buf = sspi_data->out_buf;

    assert(in_buf->cBuffers >= 1);
    assert(in_buf->pBuffers[0].pvBuffer != NULL);
    assert(in_buf->pBuffers[0].cbBuffer != 0);

    assert(out_buf->cBuffers >= 1);
    assert(out_buf->pBuffers[0].pvBuffer != NULL);
    assert(out_buf->pBuffers[0].cbBuffer != 0);

    trace("Running the client the %s time.\n", first?"first":"second");

    /* We can either use ISC_REQ_ALLOCATE_MEMORY flag to ask the provider
     * always allocate output buffers for us, or initialize cbBuffer
     * before each call because the API changes it to represent actual
     * amount of data in the buffer.
     */

    /* test a failing call only the first time, otherwise we get
     * SEC_E_OUT_OF_SEQUENCE
     */
    if (first)
    {
        void *old_buf;

        /* pass NULL as an output buffer */
        ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
            0, data_rep, NULL, 0, sspi_data->ctxt, NULL,
            &ctxt_attr, &ttl);

        ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));

        /* pass NULL as an output buffer */
        old_buf = out_buf->pBuffers[0].pvBuffer;
        out_buf->pBuffers[0].pvBuffer = NULL;

        ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr, 
            0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
            &ctxt_attr, &ttl);

        ok(ret == SEC_E_INTERNAL_ERROR, "expected SEC_E_INTERNAL_ERROR, got %s\n", getSecError(ret));

        out_buf->pBuffers[0].pvBuffer = old_buf;

        /* pass an output buffer of 0 size */
        out_buf->pBuffers[0].cbBuffer = 0;

        ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr, 
            0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
            &ctxt_attr, &ttl);

        ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));

        ok(out_buf->pBuffers[0].cbBuffer == 0,
           "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);

        out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;
        out_buf->pBuffers[0].BufferType = SECBUFFER_DATA;

        ret = pInitializeSecurityContextA(sspi_data->cred, NULL, NULL, req_attr,
            0, data_rep, NULL, 0, sspi_data->ctxt, out_buf,
            &ctxt_attr, &ttl);

        ok(ret == SEC_E_BUFFER_TOO_SMALL, "expected SEC_E_BUFFER_TOO_SMALL, got %s\n", getSecError(ret));
        out_buf->pBuffers[0].BufferType = SECBUFFER_TOKEN;
    }

    out_buf->pBuffers[0].cbBuffer = sspi_data->max_token;

    ret = pInitializeSecurityContextA(first?sspi_data->cred:NULL, first?NULL:sspi_data->ctxt, NULL, req_attr,
            0, data_rep, first?NULL:in_buf, 0, sspi_data->ctxt, out_buf,
            &ctxt_attr, &ttl);

    if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
    {
        pCompleteAuthToken(sspi_data->ctxt, out_buf);
        if(ret == SEC_I_COMPLETE_AND_CONTINUE)
            ret = SEC_I_CONTINUE_NEEDED;
        else if(ret == SEC_I_COMPLETE_NEEDED)
            ret = SEC_E_OK;
    }

    ok(out_buf->pBuffers[0].BufferType == SECBUFFER_TOKEN,
       "buffer type was changed from SECBUFFER_TOKEN to %d\n", out_buf->pBuffers[0].BufferType);
    ok(out_buf->pBuffers[0].cbBuffer < sspi_data->max_token,
       "InitializeSecurityContext set buffer size to %u\n", out_buf->pBuffers[0].cbBuffer);

    return ret;
}

/**********************************************************************/

static SECURITY_STATUS runServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
{
    SECURITY_STATUS ret;
    ULONG ctxt_attr;
    TimeStamp ttl;

    trace("Running the server the %s time\n", first?"first":"second");

    ret = pAcceptSecurityContext(sspi_data->cred, first?NULL:sspi_data->ctxt, 
            sspi_data->in_buf, 0, data_rep, sspi_data->ctxt, 
            sspi_data->out_buf, &ctxt_attr, &ttl);

    if(ret == SEC_I_COMPLETE_AND_CONTINUE || ret == SEC_I_COMPLETE_NEEDED)
    {
        pCompleteAuthToken(sspi_data->ctxt, sspi_data->out_buf);
        if(ret == SEC_I_COMPLETE_AND_CONTINUE)
            ret = SEC_I_CONTINUE_NEEDED;
        else if(ret == SEC_I_COMPLETE_NEEDED)
            ret = SEC_E_OK;
    }

    return ret;
}

/**********************************************************************/

static SECURITY_STATUS runFakeServer(SspiData *sspi_data, BOOL first, ULONG data_rep)
{
    trace("Running the fake server the %s time\n", first?"first":"second");

    if(!first)
    {
        sspi_data->out_buf->pBuffers[0].cbBuffer = 0;
        return SEC_E_OK;
    }
    
    if(data_rep == SECURITY_NATIVE_DREP)
    {
        sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(native_challenge);
        memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, native_challenge, 
                sspi_data->out_buf->pBuffers[0].cbBuffer);
    }
    else
    {
        sspi_data->out_buf->pBuffers[0].cbBuffer = sizeof(network_challenge);
        memcpy(sspi_data->out_buf->pBuffers[0].pvBuffer, network_challenge, 
                sspi_data->out_buf->pBuffers[0].cbBuffer);
    }

    return SEC_I_CONTINUE_NEEDED;
}

/**********************************************************************/

static void communicate(SspiData *from, SspiData *to)
{
    if(from->out_buf != NULL && to->in_buf != NULL)
    {
        trace("Running communicate.\n");
        if((from->out_buf->cBuffers >= 1) && (to->in_buf->cBuffers >= 1))
        {
            if((from->out_buf->pBuffers[0].pvBuffer != NULL) && 
                    (to->in_buf->pBuffers[0].pvBuffer != NULL))
            {
                memset(to->in_buf->pBuffers[0].pvBuffer, 0, to->max_token);
                
                memcpy(to->in_buf->pBuffers[0].pvBuffer, 
                    from->out_buf->pBuffers[0].pvBuffer,
                    from->out_buf->pBuffers[0].cbBuffer);
                
                to->in_buf->pBuffers[0].cbBuffer = from->out_buf->pBuffers[0].cbBuffer;
                
                memset(from->out_buf->pBuffers[0].pvBuffer, 0, from->max_token);
            }
        }
    }
}

/**********************************************************************/
static void testInitializeSecurityContextFlags(void)
{
    SECURITY_STATUS         sec_status;
    PSecPkgInfo             pkg_info = NULL;
    SspiData                client;
    SEC_WINNT_AUTH_IDENTITY id;
    static char             sec_pkg_name[] = "NTLM",
                            test_user[]    = "testuser",
                            workgroup[]    = "WORKGROUP",
                            test_pass[]    = "testpass";
    ULONG                   req_attr, ctxt_attr;
    TimeStamp               ttl;
    PBYTE                   packet;

    if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
    {
        skip("Package not installed, skipping test!\n");
        return;
    }

    pFreeContextBuffer(pkg_info);
    id.User = (unsigned char*) test_user;
    id.UserLength = strlen((char *) id.User);
    id.Domain = (unsigned char *) workgroup;
    id.DomainLength = strlen((char *) id.Domain);
    id.Password = (unsigned char*) test_pass;
    id.PasswordLength = strlen((char *) id.Password);
    id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    client.id = &id;

    if((sec_status = setupClient(&client, sec_pkg_name)) != SEC_E_OK)
    {
        skip("Setting up the client returned %s, skipping test!\n",
                getSecError(sec_status));
        return;
    }

    packet = client.out_buf->pBuffers[0].pvBuffer;

    /* Due to how the requesting of the flags is implemented in ntlm_auth,
     * the tests need to be in this order, as there is no way to specify
     * "I request no special features" in ntlm_auth */

    /* Without any flags, the lowest byte should not have bits 0x20 or 0x10 set*/
    req_attr = 0;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
            "With req_attr == 0, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_CONNECTION, the lowest byte should not have bits 0x20 or 0x10 set*/
    req_attr = ISC_REQ_CONNECTION;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
            "For ISC_REQ_CONNECTION, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_EXTENDED_ERROR, the lowest byte should not have bits 0x20 or 0x10 set*/
    req_attr = ISC_REQ_EXTENDED_ERROR;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
            "For ISC_REQ_EXTENDED_ERROR, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_MUTUAL_AUTH, the lowest byte should not have bits 0x20 or 0x10 set*/
    req_attr = ISC_REQ_MUTUAL_AUTH;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
            "For ISC_REQ_MUTUAL_AUTH, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_USE_DCE_STYLE, the lowest byte should not have bits 0x20 or 0x10 set*/
    req_attr = ISC_REQ_USE_DCE_STYLE;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
            "For ISC_REQ_USE_DCE_STYLE, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_DELEGATE, the lowest byte should not have bits 0x20 or 0x10 set*/
    req_attr = ISC_REQ_DELEGATE;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
            "For ISC_REQ_DELEGATE, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_INTEGRITY, the lowest byte should have bit 0x10 set */
    req_attr = ISC_REQ_INTEGRITY;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok((packet[12] & 0x10) != 0,
            "For ISC_REQ_INTEGRITY, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_REPLAY_DETECT, the lowest byte should have bit 0x10 set */
    req_attr = ISC_REQ_REPLAY_DETECT;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok((packet[12] & 0x10) != 0,
            "For ISC_REQ_REPLAY_DETECT, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_SEQUENCE_DETECT, the lowest byte should have bit 0x10 set */
    req_attr = ISC_REQ_SEQUENCE_DETECT;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok((packet[12] & 0x10) != 0,
            "For ISC_REQ_SEQUENCE_DETECT, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

    /* With ISC_REQ_CONFIDENTIALITY, the lowest byte should have bit 0x20 set */
    req_attr = ISC_REQ_CONFIDENTIALITY;

    if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
        0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
        &ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
    {
        trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
                getSecError(sec_status));
        goto tISCFend;
    }

    ok((packet[12] & 0x20) != 0,
            "For ISC_REQ_CONFIDENTIALITY, flags are 0x%02x%02x%02x%02x.\n",
            packet[15], packet[14], packet[13], packet[12]);

tISCFend:
    cleanupBuffers(&client);
    pFreeCredentialsHandle(client.cred);

}

/**********************************************************************/

static void testAuth(ULONG data_rep, BOOL fake)
{
    SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
    SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
    SECURITY_STATUS         sec_status;
    PSecPkgInfo             pkg_info = NULL;
    BOOL                    first = TRUE;
    SspiData                client, server;
    SEC_WINNT_AUTH_IDENTITY id;
    SecPkgContext_Sizes     ctxt_sizes;
    static char             sec_pkg_name[] = "NTLM",
                            test_user[] = "testuser",
                            workgroup[] = "WORKGROUP",
                            test_pass[] = "testpass";

    if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)!= SEC_E_OK)
    {
        skip("Package not installed, skipping test.\n");
        return;
    }

    pFreeContextBuffer(pkg_info);
    id.User = (unsigned char*) test_user;
    id.UserLength = strlen((char *) id.User);
    id.Domain = (unsigned char *) workgroup;
    id.DomainLength = strlen((char *) id.Domain);
    id.Password = (unsigned char*) test_pass;
    id.PasswordLength = strlen((char *) id.Password);
    id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    client.id = &id;

    sec_status = setupClient(&client, sec_pkg_name);

    if(sec_status != SEC_E_OK)
    {
        skip("Error: Setting up the client returned %s, exiting test!\n",
                getSecError(sec_status));
        pFreeCredentialsHandle(client.cred);
        return;
    }

    if(fake)
        sec_status = setupFakeServer(&server, sec_pkg_name);
    else
        sec_status = setupServer(&server, sec_pkg_name);

    if(sec_status != SEC_E_OK)
    {
        skip("Error: Setting up the server returned %s, exiting test!\n",
                getSecError(sec_status));
        pFreeCredentialsHandle(server.cred);
        pFreeCredentialsHandle(client.cred);
        return;
    }

    while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
    {
        client_stat = runClient(&client, first, data_rep);

        ok(client_stat == SEC_E_OK || client_stat == SEC_I_CONTINUE_NEEDED,
                "Running the client returned %s, more tests will fail.\n",
                getSecError(client_stat));

        communicate(&client, &server);

        if(fake)
            server_stat = runFakeServer(&server, first, data_rep);
        else
            server_stat = runServer(&server, first, data_rep);

        ok(server_stat == SEC_E_OK || server_stat == SEC_I_CONTINUE_NEEDED ||
                server_stat == SEC_E_LOGON_DENIED,
                "Running the server returned %s, more tests will fail from now.\n",
                getSecError(server_stat));

        communicate(&server, &client);
        trace("Looping\n");
        first = FALSE;
    }

    if(client_stat != SEC_E_OK)
    {
        skip("Authentication failed, skipping test.\n");
        goto tAuthend;
    }

    sec_status = pQueryContextAttributesA(client.ctxt,
            SECPKG_ATTR_SIZES, &ctxt_sizes);

    ok(sec_status == SEC_E_OK,
            "pQueryContextAttributesA(SECPKG_ATTR_SIZES) returned %s\n",
            getSecError(sec_status));
    ok((ctxt_sizes.cbMaxToken == 1904) || (ctxt_sizes.cbMaxToken == 2888),
            "cbMaxToken should be 1904 or 2888 but is %u\n",
            ctxt_sizes.cbMaxToken);
    ok(ctxt_sizes.cbMaxSignature == 16,
            "cbMaxSignature should be 16 but is %u\n",
            ctxt_sizes.cbMaxSignature);
    ok(ctxt_sizes.cbSecurityTrailer == 16,
            "cbSecurityTrailer should be 16 but is  %u\n",
            ctxt_sizes.cbSecurityTrailer);
    ok(ctxt_sizes.cbBlockSize == 0,
            "cbBlockSize should be 0 but is %u\n",
            ctxt_sizes.cbBlockSize);

tAuthend:
    cleanupBuffers(&client);
    cleanupBuffers(&server);

    if(!fake)
    {
        sec_status = pDeleteSecurityContext(server.ctxt);
        ok(sec_status == SEC_E_OK, "DeleteSecurityContext(server) returned %s\n",
            getSecError(sec_status));
    }

    sec_status = pDeleteSecurityContext(client.ctxt);
    ok(sec_status == SEC_E_OK, "DeleteSecurityContext(client) returned %s\n",
            getSecError(sec_status));

    if(!fake)
    {
        sec_status = pFreeCredentialsHandle(server.cred);
        ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(server) returned %s\n",
            getSecError(sec_status));
    }

    sec_status = pFreeCredentialsHandle(client.cred);
    ok(sec_status == SEC_E_OK, "FreeCredentialsHandle(client) returned %s\n",
            getSecError(sec_status));
}

static void testSignSeal(void)
{
    SECURITY_STATUS         client_stat = SEC_I_CONTINUE_NEEDED;
    SECURITY_STATUS         server_stat = SEC_I_CONTINUE_NEEDED;
    SECURITY_STATUS         sec_status;
    PSecPkgInfo             pkg_info = NULL;
    BOOL                    first = TRUE;
    SspiData                client, server;
    SEC_WINNT_AUTH_IDENTITY id;
    static char             sec_pkg_name[] = "NTLM";
    SecBufferDesc           crypt;
    SecBuffer               data[2], fake_data[2], complex_data[4];
    ULONG                   qop = 0;
    SecPkgContext_Sizes     ctxt_sizes;
    static char             test_user[] = "testuser",
                            workgroup[] = "WORKGROUP",
                            test_pass[] = "testpass";

    complex_data[1].pvBuffer = complex_data[3].pvBuffer = NULL;

    /****************************************************************
     * This is basically the same as in testAuth with a fake server,
     * as we need a valid, authenticated context.
     */
    if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
    {
        skip("Package not installed, skipping test.\n");
        return;
    }

    pFreeContextBuffer(pkg_info);
    id.User = (unsigned char*) test_user;
    id.UserLength = strlen((char *) id.User);
    id.Domain = (unsigned char *) workgroup;
    id.DomainLength = strlen((char *) id.Domain);
    id.Password = (unsigned char*) test_pass;
    id.PasswordLength = strlen((char *) id.Password);
    id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    client.id = &id;

    sec_status = setupClient(&client, sec_pkg_name);

    if(sec_status != SEC_E_OK)
    {
        skip("Error: Setting up the client returned %s, exiting test!\n",
                getSecError(sec_status));
        pFreeCredentialsHandle(client.cred);
        return;
    }

    sec_status = setupFakeServer(&server, sec_pkg_name);

    while(client_stat == SEC_I_CONTINUE_NEEDED && server_stat == SEC_I_CONTINUE_NEEDED)
    {
        client_stat = runClient(&client, first, SECURITY_NETWORK_DREP);

        communicate(&client, &server);

        server_stat = runFakeServer(&server, first, SECURITY_NETWORK_DREP);

        communicate(&server, &client);
        trace("Looping\n");
        first = FALSE;
    }

    /********************************************
     *    Now start with the actual testing     *
     ********************************************/

    if(pQueryContextAttributesA(client.ctxt, SECPKG_ATTR_SIZES,
                &ctxt_sizes) != SEC_E_OK)
    {
        skip("Failed to get context sizes, aborting test.\n");
        goto end;
    }

    crypt.ulVersion = SECBUFFER_VERSION;
    crypt.cBuffers = 2;

    crypt.pBuffers = fake_data;

    fake_data[0].BufferType = SECBUFFER_DATA;
    fake_data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
    fake_data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[0].cbBuffer);

    fake_data[1].BufferType = SECBUFFER_DATA;
    fake_data[1].cbBuffer = lstrlen(message);
    fake_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, fake_data[1].cbBuffer);

    sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
    ok(sec_status == SEC_E_INVALID_TOKEN,
            "MakeSignature returned %s, not SEC_E_INVALID_TOKEN.\n",
            getSecError(sec_status));

    crypt.pBuffers = data;

    data[0].BufferType = SECBUFFER_TOKEN;
    data[0].cbBuffer = ctxt_sizes.cbSecurityTrailer;
    data[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[0].cbBuffer);

    data[1].BufferType = SECBUFFER_DATA;
    data[1].cbBuffer = lstrlen(message);
    data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
    memcpy(data[1].pvBuffer, message, data[1].cbBuffer);

    /* As we forced NTLM to fall back to a password-derived session key,
     * we should get the same signature for our data, no matter if
     * it is sent by the client or the server
     */
    sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
    ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
            getSecError(sec_status));
    ok(!memcmp(crypt.pBuffers[0].pvBuffer, message_signature,
               crypt.pBuffers[0].cbBuffer), "Signature is not as expected.\n");

    data[0].cbBuffer = sizeof(message_signature);

    memcpy(data[0].pvBuffer, crypt_trailer_client, data[0].cbBuffer);

    sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
    ok(sec_status == SEC_E_MESSAGE_ALTERED,
            "VerifySignature returned %s, not SEC_E_MESSAGE_ALTERED.\n",
            getSecError(sec_status));

    memcpy(data[0].pvBuffer, message_signature, data[0].cbBuffer);

    sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
    ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK.\n",
            getSecError(sec_status));

    sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
    if (sec_status == SEC_E_UNSUPPORTED_FUNCTION)
    {
        skip("Encrypt message returned SEC_E_UNSUPPORTED_FUNCTION. "
             "Expected on Vista.\n");
        goto end;
    }
    ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
            getSecError(sec_status));

    ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client,
               crypt.pBuffers[0].cbBuffer), "Crypt trailer not as expected.\n");
    ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
               crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");

    data[0].cbBuffer = sizeof(crypt_trailer_server);
    data[1].cbBuffer = sizeof(crypt_message_server);
    memcpy(data[0].pvBuffer, crypt_trailer_server, data[0].cbBuffer);
    memcpy(data[1].pvBuffer, crypt_message_server, data[1].cbBuffer);

    sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);

    ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
            getSecError(sec_status));
    ok(!memcmp(crypt.pBuffers[1].pvBuffer, message_binary,
               crypt.pBuffers[1].cbBuffer),
            "Failed to decrypt message correctly.\n");

    trace("Testing with more than one buffer.\n");

    crypt.cBuffers = sizeof(complex_data)/sizeof(complex_data[0]);
    crypt.pBuffers = complex_data;

    complex_data[0].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
    complex_data[0].cbBuffer = sizeof(message_header);
    complex_data[0].pvBuffer = message_header;

    complex_data[1].BufferType = SECBUFFER_DATA;
    complex_data[1].cbBuffer = lstrlen(message);
    complex_data[1].pvBuffer = HeapAlloc(GetProcessHeap(), 0, data[1].cbBuffer);
    memcpy(complex_data[1].pvBuffer, message, complex_data[1].cbBuffer);

    complex_data[2].BufferType = SECBUFFER_DATA|SECBUFFER_READONLY_WITH_CHECKSUM;
    complex_data[2].cbBuffer = sizeof(message_header);
    complex_data[2].pvBuffer = message_header;

    complex_data[3].BufferType = SECBUFFER_TOKEN;
    complex_data[3].cbBuffer = ctxt_sizes.cbSecurityTrailer;
    complex_data[3].pvBuffer = HeapAlloc(GetProcessHeap(), 0, complex_data[3].cbBuffer);

    /* We should get a dummy signature again. */
    sec_status = pMakeSignature(client.ctxt, 0, &crypt, 0);
    ok(sec_status == SEC_E_OK, "MakeSignature returned %s, not SEC_E_OK.\n",
            getSecError(sec_status));
    ok(!memcmp(crypt.pBuffers[3].pvBuffer, message_signature,
               crypt.pBuffers[3].cbBuffer), "Signature is not as expected.\n");

    /* Being a dummy signature, it will verify right away, as if the server
     * sent it */
    sec_status = pVerifySignature(client.ctxt, &crypt, 0, &qop);
    ok(sec_status == SEC_E_OK, "VerifySignature returned %s, not SEC_E_OK\n",
            getSecError(sec_status));

    sec_status = pEncryptMessage(client.ctxt, 0, &crypt, 0);
    ok(sec_status == SEC_E_OK, "EncryptMessage returned %s, not SEC_E_OK.\n",
            getSecError(sec_status));

    ok(!memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
               crypt.pBuffers[3].cbBuffer), "Crypt trailer not as expected.\n");

    ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
               crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");

    memcpy(complex_data[1].pvBuffer, crypt_message_server2, complex_data[1].cbBuffer);
    memcpy(complex_data[3].pvBuffer, crypt_trailer_server2, complex_data[3].cbBuffer);

    sec_status = pDecryptMessage(client.ctxt, &crypt, 0, &qop);
    ok(sec_status == SEC_E_OK, "DecryptMessage returned %s, not SEC_E_OK.\n",
            getSecError(sec_status));


end:
    cleanupBuffers(&client);
    cleanupBuffers(&server);

    pDeleteSecurityContext(client.ctxt);
    pFreeCredentialsHandle(client.cred);

    HeapFree(GetProcessHeap(), 0, fake_data[0].pvBuffer);
    HeapFree(GetProcessHeap(), 0, fake_data[1].pvBuffer);
    HeapFree(GetProcessHeap(), 0, data[0].pvBuffer);
    HeapFree(GetProcessHeap(), 0, data[1].pvBuffer);
    HeapFree(GetProcessHeap(), 0, complex_data[1].pvBuffer);
    HeapFree(GetProcessHeap(), 0, complex_data[3].pvBuffer);
}

static void testAcquireCredentialsHandle(void)
{
    CredHandle cred;
    TimeStamp ttl;
    static char test_user[] = "testuser",
                workgroup[] = "WORKGROUP",
                test_pass[] = "testpass",
                sec_pkg_name[] = "NTLM";
    SECURITY_STATUS ret;
    SEC_WINNT_AUTH_IDENTITY id;
    PSecPkgInfo             pkg_info = NULL;

    if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
    {
        skip("NTLM package not installed, skipping test\n");
        return;
    }
    pFreeContextBuffer(pkg_info);

    id.User = (unsigned char*) test_user;
    id.UserLength = strlen((char *) id.User);
    id.Domain = (unsigned char *) workgroup;
    id.DomainLength = strlen((char *) id.Domain);
    id.Password = (unsigned char*) test_pass;
    id.PasswordLength = strlen((char *) id.Password);
    id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);

    id.DomainLength = 0;
    ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);

    id.Domain = NULL;
    ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);

    id.Domain = (unsigned char *) workgroup;
    id.DomainLength = strlen((char *) id.Domain);
    id.UserLength = 0;
    id.User = NULL;
    ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);

    id.User = (unsigned char*) test_user;
    id.UserLength = strlen((char *) id.User);
    id.Password = NULL;
    id.PasswordLength = 0;
    ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);
}

static void test_cred_multiple_use(void)
{
    static char test_user[] = "testuser",
                workgroup[] = "WORKGROUP",
                test_pass[] = "testpass",
                sec_pkg_name[] = "NTLM";
    SECURITY_STATUS ret;
    SEC_WINNT_AUTH_IDENTITY id;
    PSecPkgInfo             pkg_info = NULL;
    CredHandle              cred;
    CtxtHandle              ctxt1;
    CtxtHandle              ctxt2;
    SecBufferDesc           buffer_desc;
    SecBuffer               buffers[1];
    ULONG                   ctxt_attr;
    TimeStamp               ttl;

    if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
    {
        skip("NTLM package not installed, skipping test\n");
        return;
    }
    buffers[0].cbBuffer = pkg_info->cbMaxToken;
    buffers[0].BufferType = SECBUFFER_TOKEN;
    buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);

    pFreeContextBuffer(pkg_info);

    id.User = (unsigned char*) test_user;
    id.UserLength = strlen((char *) id.User);
    id.Domain = (unsigned char *) workgroup;
    id.DomainLength = strlen((char *) id.Domain);
    id.Password = (unsigned char*) test_pass;
    id.PasswordLength = strlen((char *) id.Password);
    id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    ret = pAcquireCredentialsHandleA(NULL, sec_pkg_name, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHande() returned %s\n",
            getSecError(ret));

    buffer_desc.ulVersion = SECBUFFER_VERSION;
    buffer_desc.cBuffers = sizeof(buffers)/sizeof(buffers[0]);
    buffer_desc.pBuffers = buffers;

    ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
            0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt1, &buffer_desc,
            &ctxt_attr, &ttl);
    ok(ret == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed with error 0x%x\n", ret);

    ret = pInitializeSecurityContextA(&cred, NULL, NULL, ISC_REQ_CONNECTION,
            0, SECURITY_NETWORK_DREP, NULL, 0, &ctxt2, &buffer_desc,
            &ctxt_attr, &ttl);
    ok(ret == SEC_I_CONTINUE_NEEDED, "Second InitializeSecurityContextA on cred handle failed with error 0x%x\n", ret);

    ret = pDeleteSecurityContext(&ctxt1);
    ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
    ret = pDeleteSecurityContext(&ctxt2);
    ok(ret == SEC_E_OK, "DeleteSecurityContext failed with error 0x%x\n", ret);
    ret = pFreeCredentialsHandle(&cred);
    ok(ret == SEC_E_OK, "FreeCredentialsHandle failed with error 0x%x\n", ret);
}

START_TEST(ntlm)
{
    InitFunctionPtrs();

    if(pFreeCredentialsHandle && pDeleteSecurityContext &&
       pDeleteSecurityContext && pAcquireCredentialsHandleA &&
       pInitializeSecurityContextA && pCompleteAuthToken &&
       pQuerySecurityPackageInfoA)
    {
        testAcquireCredentialsHandle();
        testInitializeSecurityContextFlags();
        if(pAcceptSecurityContext)
        {
            testAuth(SECURITY_NATIVE_DREP, TRUE);
            testAuth(SECURITY_NETWORK_DREP, TRUE);
            testAuth(SECURITY_NATIVE_DREP, FALSE);
            testAuth(SECURITY_NETWORK_DREP, FALSE);
        }
        if(pMakeSignature && pVerifySignature && pEncryptMessage &&
           pDecryptMessage)
            testSignSeal();

        test_cred_multiple_use();
    }
    else
        win_skip("Needed functions are not available\n");

    if(secdll)
        FreeLibrary(secdll);
}
