1#include <winpr/wtypes.h>
3#include <winpr/string.h>
4#include <winpr/print.h>
9 const BYTE expected[16];
11 const BOOL shouldMatch;
19 const BYTE expected[16];
21 const BOOL shouldMatch;
28 const BYTE passwordhash[16];
29 const BYTE expected[16];
31 const BOOL shouldMatch;
32} test_case_from_hash_t;
34static const test_case_ntowf1_t ntofw1tests[] = {
35 {
"foo1", { 0 }, TRUE, FALSE },
37 { 0x05, 0x80, 0x83, 0x4a, 0x04, 0x89, 0xed, 0x37, 0x49, 0x6b, 0x7b, 0xfa, 0xe9, 0x90, 0x9b,
42 { 0xee, 0xd4, 0xd3, 0xb5, 0x87, 0x11, 0x0d, 0x5c, 0x08, 0x51, 0x8c, 0xea, 0xa5, 0x69, 0x1e,
46 {
nullptr, { 0 }, FALSE, FALSE }
49static const test_case_ntowf2_t ntofw2tests[] = {
50 {
nullptr,
nullptr,
nullptr, { 0 }, FALSE, FALSE },
51 {
nullptr,
nullptr,
"domain1", { 0 }, FALSE, FALSE },
52 {
nullptr,
"user1",
"domain1", { 0 }, FALSE, FALSE },
53 {
"pwd1",
"user1",
"domain1", { 0 }, TRUE, FALSE },
57 { 0x9b, 0xee, 0x1e, 0x41, 0xa6, 0xd3, 0xf1, 0xf2, 0xc4, 0x00, 0xb8, 0xf9, 0x44, 0xc5, 0x44,
64 { 0xa5, 0x82, 0xcd, 0x70, 0xce, 0xb0, 0xed, 0x99, 0xe6, 0xf5, 0x45, 0x3e, 0x96, 0x93, 0x5d,
71 { 0xf9, 0x4d, 0x1e, 0x10, 0x31, 0xa1, 0x96, 0x0d, 0xa9, 0xaa, 0x64, 0xb3, 0x83, 0x1a, 0x79,
79 0x47, 0x62, 0x01, 0xda, 0x81, 0xd4, 0x48, 0xac, \
80 0x69, 0x02, 0x72, 0x46, 0x3b, 0x75, 0xb3, 0xac \
84 0x76, 0xc2, 0x51, 0x01, 0x35, 0x27, 0x08, 0x8b, \
85 0xc6, 0x4c, 0x1b, 0xd4, 0x2c, 0x78, 0x8b, 0xac \
87#define hashV1_test1_foobar1 \
89 0x2f, 0xb7, 0x06, 0xe3, 0xf4, 0xf2, 0x74, 0xe7, \
90 0x62, 0xfc, 0x53, 0xcb, 0x57, 0x9a, 0x28, 0x3a \
92#define hashV1_test1_foobar1_domain1 \
94 0xa2, 0xbc, 0x65, 0x8e, 0xda, 0xfc, 0xc2, 0xef, \
95 0xaa, 0x26, 0x41, 0x07, 0xb6, 0x9f, 0x94, 0x5c \
97#define hashV1_test1_foobar1_domain2 \
99 0xcf, 0x76, 0xd4, 0xe0, 0xe7, 0x8d, 0xc7, 0xec, \
100 0x59, 0x48, 0x9f, 0x47, 0xde, 0x52, 0xbd, 0x5c \
102#define hashV1_test2_foobar1 \
104 0x4e, 0xe8, 0xd8, 0xe1, 0xfd, 0x7a, 0x77, 0x2b, \
105 0xe7, 0x7c, 0x06, 0xe3, 0xca, 0x6e, 0x47, 0xb6 \
107#define hashV1_test2_foobar1_domain1 \
109 0x40, 0x74, 0xd1, 0x98, 0x32, 0x38, 0xdb, 0x3f, \
110 0x2d, 0x18, 0x1c, 0xd5, 0x0f, 0xb0, 0x70, 0xd2 \
112#define hashV1_test2_foobar1_domain2 \
114 0x2e, 0x63, 0x11, 0x29, 0x4f, 0x47, 0x3e, 0x87, \
115 0x72, 0x07, 0x36, 0x52, 0x20, 0xb3, 0xbe, 0x46 \
118static const test_case_from_hash_t ntofw2fromhashtests[] = {
119 {
nullptr,
nullptr, { 0 }, { 0 }, FALSE, FALSE },
120 {
"foobar1",
nullptr, hashV1_test1, { 0 }, TRUE, FALSE },
121 {
"foobar1",
nullptr, hashV1_test2, hashV1_test1_foobar1, TRUE, FALSE },
122 {
"foobar1",
nullptr, hashV1_test1, hashV1_test1_foobar1, TRUE, TRUE },
123 {
"foobar2",
nullptr, hashV1_test1, hashV1_test1_foobar1, TRUE, FALSE },
124 {
"foobar1",
"domain1", hashV1_test1, hashV1_test1_foobar1_domain1, TRUE, TRUE },
125 {
"foobar1",
"domain2", hashV1_test1, hashV1_test1_foobar1_domain1, TRUE, FALSE },
126 {
"foobar1",
"domain2", hashV1_test1, hashV1_test1_foobar1_domain2, TRUE, TRUE },
127 {
"foobar1",
nullptr, hashV1_test2, { 0 }, TRUE, FALSE },
128 {
"foobar1",
nullptr, hashV1_test1, hashV1_test2_foobar1, TRUE, FALSE },
129 {
"foobar1",
nullptr, hashV1_test2, hashV1_test2_foobar1, TRUE, TRUE },
130 {
"foobar2",
nullptr, hashV1_test2, hashV1_test2_foobar1, TRUE, FALSE },
131 {
"foobar1",
"domain1", hashV1_test2, hashV1_test2_foobar1_domain1, TRUE, TRUE },
132 {
"foobar1",
"domain2", hashV1_test2, hashV1_test2_foobar1_domain1, TRUE, FALSE },
133 {
"foobar1",
"domain2", hashV1_test2, hashV1_test2_foobar1_domain2, TRUE, TRUE }
136static BOOL testNTOWF1(
size_t x,
const test_case_ntowf1_t* test)
140 BYTE hashA[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
141 BYTE hashW[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
144 pwdlen = strlen(test->password);
146 const BOOL rcA = NTOWFv1A(test->password, pwdlen, hashA);
148 WCHAR* passwordW =
nullptr;
151 passwordW = ConvertUtf8NToWCharAlloc(test->password, pwdlen, &pwdwlen);
152 const BOOL rcW = NTOWFv1W(passwordW, pwdwlen *
sizeof(WCHAR), hashW);
155 winpr_HexDump(
"NTOWFv1A", WLOG_INFO, hashA,
sizeof(hashA));
156 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
157 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcA, test->result);
159 winpr_HexDump(
"NTOWFv1W", WLOG_INFO, hashW,
sizeof(hashW));
160 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
161 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcW, test->result);
163 if (rcA != test->result)
166 if (memcmp(test->expected, hashA,
sizeof(test->expected)) != 0)
168 if (test->shouldMatch)
172 if (rcW != test->result)
175 if (memcmp(test->expected, hashW,
sizeof(test->expected)) != 0)
177 if (test->shouldMatch)
183static BOOL testNTOWF2(
size_t x,
const test_case_ntowf2_t* test)
187 BYTE hashA[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
188 BYTE hashW[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
192 pwdlen = strlen(test->password);
196 userlen = strlen(test->user);
198 size_t domainlen = 0;
200 domainlen = strlen(test->domain);
203 NTOWFv2A(test->password, pwdlen, test->user, userlen, test->domain, domainlen, hashA);
205 WCHAR* passwordW =
nullptr;
208 passwordW = ConvertUtf8NToWCharAlloc(test->password, pwdlen, &pwdwlen);
210 WCHAR* userW =
nullptr;
213 userW = ConvertUtf8NToWCharAlloc(test->user, userlen, &userwlen);
215 WCHAR* domainW =
nullptr;
216 size_t domainwlen = 0;
218 domainW = ConvertUtf8NToWCharAlloc(test->domain, domainlen, &domainwlen);
220 const BOOL rcW = NTOWFv2W(passwordW, pwdwlen *
sizeof(WCHAR), userW, userwlen *
sizeof(WCHAR),
221 domainW, domainlen *
sizeof(WCHAR), hashW);
226 winpr_HexDump(
"NTOWFv2A", WLOG_INFO, hashA,
sizeof(hashA));
227 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
228 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcA, test->result);
230 winpr_HexDump(
"NTOWFv2W", WLOG_INFO, hashW,
sizeof(hashW));
231 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
232 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcW, test->result);
234 if (rcA != test->result)
236 if (memcmp(test->expected, hashA,
sizeof(test->expected)) != 0)
238 if (test->shouldMatch)
242 if (rcW != test->result)
244 if (memcmp(test->expected, hashW,
sizeof(test->expected)) != 0)
246 if (test->shouldMatch)
252static BOOL testNTOWFv2FromHash(
size_t x,
const test_case_from_hash_t* test)
256 BYTE hashA[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
257 BYTE hashW[
sizeof(test->expected)] = WINPR_C_ARRAY_INIT;
261 userlen = strlen(test->user);
263 size_t domainlen = 0;
265 domainlen = strlen(test->domain);
268 NTOWFv2FromHashA(test->passwordhash, test->user, userlen, test->domain, domainlen, hashA);
270 WCHAR* userW =
nullptr;
273 userW = ConvertUtf8NToWCharAlloc(test->user, userlen, &userwlen);
275 WCHAR* domainW =
nullptr;
276 size_t domainwlen = 0;
278 domainW = ConvertUtf8NToWCharAlloc(test->domain, domainlen, &domainwlen);
280 const BOOL rcW = NTOWFv2FromHashW(test->passwordhash, userW, userwlen *
sizeof(WCHAR), domainW,
281 domainwlen *
sizeof(WCHAR), hashW);
286 winpr_HexDump(
"NTOWFv2A", WLOG_INFO, hashA,
sizeof(hashA));
287 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
288 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcA, test->result);
290 winpr_HexDump(
"NTOWFv2W", WLOG_INFO, hashW,
sizeof(hashW));
291 winpr_HexDump(
"expect", WLOG_INFO, test->expected,
sizeof(test->expected));
292 WLog_INFO(
"result",
"[%" PRIuz
"] got %d, expected %d", x, rcW, test->result);
294 if (rcA != test->result)
296 if (memcmp(test->expected, hashA,
sizeof(test->expected)) != 0)
298 if (test->shouldMatch)
302 if (rcW != test->result)
304 if (memcmp(test->expected, hashW,
sizeof(test->expected)) != 0)
306 if (test->shouldMatch)
312int TestNTLM(WINPR_ATTR_UNUSED
int argc, WINPR_ATTR_UNUSED
char* argv[])
314 for (
size_t x = 0; x < ARRAYSIZE(ntofw1tests); x++)
316 const test_case_ntowf1_t* cur = &ntofw1tests[x];
317 if (!testNTOWF1(x, cur))
319 WLog_WARN(
"testNTOWF1",
"[%" PRIuz
"] test failed", x);
323 for (
size_t x = 0; x < ARRAYSIZE(ntofw2tests); x++)
325 const test_case_ntowf2_t* cur = &ntofw2tests[x];
326 if (!testNTOWF2(x, cur))
328 WLog_WARN(
"testNTOWF2",
"[%" PRIuz
"] test failed", x);
332 for (
size_t x = 0; x < ARRAYSIZE(ntofw2fromhashtests); x++)
334 const test_case_from_hash_t* cur = &ntofw2fromhashtests[x];
335 if (!testNTOWFv2FromHash(x, cur))
337 WLog_WARN(
"testNTOWFv2FromHash",
"[%" PRIuz
"] test failed", x);