3#include <winpr/assert.h>
5#include <winpr/print.h>
32 LPTSTR ServicePrincipalName;
37 SecPkgInfo* pPackageInfo;
38 SecurityFunctionTable* table;
39 SEC_WINNT_AUTH_IDENTITY identity;
42static BYTE TEST_NTLM_TIMESTAMP[8] = { 0x33, 0x57, 0xbd, 0xb1, 0x07, 0x8b, 0xcf, 0x01 };
44static BYTE TEST_NTLM_CLIENT_CHALLENGE[8] = { 0x20, 0xc0, 0x2b, 0x3d, 0xc0, 0x61, 0xa7, 0x73 };
46static BYTE TEST_NTLM_SERVER_CHALLENGE[8] = { 0xa4, 0xf1, 0xba, 0xa6, 0x7c, 0xdc, 0x1a, 0x12 };
48static BYTE TEST_NTLM_NEGOTIATE[] =
49 "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x01\x00\x00\x00\x07\x82\x08\xa2"
50 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
51 "\x06\x03\x80\x25\x00\x00\x00\x0f";
53static BYTE TEST_NTLM_CHALLENGE[] =
54 "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x02\x00\x00\x00\x00\x00\x00\x00"
55 "\x38\x00\x00\x00\x07\x82\x88\xa2\xa4\xf1\xba\xa6\x7c\xdc\x1a\x12"
56 "\x00\x00\x00\x00\x00\x00\x00\x00\x66\x00\x66\x00\x38\x00\x00\x00"
57 "\x06\x03\x80\x25\x00\x00\x00\x0f\x02\x00\x0e\x00\x4e\x00\x45\x00"
58 "\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x01\x00\x0e\x00\x4e\x00"
59 "\x45\x00\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x04\x00\x1c\x00"
60 "\x6c\x00\x61\x00\x62\x00\x2e\x00\x77\x00\x61\x00\x79\x00\x6b\x00"
61 "\x2e\x00\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x03\x00\x0e\x00"
62 "\x6e\x00\x65\x00\x77\x00\x79\x00\x65\x00\x61\x00\x72\x00\x07\x00"
63 "\x08\x00\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x00\x00\x00\x00";
65static BYTE TEST_NTLM_AUTHENTICATE[] =
66 "\x4e\x54\x4c\x4d\x53\x53\x50\x00\x03\x00\x00\x00\x18\x00\x18\x00"
67 "\x82\x00\x00\x00\x08\x01\x08\x01\x9a\x00\x00\x00\x0c\x00\x0c\x00"
68 "\x58\x00\x00\x00\x10\x00\x10\x00\x64\x00\x00\x00\x0e\x00\x0e\x00"
69 "\x74\x00\x00\x00\x00\x00\x00\x00\xa2\x01\x00\x00\x05\x82\x88\xa2"
70 "\x06\x03\x80\x25\x00\x00\x00\x0f\x12\xe5\x5a\xf5\x80\xee\x3f\x29"
71 "\xe1\xde\x90\x4d\x73\x77\x06\x25\x44\x00\x6f\x00\x6d\x00\x61\x00"
72 "\x69\x00\x6e\x00\x55\x00\x73\x00\x65\x00\x72\x00\x6e\x00\x61\x00"
73 "\x6d\x00\x65\x00\x4e\x00\x45\x00\x57\x00\x59\x00\x45\x00\x41\x00"
74 "\x52\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
75 "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x62\x14\x68\xc8\x98\x12"
76 "\xe7\x39\xd8\x76\x1b\xe9\xf7\x54\xb5\xe3\x01\x01\x00\x00\x00\x00"
77 "\x00\x00\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x20\xc0\x2b\x3d\xc0\x61"
78 "\xa7\x73\x00\x00\x00\x00\x02\x00\x0e\x00\x4e\x00\x45\x00\x57\x00"
79 "\x59\x00\x45\x00\x41\x00\x52\x00\x01\x00\x0e\x00\x4e\x00\x45\x00"
80 "\x57\x00\x59\x00\x45\x00\x41\x00\x52\x00\x04\x00\x1c\x00\x6c\x00"
81 "\x61\x00\x62\x00\x2e\x00\x77\x00\x61\x00\x79\x00\x6b\x00\x2e\x00"
82 "\x6c\x00\x6f\x00\x63\x00\x61\x00\x6c\x00\x03\x00\x0e\x00\x6e\x00"
83 "\x65\x00\x77\x00\x79\x00\x65\x00\x61\x00\x72\x00\x07\x00\x08\x00"
84 "\x33\x57\xbd\xb1\x07\x8b\xcf\x01\x06\x00\x04\x00\x02\x00\x00\x00"
85 "\x08\x00\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00"
86 "\x00\x20\x00\x00\x1e\x10\xf5\x2c\x54\x2f\x2e\x77\x1c\x13\xbf\xc3"
87 "\x3f\xe1\x7b\x28\x7e\x0b\x93\x5a\x39\xd2\xce\x12\xd7\xbd\x8c\x4e"
88 "\x2b\xb5\x0b\xf5\x0a\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00"
89 "\x00\x00\x00\x00\x00\x00\x00\x00\x09\x00\x1a\x00\x48\x00\x54\x00"
90 "\x54\x00\x50\x00\x2f\x00\x72\x00\x77\x00\x2e\x00\x6c\x00\x6f\x00"
91 "\x63\x00\x61\x00\x6c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
94#define TEST_SSPI_INTERFACE SSPI_INTERFACE_WINPR
96static const char* TEST_NTLM_USER =
"Username";
97static const char* TEST_NTLM_DOMAIN =
"Domain";
98static const char* TEST_NTLM_PASSWORD =
"P4ss123!";
102static const BYTE TEST_NTLM_HASH[16] = { 0xd5, 0x92, 0x2a, 0x65, 0xc4, 0xd5, 0xc0, 0x82,
103 0xca, 0x44, 0x4a, 0xf1, 0xbe, 0x00, 0x01, 0xdb };
107static const BYTE TEST_NTLM_V2_HASH[16] = { 0x4c, 0x7f, 0x70, 0x6f, 0x7d, 0xde, 0x05, 0xa9,
108 0xd1, 0xa0, 0xf4, 0xe7, 0xff, 0xe3, 0xbf, 0xb8 };
110static const BYTE TEST_EMPTY_PWD_NTLM_HASH[] = { 0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31,
111 0xb7, 0x3c, 0x59, 0xd7, 0xe0, 0xc0, 0x89, 0xc0 };
113static const BYTE TEST_EMPTY_PWD_NTLM_V2_HASH[] = {
114 0x0b, 0xce, 0x54, 0x87, 0x4e, 0x94, 0x20, 0x9e, 0x34, 0x48, 0x97, 0xc1, 0x60, 0x03, 0x6e, 0x3b
117#define NTLM_PACKAGE_NAME NTLM_SSP_NAME
130 BOOL haveInputBuffer;
131 LPTSTR ServicePrincipalName;
135 BOOL confidentiality;
136 SecPkgInfo* pPackageInfo;
137 SecurityFunctionTable* table;
138 SEC_WINNT_AUTH_IDENTITY identity;
141static int test_ntlm_client_init(TEST_NTLM_CLIENT* ntlm,
const char* user,
const char* domain,
142 const char* password)
144 SECURITY_STATUS status = SEC_E_INTERNAL_ERROR;
148 SecInvalidateHandle(&(ntlm->context));
149 ntlm->table = InitSecurityInterfaceEx(TEST_SSPI_INTERFACE);
152 const int rc = sspi_SetAuthIdentity(&(ntlm->identity), user, domain, password);
156 status = ntlm->table->QuerySecurityPackageInfo(NTLM_PACKAGE_NAME, &ntlm->pPackageInfo);
158 if (status != SEC_E_OK)
160 (void)fprintf(stderr,
"QuerySecurityPackageInfo status: %s (0x%08" PRIX32
")\n",
161 GetSecurityStatusString(status), status);
165 ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
166 status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME, SECPKG_CRED_OUTBOUND,
167 NULL, &ntlm->identity, NULL, NULL,
168 &ntlm->credentials, &ntlm->expiration);
170 if (status != SEC_E_OK)
172 (void)fprintf(stderr,
"AcquireCredentialsHandle status: %s (0x%08" PRIX32
")\n",
173 GetSecurityStatusString(status), status);
177 ntlm->haveContext = FALSE;
178 ntlm->haveInputBuffer = FALSE;
179 ZeroMemory(&ntlm->inputBuffer,
sizeof(
SecBuffer));
180 ZeroMemory(&ntlm->outputBuffer,
sizeof(
SecBuffer));
181 ntlm->fContextReq = 0;
184 ntlm->fContextReq |= ISC_REQ_MUTUAL_AUTH;
185 ntlm->fContextReq |= ISC_REQ_CONFIDENTIALITY;
186 ntlm->fContextReq |= ISC_REQ_USE_SESSION_KEY;
190static void test_ntlm_client_uninit(TEST_NTLM_CLIENT* ntlm)
195 if (ntlm->outputBuffer[0].pvBuffer)
197 free(ntlm->outputBuffer[0].pvBuffer);
198 ntlm->outputBuffer[0].pvBuffer = NULL;
201 free(ntlm->identity.User);
202 free(ntlm->identity.Domain);
203 free(ntlm->identity.Password);
204 free(ntlm->ServicePrincipalName);
208 SECURITY_STATUS status = ntlm->table->FreeCredentialsHandle(&ntlm->credentials);
209 WINPR_ASSERT((status == SEC_E_OK) || (status == SEC_E_SECPKG_NOT_FOUND) ||
210 (status == SEC_E_UNSUPPORTED_FUNCTION));
212 status = ntlm->table->FreeContextBuffer(ntlm->pPackageInfo);
213 WINPR_ASSERT((status == SEC_E_OK) || (status = SEC_E_INVALID_HANDLE));
215 status = ntlm->table->DeleteSecurityContext(&ntlm->context);
216 WINPR_ASSERT((status == SEC_E_OK) || (status == SEC_E_SECPKG_NOT_FOUND) ||
217 (status == SEC_E_UNSUPPORTED_FUNCTION));
258static BOOL IsSecurityStatusError(SECURITY_STATUS status)
265 case SEC_I_CONTINUE_NEEDED:
266 case SEC_I_COMPLETE_NEEDED:
267 case SEC_I_COMPLETE_AND_CONTINUE:
268 case SEC_I_LOCAL_LOGON:
269 case SEC_I_CONTEXT_EXPIRED:
270 case SEC_I_INCOMPLETE_CREDENTIALS:
271 case SEC_I_RENEGOTIATE:
272 case SEC_I_NO_LSA_CONTEXT:
273 case SEC_I_SIGNATURE_NEEDED:
274 case SEC_I_NO_RENEGOTIATION:
284static int test_ntlm_client_authenticate(TEST_NTLM_CLIENT* ntlm)
286 SECURITY_STATUS status = SEC_E_INTERNAL_ERROR;
289 if (ntlm->outputBuffer[0].pvBuffer)
291 free(ntlm->outputBuffer[0].pvBuffer);
292 ntlm->outputBuffer[0].pvBuffer = NULL;
295 ntlm->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
296 ntlm->outputBufferDesc.cBuffers = 1;
297 ntlm->outputBufferDesc.pBuffers = ntlm->outputBuffer;
298 ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN;
299 ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken;
300 ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer);
302 if (!ntlm->outputBuffer[0].pvBuffer)
305 if (ntlm->haveInputBuffer)
307 ntlm->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
308 ntlm->inputBufferDesc.cBuffers = 1;
309 ntlm->inputBufferDesc.pBuffers = ntlm->inputBuffer;
310 ntlm->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
313 if ((!ntlm) || (!ntlm->table))
315 (void)fprintf(stderr,
"ntlm_authenticate: invalid ntlm context\n");
319 status = ntlm->table->InitializeSecurityContext(
320 &ntlm->credentials, (ntlm->haveContext) ? &ntlm->context : NULL,
321 (ntlm->ServicePrincipalName) ? ntlm->ServicePrincipalName : NULL, ntlm->fContextReq, 0,
322 SECURITY_NATIVE_DREP, (ntlm->haveInputBuffer) ? &ntlm->inputBufferDesc : NULL, 0,
323 &ntlm->context, &ntlm->outputBufferDesc, &ntlm->pfContextAttr, &ntlm->expiration);
325 if (IsSecurityStatusError(status))
328 if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED))
330 if (ntlm->table->CompleteAuthToken)
333 ntlm->table->CompleteAuthToken(&ntlm->context, &ntlm->outputBufferDesc);
338 if (status == SEC_I_COMPLETE_NEEDED)
340 else if (status == SEC_I_COMPLETE_AND_CONTINUE)
341 status = SEC_I_CONTINUE_NEEDED;
344 if (ntlm->haveInputBuffer)
346 free(ntlm->inputBuffer[0].pvBuffer);
349 ntlm->haveInputBuffer = TRUE;
350 ntlm->haveContext = TRUE;
351 return (status == SEC_I_CONTINUE_NEEDED) ? 1 : 0;
354static TEST_NTLM_CLIENT* test_ntlm_client_new(
void)
356 TEST_NTLM_CLIENT* ntlm = (TEST_NTLM_CLIENT*)calloc(1,
sizeof(TEST_NTLM_CLIENT));
364static void test_ntlm_client_free(TEST_NTLM_CLIENT* ntlm)
369 test_ntlm_client_uninit(ntlm);
373static int test_ntlm_server_init(TEST_NTLM_SERVER* ntlm)
375 SECURITY_STATUS status = SEC_E_INTERNAL_ERROR;
379 ntlm->UseNtlmV2Hash = TRUE;
380 SecInvalidateHandle(&(ntlm->context));
381 ntlm->table = InitSecurityInterfaceEx(TEST_SSPI_INTERFACE);
383 return SEC_E_INTERNAL_ERROR;
385 status = ntlm->table->QuerySecurityPackageInfo(NTLM_PACKAGE_NAME, &ntlm->pPackageInfo);
387 if (status != SEC_E_OK)
389 (void)fprintf(stderr,
"QuerySecurityPackageInfo status: %s (0x%08" PRIX32
")\n",
390 GetSecurityStatusString(status), status);
394 ntlm->cbMaxToken = ntlm->pPackageInfo->cbMaxToken;
395 status = ntlm->table->AcquireCredentialsHandle(NULL, NTLM_PACKAGE_NAME, SECPKG_CRED_INBOUND,
396 NULL, NULL, NULL, NULL, &ntlm->credentials,
399 if (status != SEC_E_OK)
401 (void)fprintf(stderr,
"AcquireCredentialsHandle status: %s (0x%08" PRIX32
")\n",
402 GetSecurityStatusString(status), status);
406 ntlm->haveContext = FALSE;
407 ntlm->haveInputBuffer = FALSE;
408 ZeroMemory(&ntlm->inputBuffer,
sizeof(
SecBuffer));
409 ZeroMemory(&ntlm->outputBuffer,
sizeof(
SecBuffer));
410 ntlm->fContextReq = 0;
412 ntlm->fContextReq |= ASC_REQ_MUTUAL_AUTH;
413 ntlm->fContextReq |= ASC_REQ_CONFIDENTIALITY;
414 ntlm->fContextReq |= ASC_REQ_CONNECTION;
415 ntlm->fContextReq |= ASC_REQ_USE_SESSION_KEY;
416 ntlm->fContextReq |= ASC_REQ_REPLAY_DETECT;
417 ntlm->fContextReq |= ASC_REQ_SEQUENCE_DETECT;
418 ntlm->fContextReq |= ASC_REQ_EXTENDED_ERROR;
422static void test_ntlm_server_uninit(TEST_NTLM_SERVER* ntlm)
427 if (ntlm->outputBuffer[0].pvBuffer)
429 free(ntlm->outputBuffer[0].pvBuffer);
430 ntlm->outputBuffer[0].pvBuffer = NULL;
433 free(ntlm->identity.User);
434 free(ntlm->identity.Domain);
435 free(ntlm->identity.Password);
436 free(ntlm->ServicePrincipalName);
440 SECURITY_STATUS status = ntlm->table->FreeCredentialsHandle(&ntlm->credentials);
441 WINPR_ASSERT(status == SEC_E_OK);
442 status = ntlm->table->FreeContextBuffer(ntlm->pPackageInfo);
443 WINPR_ASSERT(status == SEC_E_OK);
444 status = ntlm->table->DeleteSecurityContext(&ntlm->context);
445 WINPR_ASSERT(status == SEC_E_OK);
449static int test_ntlm_server_authenticate(
const struct test_input_t* targ, TEST_NTLM_SERVER* ntlm)
451 SECURITY_STATUS status = SEC_E_INTERNAL_ERROR;
456 ntlm->inputBufferDesc.ulVersion = SECBUFFER_VERSION;
457 ntlm->inputBufferDesc.cBuffers = 1;
458 ntlm->inputBufferDesc.pBuffers = ntlm->inputBuffer;
459 ntlm->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
460 ntlm->outputBufferDesc.ulVersion = SECBUFFER_VERSION;
461 ntlm->outputBufferDesc.cBuffers = 1;
462 ntlm->outputBufferDesc.pBuffers = &ntlm->outputBuffer[0];
463 ntlm->outputBuffer[0].BufferType = SECBUFFER_TOKEN;
464 ntlm->outputBuffer[0].cbBuffer = ntlm->cbMaxToken;
465 ntlm->outputBuffer[0].pvBuffer = malloc(ntlm->outputBuffer[0].cbBuffer);
467 if (!ntlm->outputBuffer[0].pvBuffer)
470 status = ntlm->table->AcceptSecurityContext(
471 &ntlm->credentials, ntlm->haveContext ? &ntlm->context : NULL, &ntlm->inputBufferDesc,
472 ntlm->fContextReq, SECURITY_NATIVE_DREP, &ntlm->context, &ntlm->outputBufferDesc,
473 &ntlm->pfContextAttr, &ntlm->expiration);
475 if (status == SEC_I_CONTINUE_NEEDED)
479 if (ntlm->UseNtlmV2Hash)
481 AuthNtlmHash.Version = 2;
482 CopyMemory(AuthNtlmHash.NtlmHash, targ->ntlmv2, 16);
486 AuthNtlmHash.Version = 1;
487 CopyMemory(AuthNtlmHash.NtlmHash, targ->ntlm, 16);
491 ntlm->table->SetContextAttributes(&ntlm->context, SECPKG_ATTR_AUTH_NTLM_HASH,
495 if ((status != SEC_E_OK) && (status != SEC_I_CONTINUE_NEEDED))
497 (void)fprintf(stderr,
"AcceptSecurityContext status: %s (0x%08" PRIX32
")\n",
498 GetSecurityStatusString(status), status);
502 ntlm->haveContext = TRUE;
503 return (status == SEC_I_CONTINUE_NEEDED) ? 1 : 0;
506static TEST_NTLM_SERVER* test_ntlm_server_new(
void)
508 TEST_NTLM_SERVER* ntlm = (TEST_NTLM_SERVER*)calloc(1,
sizeof(TEST_NTLM_SERVER));
516static void test_ntlm_server_free(TEST_NTLM_SERVER* ntlm)
521 test_ntlm_server_uninit(ntlm);
525static BOOL test_default(
const struct test_input_t* arg)
532 printf(
"testcase {user=%s, domain=%s, password=%s, dynamic=%s}\n", arg->user, arg->domain,
533 arg->pwd, arg->dynamic ?
"TRUE" :
"FALSE");
538 TEST_NTLM_CLIENT* client = test_ntlm_client_new();
539 TEST_NTLM_SERVER* server = test_ntlm_server_new();
541 if (!client || !server)
543 printf(
"Memory allocation failed\n");
547 int status = test_ntlm_client_init(client, arg->user, arg->domain, arg->pwd);
551 printf(
"test_ntlm_client_init failure\n");
559 status = test_ntlm_server_init(server);
563 printf(
"test_ntlm_server_init failure\n");
570 status = test_ntlm_client_authenticate(client);
574 printf(
"test_ntlm_client_authenticate failure\n");
583 CopyMemory(AuthNtlmTimestamp.Timestamp, TEST_NTLM_TIMESTAMP, 8);
584 AuthNtlmTimestamp.ChallengeOrResponse = TRUE;
585 SECURITY_STATUS rc = client->table->SetContextAttributes(
586 &client->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP, &AuthNtlmTimestamp,
588 WINPR_ASSERT((rc == SEC_E_OK) || (rc == SEC_E_SECPKG_NOT_FOUND));
590 AuthNtlmTimestamp.ChallengeOrResponse = FALSE;
591 rc = client->table->SetContextAttributes(&client->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
594 WINPR_ASSERT((rc == SEC_E_OK) || (rc == SEC_E_SECPKG_NOT_FOUND));
596 CopyMemory(AuthNtlmClientChallenge.ClientChallenge, TEST_NTLM_CLIENT_CHALLENGE, 8);
597 CopyMemory(AuthNtlmServerChallenge.ServerChallenge, TEST_NTLM_SERVER_CHALLENGE, 8);
598 rc = client->table->SetContextAttributes(
599 &client->context, SECPKG_ATTR_AUTH_NTLM_CLIENT_CHALLENGE, &AuthNtlmClientChallenge,
601 WINPR_ASSERT((rc == SEC_E_OK) || (rc == SEC_E_SECPKG_NOT_FOUND));
603 rc = client->table->SetContextAttributes(
604 &client->context, SECPKG_ATTR_AUTH_NTLM_SERVER_CHALLENGE, &AuthNtlmServerChallenge,
606 WINPR_ASSERT((rc == SEC_E_OK) || (rc == SEC_E_SECPKG_NOT_FOUND));
609 pSecBuffer = &(client->outputBuffer[0]);
613 pSecBuffer->cbBuffer =
sizeof(TEST_NTLM_NEGOTIATE) - 1;
614 free(pSecBuffer->pvBuffer);
615 pSecBuffer->pvBuffer = malloc(pSecBuffer->cbBuffer);
617 if (!pSecBuffer->pvBuffer)
619 printf(
"Memory allocation failed\n");
623 CopyMemory(pSecBuffer->pvBuffer, TEST_NTLM_NEGOTIATE, pSecBuffer->cbBuffer);
626 (void)fprintf(stderr,
"NTLM_NEGOTIATE (length = %" PRIu32
"):\n", pSecBuffer->cbBuffer);
627 winpr_HexDump(
"sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
632 server->haveInputBuffer = TRUE;
633 server->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
634 server->inputBuffer[0].pvBuffer = pSecBuffer->pvBuffer;
635 server->inputBuffer[0].cbBuffer = pSecBuffer->cbBuffer;
636 status = test_ntlm_server_authenticate(arg, server);
640 printf(
"test_ntlm_server_authenticate failure\n");
649 CopyMemory(AuthNtlmTimestamp.Timestamp, TEST_NTLM_TIMESTAMP, 8);
650 AuthNtlmTimestamp.ChallengeOrResponse = TRUE;
651 SECURITY_STATUS rc = client->table->SetContextAttributes(
652 &server->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP, &AuthNtlmTimestamp,
654 WINPR_ASSERT(rc == SEC_E_OK);
656 AuthNtlmTimestamp.ChallengeOrResponse = FALSE;
657 rc = client->table->SetContextAttributes(&server->context, SECPKG_ATTR_AUTH_NTLM_TIMESTAMP,
660 WINPR_ASSERT(rc == SEC_E_OK);
662 CopyMemory(AuthNtlmClientChallenge.ClientChallenge, TEST_NTLM_CLIENT_CHALLENGE, 8);
663 CopyMemory(AuthNtlmServerChallenge.ServerChallenge, TEST_NTLM_SERVER_CHALLENGE, 8);
664 rc = server->table->SetContextAttributes(
665 &server->context, SECPKG_ATTR_AUTH_NTLM_CLIENT_CHALLENGE, &AuthNtlmClientChallenge,
667 WINPR_ASSERT(rc == SEC_E_OK);
669 rc = server->table->SetContextAttributes(
670 &server->context, SECPKG_ATTR_AUTH_NTLM_SERVER_CHALLENGE, &AuthNtlmServerChallenge,
672 WINPR_ASSERT(rc == SEC_E_OK);
675 pSecBuffer = &(server->outputBuffer[0]);
680 pSecBuffer->cbBuffer =
sizeof(TEST_NTLM_CHALLENGE) - 1;
681 free(pSecBuffer->pvBuffer);
682 pSecBuffer->pvBuffer = malloc(pSecBuffer->cbBuffer);
684 if (!pSecBuffer->pvBuffer)
686 printf(
"Memory allocation failed\n");
690 CopyMemory(pSecBuffer->pvBuffer, TEST_NTLM_CHALLENGE, pSecBuffer->cbBuffer);
691 AuthNtlmMessage.type = 2;
692 AuthNtlmMessage.length = pSecBuffer->cbBuffer;
693 AuthNtlmMessage.buffer = (BYTE*)pSecBuffer->pvBuffer;
694 SECURITY_STATUS rc = server->table->SetContextAttributes(
695 &server->context, SECPKG_ATTR_AUTH_NTLM_MESSAGE, &AuthNtlmMessage,
701 (void)fprintf(stderr,
"NTLM_CHALLENGE (length = %" PRIu32
"):\n", pSecBuffer->cbBuffer);
702 winpr_HexDump(
"sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
707 client->haveInputBuffer = TRUE;
708 client->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
709 client->inputBuffer[0].pvBuffer = pSecBuffer->pvBuffer;
710 client->inputBuffer[0].cbBuffer = pSecBuffer->cbBuffer;
711 status = test_ntlm_client_authenticate(client);
715 printf(
"test_ntlm_client_authenticate failure\n");
719 pSecBuffer = &(client->outputBuffer[0]);
723 pSecBuffer->cbBuffer =
sizeof(TEST_NTLM_AUTHENTICATE) - 1;
724 free(pSecBuffer->pvBuffer);
725 pSecBuffer->pvBuffer = malloc(pSecBuffer->cbBuffer);
727 if (!pSecBuffer->pvBuffer)
729 printf(
"Memory allocation failed\n");
733 CopyMemory(pSecBuffer->pvBuffer, TEST_NTLM_AUTHENTICATE, pSecBuffer->cbBuffer);
736 (void)fprintf(stderr,
"NTLM_AUTHENTICATE (length = %" PRIu32
"):\n", pSecBuffer->cbBuffer);
737 winpr_HexDump(
"sspi.test", WLOG_DEBUG, (BYTE*)pSecBuffer->pvBuffer, pSecBuffer->cbBuffer);
741 server->haveInputBuffer = TRUE;
742 server->inputBuffer[0].BufferType = SECBUFFER_TOKEN;
743 server->inputBuffer[0].pvBuffer = pSecBuffer->pvBuffer;
744 server->inputBuffer[0].cbBuffer = pSecBuffer->cbBuffer;
745 status = test_ntlm_server_authenticate(arg, server);
749 printf(
"test_ntlm_server_authenticate failure\n");
759 test_ntlm_client_free(client);
760 test_ntlm_server_free(server);
762 printf(
"testcase {user=%s, domain=%s, password=%s, dynamic=%s} returns %d\n", arg->user,
763 arg->domain, arg->pwd, arg->dynamic ?
"TRUE" :
"FALSE", rc);
767int TestNTLM(
int argc,
char* argv[])
772 const struct test_input_t inputs[] = {
773 { TEST_NTLM_USER, TEST_NTLM_DOMAIN, TEST_NTLM_PASSWORD, TEST_NTLM_HASH, TEST_NTLM_V2_HASH,
775 { TEST_NTLM_USER, TEST_NTLM_DOMAIN, TEST_NTLM_PASSWORD, TEST_NTLM_HASH, TEST_NTLM_V2_HASH,
777 { TEST_NTLM_USER, TEST_NTLM_DOMAIN,
"", TEST_EMPTY_PWD_NTLM_HASH,
778 TEST_EMPTY_PWD_NTLM_V2_HASH, TRUE, TRUE },
779 { TEST_NTLM_USER, TEST_NTLM_DOMAIN, NULL, TEST_EMPTY_PWD_NTLM_HASH,
780 TEST_EMPTY_PWD_NTLM_V2_HASH, TRUE, FALSE }
784 for (
size_t x = 0; x < ARRAYSIZE(inputs); x++)
786 const struct test_input_t* cur = &inputs[x];
787 const BOOL res = test_default(cur);
788 if (res != cur->expected)