You've already forked linux-packaging-mono
Imported Upstream version 4.8.0.309
Former-commit-id: 5f9c6ae75f295e057a7d2971f3a6df4656fa8850
This commit is contained in:
parent
ee1447783b
commit
94b2861243
@@ -15,10 +15,9 @@ namespace System.Data.SqlClient
|
||||
/// Base class containing raw key bytes for symmetric key algorithms. Some encryption algorithms can use the key directly while others derive sub keys from this.
|
||||
/// If an algorithm needs to derive more keys, have a derived class from this and use it in the corresponding encryption algorithm.
|
||||
/// </summary>
|
||||
internal class SqlClientSymmetricKey
|
||||
{
|
||||
internal class SqlClientSymmetricKey {
|
||||
/// <summary>
|
||||
/// DPAPI protected key
|
||||
/// The underlying key material
|
||||
/// </summary>
|
||||
protected readonly byte[] _rootKey;
|
||||
|
||||
@@ -26,8 +25,7 @@ namespace System.Data.SqlClient
|
||||
/// Constructor that initializes the root key.
|
||||
/// </summary>
|
||||
/// <param name="rootKey">root key</param>
|
||||
internal SqlClientSymmetricKey(byte[] rootKey)
|
||||
{
|
||||
internal SqlClientSymmetricKey(byte[] rootKey) {
|
||||
// Key validation
|
||||
if (rootKey == null || rootKey.Length == 0) {
|
||||
throw SQL.NullColumnEncryptionKeySysErr();
|
||||
@@ -36,14 +34,24 @@ namespace System.Data.SqlClient
|
||||
_rootKey = rootKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destructor that cleans up the key material.
|
||||
/// This is a best effort approach since there are no guarantees around GC.
|
||||
/// </summary>
|
||||
~SqlClientSymmetricKey() {
|
||||
if (_rootKey != null) {
|
||||
for (int i = 0; i < _rootKey.Length; i++) {
|
||||
_rootKey[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a copy of the plain text key
|
||||
/// This is needed for actual encryption/decryption.
|
||||
/// </summary>
|
||||
internal virtual byte[] RootKey
|
||||
{
|
||||
get
|
||||
{
|
||||
internal virtual byte[] RootKey {
|
||||
get {
|
||||
return _rootKey;
|
||||
}
|
||||
}
|
||||
@@ -52,8 +60,7 @@ namespace System.Data.SqlClient
|
||||
/// Computes SHA256 value of the plain text key bytes
|
||||
/// </summary>
|
||||
/// <returns>A string containing SHA256 hash of the root key</returns>
|
||||
internal virtual string GetKeyHash()
|
||||
{
|
||||
internal virtual string GetKeyHash() {
|
||||
return SqlSecurityUtility.GetSHA256Hash(RootKey);
|
||||
}
|
||||
|
||||
@@ -63,10 +70,7 @@ namespace System.Data.SqlClient
|
||||
/// <returns>
|
||||
/// Returns the length of the root key
|
||||
/// </returns>
|
||||
internal virtual int Length()
|
||||
{
|
||||
// Note: DPAPI preserves the original byte length
|
||||
// so for now, this is as same as returning the length of the raw key.
|
||||
internal virtual int Length() {
|
||||
return _rootKey.Length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1 +1 @@
|
||||
2e560dbf344a2a5ef4577863f3342dc13d2498de
|
||||
46a53537089cdd872b7c8964bfc4fc8718f9c782
|
||||
@@ -1 +1 @@
|
||||
0ce4dbb08763054308721ed6139b428134b0cb54
|
||||
306a42079800e4f74776c8f8f967a9df88f0c8f5
|
||||
@@ -30,6 +30,7 @@ namespace System.Data.SqlClient {
|
||||
internal const string Application_Name = TdsEnums.SQL_PROVIDER_NAME;
|
||||
internal const bool Asynchronous = false;
|
||||
internal const string AttachDBFilename = "";
|
||||
internal const PoolBlockingPeriod PoolBlockingPeriod = DbConnectionStringDefaults.PoolBlockingPeriod;
|
||||
internal const int Connect_Timeout = ADP.DefaultConnectionTimeout;
|
||||
internal const bool Connection_Reset = true;
|
||||
internal const bool Context_Connection = false;
|
||||
@@ -69,6 +70,7 @@ namespace System.Data.SqlClient {
|
||||
internal const string Application_Name = "application name";
|
||||
internal const string AsynchronousProcessing = "asynchronous processing";
|
||||
internal const string AttachDBFilename = "attachdbfilename";
|
||||
internal const string PoolBlockingPeriod = "poolblockingperiod";
|
||||
internal const string ColumnEncryptionSetting = "column encryption setting";
|
||||
internal const string Connect_Timeout = "connect timeout";
|
||||
internal const string Connection_Reset = "connection reset";
|
||||
@@ -190,6 +192,7 @@ namespace System.Data.SqlClient {
|
||||
|
||||
private readonly bool _integratedSecurity;
|
||||
|
||||
private readonly PoolBlockingPeriod _poolBlockingPeriod;
|
||||
private readonly bool _connectionReset;
|
||||
private readonly bool _contextConnection;
|
||||
private readonly bool _encrypt;
|
||||
@@ -247,6 +250,7 @@ namespace System.Data.SqlClient {
|
||||
ConvertValueToBoolean(KEY.AsynchronousProcessing, DEFAULT.Asynchronous); // while we don't use it anymore, we still need to verify it is true/false
|
||||
|
||||
// SQLPT 41700: Ignore ResetConnection=False (still validate the keyword/value)
|
||||
_poolBlockingPeriod = ConvertValueToPoolBlockingPeriod();
|
||||
_connectionReset = ConvertValueToBoolean(KEY.Connection_Reset, DEFAULT.Connection_Reset);
|
||||
_contextConnection = ConvertValueToBoolean(KEY.Context_Connection, DEFAULT.Context_Connection);
|
||||
_encrypt = ConvertValueToEncrypt();
|
||||
@@ -490,6 +494,7 @@ namespace System.Data.SqlClient {
|
||||
_userInstance = userInstance;
|
||||
_connectTimeout = connectionOptions._connectTimeout;
|
||||
_loadBalanceTimeout = connectionOptions._loadBalanceTimeout;
|
||||
_poolBlockingPeriod = connectionOptions._poolBlockingPeriod;
|
||||
_maxPoolSize = connectionOptions._maxPoolSize;
|
||||
_minPoolSize = connectionOptions._minPoolSize;
|
||||
_multiSubnetFailover = connectionOptions._multiSubnetFailover;
|
||||
@@ -525,6 +530,8 @@ namespace System.Data.SqlClient {
|
||||
// will work. In the future we can deprecate the keyword entirely.
|
||||
internal bool Asynchronous { get { return true; } }
|
||||
|
||||
internal PoolBlockingPeriod PoolBlockingPeriod { get { return _poolBlockingPeriod; } }
|
||||
|
||||
// SQLPT 41700: Ignore ResetConnection=False, always reset the connection for security
|
||||
internal bool ConnectionReset { get { return true; } }
|
||||
internal bool ContextConnection { get { return _contextConnection; } }
|
||||
@@ -620,6 +627,7 @@ namespace System.Data.SqlClient {
|
||||
hash.Add(KEY.Application_Name, KEY.Application_Name);
|
||||
hash.Add(KEY.AsynchronousProcessing, KEY.AsynchronousProcessing);
|
||||
hash.Add(KEY.AttachDBFilename, KEY.AttachDBFilename);
|
||||
hash.Add(KEY.PoolBlockingPeriod, KEY.PoolBlockingPeriod);
|
||||
hash.Add(KEY.Connect_Timeout, KEY.Connect_Timeout);
|
||||
hash.Add(KEY.Connection_Reset, KEY.Connection_Reset);
|
||||
hash.Add(KEY.Context_Connection, KEY.Context_Connection);
|
||||
@@ -779,6 +787,28 @@ namespace System.Data.SqlClient {
|
||||
// ArgumentException and other types are raised as is (no wrapping)
|
||||
}
|
||||
|
||||
internal System.Data.SqlClient.PoolBlockingPeriod ConvertValueToPoolBlockingPeriod()
|
||||
{
|
||||
object value = base.Parsetable[KEY.PoolBlockingPeriod];
|
||||
if (value == null)
|
||||
{
|
||||
return DEFAULT.PoolBlockingPeriod;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return DbConnectionStringBuilderUtil.ConvertToPoolBlockingPeriod(KEY.PoolBlockingPeriod, value);
|
||||
}
|
||||
catch (FormatException e)
|
||||
{
|
||||
throw ADP.InvalidConnectionOptionValue(KEY.PoolBlockingPeriod, e);
|
||||
}
|
||||
catch (OverflowException e)
|
||||
{
|
||||
throw ADP.InvalidConnectionOptionValue(KEY.PoolBlockingPeriod, e);
|
||||
}
|
||||
}
|
||||
|
||||
internal SqlAuthenticationMethod ConvertValueToAuthenticationType() {
|
||||
object value = base.Parsetable[KEY.Authentication];
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ namespace System.Data.SqlClient {
|
||||
Pooling,
|
||||
MinPoolSize,
|
||||
MaxPoolSize,
|
||||
PoolBlockingPeriod,
|
||||
|
||||
AsynchronousProcessing,
|
||||
ConnectionReset,
|
||||
@@ -127,6 +128,7 @@ namespace System.Data.SqlClient {
|
||||
private bool _userInstance = DbConnectionStringDefaults.UserInstance;
|
||||
private SqlAuthenticationMethod _authentication = DbConnectionStringDefaults.Authentication;
|
||||
private SqlConnectionColumnEncryptionSetting _columnEncryptionSetting = DbConnectionStringDefaults.ColumnEncryptionSetting;
|
||||
private PoolBlockingPeriod _poolBlockingPeriod = DbConnectionStringDefaults.PoolBlockingPeriod;
|
||||
|
||||
static SqlConnectionStringBuilder() {
|
||||
string[] validKeywords = new string[KeywordsCount];
|
||||
@@ -134,6 +136,7 @@ namespace System.Data.SqlClient {
|
||||
validKeywords[(int)Keywords.ApplicationName] = DbConnectionStringKeywords.ApplicationName;
|
||||
validKeywords[(int)Keywords.AsynchronousProcessing] = DbConnectionStringKeywords.AsynchronousProcessing;
|
||||
validKeywords[(int)Keywords.AttachDBFilename] = DbConnectionStringKeywords.AttachDBFilename;
|
||||
validKeywords[(int)Keywords.PoolBlockingPeriod] = DbConnectionStringKeywords.PoolBlockingPeriod;
|
||||
validKeywords[(int)Keywords.ConnectionReset] = DbConnectionStringKeywords.ConnectionReset;
|
||||
validKeywords[(int)Keywords.ContextConnection] = DbConnectionStringKeywords.ContextConnection;
|
||||
validKeywords[(int)Keywords.ConnectTimeout] = DbConnectionStringKeywords.ConnectTimeout;
|
||||
@@ -174,6 +177,7 @@ namespace System.Data.SqlClient {
|
||||
hash.Add(DbConnectionStringKeywords.ApplicationName, Keywords.ApplicationName);
|
||||
hash.Add(DbConnectionStringKeywords.AsynchronousProcessing, Keywords.AsynchronousProcessing);
|
||||
hash.Add(DbConnectionStringKeywords.AttachDBFilename, Keywords.AttachDBFilename);
|
||||
hash.Add(DbConnectionStringKeywords.PoolBlockingPeriod, Keywords.PoolBlockingPeriod);
|
||||
hash.Add(DbConnectionStringKeywords.ConnectTimeout, Keywords.ConnectTimeout);
|
||||
hash.Add(DbConnectionStringKeywords.ConnectionReset, Keywords.ConnectionReset);
|
||||
hash.Add(DbConnectionStringKeywords.ContextConnection, Keywords.ContextConnection);
|
||||
@@ -278,6 +282,7 @@ namespace System.Data.SqlClient {
|
||||
case Keywords.Authentication: Authentication = ConvertToAuthenticationType(keyword, value); break;
|
||||
case Keywords.ColumnEncryptionSetting: ColumnEncryptionSetting = ConvertToColumnEncryptionSetting(keyword, value); break;
|
||||
case Keywords.AsynchronousProcessing: AsynchronousProcessing = ConvertToBoolean(value); break;
|
||||
case Keywords.PoolBlockingPeriod: PoolBlockingPeriod = ConvertToPoolBlockingPeriod(keyword, value); break;
|
||||
#pragma warning disable 618 // Obsolete ConnectionReset
|
||||
case Keywords.ConnectionReset: ConnectionReset = ConvertToBoolean(value); break;
|
||||
#pragma warning restore 618
|
||||
@@ -360,6 +365,25 @@ namespace System.Data.SqlClient {
|
||||
}
|
||||
}
|
||||
|
||||
[DisplayName(DbConnectionStringKeywords.PoolBlockingPeriod)]
|
||||
[ResCategoryAttribute(Res.DataCategory_Pooling)]
|
||||
[ResDescriptionAttribute(Res.DbConnectionString_PoolBlockingPeriod)]
|
||||
[RefreshPropertiesAttribute(RefreshProperties.All)]
|
||||
public PoolBlockingPeriod PoolBlockingPeriod
|
||||
{
|
||||
get { return _poolBlockingPeriod; }
|
||||
set
|
||||
{
|
||||
if (!DbConnectionStringBuilderUtil.IsValidPoolBlockingPeriodValue(value))
|
||||
{
|
||||
throw ADP.InvalidEnumerationValue(typeof(PoolBlockingPeriod), (int)value);
|
||||
}
|
||||
|
||||
SetPoolBlockingPeriodValue(value);
|
||||
_poolBlockingPeriod = value;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false)]
|
||||
[DisplayName(DbConnectionStringKeywords.ConnectionReset)]
|
||||
[Obsolete("ConnectionReset has been deprecated. SqlConnection will ignore the 'connection reset' keyword and always reset the connection")] // SQLPT 41700
|
||||
@@ -881,6 +905,10 @@ namespace System.Data.SqlClient {
|
||||
private static SqlAuthenticationMethod ConvertToAuthenticationType(string keyword, object value) {
|
||||
return DbConnectionStringBuilderUtil.ConvertToAuthenticationType(keyword, value);
|
||||
}
|
||||
private static PoolBlockingPeriod ConvertToPoolBlockingPeriod(string keyword, object value)
|
||||
{
|
||||
return DbConnectionStringBuilderUtil.ConvertToPoolBlockingPeriod(keyword, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert to SqlConnectionColumnEncryptionSetting.
|
||||
@@ -906,6 +934,7 @@ namespace System.Data.SqlClient {
|
||||
case Keywords.ApplicationName: return ApplicationName;
|
||||
case Keywords.AsynchronousProcessing: return AsynchronousProcessing;
|
||||
case Keywords.AttachDBFilename: return AttachDBFilename;
|
||||
case Keywords.PoolBlockingPeriod: return PoolBlockingPeriod;
|
||||
case Keywords.ConnectTimeout: return ConnectTimeout;
|
||||
#pragma warning disable 618 // Obsolete ConnectionReset
|
||||
case Keywords.ConnectionReset: return ConnectionReset;
|
||||
@@ -1012,6 +1041,10 @@ namespace System.Data.SqlClient {
|
||||
case Keywords.Authentication:
|
||||
_authentication = DbConnectionStringDefaults.Authentication;
|
||||
break;
|
||||
case Keywords.PoolBlockingPeriod:
|
||||
_poolBlockingPeriod = DbConnectionStringDefaults.PoolBlockingPeriod;
|
||||
break;
|
||||
|
||||
case Keywords.ConnectTimeout:
|
||||
_connectTimeout = DbConnectionStringDefaults.ConnectTimeout;
|
||||
break;
|
||||
@@ -1128,6 +1161,11 @@ namespace System.Data.SqlClient {
|
||||
Debug.Assert(DbConnectionStringBuilderUtil.IsValidApplicationIntentValue(value), "Invalid value for ApplicationIntent");
|
||||
base[DbConnectionStringKeywords.ApplicationIntent] = DbConnectionStringBuilderUtil.ApplicationIntentToString(value);
|
||||
}
|
||||
private void SetPoolBlockingPeriodValue(PoolBlockingPeriod value)
|
||||
{
|
||||
Debug.Assert(DbConnectionStringBuilderUtil.IsValidPoolBlockingPeriodValue(value), "Invalid value for PoolBlockingPeriod");
|
||||
base[DbConnectionStringKeywords.PoolBlockingPeriod] = DbConnectionStringBuilderUtil.PoolBlockingPeriodToString(value);
|
||||
}
|
||||
private void SetAuthenticationValue(SqlAuthenticationMethod value) {
|
||||
Debug.Assert(DbConnectionStringBuilderUtil.IsValidAuthenticationTypeValue(value), "Invalid value for AuthenticationType");
|
||||
base[DbConnectionStringKeywords.Authentication] = DbConnectionStringBuilderUtil.AuthenticationTypeToString(value);
|
||||
|
||||
@@ -207,10 +207,10 @@ namespace System.Data.SqlClient
|
||||
durationString = null;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// This message is to be added only when within the various stages of a connection.
|
||||
// In all other cases, it will default to the original error message.
|
||||
if ((currentPhase != SqlConnectionTimeoutErrorPhase.Undefined) || (currentPhase != SqlConnectionTimeoutErrorPhase.Complete))
|
||||
if ((currentPhase != SqlConnectionTimeoutErrorPhase.Undefined) && (currentPhase != SqlConnectionTimeoutErrorPhase.Complete))
|
||||
{
|
||||
// NOTE: In case of a failover scenario, add a string that this failure occured as part of the primary or secondary server
|
||||
if (isFailoverScenario)
|
||||
@@ -229,13 +229,13 @@ namespace System.Data.SqlClient
|
||||
originalPhaseDurations[(int)SqlConnectionTimeoutErrorPhase.ProcessConnectionAuth].GetMilliSecondDuration(),
|
||||
originalPhaseDurations[(int)SqlConnectionTimeoutErrorPhase.PostLogin].GetMilliSecondDuration());
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: To display duration in each phase.
|
||||
if (durationString != null)
|
||||
{
|
||||
errorBuilder.Append(" ");
|
||||
errorBuilder.Append(durationString);
|
||||
}
|
||||
// NOTE: To display duration in each phase.
|
||||
if (durationString != null)
|
||||
{
|
||||
errorBuilder.Append(" ");
|
||||
errorBuilder.Append(durationString);
|
||||
}
|
||||
|
||||
return errorBuilder.ToString();
|
||||
|
||||
@@ -1 +1 @@
|
||||
c07b195ac1ba68e64a6342f0c03bbc6e4bc32456
|
||||
376909b9abd7bd6b626018dfbe5b83b5a12940c2
|
||||
@@ -99,9 +99,6 @@ namespace System.Data.SqlClient {
|
||||
}
|
||||
|
||||
set {
|
||||
Debug.Assert(_columnEncryptionCipherMetadata == null || value == null,
|
||||
"_columnEncryptionCipherMetadata should be set to a non-null value only once.");
|
||||
|
||||
_columnEncryptionCipherMetadata = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,18 +13,19 @@ namespace System.Data.SqlClient {
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.Caching;
|
||||
using System.Text;
|
||||
|
||||
/// <summary>
|
||||
/// <para> Implements a cache of Symmetric Keys (once they are decrypted).Useful for rapidly decrypting multiple data values.</para>
|
||||
/// </summary>
|
||||
sealed internal class SqlSymmetricKeyCache {
|
||||
private readonly ConcurrentDictionary<string,SqlClientSymmetricKey> _cache;
|
||||
private readonly MemoryCache _cache;
|
||||
private static readonly SqlSymmetricKeyCache _singletonInstance = new SqlSymmetricKeyCache();
|
||||
|
||||
|
||||
private SqlSymmetricKeyCache () {
|
||||
_cache = new ConcurrentDictionary<string, SqlClientSymmetricKey>(concurrencyLevel: 4 * Environment.ProcessorCount /* default value in ConcurrentDictionary*/, capacity: 2);
|
||||
_cache = new MemoryCache("ColumnEncryptionKeyCache");
|
||||
}
|
||||
|
||||
internal static SqlSymmetricKeyCache GetInstance () {
|
||||
@@ -54,10 +55,10 @@ namespace System.Data.SqlClient {
|
||||
Debug.Assert(cacheLookupKey.Length <= capacity, "We needed to allocate a larger array");
|
||||
#endif //DEBUG
|
||||
|
||||
encryptionKey = null;
|
||||
|
||||
// Lookup the key in cache
|
||||
if (!_cache.TryGetValue(cacheLookupKey, out encryptionKey)) {
|
||||
encryptionKey = _cache.Get(cacheLookupKey) as SqlClientSymmetricKey;
|
||||
|
||||
if (encryptionKey == null) {
|
||||
Debug.Assert(SqlConnection.ColumnEncryptionTrustedMasterKeyPaths != null, @"SqlConnection.ColumnEncryptionTrustedMasterKeyPaths should not be null");
|
||||
|
||||
// Check against the trusted key paths
|
||||
@@ -96,9 +97,13 @@ namespace System.Data.SqlClient {
|
||||
|
||||
encryptionKey = new SqlClientSymmetricKey (plaintextKey);
|
||||
|
||||
// In case multiple threads reach here at the same time, the first one wins.
|
||||
// The allocated memory will be reclaimed by Garbage Collector.
|
||||
_cache.TryAdd(cacheLookupKey, encryptionKey);
|
||||
// If the cache TTL is zero, don't even bother inserting to the cache.
|
||||
if (SqlConnection.ColumnEncryptionKeyCacheTtl != TimeSpan.Zero) {
|
||||
// In case multiple threads reach here at the same time, the first one wins.
|
||||
// The allocated memory will be reclaimed by Garbage Collector.
|
||||
DateTimeOffset expirationTime = DateTimeOffset.UtcNow.Add(SqlConnection.ColumnEncryptionKeyCacheTtl);
|
||||
_cache.Add(cacheLookupKey, encryptionKey, expirationTime);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -1543,7 +1543,7 @@ namespace System.Data.SqlClient {
|
||||
return Res.GetString(Res.SQL_SSPIGenerateError);
|
||||
}
|
||||
static internal string Timeout() {
|
||||
return Res.GetString(Res.SQL_Timeout);
|
||||
return Res.GetString(Res.SQL_Timeout_Execution);
|
||||
}
|
||||
static internal string Timeout_PreLogin_Begin() {
|
||||
return Res.GetString(Res.SQL_Timeout_PreLogin_Begin);
|
||||
|
||||
@@ -544,6 +544,9 @@ namespace System.Data.SqlClient {
|
||||
public const int IMPERSONATION_FAILED = 1346;
|
||||
public const int P_TOKENTOOLONG = 103;
|
||||
|
||||
// SQL error that indicates retry for Always Encrypted
|
||||
public const int TCE_CONVERSION_ERROR_CLIENT_RETRY = 33514;
|
||||
|
||||
// SNI\Win32 error values
|
||||
// NOTE: these are simply windows system error codes, not SNI specific
|
||||
public const uint SNI_UNINITIALIZED = unchecked((uint)-1);
|
||||
|
||||
Reference in New Issue
Block a user