/*
 * Copyright 2005, 2006 Kai Blin
 *
 * 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
 *
 * This file implements the NTLM security provider.
 */

#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "wincred.h"
#include "rpc.h"
#include "sspi.h"
#include "lm.h"
#include "secur32_priv.h"
#include "hmac_md5.h"
#include "wine/unicode.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(ntlm);

#define NTLM_MAX_BUF 1904
#define MIN_NTLM_AUTH_MAJOR_VERSION 3
#define MIN_NTLM_AUTH_MINOR_VERSION 0
#define MIN_NTLM_AUTH_MICRO_VERSION 25

static CHAR ntlm_auth[] = "ntlm_auth";

typedef struct _NtlmCredentials
{
    HelperMode mode;

    /* these are all in the Unix codepage */
    char *username_arg;
    char *domain_arg;
    char *password; /* not nul-terminated */
    int pwlen;
} NtlmCredentials, *PNtlmCredentials;

/***********************************************************************
 *              QueryCredentialsAttributesA
 */
static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA(
        PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
{
    SECURITY_STATUS ret;

    TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);

    if(ulAttribute == SECPKG_ATTR_NAMES)
    {
        FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
        ret = SEC_E_UNSUPPORTED_FUNCTION;
    }
    else
        ret = SEC_E_UNSUPPORTED_FUNCTION;
    
    return ret;
}

/***********************************************************************
 *              QueryCredentialsAttributesW
 */
static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW(
        PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
{
    SECURITY_STATUS ret;

    TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);

    if(ulAttribute == SECPKG_ATTR_NAMES)
    {
        FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
        ret = SEC_E_UNSUPPORTED_FUNCTION;
    }
    else
        ret = SEC_E_UNSUPPORTED_FUNCTION;
    
    return ret;
}

static char *ntlm_GetUsernameArg(LPCWSTR userW, INT userW_length)
{
    static const char username_arg[] = "--username=";
    char *user;
    int unixcp_size;

    unixcp_size =  WideCharToMultiByte(CP_UNIXCP, WC_NO_BEST_FIT_CHARS,
        userW, userW_length, NULL, 0, NULL, NULL) + sizeof(username_arg);
    user = HeapAlloc(GetProcessHeap(), 0, unixcp_size);
    if (!user) return NULL;
    memcpy(user, username_arg, sizeof(username_arg) - 1);
    WideCharToMultiByte(CP_UNIXCP, WC_NO_BEST_FIT_CHARS, userW, userW_length,
        user + sizeof(username_arg) - 1,
        unixcp_size - sizeof(username_arg) + 1, NULL, NULL);
    user[unixcp_size - 1] = '\0';
    return user;
}

static char *ntlm_GetDomainArg(LPCWSTR domainW, INT domainW_length)
{
    static const char domain_arg[] = "--domain=";
    char *domain;
    int unixcp_size;

    unixcp_size = WideCharToMultiByte(CP_UNIXCP, WC_NO_BEST_FIT_CHARS,
        domainW, domainW_length, NULL, 0,  NULL, NULL) + sizeof(domain_arg);
    domain = HeapAlloc(GetProcessHeap(), 0, unixcp_size);
    if (!domain) return NULL;
    memcpy(domain, domain_arg, sizeof(domain_arg) - 1);
    WideCharToMultiByte(CP_UNIXCP, WC_NO_BEST_FIT_CHARS, domainW,
        domainW_length, domain + sizeof(domain_arg) - 1,
        unixcp_size - sizeof(domain) + 1, NULL, NULL);
    domain[unixcp_size - 1] = '\0';
    return domain;
}

/***********************************************************************
 *              AcquireCredentialsHandleW
 */
static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(
 SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;
    PNtlmCredentials ntlm_cred = NULL;
    SEC_WCHAR *username = NULL, *domain = NULL;

    TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p)\n",
     debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
     pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);

    switch(fCredentialUse)
    {
        case SECPKG_CRED_INBOUND:
            ntlm_cred = HeapAlloc(GetProcessHeap(), 0, sizeof(*ntlm_cred));
            if (!ntlm_cred)
                ret = SEC_E_INSUFFICIENT_MEMORY;
            else
            {
                ntlm_cred->mode = NTLM_SERVER;
                ntlm_cred->username_arg = NULL;
                ntlm_cred->domain_arg = NULL;
                ntlm_cred->password = NULL;
                ntlm_cred->pwlen = 0;
                phCredential->dwUpper = fCredentialUse;
                phCredential->dwLower = (ULONG_PTR)ntlm_cred;
                ret = SEC_E_OK;
            }
            break;
        case SECPKG_CRED_OUTBOUND:
            {
                ntlm_cred = HeapAlloc(GetProcessHeap(), 0, sizeof(*ntlm_cred));
                if (!ntlm_cred)
                {
                    ret = SEC_E_INSUFFICIENT_MEMORY;
                    break;
                }
                ntlm_cred->mode = NTLM_CLIENT;
                ntlm_cred->username_arg = NULL;
                ntlm_cred->domain_arg = NULL;
                ntlm_cred->password = NULL;
                ntlm_cred->pwlen = 0;

                if(pAuthData != NULL)
                {
                    PSEC_WINNT_AUTH_IDENTITY_W auth_data = pAuthData;

                    TRACE("Username is %s\n", debugstr_wn(auth_data->User, auth_data->UserLength));
                    TRACE("Domain name is %s\n", debugstr_wn(auth_data->Domain, auth_data->DomainLength));

                    ntlm_cred->username_arg = ntlm_GetUsernameArg(auth_data->User, auth_data->UserLength);
                    ntlm_cred->domain_arg = ntlm_GetDomainArg(auth_data->Domain, auth_data->DomainLength);

                    if(auth_data->PasswordLength != 0)
                    {
                        ntlm_cred->pwlen = WideCharToMultiByte(CP_UNIXCP,
                                                               WC_NO_BEST_FIT_CHARS, auth_data->Password,
                                                               auth_data->PasswordLength, NULL, 0, NULL,
                                                               NULL);

                        ntlm_cred->password = HeapAlloc(GetProcessHeap(), 0,
                                                        ntlm_cred->pwlen);

                        WideCharToMultiByte(CP_UNIXCP, WC_NO_BEST_FIT_CHARS,
                                            auth_data->Password, auth_data->PasswordLength,
                                            ntlm_cred->password, ntlm_cred->pwlen, NULL, NULL);
                    }
                }

                phCredential->dwUpper = fCredentialUse;
                phCredential->dwLower = (ULONG_PTR)ntlm_cred;
                TRACE("ACH phCredential->dwUpper: 0x%08lx, dwLower: 0x%08lx\n",
                      phCredential->dwUpper, phCredential->dwLower);
                ret = SEC_E_OK;
                break;
            }
        case SECPKG_CRED_BOTH:
            FIXME("AcquireCredentialsHandle: SECPKG_CRED_BOTH stub\n");
            ret = SEC_E_UNSUPPORTED_FUNCTION;
            phCredential = NULL;
            break;
        default:
            phCredential = NULL;
            ret = SEC_E_UNKNOWN_CREDENTIALS;
    }

    HeapFree(GetProcessHeap(), 0, username);
    HeapFree(GetProcessHeap(), 0, domain);

    return ret;
}

/***********************************************************************
 *              AcquireCredentialsHandleA
 */
