Leaked source code of windows server 2003
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.

1204 lines
30 KiB

  1. /*--
  2. Copyright (c) 1987-1993 Microsoft Corporation
  3. Module Name:
  4. ssptest.c
  5. Abstract:
  6. Test program for the NtLmSsp service.
  7. Author:
  8. 28-Jun-1993 (cliffv)
  9. Environment:
  10. User mode only.
  11. Contains NT-specific code.
  12. Requires ANSI C extensions: slash-slash comments, long external names.
  13. Revision History:
  14. --*/
  15. //
  16. // Common include files.
  17. //
  18. #include <nt.h>
  19. #include <ntrtl.h>
  20. #include <nturtl.h>
  21. #include <windef.h>
  22. #include <winbase.h>
  23. #include <winsvc.h> // Needed for service controller APIs
  24. #include <lmcons.h>
  25. #include <lmerr.h>
  26. #include <lmsname.h>
  27. #include <rpc.h>
  28. #include <stdio.h> // printf
  29. #include <stdlib.h> // strtoul
  30. #include <tstring.h> // NetpAllocWStrFromWStr
  31. #include <security.h> // General definition of a Security Support Provider
  32. #include <ntmsv1_0.h>
  33. #include <ntlmsp.h> // External definition of the NtLmSsp service
  34. BOOLEAN QuietMode = FALSE; // Don't be verbose
  35. // BUGBUG Should be in the SDK?
  36. #define MSV1_0_PACKAGE_NAMEW L"MICROSOFT_AUTHENTICATION_PACKAGE_V1_0"
  37. #define KERBEROS_PACKAGE_NAME "Kerberos"
  38. VOID
  39. DumpBuffer(
  40. PVOID Buffer,
  41. DWORD BufferSize
  42. )
  43. /*++
  44. Routine Description:
  45. Dumps the buffer content on to the debugger output.
  46. Arguments:
  47. Buffer: buffer pointer.
  48. BufferSize: size of the buffer.
  49. Return Value:
  50. none
  51. --*/
  52. {
  53. #define NUM_CHARS 16
  54. DWORD i, limit;
  55. CHAR TextBuffer[NUM_CHARS + 1];
  56. LPBYTE BufferPtr = Buffer;
  57. printf("------------------------------------\n");
  58. //
  59. // Hex dump of the bytes
  60. //
  61. limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS;
  62. for (i = 0; i < limit; i++) {
  63. if (i < BufferSize) {
  64. printf("%02x ", BufferPtr[i]);
  65. if (BufferPtr[i] < 31 ) {
  66. TextBuffer[i % NUM_CHARS] = '.';
  67. } else if (BufferPtr[i] == '\0') {
  68. TextBuffer[i % NUM_CHARS] = ' ';
  69. } else {
  70. TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i];
  71. }
  72. } else {
  73. printf(" ");
  74. TextBuffer[i % NUM_CHARS] = ' ';
  75. }
  76. if ((i + 1) % NUM_CHARS == 0) {
  77. TextBuffer[NUM_CHARS] = 0;
  78. printf(" %s\n", TextBuffer);
  79. }
  80. }
  81. printf("------------------------------------\n");
  82. }
  83. VOID
  84. PrintTime(
  85. LPSTR Comment,
  86. TimeStamp ConvertTime
  87. )
  88. /*++
  89. Routine Description:
  90. Print the specified time
  91. Arguments:
  92. Comment - Comment to print in front of the time
  93. Time - Local time to print
  94. Return Value:
  95. None
  96. --*/
  97. {
  98. LARGE_INTEGER LocalTime;
  99. LocalTime.HighPart = ConvertTime.HighPart;
  100. LocalTime.LowPart = ConvertTime.LowPart;
  101. printf( "%s", Comment );
  102. //
  103. // If the time is infinite,
  104. // just say so.
  105. //
  106. if ( LocalTime.HighPart == 0x7FFFFFFF && LocalTime.LowPart == 0xFFFFFFFF ) {
  107. printf( "Infinite\n" );
  108. //
  109. // Otherwise print it more clearly
  110. //
  111. } else {
  112. TIME_FIELDS TimeFields = {0};
  113. /*
  114. RtlTimeToTimeFields( &LocalTime, &TimeFields );
  115. */
  116. printf( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
  117. TimeFields.Month,
  118. TimeFields.Day,
  119. TimeFields.Year,
  120. TimeFields.Hour,
  121. TimeFields.Minute,
  122. TimeFields.Second );
  123. }
  124. }
  125. VOID
  126. PrintStatus(
  127. NET_API_STATUS NetStatus
  128. )
  129. /*++
  130. Routine Description:
  131. Print a net status code.
  132. Arguments:
  133. NetStatus - The net status code to print.
  134. Return Value:
  135. None
  136. --*/
  137. {
  138. printf( "Status = %lu 0x%lx", NetStatus, NetStatus );
  139. switch (NetStatus) {
  140. case NERR_Success:
  141. printf( " NERR_Success" );
  142. break;
  143. case NERR_DCNotFound:
  144. printf( " NERR_DCNotFound" );
  145. break;
  146. case ERROR_LOGON_FAILURE:
  147. printf( " ERROR_LOGON_FAILURE" );
  148. break;
  149. case ERROR_ACCESS_DENIED:
  150. printf( " ERROR_ACCESS_DENIED" );
  151. break;
  152. case ERROR_NOT_SUPPORTED:
  153. printf( " ERROR_NOT_SUPPORTED" );
  154. break;
  155. case ERROR_NO_LOGON_SERVERS:
  156. printf( " ERROR_NO_LOGON_SERVERS" );
  157. break;
  158. case ERROR_NO_SUCH_DOMAIN:
  159. printf( " ERROR_NO_SUCH_DOMAIN" );
  160. break;
  161. case ERROR_NO_TRUST_LSA_SECRET:
  162. printf( " ERROR_NO_TRUST_LSA_SECRET" );
  163. break;
  164. case ERROR_NO_TRUST_SAM_ACCOUNT:
  165. printf( " ERROR_NO_TRUST_SAM_ACCOUNT" );
  166. break;
  167. case ERROR_DOMAIN_TRUST_INCONSISTENT:
  168. printf( " ERROR_DOMAIN_TRUST_INCONSISTENT" );
  169. break;
  170. case ERROR_BAD_NETPATH:
  171. printf( " ERROR_BAD_NETPATH" );
  172. break;
  173. case ERROR_FILE_NOT_FOUND:
  174. printf( " ERROR_FILE_NOT_FOUND" );
  175. break;
  176. case NERR_NetNotStarted:
  177. printf( " NERR_NetNotStarted" );
  178. break;
  179. case NERR_WkstaNotStarted:
  180. printf( " NERR_WkstaNotStarted" );
  181. break;
  182. case NERR_ServerNotStarted:
  183. printf( " NERR_ServerNotStarted" );
  184. break;
  185. case NERR_BrowserNotStarted:
  186. printf( " NERR_BrowserNotStarted" );
  187. break;
  188. case NERR_ServiceNotInstalled:
  189. printf( " NERR_ServiceNotInstalled" );
  190. break;
  191. case NERR_BadTransactConfig:
  192. printf( " NERR_BadTransactConfig" );
  193. break;
  194. case SEC_E_NO_SPM:
  195. printf( " SEC_E_NO_SPM" );
  196. break;
  197. case SEC_E_BAD_PKGID:
  198. printf( " SEC_E_BAD_PKGID" ); break;
  199. case SEC_E_NOT_OWNER:
  200. printf( " SEC_E_NOT_OWNER" ); break;
  201. case SEC_E_CANNOT_INSTALL:
  202. printf( " SEC_E_CANNOT_INSTALL" ); break;
  203. case SEC_E_INVALID_TOKEN:
  204. printf( " SEC_E_INVALID_TOKEN" ); break;
  205. case SEC_E_CANNOT_PACK:
  206. printf( " SEC_E_CANNOT_PACK" ); break;
  207. case SEC_E_QOP_NOT_SUPPORTED:
  208. printf( " SEC_E_QOP_NOT_SUPPORTED" ); break;
  209. case SEC_E_NO_IMPERSONATION:
  210. printf( " SEC_E_NO_IMPERSONATION" ); break;
  211. case SEC_E_LOGON_DENIED:
  212. printf( " SEC_E_LOGON_DENIED" ); break;
  213. case SEC_E_UNKNOWN_CREDENTIALS:
  214. printf( " SEC_E_UNKNOWN_CREDENTIALS" ); break;
  215. case SEC_E_NO_CREDENTIALS:
  216. printf( " SEC_E_NO_CREDENTIALS" ); break;
  217. case SEC_E_MESSAGE_ALTERED:
  218. printf( " SEC_E_MESSAGE_ALTERED" ); break;
  219. case SEC_E_OUT_OF_SEQUENCE:
  220. printf( " SEC_E_OUT_OF_SEQUENCE" ); break;
  221. case SEC_E_INSUFFICIENT_MEMORY:
  222. printf( " SEC_E_INSUFFICIENT_MEMORY" ); break;
  223. case SEC_E_INVALID_HANDLE:
  224. printf( " SEC_E_INVALID_HANDLE" ); break;
  225. case SEC_E_NOT_SUPPORTED:
  226. printf( " SEC_E_NOT_SUPPORTED" ); break;
  227. case SEC_I_CONTINUE_NEEDED:
  228. printf( " SEC_I_CONTINUE_NEEDED" ); break;
  229. }
  230. printf( "\n" );
  231. }
  232. VOID
  233. TestLpcRoutine(
  234. LPWSTR DomainName,
  235. LPWSTR UserName,
  236. LPWSTR Password
  237. )
  238. /*++
  239. Routine Description:
  240. Test base LPC functionality
  241. Arguments:
  242. None
  243. Return Value:
  244. None
  245. --*/
  246. {
  247. SECURITY_STATUS SecStatus;
  248. CredHandle CredentialHandle1;
  249. CredHandle CredentialHandle2;
  250. CtxtHandle ClientContextHandle;
  251. CtxtHandle ServerContextHandle;
  252. TimeStamp Lifetime;
  253. ULONG ContextAttributes;
  254. ULONG PackageCount,i;
  255. PSecPkgInfo PackageInfo;
  256. PSecPkgInfo pTmp;
  257. SEC_WINNT_AUTH_IDENTITY AuthIdentity;
  258. SecBufferDesc NegotiateDesc;
  259. SecBuffer NegotiateBuffer;
  260. SecBufferDesc ChallengeDesc;
  261. SecBuffer ChallengeBuffer;
  262. SecBufferDesc AuthenticateDesc;
  263. SecBuffer AuthenticateBuffer;
  264. SecPkgContext_Sizes ContextSizes;
  265. SecPkgContext_Lifespan ContextLifespan;
  266. UCHAR ContextNamesBuffer[sizeof(SecPkgContext_Names)+UNLEN*sizeof(WCHAR)];
  267. PSecPkgContext_Names ContextNames = (PSecPkgContext_Names) ContextNamesBuffer;
  268. SecBufferDesc SignMessage;
  269. SecBuffer SigBuffers[2];
  270. BYTE bDataBuffer[20];
  271. BYTE bSigBuffer[100];
  272. NegotiateBuffer.pvBuffer = NULL;
  273. ChallengeBuffer.pvBuffer = NULL;
  274. AuthenticateBuffer.pvBuffer = NULL;
  275. SigBuffers[1].pvBuffer = bSigBuffer;
  276. SigBuffers[1].cbBuffer = sizeof(bSigBuffer);
  277. SigBuffers[1].BufferType = SECBUFFER_TOKEN;
  278. SigBuffers[0].pvBuffer = bDataBuffer;
  279. SigBuffers[0].cbBuffer = sizeof(bDataBuffer);
  280. SigBuffers[0].BufferType = SECBUFFER_DATA;
  281. memset(bDataBuffer,0xeb,sizeof(bDataBuffer));
  282. SignMessage.pBuffers = SigBuffers;
  283. SignMessage.cBuffers = 2;
  284. SignMessage.ulVersion = 0;
  285. //
  286. // Get info about the security packages.
  287. //
  288. SecStatus = EnumerateSecurityPackages( &PackageCount, &PackageInfo );
  289. if ( SecStatus != STATUS_SUCCESS ) {
  290. printf( "EnumerateSecurityPackages failed:" );
  291. PrintStatus( SecStatus );
  292. return;
  293. }
  294. if ( !QuietMode ) {
  295. printf( "PackageCount: %ld\n", PackageCount );
  296. for ( i= 0; i< PackageCount; i++)
  297. {
  298. pTmp = (PackageInfo + i);
  299. printf( "Name: %ws Comment: %ws\n", pTmp->Name, pTmp->Comment );
  300. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  301. pTmp->fCapabilities,
  302. pTmp->wVersion,
  303. pTmp->wRPCID,
  304. pTmp->cbMaxToken );
  305. }
  306. }
  307. //
  308. // Get info about the security packages.
  309. //
  310. SecStatus = QuerySecurityPackageInfo( KERBEROS_PACKAGE_NAME, &PackageInfo );
  311. if ( SecStatus != STATUS_SUCCESS ) {
  312. printf( "QuerySecurityPackageInfo failed:" );
  313. PrintStatus( SecStatus );
  314. return;
  315. }
  316. if ( !QuietMode ) {
  317. printf( "Name: %ws Comment: %ws\n", PackageInfo->Name, PackageInfo->Comment );
  318. printf( "Cap: %ld Version: %ld RPCid: %ld MaxToken: %ld\n\n",
  319. PackageInfo->fCapabilities,
  320. PackageInfo->wVersion,
  321. PackageInfo->wRPCID,
  322. PackageInfo->cbMaxToken );
  323. }
  324. //
  325. // Acquire a credential handle for the server side
  326. //
  327. SecStatus = AcquireCredentialsHandle(
  328. NULL, // New principal
  329. KERBEROS_PACKAGE_NAME, // Package Name
  330. SECPKG_CRED_INBOUND,
  331. NULL,
  332. NULL,
  333. NULL,
  334. NULL,
  335. &CredentialHandle1,
  336. &Lifetime );
  337. if ( SecStatus != STATUS_SUCCESS ) {
  338. printf( "AcquireCredentialsHandle failed: ");
  339. PrintStatus( SecStatus );
  340. return;
  341. }
  342. if ( !QuietMode ) {
  343. printf( "CredentialHandle1: 0x%lx 0x%lx ",
  344. CredentialHandle1.dwLower, CredentialHandle1.dwUpper );
  345. PrintTime( "Lifetime: ", Lifetime );
  346. }
  347. //
  348. // Acquire a credential handle for the client side
  349. //
  350. RtlZeroMemory( &AuthIdentity, sizeof(AuthIdentity) );
  351. #define DO_OEM 1
  352. #ifndef DO_OEM
  353. if ( DomainName != NULL ) {
  354. AuthIdentity.Domain = DomainName;
  355. AuthIdentity.DomainLength = wcslen(DomainName);
  356. }
  357. if ( UserName != NULL ) {
  358. AuthIdentity.User = UserName;
  359. AuthIdentity.UserLength = wcslen(UserName);
  360. }
  361. if ( Password != NULL ) {
  362. AuthIdentity.Password = Password;
  363. AuthIdentity.PasswordLength = wcslen(Password);
  364. }
  365. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  366. #else
  367. //
  368. // BUGBUG: memory leak here
  369. //
  370. if ( DomainName != NULL ) {
  371. AuthIdentity.Domain = (LPWSTR) NetpAllocStrFromWStr(DomainName);
  372. AuthIdentity.DomainLength = wcslen(DomainName);
  373. }
  374. if ( UserName != NULL ) {
  375. AuthIdentity.User = (LPWSTR) NetpAllocStrFromWStr(UserName);
  376. AuthIdentity.UserLength = wcslen(UserName);
  377. }
  378. if ( Password != NULL ) {
  379. AuthIdentity.Password = (LPWSTR) NetpAllocStrFromWStr(Password);
  380. AuthIdentity.PasswordLength = wcslen(Password);
  381. }
  382. AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  383. #endif
  384. SecStatus = AcquireCredentialsHandle(
  385. NULL, // New principal
  386. KERBEROS_PACKAGE_NAME, // Package Name
  387. SECPKG_CRED_OUTBOUND,
  388. NULL,
  389. (DomainName == NULL && UserName == NULL && Password == NULL) ?
  390. NULL : &AuthIdentity,
  391. NULL,
  392. NULL,
  393. &CredentialHandle2,
  394. &Lifetime );
  395. if ( SecStatus != STATUS_SUCCESS ) {
  396. printf( "AcquireCredentialsHandle failed: " );
  397. PrintStatus( SecStatus );
  398. return;
  399. }
  400. if ( !QuietMode ) {
  401. printf( "CredentialHandle2: 0x%lx 0x%lx ",
  402. CredentialHandle2.dwLower, CredentialHandle2.dwUpper );
  403. PrintTime( "Lifetime: ", Lifetime );
  404. }
  405. //
  406. // Get the NegotiateMessage (ClientSide)
  407. //
  408. NegotiateDesc.ulVersion = 0;
  409. NegotiateDesc.cBuffers = 1;
  410. NegotiateDesc.pBuffers = &NegotiateBuffer;
  411. NegotiateBuffer.cbBuffer = PackageInfo->cbMaxToken;
  412. NegotiateBuffer.BufferType = SECBUFFER_TOKEN;
  413. NegotiateBuffer.pvBuffer = LocalAlloc( 0, NegotiateBuffer.cbBuffer );
  414. if ( NegotiateBuffer.pvBuffer == NULL ) {
  415. printf( "Allocate NegotiateMessage failed: 0x%ld\n", GetLastError() );
  416. return;
  417. }
  418. SecStatus = InitializeSecurityContext(
  419. &CredentialHandle2,
  420. NULL, // No Client context yet
  421. "\\\\Frank\\IPC$", // Faked target name
  422. ISC_REQ_SEQUENCE_DETECT,
  423. 0, // Reserved 1
  424. SECURITY_NATIVE_DREP,
  425. NULL, // No initial input token
  426. 0, // Reserved 2
  427. &ClientContextHandle,
  428. &NegotiateDesc,
  429. &ContextAttributes,
  430. &Lifetime );
  431. if ( SecStatus != STATUS_SUCCESS ) {
  432. if ( !QuietMode || !NT_SUCCESS(SecStatus) ) {
  433. printf( "InitializeSecurityContext (negotiate): " );
  434. PrintStatus( SecStatus );
  435. }
  436. if ( !NT_SUCCESS(SecStatus) ) {
  437. return;
  438. }
  439. }
  440. if ( !QuietMode ) {
  441. printf( "\n\nNegotiate Message:\n" );
  442. printf( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  443. ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
  444. ContextAttributes );
  445. PrintTime( "Lifetime: ", Lifetime );
  446. DumpBuffer( NegotiateBuffer.pvBuffer, NegotiateBuffer.cbBuffer );
  447. }
  448. //
  449. // Get the ChallengeMessage (ServerSide)
  450. //
  451. NegotiateBuffer.BufferType |= SECBUFFER_READONLY;
  452. ChallengeDesc.ulVersion = 0;
  453. ChallengeDesc.cBuffers = 1;
  454. ChallengeDesc.pBuffers = &ChallengeBuffer;
  455. ChallengeBuffer.cbBuffer = PackageInfo->cbMaxToken;
  456. ChallengeBuffer.BufferType = SECBUFFER_TOKEN;
  457. ChallengeBuffer.pvBuffer = LocalAlloc( 0, ChallengeBuffer.cbBuffer );
  458. if ( ChallengeBuffer.pvBuffer == NULL ) {
  459. printf( "Allocate ChallengeMessage failed: 0x%ld\n", GetLastError() );
  460. return;
  461. }
  462. SecStatus = AcceptSecurityContext(
  463. &CredentialHandle1,
  464. NULL, // No Server context yet
  465. &NegotiateDesc,
  466. ISC_REQ_SEQUENCE_DETECT,
  467. SECURITY_NATIVE_DREP,
  468. &ServerContextHandle,
  469. &ChallengeDesc,
  470. &ContextAttributes,
  471. &Lifetime );
  472. if ( SecStatus != STATUS_SUCCESS ) {
  473. if ( !QuietMode || !NT_SUCCESS(SecStatus) ) {
  474. printf( "AcceptSecurityContext (Challenge): " );
  475. PrintStatus( SecStatus );
  476. }
  477. if ( !NT_SUCCESS(SecStatus) ) {
  478. return;
  479. }
  480. }
  481. if ( !QuietMode ) {
  482. printf( "\n\nChallenge Message:\n" );
  483. printf( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  484. ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
  485. ContextAttributes );
  486. PrintTime( "Lifetime: ", Lifetime );
  487. DumpBuffer( ChallengeBuffer.pvBuffer, ChallengeBuffer.cbBuffer );
  488. }
  489. //
  490. // Get the AuthenticateMessage (ClientSide)
  491. //
  492. ChallengeBuffer.BufferType |= SECBUFFER_READONLY;
  493. AuthenticateDesc.ulVersion = 0;
  494. AuthenticateDesc.cBuffers = 1;
  495. AuthenticateDesc.pBuffers = &AuthenticateBuffer;
  496. AuthenticateBuffer.cbBuffer = PackageInfo->cbMaxToken;
  497. AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
  498. AuthenticateBuffer.pvBuffer = LocalAlloc( 0, AuthenticateBuffer.cbBuffer );
  499. if ( AuthenticateBuffer.pvBuffer == NULL ) {
  500. printf( "Allocate AuthenticateMessage failed: 0x%ld\n", GetLastError() );
  501. return;
  502. }
  503. SecStatus = InitializeSecurityContext(
  504. NULL,
  505. &ClientContextHandle,
  506. "\\\\Frank\\IPC$", // Faked target name
  507. 0,
  508. 0, // Reserved 1
  509. SECURITY_NATIVE_DREP,
  510. &ChallengeDesc,
  511. 0, // Reserved 2
  512. &ClientContextHandle,
  513. &AuthenticateDesc,
  514. &ContextAttributes,
  515. &Lifetime );
  516. if ( SecStatus != STATUS_SUCCESS ) {
  517. printf( "InitializeSecurityContext (Authenticate): " );
  518. PrintStatus( SecStatus );
  519. if ( !NT_SUCCESS(SecStatus) ) {
  520. return;
  521. }
  522. }
  523. if ( !QuietMode ) {
  524. printf( "\n\nAuthenticate Message:\n" );
  525. printf( "ClientContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  526. ClientContextHandle.dwLower, ClientContextHandle.dwUpper,
  527. ContextAttributes );
  528. PrintTime( "Lifetime: ", Lifetime );
  529. DumpBuffer( AuthenticateBuffer.pvBuffer, AuthenticateBuffer.cbBuffer );
  530. }
  531. //
  532. // Finally authenticate the user (ServerSide)
  533. //
  534. AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
  535. SecStatus = AcceptSecurityContext(
  536. NULL,
  537. &ServerContextHandle,
  538. &AuthenticateDesc,
  539. 0,
  540. SECURITY_NATIVE_DREP,
  541. &ServerContextHandle,
  542. NULL,
  543. &ContextAttributes,
  544. &Lifetime );
  545. if ( SecStatus != STATUS_SUCCESS ) {
  546. printf( "AcceptSecurityContext (Challenge): " );
  547. PrintStatus( SecStatus );
  548. if ( !NT_SUCCESS(SecStatus) ) {
  549. return;
  550. }
  551. }
  552. if ( !QuietMode ) {
  553. printf( "\n\nFinal Authentication:\n" );
  554. printf( "ServerContextHandle: 0x%lx 0x%lx Attributes: 0x%lx ",
  555. ServerContextHandle.dwLower, ServerContextHandle.dwUpper,
  556. ContextAttributes );
  557. PrintTime( "Lifetime: ", Lifetime );
  558. printf(" \n" );
  559. }
  560. //
  561. // Query as many attributes as possible
  562. //
  563. SecStatus = QueryContextAttributes(
  564. &ClientContextHandle,
  565. SECPKG_ATTR_SIZES,
  566. &ContextSizes );
  567. if ( SecStatus != STATUS_SUCCESS ) {
  568. printf( "QueryContextAttributes (sizes): " );
  569. PrintStatus( SecStatus );
  570. if ( !NT_SUCCESS(SecStatus) ) {
  571. return;
  572. }
  573. }
  574. if ( !QuietMode ) {
  575. printf( "QuerySizes: %ld %ld %ld %ld\n",
  576. ContextSizes.cbMaxToken,
  577. ContextSizes.cbMaxSignature,
  578. ContextSizes.cbBlockSize,
  579. ContextSizes.cbSecurityTrailer );
  580. }
  581. SecStatus = QueryContextAttributes(
  582. &ClientContextHandle,
  583. SECPKG_ATTR_NAMES,
  584. ContextNamesBuffer );
  585. if ( SecStatus != STATUS_SUCCESS ) {
  586. printf( "QueryContextAttributes (names): " );
  587. PrintStatus( SecStatus );
  588. if ( !NT_SUCCESS(SecStatus) ) {
  589. return;
  590. }
  591. }
  592. if ( !QuietMode ) {
  593. printf( "QueryNames: %ws\n", ContextNames->sUserName );
  594. }
  595. SecStatus = QueryContextAttributes(
  596. &ClientContextHandle,
  597. SECPKG_ATTR_LIFESPAN,
  598. &ContextLifespan );
  599. if ( SecStatus != STATUS_SUCCESS ) {
  600. printf( "QueryContextAttributes (lifespan): " );
  601. PrintStatus( SecStatus );
  602. }
  603. if ( NT_SUCCESS(SecStatus) )
  604. {
  605. if ( !QuietMode )
  606. {
  607. PrintTime(" Start:", ContextLifespan.tsStart );
  608. PrintTime(" Expiry:", ContextLifespan.tsExpiry );
  609. }
  610. }
  611. //
  612. // Get the ChallengeMessage (ServerSide)
  613. //
  614. // Now make a third call to Initialize to check that RPC can
  615. // reauthenticate.
  616. //
  617. AuthenticateBuffer.BufferType = SECBUFFER_TOKEN;
  618. SecStatus = InitializeSecurityContext(
  619. NULL,
  620. &ClientContextHandle,
  621. "\\\\Frank\\IPC$", // Faked target name
  622. 0,
  623. 0, // Reserved 1
  624. SECURITY_NATIVE_DREP,
  625. NULL,
  626. 0, // Reserved 2
  627. &ClientContextHandle,
  628. &AuthenticateDesc,
  629. &ContextAttributes,
  630. &Lifetime );
  631. if ( SecStatus != STATUS_SUCCESS ) {
  632. printf( "InitializeSecurityContext (Re-Authenticate): " );
  633. PrintStatus( SecStatus );
  634. if ( !NT_SUCCESS(SecStatus) ) {
  635. return;
  636. }
  637. }
  638. //
  639. // Now try to re-authenticate the user (ServerSide)
  640. //
  641. AuthenticateBuffer.BufferType |= SECBUFFER_READONLY;
  642. SecStatus = AcceptSecurityContext(
  643. NULL,
  644. &ServerContextHandle,
  645. &AuthenticateDesc,
  646. 0,
  647. SECURITY_NATIVE_DREP,
  648. &ServerContextHandle,
  649. NULL,
  650. &ContextAttributes,
  651. &Lifetime );
  652. if ( SecStatus != STATUS_SUCCESS ) {
  653. printf( "AcceptSecurityContext (Re-authenticate): " );
  654. PrintStatus( SecStatus );
  655. if ( !NT_SUCCESS(SecStatus) ) {
  656. return;
  657. }
  658. }
  659. //
  660. // Impersonate the client (ServerSide)
  661. //
  662. SecStatus = ImpersonateSecurityContext( &ServerContextHandle );
  663. if ( SecStatus != STATUS_SUCCESS ) {
  664. printf( "ImpersonateSecurityContext: " );
  665. PrintStatus( SecStatus );
  666. if ( !NT_SUCCESS(SecStatus) ) {
  667. return;
  668. }
  669. }
  670. //
  671. // Do something while impersonating (Access the token)
  672. //
  673. /*
  674. {
  675. NTSTATUS Status;
  676. HANDLE TokenHandle = NULL;
  677. //
  678. // Open the token,
  679. //
  680. Status = NtOpenThreadToken(
  681. NtCurrentThread(),
  682. TOKEN_QUERY,
  683. (BOOLEAN) TRUE, // Not really using the impersonation token
  684. &TokenHandle );
  685. if ( !NT_SUCCESS(Status) ) {
  686. printf( "Access Thread token while impersonating: " );
  687. PrintStatus( Status );
  688. return;
  689. } else {
  690. (VOID) NtClose( TokenHandle );
  691. }
  692. }
  693. */
  694. //
  695. // RevertToSelf (ServerSide)
  696. //
  697. SecStatus = RevertSecurityContext( &ServerContextHandle );
  698. if ( SecStatus != STATUS_SUCCESS ) {
  699. printf( "RevertSecurityContext: " );
  700. PrintStatus( SecStatus );
  701. if ( !NT_SUCCESS(SecStatus) ) {
  702. return;
  703. }
  704. }
  705. //
  706. // Sign a message
  707. //
  708. SecStatus = MakeSignature(
  709. &ClientContextHandle,
  710. 0,
  711. &SignMessage,
  712. 0 );
  713. if ( SecStatus != STATUS_SUCCESS ) {
  714. printf( "MakeSignature: " );
  715. PrintStatus( SecStatus );
  716. if ( !NT_SUCCESS(SecStatus) ) {
  717. return;
  718. }
  719. }
  720. if ( !QuietMode ) {
  721. printf("\n Signature: \n");
  722. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  723. }
  724. //
  725. // Verify the signature
  726. //
  727. SecStatus = VerifySignature(
  728. &ServerContextHandle,
  729. &SignMessage,
  730. 0,
  731. 0 );
  732. if ( SecStatus != STATUS_SUCCESS ) {
  733. printf( "VerifySignature: " );
  734. PrintStatus( SecStatus );
  735. if ( !NT_SUCCESS(SecStatus) ) {
  736. return;
  737. }
  738. }
  739. //
  740. // Sign a message, this time to check if it can detect a change in the
  741. // message
  742. //
  743. SecStatus = MakeSignature(
  744. &ClientContextHandle,
  745. 0,
  746. &SignMessage,
  747. 0 );
  748. if ( SecStatus != STATUS_SUCCESS ) {
  749. printf( "MakeSignature: " );
  750. PrintStatus( SecStatus );
  751. if ( !NT_SUCCESS(SecStatus) ) {
  752. return;
  753. }
  754. }
  755. if ( !QuietMode ) {
  756. printf("\n Signature: \n");
  757. DumpBuffer(SigBuffers[1].pvBuffer,SigBuffers[1].cbBuffer);
  758. }
  759. //
  760. // Mess up the message to see if VerifySignature works
  761. //
  762. bDataBuffer[10] = 0xec;
  763. //
  764. // Verify the signature
  765. //
  766. SecStatus = VerifySignature(
  767. &ServerContextHandle,
  768. &SignMessage,
  769. 0,
  770. 0 );
  771. if ( SecStatus != SEC_E_MESSAGE_ALTERED ) {
  772. printf( "VerifySignature: " );
  773. PrintStatus( SecStatus );
  774. if ( !NT_SUCCESS(SecStatus) ) {
  775. return;
  776. }
  777. }
  778. //
  779. // Delete both contexts.
  780. //
  781. SecStatus = DeleteSecurityContext( &ClientContextHandle );
  782. if ( SecStatus != STATUS_SUCCESS ) {
  783. printf( "DeleteSecurityContext failed: " );
  784. PrintStatus( SecStatus );
  785. return;
  786. }
  787. SecStatus = DeleteSecurityContext( &ServerContextHandle );
  788. if ( SecStatus != STATUS_SUCCESS ) {
  789. printf( "DeleteSecurityContext failed: " );
  790. PrintStatus( SecStatus );
  791. return;
  792. }
  793. //
  794. // Free both credential handles
  795. //
  796. SecStatus = FreeCredentialsHandle( &CredentialHandle1 );
  797. if ( SecStatus != STATUS_SUCCESS ) {
  798. printf( "FreeCredentialsHandle failed: " );
  799. PrintStatus( SecStatus );
  800. return;
  801. }
  802. SecStatus = FreeCredentialsHandle( &CredentialHandle2 );
  803. if ( SecStatus != STATUS_SUCCESS ) {
  804. printf( "FreeCredentialsHandle failed: " );
  805. PrintStatus( SecStatus );
  806. return;
  807. }
  808. //
  809. // Final Cleanup
  810. //
  811. if ( NegotiateBuffer.pvBuffer != NULL ) {
  812. (VOID) LocalFree( NegotiateBuffer.pvBuffer );
  813. }
  814. if ( ChallengeBuffer.pvBuffer != NULL ) {
  815. (VOID) LocalFree( ChallengeBuffer.pvBuffer );
  816. }
  817. if ( AuthenticateBuffer.pvBuffer != NULL ) {
  818. (VOID) LocalFree( AuthenticateBuffer.pvBuffer );
  819. }
  820. }
  821. int __cdecl
  822. main(
  823. IN int argc,
  824. IN char ** argv
  825. )
  826. /*++
  827. Routine Description:
  828. Drive the NtLmSsp service
  829. Arguments:
  830. argc - the number of command-line arguments.
  831. argv - an array of pointers to the arguments.
  832. Return Value:
  833. Exit status
  834. --*/
  835. {
  836. LPSTR argument;
  837. int i;
  838. ULONG j;
  839. ULONG Iterations;
  840. LPWSTR DomainName = NULL;
  841. LPWSTR UserName = NULL;
  842. LPWSTR Password = NULL;
  843. enum {
  844. NoAction,
  845. ConfigureService,
  846. #define CONFIG_PARAM "/ConfigureService"
  847. TestLpc,
  848. #define TESTLPC_PARAM "/TestLpc"
  849. #define TESTLPC2_PARAM "/TestLpc:"
  850. } Action = NoAction;
  851. #define QUIET_PARAM "/Q"
  852. //
  853. // Loop through the arguments handle each in turn
  854. //
  855. for ( i=1; i<argc; i++ ) {
  856. argument = argv[i];
  857. //
  858. // Handle /TestLpc
  859. //
  860. if ( _stricmp( argument, TESTLPC_PARAM ) == 0 ) {
  861. if ( Action != NoAction ) {
  862. goto Usage;
  863. }
  864. Action = TestLpc;
  865. Iterations = 1;
  866. //
  867. // Handle /TestLpc:
  868. //
  869. } else if ( _strnicmp( argument,
  870. TESTLPC2_PARAM,
  871. sizeof(TESTLPC2_PARAM)-1 ) == 0 ){
  872. char *end;
  873. if ( Action != NoAction ) {
  874. goto Usage;
  875. }
  876. Action = TestLpc;
  877. Iterations = strtoul( &argument[sizeof(TESTLPC2_PARAM)-1], &end, 10 );
  878. i++;
  879. if ( i < argc ) {
  880. argument = argv[i];
  881. DomainName = NetpAllocWStrFromStr( argument );
  882. i++;
  883. if ( i < argc ) {
  884. argument = argv[i];
  885. UserName = NetpAllocWStrFromStr( argument );
  886. i++;
  887. if ( i < argc ) {
  888. argument = argv[i];
  889. Password = NetpAllocWStrFromStr( argument );
  890. }
  891. }
  892. }
  893. } else {
  894. //
  895. // Handle all other parameters
  896. //
  897. Usage:
  898. fprintf( stderr, "Usage: ssptest [/OPTIONS]\n\n" );
  899. fprintf(
  900. stderr,
  901. "\n"
  902. " " TESTLPC_PARAM "[:<iterations> <DomainName> <UserName> <Password>] - Test basic LPC to NtLmSsp service.\n"
  903. " " QUIET_PARAM " - Don't be so verbose\n"
  904. "\n"
  905. "\n" );
  906. return(1);
  907. }
  908. }
  909. //
  910. // Perform the action requested
  911. //
  912. switch ( Action ) {
  913. case TestLpc: {
  914. for ( j=0; j<Iterations ; j++ ) {
  915. TestLpcRoutine( DomainName, UserName, Password );
  916. }
  917. break;
  918. }
  919. }
  920. return 0;
  921. }