Ejemplo n.º 1
0
        internal static void LoadIntoObjectFromByteArray(IPersistStream persistableObject, byte[] byteStream)
        {
            SafeHGlobalHandle hGlobal     = SafeHGlobalHandle.AllocHGlobal(byteStream.Length);
            IntPtr            destination = SafeNativeMethods.GlobalLock(hGlobal);

            if (IntPtr.Zero == destination)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new OutOfMemoryException());
            }
            try
            {
                Marshal.Copy(byteStream, 0, destination, byteStream.Length);
                IStream pStm = SafeNativeMethods.CreateStreamOnHGlobal(hGlobal, false);
                try
                {
                    persistableObject.Load(pStm);
                }
                finally
                {
                    Marshal.ReleaseComObject(pStm);
                }
            }
            finally
            {
                SafeNativeMethods.GlobalUnlock(hGlobal);
            }
        }
        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);
        }
        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);
        }
        static SafeHGlobalHandle CopyOidsToUnmanagedMemory(OidCollection oids)
        {
            SafeHGlobalHandle safeAllocHandle = SafeHGlobalHandle.InvalidHandle;

            if (oids == null || oids.Count == 0)
            {
                return(safeAllocHandle);
            }

            // Copy the oid strings to a local list to prevent a security race condition where
            // the OidCollection or individual oids can be modified by another thread and
            // potentially cause a buffer overflow
            List <string> oidStrs = new List <string>();

            foreach (Oid oid in oids)
            {
                oidStrs.Add(oid.Value);
            }

            IntPtr pOid            = IntPtr.Zero;
            IntPtr pNullTerminator = IntPtr.Zero;

            // Needs to be checked to avoid having large sets of oids overflow the sizes and allow
            // a potential buffer overflow
            checked {
                int ptrSize = oidStrs.Count * Marshal.SizeOf(typeof(IntPtr));
                int oidSize = 0;
                foreach (string oidStr in oidStrs)
                {
                    oidSize += (oidStr.Length + 1);
                }
                safeAllocHandle = SafeHGlobalHandle.AllocHGlobal(ptrSize + oidSize);
                pOid            = new IntPtr((long)safeAllocHandle.DangerousGetHandle() + ptrSize);
            }

            for (int index = 0; index < oidStrs.Count; index++)
            {
                Marshal.WriteIntPtr(new IntPtr((long)safeAllocHandle.DangerousGetHandle() + index * Marshal.SizeOf(typeof(IntPtr))), pOid);
                byte[] ansiOid = Encoding.ASCII.GetBytes(oidStrs[index]);

                if (ansiOid.Length != oidStrs[index].Length)
                {
                    // We assumed single byte characters, fail if this is not the case.  The exception is not ideal.
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.CollectionWasModified)));
                }

                Marshal.Copy(ansiOid, 0, pOid, ansiOid.Length);
                pNullTerminator = new IntPtr((long)pOid + ansiOid.Length);
                Marshal.WriteByte(pNullTerminator, 0);

                pOid = new IntPtr((long)pOid + oidStrs[index].Length + 1);
            }
            return(safeAllocHandle);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Adds or replaces groups in the specified Authz Client Context.
        /// </summary>
        /// <remarks>This method invokes AuthzModifySids, modifying the groups
        /// using AUTHZ_SID_OPERATION_REPLACE. This ensures that a group that
        /// already exists is retained and the ones not present are added</remarks>
        /// <param name="hAuthzClientContext">Handle to the Authz Client Context to be modified</param>
        /// <returns>Win32Error.ERROR_SUCCESS on success and Win32 error code otherwise.</returns>
        public int ApplyGroups(AUTHZ_CLIENT_CONTEXT_HANDLE hAuthzClientContext)
        {
            var toBeFreed        = new List <SafeHGlobalHandle>();
            var sidAndAttributes = new List <NativeMethods.SID_AND_ATTRIBUTES>(this.Count);
            var sidOps           = new NativeMethods.AuthzSIDOperation[this.Count];

            foreach (var sid in this)
            {
                byte[] rawSid = new byte[sid.BinaryLength];
                sid.GetBinaryForm(rawSid, 0);

                SafeHGlobalHandle safesid = SafeHGlobalHandle.AllocHGlobal(rawSid);
                toBeFreed.Add(safesid);

                sidAndAttributes.Add(new NativeMethods.SID_AND_ATTRIBUTES(safesid.ToIntPtr(),
                                                                          NativeMethods.GroupAddtibute.Enabled));
            }

            SafeHGlobalHandle tokenGroups = SafeHGlobalHandle.AllocHGlobal(Marshal.SizeOf(typeof(ULONG)),
                                                                           sidAndAttributes,
                                                                           sidAndAttributes.Count);

            Marshal.WriteInt32(tokenGroups.ToIntPtr(), sidAndAttributes.Count);

            for (int Idx = 0; Idx < this.Count; ++Idx)
            {
                sidOps[Idx] = NativeMethods.AuthzSIDOperation.Replace;
            }

            if (!NativeMethods.AuthzModifySids(hAuthzClientContext,
                                               type == GroupType.User
                                               ? NativeMethods.AuthzContextInformationClass.AuthzContextInfoGroupsSids
                                               : NativeMethods.AuthzContextInformationClass.AuthzContextInfoDeviceSids,
                                               sidOps,
                                               tokenGroups.ToIntPtr()))
            {
                return(Marshal.GetLastWin32Error());
            }

            return(Win32Error.ERROR_SUCCESS);
        }
