From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/se/ctlnpqos.c | 1729 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1729 insertions(+) create mode 100644 private/ntos/se/ctlnpqos.c (limited to 'private/ntos/se/ctlnpqos.c') diff --git a/private/ntos/se/ctlnpqos.c b/private/ntos/se/ctlnpqos.c new file mode 100644 index 000000000..ffaf1520d --- /dev/null +++ b/private/ntos/se/ctlnpqos.c @@ -0,0 +1,1729 @@ + +////////////////////////////////////////////////////////////////////////////// +// // +// Global Definitions // +// // +////////////////////////////////////////////////////////////////////////////// + +#define DevPrint +//#define DevPrint DbgPrint + +#define Error(N,S) { DbgPrint(#N); DbgPrint(" Error %08lx\n", S); } + +#define Delay(SECONDS) { \ + LARGE_INTEGER Time; \ + Time.QuadPart = -10 * 1000 * 1000, ((LONGLONG)SECONDS); \ + NtDelayExecution(TRUE,(PLARGE_INTEGER)&Time); \ +} + + +////////////////////////////////////////////////////////////////////////////// +// // +// Global Variables // +// // +////////////////////////////////////////////////////////////////////////////// + + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + STRING EventName; + UNICODE_STRING UnicodeEventName; + HANDLE EventHandle; + STRING PortName; + UNICODE_STRING UnicodePortName; + STRING RelativePortName; + UNICODE_STRING UnicodeRelativePortName; + HANDLE EarPort; + HANDLE TalkPort; + SECURITY_QUALITY_OF_SERVICE SecurityQos; + ULONG RequestCount; + HANDLE ClientToken; + TOKEN_STATISTICS ClientTokenStatistics; + ULONG IgnoreLength; + + HANDLE SepServerThread; + + + + +////////////////////////////////////////////////////////////////////////////// +// // +// Test Routine Definitions // +// // +////////////////////////////////////////////////////////////////////////////// +BOOLEAN +SepClientTestStatic(VOID); + +BOOLEAN +SepClientTestDynamic(VOID); + +BOOLEAN +SepClientTestEffectiveOnly( + BOOLEAN StaticTest + ); + +BOOLEAN +SepClientTestNotEffectiveOnly( + BOOLEAN StaticTest + ); + +BOOLEAN +SepClientTestAnonymous( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ); + +BOOLEAN +SepClientTestIdentification( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ); + +BOOLEAN +SepClientTestImpersonation( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ); + +VOID +SepClientConnect( + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + SECURITY_CONTEXT_TRACKING_MODE TrackingMode, + BOOLEAN EffectiveOnly + ); + +VOID +SepClientMakeRemoteCall( VOID ); + +VOID +SepClientDropConnection( VOID ); + +BOOLEAN +SepClientTest(VOID); + +NTSTATUS +SepClientInitialize( + ); + + + + + + +BOOLEAN +SepServerTestStatic(VOID); + +BOOLEAN +SepServerTestDynamic(VOID); + +BOOLEAN +SepServerTestEffectiveOnly( + BOOLEAN StaticTest + ); + +BOOLEAN +SepServerTestNotEffectiveOnly( + BOOLEAN StaticTest + ); + +BOOLEAN +SepServerTestAnonymous( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ); + +BOOLEAN +SepServerTestIdentification( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ); + +BOOLEAN +SepServerTestImpersonation( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ); + +VOID +SepServerWaitForNextConnect( VOID ); + +VOID +SepServerGetNextMessage( VOID ); + +VOID +SepServerCompleteMessage( VOID ); + +VOID +SepServerDropConnection( VOID ); + + + +BOOLEAN +SepServerTest(VOID); + +NTSTATUS +SepServerInitialize( + ); + +VOID +SepServerSpawnClientProcess(VOID); + + + + +VOID +SepWritePipe( PSZ String ); + +VOID +SepReadPipe(VOID); + +VOID +SepTransceivePipe( PSZ String ); + + + + +HANDLE +SepServerCreatePipe(VOID); + +VOID +SepServerListenPipe(VOID); + +VOID +SepServerImpersonatePipe(VOID); + +VOID +SepServerDisconnectPipe(VOID); + + + + +HANDLE +SepClientOpenPipe( VOID ); + + + + +BOOLEAN +CtLnpQos (VOID); + + +////////////////////////////////////////////////////////////////////////////// +// // +// Client-Side Test Routines // +// // +////////////////////////////////////////////////////////////////////////////// + + +VOID +SepClientConnect( + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + SECURITY_CONTEXT_TRACKING_MODE TrackingMode, + BOOLEAN EffectiveOnly + ) + +{ + + SecurityQos.ImpersonationLevel = ImpersonationLevel; + SecurityQos.ContextTrackingMode = TrackingMode; + SecurityQos.EffectiveOnly = EffectiveOnly; + + DevPrint("\nClient: "); + TalkPort = SepClientOpenPipe(); + + return; +} + + +VOID +SepClientMakeRemoteCall( VOID ) + +{ + + DevPrint("\nClient: "); + SepTransceivePipe( "Make Client Call\n" ); + + RequestCount += 1; + + return; +} + + +VOID +SepClientDropConnection( VOID ) + +{ + + Status = NtClose( TalkPort ); SEASSERT_SUCCESS(Status); + + return; + +} + + +BOOLEAN +SepClientTestStatic(VOID) + +{ + + BOOLEAN CompletionStatus; + + // + // Static Context Tracking ... Suite + // + + CompletionStatus = SepClientTestEffectiveOnly( TRUE ); + + + if (CompletionStatus == TRUE) { + + CompletionStatus = SepClientTestNotEffectiveOnly( TRUE ); + } + + return CompletionStatus; + +} + + +BOOLEAN +SepClientTestDynamic(VOID) + +{ + BOOLEAN CompletionStatus; + + // + // Dynamic Context Tracking ... Suite + // + + CompletionStatus = SepClientTestEffectiveOnly( FALSE ); + + + if (CompletionStatus == TRUE) { + + CompletionStatus = SepClientTestNotEffectiveOnly( FALSE ); + } + + return CompletionStatus; + +} + + +BOOLEAN +SepClientTestEffectiveOnly( + BOOLEAN StaticTest + ) + + +{ + + BOOLEAN CompletionStatus; + + // + // Effective Only ... Test + // + + CompletionStatus = SepClientTestAnonymous( StaticTest, TRUE ); + if (CompletionStatus == TRUE) { + CompletionStatus = SepClientTestIdentification( StaticTest, TRUE ); + } + if (CompletionStatus == TRUE) { + CompletionStatus = SepClientTestImpersonation( StaticTest, TRUE ); + } + + return CompletionStatus; + +} + + +BOOLEAN +SepClientTestNotEffectiveOnly( + BOOLEAN StaticTest + ) + +{ + BOOLEAN CompletionStatus; + + // + // Not Effective Only ... Test + // + + CompletionStatus = SepClientTestAnonymous( StaticTest, FALSE ); + if (CompletionStatus == TRUE) { + CompletionStatus = SepClientTestIdentification( StaticTest, FALSE ); + } + if (CompletionStatus == TRUE) { + CompletionStatus = SepClientTestImpersonation( StaticTest, FALSE ); + } + + return CompletionStatus; + +} + + +BOOLEAN +SepClientTestAnonymous( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ) + +{ + + ////////////////////////////////////////////////////////////////////////// + // // + // Anonymous Use Test // + // // + ////////////////////////////////////////////////////////////////////////// + + SECURITY_CONTEXT_TRACKING_MODE TrackingMode; + + if (StaticTest) { + TrackingMode = SECURITY_STATIC_TRACKING; + } else { + TrackingMode = SECURITY_DYNAMIC_TRACKING; + } + + if (!StaticTest) { + // + // No action for dynamic test + // + return TRUE; + } + + // + // Anonymous Use ... Test + // + + + SepClientConnect( + SecurityAnonymous, + TrackingMode, + EffectiveOnly + ); + + SepClientMakeRemoteCall(); + + SepClientDropConnection(); + + + return TRUE; +} + + +BOOLEAN +SepClientTestIdentification( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ) + +{ + + ////////////////////////////////////////////////////////////////////////// + // // + // Identification Use Test // + // // + ////////////////////////////////////////////////////////////////////////// + + SECURITY_CONTEXT_TRACKING_MODE TrackingMode; + + if (StaticTest) { + TrackingMode = SECURITY_STATIC_TRACKING; + } else { + TrackingMode = SECURITY_DYNAMIC_TRACKING; + } + + // + // Identification Use ... Test + // + + + SepClientConnect( + SecurityIdentification, + TrackingMode, + EffectiveOnly + ); + + SepClientMakeRemoteCall(); + + SepClientDropConnection(); + + + return TRUE; + +} + + +BOOLEAN +SepClientTestImpersonation( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ) + +{ + + ////////////////////////////////////////////////////////////////////////// + // // + // Impersonation Use Test // + // // + ////////////////////////////////////////////////////////////////////////// + + SECURITY_CONTEXT_TRACKING_MODE TrackingMode; + + if (StaticTest) { + TrackingMode = SECURITY_STATIC_TRACKING; + } else { + TrackingMode = SECURITY_DYNAMIC_TRACKING; + } + + + // + // Impersonation Use ... Test + // + + + SepClientConnect( + SecurityImpersonation, + TrackingMode, + EffectiveOnly + ); + + SepClientMakeRemoteCall(); + + SepClientDropConnection(); + + + + return TRUE; + +} + + + + +BOOLEAN +SepClientTest(VOID) +// +// Tests: +// +// Static Context Tracking Tests +// Effective Only +// Anonymous +// Identification +// Impersonation +// Not Effective Only +// Anonymous +// Identification +// Impersonation +// +// Dynamic Context Tracking Tests +// Effective Only +// Identification +// Impersonation +// Not Effective Only +// Identification +// Impersonation +// +{ + + BOOLEAN CompletionStatus; + + + + + // + // Run the static test suite... + // + + CompletionStatus = SepClientTestStatic(); + + // + // Run the dynamic test suite... + // + + if (CompletionStatus == TRUE) { + CompletionStatus = SepClientTestDynamic(); + } + + DbgPrint("Se: Client Test Complete.\n"); + + + return CompletionStatus; +} + + +NTSTATUS +SepClientInitialize( + ) + +{ + + + + DbgPrint("Se: Client Initializing ...\n"); + + + RequestCount = 0; + + + // + // Signal the named event to start the test + // + + DbgPrint("Se: Client Starting Test ...\n"); + Status = NtSetEvent( EventHandle, NULL ); SEASSERT_SUCCESS(Status); + + Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status); + + + return STATUS_SUCCESS; +} + + +////////////////////////////////////////////////////////////////////////////// +// // +// Server-Side Test Routines // +// // +////////////////////////////////////////////////////////////////////////////// + + +VOID +SepServerWaitForNextConnect( VOID ) +{ + + DevPrint("\nServer: "); + SepServerListenPipe(); + + Status = NtDuplicateObject( + NtCurrentProcess(), // SourceProcessHandle + EarPort, // SourceHandle + NtCurrentProcess(), // TargetProcessHandle + &TalkPort, // TargetHandle + 0, // DesiredAccess (over-ridden by option) + 0, // HandleAttributes + DUPLICATE_SAME_ACCESS // Options + ); + ASSERT(NT_SUCCESS(Status)); + + + return; + +} + +VOID +SepServerGetNextMessage( VOID ) + +{ + + + + DevPrint("\nServer: "); + SepReadPipe(); + + RequestCount += 1; + + return; +} + +VOID +SepServerCompleteMessage( VOID ) + +{ + + DevPrint("\nServer: "); + SepWritePipe("Return From Server\n"); + return; +} + +VOID +SepServerImpersonateClient( VOID ) + +{ + + DevPrint("\nServer: "); + SepServerImpersonatePipe( ); + +} + + +VOID +SepServerRevertToSelf( VOID ) + +{ + NTSTATUS TmpStatus; + HANDLE NullHandle; + + NullHandle = NULL; + TmpStatus = NtSetInformationThread( + SepServerThread, + ThreadImpersonationToken, + (PVOID)&NullHandle, + (ULONG)sizeof(HANDLE) + ); SEASSERT_SUCCESS(TmpStatus); + +} + + +VOID +SepServerDropConnection( VOID ) + +{ + DevPrint("\nServer: "); + SepServerDisconnectPipe(); + + return; +} + +BOOLEAN +SepServerTestStatic(VOID) + +{ + BOOLEAN CompletionStatus; + + DbgPrint("Se: Static Context Tracking ... Suite\n"); + + CompletionStatus = SepServerTestEffectiveOnly( TRUE ); + + + if (CompletionStatus == TRUE) { + + CompletionStatus = SepServerTestNotEffectiveOnly( TRUE ); + } + + return CompletionStatus; + +} + + +BOOLEAN +SepServerTestDynamic(VOID) + +{ + BOOLEAN CompletionStatus; + + DbgPrint("Se: Dynamic Context Tracking ... Suite\n"); + + CompletionStatus = SepServerTestEffectiveOnly( FALSE ); + + + if (CompletionStatus == TRUE) { + + CompletionStatus = SepServerTestNotEffectiveOnly( FALSE ); + } + + return CompletionStatus; + +} + + +BOOLEAN +SepServerTestEffectiveOnly( + BOOLEAN StaticTest + ) + +{ + + BOOLEAN CompletionStatus; + + DbgPrint("Se: Effective Only ... Test\n"); + + CompletionStatus = SepServerTestAnonymous( StaticTest, TRUE ); + if (CompletionStatus == TRUE) { + CompletionStatus = SepServerTestIdentification( StaticTest, TRUE ); + } + if (CompletionStatus == TRUE) { + CompletionStatus = SepServerTestImpersonation( StaticTest, TRUE ); + } + + return CompletionStatus; + +} + + +BOOLEAN +SepServerTestNotEffectiveOnly( + BOOLEAN StaticTest + ) + +{ + + BOOLEAN CompletionStatus; + + DbgPrint("Se: Not Effective Only ... Test\n"); + + CompletionStatus = SepServerTestAnonymous( StaticTest, FALSE ); + if (CompletionStatus == TRUE) { + CompletionStatus = SepServerTestIdentification( StaticTest, FALSE ); + } + if (CompletionStatus == TRUE) { + CompletionStatus = SepServerTestImpersonation( StaticTest, FALSE ); + } + + return CompletionStatus; + +} + + +BOOLEAN +SepServerTestAnonymous( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ) + +{ + BOOLEAN CompletionStatus = TRUE; + + ////////////////////////////////////////////////////////////////////////// + // // + // Anonymous Use Test // + // // + ////////////////////////////////////////////////////////////////////////// + + + if (!StaticTest) { + // + // No action for dynamic test + // + + return TRUE; + } + + DbgPrint("Se: Anonymous Use ... "); + + SepServerWaitForNextConnect(); + + SepServerGetNextMessage(); + + + SepServerImpersonateClient(); + Status = NtOpenThreadToken( + SepServerThread, + TOKEN_ALL_ACCESS, + TRUE, + &ClientToken + ); + SepServerRevertToSelf(); + if (Status == STATUS_CANT_OPEN_ANONYMOUS) { + + DbgPrint(" Succeeded\n"); + + } else { + DbgPrint("* ! FAILED (srvr) ! *\n"); + DbgPrint("Status is: 0x%lx \n", Status ); + CompletionStatus = FALSE; + } + + + SepServerCompleteMessage(); + + SepServerDropConnection(); + + // + // Appease the compiler Gods.. + // + + if (EffectiveOnly) {;} + + + return CompletionStatus; + +} + + +BOOLEAN +SepServerTestIdentification( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ) + +{ + + BOOLEAN CompletionStatus = TRUE; + ////////////////////////////////////////////////////////////////////////// + // // + // Identification Use Test // + // // + ////////////////////////////////////////////////////////////////////////// + + DbgPrint("Se: Identification Use ... "); + + SepServerWaitForNextConnect(); + + SepServerGetNextMessage(); + + SepServerImpersonateClient(); + Status = NtOpenThreadToken( + SepServerThread, + TOKEN_ALL_ACCESS, + TRUE, + &ClientToken + ); SEASSERT_SUCCESS(Status); + SepServerRevertToSelf(); + Status = NtQueryInformationToken( + ClientToken, + TokenStatistics, + &ClientTokenStatistics, + (ULONG)sizeof(TOKEN_STATISTICS), + &IgnoreLength + ); SEASSERT_SUCCESS(Status); + + if ( (ClientTokenStatistics.TokenType == TokenImpersonation) && + (ClientTokenStatistics.ImpersonationLevel == SecurityIdentification) + ) { + DbgPrint(" Succeeded\n"); + + } else { + DbgPrint("* ! FAILED (srvr) ! *\n"); + CompletionStatus = FALSE; + } + + + SepServerCompleteMessage(); + + SepServerDropConnection(); + + // + // Appease the compiler Gods.. + // + if (StaticTest) {;} + if (EffectiveOnly) {;} + + return CompletionStatus; +} + + +BOOLEAN +SepServerTestImpersonation( + BOOLEAN StaticTest, + BOOLEAN EffectiveOnly + ) + +{ + BOOLEAN CompletionStatus = TRUE; + + ////////////////////////////////////////////////////////////////////////// + // // + // Impersonation Use Test // + // // + ////////////////////////////////////////////////////////////////////////// + + DbgPrint("Se: Impersonation Use ... "); + + + SepServerWaitForNextConnect(); + + SepServerGetNextMessage(); + + + + SepServerImpersonateClient(); + Status = NtOpenThreadToken( + SepServerThread, + TOKEN_ALL_ACCESS, + TRUE, + &ClientToken + ); SEASSERT_SUCCESS(Status); + SepServerRevertToSelf(); + Status = NtQueryInformationToken( + ClientToken, + TokenStatistics, + &ClientTokenStatistics, + (ULONG)sizeof(TOKEN_STATISTICS), + &IgnoreLength + ); SEASSERT_SUCCESS(Status); + + if ( (ClientTokenStatistics.TokenType == TokenImpersonation) && + (ClientTokenStatistics.ImpersonationLevel == SecurityImpersonation) + ) { + DbgPrint(" Succeeded\n"); + + } else { + DbgPrint("* ! FAILED (srvr) ! *\n"); + CompletionStatus = FALSE; + } + + + + + SepServerCompleteMessage(); + + SepServerDropConnection(); + + // + // Appease the compiler gods + // + if (StaticTest) {;} + if (EffectiveOnly) {;} + + return CompletionStatus; +} + + +BOOLEAN +SepServerTest(VOID) +// +// Tests: +// +// Static Context Tracking Tests +// Effective Only +// Anonymous +// Identification +// Impersonation +// Not Effective Only +// Anonymous +// Identification +// Impersonation +// +// Dynamic Context Tracking Tests +// Effective Only +// Identification +// Impersonation +// Not Effective Only +// Identification +// Impersonation +// +{ + + BOOLEAN CompletionStatus; + + + DbgPrint("Se: Server Starting Test ...\n"); + + // + // Run the static test suite... + // + + CompletionStatus = SepServerTestStatic(); + + // + // Run the dynamic test suite... + // + + if (CompletionStatus == TRUE) { + CompletionStatus = SepServerTestDynamic(); + } + + DbgPrint("Se: Server Test Complete.\n"); + + // + // Print test results + // + + DbgPrint("\n"); + DbgPrint("\n"); + DbgPrint("**********************\n"); + DbgPrint("** **\n"); + + if (CompletionStatus == TRUE) { + DbgPrint("** Test Succeeded **\n"); + } else { + DbgPrint("** Test Failed !! **\n"); + } + + DbgPrint("** **\n"); + DbgPrint("**********************\n"); + + return CompletionStatus; + +} + +NTSTATUS +SepServerInitialize( + ) + +{ + + OBJECT_ATTRIBUTES ThreadAttributes; + PTEB CurrentTeb; + + + DbgPrint("Se: Server Initializing ...\n"); + + // + // Initialize global variables + // + + RequestCount = 0; + + // + // Get a handle to our thread to so that we can access our thread + // even when impersonating an anonymous client (which we can't do + // using NtCurrentThread()). + // + + CurrentTeb = NtCurrentTeb(); + InitializeObjectAttributes(&ThreadAttributes, NULL, 0, NULL, NULL); + Status = NtOpenThread( + &SepServerThread, // TargetHandle + THREAD_ALL_ACCESS, // DesiredAccess + &ThreadAttributes, // ObjectAttributes + &CurrentTeb->ClientId // ClientId + ); + ASSERT( NT_SUCCESS(Status) ); + + + // + // Create the server's port + // + + EarPort = SepServerCreatePipe(); + + + + // + // Spawn a copy of ourselves... + // + + DbgPrint("Se: Server Spawning client process ...\n"); + SepServerSpawnClientProcess(); + + + DbgPrint("Se: Server waiting for start of test signal ...\n"); + + Status = NtWaitForSingleObject( + EventHandle, + TRUE, + NULL + ); SEASSERT_SUCCESS(Status); + + Status = NtClose( EventHandle ); SEASSERT_SUCCESS(Status); + + + return STATUS_SUCCESS; +} + +VOID +SepServerSpawnClientProcess(VOID) + +{ + + RTL_USER_PROCESS_INFORMATION ProcessInformation; + STRING ProgramName; + UNICODE_STRING UnicodeProgramName; + STRING ImagePathName; + UNICODE_STRING UnicodeImagePathName; + PRTL_USER_PROCESS_PARAMETERS ProcessParameters; + + RtlInitString( &ProgramName, "\\SystemRoot\\Bin\\utlnpqos.exe" ); + Status = RtlAnsiStringToUnicodeString( + &UnicodeProgramName, + &ProgramName, + TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); + RtlInitString( &ImagePathName, "utlnpqos.exe"); + Status = RtlAnsiStringToUnicodeString( + &UnicodeImagePathName, + &ImagePathName, + TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); + + + Status = RtlCreateProcessParameters( + &ProcessParameters, + &ImagePathName, // FIX, FIX &UnicodeImagePathName, (when converted to unicode) + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL + ); + + SEASSERT_SUCCESS(Status); + RtlFreeUnicodeString( &UnicodeImagePathName ); + + + Status = RtlCreateUserProcess( + &ProgramName, // FIX, FIX &UnicodeProgramName (when converted to unicode) + ProcessParameters, // ProcessParameters + NULL, // ProcessSecurityDescriptor + NULL, // ThreadSecurityDescriptor + NtCurrentProcess(), // ParentProcess + FALSE, // InheritHandles + NULL, // DebugPort + NULL, // ExceptionPort + &ProcessInformation // ProcessInformation + ); SEASSERT_SUCCESS(Status); + RtlFreeUnicodeString( &UnicodeProgramName ); + + Status = NtResumeThread( + ProcessInformation.Thread, + NULL + ); SEASSERT_SUCCESS(Status); + + RtlDestroyProcessParameters( ProcessParameters ); + +} + + + + +////////////////////////////////////////////////////////////////////////////// +// // +// Main Program Entry Routine // +// // +////////////////////////////////////////////////////////////////////////////// + +BOOLEAN +CtLnpQos (VOID) +{ + + BOOLEAN Result = TRUE; + + RtlInitString( &PortName, "\\Device\\NamedPipe\\TestLnpQosServerPort" ); + Status = RtlAnsiStringToUnicodeString( + &UnicodePortName, + &PortName, + TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); + + RtlInitString( &RelativePortName, "TestLnpQosServerPort" ); + Status = RtlAnsiStringToUnicodeString( + &UnicodeRelativePortName, + &RelativePortName, + TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); + + + // + // Determine whether we are the client or server side of the test. + // This is done by creating or opening a named event object. If the + // event does not yet exist, then we are the client, and must create + // the server process. Otherwise, we are the server and the client + // is waiting for us to signal the event. + // + + RtlInitString( &EventName, "\\TestLnpQosEvent" ); + Status = RtlAnsiStringToUnicodeString( + &UnicodeEventName, + &EventName, + TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); + + InitializeObjectAttributes( + &ObjectAttributes, + &UnicodeEventName, + OBJ_OPENIF, + NULL, + NULL + ); + Status = NtCreateEvent( + &EventHandle, + EVENT_ALL_ACCESS, + &ObjectAttributes, + SynchronizationEvent, + FALSE + ); + RtlFreeUnicodeString( &UnicodeEventName ); + + if (Status == STATUS_OBJECT_NAME_EXISTS) { + + // + // Server is already running, therefore, this process gets to be + // the client. + // + + Status = SepClientInitialize(); SEASSERT_SUCCESS(Status); + Result = SepClientTest(); + + } else { + + SEASSERT_SUCCESS(Status); + + // + // Event wasn't yet there, so we must be the server. + // + + DbgPrint("Se: Starting Local Named Pipe Impersonation Test.\n"); + + Status = SepServerInitialize(); SEASSERT_SUCCESS(Status); + Result = SepServerTest(); + + DbgPrint("Se: End Test.\n"); + + } + + + + Status = NtTerminateThread( NtCurrentThread(), STATUS_SUCCESS); + SEASSERT_SUCCESS(Status); + + return Result; + +} + + +////////////////////////////////////////////////////////////////////////////// +// // +// Named Pipe Common Operations // +// // +////////////////////////////////////////////////////////////////////////////// + + +VOID +SepReadPipe( + ) +{ + IO_STATUS_BLOCK Iosb; + UCHAR Buffer[512]; + + DevPrint("ReadPipe...\n", 0); + + if (!NT_SUCCESS(Status = NtReadFile( TalkPort, + (HANDLE)NULL, + (PIO_APC_ROUTINE)NULL, + (PVOID)NULL, + &Iosb, + Buffer, + 512, + (PLARGE_INTEGER)NULL, + (PULONG) NULL ))) { + Error( NtReadFile, Status ); + } + + if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) { + + Error( NtWaitForSingleObject, Status ); + } + + if (!NT_SUCCESS(Iosb.Status)) { + + Error( NtReadFileFinalStatus, Iosb.Status ); + } + + return; +} + + +VOID +SepWritePipe( + PSZ String + ) +{ + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + + + DevPrint("WritePipe...\n", 0); + + if (!NT_SUCCESS(Status = NtWriteFile( TalkPort, + (HANDLE)NULL, + (PIO_APC_ROUTINE)NULL, + (PVOID)NULL, + &Iosb, + String, + strlen( String ), + (PLARGE_INTEGER)NULL, + (PULONG)NULL ))) { + Error( NtWriteFile, Status ); + } + + if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) { + + Error( NtWaitForSingleObject, Status ); + } + + if (!NT_SUCCESS(Iosb.Status)) { + + Error( NtWriteFileFinalStatus, Iosb.Status ); + } + + return; +} + + +VOID +SepTransceivePipe( + PSZ String + ) +{ + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + UCHAR Buffer[512]; + + + DevPrint("TransceivePipe...\n", 0); + + if (!NT_SUCCESS(Status = NtFsControlFile( + TalkPort, + NULL, // Event + NULL, // ApcRoutine + NULL, // ApcContext + &Iosb, + FSCTL_PIPE_TRANSCEIVE, + String, + strlen( String ), + Buffer, + 511 + ))) { + Error( NtTransceiveFile, Status ); + } + + if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) { + + Error( NtWaitForSingleObject, Status ); + } + + if (!NT_SUCCESS(Iosb.Status)) { + + Error( NtTransceiveFileFinalStatus, Iosb.Status ); + } + + return; +} + + +////////////////////////////////////////////////////////////////////////////// +// // +// Named Pipe Server Operations // +// // +////////////////////////////////////////////////////////////////////////////// + +HANDLE +SepServerCreatePipe( + VOID + ) +{ + HANDLE PipeHandle; + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + LARGE_INTEGER Timeout; + READ_MODE Mode; + ULONG Share; + NAMED_PIPE_CONFIGURATION Config = FILE_PIPE_FULL_DUPLEX; + NAMED_PIPE_TYPE PipeType = FILE_PIPE_MESSAGE_TYPE; + COMPLETION_MODE CompletionMode = FILE_PIPE_QUEUE_OPERATION; + ULONG MaximumInstances = 4; + + + // + // Set the default timeout to 60 seconds, and initalize the attributes + // + + Timeout.QuadPart = -10 * 1000 * 1000 * 60; + + InitializeObjectAttributes( + &ObjectAttributes, + &UnicodePortName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + // + // Calculate the readmode and share access + // + + Mode = (PipeType == FILE_PIPE_MESSAGE_TYPE ? FILE_PIPE_MESSAGE_MODE : + FILE_PIPE_BYTE_STREAM_MODE); + + Share = (Config == FILE_PIPE_INBOUND ? FILE_SHARE_WRITE : + (Config == FILE_PIPE_OUTBOUND ? FILE_SHARE_READ : + FILE_SHARE_READ | FILE_SHARE_WRITE)); + + if (!NT_SUCCESS(Status = NtCreateNamedPipeFile( + &PipeHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + Share, + FILE_CREATE, + 0, + PipeType, + Mode, + CompletionMode, + MaximumInstances, + 1024, + 1024, + (PLARGE_INTEGER)&Timeout ))) { + + Error( CreatePipe, Status ); + } + RtlFreeUnicodeString( &UnicodePortName ); + + return PipeHandle; +} + + +VOID +SepServerListenPipe( + ) +{ + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + + DevPrint("ListenPipe...\n", 0); + + if (!NT_SUCCESS(Status = NtFsControlFile( + EarPort, + NULL, // Event + NULL, // ApcRoutine + NULL, // ApcContext + &Iosb, + FSCTL_PIPE_LISTEN, + NULL, // InputBuffer + 0, // InputBufferLength, + NULL, // OutputBuffer + 0 // OutputBufferLength + ))) { + + Error( ListenPipe, Status ); + } + if (!NT_SUCCESS(Status = NtWaitForSingleObject( EarPort, TRUE, NULL ))) { + + Error( NtWaitForSingleObject, Status ); + } + + if (!NT_SUCCESS(Iosb.Status)) { + + Error( ListenPipeFinalStatus, Iosb.Status ); + } + + + return; +} + + +VOID +SepServerImpersonatePipe( + ) +{ + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + + DevPrint("ImpersonatePipe...\n", 0); + + if (!NT_SUCCESS(Status = NtFsControlFile( + TalkPort, + NULL, // Event + NULL, // ApcRoutine + NULL, // ApcContext + &Iosb, + FSCTL_PIPE_IMPERSONATE, + NULL, // InputBuffer + 0, // InputBufferLength, + NULL, // OutputBuffer + 0 // OutputBufferLength + ))) { + + Error( ImpersonatePipe, Status ); + } + if (!NT_SUCCESS(Status = NtWaitForSingleObject( TalkPort, TRUE, NULL ))) { + + Error( NtWaitForSingleObject, Status ); + } + + if (!NT_SUCCESS(Iosb.Status)) { + + Error( ImpersonatePipeFinalStatus, Iosb.Status ); + } + + return; +} + + +VOID +SepServerDisconnectPipe( + ) +{ + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + + DevPrint("DisconnectPipe...\n", 0); + DevPrint(" (Flush)...\n", 0); + + if (!NT_SUCCESS(Status = NtFlushBuffersFile( + TalkPort, + &Iosb + ))) { + Error( DisconnectPipe, Status ); + } + + if (!NT_SUCCESS(Iosb.Status)) { + + Error( FlushPipeFinalStatus, Iosb.Status ); + } + + + DevPrint(" (Close Talk Port)...\n", 0); + Status = NtClose( TalkPort ); SEASSERT_SUCCESS(Status); + + DevPrint(" (Disconnect)...\n", 0); + if (!NT_SUCCESS(Status = NtFsControlFile( + EarPort, + NULL, // Event + NULL, // ApcRoutine + NULL, // ApcContext + &Iosb, + FSCTL_PIPE_DISCONNECT, + NULL, // InputBuffer + 0, // InputBufferLength, + NULL, // OutputBuffer + 0 // OutputBufferLength + ))) { + + Error( DisconnectPipe, Status ); + } + if (!NT_SUCCESS(Status = NtWaitForSingleObject( EarPort, TRUE, NULL ))) { + + Error( NtWaitForSingleObject, Status ); + } + + if (!NT_SUCCESS(Iosb.Status)) { + + Error( DisconnectPipeFinalStatus, Iosb.Status ); + } + + return; +} + + +////////////////////////////////////////////////////////////////////////////// +// // +// Named Pipe Client Operations // +// // +////////////////////////////////////////////////////////////////////////////// + +HANDLE +SepClientOpenPipe( + VOID + ) +{ + HANDLE PipeHandle, NpfsHandle; + NTSTATUS Status; + IO_STATUS_BLOCK Iosb; + ULONG Share; + STRING Npfs; + UNICODE_STRING UnicodeNpfs; + PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe; + ULONG WaitPipeLength; + NAMED_PIPE_CONFIGURATION Config = FILE_PIPE_FULL_DUPLEX; + READ_MODE ReadMode = FILE_PIPE_MESSAGE_MODE; + COMPLETION_MODE CompletionMode = FILE_PIPE_QUEUE_OPERATION; + + +//#ifdef NOT_YET_WORKING + // + // Wait for the server's pipe to reach a listen state... + // + + RtlInitString( &Npfs, "\\Device\\NamedPipe\\"); + Status = RtlAnsiStringToUnicodeString( + &UnicodeNpfs, + &Npfs, + TRUE ); SEASSERT_SUCCESS( NT_SUCCESS(Status) ); + + InitializeObjectAttributes( + &ObjectAttributes, + &UnicodeNpfs, + OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + if (!NT_SUCCESS(Status = NtOpenFile( + &NpfsHandle, + GENERIC_READ | SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + FILE_SHARE_READ, + 0 ))) { + + Error( OpenNpfs, Status ); + } + RtlFreeUnicodeString( &UnicodeNpfs ); + + WaitPipeLength = + FIELD_OFFSET(FILE_PIPE_WAIT_FOR_BUFFER, Name[0]) + + RelativePortName.MaximumLength; //UNICODEFIX UnicodeRelativePortName.MaximumLength; + WaitPipe = RtlAllocateHeap(RtlProcessHeap(), 0, WaitPipeLength); + WaitPipe->TimeoutSpecified = FALSE; + + WaitPipe->NameLength = RelativePortName.Length; //UNICODEFIX UnicodeRelativePortName.Length; + strcpy(WaitPipe->Name, RelativePortName.Buffer); //UNICODEFIX UnicodePortName.Buffer; + + if (!NT_SUCCESS(Status = NtFsControlFile( + NpfsHandle, + NULL, // Event + NULL, // ApcRoutine + NULL, // ApcContext + &Iosb, + FSCTL_PIPE_WAIT, + WaitPipe, // Buffer for data to the FS + WaitPipeLength, + NULL, // OutputBuffer + 0 // OutputBufferLength + ))) { + + Error( ClientWaitPipe, Status ); + } + if (Status == STATUS_PENDING) { + if (!NT_SUCCESS(Status = NtWaitForSingleObject( NpfsHandle, TRUE, NULL ))) { + + Error( NtWaitForSingleObject, Status ); + } + } + + if (!NT_SUCCESS(Iosb.Status)) { + + Error( ClientWaitPipeFinalStatus, Iosb.Status ); + } + + Status = NtClose( NpfsHandle ); + ASSERT(NT_SUCCESS(Status)); +//#endif // NOT_YET_WORKING +// Delay(1); + + + // + // Initialize the attributes + // + + InitializeObjectAttributes( + &ObjectAttributes, + &UnicodePortName, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + ObjectAttributes.SecurityQualityOfService = (PVOID)(&SecurityQos); + + // + // Calculate the share access + // + + Share = (Config == FILE_PIPE_INBOUND ? FILE_SHARE_WRITE : + (Config == FILE_PIPE_OUTBOUND ? FILE_SHARE_READ : + FILE_SHARE_READ | FILE_SHARE_WRITE)); + + + + // + // And now open it... + // + + if (!NT_SUCCESS(Status = NtOpenFile( + &PipeHandle, + GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE, + &ObjectAttributes, + &Iosb, + Share, + 0 ))) { + + Error( OpenPipe, Status ); + } + + if ((ReadMode != FILE_PIPE_BYTE_STREAM_MODE) || + (CompletionMode != FILE_PIPE_QUEUE_OPERATION)) { + + FILE_PIPE_INFORMATION Buffer; + + Buffer.ReadMode = ReadMode; + Buffer.CompletionMode = CompletionMode; + + if (!NT_SUCCESS(Status = NtSetInformationFile( + PipeHandle, + &Iosb, + &Buffer, + sizeof(FILE_PIPE_INFORMATION), + FilePipeInformation ))) { + + Error( NtSetInformationFile, Status ); + } + } + + return PipeHandle; +} -- cgit v1.2.3