static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(
 SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
 PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
 PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;
    int user_sizeW, domain_sizeW, passwd_sizeW;
    
    SEC_WCHAR *user = NULL, *domain = NULL, *passwd = NULL, *package = NULL;
    
    PSEC_WINNT_AUTH_IDENTITY_W pAuthDataW = NULL;
    PSEC_WINNT_AUTH_IDENTITY_A identity  = NULL;

    TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p)\n",
     debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
     pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
    
    if(pszPackage != NULL)
    {
        int package_sizeW = MultiByteToWideChar(CP_ACP, 0, pszPackage, -1,
                NULL, 0);

        package = HeapAlloc(GetProcessHeap(), 0, package_sizeW * 
                sizeof(SEC_WCHAR));
        MultiByteToWideChar(CP_ACP, 0, pszPackage, -1, package, package_sizeW);
    }

    
    if(pAuthData != NULL)
    {
        identity = pAuthData;

        if(identity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
        {
            pAuthDataW = HeapAlloc(GetProcessHeap(), 0, 
                    sizeof(SEC_WINNT_AUTH_IDENTITY_W));

            if(identity->UserLength != 0)
            {
                user_sizeW = MultiByteToWideChar(CP_ACP, 0, 
                    (LPCSTR)identity->User, identity->UserLength, NULL, 0);
                user = HeapAlloc(GetProcessHeap(), 0, user_sizeW * 
                        sizeof(SEC_WCHAR));
                MultiByteToWideChar(CP_ACP, 0, (LPCSTR)identity->User, 
                    identity->UserLength, user, user_sizeW);
            }
            else
            {
                user_sizeW = 0;
            }
             
            if(identity->DomainLength != 0)
            {
                domain_sizeW = MultiByteToWideChar(CP_ACP, 0, 
                    (LPCSTR)identity->Domain, identity->DomainLength, NULL, 0);
                domain = HeapAlloc(GetProcessHeap(), 0, domain_sizeW 
                    * sizeof(SEC_WCHAR));
                MultiByteToWideChar(CP_ACP, 0, (LPCSTR)identity->Domain, 
                    identity->DomainLength, domain, domain_sizeW);
            }
            else
            {
                domain_sizeW = 0;
            }

            if(identity->PasswordLength != 0)
            {
                passwd_sizeW = MultiByteToWideChar(CP_ACP, 0, 
                    (LPCSTR)identity->Password, identity->PasswordLength,
                    NULL, 0);
                passwd = HeapAlloc(GetProcessHeap(), 0, passwd_sizeW
                    * sizeof(SEC_WCHAR));
                MultiByteToWideChar(CP_ACP, 0, (LPCSTR)identity->Password,
                    identity->PasswordLength, passwd, passwd_sizeW);
            }
            else
            {
                passwd_sizeW = 0;
            }
            
            pAuthDataW->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
            pAuthDataW->User = user;
            pAuthDataW->UserLength = user_sizeW;
            pAuthDataW->Domain = domain;
            pAuthDataW->DomainLength = domain_sizeW;
            pAuthDataW->Password = passwd;
            pAuthDataW->PasswordLength = passwd_sizeW;
        }
        else
        {
            pAuthDataW = (PSEC_WINNT_AUTH_IDENTITY_W)identity;
        }
    }       
    
    ret = ntlm_AcquireCredentialsHandleW(NULL, package, fCredentialUse, 
            pLogonID, pAuthDataW, pGetKeyFn, pGetKeyArgument, phCredential,
            ptsExpiry);
    
    HeapFree(GetProcessHeap(), 0, package);
    HeapFree(GetProcessHeap(), 0, user);
    HeapFree(GetProcessHeap(), 0, domain);
    HeapFree(GetProcessHeap(), 0, passwd);
    if(pAuthDataW != (PSEC_WINNT_AUTH_IDENTITY_W)identity)
        HeapFree(GetProcessHeap(), 0, pAuthDataW);
    
    return ret;
}

/*************************************************************************
 *             ntlm_GetTokenBufferIndex
 * Calculates the index of the secbuffer with BufferType == SECBUFFER_TOKEN
 * Returns index if found or -1 if not found.
 */
static int ntlm_GetTokenBufferIndex(PSecBufferDesc pMessage)
{
    UINT i;

    TRACE("%p\n", pMessage);

    for( i = 0; i < pMessage->cBuffers; ++i )
    {
        if(pMessage->pBuffers[i].BufferType == SECBUFFER_TOKEN)
            return i;
    }

    return -1;
}

/*************************************************************************
 *             ntlm_GetDataBufferIndex
 * Calculates the index of the first secbuffer with BufferType == SECBUFFER_DATA
 * Returns index if found or -1 if not found.
 */
static int ntlm_GetDataBufferIndex(PSecBufferDesc pMessage)
{
    UINT i;

    TRACE("%p\n", pMessage);

    for( i = 0; i < pMessage->cBuffers; ++i )
    {
        if(pMessage->pBuffers[i].BufferType == SECBUFFER_DATA)
            return i;
    }

    return -1;
}

static BOOL ntlm_GetCachedCredential(const SEC_WCHAR *pszTargetName, PCREDENTIALW *cred)
{
    LPCWSTR p;
    LPCWSTR pszHost;
    LPWSTR pszHostOnly;
    BOOL ret;

    if (!pszTargetName)
        return FALSE;

    /* try to get the start of the hostname from service principal name (SPN) */
    pszHost = strchrW(pszTargetName, '/');
    if (pszHost)
    {
        /* skip slash character */
        pszHost++;

        /* find end of host by detecting start of instance port or start of referrer */
        p = strchrW(pszHost, ':');
        if (!p)
            p = strchrW(pszHost, '/');
        if (!p)
            p = pszHost + strlenW(pszHost);
    }
    else /* otherwise not an SPN, just a host */
    {
        pszHost = pszTargetName;
        p = pszHost + strlenW(pszHost);
    }

    pszHostOnly = HeapAlloc(GetProcessHeap(), 0, (p - pszHost + 1) * sizeof(WCHAR));
    if (!pszHostOnly)
        return FALSE;

    memcpy(pszHostOnly, pszHost, (p - pszHost) * sizeof(WCHAR));
    pszHostOnly[p - pszHost] = '\0';

    ret = CredReadW(pszHostOnly, CRED_TYPE_DOMAIN_PASSWORD, 0, cred);

    HeapFree(GetProcessHeap(), 0, pszHostOnly);
    return ret;
}

/***********************************************************************
 *              InitializeSecurityContextW
 */
