bool KLUPD::NtlmImplementation::makeChallenge(std::vector<char> &challenge, const std::string &domain, const std::string &user, const std::string &password)
{
#ifdef WIN32    // no implementation for non-Windows platforms

    if(!loadSecurityLibrary())
        return false;

    TimeStamp expiration;
    if(needAquireCredentials(domain, user, password))
    {
        _SEC_WINNT_AUTH_IDENTITY *authorizationIdentityPointer = 0;
        _SEC_WINNT_AUTH_IDENTITY authorizationIdentity;

        if(getAuthorizationIdentity(authorizationIdentity, domain, user, password))
            authorizationIdentityPointer = &authorizationIdentity;

        releasePreviousCredentialsIfNeeded();

        SECURITY_STATUS result = m_funcionTable->AcquireCredentialsHandle(0, _T("NTLM"), SECPKG_CRED_OUTBOUND, 0, authorizationIdentityPointer, 0, 0, &m_credentials, &expiration);
        if(result != SEC_E_OK)
        {
            const int lastError = GetLastError();
            TRACE_MESSAGE3("Failed to make NTLM challenge: failed to acquire credentials, result 0x%x, last error '%S'",
                result, errnoToString(lastError, windowsStyle).toWideChar());
            return false;
        }
        m_credentialsObtained = true;
    }

    SecBuffer secBuffer;
    // the ISC_REQ_ALLOCATE_MEMORY content requirement does not
    //   work on Windows 98, that is why buffer is allocated on stack
    char buffer[2048];
    secBuffer.cbBuffer = 2048;
    secBuffer.pvBuffer = buffer;
    secBuffer.BufferType = SECBUFFER_TOKEN;

    SecBufferDesc messageType1;
    messageType1.cBuffers = 1;
    messageType1.pBuffers = &secBuffer;
    messageType1.ulVersion = SECBUFFER_VERSION;


    unsigned long attr = 0;
    const SECURITY_STATUS result = m_funcionTable->InitializeSecurityContext(
            &m_credentials,         // handle to credentials
            0,                      // handle to partial context (should be 0 on first call)
            0,                      // target (optional)
            0,                      // context requirements
            0,                      // reserved
            SECURITY_NETWORK_DREP,  // data representation
            0,                      // security buffer description
            0,                      // reserved
            &m_context,             // handle of new context
            &messageType1,          // security buffer description
            &attr,                  // dst context attributes
            &expiration);           // expiration time (local)

    if(result != SEC_I_CONTINUE_NEEDED  // SEC_I_CONTINUE_NEEDED is not error code - reply from server is expected to perform NTLM authorization protocol
        && result != SEC_E_OK)
    {
        const int lastError = GetLastError();
        TRACE_MESSAGE3("Failed to make NTLM challenge: failed to initialize security context, result 0x%x, last error '%S'",
            result, errnoToString(lastError, windowsStyle).toWideChar());
        return false;
    }
    m_securityContextObtained = true;

    challenge = CBase64::encodeBuffer(reinterpret_cast<unsigned char *>(secBuffer.pvBuffer), secBuffer.cbBuffer);
    return true;

#else   // WIN32
    TRACE_MESSAGE("Ntlm authorization is not implemented on this platform");
    return false;
#endif  // WIN32
}
Exemple #2
0
SSLManager::SSLManager():
	_hSecurityModule(0)
{
	loadSecurityLibrary();
}