//----------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.IdentityModel { using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Principal; using System.Text; enum EXTENDED_NAME_FORMAT { NameUnknown = 0, NameFullyQualifiedDN = 1, NameSamCompatible = 2, NameDisplay = 3, NameUniqueId = 6, NameCanonical = 7, NameUserPrincipalName = 8, NameCanonicalEx = 9, NameServicePrincipalName = 10, NameDnsDomainName = 12 } enum TokenInformationClass : uint { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert } enum Win32Error { ERROR_SUCCESS = 0, ERROR_INSUFFICIENT_BUFFER = 122, ERROR_NO_TOKEN = 1008, ERROR_NONE_MAPPED = 1332, } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct CREDUI_INFO { public int cbSize; public IntPtr hwndParent; public string pszMessageText; public string pszCaptionText; public IntPtr hbmBanner; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal class SEC_WINNT_AUTH_IDENTITY_EX { public uint Version; public uint Length; public string User; public uint UserLength; public string Domain; public uint DomainLength; public string Password; public uint PasswordLength; public uint Flags; public string PackageList; public uint PackageListLength; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct SID_AND_ATTRIBUTES { internal IntPtr Sid; internal uint Attributes; internal static readonly long SizeOf = (long)Marshal.SizeOf(typeof(SID_AND_ATTRIBUTES)); } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct TOKEN_GROUPS { internal uint GroupCount; internal SID_AND_ATTRIBUTES Groups; // SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct PLAINTEXTKEYBLOBHEADER { internal byte bType; internal byte bVersion; internal short reserved; internal int aiKeyAlg; internal int keyLength; internal static readonly int SizeOf = Marshal.SizeOf(typeof(PLAINTEXTKEYBLOBHEADER)); }; [StructLayout(LayoutKind.Sequential)] internal struct LUID { internal uint LowPart; internal uint HighPart; } [StructLayout(LayoutKind.Sequential)] internal struct LUID_AND_ATTRIBUTES { internal LUID Luid; internal uint Attributes; } [StructLayout(LayoutKind.Sequential)] internal struct TOKEN_PRIVILEGE { internal uint PrivilegeCount; internal LUID_AND_ATTRIBUTES Privilege; internal static readonly uint Size = (uint)Marshal.SizeOf(typeof(TOKEN_PRIVILEGE)); } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct UNICODE_INTPTR_STRING { internal UNICODE_INTPTR_STRING(int length, int maximumLength, IntPtr buffer) { this.Length = (ushort)length; this.MaxLength = (ushort)maximumLength; this.Buffer = buffer; } internal ushort Length; internal ushort MaxLength; internal IntPtr Buffer; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct KERB_CERTIFICATE_S4U_LOGON { internal KERB_LOGON_SUBMIT_TYPE MessageType; internal uint Flags; internal UNICODE_INTPTR_STRING UserPrincipalName; // OPTIONAL, certificate mapping hints: username or username@domain internal UNICODE_INTPTR_STRING DomainName; // used to locate the forest // OPTIONAL, certificate mapping hints: if missing, using the local machine's domain internal uint CertificateLength; // for the client certificate internal IntPtr Certificate; // for the client certificate, BER encoded internal static int Size = Marshal.SizeOf(typeof(KERB_CERTIFICATE_S4U_LOGON)); } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct TOKEN_SOURCE { private const int TOKEN_SOURCE_LENGTH = 8; [MarshalAs(UnmanagedType.ByValArray, SizeConst = TOKEN_SOURCE_LENGTH)] internal char[] Name; internal LUID SourceIdentifier; } internal enum KERB_LOGON_SUBMIT_TYPE { KerbInteractiveLogon = 2, KerbSmartCardLogon = 6, KerbWorkstationUnlockLogon = 7, KerbSmartCardUnlockLogon = 8, KerbProxyLogon = 9, KerbTicketLogon = 10, KerbTicketUnlockLogon = 11, //#if (_WIN32_WINNT >= 0x0501) -- Disabled until IIS fixes their target version. KerbS4ULogon = 12, //#endif //#if (_WIN32_WINNT >= 0x0600) KerbCertificateLogon = 13, KerbCertificateS4ULogon = 14, KerbCertificateUnlockLogon = 15, //#endif } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct QUOTA_LIMITS { internal IntPtr PagedPoolLimit; internal IntPtr NonPagedPoolLimit; internal IntPtr MinimumWorkingSetSize; internal IntPtr MaximumWorkingSetSize; internal IntPtr PagefileLimit; internal IntPtr TimeLimit; } internal enum SECURITY_IMPERSONATION_LEVEL { Anonymous = 0, Identification = 1, Impersonation = 2, Delegation = 3, } internal enum TokenType : int { TokenPrimary = 1, TokenImpersonation } internal enum SecurityLogonType : int { Interactive = 2, Network, Batch, Service, Proxy, Unlock } [SuppressUnmanagedCodeSecurity] static class NativeMethods { const string ADVAPI32 = "advapi32.dll"; const string KERNEL32 = "kernel32.dll"; const string SECUR32 = "secur32.dll"; const string CREDUI = "credui.dll"; // Error codes from ntstatus.h //internal const uint STATUS_SOME_NOT_MAPPED = 0x00000107; internal const uint STATUS_NO_MEMORY = 0xC0000017; //internal const uint STATUS_NONE_MAPPED = 0xC0000073; internal const uint STATUS_INSUFFICIENT_RESOURCES = 0xC000009A; internal const uint STATUS_ACCESS_DENIED = 0xC0000022; // From WinStatus.h internal const uint STATUS_ACCOUNT_RESTRICTION = 0xC000006E; internal static byte[] LsaSourceName = new byte[] { (byte)'W', (byte)'C', (byte)'F' }; // we set the source name to "WCF". internal static byte[] LsaKerberosName = new byte[] { (byte)'K', (byte)'e', (byte)'r', (byte)'b', (byte)'e', (byte)'r', (byte)'o', (byte)'s' }; internal const uint KERB_CERTIFICATE_S4U_LOGON_FLAG_CHECK_DUPLICATES = 0x1; internal const uint KERB_CERTIFICATE_S4U_LOGON_FLAG_CHECK_LOGONHOURS = 0x2; // Error codes from WinError.h internal const int ERROR_ACCESS_DENIED = 0x5; internal const int ERROR_BAD_LENGTH = 0x18; internal const int ERROR_INSUFFICIENT_BUFFER = 0x7A; internal const uint SE_GROUP_ENABLED = 0x00000004; internal const uint SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010; internal const uint SE_GROUP_LOGON_ID = 0xC0000000; internal const int PROV_RSA_AES = 24; internal const int KP_IV = 1; internal const uint CRYPT_DELETEKEYSET = 0x00000010; internal const uint CRYPT_VERIFYCONTEXT = 0xF0000000; internal const byte PLAINTEXTKEYBLOB = 0x8; internal const byte CUR_BLOB_VERSION = 0x2; internal const int ALG_CLASS_DATA_ENCRYPT = (3 << 13); internal const int ALG_TYPE_BLOCK = (3 << 9); internal const int CALG_AES_128 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 14); internal const int CALG_AES_192 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 15); internal const int CALG_AES_256 = (ALG_CLASS_DATA_ENCRYPT | ALG_TYPE_BLOCK | 16); [DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern bool LogonUser( [In] string lpszUserName, [In] string lpszDomain, [In] string lpszPassword, [In] uint dwLogonType, [In] uint dwLogonProvider, [Out] out SafeCloseHandle phToken ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern bool GetTokenInformation( [In] IntPtr tokenHandle, [In] uint tokenInformationClass, [In] SafeHGlobalHandle tokenInformation, [In] uint tokenInformationLength, [Out] out uint returnLength); [DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern bool CryptAcquireContextW( [Out] out SafeProvHandle phProv, [In] string pszContainer, [In] string pszProvider, [In] uint dwProvType, [In] uint dwFlags ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal unsafe static extern bool CryptImportKey( [In] SafeProvHandle hProv, [In] void* pbData, [In] uint dwDataLen, [In] IntPtr hPubKey, [In] uint dwFlags, [Out] out SafeKeyHandle phKey ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern bool CryptGetKeyParam( [In] SafeKeyHandle phKey, [In] uint dwParam, [In] IntPtr pbData, [In, Out] ref uint dwDataLen, [In] uint dwFlags ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal unsafe static extern bool CryptSetKeyParam( [In] SafeKeyHandle phKey, [In] uint dwParam, [In] void* pbData, [In] uint dwFlags ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] unsafe internal static extern bool CryptEncrypt( [In] SafeKeyHandle phKey, [In] IntPtr hHash, [In] bool final, [In] uint dwFlags, [In] void* pbData, [In, Out] ref int dwDataLen, [In] int dwBufLen ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] unsafe internal static extern bool CryptDecrypt( [In] SafeKeyHandle phKey, [In] IntPtr hHash, [In] bool final, [In] uint dwFlags, [In] void* pbData, [In, Out] ref int dwDataLen ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal static extern bool CryptDestroyKey( [In] IntPtr phKey ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal static extern bool CryptReleaseContext( [In] IntPtr hProv, [In] uint dwFlags ); [DllImport(ADVAPI32, ExactSpelling = true, CharSet = CharSet.Unicode, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern bool LookupPrivilegeValueW( [In] string lpSystemName, [In] string lpName, [Out] out LUID Luid ); [DllImport(ADVAPI32, SetLastError = true)] [ResourceExposure(ResourceScope.None)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal static extern bool AdjustTokenPrivileges( [In] SafeCloseHandle tokenHandle, [In] bool disableAllPrivileges, [In] ref TOKEN_PRIVILEGE newState, [In] uint bufferLength, [Out] out TOKEN_PRIVILEGE previousState, [Out] out uint returnLength ); [DllImport(ADVAPI32, SetLastError = true)] [ResourceExposure(ResourceScope.None)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal static extern bool RevertToSelf(); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceConsumption(ResourceScope.Process)] [ResourceExposure(ResourceScope.Process)] internal static extern bool OpenProcessToken( [In] IntPtr processToken, [In] TokenAccessLevels desiredAccess, [Out] out SafeCloseHandle tokenHandle ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern bool OpenThreadToken( [In] IntPtr threadHandle, [In] TokenAccessLevels desiredAccess, [In] bool openAsSelf, [Out] out SafeCloseHandle tokenHandle ); [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.Process)] internal static extern IntPtr GetCurrentProcess(); [DllImport(KERNEL32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern IntPtr GetCurrentThread(); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern bool DuplicateTokenEx( [In] SafeCloseHandle existingTokenHandle, [In] TokenAccessLevels desiredAccess, [In] IntPtr tokenAttributes, [In] SECURITY_IMPERSONATION_LEVEL impersonationLevel, [In] TokenType tokenType, [Out] out SafeCloseHandle duplicateTokenHandle ); [DllImport(ADVAPI32, CharSet = CharSet.Auto, SetLastError = true)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [ResourceExposure(ResourceScope.None)] internal static extern bool SetThreadToken( [In] IntPtr threadHandle, [In] SafeCloseHandle threadToken ); [DllImport(SECUR32, CharSet = CharSet.Auto, SetLastError = false)] [ResourceExposure(ResourceScope.None)] internal static extern int LsaRegisterLogonProcess( [In] ref UNICODE_INTPTR_STRING logonProcessName, [Out] out SafeLsaLogonProcessHandle lsaHandle, [Out] out IntPtr securityMode ); [DllImport(SECUR32, CharSet = CharSet.Auto, SetLastError = false)] [ResourceExposure(ResourceScope.None)] internal static extern int LsaConnectUntrusted( [Out] out SafeLsaLogonProcessHandle lsaHandle ); [DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = false)] [ResourceExposure(ResourceScope.None)] internal static extern int LsaNtStatusToWinError( [In] int status ); [DllImport(SECUR32, CharSet = CharSet.Auto, SetLastError = false)] [ResourceExposure(ResourceScope.None)] internal static extern int LsaLookupAuthenticationPackage( [In] SafeLsaLogonProcessHandle lsaHandle, [In] ref UNICODE_INTPTR_STRING packageName, [Out] out uint authenticationPackage ); [DllImport(ADVAPI32, CharSet = CharSet.Unicode, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal static extern bool AllocateLocallyUniqueId( [Out] out LUID Luid ); [DllImport(SECUR32, SetLastError = false)] [ResourceExposure(ResourceScope.None)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal static extern int LsaFreeReturnBuffer( IntPtr handle ); [DllImport(SECUR32, CharSet = CharSet.Auto, SetLastError = false)] [ResourceExposure(ResourceScope.None)] internal static extern int LsaLogonUser( [In] SafeLsaLogonProcessHandle LsaHandle, [In] ref UNICODE_INTPTR_STRING OriginName, [In] SecurityLogonType LogonType, [In] uint AuthenticationPackage, [In] IntPtr AuthenticationInformation, [In] uint AuthenticationInformationLength, [In] IntPtr LocalGroups, [In] ref TOKEN_SOURCE SourceContext, [Out] out SafeLsaReturnBufferHandle ProfileBuffer, [Out] out uint ProfileBufferLength, [Out] out LUID LogonId, [Out] out SafeCloseHandle Token, [Out] out QUOTA_LIMITS Quotas, [Out] out int SubStatus ); [DllImport(SECUR32, CharSet = CharSet.Auto, SetLastError = false)] [ResourceExposure(ResourceScope.None)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] internal static extern int LsaDeregisterLogonProcess( [In] IntPtr handle ); [DllImport(CREDUI, CharSet = CharSet.Unicode, SetLastError = true)] [ResourceExposure(ResourceScope.None)] internal unsafe static extern uint SspiPromptForCredentials( string pszTargetName, ref CREDUI_INFO pUiInfo, uint dwAuthError, string pszPackage, IntPtr authIdentity, out IntPtr ppAuthIdentity, [MarshalAs(UnmanagedType.Bool)] ref bool pfSave, uint dwFlags ); [DllImport(CREDUI, CharSet = CharSet.Unicode, SetLastError = true)] [ResourceExposure(ResourceScope.None)] [return: MarshalAs(UnmanagedType.U1)] internal unsafe static extern bool SspiIsPromptingNeeded(uint ErrorOrNtStatus); [DllImport(SECUR32, CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.U1)] internal extern static bool TranslateName( string input, EXTENDED_NAME_FORMAT inputFormat, EXTENDED_NAME_FORMAT outputFormat, StringBuilder outputString, out uint size ); } }