示例#1
0
DWORD
NtlmCreateChallengeContext(
    IN const NTLM_NEGOTIATE_MESSAGE_V1* pNtlmNegMsg,
    IN NTLM_CRED_HANDLE hCred,
    OUT PNTLM_CONTEXT *ppNtlmContext,
    OUT PSecBuffer pOutput
    )
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PNTLM_CREDENTIALS pCred = (PNTLM_CREDENTIALS)hCred;
    PNTLM_CONTEXT pNtlmContext = NULL;
    DWORD dwMessageSize = 0;
    PNTLM_CHALLENGE_MESSAGE pMessage = NULL;
    PSTR pServerName = NULL;
    PSTR pDomainName = NULL;
    PSTR pDnsServerName = NULL;
    PSTR pDnsDomainName = NULL;
    BOOLEAN bInLock = FALSE;

    *ppNtlmContext = NULL;

    dwError = NtlmCreateContext(hCred, &pNtlmContext);
    BAIL_ON_LSA_ERROR(dwError);

    if (pCred)
    {
        NTLM_LOCK_MUTEX(bInLock, &pCred->Mutex);

        dwError = NtlmGetNameInformation(
            pCred->pszDomainName,
            &pServerName,
            &pDomainName,
            &pDnsServerName,
            &pDnsDomainName);
        BAIL_ON_LSA_ERROR(dwError);

        NTLM_UNLOCK_MUTEX(bInLock, &pCred->Mutex);
    }
    else
    {
        dwError = NtlmGetNameInformation(
            NULL,
            &pServerName,
            &pDomainName,
            &pDnsServerName,
            &pDnsDomainName);
        BAIL_ON_LSA_ERROR(dwError);
    }

    dwError = NtlmGetRandomBuffer(
        pNtlmContext->Challenge,
        NTLM_CHALLENGE_SIZE
        );
    BAIL_ON_LSA_ERROR(dwError);

    dwError = NtlmCreateChallengeMessage(
        pNtlmNegMsg,
        pServerName,
        pDomainName,
        pDnsServerName,
        pDnsDomainName,
        (PBYTE)&gW2KSpoof,
        pNtlmContext->Challenge,
        &dwMessageSize,
        &pMessage
        );

    BAIL_ON_LSA_ERROR(dwError);

    pNtlmContext->NegotiatedFlags = LW_LTOH32(pMessage->NtlmFlags);
    pOutput->cbBuffer = dwMessageSize;
    pOutput->BufferType = SECBUFFER_TOKEN;
    pOutput->pvBuffer = pMessage;
    pNtlmContext->NtlmState = NtlmStateChallenge;

cleanup:
    *ppNtlmContext = pNtlmContext;

    LW_SAFE_FREE_STRING(pServerName);
    LW_SAFE_FREE_STRING(pDomainName);
    LW_SAFE_FREE_STRING(pDnsServerName);
    LW_SAFE_FREE_STRING(pDnsDomainName);

    if (pCred)
    {
        NTLM_UNLOCK_MUTEX(bInLock, &pCred->Mutex);
    }

    return dwError;

error:
    LW_SAFE_FREE_MEMORY(pMessage);

    if (pNtlmContext)
    {
        NtlmReleaseContext(&pNtlmContext);
        *ppNtlmContext = NULL;
    }
    pOutput->cbBuffer = 0;
    pOutput->BufferType = 0;
    pOutput->pvBuffer = NULL;
    goto cleanup;
}
示例#2
0
DWORD
NtlmServerInitializeSecurityContext(
    IN OPTIONAL NTLM_CRED_HANDLE hCredential,
    IN OPTIONAL const NTLM_CONTEXT_HANDLE hContext,
    IN OPTIONAL SEC_CHAR* pszTargetName,
    IN DWORD fContextReq,
    IN DWORD Reserved1,
    IN DWORD TargetDataRep,
    IN OPTIONAL const SecBuffer* pInput,
    IN DWORD Reserved2,
    IN OUT OPTIONAL PNTLM_CONTEXT_HANDLE phNewContext,
    OUT PSecBuffer pOutput,
    OUT PDWORD pfContextAttr,
    OUT OPTIONAL PTimeStamp ptsExpiry
)
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PNTLM_CREDENTIALS pCred = (PNTLM_CREDENTIALS)hCredential;
    PNTLM_CONTEXT pNtlmContext = NULL;
    PSTR pWorkstation = NULL;
    PSTR pDomain = NULL;
    PNTLM_CHALLENGE_MESSAGE pMessage = NULL;
    DWORD dwMessageSize ATTRIBUTE_UNUSED = 0;
    BOOLEAN bInLock = FALSE;

    pOutput->pvBuffer = NULL;

    if (hContext)
    {
        pNtlmContext = hContext;
    }

    if (!pNtlmContext)
    {
        if (pCred)
        {
            NTLM_LOCK_MUTEX(bInLock, &pCred->Mutex);

            dwError = NtlmGetNameInformation(
                          pCred->pszDomainName,
                          &pWorkstation,
                          &pDomain,
                          NULL,
                          NULL);
            BAIL_ON_LSA_ERROR(dwError);

            NTLM_UNLOCK_MUTEX(bInLock, &pCred->Mutex);
        }
        else
        {
            dwError = NtlmGetNameInformation(
                          NULL,
                          &pWorkstation,
                          &pDomain,
                          NULL,
                          NULL);
            BAIL_ON_LSA_ERROR(dwError);
        }

        // If we start with a NULL context, create a negotiate message
        dwError = NtlmCreateNegotiateContext(
                      hCredential,
                      fContextReq,
                      pDomain,
                      pWorkstation,
                      (PBYTE)&gXpSpoof,  //for now add OS ver info... config later
                      &pNtlmContext,
                      pOutput);
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LW_WARNING_CONTINUE_NEEDED;
    }
    else
    {
        if (pInput->BufferType != SECBUFFER_TOKEN ||
                pInput->cbBuffer == 0)
        {
            dwError = LW_ERROR_INVALID_PARAMETER;
            BAIL_ON_LSA_ERROR(dwError);
        }

        pMessage = pInput->pvBuffer;
        dwMessageSize = pInput->cbBuffer;

        dwError = NtlmCreateResponseContext(
                      pMessage,
                      hCredential,
                      pNtlmContext->bDoAnonymous,
                      &pNtlmContext,
                      pOutput);
        BAIL_ON_LSA_ERROR(dwError);
    }

    *phNewContext = pNtlmContext;

    if (pfContextAttr)
    {
        NtlmGetContextInfo(
            pNtlmContext,
            NULL,
            pfContextAttr,
            NULL,
            NULL,
            NULL);
    }


cleanup:
    if (pCred)
    {
        NTLM_UNLOCK_MUTEX(bInLock, &pCred->Mutex);
    }

    LW_SAFE_FREE_STRING(pWorkstation);
    LW_SAFE_FREE_STRING(pDomain);

    return dwError;

error:
    LW_SAFE_FREE_MEMORY(pOutput->pvBuffer);
    pOutput->cbBuffer = 0;
    pOutput->BufferType = 0;

    // If this function has already succeed once, we MUST make sure phNewContext
    // is set so the caller can cleanup whatever context is remaining.  It
    // could be the original negotiate context or a new response context but
    // either way it is vital that the caller get a context they can actually
    // cleanup ONCE they've received ANY context from this function.
    //
    // If hContext is NULL, that indicates this is the first time through this
    // call and we can safely release our context.
    if ( pNtlmContext && !hContext)
    {
        NtlmReleaseContext(&pNtlmContext);
        phNewContext = NULL;
    }

    goto cleanup;
}