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.
 
 
 
 
 
 

2619 lines
64 KiB

#include <process.h>
#include <windows.h>
//#include <winbase.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <shlwapi.h>
#include <conio.h>
//#include <shlwapip.h>
#include "resource.h"
#include "lists.hxx"
//#define DBG
#define DEBUG
#define _DEBUG
#include "main.hxx"
#define MAX_HANDLES 255
////////////////////////////////////////
//
// G L O B A L S
//
//
////////////////////////////////////////
CSessionAttributeList * g_pSessionAttributeList = NULL;
CSessionList * g_pSessionList = NULL;
DWORD dwThreads = 0;
int iNumIterations = 0;
unsigned uSeed = 0;
DWORD dwDebugLogCategory;
DWORD dwConsoleLogCategory;
DWORD dwDebugBreakCategory;
DWORD dwUIDialogMode = MODE_ALL;
BOOL fLogToDebugTerminal = FALSE;
BOOL fLogToConsole = TRUE;
BOOL fDebugBreak = FALSE;
#define MALLOC( x ) malloc(sizeof(x))
#define FIND_FUNCTION_KERNEL( x, y ) ( x##_P = (FN##x) GetProcAddress( hModule, #x ));
#define FIND_FUNCTION( x , y ) ( x##_P = (FN##x) GetProcAddress( hModule, y ));
#define IS_ARG(c) ( c == '-' )
//
// ACTION
// A routine which takes a LPVOID as input,
// performs some action
// and returns another LPVOID
//
typedef LPVOID ( WINAPI * ACTION)(LPVOID);
BOOL Test();
////////////////////////////////////////////////////////////////////////////////////
//
// D E C L A R A T I O N S
//
////////////////////////////////////////////////////////////////////////////////////
typedef enum {
MODE_NONE = -1,
MODE_BUSY,
MODE_FREE,
MODE_CAPTURED
} MODE;
/*
CONTEXT_RECORD CAPTURED_CTX = { { 0xcabdcabd, 0xcabdcabd };
CONTEXT_RECORD FREE_CTX = {{ 0, 0 };
CONTEXT_RECORD BUSY_CTX = {{ 0xb00bb00b, 0xb00bb00b };
*/
CredHandle CAPTURED_CRED = { 0xcabdcabd, 0xcabdcabd };
CredHandle FREE_CRED = { 0, 0 };
CredHandle BUSY_CRED = { 0xb00bb00b, 0xb00bb00b };
typedef struct _CONTEXT_RECORD {
// handle to the credential
CredHandle hCred;
// App ctx associated with this credential
LPSTR szAppCtx;
// User Ctx associated with this credential
LPSTR szUserCtx;
// Timestamp
DWORD dwTickCount;
// MODE
MODE Mode;
} CONTEXT_RECORD, * LPCONTEXT_RECORD;
// forward declarations
class CSessionAttribute;
#define MAX_APP_CONTEXT_LENGTH 32
#define MAX_USER_CONTEXT_LENGTH MAX_APP_CONTEXT_LENGTH
typedef struct _CREDENTIAL_STRUCT {
// username
LPSTR szUserName;
// password
LPSTR szPassword;
// realm
LPSTR szRealm;
} CREDENTIAL_STRUCT, *LPCREDENTIAL_STRUCT;
typedef struct _HANDLE_RECORD {
DWORD dwSignature;
CONTEXT_RECORD hCredArray[MAX_HANDLES];
int Count; // count of handles in use.
CRITICAL_SECTION Lock;
} HANDLE_RECORD, *LPHANDLE_RECORD;
#define CTXHANDLE_ARRAY_SIGNATURE 'xtch' // 'hctx'
#define IS_VALID_CTXHANDLE_ARRAY(x) { assert( x -> dwSignature == CTXHANDLE_ARRAY_SIGNATURE ); }
#define IDENTITY_1 "Application_1"
// bugbug: The values of the CredHandles in these structures should match
// the corresponding *_CRED structure values.
//
#ifdef NEW_LOOKUP
MODE ModeCaptured = MODE_CAPTURED;
MODE ModeFree = MODE_FREE;
MODE ModeBusy = MODE_BUSY;
#define CAPTURED_CTX_REC ModeCaptured
#define FREE_CTX_REC ModeFree
#define BUSY_CTX_REC ModeBusy
#else
CONTEXT_RECORD CAPTURED_CTX_REC = {
{ 0xcabdcabd, 0xcabdcabd },
NULL,
NULL};
CONTEXT_RECORD FREE_CTX_REC = {
{ 0, 0 },
NULL,
NULL};
CONTEXT_RECORD BUSY_CTX_REC = {
{ 0xb00bb00b, 0xb00bb00b },
NULL,
NULL};
#endif // ifdef NEW_LOOKUP
BOOL operator==(const CredHandle op1, const CredHandle op2)
{
return (( op1.dwUpper == op2.dwUpper ) && ( op1.dwUpper == op2.dwUpper ));
}
BOOL operator!=(const CredHandle op1, const CredHandle op2)
{
return (( op1.dwUpper != op2.dwUpper ) || ( op1.dwUpper != op2.dwUpper ));
}
BOOL operator==(const CONTEXT_RECORD op1, const CONTEXT_RECORD op2)
{
// we only compare the CredHandle
return (op1.hCred == op2.hCred );
}
BOOL operator!=(const CONTEXT_RECORD op1, const CONTEXT_RECORD op2)
{
// we only compare the CredHandle
return (op1.hCred != op2.hCred );
}
typedef struct {
// a string in the DWORD
DWORD dwSignature;
// handles to contexts
HANDLE_RECORD * hCredentialHandles;
// count of iterations
int iCount;
} CONTEXT_DATA, * LPCONTEXT_DATA;
#define CONTEXT_SIGNATURE 'tnoc'
#define IS_VALID_CONTEXT(s) { assert ( s -> dwSignature == CONTEXT_SIGNATURE ); }
#define SET_CONTEXT_SIGNATURE(s) { s -> dwSignature = CONTEXT_SIGNATURE; }
//
// contexts passed to threads, and RegisterWaits() etc.
//
typedef struct _CALLBACK_CONTEXT {
DWORD dwSignature;
LPCONTEXT_DATA lpContext;
LPHANDLE lpThreadHandle;
LPHANDLE lpHandle;
} CALLBACK_CONTEXT, * LPCALLBACK_CONTEXT;
#define CALLBACK_CONTEXT_SIGNATURE 'kblc' // clbk
#define IS_VALID_CALLBACK_CONTEXT(x) ( assert( s -> dwSignature ) == CALLBACK_CONTEXT_SIGNATURE )
#ifdef NEW_LOOKUP
LPCONTEXT_RECORD
FindFreeSlot(
HANDLE_RECORD * hArray,
LPCONTEXT_RECORD hMode);
#else
LPCONTEXT_RECORD
FindFreeSlot(
HANDLE_RECORD * hArray,
LPCONTEXT_RECORD hMode);
#endif
LPHANDLE_RECORD
new_handle_record(DWORD dwSignature);
LPCALLBACK_CONTEXT
new_callback_context();
LPVOID
WINAPI fnAppLogon(
LPVOID lpvData);
LPVOID
WINAPI fnAppLogonExclusive(
LPVOID lpvData);
LPVOID
WINAPI fnAppLogonShared(
LPVOID lpvData);
LPVOID
WINAPI fnAppLogoff(
LPVOID lpvData);
LPVOID
WINAPI fnInit(
LPVOID lpvData);
LPVOID
WINAPI fnPopulateCredentials(
LPVOID lpvData);
LPVOID
WINAPI fnAuthChallenge(
LPVOID lpvData);
LPVOID
WINAPI fnAuthChallengeAny(
LPVOID lpvData);
LPVOID
WINAPI fnAuthChallengeUser(
LPVOID lpvData);
LPVOID
WINAPI fnAuthChallengeUserPassword(
LPVOID lpvData);
LPVOID
WINAPI fnUiPrompt(
LPVOID lpvData);
LPVOID
WINAPI fnUiPromptAny(
LPVOID lpvData);
LPVOID
WINAPI fnUiPromptUser(
LPVOID lpvData);
LPVOID
WINAPI fnFlushCredentials(
LPVOID lpvData);
LPVOID
WINAPI fnFlushCredentialsGlobal(
LPVOID lpvData);
LPVOID
WINAPI fnFlushCredentialsSession(
LPVOID lpvData);
BOOL
SetUIUserNameAndPassword(
LPSTR szUsername,
LPSTR szPassword,
BOOL fPersist);
//DWORD WINAPI fnRegisterWaitCallback( PVOID pvData );
//
// Enum Type for STATE
//
typedef enum _State
{
STATE_INVALID,
STATE_NONE,
STATE_INIT,
STATE_APP_LOGON,
STATE_APP_LOGON_EXCLUSIVE,
STATE_APP_LOGON_SHARED,
STATE_APP_LOGOFF,
STATE_POPULATE_CREDENTIALS,
STATE_AUTH_CHALLENGE,
STATE_AUTH_CHALLENGE_ANY,
STATE_AUTH_CHALLENGE_USER,
STATE_AUTH_CHALLENGE_USER_PASS,
STATE_PREAUTH_CHALLENGE_ANY,
STATE_PREAUTH_CHALLENGE_USER,
STATE_PREAUTH_CHALLENGE_USER_PASS,
STATE_UI_PROMPT,
STATE_UI_PROMPT_ANY,
STATE_UI_PROMPT_USER,
STATE_FLUSH_CREDENTIALS,
STATE_FLUSH_CREDENTIALS_GLOBAL,
STATE_FLUSH_CREDENTIALS_SESSION,
STATE_NUKE_TRUSTED_HOSTS,
STATE_STATISTICS,
STATE_STALL,
STATE_DONE
} STATE;
//
// STATE Table definition
//
typedef struct _STATE_TABLE {
//
// The current state we are in
//
STATE CurrentState;
//
// THe next state which we will transition to
//
STATE NextState;
//
// Action ( function ) to be performed in the "CurrentState"
//
ACTION Action;
//
// prob of going from CurrentState to NextState if there
// are two or more such transitions from the same state
// present in the table
//
DWORD dwProbability;
} STATE_TABLE, *LPSTATE_TABLE;
STATE_TABLE TRANSITION_TABLE[] =
{
// transitions out of STATE_INIT
{
STATE_INIT, STATE_APP_LOGON,
fnInit,
50
},
// transitions out of STATE_INIT
{
STATE_INIT, STATE_FLUSH_CREDENTIALS,
fnInit,
100
},
// transitions out of STATE_APP_LOGON
{
STATE_APP_LOGON, STATE_UI_PROMPT,
fnAppLogon,
60
},
{
STATE_APP_LOGON, STATE_POPULATE_CREDENTIALS,
fnAppLogon,
70
},
{
STATE_APP_LOGON, STATE_AUTH_CHALLENGE,
fnAppLogon,
100
},
// transitions out of STATE_POPULATE_CREDENTIALS
{
STATE_POPULATE_CREDENTIALS, STATE_INIT,
fnPopulateCredentials,
30
},
{
STATE_POPULATE_CREDENTIALS, STATE_APP_LOGOFF,
fnPopulateCredentials,
60
},
{
STATE_POPULATE_CREDENTIALS, STATE_UI_PROMPT,
fnPopulateCredentials,
100
},
// transitions out of STATE_AUTH_CHALLENGE
{
STATE_AUTH_CHALLENGE, STATE_APP_LOGON,
fnAuthChallenge,
100
},
// transitions out of STATE_UI_PROMPT
{
STATE_UI_PROMPT, STATE_INIT,
fnUiPrompt,
100
},
// transitions out of STATE_FLUSH_CREDENTIALS
{
STATE_FLUSH_CREDENTIALS, STATE_APP_LOGON,
fnFlushCredentials,
100
},
// transitions out of STATE_APP_LOGOFF
{
STATE_APP_LOGOFF, STATE_APP_LOGON,
fnAppLogoff,
100
},
// transitions out of STATE_INVALID
{
STATE_INVALID, STATE_INVALID,
NULL,
100
},
// transitions out of STATE_DONE
{
STATE_DONE, STATE_INVALID,
NULL,
100
}
};
STATE_TABLE APP_LOGON_TRANSITION_TABLE[] =
{
// transitions out of STATE_INIT
{
STATE_INIT, STATE_APP_LOGON_SHARED,
fnInit,
50
},
{
STATE_INIT, STATE_APP_LOGON_EXCLUSIVE,
fnInit,
100
},
// transitions out of STATE_APP_LOGON_EXCLUSIVE
{
STATE_APP_LOGON_EXCLUSIVE, STATE_DONE,
fnAppLogonExclusive,
50
},
{
STATE_APP_LOGON_SHARED, STATE_DONE,
fnAppLogonShared,
100
},
// transitions out of STATE_DONE
{
STATE_DONE, STATE_DONE,
NULL,
100
}
};
STATE_TABLE AUTH_CHALLENGE_TRANSITION_TABLE[] =
{
// transitions out of STATE_INIT
{
STATE_INIT, STATE_AUTH_CHALLENGE_ANY,
fnInit,
30
},
{
STATE_INIT, STATE_AUTH_CHALLENGE_USER,
fnInit,
70
},
{
STATE_INIT, STATE_AUTH_CHALLENGE_USER_PASS,
fnInit,
100
},
// transitions out of STATE_AUTH_CHALLENGE_ANY
{
STATE_AUTH_CHALLENGE_ANY, STATE_DONE,
fnAuthChallengeAny,
50
},
// transitions out of STATE_AUTH_CHALLENGE_USER
{
STATE_AUTH_CHALLENGE_USER, STATE_DONE,
fnAuthChallengeUser,
100
},
// transitions out of STATE_AUTH_CHALLENGE_USER_PASS
{
STATE_AUTH_CHALLENGE_USER_PASS, STATE_DONE,
fnAuthChallengeUserPassword,
100
},
// transitions out of STATE_DONE
{
STATE_DONE, STATE_DONE,
NULL,
100
}
};
STATE_TABLE UI_PROMPT_TRANSITION_TABLE[] =
{
// transitions out of STATE_INIT
{
STATE_INIT, STATE_UI_PROMPT_ANY,
fnInit,
50
},
{
STATE_INIT, STATE_UI_PROMPT_USER,
fnInit,
100
},
// transitions out of STATE_UI_PROMPT_ANY
{
STATE_UI_PROMPT_ANY, STATE_DONE,
fnUiPromptAny,
100
},
// transitions out of STATE_UI_PROMPT_USER
{
STATE_UI_PROMPT_USER, STATE_DONE,
fnUiPromptUser,
100
},
// transitions out of STATE_DONE
{
STATE_DONE, STATE_DONE,
NULL,
100
}
};
STATE_TABLE FLUSH_CREDENTIALS_TRANSITION_TABLE[] =
{
// transitions out of STATE_INIT
{
STATE_INIT, STATE_FLUSH_CREDENTIALS_SESSION,
fnInit,
50
},
{
STATE_INIT, STATE_FLUSH_CREDENTIALS_GLOBAL,
fnInit,
100
},
// transitions out of STATE_FLUSH_CREDENTIALS_SESSION
{
STATE_FLUSH_CREDENTIALS_SESSION, STATE_DONE,
fnFlushCredentialsSession,
100
},
// transitions out of STATE_FLUSH_CREDENTIALS_GLOBAL
{
STATE_FLUSH_CREDENTIALS_GLOBAL, STATE_DONE,
fnFlushCredentialsGlobal,
100
},
// transitions out of STATE_DONE
{
STATE_DONE, STATE_DONE,
NULL,
100
}
};
VOID WINAPI fnRegisterWaitCallback(
PVOID pvData,
BOOLEAN fAlertable);
VOID WINAPI fnTimerCallback(
PVOID pvData,
BOOLEAN fAlertable);
LPCONTEXT_DATA
new_context();
DWORD
TuringMachine(
STATE_TABLE StateTable[],
STATE InitialState,
LPVOID lpvData);
//WAITORTIMERCALLBACKFUNC fnRegisterWaitCallback;
//extern HANDLE RegisterWaitForSingleObject( HANDLE, WAITORTIMERCALLBACKFUNC, PVOID, DWORD);
STATE
NEXT_STATE( STATE_TABLE Table[], STATE CurrentState );
ACTION
GET_STATE_ACTION( STATE_TABLE Table[], STATE CurrentState );
LPSTR
MapState( STATE State );
void
usage(void);
int __cdecl _sprintf( char * buffer, char * format, va_list );
LPVOID
WINAPI DefaultAction(
LPVOID lpvData);
#ifdef NEW_LOOKUP
LPCONTEXT_RECORD
FindFreeSlot( HANDLE_RECORD * hArray, MODE * Mode )
{
// hMode is for doing a context-sensitive search
//
// If hMode == FREE_CTX,
// begin
// find a free-slot;
// mark it busy
// return the slot;
// end
// else
// if hMode == BUSY_CTX
// begin
// find a busy-slot
// return slot
// end
// else
// /* this means that a search is being requested */
// find a record corresponding to hMode
// return it
//
int i;
HANDLE hTemp = NULL, hOrig = NULL;
LPCONTEXT_RECORD phRet = NULL;
int Cnt=0;
dprintf( ENTRY_EXIT, "Enter: FindFreeSlot( %#X, %s )\n",
hArray,
((*Mode == MODE_FREE)
?"FREE"
:((*Mode == MODE_BUSY)
?"BUSY"
:"CAPTURED")));
EnterCriticalSection( &hArray -> Lock );
for( i = 0; (i < MAX_HANDLES) && (Cnt <= hArray -> Count); i ++, Cnt++ ) {
if( // requesting a free slot
(
( *Mode == MODE_FREE )
&& ( hArray -> hCredArray[i].Mode == MODE_FREE )
)
|| // requesting any slot having valid credentials
(
( *Mode == MODE_BUSY )
&& ( hArray -> hCredArray[i].Mode == MODE_BUSY )
//&& ( hArray -> hCredArray[i].Mode != MODE_FREE )
//&& ( hArray -> hCredArray[i].Mode != MODE_CAPTURED )
)
//|| // doing a context sensitive search
// ( // bugbug: what happens when szAppCtx stored is zero ?
// //( hArray -> hCredArray[i].Mode != MODE_FREE )
// ( hArray -> hCredArray[i].Mode == MODE_BUSY )
// && ( hMode -> szAppCtx && *hMode -> szAppCtx )
// && !strcmp( hArray -> hCredArray[i].szAppCtx, hMode -> szAppCtx )
// )
) {
// capture the handle if the handle requested is a free handle
if( *Mode == MODE_FREE )
hArray -> hCredArray[i].Mode = MODE_CAPTURED;
phRet = &hArray -> hCredArray[i];
break;
}
}
LeaveCriticalSection( &hArray -> Lock );
if(( i == MAX_HANDLES ) || (Cnt > hArray -> Count) )
phRet = NULL;
else {
++ hArray -> Count;
}
if( phRet != NULL ) {
dprintf( ENTRY_EXIT, "Exit: FindFreeSlot returns [%#x,%#x]\n",
phRet->hCred.dwUpper,
phRet->hCred.dwLower);
} else {
dprintf( ENTRY_EXIT, "Exit: FindFreeSlot returns %#x\n",phRet);
}
return phRet;
}
#else
LPCONTEXT_RECORD
FindFreeSlot( HANDLE_RECORD * hArray, LPCONTEXT_RECORD hMode )
{
// hMode is for doing a context-sensitive search
//
// If hMode == FREE_CTX,
// begin
// find a free-slot;
// mark it busy
// return the slot;
// end
// else
// if hMode == BUSY_CTX
// begin
// find a busy-slot
// return slot
// end
// else
// /* this means that a search is being requested */
// find a record corresponding to hMode
// return it
//
int i;
HANDLE hTemp = NULL, hOrig = NULL;
LPCONTEXT_RECORD phRet = NULL;
int Cnt=0;
dprintf( ENTRY_EXIT, "Enter: FindFreeSlot( %#X, %#X )\n",hArray, hMode );
EnterCriticalSection( &hArray -> Lock );
for( i = 0; (i < MAX_HANDLES) && (Cnt <= hArray -> Count); i ++, Cnt++ ) {
if( // requesting a free slot
(
( hMode -> hCred == FREE_CRED )
&& ( hArray -> hCredArray[i].hCred == hMode -> hCred )
)
|| // requesting any slot having valid credentials
(
( hMode -> hCred == BUSY_CRED )
&& ( hArray -> hCredArray[i].hCred != FREE_CRED )
&& ( hArray -> hCredArray[i].hCred != CAPTURED_CRED )
)
|| // doing a context sensitive search
( // bugbug: what happens when szAppCtx stored is zero ?
( hArray -> hCredArray[i].hCred != FREE_CRED )
&& ( hMode -> szAppCtx && *hMode -> szAppCtx )
&& !strcmp( hArray -> hCredArray[i].szAppCtx, hMode -> szAppCtx )
)
) {
// capture the handle if the handle requested is a free handle
if( hMode->hCred == FREE_CRED )
hArray -> hCredArray[i].hCred = CAPTURED_CRED;
phRet = &hArray -> hCredArray[i];
break;
}
}
LeaveCriticalSection( &hArray -> Lock );
if(( i == MAX_HANDLES ) || (Cnt > hArray -> Count) )
phRet = NULL;
else {
++ hArray -> Count;
}
if( phRet != NULL ) {
dprintf( ENTRY_EXIT, "Exit: FindFreeSlot returns %#x(%#x)\n",phRet,*phRet);
} else {
dprintf( ENTRY_EXIT, "Exit: FindFreeSlot returns %#x\n",phRet);
}
return phRet;
}
#endif
int __cdecl dprintf(DWORD dwCategory, char * format, ...) {
va_list args;
char buf[1024];
char * ptr = buf;
DWORD dwThreadId = GetCurrentThreadId();
int n;
ptr += sprintf(buf,"< %d:%#x > ", uSeed, dwThreadId );
va_start(args, format);
n = vsprintf(ptr, format, args);
va_end(args);
if(
(fLogToDebugTerminal )
&& (dwCategory >= dwDebugLogCategory)
)
OutputDebugString(buf);
if(
( fLogToConsole)
&& ( dwCategory >= dwConsoleLogCategory)
)
printf("%s", buf );
if(
fDebugBreak
&& ( dwCategory >= dwDebugBreakCategory )
) {
DebugBreak();
}
return n;
}
void
usage()
{
dprintf( INFO, "thrdtest \n"
" -n<number-of-iterations> \n"
" -s: Directly Load the DLL \n"
" -d<Level>: What to log to debug terminal (default: NO logging)\n"
" -c<Level>: What to log to console (Default: INFO)\n"
" <Level>: INFO %d\n"
" ENTRY_EXIT %d\n"
" STATISTICS %d\n"
" API %d\n"
" ERROR %d\n"
" FATAL %d\n",
INFO,
ENTRY_EXIT,
STATISTICS,
API,
ERROR,
FATAL
);
exit(0);
}
LPVOID
WINAPI fnEndMonkey(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
dprintf( ENTRY_EXIT, "ENTER: fnEndMonkey : %X\n", lpvData );
dprintf( INFO, "\n\n\n Statistics ...................................\n");
dprintf( ENTRY_EXIT, "EXIT: fnEndMonkey : %X\n", lpvData );
return lpvData;
}
LPCONTEXT_DATA
new_context()
{
LPCONTEXT_DATA lpContext;
lpContext = (LPCONTEXT_DATA) MALLOC( CONTEXT_DATA );
if( !lpContext ) {
dprintf( ERROR, "Error allocating context \n");
exit(0);
}
ZeroMemory( lpContext, sizeof(CONTEXT_DATA) );
lpContext -> dwSignature = CONTEXT_SIGNATURE;
return lpContext;
}
LPHANDLE_RECORD
new_handle_record(DWORD dwSignature)
{
LPHANDLE_RECORD lpContext;
dprintf( ENTRY_EXIT, "Enter: new_handle_record \n");
lpContext = (LPHANDLE_RECORD) MALLOC( HANDLE_RECORD );
if( !lpContext ) {
dprintf( ERROR, "Error allocating handle record \n");
exit(0);
}
ZeroMemory( lpContext, sizeof(HANDLE_RECORD) );
for(int i=0; i < MAX_HANDLES; i++ ) {
lpContext->hCredArray[i].Mode = MODE_FREE;
lpContext->hCredArray[i].dwTickCount = 0;
lpContext->hCredArray[i].hCred.dwUpper = 0;
lpContext->hCredArray[i].hCred.dwLower = 0;
lpContext->hCredArray[i].szAppCtx = NULL;
lpContext->hCredArray[i].szUserCtx = NULL;
}
lpContext -> dwSignature = dwSignature;
InitializeCriticalSection( &lpContext->Lock);
//lpContext -> dwSignature = CONTEXT_SIGNATURE;
dprintf( ENTRY_EXIT, "Exit: new_handle_record \n");
return lpContext;
}
LPCALLBACK_CONTEXT
new_callback_context()
{
LPCALLBACK_CONTEXT lpContext;
dprintf( ENTRY_EXIT, "Enter: new_callback_context \n");
lpContext = (LPCALLBACK_CONTEXT) MALLOC( CALLBACK_CONTEXT );
if( !lpContext ) {
dprintf( ERROR, "Error allocating callback context \n");
exit(0);
}
ZeroMemory( lpContext, sizeof(CALLBACK_CONTEXT) );
lpContext -> dwSignature = CALLBACK_CONTEXT_SIGNATURE;
dprintf( ENTRY_EXIT, "Exit: new_callback_context \n");
return lpContext;
}
int
__cdecl main( int ac, char * av[] )
{
DWORD dwError;
LPCONTEXT_DATA lpContext;
//ZeroMemory( (LPVOID)&_Context, sizeof(CONTEXT_DATA) );
HMODULE hModule = NULL;
BOOL fExpectingIterations = FALSE;
BOOL fUseDigestDllOnly = FALSE;
BOOL fExpectingSeedValue = FALSE;
BOOL fTest = FALSE;
dwDebugLogCategory = ERROR;
dwConsoleLogCategory = INFO;
uSeed = (unsigned )time(NULL) ;
for( ac--, av++; ac; ac--, av++) {
if(IS_ARG(**av)) {
switch(*++*av) {
case 'n' :
if( *++*av) {
iNumIterations = atoi(*av);
} else
fExpectingIterations = TRUE;
break;
case 's' :
fUseDigestDllOnly = TRUE;
break;
case 'd' :
fLogToDebugTerminal = TRUE;
if( *++*av) {
dwDebugLogCategory = (DWORD)atoi(*av);
} else
dwDebugLogCategory = ERROR;
break;
case 'c' :
if( *++*av) {
dwConsoleLogCategory = (DWORD)atoi(*av);
} else
dwConsoleLogCategory = INFO;
break;
case 'b' :
fDebugBreak = TRUE;
if( *++*av) {
dwDebugBreakCategory = (DWORD)atoi(*av);
} else
dwDebugBreakCategory = ERROR;
break;
case 'r' :
if( *++*av) {
uSeed = atol(*av);
} else
fExpectingSeedValue = TRUE;
break;
case 't' :
fTest = TRUE;
break;
case 'i' :
dwUIDialogMode = MODE_IE_ONLY;
break;
case '?':
case 'h':
default:
usage();
exit(0);
break;
} // switch
} else {
if( fExpectingIterations ) {
if( *av ) {
iNumIterations = atoi(*av);
fExpectingIterations = FALSE;
}
} else
if( fExpectingSeedValue ) {
if( *av ) {
uSeed = atol(*av);
fExpectingSeedValue = FALSE;
}
} else
usage();
} // if IS_ARG
} // for
if( fExpectingIterations )
iNumIterations = -1; // infinite
dprintf( INFO, "Monkey Circus Starts ... \n");
// Get (global) dispatch table.
InitializeSecurityInterface(fUseDigestDllOnly );
// Check to see if we have digest.
if (!HaveDigest())
{
goto cleanup;
}
if( fTest ) {
Test();
goto cleanup;
}
//
// initialize global session lists
//
#ifdef AI
g_pSessionAttributeList = new CSessionAttributeList();
g_pSessionList = new CSessionList();
#endif
lpContext = new_context();
lpContext -> hCredentialHandles = new_handle_record( CTXHANDLE_ARRAY_SIGNATURE );
srand( uSeed );
dwError = TuringMachine(
TRANSITION_TABLE,
STATE_INIT,
(LPVOID) lpContext
);
cleanup:
dprintf( INFO, "Monkey circus ending ...\n");
if( hModule )
FreeLibrary( hModule );
return 0;
}
DWORD
TuringMachine(
STATE_TABLE StateTable[],
STATE InitialState,
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = ( LPCONTEXT_DATA ) lpvData;
BOOL fDone = FALSE;
STATE CurrentState;
STATE NextState;
ACTION Action;
LPVOID lpNewContext;
CurrentState = InitialState;
#define MAP_STATE(s) MapState(s)
while(
( !fDone )
&& ( lpContext -> iCount != iNumIterations)
) {
//fnStatistics( lpvData );
NextState = NEXT_STATE( StateTable, CurrentState );
#ifdef DEBUG
dprintf( INFO, "Current State : %s, Next : %s\n", MAP_STATE( CurrentState ), MAP_STATE( NextState ) );
#endif
// increment the count of iterations thru the monkey
++ lpContext -> iCount;
switch( CurrentState ) {
case STATE_INIT :
case STATE_STATISTICS:
case STATE_STALL:
case STATE_APP_LOGON:
case STATE_APP_LOGON_EXCLUSIVE:
case STATE_APP_LOGON_SHARED:
case STATE_APP_LOGOFF:
case STATE_POPULATE_CREDENTIALS:
case STATE_AUTH_CHALLENGE:
case STATE_AUTH_CHALLENGE_ANY:
case STATE_AUTH_CHALLENGE_USER:
case STATE_AUTH_CHALLENGE_USER_PASS:
case STATE_PREAUTH_CHALLENGE_ANY:
case STATE_PREAUTH_CHALLENGE_USER:
case STATE_PREAUTH_CHALLENGE_USER_PASS:
case STATE_UI_PROMPT:
case STATE_UI_PROMPT_ANY:
case STATE_UI_PROMPT_USER:
case STATE_FLUSH_CREDENTIALS:
case STATE_FLUSH_CREDENTIALS_GLOBAL:
case STATE_FLUSH_CREDENTIALS_SESSION:
Action = GET_STATE_ACTION( StateTable, CurrentState );
lpNewContext = (LPVOID) Action((LPVOID)lpContext);
break;
case STATE_INVALID :
case STATE_DONE :
fDone = TRUE;
goto finish;
break;
default:
dprintf( INFO, "BUGBUG: Reached default state \n");
break;
//break;
;
}
CurrentState = NextState;
NextState = STATE_INVALID;
}
//scanf("%d",&i);
finish:
return ERROR_SUCCESS;
}
STATE
NEXT_STATE( STATE_TABLE Table[], STATE CurrentState )
{
STATE NextState = STATE_INVALID;
int i;
DWORD dwRand,
dwPreviousStateProbability = 0,
dwProbability = 0;
BOOL fFound = FALSE;
// first generate a random number between 0 & 100 ( 0 .. 99 )
i = (int)(rand() % 100);
dwRand = (DWORD) i;
#ifdef _DEBUGG
for( i=0; Table[i].Action; i++ ) {
dprintf( INFO, "--- \t %s %s %X %d\n",
MAP_STATE( Table[i].CurrentState ),
MAP_STATE( Table[i].NextState ),
Table[i].Action,
Table[i].dwProbability );
}
#endif
//
// BUGBUG: We assume that the transition table entries are ordered in the ascending order of probabilities
for( i = 0; Table[i].Action; i++ ) {
if( Table[i].CurrentState != CurrentState )
continue;
dwProbability = Table[i].dwProbability;
NextState = Table[i].NextState;
#ifdef _DEBUGG
dprintf( INFO, "RAND: %d CurrentState: %s Considering Next State %s, prob %d\n",
dwRand, MAP_STATE( CurrentState ), MAP_STATE( NextState ), Table[i].dwProbability );
#endif
if(
( Table[i].CurrentState == CurrentState )
&& (
( Table[i].dwProbability == 100 )
|| (
( dwRand <= Table[i].dwProbability )
&& ( dwRand > dwPreviousStateProbability )
)
)
) {
fFound = TRUE;
#ifdef _DEBUGG
dprintf( INFO, ">> RAND: %d Selected Next State %s, prob %d\n",
dwRand, MAP_STATE( NextState ), Table[i].dwProbability );
#endif
break;
}
dwPreviousStateProbability = Table[i].dwProbability;
}
return fFound?NextState:STATE_INVALID;
}
ACTION
GET_STATE_ACTION( STATE_TABLE Table[], STATE CurrentState )
{
STATE NextState = STATE_INVALID;
ACTION Action = DefaultAction;
int i;
for( i = 0; Table[i].Action; i++ ) {
if( Table[i].CurrentState == CurrentState )
Action = Table[i].Action;
}
return Action;
}
LPSTR
MapState( STATE State )
{
#define MAP_STRING( x ) case x : return #x; break;
switch( State )
{
MAP_STRING( STATE_INVALID )
MAP_STRING( STATE_NONE )
MAP_STRING( STATE_INIT )
MAP_STRING( STATE_STATISTICS )
MAP_STRING( STATE_STALL )
MAP_STRING( STATE_DONE )
MAP_STRING( STATE_APP_LOGON )
MAP_STRING( STATE_APP_LOGON_EXCLUSIVE )
MAP_STRING( STATE_APP_LOGON_SHARED )
MAP_STRING( STATE_APP_LOGOFF )
MAP_STRING( STATE_POPULATE_CREDENTIALS )
MAP_STRING( STATE_AUTH_CHALLENGE )
MAP_STRING( STATE_AUTH_CHALLENGE_ANY )
MAP_STRING( STATE_AUTH_CHALLENGE_USER )
MAP_STRING( STATE_AUTH_CHALLENGE_USER_PASS )
MAP_STRING( STATE_PREAUTH_CHALLENGE_ANY )
MAP_STRING( STATE_PREAUTH_CHALLENGE_USER )
MAP_STRING( STATE_PREAUTH_CHALLENGE_USER_PASS )
MAP_STRING( STATE_UI_PROMPT )
MAP_STRING( STATE_UI_PROMPT_USER )
MAP_STRING( STATE_UI_PROMPT_ANY )
MAP_STRING( STATE_FLUSH_CREDENTIALS )
MAP_STRING( STATE_FLUSH_CREDENTIALS_GLOBAL )
MAP_STRING( STATE_FLUSH_CREDENTIALS_SESSION )
default:
return "???";
break;
}
}
LPVOID
WINAPI DefaultAction(
LPVOID lpvData)
{
dprintf( ENTRY_EXIT, "DefaultAction : %X\n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnInit(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
dprintf( ENTRY_EXIT, "Enter: fnInit %#x \n", lpvData );
dprintf( ENTRY_EXIT, "Exit: fnInit %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnAppLogoff(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
DWORD dwError = ERROR_SUCCESS;
SECURITY_STATUS ss;
dprintf( ENTRY_EXIT, "Enter: fnAppLogoff %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &BUSY_CTX_REC );
if( lpCtxRecord != NULL ) {
ss = LogoffOfDigestPkg(&lpCtxRecord -> hCred);
if(!SEC_SUCCESS(ss) ) {
dprintf(ERROR,"FreeCredentialHandle failed %s\n",
issperr2str(ss));
}
lpCtxRecord -> hCred = FREE_CRED;
lpCtxRecord ->szAppCtx = NULL;
lpCtxRecord ->szUserCtx = NULL;
lpCtxRecord->Mode = MODE_FREE;
}
dprintf( ENTRY_EXIT, "Exit: fnAppLogoff %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnAppLogon(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
DWORD dwError = ERROR_SUCCESS;
dprintf( ENTRY_EXIT, "Enter: fnAppLogon %#x \n", lpvData );
dwError = TuringMachine(
APP_LOGON_TRANSITION_TABLE,
STATE_INIT,
lpvData
);
dprintf( ENTRY_EXIT, "Exit: fnAppLogon %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnAppLogonExclusive(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
SECURITY_STATUS ss;
dprintf( ENTRY_EXIT, "Enter: fnAppLogonExclusive %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &FREE_CTX_REC );
if( lpCtxRecord != NULL ) {
lpCtxRecord -> szAppCtx = NULL;
lpCtxRecord -> szUserCtx = IDENTITY_1;
//
// BUGBUG: Need to ensure new usernames every time
//
ss = LogonToDigestPkg(NULL, IDENTITY_1, &lpCtxRecord -> hCred);
if(!SEC_SUCCESS(ss) ) {
dprintf(ERROR,"AcquireCredentialHandle(%s,%s) failed (%s)\n",
lpCtxRecord -> szAppCtx,
lpCtxRecord -> szUserCtx,
issperr2str(ss));
//
// Since we failed, Release the slot
//
lpCtxRecord->Mode = MODE_FREE;
} else {
lpCtxRecord->Mode = MODE_BUSY;
}
}
dprintf( ENTRY_EXIT, "Exit: fnAppLogonExclusive %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnAppLogonShared(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
SECURITY_STATUS ss;
dprintf( ENTRY_EXIT, "Enter: fnAppLogonShared %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &FREE_CTX_REC );
if( lpCtxRecord != NULL ) {
lpCtxRecord -> szAppCtx = NULL;
lpCtxRecord -> szUserCtx = NULL;
ss = LogonToDigestPkg(NULL, NULL, &lpCtxRecord -> hCred);
if(!SEC_SUCCESS(ss) ) {
dprintf(ERROR,"AcquireCredentialHandle(%s,%s) failed (%s)\n",
lpCtxRecord -> szAppCtx,
lpCtxRecord -> szUserCtx,
issperr2str(ss));
//
// Since we failed, Release the slot
//
lpCtxRecord->Mode = MODE_FREE;
} else {
lpCtxRecord->Mode = MODE_BUSY;
}
}
dprintf( ENTRY_EXIT, "Exit: fnAppLogonShared %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnPopulateCredentials(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
dprintf( ENTRY_EXIT, "Enter: fnPopulateCredentials %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &BUSY_CTX_REC );
if( lpCtxRecord != NULL ) {
// realm 1
PrimeCredCache(lpCtxRecord -> hCred, "[email protected]", "[email protected]", "pass1_1");
PrimeCredCache(lpCtxRecord -> hCred, "[email protected]", "[email protected]", "pass2_1");
PrimeCredCache(lpCtxRecord -> hCred, "[email protected]", "[email protected]", "pass3_1");
// realm 2
PrimeCredCache(lpCtxRecord -> hCred, "[email protected]", "[email protected]", "pass1_2");
// realm 3
PrimeCredCache(lpCtxRecord -> hCred, "[email protected]", "[email protected]", "pass1_3");
}
dprintf( ENTRY_EXIT, "Exit: fnPopulateCredentials %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnAuthChallenge(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
DWORD dwError = ERROR_SUCCESS;
dprintf( ENTRY_EXIT, "Enter: fnAuthChallenge %#x \n", lpvData );
dwError = TuringMachine(
AUTH_CHALLENGE_TRANSITION_TABLE,
STATE_INIT,
lpvData
);
dprintf( ENTRY_EXIT, "Exit: fnAuthChallenge %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnAuthChallengeAny(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
dprintf( ENTRY_EXIT, "Enter: fnAuthChallengeAny %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &BUSY_CTX_REC );
SECURITY_STATUS ss;
if( lpCtxRecord != NULL ) {
//LPSTR szChallenge;
//szChallenge = "realm=\"[email protected]\", stale = FALSE, qop=\"auth,auth-int\", nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\", opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"";
TCHAR szChallenge[512];
DWORD cbChallenge=512;
GenerateServerChallenge(szChallenge,cbChallenge);
// Package will dump response into this buffer.
CHAR szResponse[4096];
CtxtHandle hCtxt = {0,0};
memset((LPVOID)szResponse,0,4096);
// First try at authenticating.
ss = DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
NULL, // Ctxt not specified first time.
&hCtxt, // Output context.
ISC_REQ_USE_SUPPLIED_CREDS, // auth from cache.
szChallenge, // Server challenge header.
NULL, // no realm since not preauth.
"www.foo.com", // Host.
"/bar/baz/boz/bif.html", // Url.
"GET", // Method.
NULL, // no Username
NULL, // no Password.
NULL, // no nonce
NULL, // don't need hdlg for auth.
szResponse, // Response buffer.
4096);
}
if(!SEC_SUCCESS(ss) ) {
dprintf(ERROR,"ISC(use-supplied-cred) Failed %s \n", issperr2str(ss) );
}
dprintf( ENTRY_EXIT, "Exit: fnAuthChallengeAny %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnAuthChallengeUser(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
dprintf( ENTRY_EXIT, "Enter: fnAuthChallengeUser %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &BUSY_CTX_REC );
SECURITY_STATUS ss;
if( lpCtxRecord != NULL ) {
//LPSTR szChallenge;
//szChallenge = "realm=\"[email protected]\", stale = FALSE, qop=\"auth,auth-int\", nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\", opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"";
TCHAR szChallenge[512];
DWORD cbChallenge=512;
GenerateServerChallenge(szChallenge,cbChallenge);
// Package will dump response into this buffer.
CHAR szResponse[4096];
CtxtHandle hCtxt = {0,0};
memset((LPVOID)szResponse,0,4096);
// First try at authenticating.
ss = DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
NULL, // Ctxt not specified first time.
&hCtxt, // Output context.
ISC_REQ_USE_SUPPLIED_CREDS, // auth from cache.
szChallenge, // Server challenge header.
NULL, // no realm since not preauth.
"www.foo.com", // Host.
"/bar/baz/boz/bif.html", // Url.
"GET", // Method.
"[email protected]", // no Username
NULL, // no Password.
NULL, // no nonce
NULL, // don't need hdlg for auth.
szResponse, // Response buffer.
4096);
}
if(!SEC_SUCCESS(ss) ) {
dprintf(ERROR,"ISC(use-supplied-cred) Failed %s \n", issperr2str(ss) );
}
dprintf( ENTRY_EXIT, "Exit: fnAuthChallengeUser %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnAuthChallengeUserPassword(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
dprintf( ENTRY_EXIT, "Enter: fnAuthChallengeUserPassword %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &BUSY_CTX_REC );
SECURITY_STATUS ss;
if( lpCtxRecord != NULL ) {
//LPSTR szChallenge;
//szChallenge = "realm=\"[email protected]\", stale = FALSE, qop=\"auth,auth-int\", nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\", opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"";
TCHAR szChallenge[512];
DWORD cbChallenge=512;
GenerateServerChallenge(szChallenge,cbChallenge);
// Package will dump response into this buffer.
CHAR szResponse[4096];
CtxtHandle hCtxt = {0,0};
memset((LPVOID)szResponse,0,4096);
// First try at authenticating.
ss =
DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
NULL, // Ctxt not specified first time.
&hCtxt, // Output context.
ISC_REQ_USE_SUPPLIED_CREDS, // auth from cache.
szChallenge, // Server challenge header.
NULL, // no realm since not preauth.
"www.foo.com", // Host.
"/bar/baz/boz/bif.html", // Url.
"GET", // Method.
"[email protected]", // no Username
"pass1_1", // no Password.
NULL, // no nonce
NULL, // don't need hdlg for auth.
szResponse, // Response buffer.
4096);
}
if(!SEC_SUCCESS(ss) ) {
dprintf(ERROR,"ISC(use-supplied-cred) Failed %s \n", issperr2str(ss) );
DebugBreak();
}
dprintf( ENTRY_EXIT, "Exit: fnAuthChallengeUserPassword %#x \n", lpvData );
return lpvData;
}
BOOL
SetUIUserNameAndPassword(
LPSTR szUsername,
LPSTR szPassword,
BOOL fPersist)
{
#define DIALOGCLASS 32770
#define IDB_OK_BUTTON 1
#define ODS(s) dprintf(FATAL,s);
LPSTR m_szMainCaption = "Enter Network Password";
HWND hdlg;
DWORD dwTime;
DWORD dwCount=0;
dwTime = GetTickCount();
//Use this to get the hdlg for the dialog window
hdlg =::FindWindow(MAKEINTATOM(32770),(LPCTSTR)m_szMainCaption);
while ((NULL==hdlg) && (GetTickCount() - dwTime <= 10000)) {
//dprintf(FATAL,"Cannot find dialog window: %d\n",GetLastError());
// return FALSE;
hdlg =::FindWindow(MAKEINTATOM(32770),(LPCTSTR)m_szMainCaption);
}
if( hdlg == NULL ) {
dprintf(FATAL,"Cannot find dialog window: %d\n",GetLastError());
//DebugBreak();
return FALSE;
}
dprintf(INFO,"Found window.....\n");
//Use this after you've got the handle to the main dialog window.
//This will look for the edit control and enter text.
if( fPersist ) {
dprintf(INFO,"************ PASSWORD WILL BE PERSISTED ****************\n");
}
HWND hwnd = NULL;
int iEditId = 0;
UI_CONTROL uiControl;
uiControl.szUserName = szUsername;
uiControl.szPassword = szPassword;
uiControl.fPersist = fPersist;
uiControl.dwCount = 0;
uiControl.hOK = NULL;
uiControl.hPassword = NULL;
uiControl.hPasswordSave = NULL;
uiControl.hUserName = NULL;
Sleep(3000);
#if 1
uiControl.hOK = GetDlgItem(hdlg,IDB_OK_BUTTON);
uiControl.hPassword = GetDlgItem(hdlg,IDC_PASSWORD_FIELD);
uiControl.hPasswordSave = GetDlgItem(hdlg,IDC_SAVE_PASSWORD);
uiControl.hUserName = GetDlgItem(hdlg,IDC_COMBO1);
#else
EnumChildWindows(hdlg, EnumerateWindowCallback, (LPARAM)&uiControl);
#endif
dprintf(INFO,"EnumWindows Returned :\n");
dprintf(INFO,"hUsername %#x, hPassword %#x, hPasswordSave %#x, hOK %#x\n",
uiControl.hUserName,
uiControl.hPassword,
uiControl.hPasswordSave,
uiControl.hOK);
//getch();
if (uiControl.hPasswordSave != NULL) {
hdlg = uiControl.hPasswordSave;
printf("\n");
dprintf(INFO,"=============== Found SAVE_PASSWORD check box field\n");
if(!(uiControl.fPersist)) {
dprintf(INFO,"DONT WANNA PERSIST @@@@@ !\n");
} else {
//Sleep(2000);//not required remove later
if(!::PostMessage(hdlg, BM_CLICK, (WPARAM)0, (LPARAM)0)) {
ODS("FAILED: to send message to SAVE_PASSWORD check Box");
//DebugBreak();
} else {
ODS("sent message successfullly to SAVE_PASSWORD Edit Control\n");
}
// Sleep(2000);
}
++ uiControl.dwCount;
}
//getch();
if (uiControl.hUserName != NULL) {
hdlg = uiControl.hUserName;
dprintf(INFO,"Sending Message To USERNAME field (%#x)\n",hdlg);
#if 0
SendMessage(
hdlg,
CB_SHOWDROPDOWN,
(WPARAM) TRUE,
(LPARAM) 0);
#endif
//Sleep(2000);//not required remove later
if(!::SendMessage(hdlg, WM_SETTEXT, (WPARAM) 0, (LPARAM)(LPCTSTR) szUsername)) {
ODS("FAILED: to send message to Edit Box\n");
//DebugBreak();
} else {
ODS("sent message successfullly to USERNAME Edit Control\n");
}
++ uiControl.dwCount;
}
//getch();
if (uiControl.hPassword != NULL) {
hdlg = uiControl.hPassword;
printf("\n");
dprintf(INFO,"Sending Message To PASSWORD field (%#X)\n",hdlg);
//Sleep(2000);//not required remove later
if(!::SendMessage(hdlg, WM_SETTEXT, 0, (LPARAM)(LPCTSTR) szPassword)) {
ODS("FAILED: to send message to Edit Box");
//DebugBreak();
} else {
ODS("sent message successfullly to PASSWORD Edit Control\n");
}
++ uiControl.dwCount;
}
dprintf(INFO,"Clicking on OK button (%#X) in dialog \n",uiControl.hOK );
Sleep(2000);
SendMessage(uiControl.hOK, BM_CLICK, 0, 0);
//PostMessage(hdlg,
// WM_COMMAND,
// MAKEWPARAM(IDB_OK_BUTTON,BN_CLICKED),
// MAKELPARAM(,0));
return TRUE;
}
LPVOID
WINAPI fnUiPrompt(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
DWORD dwError = ERROR_SUCCESS;
dprintf( ENTRY_EXIT, "Enter: fnUiPrompt %#x \n", lpvData );
dwError = TuringMachine(
UI_PROMPT_TRANSITION_TABLE,
STATE_INIT,
lpvData
);
dprintf( ENTRY_EXIT, "Exit: fnUiPrompt %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnUiPromptUser(
LPVOID lpvData)
{
//LPSTR szChallenge;
//szChallenge = "realm=\"[email protected]\", stale = FALSE, qop=\"auth,auth-int\", nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\", opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"";
TCHAR szChallenge[512];
DWORD cbChallenge=512;
GenerateServerChallenge(szChallenge,cbChallenge);
// Package will dump response into this buffer.
CHAR szResponse[4096];
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
dprintf( ENTRY_EXIT, "Enter: fnUiPromptUser %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &BUSY_CTX_REC );
CtxtHandle hCtxt = {0,0};
SECURITY_STATUS ssResult;
memset((LPVOID)szResponse,0,4096);
// First try at authenticating.
ssResult =
DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
NULL, // Ctxt not specified first time.
&hCtxt, // Output context.
0, // auth from cache.
szChallenge, // Server challenge header.
NULL, // no realm since not preauth.
"www.foo.com", // Host.
"/bar/baz/boz/bif.html", // Url.
"GET", // Method.
"[email protected]", // Username
NULL, // no Password.
NULL, // no nonce
NULL, // don't need hdlg for auth.
szResponse, // Response buffer.
4096);
// Expect to not have credentials the first time - prompt.
if (ssResult == SEC_E_NO_CREDENTIALS)
{
memset((LPVOID)szResponse,0,4096);
ssResult =
DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
&hCtxt, // Ctxt from previous call
&hCtxt, // Output context (same as from previous).
ISC_REQ_PROMPT_FOR_CREDS, // prompt
szChallenge, // Server challenge
NULL, // No realm
"www.foo.com", // Host
"/bar/baz/boz/bif.html", // Url
"GET", // Method
NULL, // no username
NULL, // no password
NULL, // no nonce
GetDesktopWindow(), // desktop window
szResponse, // Response buffer.
4096);
}
// We now have credentials and this will generate the output string.
//
// BUGBUG:
// THis has just been fixed by AdriaanC, so we put in a hack here
// We will only prompt if the string has not been generated yet.
//
if (
(ssResult == SEC_E_OK)
&& (!*szResponse)
) {
memset((LPVOID)szResponse,0,4096);
ssResult =
DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
&hCtxt, // Ctxt not specified first time.
&hCtxt, // Output context.
0, // auth
szChallenge, // Server challenge.
NULL, // no realm
"www.foo.com", // Host.
"/bar/baz/boz/bif.html", // Url.
"GET", // Method.
NULL, // no username
NULL, // no password
NULL, // no nonce
NULL, // no hdlg
szResponse, // Response buffer.
4096);
}
return lpvData;
}
LPVOID
WINAPI fnUiPromptAny(
LPVOID lpvData)
{
//LPSTR szChallenge;
//szChallenge = "realm=\"[email protected]\", stale = FALSE, qop=\"auth,auth-int\", nonce=\"dcd98b7102dd2f0e8b11d0f600bfb0c093\", opaque=\"5ccc069c403ebaf9f0171e9517f40e41\"";
TCHAR szChallenge[512];
DWORD cbChallenge=512;
GenerateServerChallenge(szChallenge,cbChallenge);
// Package will dump response into this buffer.
CHAR szResponse[4096];
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
dprintf( ENTRY_EXIT, "Enter: fnUiPromptAny %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &BUSY_CTX_REC );
CtxtHandle hCtxt = {0,0};
SECURITY_STATUS ssResult;
memset((LPVOID)szResponse,0,4096);
// First try at authenticating.
ssResult =
DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
NULL, // Ctxt not specified first time.
&hCtxt, // Output context.
0, // auth from cache.
szChallenge, // Server challenge header.
NULL, // no realm since not preauth.
"www.foo.com", // Host.
"/bar/baz/boz/bif.html", // Url.
"GET", // Method.
NULL, // no Username
NULL, // no Password.
NULL, // no nonce
NULL, // don't need hdlg for auth.
szResponse, // Response buffer.
4096);
// Expect to not have credentials the first time - prompt.
if (ssResult == SEC_E_NO_CREDENTIALS)
{
memset((LPVOID)szResponse,0,4096);
ssResult =
DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
&hCtxt, // Ctxt from previous call
&hCtxt, // Output context (same as from previous).
ISC_REQ_PROMPT_FOR_CREDS, // prompt
szChallenge, // Server challenge
NULL, // No realm
"www.foo.com", // Host
"/bar/baz/boz/bif.html", // Url
"GET", // Method
NULL, // no username
NULL, // no password
NULL, // no nonce
GetDesktopWindow(), // desktop window
szResponse, // Response buffer.
4096);
}
// We now have credentials and this will generate the output string.
//
// BUGBUG:
// THis has just been fixed by AdriaanC, so we put in a hack here
// We will only prompt if the string has not been generated yet.
//
if (
(ssResult == SEC_E_OK)
&& (!*szResponse)
) {
memset((LPVOID)szResponse,0,4096);
ssResult =
DoAuthenticate( &lpCtxRecord -> hCred, // Cred from logging on.
&hCtxt, // Ctxt not specified first time.
&hCtxt, // Output context.
0, // auth
szChallenge, // Server challenge.
NULL, // no realm
"www.foo.com", // Host.
"/bar/baz/boz/bif.html", // Url.
"GET", // Method.
NULL, // no username
NULL, // no password
NULL, // no nonce
NULL, // no hdlg
szResponse, // Response buffer.
4096);
}
return lpvData;
}
LPVOID
WINAPI fnFlushCredentials(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
DWORD dwError = ERROR_SUCCESS;
dprintf( ENTRY_EXIT, "Enter: fnFlushCredentials %#x \n", lpvData );
dwError = TuringMachine(
FLUSH_CREDENTIALS_TRANSITION_TABLE,
STATE_INIT,
lpvData
);
dprintf( ENTRY_EXIT, "Exit: fnFlushCredentials %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnFlushCredentialsGlobal(
LPVOID lpvData)
{
dprintf( ENTRY_EXIT, "Enter: fnFlushCredentialsGlobal %#x \n", lpvData );
SECURITY_STATUS ssResult;
ssResult =
DoAuthenticate( NULL, // Cred from logging on.
NULL, // Ctxt not specified first time.
NULL, // Output context.
ISC_REQ_NULL_SESSION, // auth from cache.
NULL,//szChallenge, // Server challenge header.
NULL, // no realm since not preauth.
NULL,//"www.foo.com", // Host.
NULL,//"/bar/baz/boz/bif.html", // Url.
NULL,//"GET", // Method.
NULL,//"user1", // no Username
NULL, // no Password.
NULL, // no nonce
NULL, // don't need hdlg for auth.
NULL, // Response buffer.
0);
dprintf( ENTRY_EXIT, "Exit: fnFlushCredentialsGlobal %#x \n", lpvData );
return lpvData;
}
LPVOID
WINAPI fnFlushCredentialsSession(
LPVOID lpvData)
{
LPCONTEXT_DATA lpContext = (LPCONTEXT_DATA) lpvData;
LPCONTEXT_RECORD lpCtxRecord = NULL;
dprintf( ENTRY_EXIT, "Enter: fnFlushCredentialsSession %#x \n", lpvData );
lpCtxRecord = FindFreeSlot( lpContext -> hCredentialHandles, &BUSY_CTX_REC );
SECURITY_STATUS ssResult;
ssResult =
DoAuthenticate( &lpCtxRecord->hCred, // Cred from logging on.
NULL, // Ctxt not specified first time.
NULL,//&hCtxt, // Output context.
ISC_REQ_NULL_SESSION, // auth from cache.
NULL,//szChallenge, // Server challenge header.
NULL, // no realm since not preauth.
NULL,//"www.foo.com", // Host.
NULL,//"/bar/baz/boz/bif.html", // Url.
NULL,//"GET", // Method.
NULL,//"user1", // no Username
NULL, // no Password.
NULL, // no nonce
NULL, // don't need hdlg for auth.
NULL,
0);//szResponse); // Response buffer.
return lpvData;
}
BOOL
GenerateServerChallenge(
LPSTR szChallenge,
DWORD cbChallenge)
{
int i;
TCHAR * szAlgorithm = NULL,
* szQop = NULL,
* szNonce = NULL,
* szOpaque = NULL,
* szRealm = NULL,
* szPtr = NULL,
* szMs_message = NULL,
* szMs_reserved = NULL,
* szMs_trustmark = NULL;
//
// BUGBUG: we want to make sure that this generates a string which will fit
// in the given buffer.
//
dprintf(ENTRY_EXIT,"ENTER: GenerateServerChallenge\n" );
i = rand() % 100;
if( i < 50 ) {
szAlgorithm = _T("MD5");
} else {
szAlgorithm = _T("MD5-Sess");
}
i = rand() % 100;
if((i >= 0) && ( i < 20 )) {
szRealm = _T("[email protected]");
} else
if(( i >= 20 ) && ( i < 40)) {
szRealm = _T("[email protected]");
} else
if(( i >= 40 ) && ( i < 60)) {
szRealm = _T("[email protected]");
} else {
szRealm = _T("[email protected]");
}
#if 0
i = rand() % 100;
if( i < 50 ) {
szMs_message = _T("\"This is a test microsoft message\"");
} else {
szMs_message = NULL;
}
i = rand() % 100;
if( i < 30 ) {
szMs_trustmark = _T("\"http://www.bbbonline.org\"");
} else
if(( i >= 30 ) && (i < 80)) {
szMs_trustmark = _T("\"http://www.truste.org\"");
} else {
szMs_trustmark = NULL;
}
i = rand() % 100;
if( i < 30 ) {
szMs_reserved = _T("\"MSEXT::CAPTION=%Enter Network Password%REGISTER=%http://www.microsoft.com%\"");
}
//else
//if(( i >= 30 ) && (i < 80)) {
//szMs_trustmark = _T("\"http://www.truste.org\"");
//} else {
//szMs_trustmark = NULL;
//}
#endif
szQop = _T("auth");
szOpaque = _T("101010101010");
szNonce = _T("abcdef0123456789");
szPtr = szChallenge;
szPtr += sprintf(szChallenge,"realm=\"%s\", qop=\"%s\", algorithm=\"%s\", nonce=\"%s\", opaque=\"%s\"",
szRealm,
szQop,
szAlgorithm,
szNonce,
szOpaque);
#if 0
if( szMs_message && *szMs_message ) {
szPtr += sprintf(szPtr,", ms-message=%s, ms-message-lang=\"EN\"",
szMs_message);
}
if( szMs_trustmark && *szMs_trustmark ) {
szPtr += sprintf(szPtr,", ms-trustmark=%s",
szMs_trustmark);
}
if( szMs_reserved && *szMs_reserved ) {
szPtr += sprintf(szPtr,", ms-reserved=%s",
szMs_reserved);
}
i = rand() % 100;
if( i < 50 ) {
szPtr += sprintf( szPtr,", MS-Logoff=\"TRUE\"");
}
#endif
dprintf(ENTRY_EXIT,"EXIT: GenerateServerChallenge returns \n%s\n", szChallenge );
return TRUE;
}
#define IDENTITY_1 "app1"
#define IDENTITY_2 "app2"
BOOL Test()
{
CSessionAttributeList * g_pSessionAttributeList = NULL;
CSessionList * g_pSessionList = NULL;
CSession * pSession = NULL;
CSessionAttribute * pSessionAttribute = NULL;
CredHandle hCred1, hCred2, hCred3;
SECURITY_STATUS ssResult;
g_pSessionAttributeList = new CSessionAttributeList();
g_pSessionList = new CSessionList();
pSessionAttribute = g_pSessionAttributeList -> getNewSession( FALSE );
if( !pSessionAttribute ) {
goto cleanup;
}
LogonToDigestPkg(
pSessionAttribute ->getAppCtx() ,
pSessionAttribute->getUserCtx(),
&hCred1);
pSession = new CSession( hCred1 );
pSession -> setAttribute( pSessionAttribute );
g_pSessionList->put( pSession );
pSession = NULL;
pSessionAttribute = NULL;
//
// now get shared SessionAttribute
//
pSessionAttribute = g_pSessionAttributeList -> getNewSession( TRUE );
LogonToDigestPkg(
pSessionAttribute ->getAppCtx() ,
pSessionAttribute->getUserCtx(),
&hCred2);
pSession = new CSession( hCred2 );
pSession -> setAttribute( pSessionAttribute );
g_pSessionList -> put( pSession);
LogonToDigestPkg(
pSessionAttribute ->getAppCtx() ,
pSessionAttribute->getUserCtx(),
&hCred3);
pSession = new CSession( hCred3 );
pSession -> setAttribute( pSessionAttribute );
g_pSessionList -> put( pSession);
//
// lets add a credential to this session
//
pSession -> addCredential( "[email protected]", "user1", "pass1" );
pSession -> addCredential( "[email protected]", "user1", "pass11" );
// add one more
pSession -> addCredential( "[email protected]", "user2", "pass2" );
// add one more
pSession -> addCredential( "[email protected]", "user3", "pass3" );
// replace
pSession -> addCredential( "[email protected]", "user3", "pass31" );
// replace
pSession -> addCredential( "[email protected]", "user2", "pass21" );
pSession -> addCredential( "[email protected]", "user2", "pass22" );
cleanup:
return FALSE;
}
BOOL CALLBACK EnumerateWindowCallback1(HWND hdlg, LPARAM lParam)
{
int iEditId = 0;
BOOL fRet = TRUE;
LPUI_CONTROL lpuiControl = (LPUI_CONTROL) lParam;
LPTSTR szUsername = lpuiControl->szUserName;
LPTSTR szPassword = lpuiControl->szPassword;
dprintf(ENTRY_EXIT,"ENTER: EnumChildProc(hdlg=%#x,lParam=%#x)\n",hdlg,lParam);
dprintf(ENTRY_EXIT,"UI_CONTROL( %s %s %d %s %#x ) \n",
szUsername,
szPassword,
lpuiControl->dwCount,
(lpuiControl->fPersist?"TRUE":"FALSE"),
lpuiControl->hOK);
iEditId =::GetDlgCtrlID(hdlg);
dprintf(INFO,"The iEditId is %d!\n", iEditId);
if (iEditId == IDC_SAVE_PASSWORD) {
printf("\n");
dprintf(INFO,"=============== Found SAVE_PASSWORD check box field\n");
if(lpuiControl->dwCount == 3) {
dprintf(INFO,"Already sent message to this control\n");
goto done;;
}
if(!(lpuiControl -> fPersist)) {
dprintf(INFO,"DONT WANNA PERSIST @@@@@ !\n");
} else {
//Sleep(2000);//not required remove later
if(!::PostMessage(hdlg, BM_CLICK, (WPARAM)0, (LPARAM)0)) {
ODS("FAILED: to send message to SAVE_PASSWORD check Box");
DebugBreak();
} else {
ODS("sent message successfullly to SAVE_PASSWORD Edit Control\n");
}
// Sleep(2000);
}
++ lpuiControl->dwCount;
} else
if (iEditId == IDC_COMBO1) {
printf("\n");
dprintf(INFO,"Found USERNAME field\n");
if(lpuiControl->dwCount == 3) {
dprintf(INFO,"Already sent message to this control\n");
goto done;;
}
#if 0
SendMessage(
hdlg,
CB_SHOWDROPDOWN,
(WPARAM) TRUE,
(LPARAM) 0);
#endif
//Sleep(2000);//not required remove later
if(!::SendMessage(hdlg, WM_SETTEXT, (WPARAM) 0, (LPARAM)(LPCTSTR) szUsername)) {
ODS("FAILED: to send message to Edit Box\n");
DebugBreak();
} else {
ODS("sent message successfullly to USERNAME Edit Control\n");
}
++ lpuiControl->dwCount;
} else
if (iEditId == IDC_PASSWORD_FIELD) {
printf("\n");
dprintf(INFO,"Found PASSWORD field\n");
//Sleep(2000);//not required remove later
if(lpuiControl->dwCount == 3) {
dprintf(INFO,"Already sent message to this control\n");
goto done;;
}
if(!::SendMessage(hdlg, WM_SETTEXT, 0, (LPARAM)(LPCTSTR) szPassword)) {
ODS("FAILED: to send message to Edit Box");
DebugBreak();
} else {
ODS("sent message successfullly to PASSWORD Edit Control\n");
}
++ lpuiControl->dwCount;
} else
if( iEditId == IDB_OK_BUTTON ) {
lpuiControl->hOK = hdlg;
}
if( lpuiControl -> dwCount == 3 ) {
if( lpuiControl->hOK ) {
dprintf(INFO,"ALL WINDOWS FOUND, OK BUTTON FOUND, ABORT\n");
fRet = FALSE;
goto done;;
}
}
done:
dprintf(ENTRY_EXIT,"EXIT: EnumChileProc() returning %s\n",fRet?"TRUE":"FALSE");
return fRet;
}
BOOL CALLBACK EnumerateWindowCallback(HWND hdlg, LPARAM lParam)
{
int iEditId = 0;
BOOL fRet = TRUE;
LPUI_CONTROL lpuiControl = (LPUI_CONTROL) lParam;
dprintf(ENTRY_EXIT,"ENTER: EnumChildProc(hdlg=%#x,lParam=%#x)\n",hdlg,lParam);
dprintf(ENTRY_EXIT,"UI_CONTROL( %s %s %d %s %#x ) \n",
lpuiControl->szUserName,
lpuiControl->szPassword,
lpuiControl->dwCount,
(lpuiControl->fPersist?"TRUE":"FALSE"),
lpuiControl->hOK);
if ( (iEditId =::GetDlgCtrlID(hdlg)) == 0)
{
dprintf(INFO,"GetDlgCtrlID(hdlg) failed. GetLastError returned %d!\n", GetLastError());
return FALSE;
}
dprintf(INFO,"The iEditId is %d!\n", iEditId);
if (iEditId == IDC_SAVE_PASSWORD) {
printf("\n");
dprintf(INFO,"=============== Found SAVE_PASSWORD check box field\n");
if(lpuiControl->hPasswordSave != NULL) {
dprintf(INFO,"Already found window to this control\n");
goto done;;
}
lpuiControl->hPasswordSave = hdlg;
++ lpuiControl->dwCount;
} else
if (iEditId == IDC_COMBO1) {
printf("\n");
dprintf(INFO,"Found USERNAME field\n");
if(lpuiControl->hUserName != NULL) {
dprintf(INFO,"Already found window to this control\n");
goto done;;
}
lpuiControl->hUserName = hdlg;
++ lpuiControl->dwCount;
} else
if (iEditId == IDC_PASSWORD_FIELD) {
printf("\n");
dprintf(INFO,"Found PASSWORD field\n");
//Sleep(2000);//not required remove later
if(lpuiControl->hPassword != NULL) {
dprintf(INFO,"Already found window to this control\n");
goto done;;
}
lpuiControl->hPassword = hdlg;
++ lpuiControl->dwCount;
} else
if( iEditId == IDB_OK_BUTTON ) {
lpuiControl->hOK = hdlg;
++ lpuiControl->dwCount;
}
if( lpuiControl -> dwCount == 4 ) {
//if( lpuiControl->hOK ) {
dprintf(INFO,"ALL WINDOWS FOUND, OK BUTTON FOUND, ABORT\n");
fRet = FALSE;
goto done;
//}
}
done:
dprintf(ENTRY_EXIT,"EXIT: EnumChileProc() returning %s\n",fRet?"TRUE":"FALSE");
return fRet;
}