static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
 PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, 
 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
 PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, 
 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;
    PNtlmCredentials ntlm_cred = NULL;
    PNegoHelper helper = NULL;
    ULONG ctxt_attr = 0;
    char* buffer, *want_flags = NULL;
    PBYTE bin;
    int buffer_len, bin_len, max_len = NTLM_MAX_BUF;
    int token_idx;
    SEC_CHAR *username = NULL;
    SEC_CHAR *domain = NULL;
    SEC_CHAR *password = NULL;

    TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
     debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
     Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);

    /****************************************
     * When communicating with the client, there can be the
     * following reply packets:
     * YR <base64 blob>         should be sent to the server
     * PW                       should be sent back to helper with
     *                          base64 encoded password
     * AF <base64 blob>         client is done, blob should be
     *                          sent to server with KK prefixed
     * GF <string list>         A string list of negotiated flags
     * GK <base64 blob>         base64 encoded session key
     * BH <char reason>         something broke
     */
    /* The squid cache size is 2010 chars, and that's what ntlm_auth uses */

    if(TargetDataRep == SECURITY_NETWORK_DREP){
        TRACE("Setting SECURITY_NETWORK_DREP\n");
    }

    buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(char) * NTLM_MAX_BUF);
    bin = HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE) * NTLM_MAX_BUF);

    if((phContext == NULL) && (pInput == NULL))
    {
        static char helper_protocol[] = "--helper-protocol=ntlmssp-client-1";
        static CHAR credentials_argv[] = "--use-cached-creds";
        SEC_CHAR *client_argv[5];
        int pwlen = 0;

        TRACE("First time in ISC()\n");

        if(!phCredential)
        {
            ret = SEC_E_INVALID_HANDLE;
            goto isc_end;
        }

        /* As the server side of sspi never calls this, make sure that
         * the handler is a client handler.
         */
        ntlm_cred = (PNtlmCredentials)phCredential->dwLower;
        if(ntlm_cred->mode != NTLM_CLIENT)
        {
            TRACE("Cred mode = %d\n", ntlm_cred->mode);
            ret = SEC_E_INVALID_HANDLE;
            goto isc_end;
        }

        client_argv[0] = ntlm_auth;
        client_argv[1] = helper_protocol;
        if (!ntlm_cred->username_arg && !ntlm_cred->domain_arg)
        {
            LPWKSTA_USER_INFO_1 ui = NULL;
            NET_API_STATUS status;
            PCREDENTIALW cred;

            if (ntlm_GetCachedCredential(pszTargetName, &cred))
            {
                LPWSTR p;
                p = strchrW(cred->UserName, '\\');
                if (p)
                {
                    domain = ntlm_GetDomainArg(cred->UserName, p - cred->UserName);
                    p++;
                }
                else
                {
                    domain = ntlm_GetDomainArg(NULL, 0);
                    p = cred->UserName;
                }

                username = ntlm_GetUsernameArg(p, -1);

                if(cred->CredentialBlobSize != 0)
                {
                    pwlen = WideCharToMultiByte(CP_UNIXCP,
                        WC_NO_BEST_FIT_CHARS, (LPWSTR)cred->CredentialBlob,
                        cred->CredentialBlobSize / sizeof(WCHAR), NULL, 0,
                        NULL, NULL);

                    password = HeapAlloc(GetProcessHeap(), 0, pwlen);

                    WideCharToMultiByte(CP_UNIXCP, WC_NO_BEST_FIT_CHARS,
                                        (LPWSTR)cred->CredentialBlob,
                                        cred->CredentialBlobSize / sizeof(WCHAR),
                                        password, pwlen, NULL, NULL);
                }

                CredFree(cred);

                client_argv[2] = username;
                client_argv[3] = domain;
                client_argv[4] = NULL;
            }
            else
            {
                status = NetWkstaUserGetInfo(NULL, 1, (LPBYTE *)&ui);
                if (status != NERR_Success || ui == NULL)
                {
                    ret = SEC_E_NO_CREDENTIALS;
                    goto isc_end;
                }
                username = ntlm_GetUsernameArg(ui->wkui1_username, -1);
                NetApiBufferFree(ui);

                TRACE("using cached credentials\n");

                client_argv[2] = username;
                client_argv[3] = credentials_argv;
                client_argv[4] = NULL;
            }
        }
        else
        {
            client_argv[2] = ntlm_cred->username_arg;
            client_argv[3] = ntlm_cred->domain_arg;
            client_argv[4] = NULL;
        }

        if((ret = fork_helper(&helper, ntlm_auth, client_argv)) != SEC_E_OK)
            goto isc_end;

        helper->mode = NTLM_CLIENT;
        helper->session_key = HeapAlloc(GetProcessHeap(), 0, 16);
        if (!helper->session_key)
        {
            cleanup_helper(helper);
            ret = SEC_E_INSUFFICIENT_MEMORY;
            goto isc_end;
        }

        /* Generate the dummy session key = MD4(MD4(password))*/
        if(password || ntlm_cred->password)
        {
            SEC_WCHAR *unicode_password;
            int passwd_lenW;

            TRACE("Converting password to unicode.\n");
            passwd_lenW = MultiByteToWideChar(CP_ACP, 0,
                                              password ? password : ntlm_cred->password,
                                              password ? pwlen : ntlm_cred->pwlen,
                                              NULL, 0);
            unicode_password = HeapAlloc(GetProcessHeap(), 0,
                                         passwd_lenW * sizeof(SEC_WCHAR));
            MultiByteToWideChar(CP_ACP, 0, password ? password : ntlm_cred->password,
                                password ? pwlen : ntlm_cred->pwlen, unicode_password, passwd_lenW);

            SECUR32_CreateNTLMv1SessionKey((PBYTE)unicode_password,
                                           passwd_lenW * sizeof(SEC_WCHAR), helper->session_key);

            HeapFree(GetProcessHeap(), 0, unicode_password);
        }
        else
            memset(helper->session_key, 0, 16);

        /* Allocate space for a maximal string of 
         * "SF NTLMSSP_FEATURE_SIGN NTLMSSP_FEATURE_SEAL
         * NTLMSSP_FEATURE_SESSION_KEY"
         */
        want_flags = HeapAlloc(GetProcessHeap(), 0, 73);
        if(want_flags == NULL)
        {
            cleanup_helper(helper);
            ret = SEC_E_INSUFFICIENT_MEMORY;
            goto isc_end;
        }
        lstrcpyA(want_flags, "SF");
        if(fContextReq & ISC_REQ_CONFIDENTIALITY)
        {
            if(strstr(want_flags, "NTLMSSP_FEATURE_SEAL") == NULL)
                lstrcatA(want_flags, " NTLMSSP_FEATURE_SEAL");
        }
        if(fContextReq & ISC_REQ_CONNECTION)
            ctxt_attr |= ISC_RET_CONNECTION;
        if(fContextReq & ISC_REQ_EXTENDED_ERROR)
            ctxt_attr |= ISC_RET_EXTENDED_ERROR;
        if(fContextReq & ISC_REQ_INTEGRITY)
        {
            if(strstr(want_flags, "NTLMSSP_FEATURE_SIGN") == NULL)
                lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
        }
        if(fContextReq & ISC_REQ_MUTUAL_AUTH)
            ctxt_attr |= ISC_RET_MUTUAL_AUTH;
        if(fContextReq & ISC_REQ_REPLAY_DETECT)
        {
            if(strstr(want_flags, "NTLMSSP_FEATURE_SIGN") == NULL)
                lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
        }
        if(fContextReq & ISC_REQ_SEQUENCE_DETECT)
        {
            if(strstr(want_flags, "NTLMSSP_FEATURE_SIGN") == NULL)
                lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
        }
        if(fContextReq & ISC_REQ_STREAM)
            FIXME("ISC_REQ_STREAM\n");
        if(fContextReq & ISC_REQ_USE_DCE_STYLE)
            ctxt_attr |= ISC_RET_USED_DCE_STYLE;
        if(fContextReq & ISC_REQ_DELEGATE)
            ctxt_attr |= ISC_RET_DELEGATE;

        /* If no password is given, try to use cached credentials. Fall back to an empty
         * password if this failed. */
        if(!password && !ntlm_cred->password)
        {
            lstrcpynA(buffer, "OK", max_len-1);
            if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
            {
                cleanup_helper(helper);
                goto isc_end;
            }
            /* If the helper replied with "PW", using cached credentials failed */
            if(!strncmp(buffer, "PW", 2))
            {
                TRACE("Using cached credentials failed.\n");
                lstrcpynA(buffer, "PW AA==", max_len-1);
            }
            else /* Just do a noop on the next run */
                lstrcpynA(buffer, "OK", max_len-1);
        }
        else
        {
            lstrcpynA(buffer, "PW ", max_len-1);
            if((ret = encodeBase64(password ? (unsigned char *)password : (unsigned char *)ntlm_cred->password,
                        password ? pwlen : ntlm_cred->pwlen, buffer+3,
                        max_len-3, &buffer_len)) != SEC_E_OK)
            {
                cleanup_helper(helper);
                goto isc_end;
            }

        }

        TRACE("Sending to helper: %s\n", debugstr_a(buffer));
        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
        {
            cleanup_helper(helper);
            goto isc_end;
        }

        TRACE("Helper returned %s\n", debugstr_a(buffer));

        if(lstrlenA(want_flags) > 2)
        {
            TRACE("Want flags are %s\n", debugstr_a(want_flags));
            lstrcpynA(buffer, want_flags, max_len-1);
            if((ret = run_helper(helper, buffer, max_len, &buffer_len)) 
                    != SEC_E_OK)
                goto isc_end;
            if(!strncmp(buffer, "BH", 2))
                ERR("Helper doesn't understand new command set. Expect more things to fail.\n");
        }

        lstrcpynA(buffer, "YR", max_len-1);

        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
        {
            cleanup_helper(helper);
            goto isc_end;
        }

        TRACE("%s\n", buffer);

        if(strncmp(buffer, "YR ", 3) != 0)
        {
            /* Something borked */
            TRACE("Helper returned %c%c\n", buffer[0], buffer[1]);
            ret = SEC_E_INTERNAL_ERROR;
            cleanup_helper(helper);
            goto isc_end;
        }
        if((ret = decodeBase64(buffer+3, buffer_len-3, bin,
                        max_len-1, &bin_len)) != SEC_E_OK)
        {
            cleanup_helper(helper);
            goto isc_end;
        }

        /* put the decoded client blob into the out buffer */

        phNewContext->dwUpper = ctxt_attr;
        phNewContext->dwLower = (ULONG_PTR)helper;

        ret = SEC_I_CONTINUE_NEEDED;
    }
    else
    {
        int input_token_idx;

        /* handle second call here */
        /* encode server data to base64 */
        if (!pInput || ((input_token_idx = ntlm_GetTokenBufferIndex(pInput)) == -1))
        {
            ret = SEC_E_INVALID_TOKEN;
            goto isc_end;
        }

        if(!phContext)
        {
            ret = SEC_E_INVALID_HANDLE;
            goto isc_end;
        }

        /* As the server side of sspi never calls this, make sure that
         * the handler is a client handler.
         */
        helper = (PNegoHelper)phContext->dwLower;
        if(helper->mode != NTLM_CLIENT)
        {
            TRACE("Helper mode = %d\n", helper->mode);
            ret = SEC_E_INVALID_HANDLE;
            goto isc_end;
        }

        if (!pInput->pBuffers[input_token_idx].pvBuffer)
        {
            ret = SEC_E_INTERNAL_ERROR;
            goto isc_end;
        }

        if(pInput->pBuffers[input_token_idx].cbBuffer > max_len)
        {
            TRACE("pInput->pBuffers[%d].cbBuffer is: %d\n",
                    input_token_idx,
                    pInput->pBuffers[input_token_idx].cbBuffer);
            ret = SEC_E_INVALID_TOKEN;
            goto isc_end;
        }
        else
            bin_len = pInput->pBuffers[input_token_idx].cbBuffer;

        memcpy(bin, pInput->pBuffers[input_token_idx].pvBuffer, bin_len);

        lstrcpynA(buffer, "TT ", max_len-1);

        if((ret = encodeBase64(bin, bin_len, buffer+3,
                        max_len-3, &buffer_len)) != SEC_E_OK)
            goto isc_end;

        TRACE("Server sent: %s\n", debugstr_a(buffer));

        /* send TT base64 blob to ntlm_auth */
        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
            goto isc_end;

        TRACE("Helper replied: %s\n", debugstr_a(buffer));

        if( (strncmp(buffer, "KK ", 3) != 0) &&
                (strncmp(buffer, "AF ", 3) !=0))
        {
            TRACE("Helper returned %c%c\n", buffer[0], buffer[1]);
            ret = SEC_E_INVALID_TOKEN;
            goto isc_end;
        }

        /* decode the blob and send it to server */
        if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len,
                        &bin_len)) != SEC_E_OK)
        {
            goto isc_end;
        }

        phNewContext->dwUpper = ctxt_attr;
        phNewContext->dwLower = (ULONG_PTR)helper;

        ret = SEC_E_OK;
    }

    /* put the decoded client blob into the out buffer */

    if (!pOutput || ((token_idx = ntlm_GetTokenBufferIndex(pOutput)) == -1))
    {
        TRACE("no SECBUFFER_TOKEN buffer could be found\n");
        ret = SEC_E_BUFFER_TOO_SMALL;
        if ((phContext == NULL) && (pInput == NULL))
        {
            HeapFree(GetProcessHeap(), 0, helper->session_key);
            cleanup_helper(helper);
            phNewContext->dwUpper = 0;
            phNewContext->dwLower = 0;
        }
        goto isc_end;
    }

    if (fContextReq & ISC_REQ_ALLOCATE_MEMORY)
    {
        pOutput->pBuffers[token_idx].pvBuffer = HeapAlloc(GetProcessHeap(), 0, bin_len);
        pOutput->pBuffers[token_idx].cbBuffer = bin_len;
    }
    else if (pOutput->pBuffers[token_idx].cbBuffer < bin_len)
    {
        TRACE("out buffer is NULL or has not enough space\n");
        ret = SEC_E_BUFFER_TOO_SMALL;
        if ((phContext == NULL) && (pInput == NULL))
        {
            HeapFree(GetProcessHeap(), 0, helper->session_key);
            cleanup_helper(helper);
            phNewContext->dwUpper = 0;
            phNewContext->dwLower = 0;
        }
        goto isc_end;
    }

    if (!pOutput->pBuffers[token_idx].pvBuffer)
    {
        TRACE("out buffer is NULL\n");
        ret = SEC_E_INTERNAL_ERROR;
        if ((phContext == NULL) && (pInput == NULL))
        {
            HeapFree(GetProcessHeap(), 0, helper->session_key);
            cleanup_helper(helper);
            phNewContext->dwUpper = 0;
            phNewContext->dwLower = 0;
        }
        goto isc_end;
    }

    pOutput->pBuffers[token_idx].cbBuffer = bin_len;
    memcpy(pOutput->pBuffers[token_idx].pvBuffer, bin, bin_len);

    if(ret == SEC_E_OK)
    {
        TRACE("Getting negotiated flags\n");
        lstrcpynA(buffer, "GF", max_len - 1);
        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
            goto isc_end;

        if(buffer_len < 3)
        {
            TRACE("No flags negotiated.\n");
            helper->neg_flags = 0l;
        }
        else
        {
            TRACE("Negotiated %s\n", debugstr_a(buffer));
            sscanf(buffer + 3, "%lx", &(helper->neg_flags));
            TRACE("Stored 0x%08lx as flags\n", helper->neg_flags);
        }

        TRACE("Getting session key\n");
        lstrcpynA(buffer, "GK", max_len - 1);
        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
            goto isc_end;

        if(strncmp(buffer, "BH", 2) == 0)
            TRACE("No key negotiated.\n");
        else if(strncmp(buffer, "GK ", 3) == 0)
        {
            if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len, 
                            &bin_len)) != SEC_E_OK)
            {
                TRACE("Failed to decode session key\n");
            }
            TRACE("Session key is %s\n", debugstr_a(buffer+3));
            HeapFree(GetProcessHeap(), 0, helper->session_key);
            helper->session_key = HeapAlloc(GetProcessHeap(), 0, bin_len);
            if(!helper->session_key)
            {
                TRACE("Failed to allocate memory for session key\n");
                ret = SEC_E_INTERNAL_ERROR;
                goto isc_end;
            }
            memcpy(helper->session_key, bin, bin_len);
        }

        helper->crypt.ntlm.a4i = SECUR32_arc4Alloc();
        SECUR32_arc4Init(helper->crypt.ntlm.a4i, helper->session_key, 16);
        helper->crypt.ntlm.seq_num = 0l;
        SECUR32_CreateNTLMv2SubKeys(helper);
        helper->crypt.ntlm2.send_a4i = SECUR32_arc4Alloc();
        helper->crypt.ntlm2.recv_a4i = SECUR32_arc4Alloc();
        SECUR32_arc4Init(helper->crypt.ntlm2.send_a4i,
                         helper->crypt.ntlm2.send_seal_key, 16);
        SECUR32_arc4Init(helper->crypt.ntlm2.recv_a4i,
                         helper->crypt.ntlm2.recv_seal_key, 16);
        helper->crypt.ntlm2.send_seq_no = 0l;
        helper->crypt.ntlm2.recv_seq_no = 0l;
    }

