You've already forked linux-packaging-mono
							
							
		
			
				
	
	
		
			148 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| //------------------------------------------------------------------------------
 | |
| //     Copyright (c) Microsoft Corporation.  All rights reserved.
 | |
| //------------------------------------------------------------------------------
 | |
| 
 | |
| using System.IdentityModel;
 | |
| using System.IdentityModel.Tokens;
 | |
| using System.Runtime.Serialization;
 | |
| using System.Security.Cryptography.X509Certificates;
 | |
| using System.Security.Principal;
 | |
| using System.Security.Claims;
 | |
| 
 | |
| using Claim = System.Security.Claims.Claim;
 | |
| 
 | |
| namespace System.Security.Claims
 | |
| {
 | |
|     internal static class ClaimsHelper
 | |
|     {
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Creates a <see cref="WindowsIdentity"/> associated with a given X509 certificate.
 | |
|         /// </summary>
 | |
|         /// <param name="x509Certificate">The certificate to use to map to the associated <see cref="WindowsIdentity"/></param>
 | |
|         /// <returns></returns>
 | |
|         public static WindowsIdentity CertificateLogon(X509Certificate2 x509Certificate)
 | |
|         {
 | |
|             // for Vista, LsaLogon supporting mapping cert to NTToken
 | |
|             if (Environment.OSVersion.Version.Major >= CryptoHelper.WindowsVistaMajorNumber)
 | |
|             {
 | |
|                 return X509SecurityTokenHandler.KerberosCertificateLogon(x509Certificate);
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 // Downlevel, S4U over PrincipalName SubjectAltNames
 | |
|                 string upn = x509Certificate.GetNameInfo(X509NameType.UpnName, false);
 | |
|                 if (string.IsNullOrEmpty(upn))
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenValidationException(SR.GetString(SR.ID4067,
 | |
|                         X509Util.GetCertificateId(x509Certificate))));
 | |
|                 }
 | |
| 
 | |
|                 return new WindowsIdentity(upn);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /// <summary>
 | |
|         /// Finds the UPN claim value in the provided <see cref="ClaimsIdentity" /> object for the purpose
 | |
|         /// of mapping the identity to a <see cref="WindowsIdentity" /> object.
 | |
|         /// </summary>
 | |
|         /// <param name="claimsIdentity">The claims identity object containing the desired UPN claim.</param>
 | |
|         /// <returns>The UPN claim value found.</returns>
 | |
|         /// <exception cref="SecurityTokenException">
 | |
|         /// If <paramref name="claimsIdentity"/> contains zero UPN claims or more than one UPN claim.
 | |
|         /// </exception>
 | |
|         public static string FindUpn(ClaimsIdentity claimsIdentity)
 | |
|         {
 | |
|             string upn = null;
 | |
|             foreach (Claim claim in claimsIdentity.Claims)
 | |
|             {
 | |
|                 if (StringComparer.Ordinal.Equals(ClaimTypes.Upn, claim.Type))
 | |
|                 {
 | |
|                     // Complain if we already found a UPN claim
 | |
|                     if (upn != null)
 | |
|                     {
 | |
|                         throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID1053)));
 | |
|                     }
 | |
|                     upn = claim.Value;
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             if (string.IsNullOrEmpty(upn))
 | |
|             {
 | |
|                 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.ID1054)));
 | |
|             }
 | |
|             return upn;
 | |
|         }
 | |
| 
 | |
|         #region FIP 12979 GetAnonymous resolved as Postponed
 | |
| 
 | |
|         /*
 | |
|         /// <summary>
 | |
|         /// Generates a <see cref="WindowsClaimsIdentity"/> based on an anonymous user Windows token.
 | |
|         /// </summary>
 | |
|         /// <returns>A <see cref="WindowsClaimsIdentity"/> whose base <see cref="WindowsIdentity"/> has a Windows token for the NT AUTHORITY\ANONYMOUS LOGON user.</returns>
 | |
|         /// <exception cref="Win32Exception">Thrown if this method fails to open the current thread token.</exception>
 | |
|         /// <exception cref="Win32Exception">Thrown if this method fails to impersonate NT AUTHORITY\ANONYMOUS LOGON.</exception>
 | |
|         /// <exception cref="Win32Exception">Thrown if this method fails in attempt to reset thread token.</exception>
 | |
|         [ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
 | |
|         [SecurityPermissionAttribute( SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlPrincipal )]
 | |
|         new public static WindowsClaimsIdentity GetAnonymous()
 | |
|         {
 | |
|             SafeCloseHandle originalThreadToken;
 | |
|             WindowsClaimsIdentity result = null;
 | |
| 
 | |
|             //
 | |
|             // If the thread is impersonating
 | |
|             // preserve the token so we can put it back
 | |
|             // after capturing the anonymous token.
 | |
|             //
 | |
|             if( !NativeMethods.OpenThreadToken(
 | |
|                         NativeMethods.GetCurrentThread(),
 | |
|                         TokenAccessLevels.Impersonate,
 | |
|                         true, // Use the process identity permissions
 | |
|                         out originalThreadToken ) )
 | |
|             {
 | |
|                 int win32Result = Marshal.GetLastWin32Error();
 | |
|                 if( ( (int) Win32Error.ERROR_NO_TOKEN ) != win32Result )
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new Win32Exception( win32Result ) );
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             //
 | |
|             // Use CER to prevent the app-domain from unloading before
 | |
|             // we can set the thread token back to the original value.
 | |
|             //
 | |
|             RuntimeHelpers.PrepareConstrainedRegions();
 | |
|             try
 | |
|             {
 | |
|                 if( !NativeMethods.ImpersonateAnonymousToken( NativeMethods.GetCurrentThread() ) )
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new Win32Exception() );
 | |
|                 }
 | |
| 
 | |
|                 result = WindowsClaimsIdentity.GetCurrent();
 | |
|             }
 | |
|             finally
 | |
|             {
 | |
|                 //
 | |
|                 // Replace the thread token with the original.
 | |
|                 // Setting the thread token to zero will stop impersonating.
 | |
|                 // 
 | |
|                 if( !NativeMethods.SetThreadToken(
 | |
|                             IntPtr.Zero, // current thread
 | |
|                             originalThreadToken ) )
 | |
|                 {
 | |
|                     throw DiagnosticUtility.ExceptionUtility.ThrowHelperError( new Win32Exception() );
 | |
|                 }
 | |
| 
 | |
|                 originalThreadToken.Close();
 | |
|             }
 | |
| 
 | |
|             return result;
 | |
|         }
 | |
|  */
 | |
|         #endregion
 | |
|     }
 | |
| }
 |