diff --git a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs index 48019c3d86b8e4..10e475e78acfe5 100644 --- a/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs +++ b/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.OpenSsl.cs @@ -349,7 +349,7 @@ internal static void UpdateClientCertificate(SafeSslHandle ssl, SslAuthenticatio internal static SafeSslHandle AllocateSslHandle(SslAuthenticationOptions sslAuthenticationOptions) { SafeSslHandle? sslHandle = null; - bool cacheSslContext = sslAuthenticationOptions.AllowTlsResume && !SslStream.DisableTlsResume && sslAuthenticationOptions.EncryptionPolicy == EncryptionPolicy.RequireEncryption && sslAuthenticationOptions.CipherSuitesPolicy == null; + bool cacheSslContext = sslAuthenticationOptions.AllowTlsResume && !LocalAppContextSwitches.DisableTlsResume && sslAuthenticationOptions.EncryptionPolicy == EncryptionPolicy.RequireEncryption && sslAuthenticationOptions.CipherSuitesPolicy == null; if (cacheSslContext) { diff --git a/src/libraries/Common/src/System/AppContextSwitchHelper.cs b/src/libraries/Common/src/System/AppContextSwitchHelper.cs deleted file mode 100644 index e2607ca66eb3e8..00000000000000 --- a/src/libraries/Common/src/System/AppContextSwitchHelper.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Globalization; - -namespace System -{ - internal static class AppContextSwitchHelper - { - internal static bool GetBooleanConfig(string switchName, bool defaultValue = false) => - AppContext.TryGetSwitch(switchName, out bool value) ? value : defaultValue; - - internal static bool GetBooleanConfig(string switchName, string envVariable, bool defaultValue = false) - { - if (AppContext.TryGetSwitch(switchName, out bool value)) - { - return value; - } - - if (Environment.GetEnvironmentVariable(envVariable) is string str) - { - if (str == "1" || string.Equals(str, bool.TrueString, StringComparison.OrdinalIgnoreCase)) - { - return true; - } - if (str == "0" || string.Equals(str, bool.FalseString, StringComparison.OrdinalIgnoreCase)) - { - return false; - } - } - - return defaultValue; - } - } -} diff --git a/src/libraries/Common/src/System/LocalAppContextSwitches.Common.cs b/src/libraries/Common/src/System/LocalAppContextSwitches.Common.cs index 19806ceee1c79d..5e8e359d5a202c 100644 --- a/src/libraries/Common/src/System/LocalAppContextSwitches.Common.cs +++ b/src/libraries/Common/src/System/LocalAppContextSwitches.Common.cs @@ -16,21 +16,34 @@ internal static bool GetSwitchValue(string switchName, ref bool switchValue) => // Returns value of given switch using provided cache. [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static bool GetCachedSwitchValue(string switchName, ref int cachedSwitchValue) + internal static bool GetCachedSwitchValue(string switchName, ref int cachedSwitchValue, bool defaultValue = false) { // The cached switch value has 3 states: 0 - unknown, 1 - true, -1 - false if (cachedSwitchValue < 0) return false; if (cachedSwitchValue > 0) return true; - return GetCachedSwitchValueInternal(switchName, ref cachedSwitchValue); + return GetCachedSwitchValueInternal(switchName, null, ref cachedSwitchValue, defaultValue); } - private static bool GetCachedSwitchValueInternal(string switchName, ref int cachedSwitchValue) + // Returns value of given switch or environment variable using provided cache. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static bool GetCachedSwitchValue(string switchName, string? envVariable, ref int cachedSwitchValue, bool defaultValue = false) + { + // The cached switch value has 3 states: 0 - unknown, 1 - true, -1 - false + if (cachedSwitchValue < 0) return false; + if (cachedSwitchValue > 0) return true; + + return GetCachedSwitchValueInternal(switchName, envVariable, ref cachedSwitchValue, defaultValue); + } + + private static bool GetCachedSwitchValueInternal(string switchName, string? envVariable, ref int cachedSwitchValue, bool defaultValue) { - bool hasSwitch = AppContext.TryGetSwitch(switchName, out bool isSwitchEnabled); - if (!hasSwitch) + if (!AppContext.TryGetSwitch(switchName, out bool isSwitchEnabled)) { - isSwitchEnabled = GetSwitchDefaultValue(switchName); + if (envVariable == null || !TryGetBooleanEnvironmentVariable(envVariable, out isSwitchEnabled)) + { + isSwitchEnabled = defaultValue; + } } AppContext.TryGetSwitch("TestSwitch.LocalAppContext.DisableCaching", out bool disableCaching); @@ -42,24 +55,16 @@ private static bool GetCachedSwitchValueInternal(string switchName, ref int cach return isSwitchEnabled; } - // Provides default values for switches if they're not always false by default - private static bool GetSwitchDefaultValue(string switchName) + private static bool TryGetBooleanEnvironmentVariable(string envVariable, out bool value) { - if (switchName == "Switch.System.Runtime.Serialization.SerializationGuard") + if (Environment.GetEnvironmentVariable(envVariable) is string str) { - return true; - } + value = str == "1" || string.Equals(str, bool.TrueString, StringComparison.OrdinalIgnoreCase); - if (switchName == "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization") - { - return true; - } - - if (switchName == "System.Xml.XmlResolver.IsNetworkingEnabledByDefault") - { return true; } + value = false; return false; } } diff --git a/src/libraries/Common/src/System/Net/LocalAppContextSwitches.Net.cs b/src/libraries/Common/src/System/Net/LocalAppContextSwitches.Net.cs new file mode 100644 index 00000000000000..9cf4aba316a059 --- /dev/null +++ b/src/libraries/Common/src/System/Net/LocalAppContextSwitches.Net.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +namespace System +{ + internal static partial class LocalAppContextSwitches + { + private static int s_disableIPv6; + internal static bool DisableIPv6 + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.DisableIPv6", "DOTNET_SYSTEM_NET_DISABLEIPV6", ref s_disableIPv6); + } + + private static int s_enableSslKeyLogging; + internal static bool EnableSslKeyLogging + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#if DEBUG + get => GetCachedSwitchValue("System.Net.EnableSslKeyLogging", ref s_enableSslKeyLogging, defaultValue: true); +#else + get => GetCachedSwitchValue("System.Net.EnableSslKeyLogging", ref s_enableSslKeyLogging); +#endif + } + } +} diff --git a/src/libraries/Common/src/System/Net/Security/SslKeyLogger.cs b/src/libraries/Common/src/System/Net/Security/SslKeyLogger.cs index c0f426f082e5bb..aa7885420c9ef8 100644 --- a/src/libraries/Common/src/System/Net/Security/SslKeyLogger.cs +++ b/src/libraries/Common/src/System/Net/Security/SslKeyLogger.cs @@ -18,11 +18,7 @@ static SslKeyLogger() try { -#if DEBUG - bool isEnabled = true; -#else - bool isEnabled = AppContext.TryGetSwitch("System.Net.EnableSslKeyLogging", out bool enabled) && enabled; -#endif + bool isEnabled = LocalAppContextSwitches.EnableSslKeyLogging; if (isEnabled && s_keyLogFile != null) { diff --git a/src/libraries/Common/src/System/Net/SocketProtocolSupportPal.cs b/src/libraries/Common/src/System/Net/SocketProtocolSupportPal.cs index a61f47a0fa458d..6f2e307d5bece7 100644 --- a/src/libraries/Common/src/System/Net/SocketProtocolSupportPal.cs +++ b/src/libraries/Common/src/System/Net/SocketProtocolSupportPal.cs @@ -7,30 +7,8 @@ namespace System.Net { internal static partial class SocketProtocolSupportPal { - private const string DisableIPv6AppCtxSwitch = "System.Net.DisableIPv6"; - private const string DisableIPv6EnvironmentVariable = "DOTNET_SYSTEM_NET_DISABLEIPV6"; - - public static bool OSSupportsIPv6 { get; } = IsSupported(AddressFamily.InterNetworkV6) && !IsIPv6Disabled(); + public static bool OSSupportsIPv6 { get; } = IsSupported(AddressFamily.InterNetworkV6) && !LocalAppContextSwitches.DisableIPv6; public static bool OSSupportsIPv4 { get; } = IsSupported(AddressFamily.InterNetwork); public static bool OSSupportsUnixDomainSockets { get; } = IsSupported(AddressFamily.Unix); - - private static bool IsIPv6Disabled() - { - // First check for the AppContext switch, giving it priority over the environment variable. - if (AppContext.TryGetSwitch(DisableIPv6AppCtxSwitch, out bool disabled)) - { - return disabled; - } - - // AppContext switch wasn't used. Check the environment variable. - string? envVar = Environment.GetEnvironmentVariable(DisableIPv6EnvironmentVariable); - - if (envVar is not null) - { - return envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase); - } - - return false; - } } } diff --git a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj index 2cba1a88684d98..7e6af9f6b954f9 100644 --- a/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj +++ b/src/libraries/System.Net.Http.WinHttpHandler/src/System.Net.Http.WinHttpHandler.csproj @@ -96,8 +96,6 @@ System.Net.Http.WinHttpHandler - - - + + diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/LocalAppContextSwitches.cs b/src/libraries/System.Net.Http/src/System/Net/Http/LocalAppContextSwitches.cs new file mode 100644 index 00000000000000..558d63d6d1576a --- /dev/null +++ b/src/libraries/System.Net.Http/src/System/Net/Http/LocalAppContextSwitches.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +namespace System +{ + internal static partial class LocalAppContextSwitches + { + private static int s_usePortInSpn; + internal static bool UsePortInSpn + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.Http.UsePortInSpn", "DOTNET_SYSTEM_NET_HTTP_USEPORTINSPN", ref s_usePortInSpn); + } + } +} diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs index 85a530d2056d0f..430b9ced95d912 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/AuthenticationHelper.NtAuth.cs @@ -16,37 +16,7 @@ namespace System.Net.Http { internal static partial class AuthenticationHelper { - private const string UsePortInSpnCtxSwitch = "System.Net.Http.UsePortInSpn"; - private const string UsePortInSpnEnvironmentVariable = "DOTNET_SYSTEM_NET_HTTP_USEPORTINSPN"; - - private static NullableBool s_usePortInSpn; - - private static bool UsePortInSpn - { - get - { - NullableBool usePortInSpn = s_usePortInSpn; - if (usePortInSpn != NullableBool.Undefined) - { - return usePortInSpn == NullableBool.True; - } - - // First check for the AppContext switch, giving it priority over the environment variable. - if (AppContext.TryGetSwitch(UsePortInSpnCtxSwitch, out bool value)) - { - s_usePortInSpn = value ? NullableBool.True : NullableBool.False; - } - else - { - // AppContext switch wasn't used. Check the environment variable. - s_usePortInSpn = - Environment.GetEnvironmentVariable(UsePortInSpnEnvironmentVariable) is string envVar && - (envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? NullableBool.True : NullableBool.False; - } - - return s_usePortInSpn == NullableBool.True; - } - } + private static bool UsePortInSpn => LocalAppContextSwitches.UsePortInSpn; private static Task InnerSendAsync(HttpRequestMessage request, bool async, bool isProxyAuth, HttpConnectionPool pool, HttpConnection connection, CancellationToken cancellationToken) { diff --git a/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj b/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj index 5f7c136659e1bf..ab89dc2b72b245 100644 --- a/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj +++ b/src/libraries/System.Net.HttpListener/src/System.Net.HttpListener.csproj @@ -34,8 +34,11 @@ + + GetCachedSwitchValue("System.Net.HttpListener.EnableKernelResponseBuffering", ref s_enableKernelResponseBuffering); + } + } +} diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs index fca60206bedfe9..2c81f36f010c76 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Windows/HttpListener.Windows.cs @@ -36,7 +36,7 @@ public sealed unsafe partial class HttpListener // no more than one outstanding write at a time, and can significantly improve throughput over high-latency connections. // Applications that use asynchronous I/O and that may have more than one send outstanding at a time should not use this flag. // Enabling this can result in higher CPU and memory usage by Http.sys. - internal static bool EnableKernelResponseBuffering { get; } = AppContext.TryGetSwitch("System.Net.HttpListener.EnableKernelResponseBuffering", out bool enabled) && enabled; + internal static bool EnableKernelResponseBuffering => LocalAppContextSwitches.EnableKernelResponseBuffering; // Mitigate potential DOS attacks by limiting the number of unknown headers we accept. Numerous header names // with hash collisions will cause the server to consume excess CPU. 1000 headers limits CPU time to under diff --git a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj index 9661bd2b07d0e0..47439bf44a3f63 100644 --- a/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj +++ b/src/libraries/System.Net.NameResolution/src/System.Net.NameResolution.csproj @@ -24,6 +24,10 @@ Link="Common\System\Net\Logging\NetEventSource.Common.cs" /> + + diff --git a/src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj b/src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj index 378012a38768ca..05e55180110b81 100644 --- a/src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj +++ b/src/libraries/System.Net.NameResolution/tests/PalTests/System.Net.NameResolution.Pal.Tests.csproj @@ -29,6 +29,10 @@ Link="Common\System\Net\IPEndPointStatics.cs" /> + + + + diff --git a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj index 084eb74b3dda48..50097783501999 100644 --- a/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj +++ b/src/libraries/System.Net.Quic/src/System.Net.Quic.csproj @@ -22,7 +22,8 @@ - + + diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs index d893c9a0c5e569..bd6f8283a90ff1 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs @@ -281,6 +281,5 @@ private static bool IsTls13Disabled(bool isServer) return false; } - private static bool ShouldUseAppLocalMsQuic() => AppContextSwitchHelper.GetBooleanConfig( - "System.Net.Quic.AppLocalMsQuic"); + private static bool ShouldUseAppLocalMsQuic() => LocalAppContextSwitches.AppLocalMsQuic; } diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.Cache.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.Cache.cs index 4e06f6c6b0bd1e..823569f2a72bc6 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.Cache.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicConfiguration.Cache.cs @@ -16,9 +16,7 @@ namespace System.Net.Quic; internal static partial class MsQuicConfiguration { - internal static bool ConfigurationCacheEnabled { get; } = !AppContextSwitchHelper.GetBooleanConfig( - "System.Net.Quic.DisableConfigurationCache", - "DOTNET_SYSTEM_NET_QUIC_DISABLE_CONFIGURATION_CACHE"); + internal static bool ConfigurationCacheEnabled => !LocalAppContextSwitches.DisableConfigurationCache; private static readonly MsQuicConfigurationCache s_configurationCache = new MsQuicConfigurationCache(); diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/LocalAppContextSwitches.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/LocalAppContextSwitches.cs new file mode 100644 index 00000000000000..1b44c84b5230b9 --- /dev/null +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/LocalAppContextSwitches.cs @@ -0,0 +1,24 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; + +namespace System +{ + internal static partial class LocalAppContextSwitches + { + private static int s_disableConfigurationCache; + internal static bool DisableConfigurationCache + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.Quic.DisableConfigurationCache", "DOTNET_SYSTEM_NET_QUIC_DISABLE_CONFIGURATION_CACHE", ref s_disableConfigurationCache); + } + + private static int s_appLocalMsQuic; + internal static bool AppLocalMsQuic + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.Quic.AppLocalMsQuic", ref s_appLocalMsQuic); + } + } +} diff --git a/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 61d4b05c9aae6b..1b208fca00a699 100644 --- a/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -30,8 +30,10 @@ Link="Common\System\Obsoletions.cs" /> - + + @@ -51,6 +53,7 @@ + @@ -115,8 +118,6 @@ Link="Common\System\Net\NegotiationInfoClass.cs" /> - diff --git a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs index 5490cc86ef8a04..475483944f84a3 100644 --- a/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs +++ b/src/libraries/System.Net.Security/src/System/Net/NegotiateAuthenticationPal.Unix.cs @@ -22,16 +22,9 @@ internal partial class NegotiateAuthenticationPal private static readonly Lazy _hasSystemNetSecurityNative = new Lazy(CheckHasSystemNetSecurityNative); internal static bool HasSystemNetSecurityNative => _hasSystemNetSecurityNative.Value; - [FeatureSwitchDefinition("System.Net.Security.UseManagedNtlm")] - private static bool UseManagedNtlm { get; } = - AppContext.TryGetSwitch("System.Net.Security.UseManagedNtlm", out bool useManagedNtlm) ? - useManagedNtlm : - OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() || OperatingSystem.IsMacCatalyst() || - (OperatingSystem.IsLinux() && RuntimeInformation.RuntimeIdentifier.StartsWith("linux-bionic-", StringComparison.OrdinalIgnoreCase)); - public static NegotiateAuthenticationPal Create(NegotiateAuthenticationClientOptions clientOptions) { - if (UseManagedNtlm) + if (LocalAppContextSwitches.UseManagedNtlm) { switch (clientOptions.Package) { diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/LocalAppContextSwitches.cs b/src/libraries/System.Net.Security/src/System/Net/Security/LocalAppContextSwitches.cs new file mode 100644 index 00000000000000..369ece8ca60d0e --- /dev/null +++ b/src/libraries/System.Net.Security/src/System/Net/Security/LocalAppContextSwitches.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics.CodeAnalysis; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System +{ + internal static partial class LocalAppContextSwitches + { + private static int s_disableTlsResume; + internal static bool DisableTlsResume + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.Security.DisableTlsResume", "DOTNET_SYSTEM_NET_SECURITY_DISABLETLSRESUME", ref s_disableTlsResume); + } + + private static int s_enableServerAiaDownloads; + internal static bool EnableServerAiaDownloads + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.Security.EnableServerAiaDownloads", "DOTNET_SYSTEM_NET_SECURITY_ENABLESERVERAIADOWNLOADS", ref s_enableServerAiaDownloads); + } + + private static int s_enableOcspStapling; + internal static bool EnableOcspStapling + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.Security.EnableServerOcspStaplingFromOnlyCertificateOnLinux", ref s_enableOcspStapling); + } + +#if !TARGET_WINDOWS + private static int s_useManagedNtlm; + [FeatureSwitchDefinition("System.Net.Security.UseManagedNtlm")] + internal static bool UseManagedNtlm + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.Security.UseManagedNtlm", ref s_useManagedNtlm, + defaultValue: OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() || OperatingSystem.IsMacCatalyst() || + (OperatingSystem.IsLinux() && RuntimeInformation.RuntimeIdentifier.StartsWith("linux-bionic-", StringComparison.OrdinalIgnoreCase))); + } +#endif + +#if TARGET_APPLE + private static int s_useNetworkFramework; + internal static bool UseNetworkFramework + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => GetCachedSwitchValue("System.Net.Security.UseNetworkFramework", "DOTNET_SYSTEM_NET_SECURITY_USENETWORKFRAMEWORK", ref s_useNetworkFramework); + } +#endif + } +} diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteNwContext.cs b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteNwContext.cs index 506d118cb8b5f9..88c5e5346c8a8a 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteNwContext.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/Pal.OSX/SafeDeleteNwContext.cs @@ -32,9 +32,7 @@ namespace System.Net.Security internal sealed class SafeDeleteNwContext : SafeDeleteContext { // AppContext switch to enable Network Framework usage - internal static bool IsSwitchEnabled { get; } = AppContextSwitchHelper.GetBooleanConfig( - "System.Net.Security.UseNetworkFramework", - "DOTNET_SYSTEM_NET_SECURITY_USENETWORKFRAMEWORK"); + internal static bool IsSwitchEnabled => LocalAppContextSwitches.UseNetworkFramework; private static readonly Lazy s_isNetworkFrameworkAvailable = new Lazy(CheckNetworkFrameworkAvailability); private const int InitialReceiveBufferSize = 2 * 1024; diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs index c3a78a098584f5..10dfef558f0441 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslAuthenticationOptions.cs @@ -11,7 +11,6 @@ namespace System.Net.Security { internal sealed class SslAuthenticationOptions : IDisposable { - private const string EnableOcspStaplingContextSwitchName = "System.Net.Security.EnableServerOcspStaplingFromOnlyCertificateOnLinux"; internal const X509RevocationMode DefaultRevocationMode = X509RevocationMode.NoCheck; @@ -146,8 +145,7 @@ internal void UpdateOptions(SslServerAuthenticationOptions sslServerAuthenticati if (certificateWithKey != null && certificateWithKey.HasPrivateKey) { - bool ocspFetch = false; - _ = AppContext.TryGetSwitch(EnableOcspStaplingContextSwitchName, out ocspFetch); + bool ocspFetch = LocalAppContextSwitches.EnableOcspStapling; // given cert is X509Certificate2 with key. We can use it directly. SetCertificateContextFromCert(certificateWithKey, !ocspFetch); } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs index 29bd3092b2bf2a..c13bf7aa85d4fa 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStream.Protocol.cs @@ -16,67 +16,6 @@ namespace System.Net.Security { public partial class SslStream { - private const string DisableTlsResumeCtxSwitch = "System.Net.Security.DisableTlsResume"; - private const string DisableTlsResumeEnvironmentVariable = "DOTNET_SYSTEM_NET_SECURITY_DISABLETLSRESUME"; - private const string EnableServerAiaDownloadsCtxSwitch = "System.Net.Security.EnableServerAiaDownloads"; - private const string EnableServerAiaDownloadsEnvironmentVariable = "DOTNET_SYSTEM_NET_SECURITY_ENABLESERVERAIADOWNLOADS"; - - private static volatile NullableBool s_disableTlsResume; - private static volatile NullableBool s_enableServerAiaDownloads; - - internal static bool DisableTlsResume - { - get - { - NullableBool disableTlsResume = s_disableTlsResume; - if (disableTlsResume != NullableBool.Undefined) - { - return disableTlsResume == NullableBool.True; - } - - // First check for the AppContext switch, giving it priority over the environment variable. - if (AppContext.TryGetSwitch(DisableTlsResumeCtxSwitch, out bool value)) - { - s_disableTlsResume = value ? NullableBool.True : NullableBool.False; - } - else - { - // AppContext switch wasn't used. Check the environment variable. - s_disableTlsResume = - Environment.GetEnvironmentVariable(DisableTlsResumeEnvironmentVariable) is string envVar && - (envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? NullableBool.True : NullableBool.False; - } - - return s_disableTlsResume == NullableBool.True; - } - } - - internal static bool EnableServerAiaDownloads - { - get - { - NullableBool enableServerAiaDownloads = s_enableServerAiaDownloads; - if (enableServerAiaDownloads != NullableBool.Undefined) - { - return enableServerAiaDownloads == NullableBool.True; - } - - // First check for the AppContext switch, giving it priority over the environment variable. - if (AppContext.TryGetSwitch(EnableServerAiaDownloadsCtxSwitch, out bool value)) - { - s_enableServerAiaDownloads = value ? NullableBool.True : NullableBool.False; - } - else - { - // AppContext switch wasn't used. Check the environment variable. - s_enableServerAiaDownloads = - Environment.GetEnvironmentVariable(EnableServerAiaDownloadsEnvironmentVariable) is string envVar && - (envVar == "1" || envVar.Equals("true", StringComparison.OrdinalIgnoreCase)) ? NullableBool.True : NullableBool.False; - } - - return s_enableServerAiaDownloads == NullableBool.True; - } - } private SafeFreeCredentials? _credentialsHandle; @@ -1117,7 +1056,7 @@ internal bool VerifyRemoteCertificate(RemoteCertificateValidationCallback? remot chain.ChainPolicy.RevocationMode = _sslAuthenticationOptions.CertificateRevocationCheckMode; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot; - if (_sslAuthenticationOptions.IsServer && !EnableServerAiaDownloads) + if (_sslAuthenticationOptions.IsServer && !LocalAppContextSwitches.EnableServerAiaDownloads) { chain.ChainPolicy.DisableCertificateDownloads = true; } diff --git a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs index 3bdb83666d4c61..aecaa2feca9e07 100644 --- a/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs +++ b/src/libraries/System.Net.Security/src/System/Net/Security/SslStreamPal.Windows.cs @@ -195,7 +195,7 @@ public static ProtocolToken InitializeSecurityContext( consumed -= inputBuffers._item1.Token.Length; } - bool allowTlsResume = sslAuthenticationOptions.AllowTlsResume && !SslStream.DisableTlsResume; + bool allowTlsResume = sslAuthenticationOptions.AllowTlsResume && !LocalAppContextSwitches.DisableTlsResume; if (!allowTlsResume && newContext && context != null) { @@ -299,7 +299,7 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchannelCred(Ss Interop.SspiCli.SCHANNEL_CRED.Flags flags; Interop.SspiCli.CredentialUse direction; - bool allowTlsResume = authOptions.AllowTlsResume && !SslStream.DisableTlsResume; + bool allowTlsResume = authOptions.AllowTlsResume && !LocalAppContextSwitches.DisableTlsResume; if (!isServer) { @@ -374,7 +374,7 @@ public static unsafe SafeFreeCredentials AcquireCredentialsHandleSchCredentials( Interop.SspiCli.SCH_CREDENTIALS.Flags flags; Interop.SspiCli.CredentialUse direction; - bool allowTlsResume = authOptions.AllowTlsResume && !SslStream.DisableTlsResume; + bool allowTlsResume = authOptions.AllowTlsResume && !LocalAppContextSwitches.DisableTlsResume; if (isServer) { diff --git a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj index 42381dbab6c6b8..1fe85f24b858ee 100644 --- a/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj +++ b/src/libraries/System.Net.Security/tests/UnitTests/System.Net.Security.Unit.Tests.csproj @@ -34,8 +34,12 @@ - + + + + + GetCachedSwitchValue("Switch.System.Runtime.Serialization.SerializationGuard", ref s_serializationGuard); + get => GetCachedSwitchValue("Switch.System.Runtime.Serialization.SerializationGuard", ref s_serializationGuard, defaultValue: true); } private static int s_showILOffset; diff --git a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs index 13850120d21055..b41f05be289cce 100644 --- a/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs +++ b/src/libraries/System.Private.Xml/src/System/Xml/Core/LocalAppContextSwitches.cs @@ -76,7 +76,7 @@ public static bool IsNetworkingEnabledByDefault [MethodImpl(MethodImplOptions.AggressiveInlining)] get { - return SwitchesHelpers.GetCachedSwitchValue("System.Xml.XmlResolver.IsNetworkingEnabledByDefault", ref s_isNetworkingEnabledByDefault); + return SwitchesHelpers.GetCachedSwitchValue("System.Xml.XmlResolver.IsNetworkingEnabledByDefault", ref s_isNetworkingEnabledByDefault, defaultValue: true); } } diff --git a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/LocalAppContextSwitches.cs b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/LocalAppContextSwitches.cs index 169eb991b71d9c..7618044581e1fe 100644 --- a/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/LocalAppContextSwitches.cs +++ b/src/libraries/System.Runtime.Serialization.Formatters/src/System/Runtime/Serialization/LocalAppContextSwitches.cs @@ -13,7 +13,7 @@ internal static partial class LocalAppContextSwitches public static bool BinaryFormatterEnabled { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => GetCachedSwitchValue("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", ref s_binaryFormatterEnabled); + get => GetCachedSwitchValue("System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization", ref s_binaryFormatterEnabled, defaultValue: true); } } }