isc_end:
    HeapFree(GetProcessHeap(), 0, username);
    HeapFree(GetProcessHeap(), 0, domain);
    HeapFree(GetProcessHeap(), 0, password);
    HeapFree(GetProcessHeap(), 0, want_flags);
    HeapFree(GetProcessHeap(), 0, buffer);
    HeapFree(GetProcessHeap(), 0, bin);
    return ret;
}

/***********************************************************************
 *              InitializeSecurityContextA
 */
static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(
 PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName,
 ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
 PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext, 
 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;
    SEC_WCHAR *target = NULL;

    TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
     debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
     Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);

    if(pszTargetName != NULL)
    {
        int target_size = MultiByteToWideChar(CP_ACP, 0, pszTargetName,
            strlen(pszTargetName)+1, NULL, 0);
        target = HeapAlloc(GetProcessHeap(), 0, target_size *
                sizeof(SEC_WCHAR));
        MultiByteToWideChar(CP_ACP, 0, pszTargetName, strlen(pszTargetName)+1,
            target, target_size);
    }

    ret = ntlm_InitializeSecurityContextW(phCredential, phContext, target,
            fContextReq, Reserved1, TargetDataRep, pInput, Reserved2,
            phNewContext, pOutput, pfContextAttr, ptsExpiry);

    HeapFree(GetProcessHeap(), 0, target);
    return ret;
}

/***********************************************************************
 *              AcceptSecurityContext
 */
static SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(
 PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
 ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, 
 PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
{
    SECURITY_STATUS ret;
    char *buffer, *want_flags = NULL;
    PBYTE bin;
    int buffer_len, bin_len, max_len = NTLM_MAX_BUF;
    ULONG ctxt_attr = 0;
    PNegoHelper helper;
    PNtlmCredentials ntlm_cred;

    TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput,
     fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
     ptsExpiry);

    buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(char) * NTLM_MAX_BUF);
    bin    = HeapAlloc(GetProcessHeap(),0, sizeof(BYTE) * NTLM_MAX_BUF);

    if(TargetDataRep == SECURITY_NETWORK_DREP){
        TRACE("Using SECURITY_NETWORK_DREP\n");
    }

    if(phContext == NULL)
    {
        static CHAR server_helper_protocol[] = "--helper-protocol=squid-2.5-ntlmssp";
        SEC_CHAR *server_argv[] = { ntlm_auth,
            server_helper_protocol,
            NULL };

        if (!phCredential)
        {
            ret = SEC_E_INVALID_HANDLE;
            goto asc_end;
        }

        ntlm_cred = (PNtlmCredentials)phCredential->dwLower;

        if(ntlm_cred->mode != NTLM_SERVER)
        {
            ret = SEC_E_INVALID_HANDLE;
            goto asc_end;
        }

        /* This is the first call to AcceptSecurityHandle */
        if(pInput == NULL)
        {
            ret = SEC_E_INCOMPLETE_MESSAGE;
            goto asc_end;
        }

        if(pInput->cBuffers < 1)
        {
            ret = SEC_E_INCOMPLETE_MESSAGE;
            goto asc_end;
        }

        if(pInput->pBuffers[0].cbBuffer > max_len)
        {
            ret = SEC_E_INVALID_TOKEN;
            goto asc_end;
        }
        else
            bin_len = pInput->pBuffers[0].cbBuffer;

        if( (ret = fork_helper(&helper, ntlm_auth, server_argv)) !=
            SEC_E_OK)
        {
            ret = SEC_E_INTERNAL_ERROR;
            goto asc_end;
        }
        helper->mode = NTLM_SERVER;

        /* Handle all the flags */
        want_flags = HeapAlloc(GetProcessHeap(), 0, 73);
        if(want_flags == NULL)
        {
            TRACE("Failed to allocate memory for the want_flags!\n");
            ret = SEC_E_INSUFFICIENT_MEMORY;
            cleanup_helper(helper);
            goto asc_end;
        }
        lstrcpyA(want_flags, "SF");
        if(fContextReq & ASC_REQ_ALLOCATE_MEMORY)
        {
            FIXME("ASC_REQ_ALLOCATE_MEMORY stub\n");
        }
        if(fContextReq & ASC_REQ_CONFIDENTIALITY)
        {
            lstrcatA(want_flags, " NTLMSSP_FEATURE_SEAL");
        }
        if(fContextReq & ASC_REQ_CONNECTION)
        {
            /* This is default, so we'll enable it */
            lstrcatA(want_flags, " NTLMSSP_FEATURE_SESSION_KEY");
            ctxt_attr |= ASC_RET_CONNECTION;
        }
        if(fContextReq & ASC_REQ_EXTENDED_ERROR)
        {
            FIXME("ASC_REQ_EXTENDED_ERROR stub\n");
        }
        if(fContextReq & ASC_REQ_INTEGRITY)
        {
            lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
        }
        if(fContextReq & ASC_REQ_MUTUAL_AUTH)
        {
            FIXME("ASC_REQ_MUTUAL_AUTH stub\n");
        }
        if(fContextReq & ASC_REQ_REPLAY_DETECT)
        {
            FIXME("ASC_REQ_REPLAY_DETECT stub\n");
        }
        if(fContextReq & ISC_REQ_SEQUENCE_DETECT)
        {
            FIXME("ASC_REQ_SEQUENCE_DETECT stub\n");
        }
        if(fContextReq & ISC_REQ_STREAM)
        {
            FIXME("ASC_REQ_STREAM stub\n");
        }
        /* Done with the flags */

        if(lstrlenA(want_flags) > 3)
        {
            TRACE("Server set want_flags: %s\n", debugstr_a(want_flags));
            lstrcpynA(buffer, want_flags, max_len - 1);
            if((ret = run_helper(helper, buffer, max_len, &buffer_len)) !=
                    SEC_E_OK)
            {
                cleanup_helper(helper);
                goto asc_end;
            }
            if(!strncmp(buffer, "BH", 2))
                TRACE("Helper doesn't understand new command set\n");
        }

        /* This is the YR request from the client, encode to base64 */

        memcpy(bin, pInput->pBuffers[0].pvBuffer, bin_len);

        lstrcpynA(buffer, "YR ", max_len-1);

        if((ret = encodeBase64(bin, bin_len, buffer+3, max_len-3,
                    &buffer_len)) != SEC_E_OK)
        {
            cleanup_helper(helper);
            goto asc_end;
        }

        TRACE("Client sent: %s\n", debugstr_a(buffer));

        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) !=
                    SEC_E_OK)
        {
            cleanup_helper(helper);
            goto asc_end;
        }

        TRACE("Reply from ntlm_auth: %s\n", debugstr_a(buffer));
        /* The expected answer is TT <base64 blob> */

        if(strncmp(buffer, "TT ", 3) != 0)
        {
            ret = SEC_E_INTERNAL_ERROR;
            cleanup_helper(helper);
            goto asc_end;
        }

        if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len,
                        &bin_len)) != SEC_E_OK)
        {
            cleanup_helper(helper);
            goto asc_end;
        }

        /* send this to the client */
        if(pOutput == NULL)
        {
            ret = SEC_E_INSUFFICIENT_MEMORY;
            cleanup_helper(helper);
            goto asc_end;
        }

        if(pOutput->cBuffers < 1)
        {
            ret = SEC_E_INSUFFICIENT_MEMORY;
            cleanup_helper(helper);
            goto asc_end;
        }

        pOutput->pBuffers[0].cbBuffer = bin_len;
        pOutput->pBuffers[0].BufferType = SECBUFFER_DATA;
        memcpy(pOutput->pBuffers[0].pvBuffer, bin, bin_len);
        ret = SEC_I_CONTINUE_NEEDED;

    }
    else
    {
        /* we expect a KK request from client */
        if(pInput == NULL)
        {
            ret = SEC_E_INCOMPLETE_MESSAGE;
            goto asc_end;
        }

        if(pInput->cBuffers < 1)
        {
            ret = SEC_E_INCOMPLETE_MESSAGE;
            goto asc_end;
        }

        if(!phContext)
        {
            ret = SEC_E_INVALID_HANDLE;
            goto asc_end;
        }

        helper = (PNegoHelper)phContext->dwLower;

        if(helper->mode != NTLM_SERVER)
        {
            ret = SEC_E_INVALID_HANDLE;
            goto asc_end;
        }

        if(pInput->pBuffers[0].cbBuffer > max_len)
        {
            ret = SEC_E_INVALID_TOKEN;
            goto asc_end;
        }
        else
            bin_len = pInput->pBuffers[0].cbBuffer;

        memcpy(bin, pInput->pBuffers[0].pvBuffer, bin_len);

        lstrcpynA(buffer, "KK ", max_len-1);

        if((ret = encodeBase64(bin, bin_len, buffer+3, max_len-3,
                    &buffer_len)) != SEC_E_OK)
        {
            goto asc_end;
        }

        TRACE("Client sent: %s\n", debugstr_a(buffer));

        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) !=
                    SEC_E_OK)
        {
            goto asc_end;
        }

        TRACE("Reply from ntlm_auth: %s\n", debugstr_a(buffer));

        /* At this point, we get a NA if the user didn't authenticate, but a BH
         * if ntlm_auth could not connect to winbindd. Apart from running Wine
         * as root, there is no way to fix this for now, so just handle this as
         * a failed login. */
        if(strncmp(buffer, "AF ", 3) != 0)
        {
            if(strncmp(buffer, "NA ", 3) == 0)
            {
                ret = SEC_E_LOGON_DENIED;
                goto asc_end;
            }
            else
            {
                size_t ntlm_pipe_err_len = strlen("BH NT_STATUS_ACCESS_DENIED");

                if( (buffer_len >= ntlm_pipe_err_len) &&
                    (strncmp(buffer, "BH NT_STATUS_ACCESS_DENIED",
                             ntlm_pipe_err_len) == 0))
                {
                    TRACE("Connection to winbindd failed\n");
                    ret = SEC_E_LOGON_DENIED;
                }
                else
                    ret = SEC_E_INTERNAL_ERROR;

                goto asc_end;
            }
        }
        pOutput->pBuffers[0].cbBuffer = 0;
        ret = SEC_E_OK;

        TRACE("Getting negotiated flags\n");
        lstrcpynA(buffer, "GF", max_len - 1);
        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
            goto asc_end;

        if(buffer_len < 3)
        {
            TRACE("No flags negotiated, or helper does not support GF command\n");
        }
        else
        {
            TRACE("Negotiated %s\n", debugstr_a(buffer));
            sscanf(buffer + 3, "%lx", &(helper->neg_flags));
            TRACE("Stored 0x%08lx as flags\n", helper->neg_flags);
        }

        TRACE("Getting session key\n");
        lstrcpynA(buffer, "GK", max_len - 1);
        if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
            goto asc_end;

        if(buffer_len < 3)
            TRACE("Helper does not support GK command\n");
        else
        {
            if(strncmp(buffer, "BH ", 3) == 0)
            {
                TRACE("Helper sent %s\n", debugstr_a(buffer+3));
                helper->session_key = HeapAlloc(GetProcessHeap(), 0, 16);
                /*FIXME: Generate the dummy session key = MD4(MD4(password))*/
                memset(helper->session_key, 0 , 16);
            }
            else if(strncmp(buffer, "GK ", 3) == 0)
            {
                if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len, 
                                &bin_len)) != SEC_E_OK)
                {
                    TRACE("Failed to decode session key\n");
                }
                TRACE("Session key is %s\n", debugstr_a(buffer+3));
                helper->session_key = HeapAlloc(GetProcessHeap(), 0, 16);
                if(!helper->session_key)
                {
                    TRACE("Failed to allocate memory for session key\n");
                    ret = SEC_E_INTERNAL_ERROR;
                    goto asc_end;
                }
                memcpy(helper->session_key, bin, 16);
            }
        }
        helper->crypt.ntlm.a4i = SECUR32_arc4Alloc();
        SECUR32_arc4Init(helper->crypt.ntlm.a4i, helper->session_key, 16);
        helper->crypt.ntlm.seq_num = 0l;
    }

    phNewContext->dwUpper = ctxt_attr;
    phNewContext->dwLower = (ULONG_PTR)helper;

asc_end:
    HeapFree(GetProcessHeap(), 0, want_flags);
    HeapFree(GetProcessHeap(), 0, buffer);
    HeapFree(GetProcessHeap(), 0, bin);
    return ret;
}

/***********************************************************************
 *              CompleteAuthToken
 */
static SECURITY_STATUS SEC_ENTRY ntlm_CompleteAuthToken(PCtxtHandle phContext,
 PSecBufferDesc pToken)
{
    /* We never need to call CompleteAuthToken anyway */
    TRACE("%p %p\n", phContext, pToken);
    if (!phContext)
        return SEC_E_INVALID_HANDLE;
    
    return SEC_E_OK;
}

/***********************************************************************
 *              DeleteSecurityContext
 */
static SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext)
{
    PNegoHelper helper;

    TRACE("%p\n", phContext);
    if (!phContext)
        return SEC_E_INVALID_HANDLE;

    helper = (PNegoHelper)phContext->dwLower;

    phContext->dwUpper = 0;
    phContext->dwLower = 0;

    SECUR32_arc4Cleanup(helper->crypt.ntlm.a4i);
    HeapFree(GetProcessHeap(), 0, helper->session_key);
    SECUR32_arc4Cleanup(helper->crypt.ntlm2.send_a4i);
    SECUR32_arc4Cleanup(helper->crypt.ntlm2.recv_a4i);
    HeapFree(GetProcessHeap(), 0, helper->crypt.ntlm2.send_sign_key);
    HeapFree(GetProcessHeap(), 0, helper->crypt.ntlm2.send_seal_key);
    HeapFree(GetProcessHeap(), 0, helper->crypt.ntlm2.recv_sign_key);
    HeapFree(GetProcessHeap(), 0, helper->crypt.ntlm2.recv_seal_key);

    cleanup_helper(helper);

    return SEC_E_OK;
}

