Exemplo n.º 1
0
        internal static void CacheCredential(SafeFreeCredentials newHandle)
        {
            try
            {
                SafeCredentialReference?newRef = SafeCredentialReference.CreateReference(newHandle);

                if (newRef == null)
                {
                    return;
                }

                unchecked
                {
                    int index = Interlocked.Increment(ref s_current) & c_MaxCacheSize;
                    newRef = Interlocked.Exchange <SafeCredentialReference>(ref s_cacheSlots[index], newRef);
                }

                newRef?.Dispose();
            }
            catch (Exception e)
            {
                if (!ExceptionCheck.IsFatal(e))
                {
                    if (NetEventSource.Log.IsEnabled())
                    {
                        NetEventSource.Fail(null, $"Attempted to throw: {e}");
                    }
                }
            }
        }
Exemplo n.º 2
0
        internal static void CacheCredential(SafeFreeCredentials newHandle)
        {
            try
            {
                SafeCredentialReference?newRef = SafeCredentialReference.CreateReference(newHandle);
                if (newRef == null)
                {
                    return;
                }

                int index = Interlocked.Increment(ref s_current) & c_MaxCacheSize;
#pragma warning disable CS8601 // Possible null reference assignment.
                newRef = Interlocked.Exchange <SafeCredentialReference>(ref s_cacheSlots[index], newRef);
#pragma warning restore CS8601 // Possible null reference assignment.

                newRef?.Dispose();
            }
            catch (Exception e)
            {
                if (NetEventSource.Log.IsEnabled() && !ExceptionCheck.IsFatal(e))
                {
                    NetEventSource.Error(null, $"Attempted to throw: {e}");
                }
            }
        }
Exemplo n.º 3
0
        //
        // The app is calling this method after starting an SSL handshake.
        //
        // ATTN: The thumbPrint must be from inspected and possibly cloned user Cert object or we get a security hole in SslCredKey ctor.
        //
        internal static void CacheCredential(SafeFreeCredentials creds, byte[]?thumbPrint, SslProtocols sslProtocols, bool isServer, EncryptionPolicy encryptionPolicy, bool sendTrustList = false)
        {
            Debug.Assert(creds != null, "creds == null");

            if (creds.IsInvalid)
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Info(null, $"Refused to cache an Invalid Handle {creds}, Current Cache Count = {s_cachedCreds.Count}");
                }
                return;
            }

            SslCredKey key = new SslCredKey(thumbPrint, (int)sslProtocols, isServer, encryptionPolicy, sendTrustList);

            SafeFreeCredentials?credentials = GetCachedCredential(key);

            DateTime utcNow = DateTime.UtcNow;

            if (credentials == null || credentials.IsClosed || credentials.IsInvalid || credentials.Expiry < utcNow)
            {
                lock (s_cachedCreds)
                {
                    credentials = GetCachedCredential(key);
                    if (credentials == null || credentials.IsClosed || credentials.IsInvalid || credentials.Expiry < utcNow)
                    {
                        SafeCredentialReference?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;
                        if (NetEventSource.Log.IsEnabled())
                        {
                            NetEventSource.Info(null, $"Caching New Handle = {creds}, Current Cache Count = {s_cachedCreds.Count}");
                        }

                        ShrinkCredentialCache();
                    }
                    else
                    {
                        if (NetEventSource.Log.IsEnabled())
                        {
                            NetEventSource.Info(null, $"CacheCredential() (locked retry) Found already cached Handle = {credentials}");
                        }
                    }
                }
            }
            else
            {
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Info(null, $"CacheCredential() Ignoring incoming handle = {creds} since found already cached Handle = {credentials}");
                }
            }
Exemplo n.º 4
0
            static void ShrinkCredentialCache()
            {
                //
                // 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.
                //
                //    We won't shrink cache in the case when NO new handles are coming to it.
                //
                if ((s_cachedCreds.Count % CheckExpiredModulo) == 0)
                {
                    KeyValuePair <SslCredKey, SafeCredentialReference>[] toRemoveAttempt = s_cachedCreds.ToArray();

                    for (int i = 0; i < toRemoveAttempt.Length; ++i)
                    {
                        SafeCredentialReference?cahced = toRemoveAttempt[i].Value;
                        SafeFreeCredentials?    creds  = cahced.Target;

                        if (creds == null)
                        {
                            s_cachedCreds.TryRemove(toRemoveAttempt[i].Key, out _);
                            continue;
                        }

                        cahced.Dispose();
                        cahced = SafeCredentialReference.CreateReference(creds);
                        if (cahced != null)
                        {
                            s_cachedCreds[toRemoveAttempt[i].Key] = cahced;
                        }
                        else
                        {
                            s_cachedCreds.TryRemove(toRemoveAttempt[i].Key, out _);
                        }
                    }
                    if (NetEventSource.Log.IsEnabled())
                    {
                        NetEventSource.Info(null, $"Scavenged cache, New Cache Count = {s_cachedCreds.Count}");
                    }
                }
            }