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

/*--
Copyright (c) 1987-1998 Microsoft Corporation
Module Name:
sclogon.cxx
Abstract:
Test program for Smart Card Logon
Author:
28-Jun-1993 (cliffv)
Environment:
User mode only.
Contains NT-specific code.
Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
29-Oct-1998 (larrywin)
--*/
//
// Common include files.
//
extern "C"
{
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <ntseapi.h>
#include <ntlsa.h>
#include <windef.h>
#include <winbase.h>
#include <winsvc.h> // Needed for service controller APIs
#include <lmcons.h>
#include <lmerr.h>
#include <lmaccess.h>
#include <lmsname.h>
#include <rpc.h>
#include <stdio.h> // printf
#include <stdlib.h> // strtoul
#include <stddef.h> // 'offset' macro
#include <windows.h>
#include <winnls.h>
#include <iostream.h>
#include <winioctl.h>
#include <tchar.h>
#include <string.h>
}
#include <wchar.h>
#include <conio.h>
#include <ctype.h>
extern "C" {
#include <netlib.h> // NetpGetLocalDomainId
#include <tstring.h> // NetpAllocWStrFromWStr
#define SECURITY_KERBEROS
#define SECURITY_PACKAGE
#include <security.h> // General definition of a Security Support Provider
#include <secint.h>
#include <kerbcomm.h>
#include <negossp.h>
#include <wincrypt.h>
#include <cryptui.h>
}
#include <sclogon.h>
#include <winscard.h>
#include <log.h>
#define MAX_RECURSION_DEPTH 1
#define BUFFERSIZE 200
BOOLEAN QuietMode = FALSE; // Don't be verbose
BOOLEAN DoAnsi = FALSE;
ULONG RecursionDepth = 0;
CredHandle ServerCredHandleStorage;
PCredHandle ServerCredHandle = NULL;
LPWSTR g_wszReaderName = new wchar_t[BUFFERSIZE];
// file handle for output file
FILE *outstream;
/*++
PrintMessage:
Simple function to dump text to standard output.
Arguments:
lpszFormat - String to dump to standard output
--*/
void _cdecl
PrintMessage(
IN LPSTR lpszFormat, ...)
{
//
// Helper to do print traces...
//
va_list args;
va_start(args, lpszFormat);
int nBuf;
char szBuffer[512];
ZeroMemory(szBuffer, sizeof(szBuffer));
nBuf = _vstprintf(szBuffer, lpszFormat, args);
_tprintf(szBuffer);
fprintf(outstream, "%s", szBuffer);
OutputDebugStringA(szBuffer);
va_end(args);
}
/*++
BuildLogonInfo:
GetReaderName:
GetCardName:
GetContainerName:
GetCSPName:
: Intended for accessing the LogonInformation glob
Author:
Amanda Matlosz
Note:
Some of these are made available to outside callers; see sclogon.h
--*/
PBYTE
BuildSCLogonInfo(
LPCTSTR szCard,
LPCTSTR szReader,
LPCTSTR szContainer,
LPCTSTR szCSP)
{
// No assumptions are made regarding the values of the incoming parameters;
// At this point, it is legal for them all to be empty.
// It is also possible that NULL values are being passed in -- if this is the case,
// they must be replaced with empty strings.
LPCTSTR szCardI = TEXT("");
LPCTSTR szReaderI = TEXT("");
LPCTSTR szContainerI = TEXT("");
LPCTSTR szCSPI = TEXT("");
if (NULL != szCard)
{
szCardI = szCard;
}
if (NULL != szReader)
{
szReaderI = szReader;
}
if (NULL != szContainer)
{
szContainerI = szContainer;
}
if (NULL != szCSP)
{
szCSPI = szCSP;
}
//
// Build the LogonInfo glob using strings (or empty strings)
//
DWORD cbLi = offsetof(LogonInfo, bBuffer)
+ (lstrlen(szCardI) + 1) * sizeof(TCHAR)
+ (lstrlen(szReaderI) + 1) * sizeof(TCHAR)
+ (lstrlen(szContainerI) + 1) * sizeof(TCHAR)
+ (lstrlen(szCSPI) + 1) * sizeof(TCHAR);
LogonInfo* pLI = (LogonInfo*)LocalAlloc(LPTR, cbLi);
if (NULL == pLI)
{
return NULL;
}
pLI->ContextInformation = NULL;
pLI->dwLogonInfoLen = cbLi;
LPTSTR pBuffer = pLI->bBuffer;
pLI->nCardNameOffset = 0;
lstrcpy(pBuffer, szCardI);
pBuffer += (lstrlen(szCardI)+1);
pLI->nReaderNameOffset = (ULONG) (pBuffer-pLI->bBuffer);
lstrcpy(pBuffer, szReaderI);
pBuffer += (lstrlen(szReaderI)+1);
pLI->nContainerNameOffset = (ULONG) (pBuffer-pLI->bBuffer);
lstrcpy(pBuffer, szContainerI);
pBuffer += (lstrlen(szContainerI)+1);
pLI->nCSPNameOffset = (ULONG) (pBuffer-pLI->bBuffer);
lstrcpy(pBuffer, szCSPI);
pBuffer += (lstrlen(szCSPI)+1);
// _ASSERTE(cbLi == (DWORD)((LPBYTE)pBuffer - (LPBYTE)pLI));
return (PBYTE)pLI;
}
void
FreeErrorString(
LPCTSTR szErrorString)
{
if (NULL != szErrorString)
LocalFree((LPVOID)szErrorString);
}
LPTSTR ErrorString( IN DWORD dwError )
{
DWORD dwLen = 0;
LPTSTR szErrorString = NULL;
dwLen = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
(DWORD)dwError,
LANG_NEUTRAL,
(LPTSTR)&szErrorString,
0,
NULL);
return szErrorString;
}
HANDLE
FindAndOpenWinlogon(
VOID
)
{
PSYSTEM_PROCESS_INFORMATION SystemInfo ;
PSYSTEM_PROCESS_INFORMATION Walk ;
NTSTATUS Status ;
UNICODE_STRING Winlogon ;
HANDLE Process ;
SystemInfo = (PSYSTEM_PROCESS_INFORMATION)LocalAlloc( LMEM_FIXED, sizeof( SYSTEM_PROCESS_INFORMATION ) * 1024 );
if ( !SystemInfo )
{
return NULL ;
}
Status = NtQuerySystemInformation(
SystemProcessInformation,
SystemInfo,
sizeof( SYSTEM_PROCESS_INFORMATION ) * 1024,
NULL );
if ( !NT_SUCCESS( Status ) )
{
return NULL ;
}
RtlInitUnicodeString( &Winlogon, L"winlogon.exe" );
Walk = SystemInfo ;
while ( RtlCompareUnicodeString( &Walk->ImageName, &Winlogon, TRUE ) != 0 )
{
if ( Walk->NextEntryOffset == 0 )
{
Walk = NULL ;
break;
}
Walk = (PSYSTEM_PROCESS_INFORMATION) ((PUCHAR) Walk + Walk->NextEntryOffset );
}
if ( !Walk )
{
LocalFree( SystemInfo );
return NULL ;
}
Process = OpenProcess( PROCESS_QUERY_INFORMATION,
FALSE,
HandleToUlong(Walk->UniqueProcessId) );
LocalFree( SystemInfo );
return Process ;
}
NTSTATUS
TestScLogonRoutine(
IN ULONG Count,
IN LPSTR Pin
)
{
NTSTATUS Status;
PKERB_SMART_CARD_LOGON LogonInfo;
ULONG LogonInfoSize = sizeof(KERB_SMART_CARD_LOGON);
BOOLEAN WasEnabled;
STRING PinString;
STRING Name;
ULONG Dummy;
HANDLE LogonHandle = NULL;
ULONG PackageId;
TOKEN_SOURCE SourceContext;
PKERB_INTERACTIVE_PROFILE Profile = NULL;
ULONG ProfileSize;
LUID LogonId;
HANDLE TokenHandle = NULL;
QUOTA_LIMITS Quotas;
NTSTATUS SubStatus;
WCHAR UserNameString[100];
ULONG NameLength = 100;
PUCHAR Where;
ULONG Index;
HANDLE ScHandle = NULL;
PBYTE ScLogonInfo = NULL;
ULONG ScLogonInfoSize;
ULONG WaitResult = 0;
SCARDCONTEXT hContext = NULL;
LONG lCallReturn = -1;
LPTSTR szReaders = NULL;
LPTSTR pchReader = NULL;
LPTSTR mszCards = NULL;
LPTSTR szLogonCard = NULL;
LPTSTR szCSPName = NULL;
BYTE bSLBAtr[] = {0x3b,0xe2,0x00,0x00,0x40,0x20,0x49,0x06};
BYTE bGEMAtr[] = {0x3b,0x27,0x00,0x80,0x65,0xa2,0x00,0x01,0x01,0x37};
DWORD dwReadersLen = SCARD_AUTOALLOCATE;
DWORD dwCardsLen = SCARD_AUTOALLOCATE;
DWORD dwCSPLen = SCARD_AUTOALLOCATE;
SCARD_READERSTATE rgReaderStates[MAXIMUM_SMARTCARD_READERS]; // not necessarily max for pnp readers
LONG nIndex;
LONG nCnReaders;
BOOL fFound = FALSE;
SYSTEMTIME StartTime, DoneTime;
SYSTEMTIME stElapsed;
FILETIME ftStart, ftDone,
*pftStart = &ftStart,
*pftDone = &ftDone;
LARGE_INTEGER liStart, liDone,
*pliStart = &liStart,
*pliDone = &liDone;
LARGE_INTEGER liAccumulatedTime, liSplitTime,
*pliAccumulatedTime = &liAccumulatedTime,
*pliSplitTime = &liSplitTime;
FILETIME ftAccumulatedTime,
*pftAccumulatedTime = &ftAccumulatedTime;
SYSTEMTIME stAccumulatedTime;
LPWSTR buffer = new wchar_t[BUFFERSIZE];
int j;
memset(buffer, 0, BUFFERSIZE);
liAccumulatedTime.QuadPart = 0;
// get a ResMgr context
lCallReturn = SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &hContext);
if ( SCARD_S_SUCCESS != lCallReturn) {
swprintf(buffer, L"Failed to initialize context: 0x%x\n", lCallReturn);
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
return (NTSTATUS)lCallReturn;
}
// list all readers
lCallReturn = SCardListReaders(hContext, SCARD_ALL_READERS, (LPTSTR)&szReaders, &dwReadersLen);
if (SCARD_S_SUCCESS != lCallReturn) {
swprintf(buffer, L"Failed to list readers on the system: 0x%x\n", lCallReturn);
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
return (NTSTATUS)lCallReturn;
} else if ((0 == dwReadersLen)
|| (NULL == szReaders)
|| (0 == *szReaders))
{
lCallReturn = SCARD_E_UNKNOWN_READER; // Or some such error
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
swprintf(buffer, L"Failed to identify a reader on the system: 0x%x\n", lCallReturn);
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
return (NTSTATUS)lCallReturn;
}
// list cards
lCallReturn = SCardListCards(hContext, NULL, NULL, 0, (LPTSTR)&mszCards, &dwCardsLen);
if ( SCARD_S_SUCCESS != lCallReturn) {
printf("Failed to list cards in the system: 0x%x\n", lCallReturn);
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
swprintf(buffer, L"Failed to identify a card on the system: 0x%x\n", lCallReturn);
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
return (NTSTATUS)lCallReturn;
}
// use the list of readers to build a readerstate array
nIndex = 0;
if (0 != wcslen(g_wszReaderName)) {
// use the reader specified in the command line
rgReaderStates[nIndex].szReader = (const unsigned short *)g_wszReaderName;
rgReaderStates[nIndex].dwCurrentState = SCARD_STATE_UNAWARE;
nCnReaders = 1;
} else {
pchReader = szReaders;
while (0 != *pchReader)
{
rgReaderStates[nIndex].szReader = pchReader;
rgReaderStates[nIndex].dwCurrentState = SCARD_STATE_UNAWARE;
pchReader += lstrlen(pchReader)+1;
nIndex++;
if (MAXIMUM_SMARTCARD_READERS == nIndex)
break;
}
nCnReaders = nIndex;
}
// find a reader with one of the listed cards, or the specified card, present
lCallReturn = SCardLocateCards(hContext, mszCards, rgReaderStates, nCnReaders);
if ( SCARD_S_SUCCESS != lCallReturn) {
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
swprintf(buffer, L"Failed to locate a smart card for logon: 0x%x\n", lCallReturn);
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
return (NTSTATUS)lCallReturn;
}
// find the reader containing the requested card
for (nIndex=0; nIndex<nCnReaders && FALSE == fFound; nIndex++) {
if (rgReaderStates[nIndex].dwEventState & SCARD_STATE_ATRMATCH) {
// reader found
fFound = TRUE;
break;
}
}
if (FALSE == fFound) {
lCallReturn = SCARD_E_NO_SMARTCARD; // or some such error
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
swprintf(buffer, L"No smart card in any reader: 0x%x\n", lCallReturn);
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
return (NTSTATUS)lCallReturn;
} else { // get the name of the card found
dwCardsLen = SCARD_AUTOALLOCATE;
lCallReturn = SCardListCards(hContext, rgReaderStates[nIndex].rgbAtr, NULL, 0, (LPTSTR)&szLogonCard, &dwCardsLen);
if ( SCARD_S_SUCCESS != lCallReturn ) {
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard);
swprintf(buffer, L"Failed to get name of card in reader: 0x%x\n", lCallReturn);
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
return (NTSTATUS)lCallReturn;
}
}
// get the csp provider name for the card
lCallReturn = SCardGetCardTypeProviderName(hContext, szLogonCard, SCARD_PROVIDER_CSP, (LPTSTR)&szCSPName, &dwCSPLen);
if ( SCARD_S_SUCCESS != lCallReturn) {
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
if (NULL != szCSPName) SCardFreeMemory(hContext, (LPVOID)szCSPName);
if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard);
swprintf(buffer, L"Failed to locate smart card crypto service provider: 0x%x\n", lCallReturn);
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
return (NTSTATUS)lCallReturn;
}
ScLogonInfo = BuildSCLogonInfo(szLogonCard,
rgReaderStates[nIndex].szReader,
TEXT(""), // use default container
szCSPName
);
//
// We should now have logon info.
//
if (NULL != szReaders) SCardFreeMemory(hContext, (LPVOID)szReaders);
if (NULL != mszCards ) SCardFreeMemory(hContext, (LPVOID)mszCards);
if (NULL != szCSPName) SCardFreeMemory(hContext, (LPVOID)szCSPName);
if (NULL != szLogonCard ) SCardFreeMemory(hContext, (LPVOID)szLogonCard);
j = swprintf(buffer, L"Reader : %s\n", GetReaderName(ScLogonInfo));
j += swprintf(buffer + j, L"Card : %s\n", GetCardName(ScLogonInfo));
j += swprintf(buffer + j, L"CSP : %s\n", GetCSPName(ScLogonInfo));
PrintMessage("%S",buffer);
memset(buffer, 0, sizeof(buffer));
// perform sclogon
if (ScLogonInfo == NULL)
{
swprintf(buffer, L"Failed to get logon info!\n");
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
return (NTSTATUS) -1;
}
ScLogonInfoSize = ((struct LogonInfo *) ScLogonInfo)->dwLogonInfoLen;
Status = ScHelperInitializeContext(
ScLogonInfo,
ScLogonInfoSize
);
if (!NT_SUCCESS(Status))
{
swprintf(buffer, L"Failed to initialize helper context: 0x%x\n",Status);
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
return (NTSTATUS)Status;
}
ScHelperRelease(ScLogonInfo);
RtlInitString(
&PinString,
Pin
);
LogonInfoSize += (PinString.Length+1 ) * sizeof(WCHAR) + ScLogonInfoSize;
LogonInfo = (PKERB_SMART_CARD_LOGON) LocalAlloc(LMEM_ZEROINIT, LogonInfoSize);
LogonInfo->MessageType = KerbSmartCardLogon;
Where = (PUCHAR) (LogonInfo + 1);
LogonInfo->Pin.Buffer = (LPWSTR) Where;
LogonInfo->Pin.MaximumLength = (USHORT) LogonInfoSize;
RtlAnsiStringToUnicodeString(
&LogonInfo->Pin,
&PinString,
FALSE
);
Where += LogonInfo->Pin.Length + sizeof(WCHAR);
LogonInfo->CspDataLength = ScLogonInfoSize;
LogonInfo->CspData = Where;
RtlCopyMemory(
LogonInfo->CspData,
ScLogonInfo,
ScLogonInfoSize
);
Where += ScLogonInfoSize;
//
// Turn on the TCB privilege
//
Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
if (!NT_SUCCESS(Status))
{
swprintf(buffer, L"Failed to adjust privilege: 0x%x\n",Status);
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
return (NTSTATUS)Status;
}
RtlInitString(
&Name,
"SmartCardLogon"
);
Status = LsaRegisterLogonProcess(
&Name,
&LogonHandle,
&Dummy
);
if (!NT_SUCCESS(Status))
{
swprintf(buffer, L"Failed to register as a logon process: 0x%x\n",Status);
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
return (NTSTATUS)Status;
}
strncpy(
SourceContext.SourceName,
"SmartCardLogon ",sizeof(SourceContext.SourceName)
);
NtAllocateLocallyUniqueId(
&SourceContext.SourceIdentifier
);
RtlInitString(
&Name,
MICROSOFT_KERBEROS_NAME_A
);
Status = LsaLookupAuthenticationPackage(
LogonHandle,
&Name,
&PackageId
);
if (!NT_SUCCESS(Status))
{
swprintf(buffer, L"Failed to lookup package %Z: 0x%x\n",&Name, Status);
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
return (NTSTATUS)Status;
}
//
// Now call LsaLogonUser
//
RtlInitString(
&Name,
"SmartCardLogon"
);
for (Index = 1; Index <= Count ; Index++ )
{
swprintf(buffer, L"\nLogon %.6d\n", Index);
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
// get start time
GetSystemTime(&StartTime);
Status = LsaLogonUser(
LogonHandle,
&Name,
Interactive,
PackageId,
LogonInfo,
LogonInfoSize,
NULL, // no token groups
&SourceContext,
(PVOID *) &Profile,
&ProfileSize,
&LogonId,
&TokenHandle,
&Quotas,
&SubStatus
);
// get done time
GetSystemTime(&DoneTime);
// convert systemtime to filetime
SystemTimeToFileTime(&StartTime, &ftStart);
SystemTimeToFileTime(&DoneTime, &ftDone);
// copy filetime to large int
CopyMemory(pliStart, pftStart, 8);
CopyMemory(pliDone, pftDone, 8);
// diff the large ints and accumulate result
liDone.QuadPart = liDone.QuadPart - liStart.QuadPart;
liAccumulatedTime.QuadPart = liAccumulatedTime.QuadPart + liDone.QuadPart;
// copy result back to filetime
CopyMemory(pftDone, pliDone, 8);
// convert result back to systemtime
FileTimeToSystemTime( (CONST FILETIME *)&ftDone, &stElapsed);
// output the result
swprintf(buffer, L"RunTime: %2.2ldm:%2.2lds:%3.3ldms\n",
stElapsed.wMinute,
stElapsed.wSecond,
stElapsed.wMilliseconds);
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
if (!NT_SUCCESS(Status))
{
j = swprintf(buffer, L"lsalogonuser failed: 0x%x\n",Status);
LPTSTR szErrorMessage = ErrorString((DWORD)Status);
if (NULL == szErrorMessage) {
j += swprintf(buffer + j, L" ErrorMessage: error message not found, check ntstatus.h\n");
} else {
j += swprintf(buffer + j, L" ErrorMessage: %S\n", szErrorMessage);
}
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
return (NTSTATUS)Status;
}
if (!NT_SUCCESS(SubStatus))
{
j = swprintf(buffer, L"LsalogonUser failed: substatus = 0x%x\n",SubStatus);
LPTSTR szErrorMessage = ErrorString((DWORD)Status);
if (NULL == szErrorMessage) {
j += swprintf(buffer + j, L" ErrorMessage: error message not found, check ntstatus.h\n");
} else {
j += swprintf(buffer + j, L" ErrorMessage: %S", szErrorMessage);
}
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
return (NTSTATUS)SubStatus;
}
ImpersonateLoggedOnUser( TokenHandle );
GetUserName(UserNameString,&NameLength);
j = swprintf(buffer, L"Result: %S", ErrorString((DWORD)Status));
j += swprintf(buffer, L"Username: %ws\n",UserNameString);
PrintMessage("%S",buffer);
memset(buffer, 0, BUFFERSIZE);
RevertToSelf();
NtClose(TokenHandle);
LsaFreeReturnBuffer(Profile);
Profile = NULL;
// report average every 10th logon
if (0 == Index % 10) {
liSplitTime.QuadPart = liAccumulatedTime.QuadPart / Index;
CopyMemory(pftAccumulatedTime, pliSplitTime, 8);
FileTimeToSystemTime( (CONST FILETIME *)&ftAccumulatedTime, &stAccumulatedTime);
swprintf(buffer, L"\nAverage Time after %d Logons: %2.2ldm:%2.2lds:%3.3ldms\n",
Index,
stAccumulatedTime.wMinute,
stAccumulatedTime.wSecond,
stAccumulatedTime.wMilliseconds);
PrintMessage("%S",buffer);
}
Sleep(2000); // let card stack unwind
}
// ouput average results
if ( 1 != Count ) {
liAccumulatedTime.QuadPart = liAccumulatedTime.QuadPart / Count;
CopyMemory(pftAccumulatedTime, pliAccumulatedTime, 8);
FileTimeToSystemTime( (CONST FILETIME *)&ftAccumulatedTime, &stAccumulatedTime);
swprintf(buffer, L"\nAverage Logon Time: %2.2ldm:%2.2lds:%3.3ldms\n",
stAccumulatedTime.wMinute,
stAccumulatedTime.wSecond,
stAccumulatedTime.wMilliseconds);
PrintMessage("%S", buffer);
}
return (NTSTATUS)Status;
}
VOID
PrintKdcName(
IN PKERB_INTERNAL_NAME Name
)
{
ULONG Index;
for (Index = 0; Index < Name->NameCount ; Index++ )
{
printf(" %wZ ",&Name->Names[Index]);
}
printf("\n");
}
int __cdecl
main(
IN int argc,
IN char ** argv
)
/*++
Routine Description:
Drive the NtLmSsp service
Arguments:
argc - the number of command-line arguments.
argv - an array of pointers to the arguments.
Return Value:
Exit status
--*/
{
LPSTR argument;
int i;
ULONG j;
ULONG Iterations = 0;
LPSTR PinBuffer = new char [81];
LPSTR szReaderBuffer = new char[BUFFERSIZE];
LPSTR EventMachineBuffer = new char [81];
LPWSTR wEventMachineBuffer = new wchar_t[81];
LPWSTR PackageFunction;
ULONG ContextReq = 0;
WCHAR ContainerName[100];
WCHAR CaName[100];
WCHAR CaLocation[100];
WCHAR ServiceName[100];
NTSTATUS Status = -1;
enum {
NoAction,
#define LOGON_PARAM "/p"
TestLogon,
#define ITERATION_PARAM "/i"
#define HELP_PARAM "/?"
//#define EVENT_PARAM "/s"
#define READER_PARAM "/r"
} Action = NoAction;
memset(g_wszReaderName, 0, BUFFERSIZE);
memset(szReaderBuffer, 0, BUFFERSIZE);
// open output file
outstream = fopen( "scardbvt.out", "w" );
//
// Loop through the arguments handle each in turn
//
if ( 1 == argc ) {// silent mode
Iterations = 1;
Action = TestLogon;
printf("Enter your pin number: ");
int ch;
int j = 0;
ch = _getch();
while (ch != 0x0d) {
j += sprintf(PinBuffer + j,"%c", ch);
printf("*");
ch = _getch();
}
printf("\n");
}
for ( i=1; i<argc; i++ ) {
argument = argv[i];
//
// Handle /ConfigureService
//
if ( _strnicmp( argument, LOGON_PARAM, sizeof(LOGON_PARAM)-1 ) == 0 ) {
if ( Action != NoAction ) {
goto Usage;
}
Iterations = 1;
Action = TestLogon;
if (argc <= i + 1) {
goto Usage;
}
PinBuffer = argv[++i];
} else if ( _strnicmp( argument, ITERATION_PARAM, sizeof(ITERATION_PARAM) - 1 ) == 0 ) {
if (argc <= i + 1) {
goto Usage;
}
Iterations = atoi(argv[++i]);
} /*else if ( _strnicmp( argument, EVENT_PARAM, sizeof(EVENT_PARAM) - 1 ) == 0 ) {
if (argc <= i + 1) {
goto Usage;
}
// save name of machine to which events will be posted
EventMachineBuffer = argv[++i];
wsprintfW(wEventMachineBuffer, L"%S", EventMachineBuffer);
SetEventMachine(&wEventMachineBuffer);
//Event(PERF_INFORMATION, L"Trying to set machine name\n", 1);
} */
else if ( _strnicmp( argument, HELP_PARAM, sizeof(HELP_PARAM) - 1 ) == 0 ) {
goto Usage;
} else if ( _strnicmp( argument, READER_PARAM, sizeof(READER_PARAM) - 1 ) == 0 ) {
if (argc <= i + 1) {
goto Usage;
}
// get the name of a specified reader
szReaderBuffer = argv[++i];
wsprintfW(g_wszReaderName, L"%S", szReaderBuffer);
} else {
printf("Invalid parameter : %s\n",argument);
goto Usage;
}
}
//
// Perform the action requested
//
switch ( Action ) {
case TestLogon :
Status = TestScLogonRoutine(
Iterations,
PinBuffer
);
break;
case NoAction :
goto Usage;
break;
}
return Status;
Usage:
PrintMessage("%s - no parameters, manually enter pin\n", argv[0]);
PrintMessage(" optional parameters (if any used, must have /p)\n");
PrintMessage(" /p Pin\n");
PrintMessage(" /i Iterations\n");
// printf(" /s EventMachineName (post events to this machine)\n");
PrintMessage(" /r %cReader Name X%c (registry device name in quotes)\n", '"', '"');
return -1;
}