Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1312 lines
38 KiB

  1. // Test.cpp : Defines the entry point for the console application. This code uses SASL calling convention
  2. //
  3. #include "testglobal.h"
  4. #include <stdio.h> // printf
  5. #include <security.h> // General definition of a Security Support Provider
  6. #define AUTH_USERNAME "test1"
  7. #define AUTH_USERNAME_W L"test1"
  8. #define AUTH_NONCE "9b38dce631309cc25a653ebaad5b18ee01c8bf385260b26db0574a302be4c11367"
  9. #define AUTH_URI_W L"imap/elwood.innosoft.com"
  10. #define AUTH_NC "0000000b"
  11. #define AUTH_NC1 "00000001"
  12. #define AUTH_NC2 "00000002"
  13. #define AUTH_NC3 "00000003"
  14. #define AUTH_NC4 "00000004"
  15. #define AUTHDATA_USERNAME L"test1"
  16. // #define AUTHDATA_DOMAIN L"kdamour2w.damourlan.nttest.microsoft.com"
  17. // #define AUTHDATA_DOMAIN L"damourlan"
  18. #define AUTHDATA_DOMAIN L"damourlan"
  19. #define AUTHDATA_PASSWORD L"test1"
  20. #define STR_BUF_SIZE 4000
  21. char g_czTestPasswd[257];
  22. BOOLEAN QuietMode = FALSE; // Don't be verbose
  23. // Prototypes
  24. void PrintStatus(SECURITY_STATUS NetStatus);
  25. void PrintTime(LPSTR Comment,TimeStamp ConvertTime);
  26. void ISCRETFlags(ULONG ulFlags);
  27. void ASCRETFlags(ULONG ulFlags);
  28. VOID BinToHex(
  29. LPBYTE pSrc,
  30. UINT cSrc,
  31. LPSTR pDst
  32. );
  33. int __cdecl
  34. main(int argc, char* argv[])
  35. {
  36. BOOL bPass = TRUE;
  37. SECURITY_STATUS Status = STATUS_SUCCESS;
  38. char cTemp[STR_BUF_SIZE]; // temp buffer for scratch data
  39. char cTemp2[STR_BUF_SIZE]; // temp buffer for scratch data
  40. char cOutputTemp[STR_BUF_SIZE];
  41. char szOutSecBuf[STR_BUF_SIZE];
  42. char szChallenge[STR_BUF_SIZE];
  43. char szISCChallengeResponse[STR_BUF_SIZE]; // Output buffer from ISC
  44. char szASCChallengeResponse[STR_BUF_SIZE]; // Output buffer from ASC
  45. char szASCResponseAuth[STR_BUF_SIZE]; // Output buffer from ASC
  46. // SSPI Interface tests
  47. ULONG PackageCount = 0;
  48. int i = 0;
  49. PSecPkgInfo pPackageInfo = NULL;
  50. PSecPkgInfo pPackageTmp = NULL;
  51. SECURITY_STATUS TmpStatus = STATUS_SUCCESS;
  52. CredHandle ServerCred;
  53. CredHandle ClientCred;
  54. TimeStamp Lifetime;
  55. BOOL bServerCred = FALSE;
  56. BOOL bClientCred = FALSE;
  57. SecPkgContext_StreamSizes StreamSizes;
  58. ULONG ClientContextReqFlags = ISC_REQ_INTEGRITY | ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION;
  59. ULONG ServerContextReqFlags = ASC_REQ_INTEGRITY | ASC_REQ_CONFIDENTIALITY;
  60. ULONG ClientContextRetFlags = 0;
  61. ULONG ServerContextRetFlags = 0;
  62. ULONG TargetDataRep = 0;
  63. CtxtHandle OldContextHandle;
  64. CtxtHandle ServerCtxtHandle;
  65. CtxtHandle ClientCtxtHandle;
  66. SecBufferDesc InputBuffers;
  67. SecBufferDesc OutputBuffers;
  68. SecBuffer TempTokensIn[6];
  69. SecBuffer TempTokensOut[6];
  70. PCHAR pcPtr = NULL;
  71. int iLen = 0;
  72. UNICODE_STRING ustrUsername;
  73. UNICODE_STRING ustrPassword;
  74. UNICODE_STRING ustrDomain;
  75. STRING strTemp;
  76. STRING strChallenge;
  77. STRING strMethod;
  78. STRING strHEntity;
  79. STRING strOutBuffer;
  80. ULONG ulMessSeqNo = 0;
  81. ULONG ulQOP = 0;
  82. SEC_WINNT_AUTH_IDENTITY_W AuthData;
  83. printf("Begining TESTC...\n");
  84. ZeroMemory(&ClientCred, sizeof(CredHandle));
  85. ZeroMemory(&ServerCred, sizeof(CredHandle));
  86. ZeroMemory(&OldContextHandle, sizeof(CtxtHandle));
  87. ZeroMemory(&ServerCtxtHandle, sizeof(CtxtHandle));
  88. ZeroMemory(&ClientCtxtHandle, sizeof(CtxtHandle));
  89. ZeroMemory(&ustrUsername, sizeof(ustrUsername));
  90. ZeroMemory(&ustrPassword, sizeof(ustrPassword));
  91. ZeroMemory(&ustrDomain, sizeof(ustrDomain));
  92. ZeroMemory(&strTemp, sizeof(strTemp));
  93. ZeroMemory(&StreamSizes, sizeof(StreamSizes));
  94. // Pull out any command line args
  95. if (argc > 1)
  96. {
  97. for (i = 1; i < argc; i++)
  98. {
  99. pcPtr = argv[i];
  100. if (*pcPtr == '-')
  101. {
  102. iLen = strlen(pcPtr);
  103. if (iLen >= 2)
  104. {
  105. switch (*(pcPtr + 1))
  106. {
  107. case 'u':
  108. Status = RtlCreateUnicodeStringFromAsciiz(&ustrUsername, (pcPtr + 2));
  109. break;
  110. case 'd':
  111. Status = RtlCreateUnicodeStringFromAsciiz(&ustrDomain, (pcPtr + 2));
  112. break;
  113. case 'p':
  114. Status = RtlCreateUnicodeStringFromAsciiz(&ustrPassword, (pcPtr + 2));
  115. break;
  116. case '?':
  117. default:
  118. printf("Usage: %s -uUsername -pPassword -ddomain\n", argv[0]);
  119. return(-1);
  120. break;
  121. }
  122. }
  123. }
  124. }
  125. }
  126. //
  127. // Get info about the security packages.
  128. //
  129. Status = EnumerateSecurityPackages( &PackageCount, &pPackageInfo );
  130. TmpStatus = GetLastError();
  131. if (!NT_SUCCESS(Status)) {
  132. printf( "EnumerateSecurityPackages failed: 0x%x", Status);
  133. PrintStatus( Status );
  134. bPass = FALSE;
  135. goto CleanUp;
  136. }
  137. if ( !QuietMode ) {
  138. printf( "PackageCount: %ld\n", PackageCount );
  139. for ( i= 0; i< (int)PackageCount; i++)
  140. {
  141. pPackageTmp = (pPackageInfo + i);
  142. printf( "Name: %ws Comment: %ws\n", pPackageTmp->Name, pPackageTmp->Comment );
  143. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  144. pPackageTmp->fCapabilities,
  145. pPackageTmp->wVersion,
  146. pPackageTmp->wRPCID,
  147. pPackageTmp->cbMaxToken );
  148. }
  149. }
  150. //
  151. // Get info about the security packages.
  152. //
  153. Status = QuerySecurityPackageInfo( WDIGEST_SP_NAME, &pPackageInfo );
  154. TmpStatus = GetLastError();
  155. if (!NT_SUCCESS(Status)) {
  156. printf( "QuerySecurityPackageInfo failed: " );
  157. PrintStatus( Status );
  158. bPass = FALSE;
  159. goto CleanUp;
  160. }
  161. if ( !QuietMode ) {
  162. printf( "Name: %ws Comment: %ws\n", pPackageInfo->Name, pPackageInfo->Comment );
  163. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  164. pPackageInfo->fCapabilities,
  165. pPackageInfo->wVersion,
  166. pPackageInfo->wRPCID,
  167. pPackageInfo->cbMaxToken );
  168. }
  169. //
  170. // Acquire a credential handle for the server side
  171. //
  172. printf("Server AcquireCredentialHandle\n");
  173. Status = AcquireCredentialsHandle(
  174. NULL, // New principal
  175. WDIGEST_SP_NAME, // Package Name
  176. SECPKG_CRED_INBOUND,
  177. NULL,
  178. NULL,
  179. NULL,
  180. NULL,
  181. &ServerCred,
  182. &Lifetime );
  183. if (!NT_SUCCESS(Status)) {
  184. printf( "AcquireCredentialsHandle failed: ");
  185. printf( "FAILED: AcquireCredentialsHandle failed: status 0x%x\n", Status);
  186. PrintStatus( Status );
  187. bPass = FALSE;
  188. ZeroMemory(&ServerCred, sizeof(CredHandle));
  189. goto CleanUp;
  190. }
  191. bServerCred = TRUE;
  192. //
  193. // Acquire a credential handle for the client side
  194. //
  195. printf("Client AcquireCredentialHandle\n");
  196. if (ustrUsername.Length || ustrPassword.Length || ustrDomain.Length)
  197. {
  198. printf("ACH Using supplied credentials\n");
  199. printf(" Username %wZ Domain %wZ Password %wZ\n",
  200. &ustrUsername, &ustrDomain, &ustrPassword);
  201. ZeroMemory(&AuthData, sizeof(SEC_WINNT_AUTH_IDENTITY_W));
  202. AuthData.Domain = ustrDomain.Buffer;
  203. AuthData.DomainLength = ustrDomain.Length / sizeof(WCHAR);
  204. AuthData.Password = ustrPassword.Buffer;
  205. AuthData.PasswordLength = ustrPassword.Length / sizeof(WCHAR);
  206. AuthData.User = ustrUsername.Buffer;
  207. AuthData.UserLength = ustrUsername.Length / sizeof(WCHAR);
  208. AuthData.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  209. Status = AcquireCredentialsHandle(
  210. NULL, // AUTH_USERNAME_W, // get the creds for user digest
  211. WDIGEST_SP_NAME, // Package Name
  212. SECPKG_CRED_OUTBOUND,
  213. NULL,
  214. &AuthData, // Make NULL not to use any AuthData for cred
  215. NULL,
  216. NULL,
  217. &ClientCred,
  218. &Lifetime );
  219. }
  220. else
  221. {
  222. printf("ACH Using default credentials\n");
  223. Status = AcquireCredentialsHandle(
  224. NULL, // AUTH_USERNAME_W, // get the creds for user digest
  225. WDIGEST_SP_NAME, // Package Name
  226. SECPKG_CRED_OUTBOUND,
  227. NULL,
  228. NULL,
  229. NULL,
  230. NULL,
  231. &ClientCred,
  232. &Lifetime );
  233. }
  234. if (!NT_SUCCESS(Status)) {
  235. printf( "AcquireCredentialsHandle failed: for user %s: ", AUTH_USERNAME);
  236. PrintStatus( Status );
  237. // bPass = FALSE;
  238. // ZeroMemory(&ClientCred, sizeof(CredHandle));
  239. // goto CleanUp;
  240. }
  241. else
  242. bClientCred = TRUE;
  243. if ( !QuietMode ) {
  244. printf( "ClientCred: 0x%lx 0x%lx ",
  245. ClientCred.dwLower, ClientCred.dwUpper );
  246. printf( "ServerCred: 0x%lx 0x%lx ",
  247. ServerCred.dwLower, ServerCred.dwUpper );
  248. PrintTime( "Lifetime: ", Lifetime );
  249. }
  250. // Big time - call Accept with no parameters to get a challenge
  251. StringAllocate(&strChallenge, 0);
  252. StringCharDuplicate(&strMethod, "GET");
  253. StringAllocate(&strHEntity, 0);
  254. StringAllocate(&strOutBuffer, 4000);
  255. ZeroMemory(TempTokensIn, sizeof(TempTokensIn));
  256. ZeroMemory(TempTokensOut, sizeof(TempTokensOut));
  257. ZeroMemory(&InputBuffers, sizeof(SecBufferDesc));
  258. ZeroMemory(&OutputBuffers, sizeof(SecBufferDesc));
  259. // SASL first calls ISC with no-input
  260. InputBuffers.ulVersion = SECBUFFER_VERSION;
  261. InputBuffers.cBuffers = 1;
  262. InputBuffers.pBuffers = TempTokensIn;
  263. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  264. TempTokensIn[0].cbBuffer = 1; // no data passed in
  265. TempTokensIn[0].pvBuffer = cTemp;
  266. OutputBuffers.ulVersion = SECBUFFER_VERSION;
  267. OutputBuffers.cBuffers = 1;
  268. OutputBuffers.pBuffers = TempTokensOut;
  269. TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
  270. TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
  271. TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
  272. Status = InitializeSecurityContext(&ClientCred,
  273. NULL,
  274. AUTH_URI_W,
  275. ClientContextReqFlags,
  276. NULL,
  277. SECURITY_NATIVE_DREP,
  278. NULL, // &InputBuffers, MSDN allows NULL for 1st call
  279. NULL,
  280. &ClientCtxtHandle,
  281. &OutputBuffers,
  282. &ClientContextRetFlags,
  283. &Lifetime);
  284. if (!NT_SUCCESS(Status))
  285. {
  286. printf("InitializeSecurityContext SASL 1st call returned: ");
  287. PrintStatus( Status );
  288. bPass = FALSE;
  289. goto CleanUp;
  290. }
  291. printf("ISC Context Flags Req 0x%lx Ret 0x%lx\n", ClientContextReqFlags, ClientContextRetFlags);
  292. ISCRETFlags(ClientContextRetFlags);
  293. printf("InitializeSecurityContext SASL 1st call Output buffer size %d\n",
  294. TempTokensOut[0].cbBuffer );
  295. InputBuffers.ulVersion = SECBUFFER_VERSION;
  296. InputBuffers.cBuffers = 1;
  297. InputBuffers.pBuffers = TempTokensIn;
  298. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  299. TempTokensIn[0].cbBuffer = strChallenge.Length + 1; // for NULL
  300. TempTokensIn[0].pvBuffer = strChallenge.Buffer;
  301. OutputBuffers.ulVersion = SECBUFFER_VERSION;
  302. OutputBuffers.cBuffers = 1;
  303. OutputBuffers.pBuffers = TempTokensOut;
  304. TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
  305. TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
  306. TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
  307. Status = AcceptSecurityContext(
  308. &ServerCred,
  309. NULL,
  310. &InputBuffers,
  311. ServerContextReqFlags,
  312. TargetDataRep,
  313. &ServerCtxtHandle,
  314. &OutputBuffers,
  315. &ServerContextRetFlags,
  316. &Lifetime);
  317. if (Status != SEC_I_CONTINUE_NEEDED) // Indicates that this is the challenge
  318. {
  319. printf("SpAcceptLsaModeContext FAILED 0x%x\n", Status);
  320. PrintStatus( Status );
  321. bPass = FALSE;
  322. goto CleanUp;
  323. }
  324. ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
  325. ZeroMemory(szChallenge, STR_BUF_SIZE); // contains the output buffer
  326. strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  327. cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  328. strncpy(szChallenge, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  329. szChallenge[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  330. printf("ASC Context Flags Req 0x%lx Ret 0x%lx\n", ServerContextReqFlags, ServerContextRetFlags);
  331. ASCRETFlags(ServerContextRetFlags);
  332. printf("Challenge Output Buffer is:\n%s\n\n", cOutputTemp);
  333. printf("Now call the SSPI InitializeSecCtxt to generate the ChallengeResponse\n");
  334. sprintf(cTemp, "username=\"%s\",%s,uri=\"%S\",nc=%0.8x",
  335. AUTH_USERNAME,
  336. szChallenge,
  337. AUTH_URI_W,
  338. 1);
  339. InputBuffers.ulVersion = SECBUFFER_VERSION;
  340. InputBuffers.cBuffers = 1;
  341. InputBuffers.pBuffers = TempTokensIn;
  342. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  343. TempTokensIn[0].cbBuffer = strlen(cTemp) + 1; // for NULL
  344. TempTokensIn[0].pvBuffer = cTemp;
  345. OutputBuffers.ulVersion = SECBUFFER_VERSION;
  346. OutputBuffers.cBuffers = 1;
  347. OutputBuffers.pBuffers = TempTokensOut;
  348. TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
  349. TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
  350. TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
  351. Status = InitializeSecurityContext(&ClientCred,
  352. &ClientCtxtHandle,
  353. AUTH_URI_W,
  354. ClientContextReqFlags,
  355. NULL,
  356. SECURITY_NATIVE_DREP,
  357. &InputBuffers,
  358. NULL,
  359. &ClientCtxtHandle,
  360. &OutputBuffers,
  361. &ClientContextRetFlags,
  362. &Lifetime);
  363. if (Status != SEC_I_CONTINUE_NEEDED) // Indicates that this is the challengeresponse - wait for mutual auth
  364. {
  365. printf("SpAcceptLsaModeContext FAILED 0x%x\n", Status);
  366. PrintStatus( Status );
  367. bPass = FALSE;
  368. goto CleanUp;
  369. }
  370. printf("InitializeSecurityContext SUCCEEDED with Context Handle (0x%x,0x%x)\n",
  371. ClientCtxtHandle.dwLower, ClientCtxtHandle.dwUpper );
  372. printf("ISC Context Flags Req 0x%lx Ret 0x%lx\n", ClientContextReqFlags, ClientContextRetFlags);
  373. ISCRETFlags(ClientContextRetFlags);
  374. ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
  375. ZeroMemory(szChallenge, STR_BUF_SIZE); // contains the output buffer
  376. strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  377. cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  378. strncpy(szISCChallengeResponse, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  379. szISCChallengeResponse[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  380. printf("ISC: Challenge Response Output Buffer is\n%s\n\n", szISCChallengeResponse);
  381. InputBuffers.ulVersion = SECBUFFER_VERSION;
  382. InputBuffers.cBuffers = 1;
  383. InputBuffers.pBuffers = TempTokensIn;
  384. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  385. TempTokensIn[0].cbBuffer = strlen(cOutputTemp) + 1; // for NULL
  386. TempTokensIn[0].pvBuffer = cOutputTemp;
  387. OutputBuffers.ulVersion = SECBUFFER_VERSION;
  388. OutputBuffers.cBuffers = 1;
  389. OutputBuffers.pBuffers = TempTokensOut;
  390. TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
  391. TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
  392. TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
  393. printf("Calling the AcceptSC with a ChallengeResponse (should talk to the DC)!\n");
  394. Status = AcceptSecurityContext(
  395. &ServerCred,
  396. &ServerCtxtHandle,
  397. &InputBuffers,
  398. ServerContextReqFlags,
  399. TargetDataRep,
  400. &ServerCtxtHandle,
  401. &OutputBuffers,
  402. &ServerContextRetFlags,
  403. &Lifetime);
  404. if (!NT_SUCCESS(Status))
  405. {
  406. printf("AcceptSecurityContext 2nd Call: ");
  407. PrintStatus( Status );
  408. bPass = FALSE;
  409. goto CleanUp;
  410. }
  411. strcpy(szASCChallengeResponse, (char *)InputBuffers.pBuffers[0].pvBuffer);
  412. ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
  413. ZeroMemory(szASCResponseAuth, STR_BUF_SIZE); // contains the output buffer
  414. strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  415. cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  416. strncpy(szASCResponseAuth, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  417. szASCResponseAuth[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  418. printf("ASC has accepted the Challenge Resposne and generated rspauth for mutual auth back to client\n");
  419. printf("ASC Context Flags Req 0x%lx Ret 0x%lx\n", ServerContextReqFlags, ServerContextRetFlags);
  420. ASCRETFlags(ServerContextRetFlags);
  421. printf("ASC: Response Auth Output Buffer is\n%s\n\n", szASCResponseAuth);
  422. printf("Now have a valid Security Context handle from ASC\n\n");
  423. InputBuffers.ulVersion = SECBUFFER_VERSION;
  424. InputBuffers.cBuffers = 1;
  425. InputBuffers.pBuffers = TempTokensIn;
  426. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  427. TempTokensIn[0].cbBuffer = strlen(cOutputTemp) + 1; // for NULL
  428. TempTokensIn[0].pvBuffer = cOutputTemp;
  429. OutputBuffers.ulVersion = SECBUFFER_VERSION;
  430. OutputBuffers.cBuffers = 1;
  431. OutputBuffers.pBuffers = TempTokensOut;
  432. TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
  433. TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
  434. TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
  435. Status = InitializeSecurityContext(&ClientCred,
  436. &ClientCtxtHandle,
  437. AUTH_URI_W,
  438. ClientContextReqFlags,
  439. NULL,
  440. SECURITY_NATIVE_DREP,
  441. &InputBuffers,
  442. NULL,
  443. &ClientCtxtHandle,
  444. &OutputBuffers,
  445. &ClientContextRetFlags,
  446. &Lifetime);
  447. if (!NT_SUCCESS(Status))
  448. {
  449. printf("InitializeSecurityContext on Response Auth FAILED: ");
  450. PrintStatus( Status );
  451. bPass = FALSE;
  452. goto CleanUp;
  453. }
  454. printf("InitializeSecurityContext SUCCEEDED with Context Handle (0x%x,0x%x)\n",
  455. ClientCtxtHandle.dwLower, ClientCtxtHandle.dwUpper );
  456. printf("ISC Context Flags Req 0x%lx Ret 0x%lx\n", ClientContextReqFlags, ClientContextRetFlags);
  457. ISCRETFlags(ClientContextRetFlags);
  458. ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
  459. strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  460. cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  461. printf("\nISC: Mutual auth Output Buffer is\n%s\n\n", cOutputTemp);
  462. printf("Now have a valid Security Context handle from ISC and ASC\n\n");
  463. // Now get some info on the securitycontexts
  464. Status = QueryContextAttributes(&ServerCtxtHandle, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
  465. if (!NT_SUCCESS(Status))
  466. {
  467. printf("FAILED: QueryContextAttributes SECPKG_ATTR_STREAM_SIZES error: status 0x%x\n", Status);
  468. PrintStatus( Status );
  469. }
  470. else
  471. {
  472. printf("Server Context Stream Sizes: MaxBuf %lu Blocksize %lu Trailer %lu\n",
  473. StreamSizes.cbMaximumMessage, StreamSizes.cbBlockSize,
  474. StreamSizes.cbTrailer);
  475. }
  476. Status = QueryContextAttributes(&ClientCtxtHandle, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
  477. if (!NT_SUCCESS(Status))
  478. {
  479. printf("FAILED: QueryContextAttributes SECPKG_ATTR_STREAM_SIZES error: status 0x%x\n", Status);
  480. PrintStatus( Status );
  481. }
  482. else
  483. {
  484. printf("Client Context Stream Sizes: MaxBuf %lu Blocksize %lu Trailer %lu\n",
  485. StreamSizes.cbMaximumMessage, StreamSizes.cbBlockSize,
  486. StreamSizes.cbTrailer);
  487. }
  488. // Now have authenticated connection
  489. // Try MakeSignature and VerifySignature
  490. for (i = 0; i < 9; i++)
  491. {
  492. printf("Loop %d\n", i);
  493. ZeroMemory(cTemp, sizeof(cTemp));
  494. strcpy(cTemp, AUTH_NONCE); // Create message to sign
  495. InputBuffers.ulVersion = SECBUFFER_VERSION;
  496. InputBuffers.cBuffers = 3;
  497. InputBuffers.pBuffers = TempTokensIn;
  498. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  499. TempTokensIn[0].cbBuffer = 0;
  500. TempTokensIn[0].pvBuffer = NULL;
  501. TempTokensIn[1].BufferType = SECBUFFER_DATA; // select some data to sign
  502. TempTokensIn[1].cbBuffer = strlen(AUTH_NONCE) + 1 - i; // for NULL use i to test non-blocksize buffers
  503. TempTokensIn[1].pvBuffer = cTemp;
  504. TempTokensIn[2].BufferType = SECBUFFER_PADDING;
  505. TempTokensIn[2].cbBuffer = STR_BUF_SIZE - TempTokensIn[1].cbBuffer; // for NULL
  506. TempTokensIn[2].pvBuffer = cTemp + TempTokensIn[1].cbBuffer;
  507. if (TempTokensIn[1].cbBuffer)
  508. {
  509. printf("Input Message to process is %d bytes\n", TempTokensIn[1].cbBuffer);
  510. BinToHex((PBYTE)TempTokensIn[1].pvBuffer, TempTokensIn[1].cbBuffer, cTemp2);
  511. printf("Mesage: %s\n", cTemp2);
  512. }
  513. Status = EncryptMessage(&ClientCtxtHandle,
  514. ulQOP,
  515. &InputBuffers,
  516. 0);
  517. if (!NT_SUCCESS(Status))
  518. {
  519. printf("TestCredAPI: EncryptMessage FAILED: ");
  520. PrintStatus( Status );
  521. bPass = FALSE;
  522. goto CleanUp;
  523. }
  524. printf("Processed (sign/seal) Output Buffer for message length is %d\n",
  525. TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer);
  526. if (TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer)
  527. {
  528. printf("Message is %d bytes\n", TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer);
  529. BinToHex((PBYTE)TempTokensIn[1].pvBuffer, TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer, cTemp2);
  530. printf("Mesage: %s\n", cTemp2);
  531. }
  532. // You now send Output buffer to Server - in this case the buffer is szOutSecBuf
  533. printf("Now verify that the 1st message is Authenticate\n");
  534. InputBuffers.ulVersion = SECBUFFER_VERSION;
  535. InputBuffers.cBuffers = 2;
  536. InputBuffers.pBuffers = TempTokensIn;
  537. TempTokensIn[0].BufferType = SECBUFFER_STREAM;
  538. TempTokensIn[0].cbBuffer = TempTokensIn[1].cbBuffer + TempTokensIn[2].cbBuffer;
  539. TempTokensIn[0].pvBuffer = TempTokensIn[1].pvBuffer;
  540. TempTokensIn[1].BufferType = SECBUFFER_DATA; // select some data to sign
  541. TempTokensIn[1].cbBuffer = 0;
  542. TempTokensIn[1].pvBuffer = NULL;
  543. Status = DecryptMessage(&ServerCtxtHandle,
  544. &InputBuffers,
  545. ulMessSeqNo,
  546. &ulQOP);
  547. if (!NT_SUCCESS(Status))
  548. {
  549. printf("TestCredAPI: DecryptMessage 1st Call FAILED :");
  550. PrintStatus( Status );
  551. bPass = FALSE;
  552. goto CleanUp;
  553. }
  554. printf("Now have a authenticated 1st message under context 0x%x\n", ServerCtxtHandle);
  555. printf("Processed (verify/unseal) is %d bytes\n", TempTokensIn[1].cbBuffer);
  556. if (TempTokensIn[1].cbBuffer)
  557. {
  558. BinToHex((PBYTE)TempTokensIn[1].pvBuffer, TempTokensIn[1].cbBuffer, cTemp2);
  559. printf("Mesage: %s\n", cTemp2);
  560. }
  561. }
  562. CleanUp:
  563. printf("Leaving test program\n");
  564. if (pPackageInfo)
  565. {
  566. FreeContextBuffer(pPackageInfo);
  567. }
  568. printf("About to call deletesecuritycontext\n");
  569. //
  570. // Free the security context handle
  571. //
  572. if (ServerCtxtHandle.dwLower || ServerCtxtHandle.dwUpper)
  573. {
  574. Status = DeleteSecurityContext(&ServerCtxtHandle);
  575. if (!NT_SUCCESS(Status))
  576. {
  577. printf("ERROR: DeleteSecurityContext ServerCtxtHandle failed: ");
  578. PrintStatus(Status);
  579. }
  580. }
  581. if (ClientCtxtHandle.dwLower || ClientCtxtHandle.dwUpper)
  582. {
  583. Status = DeleteSecurityContext(&ClientCtxtHandle);
  584. if (!NT_SUCCESS(Status))
  585. {
  586. printf("ERROR: DeleteSecurityContext ClientCtxtHandle failed: ");
  587. PrintStatus(Status);
  588. }
  589. }
  590. //
  591. // Free the credential handles
  592. //
  593. printf("Now calling to Free the ServerCred\n");
  594. if (bServerCred)
  595. {
  596. Status = FreeCredentialsHandle( &ServerCred );
  597. if (!NT_SUCCESS(Status))
  598. {
  599. printf( "FreeCredentialsHandle failed for ServerCred: " );
  600. PrintStatus(Status);
  601. }
  602. }
  603. printf("Now calling to Free the ServerCred\n");
  604. if (bClientCred)
  605. {
  606. Status = FreeCredentialsHandle(&ClientCred);
  607. if (!NT_SUCCESS(Status))
  608. {
  609. printf( "FreeCredentialsHandle failed for ClientCred: " );
  610. PrintStatus( Status );
  611. }
  612. }
  613. StringFree(&strChallenge);
  614. StringFree(&strMethod);
  615. StringFree(&strHEntity);
  616. StringFree(&strOutBuffer);
  617. if (bPass != TRUE)
  618. printf("FAILED test run with one or more tests failing.\n");
  619. else
  620. printf("All tests passed.\n");
  621. return 0;
  622. }
  623. void
  624. PrintStatus(
  625. SECURITY_STATUS NetStatus
  626. )
  627. /*++
  628. Routine Description:
  629. Print a net status code.
  630. Arguments:
  631. NetStatus - The net status code to print.
  632. Return Value:
  633. None
  634. --*/
  635. {
  636. printf( "Status = 0x%lx",NetStatus );
  637. switch (NetStatus) {
  638. case ERROR_LOGON_FAILURE:
  639. printf( " ERROR_LOGON_FAILURE" );
  640. break;
  641. case ERROR_ACCESS_DENIED:
  642. printf( " ERROR_ACCESS_DENIED" );
  643. break;
  644. case ERROR_NOT_SUPPORTED:
  645. printf( " ERROR_NOT_SUPPORTED" );
  646. break;
  647. case ERROR_NO_LOGON_SERVERS:
  648. printf( " ERROR_NO_LOGON_SERVERS" );
  649. break;
  650. case ERROR_NO_SUCH_DOMAIN:
  651. printf( " ERROR_NO_SUCH_DOMAIN" );
  652. break;
  653. case ERROR_NO_TRUST_LSA_SECRET:
  654. printf( " ERROR_NO_TRUST_LSA_SECRET" );
  655. break;
  656. case ERROR_NO_TRUST_SAM_ACCOUNT:
  657. printf( " ERROR_NO_TRUST_SAM_ACCOUNT" );
  658. break;
  659. case ERROR_DOMAIN_TRUST_INCONSISTENT:
  660. printf( " ERROR_DOMAIN_TRUST_INCONSISTENT" );
  661. break;
  662. case ERROR_BAD_NETPATH:
  663. printf( " ERROR_BAD_NETPATH" );
  664. break;
  665. case ERROR_FILE_NOT_FOUND:
  666. printf( " ERROR_FILE_NOT_FOUND" );
  667. break;
  668. case SEC_E_NO_SPM:
  669. printf( " SEC_E_NO_SPM" );
  670. break;
  671. case SEC_E_BAD_PKGID:
  672. printf( " SEC_E_BAD_PKGID" ); break;
  673. case SEC_E_NOT_OWNER:
  674. printf( " SEC_E_NOT_OWNER" ); break;
  675. case SEC_E_CANNOT_INSTALL:
  676. printf( " SEC_E_CANNOT_INSTALL" ); break;
  677. case SEC_E_INVALID_TOKEN:
  678. printf( " SEC_E_INVALID_TOKEN" ); break;
  679. case SEC_E_CANNOT_PACK:
  680. printf( " SEC_E_CANNOT_PACK" ); break;
  681. case SEC_E_QOP_NOT_SUPPORTED:
  682. printf( " SEC_E_QOP_NOT_SUPPORTED" ); break;
  683. case SEC_E_NO_IMPERSONATION:
  684. printf( " SEC_E_NO_IMPERSONATION" ); break;
  685. case SEC_E_LOGON_DENIED:
  686. printf( " SEC_E_LOGON_DENIED" ); break;
  687. case SEC_E_UNKNOWN_CREDENTIALS:
  688. printf( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
  689. case SEC_E_NO_CREDENTIALS:
  690. printf( " SEC_E_NO_CREDENTIALS" ); break;
  691. case SEC_E_MESSAGE_ALTERED:
  692. printf( " SEC_E_MESSAGE_ALTERED" ); break;
  693. case SEC_E_OUT_OF_SEQUENCE:
  694. printf( " SEC_E_OUT_OF_SEQUENCE" ); break;
  695. case SEC_E_INSUFFICIENT_MEMORY:
  696. printf( " SEC_E_INSUFFICIENT_MEMORY" ); break;
  697. case SEC_E_INVALID_HANDLE:
  698. printf( " SEC_E_INVALID_HANDLE" ); break;
  699. case SEC_E_NOT_SUPPORTED:
  700. printf( " SEC_E_NOT_SUPPORTED" ); break;
  701. case SEC_I_CONTINUE_NEEDED:
  702. printf( " SEC_I_CONTINUE_NEEDED" ); break;
  703. }
  704. printf( "\n" );
  705. }
  706. void
  707. PrintTime(
  708. LPSTR Comment,
  709. TimeStamp ConvertTime
  710. )
  711. /*++
  712. Routine Description:
  713. Print the specified time
  714. Arguments:
  715. Comment - Comment to print in front of the time
  716. Time - Local time to print
  717. Return Value:
  718. None
  719. --*/
  720. {
  721. LARGE_INTEGER LocalTime;
  722. NTSTATUS Status;
  723. LocalTime.HighPart = ConvertTime.HighPart;
  724. LocalTime.LowPart = ConvertTime.LowPart;
  725. Status = RtlSystemTimeToLocalTime( &ConvertTime, &LocalTime );
  726. if (!NT_SUCCESS( Status )) {
  727. printf( "Can't convert time from GMT to Local time\n" );
  728. LocalTime = ConvertTime;
  729. }
  730. printf( "%s", Comment );
  731. //
  732. // If the time is infinite,
  733. // just say so.
  734. //
  735. if ( LocalTime.HighPart == 0x7FFFFFFF && LocalTime.LowPart == 0xFFFFFFFF ) {
  736. printf( "Infinite\n" );
  737. //
  738. // Otherwise print it more clearly
  739. //
  740. } else {
  741. TIME_FIELDS TimeFields;
  742. RtlTimeToTimeFields( &LocalTime, &TimeFields );
  743. printf( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
  744. TimeFields.Month,
  745. TimeFields.Day,
  746. TimeFields.Year,
  747. TimeFields.Hour,
  748. TimeFields.Minute,
  749. TimeFields.Second );
  750. }
  751. }
  752. // Support Routines
  753. //+-------------------------------------------------------------------------
  754. //
  755. // Function: StringAllocate
  756. //
  757. // Synopsis: Allocates cb chars to STRING Buffer
  758. //
  759. // Arguments: pString - pointer to String to allocate memory to
  760. //
  761. // Returns: STATUS_SUCCESS - Normal completion
  762. //
  763. // Requires:
  764. //
  765. // Effects: allocates memory and sets STRING sizes
  766. //
  767. // Notes: Must call StringFree() to release memory
  768. //
  769. //--------------------------------------------------------------------------
  770. NTSTATUS
  771. StringAllocate(
  772. IN PSTRING pString,
  773. IN USHORT cb
  774. )
  775. {
  776. // DebugLog((DEB_TRACE, "NTDigest:Entering StringAllocate\n"));
  777. NTSTATUS Status = STATUS_SUCCESS;
  778. cb = cb + 1; // Add in extra room for the terminating NULL
  779. if (ARGUMENT_PRESENT(pString))
  780. {
  781. pString->Length = 0;
  782. pString->Buffer = (char *)DigestAllocateMemory((ULONG)(cb * sizeof(CHAR)));
  783. if (pString->Buffer)
  784. {
  785. pString->MaximumLength = cb;
  786. }
  787. else
  788. {
  789. pString->MaximumLength = 0;
  790. Status = STATUS_NO_MEMORY;
  791. goto CleanUp;
  792. }
  793. }
  794. else
  795. {
  796. Status = STATUS_INVALID_PARAMETER;
  797. goto CleanUp;
  798. }
  799. CleanUp:
  800. // DebugLog((DEB_TRACE, "NTDigest: Leaving StringAllocate\n"));
  801. return(Status);
  802. }
  803. //+-------------------------------------------------------------------------
  804. //
  805. // Function: StringFree
  806. //
  807. // Synopsis: Clears a String and releases the memory
  808. //
  809. // Arguments: pString - pointer to String to clear
  810. //
  811. // Returns: SEC_E_OK - released memory succeeded
  812. //
  813. // Requires:
  814. //
  815. // Effects: de-allocates memory with LsaFunctions.AllocateLsaHeap
  816. //
  817. // Notes:
  818. //
  819. //--------------------------------------------------------------------------
  820. NTSTATUS
  821. StringFree(
  822. IN PSTRING pString
  823. )
  824. {
  825. // DebugLog((DEB_TRACE, "NTDigest:Entering StringFree\n"));
  826. NTSTATUS Status = STATUS_SUCCESS;
  827. if (ARGUMENT_PRESENT(pString) &&
  828. (pString->Buffer != NULL))
  829. {
  830. DigestFreeMemory(pString->Buffer);
  831. pString->Length = 0;
  832. pString->MaximumLength = 0;
  833. pString->Buffer = NULL;
  834. }
  835. // DebugLog((DEB_TRACE, "NTDigest: Leaving StringFree\n"));
  836. return(Status);
  837. }
  838. //+-------------------------------------------------------------------------
  839. //
  840. // Function: StringCharDuplicate
  841. //
  842. // Synopsis: Duplicates a NULL terminated char. If the source string buffer is
  843. // NULL the destionation will be too.
  844. //
  845. // Arguments: Destination - Receives a copy of the source NULL Term char *
  846. // czSource - String to copy
  847. //
  848. // Returns: SEC_E_OK - the copy succeeded
  849. // SEC_E_INSUFFICIENT_MEMORY - the call to allocate
  850. // memory failed.
  851. //
  852. // Requires:
  853. //
  854. // Effects: allocates memory with LsaFunctions.AllocateLsaHeap
  855. //
  856. // Notes:
  857. //
  858. //
  859. //--------------------------------------------------------------------------
  860. NTSTATUS
  861. StringCharDuplicate(
  862. OUT PSTRING DestinationString,
  863. IN OPTIONAL char *czSource
  864. )
  865. {
  866. // DebugLog((DEB_TRACE, "NTDigest: Entering StringCharDuplicate\n"));
  867. NTSTATUS Status = STATUS_SUCCESS;
  868. USHORT cbSourceCz = 0;
  869. DestinationString->Buffer = NULL;
  870. DestinationString->Length = 0;
  871. DestinationString->MaximumLength = 0;
  872. if ((ARGUMENT_PRESENT(czSource)) &&
  873. ((cbSourceCz = strlen(czSource)) != 0))
  874. {
  875. DestinationString->Buffer = (LPSTR) DigestAllocateMemory(cbSourceCz + sizeof(CHAR));
  876. if (DestinationString->Buffer != NULL)
  877. {
  878. DestinationString->Length = cbSourceCz;
  879. DestinationString->MaximumLength = cbSourceCz + sizeof(CHAR);
  880. RtlCopyMemory(
  881. DestinationString->Buffer,
  882. czSource,
  883. cbSourceCz
  884. );
  885. DestinationString->Buffer[cbSourceCz/sizeof(CHAR)] = '\0';
  886. }
  887. else
  888. {
  889. Status = STATUS_NO_MEMORY;
  890. // DebugLog((DEB_ERROR, "NTDigest: StringCharDuplicate, DigestAllocateMemory returns NULL\n"));
  891. goto CleanUp;
  892. }
  893. }
  894. CleanUp:
  895. // DebugLog((DEB_TRACE, "NTDigest: Leaving StringCharDuplicate\n"));
  896. return(Status);
  897. }
  898. //+-------------------------------------------------------------------------
  899. //
  900. // Function: DigestAllocateMemory
  901. //
  902. // Synopsis: Allocate memory in either lsa mode or user mode
  903. //
  904. // Effects: Allocated chunk is zeroed out
  905. //
  906. // Arguments:
  907. //
  908. // Requires:
  909. //
  910. // Returns:
  911. //
  912. // Notes:
  913. //
  914. //
  915. //--------------------------------------------------------------------------
  916. PVOID
  917. DigestAllocateMemory(
  918. IN ULONG BufferSize
  919. )
  920. {
  921. PVOID Buffer = NULL;
  922. // DebugLog((DEB_TRACE, "Entering DigestAllocateMemory\n"));
  923. Buffer = LocalAlloc(LPTR, BufferSize);
  924. // DebugLog((DEB_TRACE, "Leaving DigestAllocateMemory\n"));
  925. return Buffer;
  926. }
  927. //+-------------------------------------------------------------------------
  928. //
  929. // Function: NtLmFree
  930. //
  931. // Synopsis: Free memory in either lsa mode or user mode
  932. //
  933. // Effects:
  934. //
  935. // Arguments:
  936. //
  937. // Requires:
  938. //
  939. // Returns:
  940. //
  941. // Notes:
  942. //
  943. //
  944. //--------------------------------------------------------------------------
  945. VOID
  946. DigestFreeMemory(
  947. IN PVOID Buffer
  948. )
  949. {
  950. // DebugLog((DEB_TRACE, "Entering DigestFreeMemory\n"));
  951. LocalFree(Buffer);
  952. // DebugLog((DEB_TRACE, "Leaving DigestFreeMemory\n"));
  953. }
  954. VOID
  955. BinToHex(
  956. LPBYTE pSrc,
  957. UINT cSrc,
  958. LPSTR pDst
  959. )
  960. {
  961. #define TOHEX(a) ((a)>=10 ? 'a'+(a)-10 : '0'+(a))
  962. for ( UINT x = 0, y = 0 ; x < cSrc ; ++x )
  963. {
  964. UINT v;
  965. v = pSrc[x]>>4;
  966. pDst[y++] = TOHEX( v );
  967. v = pSrc[x]&0x0f;
  968. pDst[y++] = TOHEX( v );
  969. }
  970. pDst[y] = '\0';
  971. }
  972. VOID
  973. ISCRETFlags( ULONG ulFlags)
  974. {
  975. printf("ISC Ret Flag (0x%x):", ulFlags);
  976. if (ulFlags & ISC_RET_DELEGATE)
  977. {
  978. printf(" Delegate");
  979. }
  980. if (ulFlags & ISC_RET_MUTUAL_AUTH)
  981. {
  982. printf(" Mutual_Auth");
  983. }
  984. if (ulFlags & ISC_RET_REPLAY_DETECT)
  985. {
  986. printf(" Replay_Detect");
  987. }
  988. if (ulFlags & ISC_RET_SEQUENCE_DETECT)
  989. {
  990. printf(" Seq_Detect");
  991. }
  992. if (ulFlags & ISC_RET_CONFIDENTIALITY)
  993. {
  994. printf(" Confident");
  995. }
  996. if (ulFlags & ISC_RET_ALLOCATED_MEMORY)
  997. {
  998. printf(" Alloc_Mem");
  999. }
  1000. if (ulFlags & ISC_RET_CONNECTION)
  1001. {
  1002. printf(" Connection");
  1003. }
  1004. if (ulFlags & ISC_RET_INTEGRITY)
  1005. {
  1006. printf(" Integrity");
  1007. }
  1008. printf("\n");
  1009. }
  1010. VOID
  1011. ASCRETFlags( ULONG ulFlags)
  1012. {
  1013. printf("ASC Ret Flag (0x%x):", ulFlags);
  1014. if (ulFlags & ASC_RET_DELEGATE)
  1015. {
  1016. printf(" Delegate");
  1017. }
  1018. if (ulFlags & ASC_RET_MUTUAL_AUTH)
  1019. {
  1020. printf(" Mutual_Auth");
  1021. }
  1022. if (ulFlags & ASC_RET_REPLAY_DETECT)
  1023. {
  1024. printf(" Replay_Detect");
  1025. }
  1026. if (ulFlags & ASC_RET_SEQUENCE_DETECT)
  1027. {
  1028. printf(" Seq_Detect");
  1029. }
  1030. if (ulFlags & ASC_RET_CONFIDENTIALITY)
  1031. {
  1032. printf(" Confident");
  1033. }
  1034. if (ulFlags & ASC_RET_ALLOCATED_MEMORY)
  1035. {
  1036. printf(" Alloc_Mem");
  1037. }
  1038. if (ulFlags & ASC_RET_CONNECTION)
  1039. {
  1040. printf(" Connection");
  1041. }
  1042. if (ulFlags & ASC_RET_INTEGRITY)
  1043. {
  1044. printf(" Integrity");
  1045. }
  1046. printf("\n");
  1047. }