コード例 #1
0
ファイル: acceptsecctxt.c プロジェクト: borland667/pbis
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
NtlmCreateResponseContext(
    IN PNTLM_CHALLENGE_MESSAGE pChlngMsg,
    IN NTLM_CRED_HANDLE hCred,
    IN BOOLEAN bDoAnonymous,
    OUT PNTLM_CONTEXT* ppNtlmContext,
    OUT PSecBuffer pOutput
)
{
    DWORD dwError = LW_ERROR_SUCCESS;
    PNTLM_RESPONSE_MESSAGE_V1 pMessage = NULL;
    PCSTR pUserNameTemp = NULL;
    PCSTR pPassword = NULL;
    PNTLM_CONTEXT pNtlmContext = NULL;
    PBYTE pMasterKey = NULL;
    BYTE LmUserSessionKey[NTLM_SESSION_KEY_SIZE] = {0};
    BYTE NtlmUserSessionKey[NTLM_SESSION_KEY_SIZE] = {0};
    BYTE LanManagerSessionKey[NTLM_SESSION_KEY_SIZE] = {0};
    BYTE SecondaryKey[NTLM_SESSION_KEY_SIZE] = {0};
    PLSA_LOGIN_NAME_INFO pUserNameInfo = NULL;
    DWORD dwMessageSize = 0;
    NTLM_CONFIG config;
    DWORD dwNtRespType = 0;
    DWORD dwLmRespType = 0;

    *ppNtlmContext = NULL;

    dwError = NtlmReadRegistry(&config);
    BAIL_ON_LSA_ERROR(dwError);

    if (bDoAnonymous)
    {
        pUserNameTemp = "";
        pPassword = "";
    }
    else
    {
        NtlmGetCredentialInfo(
            hCred,
            &pUserNameTemp,
            &pPassword,
            NULL);

        if (!pUserNameTemp[0] && !pPassword[0])
        {
            bDoAnonymous = TRUE;
        }
    }

    if (bDoAnonymous)
    {
        dwError = LwAllocateMemory(
                      sizeof(*pUserNameInfo),
                      OUT_PPVOID(&pUserNameInfo));
        BAIL_ON_LSA_ERROR(dwError);

        dwError = LwAllocateString(
                      "",
                      &pUserNameInfo->pszName);
        BAIL_ON_LSA_ERROR(dwError);
        dwError = LwAllocateString(
                      "",
                      &pUserNameInfo->pszDomain);
        BAIL_ON_LSA_ERROR(dwError);
    }
    else
    {
        dwError = LsaSrvCrackDomainQualifiedName(
                      pUserNameTemp,
                      &pUserNameInfo);
        BAIL_ON_LSA_ERROR(dwError);
    }

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

    dwError = LwAllocateString(
                  pUserNameTemp,
                  &pNtlmContext->pszClientUsername);
    BAIL_ON_LSA_ERROR(dwError);

    if (bDoAnonymous)
    {
        dwNtRespType = NTLM_RESPONSE_TYPE_ANON_NTLM;
        dwLmRespType = NTLM_RESPONSE_TYPE_ANON_LM;
    }
    else if (config.bSendNTLMv2)
    {
        dwNtRespType = NTLM_RESPONSE_TYPE_NTLMv2;
        // TODO: the correct thing is to use LMv2
        dwLmRespType = NTLM_RESPONSE_TYPE_LM;
    }
    else if(LW_LTOH32(pChlngMsg->NtlmFlags) & NTLM_FLAG_NTLM2)
    {
        dwLmRespType = NTLM_RESPONSE_TYPE_NTLM2;
        dwNtRespType = NTLM_RESPONSE_TYPE_NTLM2;
    }
    else
    {
        dwNtRespType = NTLM_RESPONSE_TYPE_NTLM;
        dwLmRespType = NTLM_RESPONSE_TYPE_LM;
    }

    dwError = NtlmCreateResponseMessage(
                  pChlngMsg,
                  pUserNameInfo->pszName,
                  pUserNameInfo->pszDomain,
                  pPassword,
                  (PBYTE)&gXpSpoof,
                  dwNtRespType,
                  dwLmRespType,
                  &dwMessageSize,
                  &pMessage,
                  LmUserSessionKey,
                  NtlmUserSessionKey
              );
    BAIL_ON_LSA_ERROR(dwError);

    // As a side effect of creating the response, we must also set/produce the
    // master session key...

    pMasterKey = NtlmUserSessionKey;

    if (LW_LTOH32(pChlngMsg->NtlmFlags) & NTLM_FLAG_LM_KEY)
    {
        NtlmGenerateLanManagerSessionKey(
            pMessage,
            LmUserSessionKey,
            LanManagerSessionKey);

        pMasterKey = LanManagerSessionKey;
    }

    if (LW_LTOH32(pChlngMsg->NtlmFlags) & NTLM_FLAG_KEY_EXCH)
    {
        // This is the key we will use for session security...
        dwError = NtlmGetRandomBuffer(
                      SecondaryKey,
                      NTLM_SESSION_KEY_SIZE);
        BAIL_ON_LSA_ERROR(dwError);

        // Encrypt it with the "master key" set above and send it along with the
        // response
        NtlmStoreSecondaryKey(
            pMasterKey,
            SecondaryKey,
            pMessage);

        pMasterKey = SecondaryKey;
    }

    NtlmWeakenSessionKey(
        pChlngMsg,
        pMasterKey,
        &pNtlmContext->cbSessionKeyLen);

    memcpy(pNtlmContext->SessionKey, pMasterKey, NTLM_SESSION_KEY_SIZE);

    pNtlmContext->NegotiatedFlags = LW_LTOH32(pChlngMsg->NtlmFlags);
    pOutput->cbBuffer = dwMessageSize;
    pOutput->BufferType = SECBUFFER_TOKEN;
    pOutput->pvBuffer = pMessage;
    pNtlmContext->NtlmState = NtlmStateResponse;
    pNtlmContext->bInitiatedSide = TRUE;
    pNtlmContext->bDoAnonymous = bDoAnonymous;

    dwError = NtlmInitializeKeys(pNtlmContext);
    BAIL_ON_LSA_ERROR(dwError);

cleanup:
    if (pUserNameInfo)
    {
        LsaSrvFreeNameInfo(pUserNameInfo);
    }

    *ppNtlmContext = pNtlmContext;

    return dwError;
error:
    LW_SAFE_FREE_MEMORY(pMessage);
    if (pNtlmContext)
    {
        NtlmFreeContext(&pNtlmContext);
    }
    pOutput->cbBuffer = 0;
    pOutput->BufferType = 0;
    pOutput->pvBuffer = NULL;

    goto cleanup;
}