internal bool TryGetContextIdentity(out WindowsIdentity mappedIdentity) { bool flag; if (!this.IsValidContext) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(-2146893055)); } SafeCloseHandle token = null; try { if (SspiWrapper.QuerySecurityContextToken(this.securityContext, out token) != 0) { mappedIdentity = null; return(false); } mappedIdentity = new WindowsIdentity(token.DangerousGetHandle(), "SSL/PCT"); flag = true; } finally { if (token != null) { token.Close(); } } return(flag); }
// // Note that method will demand PrincipalControlPermission // which essentially means demanding full trust // internal IIdentity GetIdentity() { CheckThrow(true); IIdentity result = null; string name = _Context.IsServer? _Context.AssociatedName: _Context.Spn; string protocol = "NTLM"; protocol = _Context.ProtocolName; if (_Context.IsServer) { SafeCloseHandle token = null; try { token = _Context.GetContextToken(); string authtype = _Context.ProtocolName; result = new WindowsIdentity(token.DangerousGetHandle(), authtype, WindowsAccountType.Normal, true); return(result); } catch (SecurityException) { //ignore and construct generic Identity if failed due to security problem } finally { if (token != null) { token.Close(); } } } // on the client we don't have access to the remote side identity. result = new GenericIdentity(name, protocol); return(result); }
internal IIdentity GetIdentity() { this.CheckThrow(true); string name = this._Context.IsServer ? this._Context.AssociatedName : this._Context.Spn; string type = "NTLM"; if (!ComNetOS.IsWin9x) { type = this._Context.ProtocolName; } if (this._Context.IsServer && !ComNetOS.IsWin9x) { SafeCloseHandle contextToken = null; try { contextToken = this._Context.GetContextToken(); return(new WindowsIdentity(contextToken.DangerousGetHandle(), this._Context.ProtocolName, WindowsAccountType.Normal, true)); } catch (SecurityException) { } finally { if (contextToken != null) { contextToken.Close(); } } } return(new GenericIdentity(name, type)); }
internal bool TryGetContextIdentity(out WindowsIdentity mappedIdentity) { if (!IsValidContext) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)SecurityStatus.InvalidHandle)); } SafeCloseHandle token = null; try { SecurityStatus status = (SecurityStatus)SspiWrapper.QuerySecurityContextToken(this.securityContext, out token); if (status != SecurityStatus.OK) { mappedIdentity = null; return(false); } mappedIdentity = new WindowsIdentity(token.DangerousGetHandle(), SecurityUtils.AuthTypeCertMap); return(true); } finally { if (token != null) { token.Close(); } } }
internal static bool IsPrimaryToken(SafeCloseHandle token) { using (SafeHandle handle = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenType)) { return(Marshal.ReadInt32(handle.DangerousGetHandle()) == 1); } }
public static SafeHandle GetTokenInformation(SafeCloseHandle token, TOKEN_INFORMATION_CLASS infoClass) { uint num; if (!GetTokenInformation(token, infoClass, SafeHGlobalHandle.InvalidHandle, 0, out num)) { int err = Marshal.GetLastWin32Error(); if (err != 0x7a) { throw new Win32Exception(err, "GetTokenInfoFailed"); } } SafeHandle tokenInformation = SafeHGlobalHandle.AllocHGlobal(num); try { if (!GetTokenInformation(token, infoClass, tokenInformation, num, out num)) { int num3 = Marshal.GetLastWin32Error(); throw new Win32Exception(num3, "GetTokenInfoFailed"); } } catch { tokenInformation.Dispose(); throw; } return(tokenInformation); }
public static WindowsIdentity GetProcessIdentity() { SafeCloseHandle tokenHandle = null; lock (lockObject) { try { if (!SafeNativeMethods.GetCurrentProcessToken(SafeNativeMethods.GetCurrentProcess(), TokenAccessLevels.Query, out tokenHandle)) { int error = Marshal.GetLastWin32Error(); Utility.CloseInvalidOutSafeHandle(tokenHandle); throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("OpenProcessTokenFailed", new object[] { error }))); } processIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle()); } finally { if (tokenHandle != null) { tokenHandle.Dispose(); } } } return(processIdentity); }
public static SafeHandle GetTokenInformation(SafeCloseHandle token, TOKEN_INFORMATION_CLASS infoClass) { uint num; if (!SafeNativeMethods.GetTokenInformation(token, infoClass, SafeHGlobalHandle.InvalidHandle, 0, out num)) { int error = Marshal.GetLastWin32Error(); if (error != 0x7a) { throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("GetTokenInfoFailed", new object[] { error }))); } } SafeHandle tokenInformation = SafeHGlobalHandle.AllocHGlobal(num); try { if (!SafeNativeMethods.GetTokenInformation(token, infoClass, tokenInformation, num, out num)) { int num3 = Marshal.GetLastWin32Error(); throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(num3, System.ServiceModel.SR.GetString("GetTokenInfoFailed", new object[] { num3 }))); } } catch { tokenInformation.Dispose(); throw; } return(tokenInformation); }
internal static extern bool DuplicateTokenEx( [In] SafeCloseHandle existingToken, [In] TokenAccessLevels desiredAccess, [In] IntPtr tokenAttributes, [In] SecurityImpersonationLevel impersonationLevel, [In] TokenType tokenType, out SafeCloseHandle newToken);
internal static System.ServiceModel.ComIntegration.LUID GetModifiedIDLUID(SafeCloseHandle token) { using (SafeHandle handle = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenStatistics)) { TOKEN_STATISTICS token_statistics = (TOKEN_STATISTICS)Marshal.PtrToStructure(handle.DangerousGetHandle(), typeof(TOKEN_STATISTICS)); return(token_statistics.ModifiedId); } }
internal static extern bool AccessCheck( [In] byte[] securityDescriptor, [In] SafeCloseHandle clientToken, [In] int desiredAccess, [In] GENERIC_MAPPING genericMapping, out PRIVILEGE_SET privilegeSet, [In, Out] ref uint privilegeSetLength, out uint grantedAccess, out bool accessStatus);
public static WindowsIdentity GetAnonymousIdentity() { SafeCloseHandle tokenHandle = null; bool flag = false; lock (lockObject) { if (anonymousIdentity == null) { try { try { if (!SafeNativeMethods.ImpersonateAnonymousUserOnCurrentThread(SafeNativeMethods.GetCurrentThread())) { int error = Marshal.GetLastWin32Error(); throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("ImpersonateAnonymousTokenFailed", new object[] { error }))); } flag = true; if (!SafeNativeMethods.OpenCurrentThreadToken(SafeNativeMethods.GetCurrentThread(), TokenAccessLevels.Query, true, out tokenHandle)) { int num2 = Marshal.GetLastWin32Error(); if (!SafeNativeMethods.RevertToSelf()) { num2 = Marshal.GetLastWin32Error(); System.ServiceModel.DiagnosticUtility.FailFast("RevertToSelf() failed with " + num2); } flag = false; Utility.CloseInvalidOutSafeHandle(tokenHandle); throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(num2, System.ServiceModel.SR.GetString("OpenThreadTokenFailed", new object[] { num2 }))); } if (!SafeNativeMethods.RevertToSelf()) { System.ServiceModel.DiagnosticUtility.FailFast("RevertToSelf() failed with " + Marshal.GetLastWin32Error()); } flag = false; using (tokenHandle) { anonymousIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle()); } } finally { if (flag && !SafeNativeMethods.RevertToSelf()) { System.ServiceModel.DiagnosticUtility.FailFast("RevertToSelf() failed with " + Marshal.GetLastWin32Error()); } } } catch { throw; } } } return(anonymousIdentity); }
internal static bool IsAtleastImpersonationToken(SafeCloseHandle token) { using (SafeHandle handle = GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TokenImpersonationLevel)) { if (Marshal.ReadInt32(handle.DangerousGetHandle()) < 2) { return(false); } return(true); } }
public static FileSystemRights GetEffectivePermissions( WindowsIdentity clientIdentity, FileSecurity securityDescriptor) { bool isAccessAllowed = false; byte[] binaryForm = securityDescriptor.GetSecurityDescriptorBinaryForm(); SafeCloseHandle newToken = null; SafeCloseHandle token = new SafeCloseHandle(clientIdentity.Token, false); try { if (IsPrimaryToken(token) && !DuplicateTokenEx( token, TokenAccessLevels.Query, IntPtr.Zero, SecurityImpersonationLevel.Identification, TokenType.TokenImpersonation, out newToken)) { int err = Marshal.GetLastWin32Error(); CloseInvalidOutSafeHandle(newToken); throw new Win32Exception(err, "DuplicateTokenExFailed"); } GENERIC_MAPPING genericMapping = new GENERIC_MAPPING(); PRIVILEGE_SET structPrivilegeSet = new PRIVILEGE_SET(); uint privilegeSetLength = (uint)Marshal.SizeOf(structPrivilegeSet); uint grantedAccess = 0; if (!AccessCheck( binaryForm, newToken ?? token, 0x2000000, genericMapping, out structPrivilegeSet, ref privilegeSetLength, out grantedAccess, out isAccessAllowed)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "AccessCheckFailed"); } return((FileSystemRights)grantedAccess); } finally { if (newToken != null) { newToken.Dispose(); } } }
public string GetRemoteIdentityName() { if (!this.isServer) { return(this.servicePrincipalName); } if (this.IsValidContext) { using (SafeCloseHandle handle = this.GetContextToken()) { using (WindowsIdentity identity = new WindowsIdentity(handle.DangerousGetHandle(), this.ProtocolName)) { return(identity.Name); } } } return(string.Empty); }
private bool IsImpersonatedContext() { SafeCloseHandle tokenHandle = null; if (!System.ServiceModel.ComIntegration.SafeNativeMethods.OpenCurrentThreadToken(System.ServiceModel.ComIntegration.SafeNativeMethods.GetCurrentThread(), TokenAccessLevels.Query, true, out tokenHandle)) { int error = Marshal.GetLastWin32Error(); Utility.CloseInvalidOutSafeHandle(tokenHandle); if (error == 0x3f0) { return(false); } ErrorBehavior.ThrowAndCatch(new Win32Exception(error)); return(true); } tokenHandle.Close(); return(true); }
protected override ReadOnlyCollection <IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password) { string domain = null; string[] strings = userName.Split('\\'); if (strings.Length != 1) { if (strings.Length != 2 || string.IsNullOrEmpty(strings[0])) { // Only support one slash and domain cannot be empty (consistent with windowslogon). throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.GetString(SR.IncorrectUserNameFormat)); } // This is the downlevel case - domain\userName userName = strings[1]; domain = strings[0]; } const uint LOGON32_PROVIDER_DEFAULT = 0; const uint LOGON32_LOGON_NETWORK_CLEARTEXT = 8; SafeCloseHandle tokenHandle = null; try { if (!NativeMethods.LogonUser(userName, domain, password, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, out tokenHandle)) { int error = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.FailLogonUser, userName), new Win32Exception(error))); } WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeBasic); WindowsClaimSet claimSet = new WindowsClaimSet(windowsIdentity, SecurityUtils.AuthTypeBasic, this.includeWindowsGroups, false); return(SecurityUtils.CreateAuthorizationPolicies(claimSet, claimSet.ExpirationTime)); } finally { if (tokenHandle != null) { tokenHandle.Close(); } } }
private void CheckAccess(WindowsIdentity clientIdentity, out bool IsAccessAllowed) { if (this.securityDescriptor == null) { throw Fx.AssertAndThrowFatal("Security Descriptor must not be NULL"); } IsAccessAllowed = false; byte[] binaryForm = new byte[this.securityDescriptor.BinaryLength]; this.securityDescriptor.GetBinaryForm(binaryForm, 0); SafeCloseHandle newToken = null; SafeCloseHandle token = new SafeCloseHandle(clientIdentity.Token, false); try { if (System.ServiceModel.ComIntegration.SecurityUtils.IsPrimaryToken(token) && !SafeNativeMethods.DuplicateTokenEx(token, TokenAccessLevels.Query, IntPtr.Zero, SecurityImpersonationLevel.Identification, System.ServiceModel.ComIntegration.TokenType.TokenImpersonation, out newToken)) { int error = Marshal.GetLastWin32Error(); Utility.CloseInvalidOutSafeHandle(newToken); throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("DuplicateTokenExFailed", new object[] { error }))); } GENERIC_MAPPING genericMapping = new GENERIC_MAPPING(); PRIVILEGE_SET structure = new PRIVILEGE_SET(); uint privilegeSetLength = (uint)Marshal.SizeOf(structure); uint grantedAccess = 0; if (!SafeNativeMethods.AccessCheck(binaryForm, (newToken != null) ? newToken : token, 1, genericMapping, out structure, ref privilegeSetLength, out grantedAccess, out IsAccessAllowed)) { int num4 = Marshal.GetLastWin32Error(); throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(num4, System.ServiceModel.SR.GetString("AccessCheckFailed", new object[] { num4 }))); } } finally { if (newToken != null) { newToken.Dispose(); } } }
protected override ReadOnlyCollection <IAuthorizationPolicy> ValidateUserNamePasswordCore(string userName, string password) { string lpszDomain = null; ReadOnlyCollection <IAuthorizationPolicy> onlys; string[] strArray = userName.Split(new char[] { '\\' }); if (strArray.Length != 1) { if ((strArray.Length != 2) || string.IsNullOrEmpty(strArray[0])) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(System.IdentityModel.SR.GetString("IncorrectUserNameFormat")); } userName = strArray[1]; lpszDomain = strArray[0]; } SafeCloseHandle phToken = null; try { if (!System.IdentityModel.NativeMethods.LogonUser(userName, lpszDomain, password, 8, 0, out phToken)) { int error = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(System.IdentityModel.SR.GetString("FailLogonUser", new object[] { userName }), new Win32Exception(error))); } WindowsIdentity windowsIdentity = new WindowsIdentity(phToken.DangerousGetHandle(), "Basic"); WindowsClaimSet claimSet = new WindowsClaimSet(windowsIdentity, "Basic", this.includeWindowsGroups, false); onlys = System.IdentityModel.SecurityUtils.CreateAuthorizationPolicies(claimSet, claimSet.ExpirationTime); } finally { if (phToken != null) { phToken.Close(); } } return(onlys); }
internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy) { if (!this.isAuthenticated) { bool flag = false; SafeDeleteContext refContext = null; SafeCloseHandle token = null; byte[] request = this.request; try { if (credentialsHandle == null) { credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound, new string[0]); flag = true; } SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect; ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy); if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("SecurityChannelBindingMissing"))); } if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy) { inFlags |= SspiContextFlags.ChannelBindingProxyBindings; } SspiContextFlags zero = SspiContextFlags.Zero; SecurityBuffer outputBuffer = new SecurityBuffer(0, BufferType.Token); List <SecurityBuffer> list = new List <SecurityBuffer>(2) { new SecurityBuffer(request, 2) }; if (helper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(helper.ChannelBinding)); } SecurityBuffer[] inputBuffers = null; if (list.Count > 0) { inputBuffers = list.ToArray(); } int error = SspiWrapper.AcceptSecurityContext(credentialsHandle, ref refContext, inFlags, Endianness.Native, inputBuffers, outputBuffer, ref zero); switch (error) { case 0: break; case 0x90312: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error))); case -2146893056: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosApReqInvalidOrOutOfMemory"), new Win32Exception(error))); default: throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailAcceptSecurityContext"), new Win32Exception(error))); } LifeSpan span = (LifeSpan)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.Lifespan); DateTime effectiveTimeUtc = span.EffectiveTimeUtc; DateTime expiryTimeUtc = span.ExpiryTimeUtc; SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.SessionKey); this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey); error = SspiWrapper.QuerySecurityContextToken(refContext, out token); if (error != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error)); } System.Security.Principal.WindowsIdentity windowsIdentity = new System.Security.Principal.WindowsIdentity(token.DangerousGetHandle(), "Kerberos"); base.Initialize(this.id, "Kerberos", effectiveTimeUtc, expiryTimeUtc, windowsIdentity, false); this.isAuthenticated = true; } finally { if (token != null) { token.Close(); } if (refContext != null) { refContext.Close(); } if (flag && (credentialsHandle != null)) { credentialsHandle.Close(); } } } }
/// <summary> /// Validates a <see cref="UserNameSecurityToken"/>. /// </summary> /// <param name="token">The <see cref="UserNameSecurityToken"/> to validate.</param> /// <returns>A <see cref="ReadOnlyCollection{T}"/> of <see cref="ClaimsIdentity"/> representing the identities contained in the token.</returns> /// <exception cref="ArgumentNullException">The parameter 'token' is null.</exception> /// <exception cref="ArgumentException">The token is not assignable from<see cref="UserNameSecurityToken"/>.</exception> /// <exception cref="InvalidOperationException">Configuration <see cref="SecurityTokenHandlerConfiguration"/>is null.</exception> /// <exception cref="ArgumentException">If username is not if the form 'user\domain'.</exception> /// <exception cref="SecurityTokenValidationException">LogonUser using the given token failed.</exception> public override ReadOnlyCollection <ClaimsIdentity> ValidateToken(SecurityToken token) { if (token == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("token"); } UserNameSecurityToken usernameToken = token as UserNameSecurityToken; if (usernameToken == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token", SR.GetString(SR.ID0018, typeof(UserNameSecurityToken))); } if (this.Configuration == null) { throw DiagnosticUtility.ThrowHelperInvalidOperation(SR.GetString(SR.ID4274)); } try { string userName = usernameToken.UserName; string password = usernameToken.Password; string domain = null; string[] strings = usernameToken.UserName.Split('\\'); if (strings.Length != 1) { if (strings.Length != 2 || string.IsNullOrEmpty(strings[0])) { // Only support one slash and domain cannot be empty (consistent with windowslogon). throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token", SR.GetString(SR.ID4062)); } // This is the downlevel case - domain\userName userName = strings[1]; domain = strings[0]; } const uint LOGON32_PROVIDER_DEFAULT = 0; const uint LOGON32_LOGON_NETWORK_CLEARTEXT = 8; SafeCloseHandle tokenHandle = null; try { if (!NativeMethods.LogonUser(userName, domain, password, LOGON32_LOGON_NETWORK_CLEARTEXT, LOGON32_PROVIDER_DEFAULT, out tokenHandle)) { int error = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.ID4063, userName), new Win32Exception(error))); } WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle(), AuthenticationTypes.Password, WindowsAccountType.Normal, true); // PARTIAL TRUST: will fail when adding claims, AddClaim is SecurityCritical. windowsIdentity.AddClaim(new Claim(ClaimTypes.AuthenticationInstant, XmlConvert.ToString(DateTime.UtcNow, DateTimeFormats.Generated), ClaimValueTypes.DateTime)); windowsIdentity.AddClaim(new Claim(ClaimTypes.AuthenticationMethod, AuthenticationMethods.Password)); if (this.Configuration.SaveBootstrapContext) { if (RetainPassword) { windowsIdentity.BootstrapContext = new BootstrapContext(usernameToken, this); } else { windowsIdentity.BootstrapContext = new BootstrapContext(new UserNameSecurityToken(usernameToken.UserName, null), this); } } this.TraceTokenValidationSuccess(token); List <ClaimsIdentity> identities = new List <ClaimsIdentity>(1); identities.Add(windowsIdentity); return(identities.AsReadOnly()); } finally { if (tokenHandle != null) { tokenHandle.Close(); } } } catch (Exception e) { if (Fx.IsFatal(e)) { throw; } this.TraceTokenValidationFailure(token, e.Message); throw e; } }
internal static WindowsIdentity KerberosCertificateLogon(X509Certificate2 certificate) { int status; SafeHGlobalHandle pSourceName = null; SafeHGlobalHandle pPackageName = null; SafeHGlobalHandle pLogonInfo = null; SafeLsaLogonProcessHandle logonHandle = null; SafeLsaReturnBufferHandle profileHandle = null; SafeCloseHandle tokenHandle = null; try { pSourceName = SafeHGlobalHandle.AllocHGlobal(NativeMethods.LsaSourceName.Length + 1); Marshal.Copy(NativeMethods.LsaSourceName, 0, pSourceName.DangerousGetHandle(), NativeMethods.LsaSourceName.Length); UNICODE_INTPTR_STRING sourceName = new UNICODE_INTPTR_STRING(NativeMethods.LsaSourceName.Length, NativeMethods.LsaSourceName.Length + 1, pSourceName.DangerousGetHandle()); Privilege privilege = null; RuntimeHelpers.PrepareConstrainedRegions(); // Try to get an impersonation token. try { // Try to enable the TCB privilege if possible try { privilege = new Privilege(Privilege.SeTcbPrivilege); privilege.Enable(); } catch (PrivilegeNotHeldException ex) { DiagnosticUtility.TraceHandledException(ex, TraceEventType.Information); } IntPtr dummy = IntPtr.Zero; status = NativeMethods.LsaRegisterLogonProcess(ref sourceName, out logonHandle, out dummy); if (NativeMethods.ERROR_ACCESS_DENIED == NativeMethods.LsaNtStatusToWinError(status)) { // We don't have the Tcb privilege. The best we can hope for is to get an Identification token. status = NativeMethods.LsaConnectUntrusted(out logonHandle); } if (status < 0) // non-negative numbers indicate success { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status))); } } finally { // if reverting privilege fails, fail fast! int revertResult = -1; string message = null; try { revertResult = privilege.Revert(); if (revertResult != 0) { message = SR.GetString(SR.RevertingPrivilegeFailed, new Win32Exception(revertResult)); } } finally { if (revertResult != 0) { DiagnosticUtility.FailFast(message); } } } // package name ("Kerberos") pPackageName = SafeHGlobalHandle.AllocHGlobal(NativeMethods.LsaKerberosName.Length + 1); Marshal.Copy(NativeMethods.LsaKerberosName, 0, pPackageName.DangerousGetHandle(), NativeMethods.LsaKerberosName.Length); UNICODE_INTPTR_STRING packageName = new UNICODE_INTPTR_STRING(NativeMethods.LsaKerberosName.Length, NativeMethods.LsaKerberosName.Length + 1, pPackageName.DangerousGetHandle()); uint packageId = 0; status = NativeMethods.LsaLookupAuthenticationPackage(logonHandle, ref packageName, out packageId); if (status < 0) // non-negative numbers indicate success { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status))); } // source context TOKEN_SOURCE sourceContext = new TOKEN_SOURCE(); if (!NativeMethods.AllocateLocallyUniqueId(out sourceContext.SourceIdentifier)) { int dwErrorCode = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(dwErrorCode)); } // SourceContext sourceContext.Name = new char[8]; sourceContext.Name[0] = 'W'; sourceContext.Name[1] = 'C'; sourceContext.Name[2] = 'F'; // LogonInfo byte[] certRawData = certificate.RawData; int logonInfoSize = KERB_CERTIFICATE_S4U_LOGON.Size + certRawData.Length; pLogonInfo = SafeHGlobalHandle.AllocHGlobal(logonInfoSize); unsafe { KERB_CERTIFICATE_S4U_LOGON *pInfo = (KERB_CERTIFICATE_S4U_LOGON *)pLogonInfo.DangerousGetHandle().ToPointer(); pInfo->MessageType = KERB_LOGON_SUBMIT_TYPE.KerbCertificateS4ULogon; pInfo->Flags = NativeMethods.KERB_CERTIFICATE_S4U_LOGON_FLAG_CHECK_LOGONHOURS; pInfo->UserPrincipalName = new UNICODE_INTPTR_STRING(0, 0, IntPtr.Zero); pInfo->DomainName = new UNICODE_INTPTR_STRING(0, 0, IntPtr.Zero); pInfo->CertificateLength = (uint)certRawData.Length; pInfo->Certificate = new IntPtr(pLogonInfo.DangerousGetHandle().ToInt64() + KERB_CERTIFICATE_S4U_LOGON.Size); Marshal.Copy(certRawData, 0, pInfo->Certificate, certRawData.Length); } QUOTA_LIMITS quotas = new QUOTA_LIMITS(); LUID logonId = new LUID(); uint profileBufferLength; int subStatus = 0; // Call LsaLogonUser status = NativeMethods.LsaLogonUser( logonHandle, ref sourceName, SecurityLogonType.Network, packageId, pLogonInfo.DangerousGetHandle(), (uint)logonInfoSize, IntPtr.Zero, ref sourceContext, out profileHandle, out profileBufferLength, out logonId, out tokenHandle, out quotas, out subStatus ); // LsaLogon has restriction (eg. password expired). SubStatus indicates the reason. if ((uint)status == NativeMethods.STATUS_ACCOUNT_RESTRICTION && subStatus < 0) { status = subStatus; } if (status < 0) // non-negative numbers indicate success { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(status))); } if (subStatus < 0) // non-negative numbers indicate success { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(NativeMethods.LsaNtStatusToWinError(subStatus))); } return(new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeCertMap)); } finally { if (tokenHandle != null) { tokenHandle.Close(); } if (pLogonInfo != null) { pLogonInfo.Close(); } if (profileHandle != null) { profileHandle.Close(); } if (pSourceName != null) { pSourceName.Close(); } if (pPackageName != null) { pPackageName.Close(); } if (logonHandle != null) { logonHandle.Close(); } } }
internal static extern bool GetCurrentProcessToken([In] IntPtr ProcessHandle, [In] TokenAccessLevels DesiredAccess, out SafeCloseHandle TokenHandle);
internal static extern bool DuplicateTokenEx([In] SafeCloseHandle ExistingToken, [In] TokenAccessLevels DesiredAccess, [In] IntPtr TokenAttributes, [In] SecurityImpersonationLevel ImpersonationLevel, [In] System.ServiceModel.ComIntegration.TokenType TokenType, out SafeCloseHandle NewToken);
internal static extern bool SetCurrentThreadToken([In] IntPtr ThreadHandle, [In] SafeCloseHandle TokenHandle);
internal static extern bool OpenCurrentThreadToken([In] IntPtr ThreadHandle, [In] TokenAccessLevels DesiredAccess, [In] bool OpenAsSelf, out SafeCloseHandle TokenHandle);
public static int QuerySecurityContextToken( SafeDeleteContext context, out SafeCloseHandle token) { return context.GetSecurityContextToken(out token); }
internal static extern bool GetTokenInformation( [In] SafeCloseHandle tokenHandle, [In] TOKEN_INFORMATION_CLASS tokenInformationClass, [In] SafeHandle tokenInformation, [Out] uint tokenInformationLength, out uint returnLength);
// This internal API is not thread-safe. It is acceptable since .. // 1) From public OM, Initialize happens at ctor time. // 2) From internal OM (Sfx), Initialize happens right after ctor (single thread env). // i.e. ReadToken and then AuthenticateToken. internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy) { if (this.isAuthenticated) { return; } bool ownCredentialsHandle = false; SafeDeleteContext securityContext = null; SafeCloseHandle tokenHandle = null; #if RECOMPUTEGSS int tokenSize = DEREncoding.TokenSize(this.request.Length); byte[] rawRequest = new byte[tokenSize]; int offset = 0; int len = this.request.Length; DEREncoding.MakeTokenHeader(this.request.Length, rawRequest, ref offset, ref len); System.Buffer.BlockCopy(this.request, 0, rawRequest, offset, this.request.Length); #else byte[] rawRequest = this.request; #endif try { if (credentialsHandle == null) { credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound); ownCredentialsHandle = true; } SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.Confidentiality | SspiContextFlags.ReplayDetect | SspiContextFlags.SequenceDetect; ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy); if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing))); } if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported) { fContextReq |= SspiContextFlags.ChannelBindingAllowMissingBindings; } if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy) { fContextReq |= SspiContextFlags.ChannelBindingProxyBindings; } SspiContextFlags contextFlags = SspiContextFlags.Zero; SecurityBuffer outSecurityBuffer = new SecurityBuffer(0, BufferType.Token); List <SecurityBuffer> list = new List <SecurityBuffer>(2); list.Add(new SecurityBuffer(rawRequest, BufferType.Token)); if (policyHelper.ShouldAddChannelBindingToASC()) { list.Add(new SecurityBuffer(policyHelper.ChannelBinding)); } SecurityBuffer[] inSecurityBuffer = null; if (list.Count > 0) { inSecurityBuffer = list.ToArray(); } int statusCode = SspiWrapper.AcceptSecurityContext(credentialsHandle, ref securityContext, fContextReq, Endianness.Native, inSecurityBuffer, outSecurityBuffer, ref contextFlags); if (DiagnosticUtility.ShouldTraceInformation) { SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, true, channelBinding); } if (statusCode != (int)SecurityStatus.OK) { if (statusCode == (int)SecurityStatus.ContinueNeeded) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode))); } else if (statusCode == (int)SecurityStatus.OutOfMemory) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.KerberosApReqInvalidOrOutOfMemory), new Win32Exception(statusCode))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new SecurityTokenException(SR.GetString(SR.FailAcceptSecurityContext), new Win32Exception(statusCode))); } } // Expiration LifeSpan lifeSpan = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan); DateTime effectiveTime = lifeSpan.EffectiveTimeUtc; DateTime expirationTime = lifeSpan.ExpiryTimeUtc; // SessionKey SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey); this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey); // WindowsSecurityToken statusCode = SspiWrapper.QuerySecurityContextToken(securityContext, out tokenHandle); if (statusCode != (int)SecurityStatus.OK) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode)); } WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeKerberos); Initialize(this.id, SecurityUtils.AuthTypeKerberos, effectiveTime, expirationTime, windowsIdentity, false); // Authenticated this.isAuthenticated = true; } finally { if (tokenHandle != null) { tokenHandle.Close(); } if (securityContext != null) { securityContext.Close(); } if (ownCredentialsHandle && credentialsHandle != null) { credentialsHandle.Close(); } } }
internal static extern bool DuplicateHandle(IntPtr hSourceProcessHandle, PipeHandle hSourceHandle, SafeCloseHandle hTargetProcessHandle, out IntPtr lpTargetHandle, int dwDesiredAccess, bool bInheritHandle, int dwOptions);
private static unsafe WindowsIdentity KerberosCertificateLogon(X509Certificate2 certificate) { SafeHGlobalHandle handle = null; SafeHGlobalHandle handle2 = null; SafeHGlobalHandle handle3 = null; SafeLsaLogonProcessHandle lsaHandle = null; SafeLsaReturnBufferHandle profileBuffer = null; SafeCloseHandle token = null; WindowsIdentity identity; try { int num; uint num6; handle = SafeHGlobalHandle.AllocHGlobal((int)(System.IdentityModel.NativeMethods.LsaSourceName.Length + 1)); Marshal.Copy(System.IdentityModel.NativeMethods.LsaSourceName, 0, handle.DangerousGetHandle(), System.IdentityModel.NativeMethods.LsaSourceName.Length); UNICODE_INTPTR_STRING logonProcessName = new UNICODE_INTPTR_STRING(System.IdentityModel.NativeMethods.LsaSourceName.Length, System.IdentityModel.NativeMethods.LsaSourceName.Length + 1, handle.DangerousGetHandle()); System.IdentityModel.Privilege privilege = null; RuntimeHelpers.PrepareConstrainedRegions(); try { try { privilege = new System.IdentityModel.Privilege("SeTcbPrivilege"); privilege.Enable(); } catch (PrivilegeNotHeldException exception) { if (DiagnosticUtility.ShouldTraceInformation) { DiagnosticUtility.ExceptionUtility.TraceHandledException(exception, TraceEventType.Information); } } IntPtr zero = IntPtr.Zero; num = System.IdentityModel.NativeMethods.LsaRegisterLogonProcess(ref logonProcessName, out lsaHandle, out zero); if (5 == System.IdentityModel.NativeMethods.LsaNtStatusToWinError(num)) { num = System.IdentityModel.NativeMethods.LsaConnectUntrusted(out lsaHandle); } if (num < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(System.IdentityModel.NativeMethods.LsaNtStatusToWinError(num))); } } finally { int error = -1; string message = null; try { error = privilege.Revert(); if (error != 0) { message = System.IdentityModel.SR.GetString("RevertingPrivilegeFailed", new object[] { new Win32Exception(error) }); } } finally { if (error != 0) { DiagnosticUtility.FailFast(message); } } } handle2 = SafeHGlobalHandle.AllocHGlobal((int)(System.IdentityModel.NativeMethods.LsaKerberosName.Length + 1)); Marshal.Copy(System.IdentityModel.NativeMethods.LsaKerberosName, 0, handle2.DangerousGetHandle(), System.IdentityModel.NativeMethods.LsaKerberosName.Length); UNICODE_INTPTR_STRING packageName = new UNICODE_INTPTR_STRING(System.IdentityModel.NativeMethods.LsaKerberosName.Length, System.IdentityModel.NativeMethods.LsaKerberosName.Length + 1, handle2.DangerousGetHandle()); uint authenticationPackage = 0; num = System.IdentityModel.NativeMethods.LsaLookupAuthenticationPackage(lsaHandle, ref packageName, out authenticationPackage); if (num < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(System.IdentityModel.NativeMethods.LsaNtStatusToWinError(num))); } TOKEN_SOURCE sourceContext = new TOKEN_SOURCE(); if (!System.IdentityModel.NativeMethods.AllocateLocallyUniqueId(out sourceContext.SourceIdentifier)) { int num4 = Marshal.GetLastWin32Error(); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(num4)); } sourceContext.Name = new char[8]; sourceContext.Name[0] = 'W'; sourceContext.Name[1] = 'C'; sourceContext.Name[2] = 'F'; byte[] rawData = certificate.RawData; int cb = KERB_CERTIFICATE_S4U_LOGON.Size + rawData.Length; handle3 = SafeHGlobalHandle.AllocHGlobal(cb); KERB_CERTIFICATE_S4U_LOGON *kerb_certificate_su_logonPtr = (KERB_CERTIFICATE_S4U_LOGON *)handle3.DangerousGetHandle().ToPointer(); kerb_certificate_su_logonPtr->MessageType = KERB_LOGON_SUBMIT_TYPE.KerbCertificateS4ULogon; kerb_certificate_su_logonPtr->Flags = 2; kerb_certificate_su_logonPtr->UserPrincipalName = new UNICODE_INTPTR_STRING(0, 0, IntPtr.Zero); kerb_certificate_su_logonPtr->DomainName = new UNICODE_INTPTR_STRING(0, 0, IntPtr.Zero); kerb_certificate_su_logonPtr->CertificateLength = (uint)rawData.Length; kerb_certificate_su_logonPtr->Certificate = new IntPtr(handle3.DangerousGetHandle().ToInt64() + KERB_CERTIFICATE_S4U_LOGON.Size); Marshal.Copy(rawData, 0, kerb_certificate_su_logonPtr->Certificate, rawData.Length); QUOTA_LIMITS quotas = new QUOTA_LIMITS(); LUID logonId = new LUID(); int subStatus = 0; num = System.IdentityModel.NativeMethods.LsaLogonUser(lsaHandle, ref logonProcessName, System.IdentityModel.SecurityLogonType.Network, authenticationPackage, handle3.DangerousGetHandle(), (uint)cb, IntPtr.Zero, ref sourceContext, out profileBuffer, out num6, out logonId, out token, out quotas, out subStatus); if ((num == -1073741714) && (subStatus < 0)) { num = subStatus; } if (num < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(System.IdentityModel.NativeMethods.LsaNtStatusToWinError(num))); } if (subStatus < 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(System.IdentityModel.NativeMethods.LsaNtStatusToWinError(subStatus))); } identity = new WindowsIdentity(token.DangerousGetHandle(), "SSL/PCT"); } finally { if (token != null) { token.Close(); } if (handle3 != null) { handle3.Close(); } if (profileBuffer != null) { profileBuffer.Close(); } if (handle != null) { handle.Close(); } if (handle2 != null) { handle2.Close(); } if (lsaHandle != null) { lsaHandle.Close(); } } return(identity); }