/***********************************************************************
 *              QueryContextAttributesW
 */
static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext,
 ULONG ulAttribute, void *pBuffer)
{
    TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
    if (!phContext)
        return SEC_E_INVALID_HANDLE;

    switch(ulAttribute)
    {
#define _x(x) case (x) : FIXME(#x" stub\n"); break
        _x(SECPKG_ATTR_ACCESS_TOKEN);
        _x(SECPKG_ATTR_AUTHORITY);
        _x(SECPKG_ATTR_DCE_INFO);
        case SECPKG_ATTR_FLAGS:
        {
            PSecPkgContext_Flags spcf = (PSecPkgContext_Flags)pBuffer;
            PNegoHelper helper = (PNegoHelper)phContext->dwLower;

            spcf->Flags = 0;
            if(helper->neg_flags & NTLMSSP_NEGOTIATE_SIGN)
                spcf->Flags |= ISC_RET_INTEGRITY;
            if(helper->neg_flags & NTLMSSP_NEGOTIATE_SEAL)
                spcf->Flags |= ISC_RET_CONFIDENTIALITY;
            return SEC_E_OK;
        }
        _x(SECPKG_ATTR_KEY_INFO);
        _x(SECPKG_ATTR_LIFESPAN);
        _x(SECPKG_ATTR_NAMES);
        _x(SECPKG_ATTR_NATIVE_NAMES);
        _x(SECPKG_ATTR_NEGOTIATION_INFO);
        _x(SECPKG_ATTR_PACKAGE_INFO);
        _x(SECPKG_ATTR_PASSWORD_EXPIRY);
        _x(SECPKG_ATTR_SESSION_KEY);
        case SECPKG_ATTR_SIZES:
        {
            PSecPkgContext_Sizes spcs = (PSecPkgContext_Sizes)pBuffer;
            spcs->cbMaxToken = NTLM_MAX_BUF;
            spcs->cbMaxSignature = 16;
            spcs->cbBlockSize = 0;
            spcs->cbSecurityTrailer = 16;
            return SEC_E_OK;
        }
        _x(SECPKG_ATTR_STREAM_SIZES);
        _x(SECPKG_ATTR_TARGET_INFORMATION);
#undef _x
        default:
            TRACE("Unknown value %d passed for ulAttribute\n", ulAttribute);
    }

    return SEC_E_UNSUPPORTED_FUNCTION;
}

/***********************************************************************
 *              QueryContextAttributesA
 */
static SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext,
 ULONG ulAttribute, void *pBuffer)
{
    return ntlm_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
}

/***********************************************************************
 *              ImpersonateSecurityContext
 */
static SECURITY_STATUS SEC_ENTRY ntlm_ImpersonateSecurityContext(PCtxtHandle phContext)
{
    SECURITY_STATUS ret;

    TRACE("%p\n", phContext);
    if (phContext)
    {
        ret = SEC_E_UNSUPPORTED_FUNCTION;
    }
    else
    {
        ret = SEC_E_INVALID_HANDLE;
    }
    return ret;
}

/***********************************************************************
 *              RevertSecurityContext
 */
static SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext(PCtxtHandle phContext)
{
    SECURITY_STATUS ret;

    TRACE("%p\n", phContext);
    if (phContext)
    {
        ret = SEC_E_UNSUPPORTED_FUNCTION;
    }
    else
    {
        ret = SEC_E_INVALID_HANDLE;
    }
    return ret;
}

/***********************************************************************
 *             ntlm_CreateSignature
 * As both MakeSignature and VerifySignature need this, but different keys
 * are needed for NTLMv2, the logic goes into a helper function.
 * To ensure maximal reusability, we can specify the direction as NTLM_SEND for
 * signing/encrypting and NTLM_RECV for verfying/decrypting. When encrypting,
 * the signature is encrypted after the message was encrypted, so
 * CreateSignature shouldn't do it. In this case, encrypt_sig can be set to
 * false.
 */
static SECURITY_STATUS ntlm_CreateSignature(PNegoHelper helper, PSecBufferDesc pMessage,
        int token_idx, SignDirection direction, BOOL encrypt_sig)
{
    ULONG sign_version = 1;
    UINT i;
    PBYTE sig;
    TRACE("%p, %p, %d, %d, %d\n", helper, pMessage, token_idx, direction,
            encrypt_sig);

    sig = pMessage->pBuffers[token_idx].pvBuffer;

    if(helper->neg_flags & NTLMSSP_NEGOTIATE_NTLM2 &&
            helper->neg_flags & NTLMSSP_NEGOTIATE_SIGN)
    {
        BYTE digest[16];
        BYTE seq_no[4];
        HMAC_MD5_CTX hmac_md5_ctx;

        TRACE("Signing NTLM2 style\n");

        if(direction == NTLM_SEND)
        {
            seq_no[0] = (helper->crypt.ntlm2.send_seq_no >>  0) & 0xff;
            seq_no[1] = (helper->crypt.ntlm2.send_seq_no >>  8) & 0xff;
            seq_no[2] = (helper->crypt.ntlm2.send_seq_no >> 16) & 0xff;
            seq_no[3] = (helper->crypt.ntlm2.send_seq_no >> 24) & 0xff;

            ++(helper->crypt.ntlm2.send_seq_no);

            HMACMD5Init(&hmac_md5_ctx, helper->crypt.ntlm2.send_sign_key, 16);
        }
        else
        {
            seq_no[0] = (helper->crypt.ntlm2.recv_seq_no >>  0) & 0xff;
            seq_no[1] = (helper->crypt.ntlm2.recv_seq_no >>  8) & 0xff;
            seq_no[2] = (helper->crypt.ntlm2.recv_seq_no >> 16) & 0xff;
            seq_no[3] = (helper->crypt.ntlm2.recv_seq_no >> 24) & 0xff;

            ++(helper->crypt.ntlm2.recv_seq_no);

            HMACMD5Init(&hmac_md5_ctx, helper->crypt.ntlm2.recv_sign_key, 16);
        }

        HMACMD5Update(&hmac_md5_ctx, seq_no, 4);
        for( i = 0; i < pMessage->cBuffers; ++i )
        {
            if(pMessage->pBuffers[i].BufferType & SECBUFFER_DATA)
                HMACMD5Update(&hmac_md5_ctx, pMessage->pBuffers[i].pvBuffer,
                        pMessage->pBuffers[i].cbBuffer);
        }

        HMACMD5Final(&hmac_md5_ctx, digest);

        if(encrypt_sig && helper->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCHANGE)
        {
            if(direction == NTLM_SEND)
                SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i, digest, 8);
            else
                SECUR32_arc4Process(helper->crypt.ntlm2.recv_a4i, digest, 8);
        }

        /* The NTLM2 signature is the sign version */
        sig[ 0] = (sign_version >>  0) & 0xff;
        sig[ 1] = (sign_version >>  8) & 0xff;
        sig[ 2] = (sign_version >> 16) & 0xff;
        sig[ 3] = (sign_version >> 24) & 0xff;
        /* The first 8 bytes of the digest */
        memcpy(sig+4, digest, 8);
        /* And the sequence number */
        memcpy(sig+12, seq_no, 4);

        pMessage->pBuffers[token_idx].cbBuffer = 16;

        return SEC_E_OK;
    }
    if(helper->neg_flags & NTLMSSP_NEGOTIATE_SIGN)
    {
        ULONG crc = 0U;
        TRACE("Signing NTLM1 style\n");

        for(i=0; i < pMessage->cBuffers; ++i)
        {
            if(pMessage->pBuffers[i].BufferType & SECBUFFER_DATA)
            {
                crc = ComputeCrc32(pMessage->pBuffers[i].pvBuffer,
                    pMessage->pBuffers[i].cbBuffer, crc);
            }
        }

        sig[ 0] = (sign_version >>  0) & 0xff;
        sig[ 1] = (sign_version >>  8) & 0xff;
        sig[ 2] = (sign_version >> 16) & 0xff;
        sig[ 3] = (sign_version >> 24) & 0xff;
        memset(sig+4, 0, 4);
        sig[ 8] = (crc >>  0) & 0xff;
        sig[ 9] = (crc >>  8) & 0xff;
        sig[10] = (crc >> 16) & 0xff;
        sig[11] = (crc >> 24) & 0xff;
        sig[12] = (helper->crypt.ntlm.seq_num >>  0) & 0xff;
        sig[13] = (helper->crypt.ntlm.seq_num >>  8) & 0xff;
        sig[14] = (helper->crypt.ntlm.seq_num >> 16) & 0xff;
        sig[15] = (helper->crypt.ntlm.seq_num >> 24) & 0xff;

        ++(helper->crypt.ntlm.seq_num);

        if(encrypt_sig)
            SECUR32_arc4Process(helper->crypt.ntlm.a4i, sig+4, 12);
        return SEC_E_OK;
    }

    if(helper->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN || helper->neg_flags == 0)
    {
        TRACE("Creating a dummy signature.\n");
        /* A dummy signature is 0x01 followed by 15 bytes of 0x00 */
        memset(pMessage->pBuffers[token_idx].pvBuffer, 0, 16);
        memset(pMessage->pBuffers[token_idx].pvBuffer, 0x01, 1);
        pMessage->pBuffers[token_idx].cbBuffer = 16;
        return SEC_E_OK;
    }

    return SEC_E_UNSUPPORTED_FUNCTION;
}

