File: ClaimsHelper.cs

package info (click to toggle)
mono 4.6.2.7%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 778,148 kB
  • ctags: 914,052
  • sloc: cs: 5,779,509; xml: 2,773,713; ansic: 432,645; sh: 14,749; makefile: 12,361; perl: 2,488; python: 1,434; cpp: 849; asm: 531; sql: 95; sed: 16; php: 1
file content (147 lines) | stat: -rw-r--r-- 6,375 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
//------------------------------------------------------------------------------
//     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
    }
}