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 }
SSLManager::SSLManager(): _hSecurityModule(0) { loadSecurityLibrary(); }