/***********************************************************************
 *              MakeSignature
 */
static SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
 PSecBufferDesc pMessage, ULONG MessageSeqNo)
{
    PNegoHelper helper;
    int token_idx;

    TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
    if (!phContext)
        return SEC_E_INVALID_HANDLE;

    if(fQOP)
        FIXME("Ignoring fQOP 0x%08x\n", fQOP);

    if(MessageSeqNo)
        FIXME("Ignoring MessageSeqNo\n");

    if(!pMessage || !pMessage->pBuffers || pMessage->cBuffers < 2)
        return SEC_E_INVALID_TOKEN;

    /* If we didn't find a SECBUFFER_TOKEN type buffer */
    if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1)
        return SEC_E_INVALID_TOKEN;

    if(pMessage->pBuffers[token_idx].cbBuffer < 16)
        return SEC_E_BUFFER_TOO_SMALL;

    helper = (PNegoHelper)phContext->dwLower;
    TRACE("Negotiated flags are: 0x%08lx\n", helper->neg_flags);

    return ntlm_CreateSignature(helper, pMessage, token_idx, NTLM_SEND, TRUE);
}

/***********************************************************************
 *              VerifySignature
 */
static SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext,
 PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
{
    PNegoHelper helper;
    ULONG fQOP = 0;
    UINT i;
    int token_idx;
    SECURITY_STATUS ret;
    SecBufferDesc local_desc;
    PSecBuffer     local_buff;
    BYTE          local_sig[16];

    TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
    if(!phContext)
        return SEC_E_INVALID_HANDLE;

    if(!pMessage || !pMessage->pBuffers || pMessage->cBuffers < 2)
        return SEC_E_INVALID_TOKEN;

    if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1)
        return SEC_E_INVALID_TOKEN;

    if(pMessage->pBuffers[token_idx].cbBuffer < 16)
        return SEC_E_BUFFER_TOO_SMALL;

    if(MessageSeqNo)
        FIXME("Ignoring MessageSeqNo\n");

    helper = (PNegoHelper)phContext->dwLower;
    TRACE("Negotiated flags: 0x%08lx\n", helper->neg_flags);

    local_buff = HeapAlloc(GetProcessHeap(), 0, pMessage->cBuffers * sizeof(SecBuffer));

    local_desc.ulVersion = SECBUFFER_VERSION;
    local_desc.cBuffers = pMessage->cBuffers;
    local_desc.pBuffers = local_buff;

    for(i=0; i < pMessage->cBuffers; ++i)
    {
        if(pMessage->pBuffers[i].BufferType == SECBUFFER_TOKEN)
        {
            local_buff[i].BufferType = SECBUFFER_TOKEN;
            local_buff[i].cbBuffer = 16;
            local_buff[i].pvBuffer = local_sig;
        }
        else
        {
            local_buff[i].BufferType = pMessage->pBuffers[i].BufferType;
            local_buff[i].cbBuffer = pMessage->pBuffers[i].cbBuffer;
            local_buff[i].pvBuffer = pMessage->pBuffers[i].pvBuffer;
        }
    }

    if((ret = ntlm_CreateSignature(helper, &local_desc, token_idx, NTLM_RECV, TRUE)) != SEC_E_OK)
        return ret;

    if(memcmp(((PBYTE)local_buff[token_idx].pvBuffer) + 8,
                ((PBYTE)pMessage->pBuffers[token_idx].pvBuffer) + 8, 8))
        ret = SEC_E_MESSAGE_ALTERED;
    else
        ret = SEC_E_OK;

    HeapFree(GetProcessHeap(), 0, local_buff);
    pfQOP = &fQOP;

    return ret;

}

/***********************************************************************
 *             FreeCredentialsHandle
 */
static SECURITY_STATUS SEC_ENTRY ntlm_FreeCredentialsHandle(
        PCredHandle phCredential)
{
    SECURITY_STATUS ret;

    if(phCredential){
        PNtlmCredentials ntlm_cred = (PNtlmCredentials) phCredential->dwLower;
        phCredential->dwUpper = 0;
        phCredential->dwLower = 0;
        if (ntlm_cred->password)
            memset(ntlm_cred->password, 0, ntlm_cred->pwlen);
        HeapFree(GetProcessHeap(), 0, ntlm_cred->password);
        HeapFree(GetProcessHeap(), 0, ntlm_cred->username_arg);
        HeapFree(GetProcessHeap(), 0, ntlm_cred->domain_arg);
        HeapFree(GetProcessHeap(), 0, ntlm_cred);
        ret = SEC_E_OK;
    }
    else
        ret = SEC_E_OK;
    
    return ret;
}

/***********************************************************************
 *             EncryptMessage
 */
static SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext,
        ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
{
    PNegoHelper helper;
    int token_idx, data_idx;

    TRACE("(%p %d %p %d)\n", phContext, fQOP, pMessage, MessageSeqNo);

    if(!phContext)
        return SEC_E_INVALID_HANDLE;

    if(fQOP)
        FIXME("Ignoring fQOP\n");

    if(MessageSeqNo)
        FIXME("Ignoring MessageSeqNo\n");

    if(!pMessage || !pMessage->pBuffers || pMessage->cBuffers < 2)
        return SEC_E_INVALID_TOKEN;

    if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1)
        return SEC_E_INVALID_TOKEN;

    if((data_idx = ntlm_GetDataBufferIndex(pMessage)) ==-1 )
        return SEC_E_INVALID_TOKEN;

    if(pMessage->pBuffers[token_idx].cbBuffer < 16)
        return SEC_E_BUFFER_TOO_SMALL;

    helper = (PNegoHelper) phContext->dwLower;

    if(helper->neg_flags & NTLMSSP_NEGOTIATE_NTLM2 && 
            helper->neg_flags & NTLMSSP_NEGOTIATE_SEAL)
    { 
        ntlm_CreateSignature(helper, pMessage, token_idx, NTLM_SEND, FALSE);
        SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i,
                pMessage->pBuffers[data_idx].pvBuffer,
                pMessage->pBuffers[data_idx].cbBuffer);

        if(helper->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCHANGE)
            SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i,
                    ((BYTE *)pMessage->pBuffers[token_idx].pvBuffer)+4, 8);


        return SEC_E_OK;
    }
    else
    {
        PBYTE sig;
        ULONG save_flags;

        /* EncryptMessage always produces real signatures, so make sure
         * NTLMSSP_NEGOTIATE_SIGN is set*/
        save_flags = helper->neg_flags;
        helper->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
        ntlm_CreateSignature(helper, pMessage, token_idx, NTLM_SEND, FALSE);
        helper->neg_flags = save_flags;

        sig = pMessage->pBuffers[token_idx].pvBuffer;

        SECUR32_arc4Process(helper->crypt.ntlm.a4i,
                pMessage->pBuffers[data_idx].pvBuffer,
                pMessage->pBuffers[data_idx].cbBuffer);
        SECUR32_arc4Process(helper->crypt.ntlm.a4i, sig+4, 12);

        if(helper->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN || helper->neg_flags == 0)
            memset(sig+4, 0, 4);

    }

    return SEC_E_OK;
}

/***********************************************************************
 *             DecryptMessage
 */
static SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext,
        PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
{
    SECURITY_STATUS ret;
    ULONG ntlmssp_flags_save;
    PNegoHelper helper;
    int token_idx, data_idx;
    TRACE("(%p %p %d %p)\n", phContext, pMessage, MessageSeqNo, pfQOP);

    if(!phContext)
        return SEC_E_INVALID_HANDLE;

    if(MessageSeqNo)
        FIXME("Ignoring MessageSeqNo\n");

    if(!pMessage || !pMessage->pBuffers || pMessage->cBuffers < 2)
        return SEC_E_INVALID_TOKEN;

    if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1)
        return SEC_E_INVALID_TOKEN;

    if((data_idx = ntlm_GetDataBufferIndex(pMessage)) ==-1)
        return SEC_E_INVALID_TOKEN;

    if(pMessage->pBuffers[token_idx].cbBuffer < 16)
        return SEC_E_BUFFER_TOO_SMALL;

    helper = (PNegoHelper) phContext->dwLower;

    if(helper->neg_flags & NTLMSSP_NEGOTIATE_NTLM2 && helper->neg_flags & NTLMSSP_NEGOTIATE_SEAL)
    {
        SECUR32_arc4Process(helper->crypt.ntlm2.recv_a4i,
                pMessage->pBuffers[data_idx].pvBuffer,
                pMessage->pBuffers[data_idx].cbBuffer);
    }
    else
    {
        SECUR32_arc4Process(helper->crypt.ntlm.a4i,
                pMessage->pBuffers[data_idx].pvBuffer,
                pMessage->pBuffers[data_idx].cbBuffer);
    }

    /* Make sure we use a session key for the signature check, EncryptMessage
     * always does that, even in the dummy case */
    ntlmssp_flags_save = helper->neg_flags;

    helper->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
    ret = ntlm_VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);

    helper->neg_flags = ntlmssp_flags_save;

    return ret;
}

