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.
 
 
 
 
 
 

493 lines
12 KiB

#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
#define SECURITY_WIN32
#include <security.h>
#include <sspi.h>
#include <ntsecapi.h>
#include <ntrtl.h>
#include <schannel.h>
#include <sslcache.h>
#define LIST_CACHE_ENTRIES 1
#define LIST_ENTRIES_INTERACTIVE 2
#define PURGE_CACHE_ENTRIES 3
DWORD dwOperation = LIST_CACHE_ENTRIES;
BOOL fIncludeClient = FALSE;
BOOL fIncludeServer = FALSE;
BOOL fIncludeMappedEntries = FALSE;
LPSTR pszServerName = NULL;
void
DisplayCacheInfo(
HANDLE LsaHandle,
DWORD PackageNumber,
BOOL fClient,
BOOL fServer);
void
PurgeCacheEntries(
HANDLE LsaHandle,
DWORD PackageNumber);
void
DisplayCacheInfoInteractive(
HANDLE LsaHandle,
DWORD PackageNumber);
void Usage(void)
{
printf("USAGE: sslcache [ operation ] [ flags ]\n");
printf("\n");
printf(" OPERATIONS:\n");
printf(" -l List cache entries (default)\n");
printf(" -i List cache entries interactively\n");
printf(" -p Purge cache entries\n");
printf("\n");
printf(" FLAGS:\n");
printf(" -c Include client entries (default)\n");
printf(" -s Include server entries\n");
printf(" -S Include IIS mapped server entries (purge only)\n");
}
void _cdecl main(int argc, char *argv[])
{
DWORD Status;
HANDLE LsaHandle;
DWORD PackageNumber;
LSA_STRING PackageName;
BOOLEAN Trusted = TRUE;
BOOLEAN WasEnabled;
STRING Name;
ULONG Dummy;
INT i;
INT iOption;
PCHAR pszOption;
//
// Parse user-supplied parameters.
//
for(i = 1; i < argc; i++)
{
if(argv[i][0] == '/') argv[i][0] = '-';
if(argv[i][0] != '-')
{
printf("**** Invalid argument \"%s\"\n", argv[i]);
Usage();
return;
}
iOption = argv[i][1];
pszOption = &argv[i][2];
switch(iOption)
{
case 'l':
dwOperation = LIST_CACHE_ENTRIES;
break;
case 'i':
dwOperation = LIST_ENTRIES_INTERACTIVE;
break;
case 'p':
dwOperation = PURGE_CACHE_ENTRIES;
break;
case 'c':
fIncludeClient = TRUE;
break;
case 's':
if(*pszOption == '\0')
{
fIncludeServer = TRUE;
}
else
{
pszServerName = pszOption;
fIncludeClient = TRUE;
}
break;
case 'S':
fIncludeMappedEntries = TRUE;
fIncludeServer = TRUE;
break;
default:
printf("**** Invalid option \"%s\"\n", argv[i]);
Usage();
return;
}
}
//
// If neither client nor server was specified by user set appropriate default.
//
if(!fIncludeClient && !fIncludeServer)
{
if(dwOperation == PURGE_CACHE_ENTRIES)
{
fIncludeClient = TRUE;
}
else
{
fIncludeClient = TRUE;
fIncludeServer = TRUE;
}
}
//
// Get handle to schannel security package.
//
Status = RtlAdjustPrivilege(SE_TCB_PRIVILEGE, TRUE, FALSE, &WasEnabled);
if (!NT_SUCCESS(Status))
{
Trusted = FALSE;
}
RtlInitString(
&Name,
"sslcache");
if(Trusted)
{
Status = LsaRegisterLogonProcess(
&Name,
&LsaHandle,
&Dummy);
if(FAILED(Status))
{
printf("**** Error 0x%x returned by LsaRegisterLogonProcess\n", Status);
return;
}
}
else
{
Status = LsaConnectUntrusted(&LsaHandle);
if(FAILED(Status))
{
printf("**** Error 0x%x returned by LsaConnectUntrusted\n", Status);
return;
}
}
PackageName.Buffer = UNISP_NAME_A;
PackageName.Length = (USHORT)strlen(PackageName.Buffer);
PackageName.MaximumLength = PackageName.Length + 1;
Status = LsaLookupAuthenticationPackage(
LsaHandle,
&PackageName,
&PackageNumber);
if(FAILED(Status))
{
printf("**** Error 0x%x returned by LsaLookupAuthenticationPackage\n", Status);
CloseHandle(LsaHandle);
return;
}
//
// Perform specified operation.
//
if(dwOperation == LIST_CACHE_ENTRIES)
{
printf("\nDISPLAY CACHE ENTRIES\n");
printf("\n");
if(fIncludeClient)
{
printf("--CLIENT--\n");
DisplayCacheInfo(LsaHandle, PackageNumber, TRUE, FALSE);
}
if(fIncludeServer)
{
printf("--SERVER--\n");
DisplayCacheInfo(LsaHandle, PackageNumber, FALSE, TRUE);
}
if(fIncludeClient && fIncludeServer)
{
printf("--TOTAL--\n");
DisplayCacheInfo(LsaHandle, PackageNumber, TRUE, TRUE);
}
}
else if(dwOperation == LIST_ENTRIES_INTERACTIVE)
{
DisplayCacheInfoInteractive(LsaHandle, PackageNumber);
}
else
{
PurgeCacheEntries(LsaHandle, PackageNumber);
}
CloseHandle(LsaHandle);
}
void
PurgeCacheEntries(
HANDLE LsaHandle,
DWORD PackageNumber)
{
PSSL_PURGE_SESSION_CACHE_REQUEST pRequest;
DWORD cchServerName;
DWORD cbServerName;
DWORD SubStatus;
DWORD Status;
printf("\nPURGE CACHE ENTRIES\n");
printf("Client:%s\n", fIncludeClient ? "yes" : "no");
printf("Server:%s\n", fIncludeServer ? "yes" : "no");
if(pszServerName == NULL)
{
cbServerName = 0;
pRequest = (PSSL_PURGE_SESSION_CACHE_REQUEST)LocalAlloc(LPTR, sizeof(SSL_PURGE_SESSION_CACHE_REQUEST));
if(pRequest == NULL)
{
printf("**** Out of memory\n");
return;
}
}
else
{
cchServerName = MultiByteToWideChar(CP_ACP, 0, pszServerName, -1, NULL, 0);
cbServerName = (cchServerName + 1) * sizeof(WCHAR);
pRequest = LocalAlloc(LPTR, sizeof(SSL_PURGE_SESSION_CACHE_REQUEST) + cbServerName);
if(pRequest == NULL)
{
printf("**** Out of memory\n");
return;
}
cchServerName = MultiByteToWideChar(CP_ACP, 0, pszServerName, -1, (LPWSTR)(pRequest + 1), cchServerName);
if(cchServerName == 0)
{
printf("**** Error converting server name\n");
return;
}
pRequest->ServerName.Buffer = (LPWSTR)(pRequest + 1);
pRequest->ServerName.Length = (WORD)(cchServerName * sizeof(WCHAR));
pRequest->ServerName.MaximumLength = (WORD)cbServerName;
}
pRequest->MessageType = SslPurgeSessionCacheMessage;
if(fIncludeClient)
{
pRequest->Flags |= SSL_PURGE_CLIENT_ENTRIES;
}
if(fIncludeServer)
{
pRequest->Flags |= SSL_PURGE_SERVER_ENTRIES | SSL_PURGE_SERVER_ALL_ENTRIES;
}
if(fIncludeMappedEntries)
{
pRequest->Flags |= SSL_PURGE_SERVER_ENTRIES_DISCARD_LOCATORS;
}
Status = LsaCallAuthenticationPackage(
LsaHandle,
PackageNumber,
pRequest,
sizeof(SSL_PURGE_SESSION_CACHE_REQUEST) + cbServerName,
NULL,
NULL,
&SubStatus);
if(FAILED(Status))
{
printf("**** Error 0x%x returned by LsaCallAuthenticationPackage\n", Status);
return;
}
if(FAILED(SubStatus))
{
if(SubStatus == 0xC0000061)
{
printf("**** The TCB privilege is required to perform this operation.\n");
}
else
{
printf("**** Error 0x%x occurred while purging cache entries.\n", SubStatus);
}
}
}
void
DisplayCacheInfo(
HANDLE LsaHandle,
DWORD PackageNumber,
BOOL fClient,
BOOL fServer)
{
PSSL_SESSION_CACHE_INFO_REQUEST pRequest = NULL;
PSSL_SESSION_CACHE_INFO_RESPONSE pResponse = NULL;
DWORD cbResponse = 0;
DWORD SubStatus;
DWORD Status;
pRequest = (PSSL_SESSION_CACHE_INFO_REQUEST)LocalAlloc(LPTR, sizeof(SSL_SESSION_CACHE_INFO_REQUEST));
if(pRequest == NULL)
{
printf("**** Out of memory\n");
goto cleanup;
}
pRequest->MessageType = SslSessionCacheInfoMessage;
if(fClient)
{
pRequest->Flags |= SSL_RETRIEVE_CLIENT_ENTRIES;
}
if(fServer)
{
pRequest->Flags |= SSL_RETRIEVE_SERVER_ENTRIES;
}
Status = LsaCallAuthenticationPackage(
LsaHandle,
PackageNumber,
pRequest,
sizeof(SSL_SESSION_CACHE_INFO_REQUEST),
&pResponse,
&cbResponse,
&SubStatus);
if(FAILED(Status))
{
printf("**** Error 0x%x returned by LsaCallAuthenticationPackage\n", Status);
goto cleanup;
}
if(FAILED(SubStatus))
{
printf("**** Error 0x%x occurred while reading cache entries.\n", SubStatus);
}
printf("CacheSize: %d \n", pResponse->CacheSize);
printf("Entries: %d \n", pResponse->Entries);
printf("ActiveEntries: %d \n", pResponse->ActiveEntries);
printf("Zombies: %d \n", pResponse->Zombies);
printf("ExpiredZombies: %d \n", pResponse->ExpiredZombies);
printf("AbortedZombies: %d \n", pResponse->AbortedZombies);
printf("DeletedZombies: %d \n", pResponse->DeletedZombies);
printf("\n");
cleanup:
if(pRequest)
{
LocalFree(pRequest);
}
if (pResponse != NULL)
{
LsaFreeReturnBuffer(pResponse);
}
}
void cls(HANDLE hConsole)
{
COORD coordScreen = { 0, 0 }; /* here's where we'll home the
cursor */
BOOL bSuccess;
DWORD cCharsWritten;
CONSOLE_SCREEN_BUFFER_INFO csbi; /* to get buffer info */
DWORD dwConSize; /* number of character cells in
the current buffer */
/* get the number of character cells in the current buffer */
bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
/* fill the entire screen with blanks */
bSuccess = FillConsoleOutputCharacter( hConsole, (TCHAR) ' ',
dwConSize, coordScreen, &cCharsWritten );
/* get the current text attribute */
bSuccess = GetConsoleScreenBufferInfo( hConsole, &csbi );
/* now set the buffer's attributes accordingly */
bSuccess = FillConsoleOutputAttribute( hConsole, csbi.wAttributes,
dwConSize, coordScreen, &cCharsWritten );
/* put the cursor at (0, 0) */
bSuccess = SetConsoleCursorPosition( hConsole, coordScreen );
}
void home(HANDLE hConsole)
{
COORD coordScreen = { 0, 0 }; /* here's where we'll home the
cursor */
BOOL bSuccess;
/* put the cursor at (0, 0) */
bSuccess = SetConsoleCursorPosition( hConsole, coordScreen );
}
void
DisplayCacheInfoInteractive(
HANDLE LsaHandle,
DWORD PackageNumber)
{
HANDLE hConsoleOut;
hConsoleOut = GetStdHandle( STD_OUTPUT_HANDLE );
cls(hConsoleOut);
while(TRUE)
{
home(hConsoleOut);
if(fIncludeClient)
{
printf("--CLIENT--\n");
DisplayCacheInfo(LsaHandle, PackageNumber, TRUE, FALSE);
}
if(fIncludeServer)
{
printf("--SERVER--\n");
DisplayCacheInfo(LsaHandle, PackageNumber, FALSE, TRUE);
}
if(fIncludeClient && fIncludeServer)
{
printf("--TOTAL--\n");
DisplayCacheInfo(LsaHandle, PackageNumber, TRUE, TRUE);
}
Sleep(2000);
}
}