Ejemplo n.º 6
0
        private static SafeHGlobalHandle CopyOidsToUnmanagedMemory(OidCollection oids)
        {
            SafeHGlobalHandle invalidHandle = SafeHGlobalHandle.InvalidHandle;

            if ((oids != null) && (oids.Count != 0))
            {
                List <string> list       = new List <string>();
                OidEnumerator enumerator = oids.GetEnumerator();
                while (enumerator.MoveNext())
                {
                    Oid current = enumerator.Current;
                    list.Add(current.Value);
                }
                IntPtr zero = IntPtr.Zero;
                IntPtr ptr  = IntPtr.Zero;
                int    num  = list.Count * Marshal.SizeOf(typeof(IntPtr));
                int    num2 = 0;
                foreach (string str in list)
                {
                    num2 += str.Length + 1;
                }
                invalidHandle = SafeHGlobalHandle.AllocHGlobal((int)(num + num2));
                zero          = new IntPtr(((long)invalidHandle.DangerousGetHandle()) + num);
                for (int i = 0; i < list.Count; i++)
                {
                    Marshal.WriteIntPtr(new IntPtr(((long)invalidHandle.DangerousGetHandle()) + (i * Marshal.SizeOf(typeof(IntPtr)))), zero);
                    byte[] bytes = Encoding.ASCII.GetBytes(list[i]);
                    if (bytes.Length != list[i].Length)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(System.IdentityModel.SR.GetString("ObjectIsReadOnly")));
                    }
                    Marshal.Copy(bytes, 0, zero, bytes.Length);
                    ptr = new IntPtr(((long)zero) + bytes.Length);
                    Marshal.WriteByte(ptr, 0);
                    zero = new IntPtr((((long)zero) + list[i].Length) + 1L);
                }
            }
            return(invalidHandle);
        }
        private static SafeHGlobalHandle GetTokenInformation(IntPtr tokenHandle, System.IdentityModel.TokenInformationClass tokenInformationClass, out uint dwLength)
        {
            SafeHGlobalHandle invalidHandle = SafeHGlobalHandle.InvalidHandle;

            dwLength = (uint)Marshal.SizeOf(typeof(uint));
            bool flag  = System.IdentityModel.NativeMethods.GetTokenInformation(tokenHandle, (uint)tokenInformationClass, invalidHandle, 0, out dwLength);
            int  error = Marshal.GetLastWin32Error();

            switch (error)
            {
            case (0x18 && 0x7a):
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
            }
            invalidHandle = SafeHGlobalHandle.AllocHGlobal(dwLength);
            flag          = System.IdentityModel.NativeMethods.GetTokenInformation(tokenHandle, (uint)tokenInformationClass, invalidHandle, dwLength, out dwLength);
            error         = Marshal.GetLastWin32Error();
            if (flag)
            {
                return(invalidHandle);
            }
            invalidHandle.Close();
            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
        }
