NTLM (proxy) authentication support for HTTPClientSession

This commit is contained in:
Günter Obiltschnig
2019-03-18 16:58:57 +01:00
parent da7de5e586
commit 0f3f11a3b2
22 changed files with 1711 additions and 279 deletions

View File

@@ -27,7 +27,8 @@ objects = \
WebSocketTest WebSocketTestSuite \
SyslogTest \
OAuth10CredentialsTest OAuth20CredentialsTest OAuthTestSuite \
PollSetTest UDPServerTest UDPServerTestSuite
PollSetTest UDPServerTest UDPServerTestSuite \
NTLMCredentialsTest
target = testrunner
target_version = 1

View File

@@ -44,7 +44,7 @@ void HTTPCredentialsTest::testBasicCredentials()
{
HTTPRequest request;
assertTrue (!request.hasCredentials());
HTTPBasicCredentials cred("user", "secret");
cred.authenticate(request);
assertTrue (request.hasCredentials());
@@ -53,7 +53,7 @@ void HTTPCredentialsTest::testBasicCredentials()
request.getCredentials(scheme, info);
assertTrue (scheme == "Basic");
assertTrue (info == "dXNlcjpzZWNyZXQ=");
HTTPBasicCredentials cred2(request);
assertTrue (cred2.getUsername() == "user");
assertTrue (cred2.getPassword() == "secret");
@@ -64,7 +64,7 @@ void HTTPCredentialsTest::testProxyBasicCredentials()
{
HTTPRequest request;
assertTrue (!request.hasProxyCredentials());
HTTPBasicCredentials cred("user", "secret");
cred.proxyAuthenticate(request);
assertTrue (request.hasProxyCredentials());
@@ -79,7 +79,7 @@ void HTTPCredentialsTest::testProxyBasicCredentials()
void HTTPCredentialsTest::testBadCredentials()
{
HTTPRequest request;
std::string scheme;
std::string info;
try
@@ -90,12 +90,12 @@ void HTTPCredentialsTest::testBadCredentials()
catch (NotAuthenticatedException&)
{
}
request.setCredentials("Test", "SomeData");
request.getCredentials(scheme, info);
assertTrue (scheme == "Test");
assertTrue (info == "SomeData");
try
{
HTTPBasicCredentials cred(request);
@@ -111,7 +111,7 @@ void HTTPCredentialsTest::testAuthenticationParams()
{
const std::string authInfo("nonce=\"212573bb90170538efad012978ab811f%lu\", realm=\"TestDigest\", response=\"40e4889cfbd0e561f71e3107a2863bc4\", uri=\"/digest/\", username=\"user\"");
HTTPAuthenticationParams params(authInfo);
assertTrue (params["nonce"] == "212573bb90170538efad012978ab811f%lu");
assertTrue (params["realm"] == "TestDigest");
assertTrue (params["response"] == "40e4889cfbd0e561f71e3107a2863bc4");
@@ -119,7 +119,7 @@ void HTTPCredentialsTest::testAuthenticationParams()
assertTrue (params["username"] == "user");
assertTrue (params.size() == 5);
assertTrue (params.toString() == authInfo);
params.clear();
HTTPRequest request;
request.set("Authorization", "Digest " + authInfo);
@@ -134,22 +134,29 @@ void HTTPCredentialsTest::testAuthenticationParams()
params.clear();
HTTPResponse response;
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
params.fromResponse(response);
assertTrue (params["realm"] == "TestDigest");
assertTrue (params["nonce"] == "212573bb90170538efad012978ab811f%lu");
assertTrue (params.size() == 2);
params.clear();
response.set("WWW-Authenticate", "NTLM TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA");
params.fromResponse(response);
assertTrue (params["NTLM"] == "TlRMTVNTUAACAAAADAAMADAAAAABAoEAASNFZ4mrze8AAAAAAAAAAGIAYgA8AAAARABPAE0AQQBJAE4AAgAMAEQATwBNAEEASQBOAAEADABTAEUAUgBWAEUAUgAEABQAZABvAG0AYQBpAG4ALgBjAG8AbQADACIAcwBlAHIAdgBlAHIALgBkAG8AbQBhAGkAbgAuAGMAbwBtAAAAAAA");
assertTrue (params.size() == 1);
}
void HTTPCredentialsTest::testAuthenticationParamsMultipleHeaders()
{
HTTPResponse response;
response.add("WWW-Authenticate", "Unsupported realm=\"TestUnsupported\"");
response.add("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
response.add("WWW-Authenticate", "Unsupported realm=\"TestUnsupported\"");
response.add("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
HTTPAuthenticationParams params(response);
assertTrue (params["realm"] == "TestDigest");
assertTrue (params["nonce"] == "212573bb90170538efad012978ab811f%lu");
assertTrue (params.size() == 2);
@@ -161,7 +168,7 @@ void HTTPCredentialsTest::testDigestCredentials()
HTTPDigestCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/digest/");
HTTPResponse response;
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
creds.authenticate(request, response);
std::string auth = request.get("Authorization");
assertTrue (auth == "Digest username=\"user\", nonce=\"212573bb90170538efad012978ab811f%lu\", realm=\"TestDigest\", uri=\"/digest/\", response=\"40e4889cfbd0e561f71e3107a2863bc4\"");
@@ -173,9 +180,9 @@ void HTTPCredentialsTest::testDigestCredentialsQoP()
HTTPDigestCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/digest/");
HTTPResponse response;
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth,auth-int\"");
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth,auth-int\"");
creds.authenticate(request, response);
HTTPAuthenticationParams params(request);
assertTrue (params["nonce"] == "212573bb90170538efad012978ab811f%lu");
assertTrue (params["realm"] == "TestDigest");
@@ -187,12 +194,12 @@ void HTTPCredentialsTest::testDigestCredentialsQoP()
assertTrue (params["nc"] == "00000001");
assertTrue (params["qop"] == "auth");
assertTrue (params.size() == 9);
std::string cnonce = params["cnonce"];
std::string aresp = params["response"];
params.clear();
creds.updateAuthInfo(request);
params.fromRequest(request);
assertTrue (params["nonce"] == "212573bb90170538efad012978ab811f%lu");
@@ -213,8 +220,8 @@ void HTTPCredentialsTest::testCredentialsBasic()
HTTPCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/basic/");
HTTPResponse response;
response.set("WWW-Authenticate", "Basic realm=\"TestBasic\"");
creds.authenticate(request, response);
response.set("WWW-Authenticate", "Basic realm=\"TestBasic\"");
creds.authenticate(request, response);
assertTrue (request.get("Authorization") == "Basic dXNlcjpzM2NyM3Q=");
}
@@ -224,8 +231,8 @@ void HTTPCredentialsTest::testProxyCredentialsBasic()
HTTPCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/basic/");
HTTPResponse response;
response.set("Proxy-Authenticate", "Basic realm=\"TestBasic\"");
creds.proxyAuthenticate(request, response);
response.set("Proxy-Authenticate", "Basic realm=\"TestBasic\"");
creds.proxyAuthenticate(request, response);
assertTrue (request.get("Proxy-Authorization") == "Basic dXNlcjpzM2NyM3Q=");
}
@@ -235,7 +242,7 @@ void HTTPCredentialsTest::testCredentialsDigest()
HTTPCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/digest/");
HTTPResponse response;
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
creds.authenticate(request, response);
std::string auth = request.get("Authorization");
assertTrue (auth == "Digest username=\"user\", nonce=\"212573bb90170538efad012978ab811f%lu\", realm=\"TestDigest\", uri=\"/digest/\", response=\"40e4889cfbd0e561f71e3107a2863bc4\"");
@@ -247,8 +254,8 @@ void HTTPCredentialsTest::testCredentialsDigestMultipleHeaders()
HTTPCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/digest/");
HTTPResponse response;
response.add("WWW-Authenticate", "Unsupported realm=\"TestUnsupported\"");
response.add("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
response.add("WWW-Authenticate", "Unsupported realm=\"TestUnsupported\"");
response.add("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
creds.authenticate(request, response);
std::string auth = request.get("Authorization");
assertTrue (auth == "Digest username=\"user\", nonce=\"212573bb90170538efad012978ab811f%lu\", realm=\"TestDigest\", uri=\"/digest/\", response=\"40e4889cfbd0e561f71e3107a2863bc4\"");
@@ -260,8 +267,8 @@ void HTTPCredentialsTest::testProxyCredentialsDigest()
HTTPCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/digest/");
HTTPResponse response;
response.set("Proxy-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
creds.proxyAuthenticate(request, response);
response.set("Proxy-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
creds.proxyAuthenticate(request, response);
assertTrue (request.get("Proxy-Authorization") == "Digest username=\"user\", nonce=\"212573bb90170538efad012978ab811f%lu\", realm=\"TestDigest\", uri=\"/digest/\", response=\"40e4889cfbd0e561f71e3107a2863bc4\"");
}
@@ -282,10 +289,10 @@ void HTTPCredentialsTest::testVerifyAuthInfo()
HTTPDigestCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/digest/");
HTTPResponse response;
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\"");
creds.authenticate(request, response);
assertTrue (creds.verifyAuthInfo(request));
request.set("Authorization", "Digest nonce=\"212573bb90170538efad012978ab811f%lu\", realm=\"TestDigest\", response=\"xxe4889cfbd0e561f71e3107a2863bc4\", uri=\"/digest/\", username=\"user\"");
assertTrue (!creds.verifyAuthInfo(request));
}
@@ -296,10 +303,10 @@ void HTTPCredentialsTest::testVerifyAuthInfoQoP()
HTTPDigestCredentials creds("user", "s3cr3t");
HTTPRequest request(HTTPRequest::HTTP_GET, "/digest/");
HTTPResponse response;
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth,auth-int\"");
response.set("WWW-Authenticate", "Digest realm=\"TestDigest\", nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth,auth-int\"");
creds.authenticate(request, response);
assertTrue (creds.verifyAuthInfo(request));
request.set("Authorization", "Digest cnonce=\"f9c80ffd1c3bc4ee47ed92b704ba75a4\", nc=00000001, nonce=\"212573bb90170538efad012978ab811f%lu\", opaque=\"opaque\", qop=\"auth\", realm=\"TestDigest\", response=\"ff0e90b9aa019120ea0ed6e23ce95d9a\", uri=\"/digest/\", username=\"user\"");
assertTrue (!creds.verifyAuthInfo(request));
}

View File

@@ -13,6 +13,7 @@
#include "HTTPResponseTest.h"
#include "HTTPCookieTest.h"
#include "HTTPCredentialsTest.h"
#include "NTLMCredentialsTest.h"
CppUnit::Test* HTTPTestSuite::suite()
@@ -23,6 +24,7 @@ CppUnit::Test* HTTPTestSuite::suite()
pSuite->addTest(HTTPResponseTest::suite());
pSuite->addTest(HTTPCookieTest::suite());
pSuite->addTest(HTTPCredentialsTest::suite());
pSuite->addTest(NTLMCredentialsTest::suite());
return pSuite;
}

View File

@@ -0,0 +1,279 @@
//
// NTLMCredentialsTest.cpp
//
// Copyright (c) 2014, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#include "NTLMCredentialsTest.h"
#include "CppUnit/TestCaller.h"
#include "CppUnit/TestSuite.h"
#include "Poco/Net/NTLMCredentials.h"
#include "Poco/DigestEngine.h"
using Poco::Net::NTLMCredentials;
NTLMCredentialsTest::NTLMCredentialsTest(const std::string& name): CppUnit::TestCase(name)
{
}
NTLMCredentialsTest::~NTLMCredentialsTest()
{
}
void NTLMCredentialsTest::testNonce()
{
std::vector<unsigned char> nonce1 = NTLMCredentials::createNonce();
assertTrue (nonce1.size() == 8);
std::vector<unsigned char> nonce2 = NTLMCredentials::createNonce();
assertTrue (nonce2.size() == 8);
assertTrue (nonce1 != nonce2);
}
void NTLMCredentialsTest::testPasswordHash()
{
std::vector<unsigned char> passHash = NTLMCredentials::createPasswordHash("SecREt01");
std::string passHashHex = Poco::DigestEngine::digestToHex(passHash);
assertTrue (passHashHex == "cd06ca7c7e10c99b1d33b7485a2ed808");
}
void NTLMCredentialsTest::testNTLMv2Hash()
{
std::vector<unsigned char> ntlm2Hash = NTLMCredentials::createNTLMv2Hash("user", "DOMAIN", "SecREt01");
std::string ntlm2HashHex = Poco::DigestEngine::digestToHex(ntlm2Hash);
assertTrue (ntlm2HashHex == "04b8e0ba74289cc540826bab1dee63ae");
}
void NTLMCredentialsTest::testLMv2Response()
{
static const unsigned char CHALLENGE[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
static const unsigned char NONCE[] = {0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44};
std::vector<unsigned char> challenge(CHALLENGE, CHALLENGE + 8);
std::vector<unsigned char> nonce(NONCE, NONCE + 8);
std::vector<unsigned char> ntlm2Hash = NTLMCredentials::createNTLMv2Hash("user", "DOMAIN", "SecREt01");
std::vector<unsigned char> lm2Response = NTLMCredentials::createLMv2Response(ntlm2Hash, challenge, nonce);
std::string lm2ResponseHex = Poco::DigestEngine::digestToHex(lm2Response);
assertTrue (lm2ResponseHex == "d6e6152ea25d03b7c6ba6629c2d6aaf0ffffff0011223344");
}
void NTLMCredentialsTest::testNTLMv2Response()
{
static const unsigned char CHALLENGE[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
static const unsigned char NONCE[] = {0xff, 0xff, 0xff, 0x00, 0x11, 0x22, 0x33, 0x44};
static const unsigned char TARGET_INFO[] = {
0x02, 0x00, 0x0c, 0x00, 0x44, 0x00, 0x4f, 0x00,
0x4d, 0x00, 0x41, 0x00, 0x49, 0x00, 0x4e, 0x00,
0x01, 0x00, 0x0c, 0x00, 0x53, 0x00, 0x45, 0x00,
0x52, 0x00, 0x56, 0x00, 0x45, 0x00, 0x52, 0x00,
0x04, 0x00, 0x14, 0x00, 0x64, 0x00, 0x6f, 0x00,
0x6d, 0x00, 0x61, 0x00, 0x69, 0x00, 0x6e, 0x00,
0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00,
0x03, 0x00, 0x22, 0x00, 0x73, 0x00, 0x65, 0x00,
0x72, 0x00, 0x76, 0x00, 0x65, 0x00, 0x72, 0x00,
0x2e, 0x00, 0x64, 0x00, 0x6f, 0x00, 0x6d, 0x00,
0x61, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00,
0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x00, 0x00,
0x00, 0x00
};
std::vector<unsigned char> challenge(CHALLENGE, CHALLENGE + 8);
std::vector<unsigned char> nonce(NONCE, NONCE + 8);
std::vector<unsigned char> targetInfo(TARGET_INFO, TARGET_INFO + sizeof(TARGET_INFO));
std::vector<unsigned char> ntlm2Hash = NTLMCredentials::createNTLMv2Hash("user", "DOMAIN", "SecREt01");
Poco::UInt64 timestamp = Poco::UInt64(12700317600)*10000000;
std::vector<unsigned char> ntlm2Response = NTLMCredentials::createNTLMv2Response(
ntlm2Hash,
challenge,
nonce,
targetInfo,
timestamp);
std::string ntlm2ResponseHex = Poco::DigestEngine::digestToHex(ntlm2Response);
assertTrue (ntlm2ResponseHex ==
"cbabbca713eb795d04c97abc01ee4983"
"01010000000000000090d336b734c301"
"ffffff00112233440000000002000c00"
"44004f004d00410049004e0001000c00"
"53004500520056004500520004001400"
"64006f006d00610069006e002e006300"
"6f006d00030022007300650072007600"
"650072002e0064006f006d0061006900"
"6e002e0063006f006d00000000000000"
"0000"
);
}
void NTLMCredentialsTest::testFormatNegotiateMessage()
{
NTLMCredentials::NegotiateMessage msg1;
msg1.flags = 0;
std::vector<unsigned char> msg1Buffer = NTLMCredentials::formatNegotiateMessage(msg1);
std::string msg1BufferHex = Poco::DigestEngine::digestToHex(msg1Buffer);
assertTrue (msg1BufferHex == "4e544c4d53535000010000000582080000000000180000000000000018000000");
msg1.domain = "DOMAIN";
msg1Buffer = NTLMCredentials::formatNegotiateMessage(msg1);
msg1BufferHex = Poco::DigestEngine::digestToHex(msg1Buffer);
assertTrue (msg1BufferHex == "4e544c4d5353500001000000059208000c000c0018000000000000002400000044004f004d00410049004e00");
msg1.workstation = "WORKST";
msg1Buffer = NTLMCredentials::formatNegotiateMessage(msg1);
msg1BufferHex = Poco::DigestEngine::digestToHex(msg1Buffer);
assertTrue (msg1BufferHex == "4e544c4d535350000100000005b208000c000c00180000000c000c002400000044004f004d00410049004e0057004f0052004b0053005400");
}
void NTLMCredentialsTest::testParseChallengeMessage()
{
const unsigned char BUFFER[] = {
0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef
};
NTLMCredentials::ChallengeMessage msg2;
bool ok = NTLMCredentials::parseChallengeMessage(BUFFER, sizeof(BUFFER), msg2);
assertTrue (ok);
assertTrue (msg2.flags == (NTLMCredentials::NTLM_FLAG_NEGOTIATE_OEM | NTLMCredentials::NTLM_FLAG_NEGOTIATE_NTLM));
assertTrue (msg2.challenge.size() == 8);
assertTrue (msg2.targetInfo.empty());
assertTrue (msg2.challenge[0] == 0x01);
assertTrue (msg2.challenge[1] == 0x23);
assertTrue (msg2.challenge[7] == 0xef);
}
void NTLMCredentialsTest::testParseChallengeMessageWithTargetInfo()
{
const unsigned char BUFFER[] = {
0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00,
0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00,
0x30, 0x00, 0x00, 0x00, 0x01, 0x02, 0x81, 0x00,
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x62, 0x00, 0x62, 0x00, 0x3c, 0x00, 0x00, 0x00,
0x44, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x41, 0x00,
0x49, 0x00, 0x4e, 0x00, 0x02, 0x00, 0x0c, 0x00,
0x44, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x41, 0x00,
0x49, 0x00, 0x4e, 0x00, 0x01, 0x00, 0x0c, 0x00,
0x53, 0x00, 0x45, 0x00, 0x52, 0x00, 0x56, 0x00,
0x45, 0x00, 0x52, 0x00, 0x04, 0x00, 0x14, 0x00,
0x64, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x61, 0x00,
0x69, 0x00, 0x6e, 0x00, 0x2e, 0x00, 0x63, 0x00,
0x6f, 0x00, 0x6d, 0x00, 0x03, 0x00, 0x22, 0x00,
0x73, 0x00, 0x65, 0x00, 0x72, 0x00, 0x76, 0x00,
0x65, 0x00, 0x72, 0x00, 0x2e, 0x00, 0x64, 0x00,
0x6f, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x69, 0x00,
0x6e, 0x00, 0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00,
0x6d, 0x00, 0x00, 0x00, 0x00, 0x00
};
NTLMCredentials::ChallengeMessage msg2;
bool ok = NTLMCredentials::parseChallengeMessage(BUFFER, sizeof(BUFFER), msg2);
assertTrue (ok);
assertTrue (msg2.flags == (NTLMCredentials::NTLM_FLAG_NEGOTIATE_UNICODE | NTLMCredentials::NTLM_FLAG_NEGOTIATE_NTLM | NTLMCredentials::NTLM_FLAG_NEGOTIATE_TARGET | NTLMCredentials::NTLM_FLAG_TARGET_DOMAIN));
assertTrue (msg2.challenge.size() == 8);
assertTrue (msg2.target == "DOMAIN");
assertTrue (msg2.targetInfo.size() == 98);
assertTrue (msg2.challenge[0] == 0x01);
assertTrue (msg2.challenge[1] == 0x23);
assertTrue (msg2.challenge[7] == 0xef);
assertTrue (msg2.targetInfo[0] == 0x02);
assertTrue (msg2.targetInfo[1] == 0x00);
assertTrue (msg2.targetInfo[97] == 0x00);
}
void NTLMCredentialsTest::testFormatAuthenticateMessage()
{
const unsigned char LM[] = {
0xc3, 0x37, 0xcd, 0x5c, 0xbd, 0x44, 0xfc, 0x97,
0x82, 0xa6, 0x67, 0xaf, 0x6d, 0x42, 0x7c, 0x6d,
0xe6, 0x7c, 0x20, 0xc2, 0xd3, 0xe7, 0x7c, 0x56
};
const unsigned char NTLM[] = {
0x25, 0xa9, 0x8c, 0x1c, 0x31, 0xe8, 0x18, 0x47,
0x46, 0x6b, 0x29, 0xb2, 0xdf, 0x46, 0x80, 0xf3,
0x99, 0x58, 0xfb, 0x8c, 0x21, 0x3a, 0x9c, 0xc6
};
NTLMCredentials::AuthenticateMessage msg3;
msg3.flags = NTLMCredentials::NTLM_FLAG_NEGOTIATE_UNICODE | NTLMCredentials::NTLM_FLAG_NEGOTIATE_NTLM;
msg3.target = "DOMAIN";
msg3.username = "user";
msg3.workstation = "WORKSTATION";
msg3.lmResponse.assign(LM, LM + sizeof(LM));
msg3.ntlmResponse.assign(NTLM, NTLM + sizeof(NTLM));
std::vector<unsigned char> msg3Buffer = NTLMCredentials::formatAuthenticateMessage(msg3);
std::string msg3BufferHex = Poco::DigestEngine::digestToHex(msg3Buffer);
assertTrue (msg3BufferHex ==
"4e544c4d5353500003000000180018004000000018001800"
"580000000c000c0070000000080008007c00000016001600"
"84000000000000009a00000001020000c337cd5cbd44fc97"
"82a667af6d427c6de67c20c2d3e77c5625a98c1c31e81847"
"466b29b2df4680f39958fb8c213a9cc644004f004d004100"
"49004e00750073006500720057004f0052004b0053005400"
"4100540049004f004e00"
);
}
void NTLMCredentialsTest::setUp()
{
}
void NTLMCredentialsTest::tearDown()
{
}
CppUnit::Test* NTLMCredentialsTest::suite()
{
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("NTLMCredentialsTest");
CppUnit_addTest(pSuite, NTLMCredentialsTest, testNonce);
CppUnit_addTest(pSuite, NTLMCredentialsTest, testPasswordHash);
CppUnit_addTest(pSuite, NTLMCredentialsTest, testNTLMv2Hash);
CppUnit_addTest(pSuite, NTLMCredentialsTest, testLMv2Response);
CppUnit_addTest(pSuite, NTLMCredentialsTest, testNTLMv2Response);
CppUnit_addTest(pSuite, NTLMCredentialsTest, testFormatNegotiateMessage);
CppUnit_addTest(pSuite, NTLMCredentialsTest, testParseChallengeMessage);
CppUnit_addTest(pSuite, NTLMCredentialsTest, testParseChallengeMessageWithTargetInfo);
CppUnit_addTest(pSuite, NTLMCredentialsTest, testFormatAuthenticateMessage);
return pSuite;
}

View File

@@ -0,0 +1,46 @@
//
// NTLMCredentialsTest.h
//
// Definition of the NTLMCredentialsTest class.
//
// Copyright (c) 2019, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier: BSL-1.0
//
#ifndef NTLMCredentialsTest_INCLUDED
#define NTLMCredentialsTest_INCLUDED
#include "Poco/Net/Net.h"
#include "CppUnit/TestCase.h"
class NTLMCredentialsTest: public CppUnit::TestCase
{
public:
NTLMCredentialsTest(const std::string& name);
~NTLMCredentialsTest();
void testNonce();
void testPasswordHash();
void testNTLMv2Hash();
void testLMv2Response();
void testNTLMv2Response();
void testFormatNegotiateMessage();
void testParseChallengeMessage();
void testParseChallengeMessageWithTargetInfo();
void testFormatAuthenticateMessage();
void setUp();
void tearDown();
static CppUnit::Test* suite();
private:
};
#endif // NTLMCredentialsTest_INCLUDED