/*
 * 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 <secext.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 * pAcquireCredentialsHandleW)(SEC_CHAR*, SEC_WCHAR*,
                            ULONG, PLUID, void*, SEC_GET_KEY_FN, void*, CredHandle*, TimeStamp*);
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);
static BOOLEAN (WINAPI * pGetUserNameExA)(EXTENDED_NAME_FORMAT, LPSTR, PULONG);

typedef struct _SspiData {
    CredHandle cred;
    CtxtHandle ctxt;
    PSecBufferDesc in_buf;
    PSecBufferDesc out_buf;
    PSEC_WINNT_AUTH_IDENTITY_A 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 const 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 char test_user[] = "testuser",
            workgroup[] = "WORKGROUP",
            test_pass[] = "testpass",
            sec_pkg_name[] = "NTLM";

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");
        pAcquireCredentialsHandleW = (void*)GetProcAddress(secdll, "AcquireCredentialsHandleW");
        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");
        pGetUserNameExA = (PVOID)GetProcAddress(secdll, "GetUserNameExA");
    }
}

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");
    
    ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);

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

    setupBuffers(sspi_data, sec_pkg_info);
    pFreeContextBuffer(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, "AcquireCredentialsHandle() 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");

    ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);

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

    setupBuffers(sspi_data, sec_pkg_info);
    pFreeContextBuffer(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, "AcquireCredentialsHandle() 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");

    ret = pQuerySecurityPackageInfoA(provider, &sec_pkg_info);

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

    ret = setupBuffers(sspi_data, sec_pkg_info);
    pFreeContextBuffer(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 || ret == SEC_I_CONTINUE_NEEDED,
           "expected SEC_E_INTERNAL_ERROR or SEC_I_CONTINUE_NEEDED, 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;
    PSecPkgInfoA            pkg_info = NULL;
    SspiData                client;
    SEC_WINNT_AUTH_IDENTITY_A id;
    ULONG                   req_attr, ctxt_attr;
    TimeStamp               ttl;
    PBYTE                   packet;

    if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
    {
        ok(0, "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;

    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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

    /* 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]);
    pDeleteSecurityContext(&client.ctxt);

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;
    PSecPkgInfoA            pkg_info = NULL;
    BOOL                    first = TRUE;
    SspiData                client, server;
    SEC_WINNT_AUTH_IDENTITY_A id;
    SecPkgContext_Sizes     ctxt_sizes;

    if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info)!= SEC_E_OK)
    {
        ok(0, "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;

    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;
    PSecPkgInfoA            pkg_info = NULL;
    BOOL                    first = TRUE;
    SspiData                client, server;
    SEC_WINNT_AUTH_IDENTITY_A id;
    static char             sec_pkg_name[] = "NTLM";
    SecBufferDesc           crypt;
    SecBuffer               data[2], fake_data[2], complex_data[4];
    ULONG                   qop = 0xdeadbeef;
    SecPkgContext_Sizes     ctxt_sizes;

    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)
    {
        ok(0, "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;

    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);
    ok(sec_status == SEC_E_OK, "setupFakeServer returned %s\n", getSecError(sec_status));

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

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

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

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

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

    /********************************************
     *    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 = lstrlenA(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 = lstrlenA(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));
    ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);

    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));
    ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);

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

    /* first 8 bytes must always be the same */
    ok(!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, 8), "Crypt trailer not as expected.\n");

    /* the rest depends on the session key */
    if (!memcmp(crypt.pBuffers[0].pvBuffer, crypt_trailer_client, crypt.pBuffers[0].cbBuffer))
    {
        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");
        if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client,
                   crypt.pBuffers[1].cbBuffer))
        {
            int i;
            for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
            {
                if (i % 8 == 0) printf("     ");
                printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
                if (i % 8 == 7) printf("\n");
            }
            printf("\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");
        ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);
    }
    else trace( "A different session key is being used\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 = lstrlenA(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));
    ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);

    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, 8), "Crypt trailer not as expected.\n");

    if (memcmp(crypt.pBuffers[3].pvBuffer, crypt_trailer_client2,
               crypt.pBuffers[3].cbBuffer)) goto end;

    ok(!memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
               crypt.pBuffers[1].cbBuffer), "Crypt message not as expected.\n");
    if (memcmp(crypt.pBuffers[1].pvBuffer, crypt_message_client2,
               crypt.pBuffers[1].cbBuffer))
    {
        int i;
        for (i = 0; i < crypt.pBuffers[1].cbBuffer; i++)
        {
            if (i % 8 == 0) printf("     ");
            printf("0x%02x,", ((unsigned char *)crypt.pBuffers[1].pvBuffer)[i]);
            if (i % 8 == 7) printf("\n");
        }
        printf("\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));
    ok(qop == 0xdeadbeef, "qop changed to %u\n", qop);


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 BOOL testAcquireCredentialsHandle(void)
{
    CredHandle cred;
    TimeStamp ttl;
    SECURITY_STATUS ret;
    SEC_WINNT_AUTH_IDENTITY_A id;
    PSecPkgInfoA pkg_info = NULL;

    if(pQuerySecurityPackageInfoA(sec_pkg_name, &pkg_info) != SEC_E_OK)
    {
        ok(0, "NTLM package not installed, skipping test\n");
        return FALSE;
    }
    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, "AcquireCredentialsHandle() 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, "AcquireCredentialsHandle() 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, "AcquireCredentialsHandle() 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, "AcquireCredentialsHandle() 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, "AcquireCredentialsHandle() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);
    return TRUE;
}

static void testAcquireCredentialsHandleW(void)
{
    CredHandle cred;
    TimeStamp ttl;
    static WCHAR sec_pkg_nameW[] = {'N','T','L','M',0 };
    static WCHAR test_userW[]    = {'t','e','s','t','u','s','e','r',0 };
    static WCHAR workgroupW[]    = {'W','O','R','K','G','R','O','U','P',0};
    static WCHAR test_passW[]    = {'t','e','s','t','p','a','s','s',0};
    SECURITY_STATUS ret;
    SEC_WINNT_AUTH_IDENTITY_A idA;
    SEC_WINNT_AUTH_IDENTITY_W id;
    PSecPkgInfoA pkg_info = NULL;

    if(!pAcquireCredentialsHandleW)
    {
        win_skip("AcquireCredentialsHandleW not available\n");
        return;
    }

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

    id.User = test_userW;
    id.UserLength = lstrlenW(test_userW);
    id.Domain = workgroupW;
    id.DomainLength = lstrlenW(workgroupW);
    id.Password = test_passW;
    id.PasswordLength = lstrlenW(test_passW);
    id.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

    ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);

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

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

    id.Domain = workgroupW;
    id.DomainLength = lstrlenW(workgroupW);
    id.UserLength = 0;
    id.User = NULL;
    ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);

    id.User = test_userW;
    id.UserLength = lstrlenW(test_userW);
    id.Password = test_passW;    /* NULL string causes a crash. */
    id.PasswordLength = 0;
    ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
            NULL, &id, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);

    /* Test using the ASCII structure. */
    idA.User = (unsigned char*) test_user;
    idA.UserLength = strlen(test_user);
    idA.Domain = (unsigned char *) workgroup;
    idA.DomainLength = strlen(workgroup);
    idA.Password = (unsigned char*) test_pass;
    idA.PasswordLength = strlen(test_pass);
    idA.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

    ret = pAcquireCredentialsHandleW(NULL, sec_pkg_nameW, SECPKG_CRED_OUTBOUND,
            NULL, &idA, NULL, NULL, &cred, &ttl);
    ok(ret == SEC_E_OK, "AcquireCredentialsHandeW() returned %s\n",
            getSecError(ret));
    pFreeCredentialsHandle(&cred);
}