Ejemplo n.º 8
0
        static SafeHGlobalHandle GetTokenInformation(IntPtr tokenHandle, TokenInformationClass tokenInformationClass, out uint dwLength)
        {
            SafeHGlobalHandle safeAllocHandle = SafeHGlobalHandle.InvalidHandle;

            dwLength = (uint)Marshal.SizeOf(typeof(uint));
            bool result = NativeMethods.GetTokenInformation(tokenHandle,
                                                            (uint)tokenInformationClass,
                                                            safeAllocHandle,
                                                            0,
                                                            out dwLength);
            int dwErrorCode = Marshal.GetLastWin32Error();

            switch (dwErrorCode)
            {
            case NativeMethods.ERROR_BAD_LENGTH:
            // special case for TokenSessionId. Falling through
            case NativeMethods.ERROR_INSUFFICIENT_BUFFER:
                safeAllocHandle = SafeHGlobalHandle.AllocHGlobal(dwLength);
                result          = NativeMethods.GetTokenInformation(tokenHandle,
                                                                    (uint)tokenInformationClass,
                                                                    safeAllocHandle,
                                                                    dwLength,
                                                                    out dwLength);
                dwErrorCode = Marshal.GetLastWin32Error();
                if (!result)
                {
                    safeAllocHandle.Close();
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(dwErrorCode));
                }
                break;

            default:
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(dwErrorCode));
            }
            return(safeAllocHandle);
        }
Ejemplo n.º 9
0
        public X509Certificate2Collection Find(X509FindType findType, object findValue, bool validOnly)
        {
            SafeHGlobalHandle invalidHandle = SafeHGlobalHandle.InvalidHandle;

            System.IdentityModel.SafeCertContextHandle pPrevCertContext = System.IdentityModel.SafeCertContextHandle.InvalidHandle;
            X509Certificate2Collection certificates = new X509Certificate2Collection();
            SafeHGlobalHandle          handle3      = SafeHGlobalHandle.InvalidHandle;

            try
            {
                uint   num;
                string str;
                byte[] buffer;
                System.IdentityModel.CAPI.CRYPTOAPI_BLOB cryptoapi_blob;
                switch (findType)
                {
                case X509FindType.FindByThumbprint:
                    buffer = findValue as byte[];
                    if (buffer == null)
                    {
                        str = findValue as string;
                        if (str == null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.IdentityModel.SR.GetString("X509FindValueMismatchMulti", new object[] { findType, typeof(string), typeof(byte[]), findValue.GetType() })));
                        }
                        goto Label_011A;
                    }
                    goto Label_0123;

                case X509FindType.FindBySubjectName:
                    str = findValue as string;
                    if (str == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.IdentityModel.SR.GetString("X509FindValueMismatch", new object[] { findType, typeof(string), findValue.GetType() })));
                    }
                    break;

                case X509FindType.FindBySubjectDistinguishedName:
                    if (!(findValue is string))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.IdentityModel.SR.GetString("X509FindValueMismatch", new object[] { findType, typeof(string), findValue.GetType() })));
                    }
                    goto Label_01C4;

                case X509FindType.FindByIssuerName:
                    str = findValue as string;
                    if (str == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.IdentityModel.SR.GetString("X509FindValueMismatch", new object[] { findType, typeof(string), findValue.GetType() })));
                    }
                    goto Label_021D;

                case X509FindType.FindByIssuerDistinguishedName:
                    if (!(findValue is string))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.IdentityModel.SR.GetString("X509FindValueMismatch", new object[] { findType, typeof(string), findValue.GetType() })));
                    }
                    goto Label_027E;

                case X509FindType.FindBySerialNumber:
                    buffer = findValue as byte[];
                    if (buffer == null)
                    {
                        str = findValue as string;
                        if (str == null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.IdentityModel.SR.GetString("X509FindValueMismatchMulti", new object[] { findType, typeof(string), typeof(byte[]), findValue.GetType() })));
                        }
                        goto Label_02F4;
                    }
                    goto Label_033C;

                case X509FindType.FindBySubjectKeyIdentifier:
                    buffer = findValue as byte[];
                    if (buffer == null)
                    {
                        str = findValue as string;
                        if (str == null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.IdentityModel.SR.GetString("X509FindValueMismatchMulti", new object[] { findType, typeof(string), typeof(byte[]), findValue.GetType() })));
                        }
                        buffer = System.IdentityModel.SecurityUtils.DecodeHexString(str);
                    }
                    findValue = buffer;
                    num       = 0;
                    goto Label_03F4;

                default:
                {
                    X509Store store = new X509Store(this.certStoreHandle.DangerousGetHandle());
                    try
                    {
                        return(store.Certificates.Find(findType, findValue, validOnly));
                    }
                    finally
                    {
                        store.Close();
                    }
                    goto Label_03F4;
                }
                }
                num           = 0x80007;
                invalidHandle = SafeHGlobalHandle.AllocHGlobal(str);
                goto Label_03F4;
