windows-nt/Source/XPSP1/NT/ds/security/protocols/schannel/lsa/package.c
2020-09-26 16:20:57 +08:00

488 lines
14 KiB
C

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1995.
//
// File: package.c
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 10-02-96 RichardW Created
//
//----------------------------------------------------------------------------
#include "sslp.h"
#include <ntmsv1_0.h>
#include <wow64t.h>
#define UNISP_NAME_WO L"Microsoft Unified Security Protocol Provider"
#define SSL2SP_NAME_WO L"Microsoft SSL"
#define SSL3SP_NAME_WO L"Microsoft SSL 3.0"
#define PCT1SP_NAME_WO L"Microsoft PCT"
#define SCHANNEL_PACKAGE_NAME L"Schannel"
#define SCHANNEL_PACKAGE_COMMENT L"Schannel Security Package"
#define SCHANNEL_DLL_NAME L"schannel.dll"
DWORD dwSchannelPackageCapabilities = SECPKG_FLAG_INTEGRITY |
SECPKG_FLAG_PRIVACY |
SECPKG_FLAG_CONNECTION |
SECPKG_FLAG_MULTI_REQUIRED |
SECPKG_FLAG_EXTENDED_ERROR |
SECPKG_FLAG_IMPERSONATION |
SECPKG_FLAG_ACCEPT_WIN32_NAME |
// SECPKG_FLAG_NEGOTIABLE |
SECPKG_FLAG_MUTUAL_AUTH |
SECPKG_FLAG_STREAM;
BOOL SslGlobalStrongEncryptionPermitted = FALSE;
// List of (QueryContextAttributes) attributes that are to be
// thunked down to the LSA process.
ULONG ThunkedContextLevels[] = {
SECPKG_ATTR_AUTHORITY,
SECPKG_ATTR_ISSUER_LIST,
SECPKG_ATTR_ISSUER_LIST_EX,
SECPKG_ATTR_LOCAL_CERT_CONTEXT,
SECPKG_ATTR_LOCAL_CRED,
SECPKG_ATTR_EAP_KEY_BLOCK,
SECPKG_ATTR_USE_VALIDATED,
SECPKG_ATTR_CREDENTIAL_NAME,
SECPKG_ATTR_TARGET_INFORMATION,
SECPKG_ATTR_APP_DATA
};
//
// This package exports the following: A unified ssl/tls/pct provider,
// and the same unified provider under a different name. We have to
// keep the original one for backward compatibility, but whistler
// components can start using the new friendlier name.
//
SECPKG_FUNCTION_TABLE SpTable[] = {
{ // The Unified Provider
NULL,
NULL,
SpCallPackage,
SpLogonTerminated,
SpCallPackageUntrusted,
SpCallPackagePassthrough,
NULL,
NULL,
SpInitialize,
SpShutdown,
SpUniGetInfo,
SpAcceptCredentials,
SpUniAcquireCredentialsHandle,
SpQueryCredentialsAttributes,
SpFreeCredentialsHandle,
SpSaveCredentials,
SpGetCredentials,
SpDeleteCredentials,
SpInitLsaModeContext,
SpAcceptLsaModeContext,
SpDeleteContext,
SpApplyControlToken,
SpGetUserInfo,
SpGetExtendedInformation,
SpLsaQueryContextAttributes,
NULL,
NULL,
SpSetContextAttributes
},
{ // The Unified Provider
NULL,
NULL,
SpCallPackage,
SpLogonTerminated,
SpCallPackageUntrusted,
SpCallPackagePassthrough,
NULL,
NULL,
SpInitialize,
SpShutdown,
SpSslGetInfo,
SpAcceptCredentials,
SpUniAcquireCredentialsHandle,
SpQueryCredentialsAttributes,
SpFreeCredentialsHandle,
SpSaveCredentials,
SpGetCredentials,
SpDeleteCredentials,
SpInitLsaModeContext,
SpAcceptLsaModeContext,
SpDeleteContext,
SpApplyControlToken,
SpGetUserInfo,
SpGetExtendedInformation,
SpLsaQueryContextAttributes,
NULL,
NULL,
SpSetContextAttributes
}
};
ULONG_PTR SpPackageId;
PLSA_SECPKG_FUNCTION_TABLE LsaTable ;
BOOL SpInitialized = FALSE ;
HINSTANCE hDllInstance ;
BOOL ReplaceBaseProvider = TRUE;
TOKEN_SOURCE SslTokenSource ;
SECURITY_STRING SslNamePrefix = { 8, 10, L"X509" };
SECURITY_STRING SslComputerName ;
SECURITY_STRING SslDomainName ;
SECURITY_STRING SslPackageName ;
SECURITY_STRING SslMsvName ;
extern PWSTR SslDnsDomainName ;
//+---------------------------------------------------------------------------
//
// Function: SpLsaModeInitialize
//
// Synopsis: LSA Mode Initialization Function
//
// Arguments: [LsaVersion] --
// [PackageVersion] --
// [Table] --
// [TableCount] --
//
// History: 10-03-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
SECURITY_STATUS
SEC_ENTRY
SpLsaModeInitialize(
IN ULONG LsaVersion,
OUT PULONG PackageVersion,
OUT PSECPKG_FUNCTION_TABLE * Table,
OUT PULONG TableCount)
{
HKEY hKey;
int err;
DWORD type;
DWORD size;
*PackageVersion = SECPKG_INTERFACE_VERSION_2;
*Table = SpTable ;
*TableCount = sizeof( SpTable ) / sizeof( SECPKG_FUNCTION_TABLE );
return( SEC_E_OK );
}
//+---------------------------------------------------------------------------
//
// Function: SpInitialize
//
// Synopsis: Package Initialization Function
//
// Arguments: [dwPackageID] --
// [pParameters] --
// [Table] --
//
// History: 10-03-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
SECURITY_STATUS
SEC_ENTRY
SpInitialize(
ULONG_PTR dwPackageID,
PSECPKG_PARAMETERS pParameters,
PLSA_SECPKG_FUNCTION_TABLE Table)
{
WCHAR ComputerName[ 32 ];
DWORD Size ;
UNICODE_STRING Temp ;
if ( !SpInitialized )
{
SpPackageId = dwPackageID ;
LsaTable = Table ;
CopyMemory( SslTokenSource.SourceName, "SChannel", 8 );
AllocateLocallyUniqueId( &SslTokenSource.SourceIdentifier );
Size = sizeof( ComputerName ) / sizeof( WCHAR );
GetComputerName( ComputerName, &Size );
RtlInitUnicodeString( &Temp, ComputerName );
SslDuplicateString( &SslComputerName, &Temp );
SslDuplicateString( &SslDomainName, &pParameters->DomainName );
RtlInitUnicodeString( &SslPackageName, UNISP_NAME_W );
RtlCreateUnicodeStringFromAsciiz( &SslMsvName, MSV1_0_PACKAGE_NAME );
if ( !SslDnsDomainName )
{
DWORD DnsDomainLength = 0 ;
GetComputerNameEx( ComputerNameDnsDomain, NULL, &DnsDomainLength );
SslDnsDomainName = LocalAlloc( LMEM_FIXED,
(DnsDomainLength + 1) * sizeof(WCHAR) );
if ( SslDnsDomainName )
{
DnsDomainLength++ ;
GetComputerNameEx( ComputerNameDnsDomain, SslDnsDomainName, &DnsDomainLength );
}
}
if ((pParameters->MachineState & SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED) != 0)
{
SslGlobalStrongEncryptionPermitted = TRUE;
}
SpInitialized = TRUE;
}
return(S_OK);
}
//+---------------------------------------------------------------------------
//
// Function: SpUniGetInfo
//
// Synopsis: Get Package Information
//
// Arguments: [pInfo] --
//
// History: 10-03-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
SECURITY_STATUS
SEC_ENTRY
SpUniGetInfo(
PSecPkgInfo pInfo
)
{
pInfo->wVersion = 1;
pInfo->wRPCID = UNISP_RPC_ID;
pInfo->fCapabilities = dwSchannelPackageCapabilities;
pInfo->cbMaxToken = 0x4000;
pInfo->Name = ReplaceBaseProvider ? UNISP_NAME_WO : UNISP_NAME_W ;
pInfo->Comment = UNISP_NAME_W ;
return(S_OK);
}
//+---------------------------------------------------------------------------
//
// Function: SpSslGetInfo
//
// Synopsis: Get Package Information
//
// Arguments: [pInfo] --
//
// History: 10-03-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
SECURITY_STATUS
SEC_ENTRY
SpSslGetInfo(
PSecPkgInfo pInfo
)
{
pInfo->wVersion = 1;
pInfo->wRPCID = UNISP_RPC_ID;
pInfo->fCapabilities = dwSchannelPackageCapabilities;
pInfo->cbMaxToken = 0x4000;
pInfo->Name = SCHANNEL_PACKAGE_NAME;
pInfo->Comment = SCHANNEL_PACKAGE_COMMENT;
return(S_OK);
}
//+---------------------------------------------------------------------------
//
// Function: SslDuplicateString
//
// Synopsis: Duplicate a unicode string
//
// Arguments: [Dest] --
// [Source] --
//
// History: 10-18-96 RichardW Created
//
// Notes:
//
//----------------------------------------------------------------------------
NTSTATUS
SslDuplicateString(
PUNICODE_STRING Dest,
PUNICODE_STRING Source
)
{
Dest->Buffer = (PWSTR) SPExternalAlloc( Source->Length + sizeof(WCHAR) );
if ( Dest->Buffer )
{
Dest->Length = Source->Length ;
Dest->MaximumLength = Source->Length + sizeof(WCHAR) ;
CopyMemory( Dest->Buffer, Source->Buffer, Source->Length );
Dest->Buffer[ Dest->Length / 2 ] = L'\0';
return( STATUS_SUCCESS );
}
return( STATUS_NO_MEMORY );
}
//+---------------------------------------------------------------------------
//
// Function: SpGetExtendedInformation
//
// Synopsis: Return extended information to the LSA
//
// Arguments: [Class] -- Information Class
// [pInfo] -- Returned Information Pointer
//
// History: 3-24-97 ramas Created
//
// Notes:
//
//----------------------------------------------------------------------------
SECURITY_STATUS
SEC_ENTRY
SpGetExtendedInformation(
SECPKG_EXTENDED_INFORMATION_CLASS Class,
PSECPKG_EXTENDED_INFORMATION * pInfo
)
{
PSECPKG_EXTENDED_INFORMATION Info ;
PWSTR pszPath;
SECURITY_STATUS Status ;
ULONG Size ;
switch ( Class )
{
case SecpkgContextThunks:
Info = (PSECPKG_EXTENDED_INFORMATION) LsaTable->AllocateLsaHeap(
sizeof( SECPKG_EXTENDED_INFORMATION ) +
sizeof( ThunkedContextLevels ) );
if ( Info )
{
Info->Class = Class ;
Info->Info.ContextThunks.InfoLevelCount =
sizeof( ThunkedContextLevels ) / sizeof( ULONG );
CopyMemory( Info->Info.ContextThunks.Levels,
ThunkedContextLevels,
sizeof( ThunkedContextLevels ) );
Status = SEC_E_OK ;
}
else
{
Status = SEC_E_INSUFFICIENT_MEMORY ;
}
break;
#ifdef LATER
case SecpkgGssInfo:
Info = (PSECPKG_EXTENDED_INFORMATION) LsaTable->AllocateLsaHeap(
sizeof( SECPKG_EXTENDED_INFORMATION ) +
sizeof( Md5Oid ) );
if ( Info )
{
Info->Class = Class ;
Info->Info.GssInfo.EncodedIdLength = sizeof( Md5Oid );
CopyMemory( Info->Info.GssInfo.EncodedId,
Md5Oid,
sizeof( Md5Oid ) );
Status = SEC_E_OK ;
}
else
{
Status = SEC_E_INSUFFICIENT_MEMORY ;
}
#endif
case SecpkgWowClientDll:
//
// This indicates that we're smart enough to handle wow client processes
//
Info = (PSECPKG_EXTENDED_INFORMATION)
LsaTable->AllocateLsaHeap( sizeof( SECPKG_EXTENDED_INFORMATION ) +
(MAX_PATH * sizeof(WCHAR) ) );
if ( Info == NULL )
{
Status = STATUS_INSUFFICIENT_RESOURCES ;
break;
}
pszPath = (PWSTR) (Info + 1);
Size = GetSystemWow64Directory(pszPath, MAX_PATH);
if(Size == 0)
{
// This call will fail on x86 platforms.
Status = SEC_E_UNSUPPORTED_FUNCTION;
LsaTable->FreeLsaHeap(Info);
break;
}
if(Size + 1 + wcslen(SCHANNEL_DLL_NAME) >= MAX_PATH)
{
Status = STATUS_INSUFFICIENT_RESOURCES ;
LsaTable->FreeLsaHeap(Info);
break;
}
wcscat(pszPath, L"\\");
wcscat(pszPath, SCHANNEL_DLL_NAME);
Size += 1 + wcslen(SCHANNEL_DLL_NAME);
Info->Class = SecpkgWowClientDll ;
Info->Info.WowClientDll.WowClientDllPath.Buffer = pszPath;
Info->Info.WowClientDll.WowClientDllPath.Length = (USHORT) (Size * sizeof(WCHAR));
Info->Info.WowClientDll.WowClientDllPath.MaximumLength = (USHORT) ((Size + 1) * sizeof(WCHAR) );
Status = SEC_E_OK;
break;
default:
Status = SEC_E_UNSUPPORTED_FUNCTION ;
Info = NULL ;
break;
}
*pInfo = Info ;
return Status ;
}