mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-29 12:18:01 +01:00
added support for SSPI-based NTLM authentication using the credentials of the currently logged in Windows user (Windows only)
This commit is contained in:
@@ -64,6 +64,12 @@ void HTTPNTLMCredentials::setPassword(const std::string& password)
|
||||
}
|
||||
|
||||
|
||||
void HTTPNTLMCredentials::setHost(const std::string& host)
|
||||
{
|
||||
_host = host;
|
||||
}
|
||||
|
||||
|
||||
void HTTPNTLMCredentials::authenticate(HTTPRequest& request, const HTTPResponse& response)
|
||||
{
|
||||
HTTPAuthenticationParams params(response);
|
||||
@@ -108,45 +114,62 @@ std::string HTTPNTLMCredentials::createNTLMMessage(const std::string& responseAu
|
||||
{
|
||||
if (responseAuthParams.empty())
|
||||
{
|
||||
NTLMCredentials::NegotiateMessage negotiateMsg;
|
||||
std::string username;
|
||||
NTLMCredentials::splitUsername(_username, username, negotiateMsg.domain);
|
||||
std::vector<unsigned char> negotiateBuf = NTLMCredentials::formatNegotiateMessage(negotiateMsg);
|
||||
std::vector<unsigned char> negotiateBuf;
|
||||
if (useSSPINTLM())
|
||||
{
|
||||
_pNTLMContext = SSPINTLMCredentials::createNTLMContext(_host, SSPINTLMCredentials::SERVICE_HTTP);
|
||||
negotiateBuf = SSPINTLMCredentials::negotiate(*_pNTLMContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
NTLMCredentials::NegotiateMessage negotiateMsg;
|
||||
std::string username;
|
||||
NTLMCredentials::splitUsername(_username, username, negotiateMsg.domain);
|
||||
negotiateBuf = NTLMCredentials::formatNegotiateMessage(negotiateMsg);
|
||||
}
|
||||
return NTLMCredentials::toBase64(negotiateBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::vector<unsigned char> buffer = NTLMCredentials::fromBase64(responseAuthParams);
|
||||
if (buffer.empty()) throw HTTPException("Invalid NTLM challenge");
|
||||
NTLMCredentials::ChallengeMessage challengeMsg;
|
||||
if (NTLMCredentials::parseChallengeMessage(&buffer[0], buffer.size(), challengeMsg))
|
||||
std::vector<unsigned char> authenticateBuf;
|
||||
if (useSSPINTLM() && _pNTLMContext)
|
||||
{
|
||||
if ((challengeMsg.flags & NTLMCredentials::NTLM_FLAG_NEGOTIATE_NTLM2_KEY) == 0)
|
||||
{
|
||||
throw HTTPException("Proxy does not support NTLMv2 authentication");
|
||||
}
|
||||
|
||||
std::string username;
|
||||
std::string domain;
|
||||
NTLMCredentials::splitUsername(_username, username, domain);
|
||||
|
||||
NTLMCredentials::AuthenticateMessage authenticateMsg;
|
||||
authenticateMsg.flags = challengeMsg.flags;
|
||||
authenticateMsg.target = challengeMsg.target;
|
||||
authenticateMsg.username = username;
|
||||
|
||||
std::vector<unsigned char> lmNonce = NTLMCredentials::createNonce();
|
||||
std::vector<unsigned char> ntlmNonce = NTLMCredentials::createNonce();
|
||||
Poco::UInt64 timestamp = NTLMCredentials::createTimestamp();
|
||||
std::vector<unsigned char> ntlm2Hash = NTLMCredentials::createNTLMv2Hash(username, challengeMsg.target, _password);
|
||||
|
||||
authenticateMsg.lmResponse = NTLMCredentials::createLMv2Response(ntlm2Hash, challengeMsg.challenge, lmNonce);
|
||||
authenticateMsg.ntlmResponse = NTLMCredentials::createNTLMv2Response(ntlm2Hash, challengeMsg.challenge, ntlmNonce, challengeMsg.targetInfo, timestamp);
|
||||
|
||||
std::vector<unsigned char> authenticateBuf = NTLMCredentials::formatAuthenticateMessage(authenticateMsg);
|
||||
return NTLMCredentials::toBase64(authenticateBuf);
|
||||
authenticateBuf = SSPINTLMCredentials::authenticate(*_pNTLMContext, buffer);
|
||||
}
|
||||
else throw HTTPException("Invalid NTLM challenge");
|
||||
else
|
||||
{
|
||||
NTLMCredentials::ChallengeMessage challengeMsg;
|
||||
if (NTLMCredentials::parseChallengeMessage(&buffer[0], buffer.size(), challengeMsg))
|
||||
{
|
||||
if ((challengeMsg.flags & NTLMCredentials::NTLM_FLAG_NEGOTIATE_NTLM2_KEY) == 0)
|
||||
{
|
||||
throw HTTPException("Proxy does not support NTLMv2 authentication");
|
||||
}
|
||||
|
||||
std::string username;
|
||||
std::string domain;
|
||||
NTLMCredentials::splitUsername(_username, username, domain);
|
||||
|
||||
NTLMCredentials::AuthenticateMessage authenticateMsg;
|
||||
authenticateMsg.flags = challengeMsg.flags;
|
||||
authenticateMsg.target = challengeMsg.target;
|
||||
authenticateMsg.username = username;
|
||||
|
||||
std::vector<unsigned char> lmNonce = NTLMCredentials::createNonce();
|
||||
std::vector<unsigned char> ntlmNonce = NTLMCredentials::createNonce();
|
||||
Poco::UInt64 timestamp = NTLMCredentials::createTimestamp();
|
||||
std::vector<unsigned char> ntlm2Hash = NTLMCredentials::createNTLMv2Hash(username, challengeMsg.target, _password);
|
||||
|
||||
authenticateMsg.lmResponse = NTLMCredentials::createLMv2Response(ntlm2Hash, challengeMsg.challenge, lmNonce);
|
||||
authenticateMsg.ntlmResponse = NTLMCredentials::createNTLMv2Response(ntlm2Hash, challengeMsg.challenge, ntlmNonce, challengeMsg.targetInfo, timestamp);
|
||||
|
||||
authenticateBuf = NTLMCredentials::formatAuthenticateMessage(authenticateMsg);
|
||||
}
|
||||
else throw HTTPException("Invalid NTLM challenge");
|
||||
}
|
||||
return NTLMCredentials::toBase64(authenticateBuf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user