Label_011A:
                buffer = System.IdentityModel.SecurityUtils.DecodeHexString(str);
Label_0123:
                cryptoapi_blob        = new System.IdentityModel.CAPI.CRYPTOAPI_BLOB();
                handle3               = SafeHGlobalHandle.AllocHGlobal(buffer);
                cryptoapi_blob.pbData = handle3.DangerousGetHandle();
                cryptoapi_blob.cbData = (uint)buffer.Length;
                num = 0x10000;
                Marshal.StructureToPtr(cryptoapi_blob, SafeHGlobalHandle.AllocHGlobal(System.IdentityModel.CAPI.CRYPTOAPI_BLOB.Size).DangerousGetHandle(), false);
                goto Label_03F4;
Label_01C4:
                num = 0;
                goto Label_03F4;
Label_021D:
                num           = 0x80004;
                invalidHandle = SafeHGlobalHandle.AllocHGlobal(str);
                goto Label_03F4;
Label_027E:
                num = 0;
                goto Label_03F4;
Label_02F4:
                buffer = System.IdentityModel.SecurityUtils.DecodeHexString(str);
                int length = buffer.Length;
                int index  = 0;
                for (int i = length - 1; index < (buffer.Length / 2); i--)
                {
                    byte num5 = buffer[index];
                    buffer[index] = buffer[i];
                    buffer[i]     = num5;
                    index++;
                }
Label_033C:
                findValue = buffer;
                num       = 0;
