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.

1448 lines
42 KiB

  1. // Test.cpp : Defines the entry point for the console application.
  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_REALM "simple_digest"
  9. #define AUTH_REALM_W L"simple_digest\"_widechar"
  10. #define AUTH_NONCE "9b38dce631309cc25a653ebaad5b18ee01c8bf385260b26db0574a302be4c11367"
  11. #define AUTH_METHOD "GET"
  12. #define AUTH_ALGORITHM "md5-sess"
  13. #define AUTH_QOP "auth"
  14. #define AUTH_PASSWD "secret"
  15. #define AUTH_CNONCE "34c52218425a779f41d5075931fe6c93"
  16. #define AUTH_URI "/dir/index.html"
  17. #define AUTH_URI_W L"/dir/index.html"
  18. #define AUTH_URI2 "/simple_digest/progress.html"
  19. #define AUTH_URI2_W L"/simple_digest/progress.html"
  20. #define AUTH_NC "0000000b"
  21. #define AUTH_NC1 "00000001"
  22. #define AUTH_NC2 "00000002"
  23. #define AUTH_NC3 "00000003"
  24. #define AUTH_NC4 "00000004"
  25. #define AUTH_REQDIGEST "60cac55049f9887c9fb853f485128368"
  26. #define STR_BUF_SIZE 4000
  27. // Prototypes
  28. void PrintStatus(SECURITY_STATUS NetStatus);
  29. void MyPrintTime(LPSTR Comment,TimeStamp ConvertTime);
  30. int __cdecl
  31. main(int argc, char* argv[])
  32. {
  33. int bPass = 1;
  34. SECURITY_STATUS Status = STATUS_SUCCESS;
  35. char cTemp[STR_BUF_SIZE]; // temp buffer for scratch data
  36. char cOutputTemp[STR_BUF_SIZE];
  37. char szOutSecBuf[STR_BUF_SIZE];
  38. char szChallenge[STR_BUF_SIZE];
  39. char szISCChallengeResponse[STR_BUF_SIZE]; // Output buffer from ISC
  40. char szASCChallengeResponse[STR_BUF_SIZE]; // Output buffer from ASC
  41. // SSPI Interface tests
  42. ULONG PackageCount = 0;
  43. int i = 0;
  44. PSecPkgInfo pPackageInfo = NULL;
  45. PSecPkgInfo pPackageTmp = NULL;
  46. SECURITY_STATUS TmpStatus = STATUS_SUCCESS;
  47. HANDLE hClientToken = NULL;
  48. CredHandle ServerCred;
  49. CredHandle ClientCred;
  50. TimeStamp Lifetime;
  51. BOOL bServerCred = FALSE;
  52. BOOL bClientCred = FALSE;
  53. BOOL bRC = FALSE;
  54. ULONG ContextReqFlags = 0;
  55. ULONG ContextFlagsUtilized = 0;
  56. ULONG TargetDataRep = 0;
  57. ULONG ContextAttributes = 0;
  58. CtxtHandle OldContextHandle;
  59. CtxtHandle ServerCtxtHandle;
  60. CtxtHandle ClientCtxtHandle;
  61. SecBufferDesc InputBuffers;
  62. SecBufferDesc OutputBuffers;
  63. SecBuffer TempTokensIn[6];
  64. SecBuffer TempTokensOut[6];
  65. SecPkgContext_Names SecServerName;
  66. SecPkgCredentials_Names SecCredClientName;
  67. SecPkgContext_StreamSizes StreamSizes;
  68. TimeStamp SecContextExpiry;
  69. PCHAR pcPtr = NULL;
  70. int iLen = 0;
  71. STRING strChallenge;
  72. STRING strMethod;
  73. STRING strURL;
  74. STRING strHEntity;
  75. STRING strOutBuffer;
  76. UNICODE_STRING ustrUsername;
  77. UNICODE_STRING ustrPassword;
  78. UNICODE_STRING ustrDomain;
  79. STRING strTemp;
  80. ULONG ulMessSeqNo = 0;
  81. ULONG ulQOP = 0;
  82. SEC_WINNT_AUTH_IDENTITY_W AuthData;
  83. printf("Begining TESTB...\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(&SecServerName, sizeof(SecPkgContext_Names));
  90. ZeroMemory(&SecCredClientName, sizeof(SecPkgCredentials_Names));
  91. ZeroMemory(&SecContextExpiry, sizeof(SecContextExpiry));
  92. ZeroMemory(&ustrUsername, sizeof(ustrUsername));
  93. ZeroMemory(&ustrPassword, sizeof(ustrPassword));
  94. ZeroMemory(&ustrDomain, sizeof(ustrDomain));
  95. ZeroMemory(&strTemp, sizeof(strTemp));
  96. ZeroMemory(&StreamSizes, sizeof(StreamSizes));
  97. // Pull out any command line args
  98. if (argc > 1)
  99. {
  100. for (i = 1; i < argc; i++)
  101. {
  102. pcPtr = argv[i];
  103. if (*pcPtr == '-')
  104. {
  105. iLen = strlen(pcPtr);
  106. if (iLen >= 2)
  107. {
  108. switch (*(pcPtr + 1))
  109. {
  110. case 'u':
  111. Status = RtlCreateUnicodeStringFromAsciiz(&ustrUsername, (pcPtr + 2));
  112. break;
  113. case 'd':
  114. Status = RtlCreateUnicodeStringFromAsciiz(&ustrDomain, (pcPtr + 2));
  115. break;
  116. case 'p':
  117. Status = RtlCreateUnicodeStringFromAsciiz(&ustrPassword, (pcPtr + 2));
  118. break;
  119. case '?':
  120. default:
  121. printf("Usage: %s -uUsername -pPassword -ddomain\n", argv[0]);
  122. return(-1);
  123. break;
  124. }
  125. }
  126. }
  127. }
  128. }
  129. //
  130. // Get info about the security packages.
  131. //
  132. Status = EnumerateSecurityPackages( &PackageCount, &pPackageInfo );
  133. TmpStatus = GetLastError();
  134. if (!NT_SUCCESS(Status)) {
  135. printf( "FAILED: EnumerateSecurityPackages failed: 0x%x\n", Status);
  136. PrintStatus( Status );
  137. bPass = 0;
  138. goto CleanUp;
  139. }
  140. printf( "PackageCount: %ld\n", PackageCount );
  141. for ( i= 0; i< (int)PackageCount; i++)
  142. {
  143. pPackageTmp = (pPackageInfo + i);
  144. printf( "Name: %ws Comment: %ws\n", pPackageTmp->Name, pPackageTmp->Comment );
  145. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  146. pPackageTmp->fCapabilities,
  147. pPackageTmp->wVersion,
  148. pPackageTmp->wRPCID,
  149. pPackageTmp->cbMaxToken );
  150. }
  151. //
  152. // Get info about the security packages.
  153. //
  154. Status = QuerySecurityPackageInfo( WDIGEST_SP_NAME, &pPackageInfo );
  155. TmpStatus = GetLastError();
  156. if (!NT_SUCCESS(Status)) {
  157. printf( "FAILED: QuerySecurityPackageInfo failed: status 0x%x\n", Status);
  158. PrintStatus( Status );
  159. bPass = 0;
  160. goto CleanUp;
  161. }
  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. // Acquire a credential handle for the server side
  170. //
  171. printf("Server AcquireCredentialHandle\n");
  172. Status = AcquireCredentialsHandle(
  173. NULL, // New principal
  174. WDIGEST_SP_NAME, // Package Name
  175. SECPKG_CRED_INBOUND,
  176. NULL,
  177. NULL,
  178. NULL,
  179. NULL,
  180. &ServerCred,
  181. &Lifetime );
  182. if (!NT_SUCCESS(Status)) {
  183. printf( "FAILED: AcquireCredentialsHandle failed: status 0x%x\n", Status);
  184. // TmpStatus = GetLastError();
  185. PrintStatus( Status );
  186. bPass = 0;
  187. ZeroMemory(&ServerCred, sizeof(CredHandle));
  188. goto CleanUp;
  189. }
  190. bServerCred = TRUE;
  191. MyPrintTime("Server ACH LifeTime: ", Lifetime);
  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( "FAILED: AcquireCredentialsHandle failed: status 0x%x\n", Status);
  236. // TmpStatus = GetLastError();
  237. PrintStatus( Status );
  238. bPass = 0;
  239. // ZeroMemory(&ClientCred, sizeof(CredHandle));
  240. goto CleanUp;
  241. }
  242. else
  243. bClientCred = TRUE;
  244. printf( "ClientCred: 0x%lx 0x%lx ",
  245. ClientCred.dwLower, ClientCred.dwUpper );
  246. printf( "ServerCred: 0x%lx 0x%lx \n",
  247. ServerCred.dwLower, ServerCred.dwUpper );
  248. MyPrintTime( "Client ACH Lifetime: ", Lifetime );
  249. // Big time - call Accept with no parameters to get a challenge
  250. StringAllocate(&strChallenge, 1);
  251. StringCharDuplicate(&strMethod, "GET");
  252. StringCharDuplicate(&strURL, AUTH_URI);
  253. StringAllocate(&strHEntity, NULL);
  254. StringAllocate(&strOutBuffer, 4000);
  255. // ZeroMemory(TempTokensIn, sizeof(TempTokensIn));
  256. // ZeroMemory(TempTokensOut, sizeof(TempTokensOut));
  257. ZeroMemory(&InputBuffers, sizeof(InputBuffers));
  258. ZeroMemory(&OutputBuffers, sizeof(OutputBuffers));
  259. InputBuffers.ulVersion = SECBUFFER_VERSION;
  260. InputBuffers.cBuffers = 5;
  261. InputBuffers.pBuffers = TempTokensIn;
  262. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  263. TempTokensIn[0].cbBuffer = 0; // for NULL
  264. TempTokensIn[0].pvBuffer = NULL;
  265. TempTokensIn[1].BufferType = SECBUFFER_PKG_PARAMS;
  266. TempTokensIn[1].cbBuffer = 0; // for NULL
  267. TempTokensIn[1].pvBuffer = NULL;
  268. TempTokensIn[2].BufferType = SECBUFFER_PKG_PARAMS;
  269. TempTokensIn[2].cbBuffer = 0; // for NULL
  270. TempTokensIn[2].pvBuffer = NULL;
  271. TempTokensIn[3].BufferType = SECBUFFER_PKG_PARAMS;
  272. TempTokensIn[3].cbBuffer = 0; // strHEntity.Length + 1; // for NULL
  273. TempTokensIn[3].pvBuffer = NULL; // strHEntity.Buffer;
  274. TempTokensIn[4].BufferType = SECBUFFER_PKG_PARAMS;
  275. TempTokensIn[4].cbBuffer = 0; // (wcslen(AUTH_REALM_W) + 1) * sizeof(WCHAR); // Realm size count to use for this challenge
  276. TempTokensIn[4].pvBuffer = NULL; // AUTH_REALM_W; // Realm to use for this challenge
  277. OutputBuffers.ulVersion = SECBUFFER_VERSION;
  278. OutputBuffers.cBuffers = 1;
  279. OutputBuffers.pBuffers = TempTokensOut;
  280. TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
  281. TempTokensOut[0].cbBuffer = 0; // strOutBuffer.MaximumLength; // use any space here
  282. TempTokensOut[0].pvBuffer = NULL; // strOutBuffer.Buffer;
  283. ContextReqFlags = ASC_REQ_REPLAY_DETECT | ASC_REQ_CONNECTION | ASC_REQ_ALLOCATE_MEMORY;
  284. printf("ASC will create the output buffer\n");
  285. Status = AcceptSecurityContext(
  286. &ServerCred,
  287. NULL,
  288. &InputBuffers,
  289. ContextReqFlags,
  290. TargetDataRep,
  291. &ServerCtxtHandle,
  292. &OutputBuffers,
  293. &ContextAttributes,
  294. &Lifetime);
  295. if ((Status != SEC_I_CONTINUE_NEEDED) &&
  296. (Status != STATUS_SUCCESS)) // Indicates that this is the challenge
  297. {
  298. printf("FAILED: SpAcceptLsaModeContext error status 0x%x\n", Status);
  299. PrintStatus( Status );
  300. bPass = 0;
  301. goto CleanUp;
  302. }
  303. if (!OutputBuffers.pBuffers[0].pvBuffer && OutputBuffers.pBuffers[0].cbBuffer)
  304. {
  305. printf("FAILED: SpAcceptLsaModeContext invalid output buffer pointer with length provided\n");
  306. Status = SEC_E_INTERNAL_ERROR;
  307. PrintStatus( Status );
  308. bPass = 0;
  309. goto CleanUp;
  310. }
  311. ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
  312. ZeroMemory(szChallenge, STR_BUF_SIZE); // contains the output buffer
  313. strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  314. cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  315. strncpy(szChallenge, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  316. szChallenge[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  317. Status = FreeContextBuffer(OutputBuffers.pBuffers[0].pvBuffer);
  318. if (!NT_SUCCESS(Status))
  319. {
  320. printf("FAILED: FreeContextBuffer error: status 0x%x\n", Status);
  321. TmpStatus = GetLastError();
  322. PrintStatus( Status );
  323. bPass = 0;
  324. goto CleanUp;
  325. }
  326. printf("Context Flags Req 0x%lx Ret 0x%lx\n", ContextReqFlags, ContextAttributes);
  327. printf("Challenge Output Buffer is:\n%s\n\n", cOutputTemp);
  328. MyPrintTime("Server ASC LifeTime: ", Lifetime);
  329. printf("Now call the SSPI InitializeSecCtxt to generate the ChallengeResponse\n");
  330. InputBuffers.ulVersion = SECBUFFER_VERSION;
  331. InputBuffers.cBuffers = 3;
  332. InputBuffers.pBuffers = TempTokensIn;
  333. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  334. TempTokensIn[0].cbBuffer = strlen(szChallenge) + 1; // for NULL
  335. TempTokensIn[0].pvBuffer = szChallenge;
  336. TempTokensIn[1].BufferType = SECBUFFER_PKG_PARAMS;
  337. TempTokensIn[1].cbBuffer = strMethod.Length + 1; // for NULL
  338. TempTokensIn[1].pvBuffer = strMethod.Buffer;
  339. TempTokensIn[2].BufferType = SECBUFFER_PKG_PARAMS;
  340. TempTokensIn[2].cbBuffer = 0; // strHEntity.Length + 1; // for NULL
  341. TempTokensIn[2].pvBuffer = NULL; // strHEntity.Buffer;
  342. OutputBuffers.ulVersion = SECBUFFER_VERSION;
  343. OutputBuffers.cBuffers = 1;
  344. OutputBuffers.pBuffers = TempTokensOut;
  345. TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
  346. TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
  347. TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
  348. ContextReqFlags = ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION;
  349. Status = InitializeSecurityContext(&ClientCred,
  350. NULL,
  351. AUTH_URI_W,
  352. ContextReqFlags,
  353. NULL,
  354. SECURITY_NATIVE_DREP,
  355. &InputBuffers,
  356. NULL,
  357. &ClientCtxtHandle,
  358. &OutputBuffers,
  359. &ContextFlagsUtilized,
  360. &Lifetime);
  361. if (!NT_SUCCESS(Status))
  362. {
  363. printf("FAILED: InitializeSecurityContext error: status 0x%x\n", Status);
  364. TmpStatus = GetLastError();
  365. PrintStatus( Status );
  366. bPass = 0;
  367. goto CleanUp;
  368. }
  369. printf("InitializeSecurityContext SUCCEEDED with Context Handle (0x%x,0x%x)\n",
  370. ClientCtxtHandle.dwLower, ClientCtxtHandle.dwUpper );
  371. printf("Context Flags Req 0x%lx Ret 0x%lx\n", ContextReqFlags, ContextFlagsUtilized);
  372. MyPrintTime("Client ISC LifeTime: ", Lifetime);
  373. ZeroMemory(cOutputTemp, STR_BUF_SIZE); // contains the output buffer
  374. ZeroMemory(szChallenge, STR_BUF_SIZE); // contains the output buffer
  375. strncpy(cOutputTemp, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  376. cOutputTemp[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  377. strncpy(szISCChallengeResponse, (char *)OutputBuffers.pBuffers[0].pvBuffer, OutputBuffers.pBuffers[0].cbBuffer);
  378. szISCChallengeResponse[OutputBuffers.pBuffers[0].cbBuffer] = '\0';
  379. printf("\nISC: Challenge Response Output Buffer is\n%s\n\n", szISCChallengeResponse);
  380. InputBuffers.ulVersion = SECBUFFER_VERSION;
  381. InputBuffers.cBuffers = 5;
  382. InputBuffers.pBuffers = TempTokensIn;
  383. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  384. TempTokensIn[0].cbBuffer = strlen(cOutputTemp) + 1; // for NULL
  385. TempTokensIn[0].pvBuffer = cOutputTemp;
  386. TempTokensIn[1].BufferType = SECBUFFER_PKG_PARAMS;
  387. TempTokensIn[1].cbBuffer = strMethod.Length + 1; // for NULL
  388. TempTokensIn[1].pvBuffer = strMethod.Buffer;
  389. TempTokensIn[2].BufferType = SECBUFFER_PKG_PARAMS;
  390. TempTokensIn[2].cbBuffer = strURL.Length + 1; // for NULL
  391. TempTokensIn[2].pvBuffer = strURL.Buffer;
  392. TempTokensIn[3].BufferType = SECBUFFER_PKG_PARAMS;
  393. TempTokensIn[3].cbBuffer = 0; // strHEntity.Length + 1; // for NULL
  394. TempTokensIn[3].pvBuffer = NULL; // strHEntity.Buffer;
  395. TempTokensIn[4].BufferType = SECBUFFER_PKG_PARAMS;
  396. TempTokensIn[4].cbBuffer = 0; // Realm not used for challengeresponse
  397. TempTokensIn[4].pvBuffer = NULL; // not used for challengeresponse
  398. OutputBuffers.ulVersion = SECBUFFER_VERSION;
  399. OutputBuffers.cBuffers = 1;
  400. OutputBuffers.pBuffers = TempTokensOut;
  401. TempTokensOut[0].BufferType = SECBUFFER_TOKEN;
  402. TempTokensOut[0].cbBuffer = strOutBuffer.MaximumLength; // use any space here
  403. TempTokensOut[0].pvBuffer = strOutBuffer.Buffer;
  404. ContextReqFlags = ASC_REQ_REPLAY_DETECT | ASC_REQ_CONNECTION; // | ASC_REQ_ALLOCATE_MEMORY;
  405. printf("Calling the AcceptSC with a ChallengeResponse (should talk to the DC)!\n");
  406. Status = AcceptSecurityContext(
  407. &ServerCred,
  408. NULL,
  409. &InputBuffers,
  410. ContextReqFlags,
  411. TargetDataRep,
  412. &ServerCtxtHandle,
  413. &OutputBuffers,
  414. &ContextAttributes,
  415. &Lifetime);
  416. if (!NT_SUCCESS(Status))
  417. {
  418. printf("FAILED: AcceptSecurityContext 2nd Call: status 0x%x\n", Status);
  419. PrintStatus( Status );
  420. bPass = 0;
  421. goto CleanUp;
  422. }
  423. strcpy(szASCChallengeResponse, (char *)InputBuffers.pBuffers[0].pvBuffer);
  424. printf("ASC has accepted the Challenge Resposne\n");
  425. printf("Now have a valid Security Context handle from ISC and ASC\n\n");
  426. printf("Context Flags Req 0x%lx Ret 0x%lx\n", ContextReqFlags, ContextAttributes);
  427. MyPrintTime("Server ASC LifeTime: ", Lifetime);
  428. Status = FreeContextBuffer(OutputBuffers.pBuffers[0].pvBuffer);
  429. if (!NT_SUCCESS(Status))
  430. {
  431. printf("FAILED: FreeContextBuffer error: status 0x%x\n", Status);
  432. TmpStatus = GetLastError();
  433. PrintStatus( Status );
  434. bPass = 0;
  435. goto CleanUp;
  436. }
  437. // Now get some info on the securitycontexts
  438. Status = QueryContextAttributes(&ServerCtxtHandle, SECPKG_ATTR_NAMES, &SecServerName);
  439. if (!NT_SUCCESS(Status))
  440. {
  441. printf("FAILED: QueryContextAttributes error: status 0x%x\n", Status);
  442. PrintStatus( Status );
  443. bPass = 0;
  444. goto CleanUp;
  445. }
  446. if (SecServerName.sUserName)
  447. {
  448. printf("QueryContextAttributes reports that Username is %S\n", SecServerName.sUserName);
  449. }
  450. // Now get some info on the securitycontexts
  451. Status = QueryContextAttributes(&ServerCtxtHandle, SECPKG_ATTR_PASSWORD_EXPIRY, &SecContextExpiry);
  452. if (!NT_SUCCESS(Status))
  453. {
  454. printf("FAILED: QueryContextAttributes error: status 0x%x\n", Status);
  455. PrintStatus( Status );
  456. bPass = 0;
  457. goto CleanUp;
  458. }
  459. MyPrintTime("QueryContextAttributes reports server context expires: ", SecContextExpiry);
  460. // Now get some info on the securitycontexts
  461. Status = QueryContextAttributes(&ServerCtxtHandle, SECPKG_ATTR_STREAM_SIZES, &StreamSizes);
  462. if (!NT_SUCCESS(Status))
  463. {
  464. printf("FAILED: QueryContextAttributes SECPKG_ATTR_STREAM_SIZES error: status 0x%x\n", Status);
  465. PrintStatus( Status );
  466. bPass = 0;
  467. goto CleanUp;
  468. }
  469. printf("Server Context(StreamSizes): MaxBuf %lu Blocksize %lu\n",
  470. StreamSizes.cbMaximumMessage, StreamSizes.cbBlockSize);
  471. // Now get some info on the securitycontexts
  472. Status = QueryCredentialsAttributes(&ClientCred, SECPKG_CRED_ATTR_NAMES, &SecCredClientName);
  473. if (!NT_SUCCESS(Status))
  474. {
  475. printf("FAILED: QueryCredentialAttributes error: status 0x%x\n", Status);
  476. PrintStatus( Status );
  477. bPass = 0;
  478. goto CleanUp;
  479. }
  480. if (SecCredClientName.sUserName)
  481. {
  482. printf("QueryCredentialAttributes reports that Username is %S\n", SecCredClientName.sUserName);
  483. }
  484. InputBuffers.ulVersion = SECBUFFER_VERSION;
  485. InputBuffers.cBuffers = 5;
  486. InputBuffers.pBuffers = TempTokensIn;
  487. // The first call to MakeSignature this represents the SECOND request on this Nonce!
  488. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  489. TempTokensIn[0].cbBuffer = 0; // strlen(szISCChallengeResponse) + 1; // for NULL
  490. TempTokensIn[0].pvBuffer = NULL; // szISCChallengeResponse;
  491. TempTokensIn[1].BufferType = SECBUFFER_PKG_PARAMS;
  492. TempTokensIn[1].cbBuffer = strMethod.Length + 1; // for NULL
  493. TempTokensIn[1].pvBuffer = strMethod.Buffer;
  494. TempTokensIn[2].BufferType = SECBUFFER_PKG_PARAMS;
  495. TempTokensIn[2].cbBuffer = (strlen(AUTH_URI2) + 1) * sizeof(CHAR); // Realm size count to use for this challenge
  496. TempTokensIn[2].pvBuffer = AUTH_URI2; // Realm to use for this challenge
  497. TempTokensIn[3].BufferType = SECBUFFER_PKG_PARAMS;
  498. TempTokensIn[3].cbBuffer = 0; // strHEntity.Length + 1; // for NULL
  499. TempTokensIn[3].pvBuffer = NULL; // strHEntity.Buffer;
  500. TempTokensIn[4].BufferType = SECBUFFER_PKG_PARAMS; // There is no OutputBuffers
  501. TempTokensIn[4].cbBuffer = 4000; // So tack on another bufffer on end for output
  502. TempTokensIn[4].pvBuffer = szOutSecBuf;
  503. Status = MakeSignature(&ClientCtxtHandle,
  504. ulQOP,
  505. &InputBuffers,
  506. 0);
  507. if (!NT_SUCCESS(Status))
  508. {
  509. printf("FAILED: MakeSignature error: status 0x%x\n", Status);
  510. PrintStatus( Status );
  511. bPass = 0;
  512. goto CleanUp;
  513. }
  514. printf("\nMakeSig: Challenge Response Output Buffer for 2nd message is\n%s\n", szOutSecBuf);
  515. // You now send Output buffer to Server - in this case the buffer is szOutSecBuf
  516. printf("Now verify that the 2nd message is Authenticate\n");
  517. // The First message to VerifySignature is the Input to the final call of ASC
  518. strcpy(cOutputTemp, szOutSecBuf);
  519. TempTokensIn[0].BufferType = SECBUFFER_TOKEN;
  520. TempTokensIn[0].cbBuffer = strlen(cOutputTemp) + 1; // for NULL
  521. TempTokensIn[0].pvBuffer = cOutputTemp;
  522. Status = VerifySignature(&ServerCtxtHandle,
  523. &InputBuffers,
  524. ulMessSeqNo,
  525. &ulQOP);
  526. if (!NT_SUCCESS(Status))
  527. {
  528. printf("FAILED: VerifySignature 1st Call error : status 0x%x\n", Status);
  529. PrintStatus( Status );
  530. bPass = 0;
  531. goto CleanUp;
  532. }
  533. printf("Now have a authenticated 1st message under context 0x%x !\n", ServerCtxtHandle);
  534. printf("VerifySig: Check if still OK: Output Buffer (Verify should not have modified it) is\n%s\n\n", cOutputTemp);
  535. Status = VerifySignature(&ServerCtxtHandle,
  536. &InputBuffers,
  537. ulMessSeqNo,
  538. &ulQOP);
  539. if (NT_SUCCESS(Status))
  540. {
  541. printf("FAILED: VerifySignature 2nd Call should not have succeeded status 0x%x\n", Status);
  542. bPass = 0;
  543. goto CleanUp;
  544. }
  545. printf("Verified that replay does not work!!\n");
  546. goto CleanUp;
  547. CleanUp:
  548. printf("Leaving NT Digest testb\n\n\n");
  549. if (pPackageInfo)
  550. {
  551. FreeContextBuffer(pPackageInfo);
  552. }
  553. if (SecServerName.sUserName)
  554. {
  555. FreeContextBuffer(SecServerName.sUserName);
  556. }
  557. if (SecCredClientName.sUserName)
  558. {
  559. FreeContextBuffer(SecCredClientName.sUserName);
  560. }
  561. printf("About to call deletesecuritycontext\n");
  562. //
  563. // Free the security context handle
  564. //
  565. if (ServerCtxtHandle.dwLower || ServerCtxtHandle.dwUpper)
  566. {
  567. Status = DeleteSecurityContext(&ServerCtxtHandle);
  568. if (!NT_SUCCESS(Status))
  569. {
  570. printf("ERROR: DeleteSecurityContext ServerCtxtHandle failed: ");
  571. PrintStatus(Status);
  572. }
  573. }
  574. if (ClientCtxtHandle.dwLower || ClientCtxtHandle.dwUpper)
  575. {
  576. Status = DeleteSecurityContext(&ClientCtxtHandle);
  577. if (!NT_SUCCESS(Status))
  578. {
  579. printf("ERROR: DeleteSecurityContext ClientCtxtHandle failed: ");
  580. PrintStatus(Status);
  581. }
  582. }
  583. //
  584. // Free the credential handles
  585. //
  586. printf("Now calling to Free the ServerCred\n");
  587. if (bServerCred)
  588. {
  589. Status = FreeCredentialsHandle( &ServerCred );
  590. if (!NT_SUCCESS(Status))
  591. {
  592. printf( "FreeCredentialsHandle failed for ServerCred: " );
  593. PrintStatus(Status);
  594. }
  595. }
  596. printf("Now calling to Free the ServerCred\n");
  597. if (bClientCred)
  598. {
  599. Status = FreeCredentialsHandle(&ClientCred);
  600. if (!NT_SUCCESS(Status))
  601. {
  602. printf( "FreeCredentialsHandle failed for ClientCred: " );
  603. PrintStatus( Status );
  604. }
  605. }
  606. StringFree(&strChallenge);
  607. StringFree(&strMethod);
  608. StringFree(&strURL);
  609. StringFree(&strHEntity);
  610. StringFree(&strOutBuffer);
  611. if (bPass != 1)
  612. {
  613. printf("FAILED test run with one or more tests failing.\n");
  614. }
  615. else
  616. {
  617. printf("All tests passed.\n");
  618. }
  619. return 0;
  620. }
  621. void
  622. PrintStatus(
  623. SECURITY_STATUS NetStatus
  624. )
  625. /*++
  626. Routine Description:
  627. Print a net status code.
  628. Arguments:
  629. NetStatus - The net status code to print.
  630. Return Value:
  631. None
  632. --*/
  633. {
  634. printf( "Status = 0x%lx",NetStatus );
  635. switch (NetStatus) {
  636. case ERROR_LOGON_FAILURE:
  637. printf( " ERROR_LOGON_FAILURE" );
  638. break;
  639. case ERROR_ACCESS_DENIED:
  640. printf( " ERROR_ACCESS_DENIED" );
  641. break;
  642. case ERROR_NOT_SUPPORTED:
  643. printf( " ERROR_NOT_SUPPORTED" );
  644. break;
  645. case ERROR_NO_LOGON_SERVERS:
  646. printf( " ERROR_NO_LOGON_SERVERS" );
  647. break;
  648. case ERROR_NO_SUCH_DOMAIN:
  649. printf( " ERROR_NO_SUCH_DOMAIN" );
  650. break;
  651. case ERROR_NO_TRUST_LSA_SECRET:
  652. printf( " ERROR_NO_TRUST_LSA_SECRET" );
  653. break;
  654. case ERROR_NO_TRUST_SAM_ACCOUNT:
  655. printf( " ERROR_NO_TRUST_SAM_ACCOUNT" );
  656. break;
  657. case ERROR_DOMAIN_TRUST_INCONSISTENT:
  658. printf( " ERROR_DOMAIN_TRUST_INCONSISTENT" );
  659. break;
  660. case ERROR_BAD_NETPATH:
  661. printf( " ERROR_BAD_NETPATH" );
  662. break;
  663. case ERROR_FILE_NOT_FOUND:
  664. printf( " ERROR_FILE_NOT_FOUND" );
  665. break;
  666. case SEC_E_NO_SPM:
  667. printf( " SEC_E_NO_SPM" );
  668. break;
  669. case SEC_E_BAD_PKGID:
  670. printf( " SEC_E_BAD_PKGID" ); break;
  671. case SEC_E_NOT_OWNER:
  672. printf( " SEC_E_NOT_OWNER" ); break;
  673. case SEC_E_CANNOT_INSTALL:
  674. printf( " SEC_E_CANNOT_INSTALL" ); break;
  675. case SEC_E_INVALID_TOKEN:
  676. printf( " SEC_E_INVALID_TOKEN" ); break;
  677. case SEC_E_CANNOT_PACK:
  678. printf( " SEC_E_CANNOT_PACK" ); break;
  679. case SEC_E_QOP_NOT_SUPPORTED:
  680. printf( " SEC_E_QOP_NOT_SUPPORTED" ); break;
  681. case SEC_E_NO_IMPERSONATION:
  682. printf( " SEC_E_NO_IMPERSONATION" ); break;
  683. case SEC_E_LOGON_DENIED:
  684. printf( " SEC_E_LOGON_DENIED" ); break;
  685. case SEC_E_UNKNOWN_CREDENTIALS:
  686. printf( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
  687. case SEC_E_NO_CREDENTIALS:
  688. printf( " SEC_E_NO_CREDENTIALS" ); break;
  689. case SEC_E_MESSAGE_ALTERED:
  690. printf( " SEC_E_MESSAGE_ALTERED" ); break;
  691. case SEC_E_OUT_OF_SEQUENCE:
  692. printf( " SEC_E_OUT_OF_SEQUENCE" ); break;
  693. case SEC_E_INSUFFICIENT_MEMORY:
  694. printf( " SEC_E_INSUFFICIENT_MEMORY" ); break;
  695. case SEC_E_INVALID_HANDLE:
  696. printf( " SEC_E_INVALID_HANDLE" ); break;
  697. case SEC_E_NOT_SUPPORTED:
  698. printf( " SEC_E_NOT_SUPPORTED" ); break;
  699. case SEC_I_CONTINUE_NEEDED:
  700. printf( " SEC_I_CONTINUE_NEEDED" ); break;
  701. }
  702. printf( "\n" );
  703. }
  704. void
  705. MyPrintTime(
  706. LPSTR Comment,
  707. TimeStamp ConvertTime
  708. )
  709. /*++
  710. Routine Description:
  711. Print the specified time
  712. Arguments:
  713. Comment - Comment to print in front of the time
  714. Time - Local time to print
  715. Return Value:
  716. None
  717. --*/
  718. {
  719. LARGE_INTEGER LocalTime;
  720. NTSTATUS Status;
  721. printf( "%s High/low 0x%x/0x%x: ", Comment, ConvertTime.HighPart, ConvertTime.LowPart);
  722. //
  723. // If the time is infinite,
  724. // just say so.
  725. //
  726. if ( (ConvertTime.HighPart == 0x7FFFFFFF) && (ConvertTime.LowPart == 0xFFFFFFFF) ) {
  727. printf( "Infinite\n" );
  728. //
  729. // Otherwise print it more clearly
  730. //
  731. } else {
  732. LocalTime.HighPart = 0;
  733. LocalTime.LowPart = 0;
  734. Status = RtlSystemTimeToLocalTime( &ConvertTime, &LocalTime );
  735. if (!NT_SUCCESS( Status )) {
  736. printf( "Can't convert time from GMT to Local time\n" );
  737. LocalTime = ConvertTime;
  738. }
  739. TIME_FIELDS TimeFields;
  740. RtlTimeToTimeFields( &LocalTime, &TimeFields );
  741. printf( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
  742. TimeFields.Month,
  743. TimeFields.Day,
  744. TimeFields.Year,
  745. TimeFields.Hour,
  746. TimeFields.Minute,
  747. TimeFields.Second );
  748. }
  749. }
  750. // Support Routines
  751. //+-------------------------------------------------------------------------
  752. //
  753. // Function: StringAllocate
  754. //
  755. // Synopsis: Allocates cb chars to STRING Buffer
  756. //
  757. // Arguments: pString - pointer to String to allocate memory to
  758. //
  759. // Returns: STATUS_SUCCESS - Normal completion
  760. //
  761. // Requires:
  762. //
  763. // Effects: allocates memory and sets STRING sizes
  764. //
  765. // Notes: Must call StringFree() to release memory
  766. //
  767. //--------------------------------------------------------------------------
  768. NTSTATUS
  769. StringAllocate(
  770. IN PSTRING pString,
  771. IN USHORT cb
  772. )
  773. {
  774. // DebugLog((DEB_TRACE, "NTDigest:Entering StringAllocate\n"));
  775. NTSTATUS Status = STATUS_SUCCESS;
  776. cb = cb + 1; // Add in extra room for the terminating NULL
  777. if (ARGUMENT_PRESENT(pString))
  778. {
  779. pString->Length = 0;
  780. pString->Buffer = (char *)DigestAllocateMemory((ULONG)(cb * sizeof(CHAR)));
  781. if (pString->Buffer)
  782. {
  783. pString->MaximumLength = cb;
  784. }
  785. else
  786. {
  787. pString->MaximumLength = 0;
  788. Status = STATUS_NO_MEMORY;
  789. goto CleanUp;
  790. }
  791. }
  792. else
  793. {
  794. Status = STATUS_INVALID_PARAMETER;
  795. goto CleanUp;
  796. }
  797. CleanUp:
  798. // DebugLog((DEB_TRACE, "NTDigest: Leaving StringAllocate\n"));
  799. return(Status);
  800. }
  801. //+-------------------------------------------------------------------------
  802. //
  803. // Function: StringFree
  804. //
  805. // Synopsis: Clears a String and releases the memory
  806. //
  807. // Arguments: pString - pointer to String to clear
  808. //
  809. // Returns: SEC_E_OK - released memory succeeded
  810. //
  811. // Requires:
  812. //
  813. // Effects: de-allocates memory with LsaFunctions.AllocateLsaHeap
  814. //
  815. // Notes:
  816. //
  817. //--------------------------------------------------------------------------
  818. NTSTATUS
  819. StringFree(
  820. IN PSTRING pString
  821. )
  822. {
  823. // DebugLog((DEB_TRACE, "NTDigest:Entering StringFree\n"));
  824. NTSTATUS Status = STATUS_SUCCESS;
  825. if (ARGUMENT_PRESENT(pString) &&
  826. (pString->Buffer != NULL))
  827. {
  828. DigestFreeMemory(pString->Buffer);
  829. pString->Length = 0;
  830. pString->MaximumLength = 0;
  831. pString->Buffer = NULL;
  832. }
  833. // DebugLog((DEB_TRACE, "NTDigest: Leaving StringFree\n"));
  834. return(Status);
  835. }
  836. //+-------------------------------------------------------------------------
  837. //
  838. // Function: StringCharDuplicate
  839. //
  840. // Synopsis: Duplicates a NULL terminated char. If the source string buffer is
  841. // NULL the destionation will be too.
  842. //
  843. // Arguments: Destination - Receives a copy of the source NULL Term char *
  844. // czSource - String to copy
  845. //
  846. // Returns: SEC_E_OK - the copy succeeded
  847. // SEC_E_INSUFFICIENT_MEMORY - the call to allocate
  848. // memory failed.
  849. //
  850. // Requires:
  851. //
  852. // Effects: allocates memory with LsaFunctions.AllocateLsaHeap
  853. //
  854. // Notes:
  855. //
  856. //
  857. //--------------------------------------------------------------------------
  858. NTSTATUS
  859. StringCharDuplicate(
  860. OUT PSTRING DestinationString,
  861. IN OPTIONAL char *czSource
  862. )
  863. {
  864. // DebugLog((DEB_TRACE, "NTDigest: Entering StringCharDuplicate\n"));
  865. NTSTATUS Status = STATUS_SUCCESS;
  866. USHORT cbSourceCz = 0;
  867. DestinationString->Buffer = NULL;
  868. DestinationString->Length = 0;
  869. DestinationString->MaximumLength = 0;
  870. if ((ARGUMENT_PRESENT(czSource)) &&
  871. ((cbSourceCz = strlen(czSource)) != 0))
  872. {
  873. DestinationString->Buffer = (LPSTR) DigestAllocateMemory(cbSourceCz + sizeof(CHAR));
  874. if (DestinationString->Buffer != NULL)
  875. {
  876. DestinationString->Length = cbSourceCz;
  877. DestinationString->MaximumLength = cbSourceCz + sizeof(CHAR);
  878. RtlCopyMemory(
  879. DestinationString->Buffer,
  880. czSource,
  881. cbSourceCz
  882. );
  883. DestinationString->Buffer[cbSourceCz/sizeof(CHAR)] = '\0';
  884. }
  885. else
  886. {
  887. Status = STATUS_NO_MEMORY;
  888. // DebugLog((DEB_ERROR, "NTDigest: StringCharDuplicate, DigestAllocateMemory returns NULL\n"));
  889. goto CleanUp;
  890. }
  891. }
  892. CleanUp:
  893. // DebugLog((DEB_TRACE, "NTDigest: Leaving StringCharDuplicate\n"));
  894. return(Status);
  895. }
  896. //+-------------------------------------------------------------------------
  897. //
  898. // Function: DigestAllocateMemory
  899. //
  900. // Synopsis: Allocate memory in either lsa mode or user mode
  901. //
  902. // Effects: Allocated chunk is zeroed out
  903. //
  904. // Arguments:
  905. //
  906. // Requires:
  907. //
  908. // Returns:
  909. //
  910. // Notes:
  911. //
  912. //
  913. //--------------------------------------------------------------------------
  914. PVOID
  915. DigestAllocateMemory(
  916. IN ULONG BufferSize
  917. )
  918. {
  919. PVOID Buffer = NULL;
  920. // DebugLog((DEB_TRACE, "Entering DigestAllocateMemory\n"));
  921. Buffer = LocalAlloc(LPTR, BufferSize);
  922. // DebugLog((DEB_TRACE, "Leaving DigestAllocateMemory\n"));
  923. return Buffer;
  924. }
  925. //+-------------------------------------------------------------------------
  926. //
  927. // Function: NtLmFree
  928. //
  929. // Synopsis: Free memory in either lsa mode or user mode
  930. //
  931. // Effects:
  932. //
  933. // Arguments:
  934. //
  935. // Requires:
  936. //
  937. // Returns:
  938. //
  939. // Notes:
  940. //
  941. //
  942. //--------------------------------------------------------------------------
  943. VOID
  944. DigestFreeMemory(
  945. IN PVOID Buffer
  946. )
  947. {
  948. // DebugLog((DEB_TRACE, "Entering DigestFreeMemory\n"));
  949. LocalFree(Buffer);
  950. // DebugLog((DEB_TRACE, "Leaving DigestFreeMemory\n"));
  951. }
  952. /*
  953. //+-------------------------------------------------------------------------
  954. //
  955. // Function: DecodeUnicodeString
  956. //
  957. // Synopsis: Convert an encoded string into Unicode
  958. //
  959. // Arguments: pstrSource - pointer to String with encoded input
  960. //
  961. // pustrDestination - pointer to a destination Unicode string
  962. //
  963. // Returns: STATUS_SUCCESS - Normal completion
  964. //
  965. // Requires:
  966. //
  967. // Effects: allocates memory and sets UNICODE_STRING sizes
  968. //
  969. // Notes: Must call UnicodeStringFree() to release memory
  970. //
  971. //--------------------------------------------------------------------------
  972. NTSTATUS
  973. DecodeUnicodeString(
  974. IN PSTRING pstrSource,
  975. IN UINT CodePage,
  976. OUT PUNICODE_STRING pustrDestination
  977. )
  978. {
  979. NTSTATUS Status = STATUS_SUCCESS;
  980. int cNumWChars = 0; // number of wide characters
  981. int cb = 0; // number of bytes to allocate
  982. int iRC = 0; // return code
  983. DWORD dwError = 0;
  984. // Handle case if there is no characters to convert
  985. if (!pstrSource->Length)
  986. {
  987. pustrDestination->Length = 0;
  988. pustrDestination->MaximumLength = 0;
  989. pustrDestination->Buffer = NULL;
  990. goto CleanUp;
  991. }
  992. // Determine number of characters needed in unicode string
  993. cNumWChars = MultiByteToWideChar(CodePage,
  994. 0,
  995. pstrSource->Buffer,
  996. pstrSource->Length,
  997. NULL,
  998. 0);
  999. if (cNumWChars <= 0)
  1000. {
  1001. Status = E_FAIL;
  1002. dwError = GetLastError();
  1003. goto CleanUp;
  1004. }
  1005. Status = UnicodeStringAllocate(pustrDestination, (USHORT)cNumWChars);
  1006. if (!NT_SUCCESS(Status))
  1007. {
  1008. goto CleanUp;
  1009. }
  1010. // We now have the space allocated so convert encoded unicode
  1011. iRC = MultiByteToWideChar(CodePage,
  1012. 0,
  1013. pstrSource->Buffer,
  1014. pstrSource->Length,
  1015. pustrDestination->Buffer,
  1016. cNumWChars);
  1017. if (iRC == 0)
  1018. {
  1019. UnicodeStringFree(pustrDestination); // Free up allocation on error
  1020. Status = E_FAIL;
  1021. dwError = GetLastError();
  1022. goto CleanUp;
  1023. }
  1024. // decoding successful set size of unicode string
  1025. pustrDestination->Length = (USHORT)(iRC * sizeof(WCHAR));
  1026. CleanUp:
  1027. return Status;
  1028. }
  1029. //+-------------------------------------------------------------------------
  1030. //
  1031. // Function: UnicodeStringDuplicate
  1032. //
  1033. // Synopsis: Duplicates a UNICODE_STRING. If the source string buffer is
  1034. // NULL the destionation will be too. Assumes Destination has
  1035. // no string info (called ClearUnicodeString)
  1036. //
  1037. // Arguments: DestinationString - Receives a copy of the source string
  1038. // SourceString - String to copy
  1039. //
  1040. // Returns: SEC_E_OK - the copy succeeded
  1041. // SEC_E_INSUFFICIENT_MEMORY - the call to allocate
  1042. // memory failed.
  1043. //
  1044. // Requires:
  1045. //
  1046. // Effects: allocates memory with DigestAllocateMemory
  1047. //
  1048. // Notes: will add a NULL character to resulting UNICODE_STRING
  1049. //
  1050. //--------------------------------------------------------------------------
  1051. NTSTATUS
  1052. UnicodeStringDuplicate(
  1053. OUT PUNICODE_STRING DestinationString,
  1054. IN OPTIONAL PUNICODE_STRING SourceString
  1055. )
  1056. {
  1057. // DebugLog((DEB_TRACE, "NTDigest:Entering DuplicateUnicodeString\n"));
  1058. NTSTATUS Status = STATUS_SUCCESS;
  1059. DestinationString->Buffer = NULL;
  1060. DestinationString->Length = 0;
  1061. DestinationString->MaximumLength = 0;
  1062. if ((ARGUMENT_PRESENT(SourceString)) &&
  1063. (SourceString->Buffer != NULL))
  1064. {
  1065. DestinationString->Buffer = (LPWSTR) DigestAllocateMemory(SourceString->Length + sizeof(WCHAR));
  1066. if (DestinationString->Buffer != NULL)
  1067. {
  1068. DestinationString->Length = SourceString->Length;
  1069. DestinationString->MaximumLength = SourceString->Length + sizeof(WCHAR);
  1070. RtlCopyMemory(
  1071. DestinationString->Buffer,
  1072. SourceString->Buffer,
  1073. SourceString->Length
  1074. );
  1075. DestinationString->Buffer[SourceString->Length/sizeof(WCHAR)] = L'\0';
  1076. }
  1077. else
  1078. {
  1079. Status = SEC_E_INSUFFICIENT_MEMORY;
  1080. goto CleanUp;
  1081. }
  1082. }
  1083. CleanUp:
  1084. // DebugLog((DEB_TRACE, "NTDigest: Leaving UnicodeStringDuplicate\n"));
  1085. return(Status);
  1086. }
  1087. //+-------------------------------------------------------------------------
  1088. //
  1089. // Function: UnicodeStringAllocate
  1090. //
  1091. // Synopsis: Allocates cb wide chars to STRING Buffer
  1092. //
  1093. // Arguments: pString - pointer to String to allocate memory to
  1094. //
  1095. // Returns: STATUS_SUCCESS - Normal completion
  1096. //
  1097. // Requires:
  1098. //
  1099. // Effects: allocates memory and sets STRING sizes
  1100. //
  1101. // Notes: Must call StringFree() to release memory
  1102. //
  1103. //--------------------------------------------------------------------------
  1104. NTSTATUS
  1105. UnicodeStringAllocate(
  1106. IN PUNICODE_STRING pString,
  1107. IN USHORT cNumWChars
  1108. )
  1109. {
  1110. // DebugLog((DEB_TRACE, "Entering UnicodeStringAllocate\n"));
  1111. NTSTATUS Status = STATUS_SUCCESS;
  1112. USHORT cb = 0;
  1113. cb = cNumWChars + 1; // Add in extra room for the terminating NULL
  1114. cb = cb * sizeof(WCHAR); // now convert to wide characters
  1115. if (ARGUMENT_PRESENT(pString))
  1116. {
  1117. pString->Length = 0;
  1118. pString->Buffer = (PWSTR)DigestAllocateMemory((ULONG)(cb));
  1119. if (pString->Buffer)
  1120. {
  1121. pString->MaximumLength = cb; // this value is in terms of bytes not WCHAR count
  1122. }
  1123. else
  1124. {
  1125. pString->MaximumLength = 0;
  1126. Status = SEC_E_INSUFFICIENT_MEMORY;
  1127. goto CleanUp;
  1128. }
  1129. }
  1130. else
  1131. {
  1132. Status = STATUS_INVALID_PARAMETER;
  1133. goto CleanUp;
  1134. }
  1135. CleanUp:
  1136. return(Status);
  1137. }
  1138. //+-------------------------------------------------------------------------
  1139. //
  1140. // Function: UnicodeStringClear
  1141. //
  1142. // Synopsis: Clears a UnicodeString and releases the memory
  1143. //
  1144. // Arguments: pString - pointer to UnicodeString to clear
  1145. //
  1146. // Returns: SEC_E_OK - released memory succeeded
  1147. //
  1148. // Requires:
  1149. //
  1150. // Effects: de-allocates memory with LsaFunctions.AllocateLsaHeap
  1151. //
  1152. // Notes:
  1153. //
  1154. //--------------------------------------------------------------------------
  1155. NTSTATUS
  1156. UnicodeStringFree(
  1157. OUT PUNICODE_STRING pString
  1158. )
  1159. {
  1160. NTSTATUS Status = STATUS_SUCCESS;
  1161. if (ARGUMENT_PRESENT(pString) &&
  1162. (pString->Buffer != NULL))
  1163. {
  1164. DigestFreeMemory(pString->Buffer);
  1165. pString->Length = 0;
  1166. pString->MaximumLength = 0;
  1167. pString->Buffer = NULL;
  1168. }
  1169. return(Status);
  1170. }
  1171. */