mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-25 02:06:04 +02:00
minor refactoring; check server challenge for NTLMv2 support
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
#include "Poco/Net/HTTPAuthenticationParams.h"
|
#include "Poco/Net/HTTPAuthenticationParams.h"
|
||||||
#include "Poco/Net/HTTPRequest.h"
|
#include "Poco/Net/HTTPRequest.h"
|
||||||
#include "Poco/Net/HTTPResponse.h"
|
#include "Poco/Net/HTTPResponse.h"
|
||||||
|
#include "Poco/Net/NetException.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
#include "Poco/NumberFormatter.h"
|
#include "Poco/NumberFormatter.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
@@ -115,25 +116,19 @@ std::string HTTPNTLMCredentials::createNTLMMessage(const std::string& responseAu
|
|||||||
std::string username;
|
std::string username;
|
||||||
splitUsername(_username, username, negotiateMsg.domain);
|
splitUsername(_username, username, negotiateMsg.domain);
|
||||||
std::vector<unsigned char> negotiateBuf = NTLMCredentials::formatNegotiateMessage(negotiateMsg);
|
std::vector<unsigned char> negotiateBuf = NTLMCredentials::formatNegotiateMessage(negotiateMsg);
|
||||||
|
return toBase64(negotiateBuf);
|
||||||
std::ostringstream ostr;
|
|
||||||
Poco::Base64Encoder base64(ostr);
|
|
||||||
base64.rdbuf()->setLineLength(0);
|
|
||||||
base64.write(reinterpret_cast<const char*>(&negotiateBuf[0]), negotiateBuf.size());
|
|
||||||
base64.close();
|
|
||||||
return ostr.str();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Poco::MemoryInputStream istr(responseAuthParams.data(), responseAuthParams.size());
|
std::vector<unsigned char> buffer = fromBase64(responseAuthParams);
|
||||||
Poco::Base64Decoder debase64(istr);
|
NTLMCredentials::ChallengeMessage challengeMsg;
|
||||||
std::vector<unsigned char> buffer(responseAuthParams.size());
|
if (NTLMCredentials::parseChallengeMessage(&buffer[0], buffer.size(), challengeMsg))
|
||||||
debase64.read(reinterpret_cast<char*>(&buffer[0]), buffer.size());
|
|
||||||
std::size_t size = static_cast<std::size_t>(debase64.gcount());
|
|
||||||
|
|
||||||
Poco::Net::NTLMCredentials::ChallengeMessage challengeMsg;
|
|
||||||
if (NTLMCredentials::parseChallengeMessage(&buffer[0], 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 username;
|
||||||
std::string domain;
|
std::string domain;
|
||||||
splitUsername(_username, username, domain);
|
splitUsername(_username, username, domain);
|
||||||
@@ -143,22 +138,18 @@ std::string HTTPNTLMCredentials::createNTLMMessage(const std::string& responseAu
|
|||||||
authenticateMsg.target = challengeMsg.target;
|
authenticateMsg.target = challengeMsg.target;
|
||||||
authenticateMsg.username = username;
|
authenticateMsg.username = username;
|
||||||
|
|
||||||
std::vector<unsigned char> nonce = NTLMCredentials::createNonce();
|
std::vector<unsigned char> lmNonce = NTLMCredentials::createNonce();
|
||||||
|
std::vector<unsigned char> ntlmNonce = NTLMCredentials::createNonce();
|
||||||
Poco::UInt64 timestamp = NTLMCredentials::createTimestamp();
|
Poco::UInt64 timestamp = NTLMCredentials::createTimestamp();
|
||||||
std::vector<unsigned char> ntlm2Hash = NTLMCredentials::createNTLMv2Hash(username, challengeMsg.target, _password);
|
std::vector<unsigned char> ntlm2Hash = NTLMCredentials::createNTLMv2Hash(username, challengeMsg.target, _password);
|
||||||
authenticateMsg.lmResponse = NTLMCredentials::createLMv2Response(ntlm2Hash, challengeMsg.challenge, nonce);
|
|
||||||
authenticateMsg.ntlmResponse = Poco::Net::NTLMCredentials::createNTLMv2Response(ntlm2Hash, challengeMsg.challenge, nonce, challengeMsg.targetInfo, timestamp);
|
|
||||||
|
|
||||||
std::vector<unsigned char> authenticateBuf = Poco::Net::NTLMCredentials::formatAuthenticateMessage(authenticateMsg);
|
authenticateMsg.lmResponse = NTLMCredentials::createLMv2Response(ntlm2Hash, challengeMsg.challenge, lmNonce);
|
||||||
|
authenticateMsg.ntlmResponse = NTLMCredentials::createNTLMv2Response(ntlm2Hash, challengeMsg.challenge, ntlmNonce, challengeMsg.targetInfo, timestamp);
|
||||||
|
|
||||||
std::ostringstream ostr;
|
std::vector<unsigned char> authenticateBuf = NTLMCredentials::formatAuthenticateMessage(authenticateMsg);
|
||||||
Poco::Base64Encoder base64(ostr);
|
return toBase64(authenticateBuf);
|
||||||
base64.rdbuf()->setLineLength(0);
|
|
||||||
base64.write(reinterpret_cast<const char*>(&authenticateBuf[0]), authenticateBuf.size());
|
|
||||||
base64.close();
|
|
||||||
return ostr.str();
|
|
||||||
}
|
}
|
||||||
else throw Poco::InvalidArgumentException("Invalid NTLM challenge");
|
else throw HTTPException("Invalid NTLM challenge");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,5 +177,26 @@ void HTTPNTLMCredentials::splitUsername(const std::string& usernameAndDomain, st
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string HTTPNTLMCredentials::toBase64(const std::vector<unsigned char>& buffer)
|
||||||
|
{
|
||||||
|
std::ostringstream ostr;
|
||||||
|
Poco::Base64Encoder base64(ostr);
|
||||||
|
base64.rdbuf()->setLineLength(0);
|
||||||
|
base64.write(reinterpret_cast<const char*>(&buffer[0]), buffer.size());
|
||||||
|
base64.close();
|
||||||
|
return ostr.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<unsigned char> HTTPNTLMCredentials::fromBase64(const std::string& base64)
|
||||||
|
{
|
||||||
|
Poco::MemoryInputStream istr(base64.data(), base64.size());
|
||||||
|
Poco::Base64Decoder debase64(istr);
|
||||||
|
std::vector<unsigned char> buffer(base64.size());
|
||||||
|
debase64.read(reinterpret_cast<char*>(&buffer[0]), buffer.size());
|
||||||
|
buffer.resize(static_cast<std::size_t>(debase64.gcount()));
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Net
|
} } // namespace Poco::Net
|
||||||
|
|||||||
Reference in New Issue
Block a user