Label_03F4:
                pPrevCertContext = System.IdentityModel.CAPI.CertFindCertificateInStore(this.certStoreHandle, 0x10001, 0, num, invalidHandle, pPrevCertContext);
                while ((pPrevCertContext != null) && !pPrevCertContext.IsInvalid)
                {
                    X509Certificate2 certificate;
                    if (this.TryGetMatchingX509Certificate(pPrevCertContext.DangerousGetHandle(), findType, num, findValue, validOnly, out certificate))
                    {
                        certificates.Add(certificate);
                    }
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try
                    {
                        continue;
                    }
                    finally
                    {
                        GC.SuppressFinalize(pPrevCertContext);
                        pPrevCertContext = System.IdentityModel.CAPI.CertFindCertificateInStore(this.certStoreHandle, 0x10001, 0, num, invalidHandle, pPrevCertContext);
                    }
                }
            }
            finally
            {
                if (pPrevCertContext != null)
                {
                    pPrevCertContext.Close();
                }
                invalidHandle.Close();
                handle3.Close();
            }
            return(certificates);
        }
        /// <summary>
        /// Adds or replaces claims in the specified Authz Client Context.
        /// </summary>
        /// <remarks>This method invokes AuthzModifyClaims, modifying the claims
        /// using AUTHZ_SECURITY_ATTRIBUTE_OPERATION_REPLACE. This ensures that
        /// the values of a claims that already exists are replaces and the ones
        /// not present are added.</remarks>
        /// <param name="handleClientContext">Handle to the Authz Client Context to be modified</param>
        /// <returns>Win32Error.ERROR_SUCCESS on success and Win32 error code otherwise.</returns>
        public int ApplyClaims(AUTHZ_CLIENT_CONTEXT_HANDLE handleClientContext)
        {
            NativeMethods.AuthzSecurityAttributeOperation[] claimOps = null;
            var claims = new List <NativeMethods.AUTHZ_SECURITY_ATTRIBUTE_V1>(this.Count);

            foreach (var claim in this)
            {
                //
                // If all of the value specified turned out invalid, ignore the claim altogether.
                //
                if (claim.Value.ValueCount == 0)
                {
                    continue;
                }

                var attribute = new NativeMethods.AUTHZ_SECURITY_ATTRIBUTE_V1();

                attribute.Name       = claim.Key;
                attribute.Flags      = 0;
                attribute.Values     = claim.Value.RawValues.ToIntPtr();
                attribute.ValueCount = claim.Value.ValueCount;

                switch (claim.Value.ValueType)
                {
                case ClaimValueType.Integer:
                {
                    Debug.Assert(attribute.ValueCount == 1);
                    attribute.Type = NativeMethods.AuthzSecurityAttributeValueType.Int;
                    break;
                }

                case ClaimValueType.Boolean:
                {
                    Debug.Assert(attribute.ValueCount == 1);
                    attribute.Type = NativeMethods.AuthzSecurityAttributeValueType.Boolean;
                    break;
                }

                case ClaimValueType.String:
                {
                    Debug.Assert(attribute.ValueCount == 1);
                    goto case ClaimValueType.MultiValuedString;
                }

                case ClaimValueType.MultiValuedString:
                {
                    attribute.Type = NativeMethods.AuthzSecurityAttributeValueType.String;
                    break;
                }
                }

                claims.Add(attribute);
            }

            var claimInfo = new NativeMethods.AUTHZ_SECURITY_ATTRIBUTES_INFORMATION();

            claimInfo.Version        = 1; // AUTHZ_SECURITY_ATTRIBUTES_INFORMATION_VERSION_V1
            claimInfo.Reserved       = 0;
            claimInfo.AttributeCount = (ULONG)claims.Count;

            SafeHGlobalHandle v1Attributes = SafeHGlobalHandle.InvalidHandle;

            if (claimInfo.AttributeCount != 0)
            {
                v1Attributes = SafeHGlobalHandle.AllocHGlobal(claims);

                claimOps = new NativeMethods.AuthzSecurityAttributeOperation[claimInfo.AttributeCount];
                for (ULONG Idx = 0; Idx < claimInfo.AttributeCount; ++Idx)
                {
                    claimOps[Idx] = NativeMethods.AuthzSecurityAttributeOperation.Replace;
                }
            }

            claimInfo.pAttributeV1 = v1Attributes.ToIntPtr();

            if (!NativeMethods.AuthzModifyClaims(handleClientContext,
                                                 claimDefnType == ClaimDefinitionType.User
                                                 ? NativeMethods.AuthzContextInformationClass.AuthzContextInfoUserClaims
                                                 : NativeMethods.AuthzContextInformationClass.AuthzContextInfoDeviceClaims,
                                                 claimOps,
                                                 ref claimInfo))
            {
                return(Marshal.GetLastWin32Error());
            }

            return(Win32Error.ERROR_SUCCESS);
        }
        /// <summary>
        /// Get the native (unmanaged) representation of the list of values in
        /// the Microsoft.Samples.Cbac.ClaimValue instance.
        /// </summary>
        /// <param name="valueType">Type of the value(s) in this instance</param>
        /// <param name="values">The collection of values each in string format</param>
        /// <param name="valueCount">Return the count of unique values</param>
        /// <returns>SafeHGlobalHandle that references a native (unmanaged)
        /// pointer to values that can be used in the 'Values' field of the
        /// CLAIM_SECURITY_ATTRIBUTE_V1 structure.</returns>
        static SafeHGlobalHandle GetRawValues(ClaimValueType valueType,
                                              string value,
                                              out ULONG valueCount)
        {
            const int BASE_OCTAL   = 8;
            const int BASE_DECIMAL = 10;
            const int BASE_HEX     = 16;

            const string OCTAL_REGEX = "^[+]?0[0-7]+$";
            const string HEX_REGEX   = "^[+]?0[xX][0-9a-fA-f]+$";

            var stringValues = new StringCollection();

            valueCount = 1;

            //
            // As part of formulating the values in native format, verify that
            // we do not have duplicates. AuthzModifyClaims fails with
            // ERROR_ALREADY_EXISTS when duplicate values are specified.
            //
            switch (valueType)
            {
            case ClaimValueType.Integer:
            {
                long[] values = new long[1];
                try
                {
                    int fromBase = BASE_DECIMAL;

                    if (Regex.Match(value, OCTAL_REGEX).Success)
                    {
                        fromBase = BASE_OCTAL;
                    }
                    else if (Regex.Match(value, HEX_REGEX).Success)
                    {
                        fromBase = BASE_HEX;
                    }

                    values[0] = Convert.ToInt64(value, fromBase);

                    return(SafeHGlobalHandle.AllocHGlobal(values));
                }
                catch (Exception e)
                {
                    throw new BadValueException(string.Format(CultureInfo.CurrentCulture,
                                                              "Invalid Int value - {0}",
                                                              value),
                                                e);
                }
            }

            case ClaimValueType.Boolean:
            {
                long[] values = new long[1];

                try
                {
                    string strValue = value;

                    if (string.Compare(value, "true", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        strValue = "1";
                    }
                    else if (string.Compare(value, "false", StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        strValue = "0";
                    }

                    values[0] = Convert.ToInt64(strValue, CultureInfo.InvariantCulture);

                    return(SafeHGlobalHandle.AllocHGlobal(values));
                }
                catch (Exception e)
                {
                    throw new BadValueException(string.Format(CultureInfo.CurrentCulture,
                                                              "Invalid Boolean value - {0}",
                                                              value), e);
                }
            }

            case ClaimValueType.MultiValuedString:
            {
                char[]       bracketChars = { '[', ']' };
                const string CSV_REGEX    = @"# Parse CVS line. Capture next value in named group: 'val'
                                                   \s*                      # Ignore leading whitespace.
                                                   (?:                      # Group of value alternatives.
                                                       ""                   # Either a double quoted string,
                                                       (?<val>              # Capture contents between quotes.
                                                       [^""]*(""""[^""]*)*  # Zero or more non-quotes, allowing 
                                                       )                    # doubled "" quotes within string.
                                                       ""\s*                # Ignore whitespace following quote.
                                                   |  (?<val>[^,]+)         # Or... One or more non-commas.
                                                   )                        # End value alternatives group.
                                                   (?:,|$)                  # Match end is comma or EOS";

                if (!value.StartsWith("[", StringComparison.Ordinal) ||
                    !value.EndsWith("]", StringComparison.Ordinal))
                {
                    throw new BadValueException(string.Format(CultureInfo.CurrentCulture,
                                                              "Multi-valued String is not enclosed within square brackets: '{0}'",
                                                              value));
                }

                MatchCollection splitResult = Regex.Matches(value.Trim(bracketChars),
                                                            CSV_REGEX,
                                                            RegexOptions.Multiline
                                                            | RegexOptions.IgnorePatternWhitespace);

                if (splitResult.Count == 0)
                {
                    throw new BadValueException(string.Format(CultureInfo.CurrentCulture,
                                                              "Ill-formed Multi-valued String: '{0}'",
                                                              value));
                }
                else
                {
                    foreach (Match literal in splitResult)
                    {
                        string strVal = literal.Groups["val"].Value.Trim();
                        if (!stringValues.Contains(strVal))
                        {
                            if (!string.IsNullOrEmpty(strVal))
                            {
                                stringValues.Add(strVal);
                            }
                        }
                        else
                        {
                            Helper.ReportDuplicateValue(ClaimValueType.MultiValuedString,
                                                        literal.Groups["val"].Value);
                        }
                    }
                }

                if (stringValues.Count == 0)
                {
                    throw new BadValueException(string.Format(CultureInfo.CurrentCulture,
                                                              "No non-empty strings in : '{0}'",
                                                              value));
                }

                valueCount = (ULONG)stringValues.Count;

                goto case ClaimValueType.String;
            }

            case ClaimValueType.String:
            {
                if (stringValues.Count == 0)
                {
                    string strVal = value.Trim();

                    if (!string.IsNullOrEmpty(strVal))
                    {
                        stringValues.Add(strVal);
                    }
                }

                var strings = new List <SafeHGlobalHandle>(stringValues.Count);

                foreach (var stringValue in stringValues)
                {
                    SafeHGlobalHandle nativeString = SafeHGlobalHandle.AllocHGlobal(stringValue);

                    strings.Add(nativeString);
                }

                SafeHGlobalHandle result = SafeHGlobalHandle.AllocHGlobal(
                    strings.Select(n => n.ToIntPtr())
                    .ToArray());

                //
                // Since the native (managed) representation is an array
                // of pointers to strings, ensure that these pointers
                // are being referenced in the uber SafeHGlobalHandle
                // that represents the array of pointers.
                //
                result.AddSubReference(strings);

                valueCount = (ULONG)strings.Count;

                return(result);
            }

            default:
            {
                valueCount = 0;
                break;
            }
            }

            return(SafeHGlobalHandle.InvalidHandle);
        }
Ejemplo n.º 12
0
        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();
                }
            }
        }
        public X509Certificate2Collection Find(X509FindType findType, object findValue, bool validOnly)
        {
            DiagnosticUtility.DebugAssert(!this.certStoreHandle.IsInvalid, "");

            uint dwFindType;
            SafeHGlobalHandle          pvFindPara   = SafeHGlobalHandle.InvalidHandle;
            SafeCertContextHandle      pCertContext = SafeCertContextHandle.InvalidHandle;
            X509Certificate2Collection result       = new X509Certificate2Collection();
            SafeHGlobalHandle          pvTemp       = SafeHGlobalHandle.InvalidHandle;
            string strFindValue;

            byte[] bytes;

            try
            {
                switch (findType)
                {
                case X509FindType.FindBySubjectName:
                    strFindValue = findValue as string;
                    if (strFindValue == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType())));
                    }

                    dwFindType = CAPI.CERT_FIND_SUBJECT_STR;
                    pvFindPara = SafeHGlobalHandle.AllocHGlobal(strFindValue);
                    break;

                case X509FindType.FindByThumbprint:
                    bytes = findValue as byte[];
                    if (bytes == null)
                    {
                        strFindValue = findValue as string;
                        if (strFindValue == null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType())));
                        }

                        bytes = SecurityUtils.DecodeHexString(strFindValue);
                    }

                    CAPI.CRYPTOAPI_BLOB blob = new CAPI.CRYPTOAPI_BLOB();
                    pvTemp      = SafeHGlobalHandle.AllocHGlobal(bytes);
                    blob.pbData = pvTemp.DangerousGetHandle();
                    blob.cbData = (uint)bytes.Length;
                    dwFindType  = CAPI.CERT_FIND_HASH;
                    pvFindPara  = SafeHGlobalHandle.AllocHGlobal(CAPI.CRYPTOAPI_BLOB.Size);
                    Marshal.StructureToPtr(blob, pvFindPara.DangerousGetHandle(), false);
                    break;

                case X509FindType.FindBySubjectDistinguishedName:
                    if (!(findValue is string))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType())));
                    }

                    dwFindType = CAPI.CERT_FIND_ANY;
                    break;

                case X509FindType.FindByIssuerName:
                    strFindValue = findValue as string;
                    if (strFindValue == null)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType())));
                    }

                    dwFindType = CAPI.CERT_FIND_ISSUER_STR;
                    pvFindPara = SafeHGlobalHandle.AllocHGlobal(strFindValue);
                    break;

                case X509FindType.FindByIssuerDistinguishedName:
                    if (!(findValue is string))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatch, findType, typeof(string), findValue.GetType())));
                    }

                    dwFindType = CAPI.CERT_FIND_ANY;
                    break;

                case X509FindType.FindBySerialNumber:
                    bytes = findValue as byte[];
                    if (bytes == null)
                    {
                        strFindValue = findValue as string;
                        if (strFindValue == null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType())));
                        }

                        bytes = SecurityUtils.DecodeHexString(strFindValue);

                        // reverse bits
                        int len = bytes.Length;
                        for (int i = 0, j = len - 1; i < bytes.Length / 2; ++i, --j)
                        {
                            byte tmp = bytes[i];
                            bytes[i] = bytes[j];
                            bytes[j] = tmp;
                        }
                    }
                    findValue  = bytes;
                    dwFindType = CAPI.CERT_FIND_ANY;
                    break;

                case X509FindType.FindBySubjectKeyIdentifier:
                    bytes = findValue as byte[];
                    if (bytes == null)
                    {
                        strFindValue = findValue as string;
                        if (strFindValue == null)
                        {
                            throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(SR.GetString(SR.X509FindValueMismatchMulti, findType, typeof(string), typeof(byte[]), findValue.GetType())));
                        }

                        bytes = SecurityUtils.DecodeHexString(strFindValue);
                    }
                    findValue  = bytes;
                    dwFindType = CAPI.CERT_FIND_ANY;
                    break;

                default:
                    // Fallback to CLR implementation
                    X509Store store = new X509Store(this.certStoreHandle.DangerousGetHandle());
                    try
                    {
                        return(store.Certificates.Find(findType, findValue, validOnly));
                    }
                    finally
                    {
                        store.Close();
                    }
                }

#pragma warning suppress 56523 // We are not interested in CRYPT_E_NOT_FOUND error, it return null anyway.
                pCertContext = CAPI.CertFindCertificateInStore(this.certStoreHandle,
                                                               CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                               0,
                                                               dwFindType,
                                                               pvFindPara,
                                                               pCertContext);

                while (pCertContext != null && !pCertContext.IsInvalid)
                {
                    X509Certificate2 cert;
                    if (TryGetMatchingX509Certificate(pCertContext.DangerousGetHandle(), findType,
                                                      dwFindType, findValue, validOnly, out cert))
                    {
                        result.Add(cert);
                    }

                    // CER
                    RuntimeHelpers.PrepareConstrainedRegions();
                    try { }
                    finally
                    {
                        // Suppress the finalizer
#pragma warning suppress 56508 // CertFindCertificateInStore will release the prev one.
                        GC.SuppressFinalize(pCertContext);
#pragma warning suppress 56523 // We are not interested in CRYPT_E_NOT_FOUND error, it return null anyway.
                        pCertContext = CAPI.CertFindCertificateInStore(this.certStoreHandle,
                                                                       CAPI.X509_ASN_ENCODING | CAPI.PKCS_7_ASN_ENCODING,
                                                                       0,
                                                                       dwFindType,
                                                                       pvFindPara,
                                                                       pCertContext);
                    }
                }
            }
            finally
            {
                if (pCertContext != null)
                {
                    pCertContext.Close();
                }
                pvFindPara.Close();
                pvTemp.Close();
            }
            return(result);
        }
        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);
        }
        private static void WriteAuditEvent(uint auditType, uint auditId, params string[] parameters)
        {
            if (!IsSecurityAuditSupported)
            {
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new PlatformNotSupportedException(System.ServiceModel.SR.GetString("SecurityAuditPlatformNotSupported")));
            }
            Privilege privilege = new Privilege("SeAuditPrivilege");

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                try
                {
                    SafeSecurityAuditHandle handle;
                    privilege.Enable();
                    if (!NativeMethods.AuthzRegisterSecurityEventSource(0, "ServiceModel 4.0.0.0", out handle))
                    {
                        int error = Marshal.GetLastWin32Error();
                        Utility.CloseInvalidOutSafeHandle(handle);
                        throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                    }
                    SafeHGlobalHandle   handle2     = null;
                    SafeHGlobalHandle[] handleArray = new SafeHGlobalHandle[parameters.Length];
                    try
                    {
                        NativeMethods.AUDIT_PARAM  audit_param;
                        NativeMethods.AUDIT_PARAMS audit_params;
                        handle2 = SafeHGlobalHandle.AllocHGlobal((int)(parameters.Length * NativeMethods.AUDIT_PARAM.Size));
                        long num2 = handle2.DangerousGetHandle().ToInt64();
                        audit_param.Type   = NativeMethods.AUDIT_PARAM_TYPE.APT_String;
                        audit_param.Length = 0;
                        audit_param.Flags  = 0;
                        audit_param.Data1  = IntPtr.Zero;
                        for (int i = 0; i < parameters.Length; i++)
                        {
                            if (!string.IsNullOrEmpty(parameters[i]))
                            {
                                string s = System.ServiceModel.Diagnostics.EventLogger.NormalizeEventLogParameter(parameters[i]);
                                handleArray[i]    = SafeHGlobalHandle.AllocHGlobal(s);
                                audit_param.Data0 = handleArray[i].DangerousGetHandle();
                            }
                            else
                            {
                                audit_param.Data0 = IntPtr.Zero;
                            }
                            Marshal.StructureToPtr(audit_param, new IntPtr(num2 + (i * NativeMethods.AUDIT_PARAM.Size)), false);
                        }
                        audit_params.Length     = 0;
                        audit_params.Flags      = auditType;
                        audit_params.Parameters = handle2;
                        audit_params.Count      = (ushort)parameters.Length;
                        if (!NativeMethods.AuthzReportSecurityEventFromParams(auditType, handle, auditId, null, ref audit_params))
                        {
                            int num4 = Marshal.GetLastWin32Error();
                            throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(num4));
                        }
                    }
                    finally
                    {
                        for (int j = 0; j < handleArray.Length; j++)
                        {
                            if (handleArray[j] != null)
                            {
                                handleArray[j].Close();
                            }
                        }
                        if (handle2 != null)
                        {
                            handle2.Close();
                        }
                        handle.Close();
                    }
                }
                finally
                {
                    int    num6    = -1;
                    string message = null;
                    try
                    {
                        num6 = privilege.Revert();
                        if (num6 != 0)
                        {
                            message = System.ServiceModel.SR.GetString("RevertingPrivilegeFailed", new object[] { new Win32Exception(num6) });
                        }
                    }
                    finally
                    {
                        if (num6 != 0)
                        {
                            System.ServiceModel.DiagnosticUtility.FailFast(message);
                        }
                    }
                }
            }
            catch
            {
                throw;
            }
        }