internal static void CacheCredential(SafeFreeCredentials newHandle) { try { SafeCredentialReference newRef = SafeCredentialReference.CreateReference(newHandle); if (newRef == null) { return; } unchecked { int index = Interlocked.Increment(ref _Current) & c_MaxCacheSize; newRef = Interlocked.Exchange <SafeCredentialReference>(ref _CacheSlots[index], newRef); } if (newRef != null) { newRef.Close(); } } catch (Exception e) { if (!NclUtilities.IsFatal(e)) { GlobalLog.Assert("SSPIHandlCache", "Attempted to throw: " + e.ToString()); } } }
internal static void CacheCredential(SafeFreeCredentials creds, byte[] thumbPrint, SchProtocols allowedProtocols, EncryptionPolicy encryptionPolicy) { if (!creds.IsInvalid) { object obj2 = new SslCredKey(thumbPrint, allowedProtocols, encryptionPolicy); SafeCredentialReference reference = s_CachedCreds[obj2] as SafeCredentialReference; if (((reference == null) || reference.IsClosed) || reference._Target.IsInvalid) { lock (s_CachedCreds) { reference = s_CachedCreds[obj2] as SafeCredentialReference; if ((reference == null) || reference.IsClosed) { reference = SafeCredentialReference.CreateReference(creds); if (reference != null) { s_CachedCreds[obj2] = reference; if ((s_CachedCreds.Count % 0x20) == 0) { DictionaryEntry[] array = new DictionaryEntry[s_CachedCreds.Count]; s_CachedCreds.CopyTo(array, 0); for (int i = 0; i < array.Length; i++) { reference = array[i].Value as SafeCredentialReference; if (reference != null) { creds = reference._Target; reference.Close(); if ((!creds.IsClosed && !creds.IsInvalid) && ((reference = SafeCredentialReference.CreateReference(creds)) != null)) { s_CachedCreds[array[i].Key] = reference; } else { s_CachedCreds.Remove(array[i].Key); } } } } } } } } } }
internal static void CacheCredential(SafeFreeCredentials newHandle) { try { SafeCredentialReference reference = SafeCredentialReference.CreateReference(newHandle); if (reference != null) { int index = Interlocked.Increment(ref _Current) & 0x1f; reference = Interlocked.Exchange <SafeCredentialReference>(ref _CacheSlots[index], reference); if (reference != null) { reference.Close(); } } } catch (Exception exception) { NclUtilities.IsFatal(exception); } }
// // The app is calling this method after starting an SSL handshake. // // ATTN: The thumbPrint must be from inspected and possbly cloned user Cert object or we get a security hole in SslCredKey ctor. // internal static void CacheCredential(SafeFreeCredentials creds, byte[] thumbPrint, SchProtocols allowedProtocols, EncryptionPolicy encryptionPolicy) { GlobalLog.Assert(creds != null, "CacheCredential|creds == null"); if (creds.IsInvalid) { GlobalLog.Print("CacheCredential() Refused to cache an Invalid Handle = " + creds.ToString() + ", Current Cache Count = " + s_CachedCreds.Count); return; } object key = new SslCredKey(thumbPrint, allowedProtocols, encryptionPolicy); SafeCredentialReference cached = s_CachedCreds[key] as SafeCredentialReference; if (cached == null || cached.IsClosed || cached._Target.IsInvalid) { lock (s_CachedCreds) { cached = s_CachedCreds[key] as SafeCredentialReference; if (cached == null || cached.IsClosed) { cached = SafeCredentialReference.CreateReference(creds); if (cached == null) { // Means the handle got closed in between, return it back and let caller deal with the issue. return; } s_CachedCreds[key] = cached; GlobalLog.Print("CacheCredential() Caching New Handle = " + creds.ToString() + ", Current Cache Count = " + s_CachedCreds.Count); // // A simplest way of preventing infinite cache grows. // // Security relief (DoS): // A number of active creds is never greater than a number of _outstanding_ // security sessions, i.e. ssl connections. // So we will try to shrink cache to the number of active creds once in a while. // // Just to make clear we won't shrink cache in the case when NO new handles are coming to it. // if ((s_CachedCreds.Count % c_CheckExpiredModulo) == 0) { DictionaryEntry[] toRemoveAttempt = new DictionaryEntry[s_CachedCreds.Count]; s_CachedCreds.CopyTo(toRemoveAttempt, 0); for (int i = 0; i < toRemoveAttempt.Length; ++i) { cached = toRemoveAttempt[i].Value as SafeCredentialReference; if (cached != null) { creds = cached._Target; cached.Close(); if (!creds.IsClosed && !creds.IsInvalid && (cached = SafeCredentialReference.CreateReference(creds)) != null) { s_CachedCreds[toRemoveAttempt[i].Key] = cached; } else { s_CachedCreds.Remove(toRemoveAttempt[i].Key); } } } GlobalLog.Print("Scavenged cache, New Cache Count = " + s_CachedCreds.Count); } } else { GlobalLog.Print("CacheCredential() (locked retry) Found already cached Handle = " + cached._Target.ToString()); } } } else { GlobalLog.Print("CacheCredential() Ignoring incoming handle = " + creds.ToString() + " since found already cached Handle = " + cached._Target.ToString()); } }