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); }
/// <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); }
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)); }
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); }
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); }
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; } }