static void test_cred_multiple_use(void)
{
    SECURITY_STATUS ret;
    SEC_WINNT_AUTH_IDENTITY_A id;
    PSecPkgInfoA            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)
    {
        ok(0, "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, "AcquireCredentialsHandle() 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);

    HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
}

static void test_null_auth_data(void)
{
    SECURITY_STATUS status;
    PSecPkgInfoA info;
    CredHandle cred;
    CtxtHandle ctx;
    SecBufferDesc buffer_desc;
    SecBuffer buffers[1];
    char user[256];
    TimeStamp ttl;
    ULONG attr, size;
    BOOLEAN ret;

    if(pQuerySecurityPackageInfoA((SEC_CHAR *)"NTLM", &info) != SEC_E_OK)
    {
        ok(0, "NTLM package not installed, skipping test\n");
        return;
    }

    status = pAcquireCredentialsHandleA(NULL, (SEC_CHAR *)"NTLM", SECPKG_CRED_OUTBOUND,
                                        NULL, NULL, NULL, NULL, &cred, &ttl);
    ok(status == SEC_E_OK, "AcquireCredentialsHandle() failed %s\n", getSecError(status));

    buffers[0].cbBuffer = info->cbMaxToken;
    buffers[0].BufferType = SECBUFFER_TOKEN;
    buffers[0].pvBuffer = HeapAlloc(GetProcessHeap(), 0, buffers[0].cbBuffer);

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

    size = sizeof(user);
    ret = pGetUserNameExA(NameSamCompatible, user, &size);
    ok(ret, "GetUserNameExA failed %u\n", GetLastError());

    status = pInitializeSecurityContextA(&cred, NULL, (SEC_CHAR *)user,
                                         ISC_REQ_CONNECTION, 0, SECURITY_NETWORK_DREP,
                                         NULL, 0, &ctx, &buffer_desc, &attr, &ttl);
    ok(status == SEC_I_CONTINUE_NEEDED, "InitializeSecurityContextA failed %s\n", getSecError(status));

    ret = pDeleteSecurityContext(&ctx);
    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);

    pFreeContextBuffer(info);
    HeapFree(GetProcessHeap(), 0, buffers[0].pvBuffer);
}

START_TEST(ntlm)
{
    InitFunctionPtrs();

    if(pFreeCredentialsHandle && pDeleteSecurityContext &&
       pAcquireCredentialsHandleA && pInitializeSecurityContextA &&
       pCompleteAuthToken && pQuerySecurityPackageInfoA)
    {
        testAcquireCredentialsHandleW();

        if(!testAcquireCredentialsHandle())
            goto cleanup;
        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();
        if (pGetUserNameExA) test_null_auth_data();
    }
    else
        win_skip("Needed functions are not available\n");

cleanup:
    if(secdll)
        FreeLibrary(secdll);
}