static const SecurityFunctionTableA ntlmTableA = {
    1,
    NULL,   /* EnumerateSecurityPackagesA */
    ntlm_QueryCredentialsAttributesA,   /* QueryCredentialsAttributesA */
    ntlm_AcquireCredentialsHandleA,     /* AcquireCredentialsHandleA */
    ntlm_FreeCredentialsHandle,         /* FreeCredentialsHandle */
    NULL,   /* Reserved2 */
    ntlm_InitializeSecurityContextA,    /* InitializeSecurityContextA */
    ntlm_AcceptSecurityContext,         /* AcceptSecurityContext */
    ntlm_CompleteAuthToken,             /* CompleteAuthToken */
    ntlm_DeleteSecurityContext,         /* DeleteSecurityContext */
    NULL,  /* ApplyControlToken */
    ntlm_QueryContextAttributesA,       /* QueryContextAttributesA */
    ntlm_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
    ntlm_RevertSecurityContext,         /* RevertSecurityContext */
    ntlm_MakeSignature,                 /* MakeSignature */
    ntlm_VerifySignature,               /* VerifySignature */
    FreeContextBuffer,                  /* FreeContextBuffer */
    NULL,   /* QuerySecurityPackageInfoA */
    NULL,   /* Reserved3 */
    NULL,   /* Reserved4 */
    NULL,   /* ExportSecurityContext */
    NULL,   /* ImportSecurityContextA */
    NULL,   /* AddCredentialsA */
    NULL,   /* Reserved8 */
    NULL,   /* QuerySecurityContextToken */
    ntlm_EncryptMessage,                /* EncryptMessage */
    ntlm_DecryptMessage,                /* DecryptMessage */
    NULL,   /* SetContextAttributesA */
};

static const SecurityFunctionTableW ntlmTableW = {
    1,
    NULL,   /* EnumerateSecurityPackagesW */
    ntlm_QueryCredentialsAttributesW,   /* QueryCredentialsAttributesW */
    ntlm_AcquireCredentialsHandleW,     /* AcquireCredentialsHandleW */
    ntlm_FreeCredentialsHandle,         /* FreeCredentialsHandle */
    NULL,   /* Reserved2 */
    ntlm_InitializeSecurityContextW,    /* InitializeSecurityContextW */
    ntlm_AcceptSecurityContext,         /* AcceptSecurityContext */
    ntlm_CompleteAuthToken,             /* CompleteAuthToken */
    ntlm_DeleteSecurityContext,         /* DeleteSecurityContext */
    NULL,  /* ApplyControlToken */
    ntlm_QueryContextAttributesW,       /* QueryContextAttributesW */
    ntlm_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
    ntlm_RevertSecurityContext,         /* RevertSecurityContext */
    ntlm_MakeSignature,                 /* MakeSignature */
    ntlm_VerifySignature,               /* VerifySignature */
    FreeContextBuffer,                  /* FreeContextBuffer */
    NULL,   /* QuerySecurityPackageInfoW */
    NULL,   /* Reserved3 */
    NULL,   /* Reserved4 */
    NULL,   /* ExportSecurityContext */
    NULL,   /* ImportSecurityContextW */
    NULL,   /* AddCredentialsW */
    NULL,   /* Reserved8 */
    NULL,   /* QuerySecurityContextToken */
    ntlm_EncryptMessage,                /* EncryptMessage */
    ntlm_DecryptMessage,                /* DecryptMessage */
    NULL,   /* SetContextAttributesW */
};

#define NTLM_COMMENT \
   { 'N', 'T', 'L', 'M', ' ', \
     'S', 'e', 'c', 'u', 'r', 'i', 't', 'y', ' ', \
     'P', 'a', 'c', 'k', 'a', 'g', 'e', 0}

static CHAR ntlm_comment_A[] = NTLM_COMMENT;
static WCHAR ntlm_comment_W[] = NTLM_COMMENT;

#define NTLM_NAME {'N', 'T', 'L', 'M', 0}

static char ntlm_name_A[] = NTLM_NAME;
static WCHAR ntlm_name_W[] = NTLM_NAME;

/* According to Windows, NTLM has the following capabilities.  */
#define CAPS ( \
        SECPKG_FLAG_INTEGRITY | \
        SECPKG_FLAG_PRIVACY | \
        SECPKG_FLAG_TOKEN_ONLY | \
        SECPKG_FLAG_CONNECTION | \
        SECPKG_FLAG_MULTI_REQUIRED | \
        SECPKG_FLAG_IMPERSONATION | \
        SECPKG_FLAG_ACCEPT_WIN32_NAME | \
        SECPKG_FLAG_READONLY_WITH_CHECKSUM)

static const SecPkgInfoW infoW = {
    CAPS,
    1,
    RPC_C_AUTHN_WINNT,
    NTLM_MAX_BUF,
    ntlm_name_W,
    ntlm_comment_W
};

static const SecPkgInfoA infoA = {
    CAPS,
    1,
    RPC_C_AUTHN_WINNT,
    NTLM_MAX_BUF,
    ntlm_name_A,
    ntlm_comment_A
};

#define NEGO_COMMENT { 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', ' ', \
    'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', \
    'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'o', 'r', 0};

static CHAR nego_comment_A[] = NEGO_COMMENT;
static WCHAR nego_comment_W[] = NEGO_COMMENT;

#define NEGO_NAME {'N', 'e', 'g', 'o', 't', 'i', 'a', 't', 'e', 0}

static CHAR nego_name_A[] = NEGO_NAME;
static WCHAR nego_name_W[] = NEGO_NAME;

#define NEGO_CAPS (\
    SECPKG_FLAG_INTEGRITY | \
    SECPKG_FLAG_PRIVACY | \
    SECPKG_FLAG_CONNECTION | \
    SECPKG_FLAG_MULTI_REQUIRED | \
    SECPKG_FLAG_EXTENDED_ERROR | \
    SECPKG_FLAG_IMPERSONATION | \
    SECPKG_FLAG_ACCEPT_WIN32_NAME | \
    SECPKG_FLAG_READONLY_WITH_CHECKSUM )

/* Not used for now, just kept here for completeness sake. We need to use the
 * NTLM_MAX_BUF value. If the hack works, we might want to refactor the code a
 * bit. */
#define NEGO_MAX_TOKEN 12000

static const SecPkgInfoW nego_infoW = {
    NEGO_CAPS,
    1,
    RPC_C_AUTHN_GSS_NEGOTIATE,
    NTLM_MAX_BUF,
    nego_name_W,
    nego_comment_W
};

static const SecPkgInfoA nego_infoA = {
    NEGO_CAPS,
    1,
    RPC_C_AUTHN_GSS_NEGOTIATE,
    NTLM_MAX_BUF,
    nego_name_A,
    nego_comment_A
};

void SECUR32_initNTLMSP(void)
{
    PNegoHelper helper;
    static CHAR version[] = "--version";

    SEC_CHAR *args[] = {
        ntlm_auth,
        version,
        NULL };

    if(fork_helper(&helper, ntlm_auth, args) != SEC_E_OK)
    {
        /* Cheat and allocate a helper anyway, so cleanup later will work. */
        helper = HeapAlloc(GetProcessHeap(),0, sizeof(NegoHelper));
        helper->major = helper->minor = helper->micro = -1;
        helper->pipe_in = helper->pipe_out = -1;
    }
    else
        check_version(helper);

    if( (helper->major >  MIN_NTLM_AUTH_MAJOR_VERSION) ||
        (helper->major == MIN_NTLM_AUTH_MAJOR_VERSION  &&
         helper->minor >  MIN_NTLM_AUTH_MINOR_VERSION) ||
        (helper->major == MIN_NTLM_AUTH_MAJOR_VERSION  &&
         helper->minor == MIN_NTLM_AUTH_MINOR_VERSION  &&
         helper->micro >= MIN_NTLM_AUTH_MICRO_VERSION) )
    {
        SecureProvider *provider = SECUR32_addProvider(&ntlmTableA, &ntlmTableW, NULL);
        SecureProvider *nego_provider = SECUR32_addProvider(&ntlmTableA, &ntlmTableW, NULL);

        SECUR32_addPackages(provider, 1L, &infoA, &infoW);
        /* HACK: Also pretend this is the Negotiate provider */
        SECUR32_addPackages(nego_provider, 1L, &nego_infoA, &nego_infoW);
    }
    else
    {
        ERR("%s was not found or is outdated. "
            "Make sure that ntlm_auth >= %d.%d.%d is in your path.\n",
            ntlm_auth,
	    MIN_NTLM_AUTH_MAJOR_VERSION,
	    MIN_NTLM_AUTH_MINOR_VERSION,
	    MIN_NTLM_AUTH_MICRO_VERSION);
        ERR("Usually, you can find it in the winbind package of your "
            "distribution.\n");

    }
    cleanup_helper(helper);
}
