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.

941 lines
27 KiB

  1. /*--
  2. Copyright (c) 1987-1998 Microsoft Corporation
  3. Module Name:
  4. sclogon.cxx
  5. Abstract:
  6. Test program for Smart Card Logon
  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. 29-Oct-1998 (larrywin)
  15. --*/
  16. //
  17. // Common include files.
  18. //
  19. extern "C"
  20. {
  21. #include <nt.h>
  22. #include <ntrtl.h>
  23. #include <nturtl.h>
  24. #include <ntseapi.h>
  25. #include <ntlsa.h>
  26. #include <windef.h>
  27. #include <winbase.h>
  28. #include <winsvc.h> // Needed for service controller APIs
  29. #include <lmcons.h>
  30. #include <lmerr.h>
  31. #include <lmaccess.h>
  32. #include <lmsname.h>
  33. #include <rpc.h>
  34. #include <stdio.h> // printf
  35. #include <stdlib.h> // strtoul
  36. #include <stddef.h> // 'offset' macro
  37. #include <windows.h>
  38. #include <winnls.h>
  39. #include <iostream.h>
  40. #include <winioctl.h>
  41. #include <tchar.h>
  42. #include <string.h>
  43. }
  44. #include <wchar.h>
  45. #include <conio.h>
  46. #include <ctype.h>
  47. extern "C" {
  48. #include <netlib.h> // NetpGetLocalDomainId
  49. #include <tstring.h> // NetpAllocWStrFromWStr
  50. #define SECURITY_KERBEROS
  51. #define SECURITY_PACKAGE
  52. #include <security.h> // General definition of a Security Support Provider
  53. #include <secint.h>
  54. #include <kerbcomm.h>
  55. #include <negossp.h>
  56. #include <wincrypt.h>
  57. #include <cryptui.h>
  58. }
  59. #include <sclogon.h>
  60. #include <winscard.h>
  61. #include <log.h>
  62. #define MAX_RECURSION_DEPTH 1
  63. #define BUFFERSIZE 200
  64. BOOLEAN QuietMode = FALSE; // Don't be verbose
  65. BOOLEAN DoAnsi = FALSE;
  66. ULONG RecursionDepth = 0;
  67. CredHandle ServerCredHandleStorage;
  68. PCredHandle ServerCredHandle = NULL;
  69. LPWSTR g_wszReaderName = new wchar_t[BUFFERSIZE];
  70. // file handle for output file
  71. FILE *outstream;
  72. /*++
  73. PrintMessage:
  74. Simple function to dump text to standard output.
  75. Arguments:
  76. lpszFormat - String to dump to standard output
  77. --*/
  78. void _cdecl
  79. PrintMessage(
  80. IN LPSTR lpszFormat, ...)
  81. {
  82. //
  83. // Helper to do print traces...
  84. //
  85. va_list args;
  86. va_start(args, lpszFormat);
  87. int nBuf;
  88. char szBuffer[512];
  89. ZeroMemory(szBuffer, sizeof(szBuffer));
  90. nBuf = _vstprintf(szBuffer, lpszFormat, args);
  91. _tprintf(szBuffer);
  92. fprintf(outstream, "%s", szBuffer);
  93. OutputDebugStringA(szBuffer);
  94. va_end(args);
  95. }
  96. /*++
  97. BuildLogonInfo:
  98. GetReaderName:
  99. GetCardName:
  100. GetContainerName:
  101. GetCSPName:
  102. : Intended for accessing the LogonInformation glob
  103. Author:
  104. Amanda Matlosz
  105. Note:
  106. Some of these are made available to outside callers; see sclogon.h
  107. --*/
  108. PBYTE
  109. BuildSCLogonInfo(
  110. LPCTSTR szCard,
  111. LPCTSTR szReader,
  112. LPCTSTR szContainer,
  113. LPCTSTR szCSP)
  114. {
  115. // No assumptions are made regarding the values of the incoming parameters;
  116. // At this point, it is legal for them all to be empty.
  117. // It is also possible that NULL values are being passed in -- if this is the case,
  118. // they must be replaced with empty strings.
  119. LPCTSTR szCardI = TEXT("");
  120. LPCTSTR szReaderI = TEXT("");
  121. LPCTSTR szContainerI = TEXT("");
  122. LPCTSTR szCSPI = TEXT("");
  123. if (NULL != szCard)
  124. {
  125. szCardI = szCard;
  126. }
  127. if (NULL != szReader)
  128. {
  129. szReaderI = szReader;
  130. }
  131. if (NULL != szContainer)
  132. {
  133. szContainerI = szContainer;
  134. }
  135. if (NULL != szCSP)
  136. {
  137. szCSPI = szCSP;
  138. }
  139. //
  140. // Build the LogonInfo glob using strings (or empty strings)
  141. //
  142. DWORD cbLi = offsetof(LogonInfo, bBuffer)
  143. + (lstrlen(szCardI) + 1) * sizeof(TCHAR)
  144. + (lstrlen(szReaderI) + 1) * sizeof(TCHAR)
  145. + (lstrlen(szContainerI) + 1) * sizeof(TCHAR)
  146. + (lstrlen(szCSPI) + 1) * sizeof(TCHAR);
  147. LogonInfo* pLI = (LogonInfo*)LocalAlloc(LPTR, cbLi);
  148. if (NULL == pLI)
  149. {
  150. return NULL;
  151. }
  152. pLI->ContextInformation = NULL;
  153. pLI->dwLogonInfoLen = cbLi;
  154. LPTSTR pBuffer = pLI->bBuffer;
  155. pLI->nCardNameOffset = 0;
  156. lstrcpy(pBuffer, szCardI);
  157. pBuffer += (lstrlen(szCardI)+1);
  158. pLI->nReaderNameOffset = (ULONG) (pBuffer-pLI->bBuffer);
  159. lstrcpy(pBuffer, szReaderI);
  160. pBuffer += (lstrlen(szReaderI)+1);
  161. pLI->nContainerNameOffset = (ULONG) (pBuffer-pLI->bBuffer);
  162. lstrcpy(pBuffer, szContainerI);
  163. pBuffer += (lstrlen(szContainerI)+1);
  164. pLI->nCSPNameOffset = (ULONG) (pBuffer-pLI->bBuffer);
  165. lstrcpy(pBuffer, szCSPI);
  166. pBuffer += (lstrlen(szCSPI)+1);
  167. // _ASSERTE(cbLi == (DWORD)((LPBYTE)pBuffer - (LPBYTE)pLI));
  168. return (PBYTE)pLI;
  169. }
  170. void
  171. FreeErrorString(
  172. LPCTSTR szErrorString)
  173. {
  174. if (NULL != szErrorString)
  175. LocalFree((LPVOID)szErrorString);
  176. }
  177. LPTSTR ErrorString( IN DWORD dwError )
  178. {
  179. DWORD dwLen = 0;
  180. LPTSTR szErrorString = NULL;
  181. dwLen = FormatMessage(
  182. FORMAT_MESSAGE_ALLOCATE_BUFFER
  183. | FORMAT_MESSAGE_FROM_SYSTEM,
  184. NULL,
  185. (DWORD)dwError,
  186. LANG_NEUTRAL,
  187. (LPTSTR)&szErrorString,
  188. 0,
  189. NULL);
  190. return szErrorString;
  191. }
  192. HANDLE
  193. FindAndOpenWinlogon(
  194. VOID
  195. )
  196. {
  197. PSYSTEM_PROCESS_INFORMATION SystemInfo ;
  198. PSYSTEM_PROCESS_INFORMATION Walk ;
  199. NTSTATUS Status ;
  200. UNICODE_STRING Winlogon ;
  201. HANDLE Process ;
  202. SystemInfo = (PSYSTEM_PROCESS_INFORMATION)LocalAlloc( LMEM_FIXED, sizeof( SYSTEM_PROCESS_INFORMATION ) * 1024 );
  203. if ( !SystemInfo )
  204. {
  205. return NULL ;
  206. }
  207. Status = NtQuerySystemInformation(
  208. SystemProcessInformation,
  209. SystemInfo,
  210. sizeof( SYSTEM_PROCESS_INFORMATION ) * 1024,
  211. NULL );
  212. if ( !NT_SUCCESS( Status ) )
  213. {
  214. return NULL ;
  215. }
  216. RtlInitUnicodeString( &Winlogon, L"winlogon.exe" );
  217. Walk = SystemInfo ;
  218. while ( RtlCompareUnicodeString( &Walk->ImageName, &Winlogon, TRUE ) != 0 )
  219. {
  220. if ( Walk->NextEntryOffset == 0 )
  221. {
  222. Walk = NULL ;
  223. break;
  224. }
  225. Walk = (PSYSTEM_PROCESS_INFORMATION) ((PUCHAR) Walk + Walk->NextEntryOffset );
  226. }
  227. if ( !Walk )
  228. {
  229. LocalFree( SystemInfo );
  230. return NULL ;
  231. }
  232. Process = OpenProcess( PROCESS_QUERY_INFORMATION,
  233. FALSE,
  234. HandleToUlong(Walk->UniqueProcessId) );
  235. LocalFree( SystemInfo );
  236. return Process ;
  237. }
  238. NTSTATUS
  239. TestScLogonRoutine(
  240. IN ULONG Count,
  241. IN LPSTR Pin
  242. )
  243. {
  244. NTSTATUS Status;
  245. PKERB_SMART_CARD_LOGON LogonInfo;
  246. ULONG LogonInfoSize = sizeof(KERB_SMART_CARD_LOGON);
  247. BOOLEAN WasEnabled;
  248. STRING PinString;
  249. STRING Name;
  250. ULONG Dummy;
  251. HANDLE LogonHandle = NULL;
  252. ULONG PackageId;
  253. TOKEN_SOURCE SourceContext;
  254. PKERB_INTERACTIVE_PROFILE Profile = NULL;
  255. ULONG ProfileSize;
  256. LUID LogonId;
  257. HANDLE TokenHandle = NULL;
  258. QUOTA_LIMITS Quotas;
  259. NTSTATUS SubStatus;
  260. WCHAR UserNameString[100];
  261. ULONG NameLength = 100;
  262. PUCHAR Where;
  263. ULONG Index;
  264. HANDLE ScHandle = NULL;
  265. PBYTE ScLogonInfo = NULL;
  266. ULONG ScLogonInfoSize;
  267. ULONG WaitResult = 0;
  268. SCARDCONTEXT hContext = NULL;
  269. LONG lCallReturn = -1;
  270. LPTSTR szReaders = NULL;
  271. LPTSTR pchReader = NULL;
  272. LPTSTR mszCards = NULL;
  273. LPTSTR szLogonCard = NULL;
  274. LPTSTR szCSPName = NULL;
  275. BYTE bSLBAtr[] = {0x3b,0xe2,0x00,0x00,0x40,0x20,0x49,0x06};
  276. BYTE bGEMAtr[] = {0x3b,0x27,0x00,0x80,0x65,0xa2,0x00,0x01,0x01,0x37};
  277. DWORD dwReadersLen = SCARD_AUTOALLOCATE;
  278. DWORD dwCardsLen = SCARD_AUTOALLOCATE;
  279. DWORD dwCSPLen = SCARD_AUTOALLOCATE;
  280. SCARD_READERSTATE rgReaderStates[MAXIMUM_SMARTCARD_READERS]; // not necessarily max for pnp readers
  281. LONG nIndex;
  282. LONG nCnReaders;
  283. BOOL fFound = FALSE;
  284. SYSTEMTIME StartTime, DoneTime;
  285. SYSTEMTIME stElapsed;
  286. FILETIME ftStart, ftDone,
  287. *pftStart = &ftStart,
  288. *pftDone = &ftDone;
  289. LARGE_INTEGER liStart, liDone,
  290. *pliStart = &liStart,
  291. *pliDone = &liDone;
  292. LARGE_INTEGER liAccumulatedTime, liSplitTime,
  293. *pliAccumulatedTime = &liAccumulatedTime,
  294. *pliSplitTime = &liSplitTime;
  295. FILETIME ftAccumulatedTime,
  296. *pftAccumulatedTime = &ftAccumulatedTime;
  297. SYSTEMTIME stAccumulatedTime;
  298. LPWSTR buffer = new wchar_t[BUFFERSIZE];
  299. int j;
  300. memset(buffer, 0, BUFFERSIZE);
  301. liAccumulatedTime.QuadPart = 0;
  302. // get a ResMgr context
  303. lCallReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext);
  304. if ( SCARD_S_SUCCESS != lCallReturn) {
  305. swprintf(buffer, L"Failed to initialize context: 0x%x\n", lCallReturn);
  306. PrintMessage("%S",buffer);
  307. memset(buffer, 0, sizeof(buffer));
  308. return (NTSTATUS)lCallReturn;
  309. }
  310. // list all readers
  311. lCallReturn = SCardListReaders(hContext, SCARD_ALL_READERS, (LPTSTR)&szReaders, &dwReadersLen);
  312. if (SCARD_S_SUCCESS != lCallReturn) {
  313. swprintf(buffer, L"Failed to list readers on the system: 0x%x\n", lCallReturn);
  314. PrintMessage("%S",buffer);
  315. memset(buffer, 0, sizeof(buffer));
  316. return (NTSTATUS)lCallReturn;
  317. } else if ((0 == dwReadersLen)
  318. || (NULL == szReaders)
  319. || (0 == *szReaders))
  320. {
  321. lCallReturn = SCARD_E_UNKNOWN_READER; // Or some such error
  322. if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
  323. swprintf(buffer, L"Failed to identify a reader on the system: 0x%x\n", lCallReturn);
  324. PrintMessage("%S",buffer);
  325. memset(buffer, 0, sizeof(buffer));
  326. return (NTSTATUS)lCallReturn;
  327. }
  328. // list cards
  329. lCallReturn = SCardListCards(hContext, NULL, NULL, 0, (LPTSTR)&mszCards, &dwCardsLen);
  330. if ( SCARD_S_SUCCESS != lCallReturn) {
  331. printf("Failed to list cards in the system: 0x%x\n", lCallReturn);
  332. if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
  333. if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
  334. swprintf(buffer, L"Failed to identify a card on the system: 0x%x\n", lCallReturn);
  335. PrintMessage("%S",buffer);
  336. memset(buffer, 0, sizeof(buffer));
  337. return (NTSTATUS)lCallReturn;
  338. }
  339. // use the list of readers to build a readerstate array
  340. nIndex = 0;
  341. if (0 != wcslen(g_wszReaderName)) {
  342. // use the reader specified in the command line
  343. rgReaderStates[nIndex].szReader = (const unsigned short *)g_wszReaderName;
  344. rgReaderStates[nIndex].dwCurrentState = SCARD_STATE_UNAWARE;
  345. nCnReaders = 1;
  346. } else {
  347. pchReader = szReaders;
  348. while (0 != *pchReader)
  349. {
  350. rgReaderStates[nIndex].szReader = pchReader;
  351. rgReaderStates[nIndex].dwCurrentState = SCARD_STATE_UNAWARE;
  352. pchReader += lstrlen(pchReader)+1;
  353. nIndex++;
  354. if (MAXIMUM_SMARTCARD_READERS == nIndex)
  355. break;
  356. }
  357. nCnReaders = nIndex;
  358. }
  359. // find a reader with one of the listed cards, or the specified card, present
  360. lCallReturn = SCardLocateCards(hContext, mszCards, rgReaderStates, nCnReaders);
  361. if ( SCARD_S_SUCCESS != lCallReturn) {
  362. if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
  363. if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
  364. swprintf(buffer, L"Failed to locate a smart card for logon: 0x%x\n", lCallReturn);
  365. PrintMessage("%S",buffer);
  366. memset(buffer, 0, sizeof(buffer));
  367. return (NTSTATUS)lCallReturn;
  368. }
  369. // find the reader containing the requested card
  370. for (nIndex=0; nIndex<nCnReaders && FALSE == fFound; nIndex++) {
  371. if (rgReaderStates[nIndex].dwEventState & SCARD_STATE_ATRMATCH) {
  372. // reader found
  373. fFound = TRUE;
  374. break;
  375. }
  376. }
  377. if (FALSE == fFound) {
  378. lCallReturn = SCARD_E_NO_SMARTCARD; // or some such error
  379. if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
  380. if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
  381. swprintf(buffer, L"No smart card in any reader: 0x%x\n", lCallReturn);
  382. PrintMessage("%S",buffer);
  383. memset(buffer, 0, sizeof(buffer));
  384. return (NTSTATUS)lCallReturn;
  385. } else { // get the name of the card found
  386. dwCardsLen = SCARD_AUTOALLOCATE;
  387. lCallReturn = SCardListCards(hContext, rgReaderStates[nIndex].rgbAtr, NULL, 0, (LPTSTR)&szLogonCard, &dwCardsLen);
  388. if ( SCARD_S_SUCCESS != lCallReturn ) {
  389. if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
  390. if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
  391. if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard);
  392. swprintf(buffer, L"Failed to get name of card in reader: 0x%x\n", lCallReturn);
  393. PrintMessage("%S",buffer);
  394. memset(buffer, 0, sizeof(buffer));
  395. return (NTSTATUS)lCallReturn;
  396. }
  397. }
  398. // get the csp provider name for the card
  399. lCallReturn = SCardGetCardTypeProviderName(hContext, szLogonCard, SCARD_PROVIDER_CSP, (LPTSTR)&szCSPName, &dwCSPLen);
  400. if ( SCARD_S_SUCCESS != lCallReturn) {
  401. if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
  402. if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
  403. if (NULL != szCSPName) SCardFreeMemory(hContext, (LPVOID)szCSPName);
  404. if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard);
  405. swprintf(buffer, L"Failed to locate smart card crypto service provider: 0x%x\n", lCallReturn);
  406. PrintMessage("%S",buffer);
  407. memset(buffer, 0, sizeof(buffer));
  408. return (NTSTATUS)lCallReturn;
  409. }
  410. ScLogonInfo = BuildSCLogonInfo(szLogonCard,
  411. rgReaderStates[nIndex].szReader,
  412. TEXT(""), // use default container
  413. szCSPName
  414. );
  415. //
  416. // We should now have logon info.
  417. //
  418. if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
  419. if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
  420. if (NULL != szCSPName) SCardFreeMemory(hContext, (LPVOID)szCSPName);
  421. if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard);
  422. j = swprintf(buffer, L"Reader : %s\n", GetReaderName(ScLogonInfo));
  423. j += swprintf(buffer + j, L"Card : %s\n", GetCardName(ScLogonInfo));
  424. j += swprintf(buffer + j, L"CSP : %s\n", GetCSPName(ScLogonInfo));
  425. PrintMessage("%S",buffer);
  426. memset(buffer, 0, sizeof(buffer));
  427. // perform sclogon
  428. if (ScLogonInfo == NULL)
  429. {
  430. swprintf(buffer, L"Failed to get logon info!\n");
  431. PrintMessage("%S",buffer);
  432. memset(buffer, 0, BUFFERSIZE);
  433. return (NTSTATUS) -1;
  434. }
  435. ScLogonInfoSize = ((struct LogonInfo *) ScLogonInfo)->dwLogonInfoLen;
  436. Status = ScHelperInitializeContext(
  437. ScLogonInfo,
  438. ScLogonInfoSize
  439. );
  440. if (!NT_SUCCESS(Status))
  441. {
  442. swprintf(buffer, L"Failed to initialize helper context: 0x%x\n",Status);
  443. PrintMessage("%S",buffer);
  444. memset(buffer, 0, BUFFERSIZE);
  445. return (NTSTATUS)Status;
  446. }
  447. ScHelperRelease(ScLogonInfo);
  448. RtlInitString(
  449. &PinString,
  450. Pin
  451. );
  452. LogonInfoSize += (PinString.Length+1 ) * sizeof(WCHAR) + ScLogonInfoSize;
  453. LogonInfo = (PKERB_SMART_CARD_LOGON) LocalAlloc(LMEM_ZEROINIT, LogonInfoSize);
  454. LogonInfo->MessageType = KerbSmartCardLogon;
  455. Where = (PUCHAR) (LogonInfo + 1);
  456. LogonInfo->Pin.Buffer = (LPWSTR) Where;
  457. LogonInfo->Pin.MaximumLength = (USHORT) LogonInfoSize;
  458. RtlAnsiStringToUnicodeString(
  459. &LogonInfo->Pin,
  460. &PinString,
  461. FALSE
  462. );
  463. Where += LogonInfo->Pin.Length + sizeof(WCHAR);
  464. LogonInfo->CspDataLength = ScLogonInfoSize;
  465. LogonInfo->CspData = Where;
  466. RtlCopyMemory(
  467. LogonInfo->CspData,
  468. ScLogonInfo,
  469. ScLogonInfoSize
  470. );
  471. Where += ScLogonInfoSize;
  472. //
  473. // Turn on the TCB privilege
  474. //
  475. Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
  476. if (!NT_SUCCESS(Status))
  477. {
  478. swprintf(buffer, L"Failed to adjust privilege: 0x%x\n",Status);
  479. PrintMessage("%S",buffer);
  480. memset(buffer, 0, BUFFERSIZE);
  481. return (NTSTATUS)Status;
  482. }
  483. RtlInitString(
  484. &Name,
  485. "SmartCardLogon"
  486. );
  487. Status = LsaRegisterLogonProcess(
  488. &Name,
  489. &LogonHandle,
  490. &Dummy
  491. );
  492. if (!NT_SUCCESS(Status))
  493. {
  494. swprintf(buffer, L"Failed to register as a logon process: 0x%x\n",Status);
  495. PrintMessage("%S",buffer);
  496. memset(buffer, 0, BUFFERSIZE);
  497. return (NTSTATUS)Status;
  498. }
  499. strncpy(
  500. SourceContext.SourceName,
  501. "SmartCardLogon ",sizeof(SourceContext.SourceName)
  502. );
  503. NtAllocateLocallyUniqueId(
  504. &SourceContext.SourceIdentifier
  505. );
  506. RtlInitString(
  507. &Name,
  508. MICROSOFT_KERBEROS_NAME_A
  509. );
  510. Status = LsaLookupAuthenticationPackage(
  511. LogonHandle,
  512. &Name,
  513. &PackageId
  514. );
  515. if (!NT_SUCCESS(Status))
  516. {
  517. swprintf(buffer, L"Failed to lookup package %Z: 0x%x\n",&Name, Status);
  518. PrintMessage("%S",buffer);
  519. memset(buffer, 0, BUFFERSIZE);
  520. return (NTSTATUS)Status;
  521. }
  522. //
  523. // Now call LsaLogonUser
  524. //
  525. RtlInitString(
  526. &Name,
  527. "SmartCardLogon"
  528. );
  529. for (Index = 1; Index <= Count ; Index++ )
  530. {
  531. swprintf(buffer, L"\nLogon %.6d\n", Index);
  532. PrintMessage("%S",buffer);
  533. memset(buffer, 0, BUFFERSIZE);
  534. // get start time
  535. GetSystemTime(&StartTime);
  536. Status = LsaLogonUser(
  537. LogonHandle,
  538. &Name,
  539. Interactive,
  540. PackageId,
  541. LogonInfo,
  542. LogonInfoSize,
  543. NULL, // no token groups
  544. &SourceContext,
  545. (PVOID *) &Profile,
  546. &ProfileSize,
  547. &LogonId,
  548. &TokenHandle,
  549. &Quotas,
  550. &SubStatus
  551. );
  552. // get done time
  553. GetSystemTime(&DoneTime);
  554. // convert systemtime to filetime
  555. SystemTimeToFileTime(&StartTime, &ftStart);
  556. SystemTimeToFileTime(&DoneTime, &ftDone);
  557. // copy filetime to large int
  558. CopyMemory(pliStart, pftStart, 8);
  559. CopyMemory(pliDone, pftDone, 8);
  560. // diff the large ints and accumulate result
  561. liDone.QuadPart = liDone.QuadPart - liStart.QuadPart;
  562. liAccumulatedTime.QuadPart = liAccumulatedTime.QuadPart + liDone.QuadPart;
  563. // copy result back to filetime
  564. CopyMemory(pftDone, pliDone, 8);
  565. // convert result back to systemtime
  566. FileTimeToSystemTime( (CONST FILETIME *)&ftDone, &stElapsed);
  567. // output the result
  568. swprintf(buffer, L"RunTime: %2.2ldm:%2.2lds:%3.3ldms\n",
  569. stElapsed.wMinute,
  570. stElapsed.wSecond,
  571. stElapsed.wMilliseconds);
  572. PrintMessage("%S",buffer);
  573. memset(buffer, 0, BUFFERSIZE);
  574. if (!NT_SUCCESS(Status))
  575. {
  576. j = swprintf(buffer, L"lsalogonuser failed: 0x%x\n",Status);
  577. LPTSTR szErrorMessage = ErrorString((DWORD)Status);
  578. if (NULL == szErrorMessage) {
  579. j += swprintf(buffer + j, L" ErrorMessage: error message not found, check ntstatus.h\n");
  580. } else {
  581. j += swprintf(buffer + j, L" ErrorMessage: %S\n", szErrorMessage);
  582. }
  583. PrintMessage("%S",buffer);
  584. memset(buffer, 0, BUFFERSIZE);
  585. return (NTSTATUS)Status;
  586. }
  587. if (!NT_SUCCESS(SubStatus))
  588. {
  589. j = swprintf(buffer, L"LsalogonUser failed: substatus = 0x%x\n",SubStatus);
  590. LPTSTR szErrorMessage = ErrorString((DWORD)Status);
  591. if (NULL == szErrorMessage) {
  592. j += swprintf(buffer + j, L" ErrorMessage: error message not found, check ntstatus.h\n");
  593. } else {
  594. j += swprintf(buffer + j, L" ErrorMessage: %S", szErrorMessage);
  595. }
  596. PrintMessage("%S",buffer);
  597. memset(buffer, 0, BUFFERSIZE);
  598. return (NTSTATUS)SubStatus;
  599. }
  600. ImpersonateLoggedOnUser( TokenHandle );
  601. GetUserName(UserNameString,&NameLength);
  602. j = swprintf(buffer, L"Result: %S", ErrorString((DWORD)Status));
  603. j += swprintf(buffer, L"Username: %ws\n",UserNameString);
  604. PrintMessage("%S",buffer);
  605. memset(buffer, 0, BUFFERSIZE);
  606. RevertToSelf();
  607. NtClose(TokenHandle);
  608. LsaFreeReturnBuffer(Profile);
  609. Profile = NULL;
  610. // report average every 10th logon
  611. if (0 == Index % 10) {
  612. liSplitTime.QuadPart = liAccumulatedTime.QuadPart / Index;
  613. CopyMemory(pftAccumulatedTime, pliSplitTime, 8);
  614. FileTimeToSystemTime( (CONST FILETIME *)&ftAccumulatedTime, &stAccumulatedTime);
  615. swprintf(buffer, L"\nAverage Time after %d Logons: %2.2ldm:%2.2lds:%3.3ldms\n",
  616. Index,
  617. stAccumulatedTime.wMinute,
  618. stAccumulatedTime.wSecond,
  619. stAccumulatedTime.wMilliseconds);
  620. PrintMessage("%S",buffer);
  621. }
  622. Sleep(2000); // let card stack unwind
  623. }
  624. // ouput average results
  625. if ( 1 != Count ) {
  626. liAccumulatedTime.QuadPart = liAccumulatedTime.QuadPart / Count;
  627. CopyMemory(pftAccumulatedTime, pliAccumulatedTime, 8);
  628. FileTimeToSystemTime( (CONST FILETIME *)&ftAccumulatedTime, &stAccumulatedTime);
  629. swprintf(buffer, L"\nAverage Logon Time: %2.2ldm:%2.2lds:%3.3ldms\n",
  630. stAccumulatedTime.wMinute,
  631. stAccumulatedTime.wSecond,
  632. stAccumulatedTime.wMilliseconds);
  633. PrintMessage("%S", buffer);
  634. }
  635. return (NTSTATUS)Status;
  636. }
  637. VOID
  638. PrintKdcName(
  639. IN PKERB_INTERNAL_NAME Name
  640. )
  641. {
  642. ULONG Index;
  643. for (Index = 0; Index < Name->NameCount ; Index++ )
  644. {
  645. printf(" %wZ ",&Name->Names[Index]);
  646. }
  647. printf("\n");
  648. }
  649. int __cdecl
  650. main(
  651. IN int argc,
  652. IN char ** argv
  653. )
  654. /*++
  655. Routine Description:
  656. Drive the NtLmSsp service
  657. Arguments:
  658. argc - the number of command-line arguments.
  659. argv - an array of pointers to the arguments.
  660. Return Value:
  661. Exit status
  662. --*/
  663. {
  664. LPSTR argument;
  665. int i;
  666. ULONG j;
  667. ULONG Iterations = 0;
  668. LPSTR PinBuffer = new char [81];
  669. LPSTR szReaderBuffer = new char[BUFFERSIZE];
  670. LPSTR EventMachineBuffer = new char [81];
  671. LPWSTR wEventMachineBuffer = new wchar_t[81];
  672. LPWSTR PackageFunction;
  673. ULONG ContextReq = 0;
  674. WCHAR ContainerName[100];
  675. WCHAR CaName[100];
  676. WCHAR CaLocation[100];
  677. WCHAR ServiceName[100];
  678. NTSTATUS Status = -1;
  679. enum {
  680. NoAction,
  681. #define LOGON_PARAM "/p"
  682. TestLogon,
  683. #define ITERATION_PARAM "/i"
  684. #define HELP_PARAM "/?"
  685. //#define EVENT_PARAM "/s"
  686. #define READER_PARAM "/r"
  687. } Action = NoAction;
  688. memset(g_wszReaderName, 0, BUFFERSIZE);
  689. memset(szReaderBuffer, 0, BUFFERSIZE);
  690. // open output file
  691. outstream = fopen( "scardbvt.out", "w" );
  692. //
  693. // Loop through the arguments handle each in turn
  694. //
  695. if ( 1 == argc ) {// silent mode
  696. Iterations = 1;
  697. Action = TestLogon;
  698. printf("Enter your pin number: ");
  699. int ch;
  700. int j = 0;
  701. ch = _getch();
  702. while (ch != 0x0d) {
  703. j += sprintf(PinBuffer + j,"%c", ch);
  704. printf("*");
  705. ch = _getch();
  706. }
  707. printf("\n");
  708. }
  709. for ( i=1; i<argc; i++ ) {
  710. argument = argv[i];
  711. //
  712. // Handle /ConfigureService
  713. //
  714. if ( _strnicmp( argument, LOGON_PARAM, sizeof(LOGON_PARAM)-1 ) == 0 ) {
  715. if ( Action != NoAction ) {
  716. goto Usage;
  717. }
  718. Iterations = 1;
  719. Action = TestLogon;
  720. if (argc <= i + 1) {
  721. goto Usage;
  722. }
  723. PinBuffer = argv[++i];
  724. } else if ( _strnicmp( argument, ITERATION_PARAM, sizeof(ITERATION_PARAM) - 1 ) == 0 ) {
  725. if (argc <= i + 1) {
  726. goto Usage;
  727. }
  728. Iterations = atoi(argv[++i]);
  729. } /*else if ( _strnicmp( argument, EVENT_PARAM, sizeof(EVENT_PARAM) - 1 ) == 0 ) {
  730. if (argc <= i + 1) {
  731. goto Usage;
  732. }
  733. // save name of machine to which events will be posted
  734. EventMachineBuffer = argv[++i];
  735. wsprintfW(wEventMachineBuffer, L"%S", EventMachineBuffer);
  736. SetEventMachine(&wEventMachineBuffer);
  737. //Event(PERF_INFORMATION, L"Trying to set machine name\n", 1);
  738. } */
  739. else if ( _strnicmp( argument, HELP_PARAM, sizeof(HELP_PARAM) - 1 ) == 0 ) {
  740. goto Usage;
  741. } else if ( _strnicmp( argument, READER_PARAM, sizeof(READER_PARAM) - 1 ) == 0 ) {
  742. if (argc <= i + 1) {
  743. goto Usage;
  744. }
  745. // get the name of a specified reader
  746. szReaderBuffer = argv[++i];
  747. wsprintfW(g_wszReaderName, L"%S", szReaderBuffer);
  748. } else {
  749. printf("Invalid parameter : %s\n",argument);
  750. goto Usage;
  751. }
  752. }
  753. //
  754. // Perform the action requested
  755. //
  756. switch ( Action ) {
  757. case TestLogon :
  758. Status = TestScLogonRoutine(
  759. Iterations,
  760. PinBuffer
  761. );
  762. break;
  763. case NoAction :
  764. goto Usage;
  765. break;
  766. }
  767. return Status;
  768. Usage:
  769. PrintMessage("%s - no parameters, manually enter pin\n", argv[0]);
  770. PrintMessage(" optional parameters (if any used, must have /p)\n");
  771. PrintMessage(" /p Pin\n");
  772. PrintMessage(" /i Iterations\n");
  773. // printf(" /s EventMachineName (post events to this machine)\n");
  774. PrintMessage(" /r %cReader Name X%c (registry device name in quotes)\n", '"', '"');
  775. return -1;
  776. }