diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj index b7a72a6d64..a2e17f592d 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft.Data.SqlClient.csproj @@ -262,6 +262,9 @@ Microsoft\Data\SqlClient\SqlConnectionPoolProviderInfo.cs + + Microsoft\Data\SqlClient\SqlConnectionString.cs + Microsoft\Data\SqlClient\SqlCredential.cs @@ -487,7 +490,6 @@ - @@ -556,7 +558,6 @@ - Microsoft\Data\SqlClient\SqlConnectionTimeoutErrorInternal.cs diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.NetCoreApp.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.NetCoreApp.cs deleted file mode 100644 index c28fcfbb9b..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.NetCoreApp.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using Microsoft.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - internal sealed partial class SqlConnectionString : DbConnectionOptions - { - } -} diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.cs deleted file mode 100644 index 598367b0a0..0000000000 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ /dev/null @@ -1,941 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Net; -using System.Net.NetworkInformation; -using System.Threading; -using Microsoft.Data.Common; - -namespace Microsoft.Data.SqlClient -{ - internal sealed partial class SqlConnectionString : DbConnectionOptions - { - // instances of this class are intended to be immutable, i.e readonly - // used by pooling classes so it is much easier to verify correctness - // when not worried about the class being modified during execution - - internal static partial class DEFAULT - { - private const string _emptyString = ""; - internal const ApplicationIntent ApplicationIntent = DbConnectionStringDefaults.ApplicationIntent; - internal const string Application_Name = TdsEnums.SQL_PROVIDER_NAME; - internal const string AttachDBFilename = _emptyString; - internal const int Command_Timeout = ADP.DefaultCommandTimeout; - internal const int Connect_Timeout = ADP.DefaultConnectionTimeout; - internal const string Current_Language = _emptyString; - internal const string Data_Source = _emptyString; - internal const bool Encrypt = true; - internal const bool Enlist = true; - internal const string FailoverPartner = _emptyString; - internal const string Initial_Catalog = _emptyString; - internal const bool Integrated_Security = false; - internal const int Load_Balance_Timeout = 0; // default of 0 means don't use - internal const bool MARS = false; - internal const int Max_Pool_Size = 100; - internal const int Min_Pool_Size = 0; - internal const bool MultiSubnetFailover = DbConnectionStringDefaults.MultiSubnetFailover; - internal const int Packet_Size = 8000; - internal const string Password = _emptyString; - internal const bool Persist_Security_Info = false; - internal const PoolBlockingPeriod PoolBlockingPeriod = DbConnectionStringDefaults.PoolBlockingPeriod; - internal const bool Pooling = true; - internal const bool TrustServerCertificate = false; - internal const string Type_System_Version = _emptyString; - internal const string User_ID = _emptyString; - internal const bool User_Instance = false; - internal const bool Replication = false; - internal const int Connect_Retry_Count = 1; - internal const int Connect_Retry_Interval = 10; - internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified; - internal const SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled; - internal const string EnclaveAttestationUrl = _emptyString; - internal static readonly SqlConnectionAttestationProtocol AttestationProtocol = SqlConnectionAttestationProtocol.NotSpecified; - internal static readonly SqlConnectionIPAddressPreference s_IPAddressPreference = SqlConnectionIPAddressPreference.IPv4First; - } - - // SqlConnection ConnectionString Options - // keys must be lowercase! - internal static class KEY - { - internal const string ApplicationIntent = "application intent"; - internal const string Application_Name = "application name"; - internal const string AttachDBFilename = "attachdbfilename"; - internal const string PoolBlockingPeriod = "pool blocking period"; - internal const string ColumnEncryptionSetting = "column encryption setting"; - internal const string EnclaveAttestationUrl = "enclave attestation url"; - internal const string AttestationProtocol = "attestation protocol"; - internal const string IPAddressPreference = "ip address preference"; - - internal const string Command_Timeout = "command timeout"; - internal const string Connect_Timeout = "connect timeout"; - internal const string Connection_Reset = "connection reset"; - internal const string Context_Connection = "context connection"; - internal const string Current_Language = "current language"; - internal const string Data_Source = "data source"; - internal const string Encrypt = "encrypt"; - internal const string Enlist = "enlist"; - internal const string FailoverPartner = "failover partner"; - internal const string Initial_Catalog = "initial catalog"; - internal const string Integrated_Security = "integrated security"; - internal const string Load_Balance_Timeout = "load balance timeout"; - internal const string MARS = "multiple active result sets"; - internal const string Max_Pool_Size = "max pool size"; - internal const string Min_Pool_Size = "min pool size"; - internal const string MultiSubnetFailover = "multi subnet failover"; - internal const string Network_Library = "network library"; - internal const string Packet_Size = "packet size"; - internal const string Password = "password"; - internal const string Persist_Security_Info = "persist security info"; - internal const string Pooling = "pooling"; - internal const string TransactionBinding = "transaction binding"; - internal const string TrustServerCertificate = "trust server certificate"; - internal const string Type_System_Version = "type system version"; - internal const string User_ID = "user id"; - internal const string User_Instance = "user instance"; - internal const string Workstation_Id = "workstation id"; - internal const string Replication = "replication"; - internal const string Connect_Retry_Count = "connect retry count"; - internal const string Connect_Retry_Interval = "connect retry interval"; - internal const string Authentication = "authentication"; - } - - // Constant for the number of duplicate options in the connection string - private static class SYNONYM - { - // ip address preference - internal const string IPADDRESSPREFERENCE = "ipaddresspreference"; - //application intent - internal const string APPLICATIONINTENT = "applicationintent"; - // application name - internal const string APP = "app"; - // attachDBFilename - internal const string EXTENDED_PROPERTIES = "extended properties"; - internal const string INITIAL_FILE_NAME = "initial file name"; - // connect timeout - internal const string CONNECTION_TIMEOUT = "connection timeout"; - internal const string TIMEOUT = "timeout"; - // current language - internal const string LANGUAGE = "language"; - // data source - internal const string ADDR = "addr"; - internal const string ADDRESS = "address"; - internal const string SERVER = "server"; - internal const string NETWORK_ADDRESS = "network address"; - // initial catalog - internal const string DATABASE = "database"; - // integrated security - internal const string TRUSTED_CONNECTION = "trusted_connection"; - //connect retry count - internal const string CONNECTRETRYCOUNT = "connectretrycount"; - //connect retry interval - internal const string CONNECTRETRYINTERVAL = "connectretryinterval"; - // load balance timeout - internal const string Connection_Lifetime = "connection lifetime"; - // multiple active result sets - internal const string MULTIPLEACTIVERESULTSETS = "multipleactiveresultsets"; - // multi subnet failover - internal const string MULTISUBNETFAILOVER = "multisubnetfailover"; - // network library - internal const string NET = "net"; - internal const string NETWORK = "network"; - // pool blocking period - internal const string POOLBLOCKINGPERIOD = "poolblockingperiod"; - // password - internal const string Pwd = "pwd"; - // persist security info - internal const string PERSISTSECURITYINFO = "persistsecurityinfo"; - // trust server certificate - internal const string TRUSTSERVERCERTIFICATE = "trustservercertificate"; - // user id - internal const string UID = "uid"; - internal const string User = "user"; - // workstation id - internal const string WSID = "wsid"; - // make sure to update SynonymCount value below when adding or removing synonyms - } - - internal const int SynonymCount = 26; - internal const int DeprecatedSynonymCount = 2; - - internal enum TypeSystem - { - Latest = 2008, - SQLServer2000 = 2000, - SQLServer2005 = 2005, - SQLServer2008 = 2008, - SQLServer2012 = 2012, - } - - internal static class TYPESYSTEMVERSION - { - internal const string Latest = "Latest"; - internal const string SQL_Server_2000 = "SQL Server 2000"; - internal const string SQL_Server_2005 = "SQL Server 2005"; - internal const string SQL_Server_2008 = "SQL Server 2008"; - internal const string SQL_Server_2012 = "SQL Server 2012"; - } - - internal enum TransactionBindingEnum - { - ImplicitUnbind, - ExplicitUnbind - } - - internal static class TRANSACTIONBINDING - { - internal const string ImplicitUnbind = "Implicit Unbind"; - internal const string ExplicitUnbind = "Explicit Unbind"; - } - - private static Dictionary s_sqlClientSynonyms; - - private readonly bool _integratedSecurity; - - private readonly bool _encrypt; - private readonly bool _trustServerCertificate; - private readonly bool _enlist; - private readonly bool _mars; - private readonly bool _persistSecurityInfo; - private readonly PoolBlockingPeriod _poolBlockingPeriod; - private readonly bool _pooling; - private readonly bool _replication; - private readonly bool _userInstance; - private readonly bool _multiSubnetFailover; - private readonly SqlAuthenticationMethod _authType; - private readonly SqlConnectionColumnEncryptionSetting _columnEncryptionSetting; - private readonly string _enclaveAttestationUrl; - private readonly SqlConnectionAttestationProtocol _attestationProtocol; - private readonly SqlConnectionIPAddressPreference _ipAddressPreference; - - private readonly int _commandTimeout; - private readonly int _connectTimeout; - private readonly int _loadBalanceTimeout; - private readonly int _maxPoolSize; - private readonly int _minPoolSize; - private readonly int _packetSize; - private readonly int _connectRetryCount; - private readonly int _connectRetryInterval; - - private readonly ApplicationIntent _applicationIntent; - private readonly string _applicationName; - private readonly string _attachDBFileName; - private readonly string _currentLanguage; - private readonly string _dataSource; - private readonly string _localDBInstance; // created based on datasource, set to NULL if datasource is not LocalDB - private readonly string _failoverPartner; - private readonly string _initialCatalog; - private readonly string _password; - private readonly string _userID; - - private readonly string _workstationId; - - private readonly TransactionBindingEnum _transactionBinding; - - private readonly TypeSystem _typeSystemVersion; - private readonly Version _typeSystemAssemblyVersion; - private static readonly Version constTypeSystemAsmVersion10 = new Version("10.0.0.0"); - private static readonly Version constTypeSystemAsmVersion11 = new Version("11.0.0.0"); - - private readonly string _expandedAttachDBFilename; // expanded during construction so that CreatePermissionSet & Expand are consistent - - internal SqlConnectionString(string connectionString) : base(connectionString, GetParseSynonyms()) - { - ThrowUnsupportedIfKeywordSet(KEY.Connection_Reset); - ThrowUnsupportedIfKeywordSet(KEY.Context_Connection); - - // Network Library has its own special error message - if (ContainsKey(KEY.Network_Library)) - { - throw SQL.NetworkLibraryKeywordNotSupported(); - } - - _integratedSecurity = ConvertValueToIntegratedSecurity(); - _poolBlockingPeriod = ConvertValueToPoolBlockingPeriod(); - _encrypt = ConvertValueToBoolean(KEY.Encrypt, DEFAULT.Encrypt); - _enlist = ConvertValueToBoolean(KEY.Enlist, DEFAULT.Enlist); - _mars = ConvertValueToBoolean(KEY.MARS, DEFAULT.MARS); - _persistSecurityInfo = ConvertValueToBoolean(KEY.Persist_Security_Info, DEFAULT.Persist_Security_Info); - _pooling = ConvertValueToBoolean(KEY.Pooling, DEFAULT.Pooling); - _replication = ConvertValueToBoolean(KEY.Replication, DEFAULT.Replication); - _userInstance = ConvertValueToBoolean(KEY.User_Instance, DEFAULT.User_Instance); - _multiSubnetFailover = ConvertValueToBoolean(KEY.MultiSubnetFailover, DEFAULT.MultiSubnetFailover); - - _commandTimeout = ConvertValueToInt32(KEY.Command_Timeout, DEFAULT.Command_Timeout); - _connectTimeout = ConvertValueToInt32(KEY.Connect_Timeout, DEFAULT.Connect_Timeout); - _loadBalanceTimeout = ConvertValueToInt32(KEY.Load_Balance_Timeout, DEFAULT.Load_Balance_Timeout); - _maxPoolSize = ConvertValueToInt32(KEY.Max_Pool_Size, DEFAULT.Max_Pool_Size); - _minPoolSize = ConvertValueToInt32(KEY.Min_Pool_Size, DEFAULT.Min_Pool_Size); - _packetSize = ConvertValueToInt32(KEY.Packet_Size, DEFAULT.Packet_Size); - _connectRetryCount = ConvertValueToInt32(KEY.Connect_Retry_Count, DEFAULT.Connect_Retry_Count); - _connectRetryInterval = ConvertValueToInt32(KEY.Connect_Retry_Interval, DEFAULT.Connect_Retry_Interval); - - _applicationIntent = ConvertValueToApplicationIntent(); - _applicationName = ConvertValueToString(KEY.Application_Name, DEFAULT.Application_Name); - _attachDBFileName = ConvertValueToString(KEY.AttachDBFilename, DEFAULT.AttachDBFilename); - _currentLanguage = ConvertValueToString(KEY.Current_Language, DEFAULT.Current_Language); - _dataSource = ConvertValueToString(KEY.Data_Source, DEFAULT.Data_Source); - _localDBInstance = LocalDBAPI.GetLocalDbInstanceNameFromServerName(_dataSource); - _failoverPartner = ConvertValueToString(KEY.FailoverPartner, DEFAULT.FailoverPartner); - _initialCatalog = ConvertValueToString(KEY.Initial_Catalog, DEFAULT.Initial_Catalog); - _password = ConvertValueToString(KEY.Password, DEFAULT.Password); - _trustServerCertificate = ConvertValueToBoolean(KEY.TrustServerCertificate, DEFAULT.TrustServerCertificate); - _authType = ConvertValueToAuthenticationType(); - _columnEncryptionSetting = ConvertValueToColumnEncryptionSetting(); - _enclaveAttestationUrl = ConvertValueToString(KEY.EnclaveAttestationUrl, DEFAULT.EnclaveAttestationUrl); - _attestationProtocol = ConvertValueToAttestationProtocol(); - _ipAddressPreference = ConvertValueToIPAddressPreference(); - - // Temporary string - this value is stored internally as an enum. - string typeSystemVersionString = ConvertValueToString(KEY.Type_System_Version, null); - string transactionBindingString = ConvertValueToString(KEY.TransactionBinding, null); - - _userID = ConvertValueToString(KEY.User_ID, DEFAULT.User_ID); - _workstationId = ConvertValueToString(KEY.Workstation_Id, null); - - if (_loadBalanceTimeout < 0) - { - throw ADP.InvalidConnectionOptionValue(KEY.Load_Balance_Timeout); - } - - if (_connectTimeout < 0) - { - throw ADP.InvalidConnectionOptionValue(KEY.Connect_Timeout); - } - - if (_commandTimeout < 0) - { - throw ADP.InvalidConnectionOptionValue(KEY.Command_Timeout); - } - - if (_maxPoolSize < 1) - { - throw ADP.InvalidConnectionOptionValue(KEY.Max_Pool_Size); - } - - if (_minPoolSize < 0) - { - throw ADP.InvalidConnectionOptionValue(KEY.Min_Pool_Size); - } - if (_maxPoolSize < _minPoolSize) - { - throw ADP.InvalidMinMaxPoolSizeValues(); - } - - if ((_packetSize < TdsEnums.MIN_PACKET_SIZE) || (TdsEnums.MAX_PACKET_SIZE < _packetSize)) - { - throw SQL.InvalidPacketSizeValue(); - } - - ValidateValueLength(_applicationName, TdsEnums.MAXLEN_APPNAME, KEY.Application_Name); - ValidateValueLength(_currentLanguage, TdsEnums.MAXLEN_LANGUAGE, KEY.Current_Language); - ValidateValueLength(_dataSource, TdsEnums.MAXLEN_SERVERNAME, KEY.Data_Source); - ValidateValueLength(_failoverPartner, TdsEnums.MAXLEN_SERVERNAME, KEY.FailoverPartner); - ValidateValueLength(_initialCatalog, TdsEnums.MAXLEN_DATABASE, KEY.Initial_Catalog); - ValidateValueLength(_password, TdsEnums.MAXLEN_CLIENTSECRET, KEY.Password); - ValidateValueLength(_userID, TdsEnums.MAXLEN_CLIENTID, KEY.User_ID); - if (null != _workstationId) - { - ValidateValueLength(_workstationId, TdsEnums.MAXLEN_HOSTNAME, KEY.Workstation_Id); - } - - if (!string.Equals(DEFAULT.FailoverPartner, _failoverPartner, StringComparison.OrdinalIgnoreCase)) - { - // fail-over partner is set - - if (_multiSubnetFailover) - { - throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: false, internalConnection: null); - } - - if (string.Equals(DEFAULT.Initial_Catalog, _initialCatalog, StringComparison.OrdinalIgnoreCase)) - { - throw ADP.MissingConnectionOptionValue(KEY.FailoverPartner, KEY.Initial_Catalog); - } - } - - // expand during construction so that CreatePermissionSet and Expand are consistent - _expandedAttachDBFilename = ExpandDataDirectory(KEY.AttachDBFilename, _attachDBFileName); - if (null != _expandedAttachDBFilename) - { - if (0 <= _expandedAttachDBFilename.IndexOf('|')) - { - throw ADP.InvalidConnectionOptionValue(KEY.AttachDBFilename); - } - ValidateValueLength(_expandedAttachDBFilename, TdsEnums.MAXLEN_ATTACHDBFILE, KEY.AttachDBFilename); - if (_localDBInstance == null) - { - // fail fast to verify LocalHost when using |DataDirectory| - // still must check again at connect time - string host = _dataSource; - VerifyLocalHostAndFixup(ref host, true, false /*don't fix-up*/); - } - } - else if (0 <= _attachDBFileName.IndexOf('|')) - { - throw ADP.InvalidConnectionOptionValue(KEY.AttachDBFilename); - } - else - { - ValidateValueLength(_attachDBFileName, TdsEnums.MAXLEN_ATTACHDBFILE, KEY.AttachDBFilename); - } - _typeSystemAssemblyVersion = constTypeSystemAsmVersion10; - - if (true == _userInstance && !string.IsNullOrEmpty(_failoverPartner)) - { - throw SQL.UserInstanceFailoverNotCompatible(); - } - - if (string.IsNullOrEmpty(typeSystemVersionString)) - { - typeSystemVersionString = DbConnectionStringDefaults.TypeSystemVersion; - } - - if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.Latest, StringComparison.OrdinalIgnoreCase)) - { - _typeSystemVersion = TypeSystem.Latest; - } - else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2000, StringComparison.OrdinalIgnoreCase)) - { - _typeSystemVersion = TypeSystem.SQLServer2000; - } - else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2005, StringComparison.OrdinalIgnoreCase)) - { - _typeSystemVersion = TypeSystem.SQLServer2005; - } - else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2008, StringComparison.OrdinalIgnoreCase)) - { - _typeSystemVersion = TypeSystem.SQLServer2008; - } - else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2012, StringComparison.OrdinalIgnoreCase)) - { - _typeSystemVersion = TypeSystem.SQLServer2012; - _typeSystemAssemblyVersion = constTypeSystemAsmVersion11; - } - else - { - throw ADP.InvalidConnectionOptionValue(KEY.Type_System_Version); - } - - if (string.IsNullOrEmpty(transactionBindingString)) - { - transactionBindingString = DbConnectionStringDefaults.TransactionBinding; - } - - if (transactionBindingString.Equals(TRANSACTIONBINDING.ImplicitUnbind, StringComparison.OrdinalIgnoreCase)) - { - _transactionBinding = TransactionBindingEnum.ImplicitUnbind; - } - else if (transactionBindingString.Equals(TRANSACTIONBINDING.ExplicitUnbind, StringComparison.OrdinalIgnoreCase)) - { - _transactionBinding = TransactionBindingEnum.ExplicitUnbind; - } - else - { - throw ADP.InvalidConnectionOptionValue(KEY.TransactionBinding); - } - - if (_applicationIntent == ApplicationIntent.ReadOnly && !string.IsNullOrEmpty(_failoverPartner)) - throw SQL.ROR_FailoverNotSupportedConnString(); - - if ((_connectRetryCount < 0) || (_connectRetryCount > 255)) - { - throw ADP.InvalidConnectRetryCountValue(); - } - - if ((_connectRetryInterval < 1) || (_connectRetryInterval > 60)) - { - throw ADP.InvalidConnectRetryIntervalValue(); - } - - if (Authentication != SqlAuthenticationMethod.NotSpecified && _integratedSecurity == true) - { - throw SQL.AuthenticationAndIntegratedSecurity(); - } - - if (Authentication == SqlClient.SqlAuthenticationMethod.ActiveDirectoryIntegrated && _hasPasswordKeyword) - { - throw SQL.IntegratedWithPassword(); - } - - if (Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive && _hasPasswordKeyword) - { - throw SQL.InteractiveWithPassword(); - } - - if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow && (_hasUserIdKeyword || _hasPasswordKeyword)) - { - throw SQL.DeviceFlowWithUsernamePassword(); - } - - if (Authentication == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity && _hasPasswordKeyword) - { - throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString); - } - - if (Authentication == SqlAuthenticationMethod.ActiveDirectoryMSI && _hasPasswordKeyword) - { - throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString); - } - - if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDefault && _hasPasswordKeyword) - { - throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString); - } - } - - // This c-tor is used to create SSE and user instance connection strings when user instance is set to true - // BUG (VSTFDevDiv) 479687: Using TransactionScope with Linq2SQL against user instances fails with "connection has been broken" message - internal SqlConnectionString(SqlConnectionString connectionOptions, string dataSource, bool userInstance, bool? setEnlistValue) : base(connectionOptions) - { - _integratedSecurity = connectionOptions._integratedSecurity; - _encrypt = connectionOptions._encrypt; - - if (setEnlistValue.HasValue) - { - _enlist = setEnlistValue.Value; - } - else - { - _enlist = connectionOptions._enlist; - } - - _mars = connectionOptions._mars; - _persistSecurityInfo = connectionOptions._persistSecurityInfo; - _pooling = connectionOptions._pooling; - _replication = connectionOptions._replication; - _userInstance = userInstance; - _commandTimeout = connectionOptions._commandTimeout; - _connectTimeout = connectionOptions._connectTimeout; - _loadBalanceTimeout = connectionOptions._loadBalanceTimeout; - _poolBlockingPeriod = connectionOptions._poolBlockingPeriod; - _maxPoolSize = connectionOptions._maxPoolSize; - _minPoolSize = connectionOptions._minPoolSize; - _multiSubnetFailover = connectionOptions._multiSubnetFailover; - _packetSize = connectionOptions._packetSize; - _applicationName = connectionOptions._applicationName; - _attachDBFileName = connectionOptions._attachDBFileName; - _currentLanguage = connectionOptions._currentLanguage; - _dataSource = dataSource; - _localDBInstance = LocalDBAPI.GetLocalDbInstanceNameFromServerName(_dataSource); - _failoverPartner = connectionOptions._failoverPartner; - _initialCatalog = connectionOptions._initialCatalog; - _password = connectionOptions._password; - _userID = connectionOptions._userID; - _workstationId = connectionOptions._workstationId; - _expandedAttachDBFilename = connectionOptions._expandedAttachDBFilename; - _typeSystemVersion = connectionOptions._typeSystemVersion; - _transactionBinding = connectionOptions._transactionBinding; - _applicationIntent = connectionOptions._applicationIntent; - _connectRetryCount = connectionOptions._connectRetryCount; - _connectRetryInterval = connectionOptions._connectRetryInterval; - _authType = connectionOptions._authType; - _columnEncryptionSetting = connectionOptions._columnEncryptionSetting; - _enclaveAttestationUrl = connectionOptions._enclaveAttestationUrl; - _attestationProtocol = connectionOptions._attestationProtocol; - - ValidateValueLength(_dataSource, TdsEnums.MAXLEN_SERVERNAME, KEY.Data_Source); - } - - internal bool IntegratedSecurity { get { return _integratedSecurity; } } - - // We always initialize in Async mode so that both synchronous and asynchronous methods - // will work. In the future we can deprecate the keyword entirely. - internal bool Asynchronous { get { return true; } } - // SQLPT 41700: Ignore ResetConnection=False, always reset the connection for security - internal bool ConnectionReset { get { return true; } } - // internal bool EnableUdtDownload { get { return _enableUdtDownload;} } - internal bool Encrypt { get { return _encrypt; } } - internal bool TrustServerCertificate { get { return _trustServerCertificate; } } - internal bool Enlist { get { return _enlist; } } - internal bool MARS { get { return _mars; } } - internal bool MultiSubnetFailover { get { return _multiSubnetFailover; } } - internal SqlAuthenticationMethod Authentication { get { return _authType; } } - internal SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting { get { return _columnEncryptionSetting; } } - internal string EnclaveAttestationUrl { get { return _enclaveAttestationUrl; } } - internal SqlConnectionAttestationProtocol AttestationProtocol { get { return _attestationProtocol; } } - internal SqlConnectionIPAddressPreference IPAddressPreference => _ipAddressPreference; - internal bool PersistSecurityInfo { get { return _persistSecurityInfo; } } - internal bool Pooling { get { return _pooling; } } - internal bool Replication { get { return _replication; } } - internal bool UserInstance { get { return _userInstance; } } - - internal int CommandTimeout { get { return _commandTimeout; } } - internal int ConnectTimeout { get { return _connectTimeout; } } - internal int LoadBalanceTimeout { get { return _loadBalanceTimeout; } } - internal int MaxPoolSize { get { return _maxPoolSize; } } - internal int MinPoolSize { get { return _minPoolSize; } } - internal int PacketSize { get { return _packetSize; } } - internal int ConnectRetryCount { get { return _connectRetryCount; } } - internal int ConnectRetryInterval { get { return _connectRetryInterval; } } - - internal ApplicationIntent ApplicationIntent { get { return _applicationIntent; } } - internal string ApplicationName { get { return _applicationName; } } - internal string AttachDBFilename { get { return _attachDBFileName; } } - internal string CurrentLanguage { get { return _currentLanguage; } } - internal string DataSource { get { return _dataSource; } } - internal string LocalDBInstance { get { return _localDBInstance; } } - internal string FailoverPartner { get { return _failoverPartner; } } - internal string InitialCatalog { get { return _initialCatalog; } } - internal string Password { get { return _password; } } - internal string UserID { get { return _userID; } } - internal string WorkstationId { get { return _workstationId; } } - internal PoolBlockingPeriod PoolBlockingPeriod { get { return _poolBlockingPeriod; } } - - internal TypeSystem TypeSystemVersion { get { return _typeSystemVersion; } } - internal Version TypeSystemAssemblyVersion { get { return _typeSystemAssemblyVersion; } } - - internal TransactionBindingEnum TransactionBinding { get { return _transactionBinding; } } - - internal bool EnforceLocalHost - { - get - { - // so tdsparser.connect can determine if SqlConnection.UserConnectionOptions - // needs to enforce local host after datasource alias lookup - return (null != _expandedAttachDBFilename) && (null == _localDBInstance); - } - } - - protected internal override string Expand() - { - if (null != _expandedAttachDBFilename) - { - return ExpandAttachDbFileName(_expandedAttachDBFilename); - } - else - { - return base.Expand(); - } - } - - private static bool CompareHostName(ref string host, string name, bool fixup) - { - // same computer name or same computer name + "\named instance" - bool equal = false; - - if (host.Equals(name, StringComparison.OrdinalIgnoreCase)) - { - if (fixup) - { - host = "."; - } - equal = true; - } - else if (host.StartsWith(name + @"\", StringComparison.OrdinalIgnoreCase)) - { - if (fixup) - { - host = "." + host.Substring(name.Length); - } - equal = true; - } - return equal; - } - - // This dictionary is meant to be read-only translation of parsed string - // keywords/synonyms to a known keyword string. - internal static Dictionary GetParseSynonyms() - { - Dictionary synonyms = s_sqlClientSynonyms; - if (null == synonyms) - { - int count = SqlConnectionStringBuilder.KeywordsCount + SqlConnectionStringBuilder.DeprecatedKeywordsCount + SynonymCount + DeprecatedSynonymCount; - synonyms = new Dictionary(count) - { - { KEY.ApplicationIntent, KEY.ApplicationIntent }, - { KEY.Application_Name, KEY.Application_Name }, - { KEY.AttachDBFilename, KEY.AttachDBFilename }, - { KEY.PoolBlockingPeriod, KEY.PoolBlockingPeriod}, - { KEY.Command_Timeout, KEY.Command_Timeout }, - { KEY.Connect_Timeout, KEY.Connect_Timeout }, - { KEY.Connection_Reset, KEY.Connection_Reset }, - { KEY.Context_Connection, KEY.Context_Connection }, - { KEY.Current_Language, KEY.Current_Language }, - { KEY.Data_Source, KEY.Data_Source }, - { KEY.Encrypt, KEY.Encrypt }, - { KEY.Enlist, KEY.Enlist }, - { KEY.FailoverPartner, KEY.FailoverPartner }, - { KEY.Initial_Catalog, KEY.Initial_Catalog }, - { KEY.Integrated_Security, KEY.Integrated_Security }, - { KEY.Load_Balance_Timeout, KEY.Load_Balance_Timeout }, - { KEY.MARS, KEY.MARS }, - { KEY.Max_Pool_Size, KEY.Max_Pool_Size }, - { KEY.Min_Pool_Size, KEY.Min_Pool_Size }, - { KEY.MultiSubnetFailover, KEY.MultiSubnetFailover }, - { KEY.Network_Library, KEY.Network_Library }, - { KEY.Packet_Size, KEY.Packet_Size }, - { KEY.Password, KEY.Password }, - { KEY.Persist_Security_Info, KEY.Persist_Security_Info }, - { KEY.Pooling, KEY.Pooling }, - { KEY.Replication, KEY.Replication }, - { KEY.TrustServerCertificate, KEY.TrustServerCertificate }, - { KEY.TransactionBinding, KEY.TransactionBinding }, - { KEY.Type_System_Version, KEY.Type_System_Version }, - { KEY.ColumnEncryptionSetting, KEY.ColumnEncryptionSetting }, - { KEY.EnclaveAttestationUrl, KEY.EnclaveAttestationUrl }, - { KEY.AttestationProtocol, KEY.AttestationProtocol}, - { KEY.User_ID, KEY.User_ID }, - { KEY.User_Instance, KEY.User_Instance }, - { KEY.Workstation_Id, KEY.Workstation_Id }, - { KEY.Connect_Retry_Count, KEY.Connect_Retry_Count }, - { KEY.Connect_Retry_Interval, KEY.Connect_Retry_Interval }, - { KEY.Authentication, KEY.Authentication }, - { KEY.IPAddressPreference, KEY.IPAddressPreference }, - - { SYNONYM.APP, KEY.Application_Name }, - { SYNONYM.APPLICATIONINTENT, KEY.ApplicationIntent }, - { SYNONYM.EXTENDED_PROPERTIES, KEY.AttachDBFilename }, - { SYNONYM.INITIAL_FILE_NAME, KEY.AttachDBFilename }, - { SYNONYM.CONNECTRETRYCOUNT, KEY.Connect_Retry_Count }, - { SYNONYM.CONNECTRETRYINTERVAL, KEY.Connect_Retry_Interval }, - { SYNONYM.CONNECTION_TIMEOUT, KEY.Connect_Timeout }, - { SYNONYM.TIMEOUT, KEY.Connect_Timeout }, - { SYNONYM.LANGUAGE, KEY.Current_Language }, - { SYNONYM.ADDR, KEY.Data_Source }, - { SYNONYM.ADDRESS, KEY.Data_Source }, - { SYNONYM.MULTIPLEACTIVERESULTSETS, KEY.MARS }, - { SYNONYM.MULTISUBNETFAILOVER, KEY.MultiSubnetFailover }, - { SYNONYM.NETWORK_ADDRESS, KEY.Data_Source }, - { SYNONYM.POOLBLOCKINGPERIOD, KEY.PoolBlockingPeriod}, - { SYNONYM.SERVER, KEY.Data_Source }, - { SYNONYM.DATABASE, KEY.Initial_Catalog }, - { SYNONYM.TRUSTED_CONNECTION, KEY.Integrated_Security }, - { SYNONYM.Connection_Lifetime, KEY.Load_Balance_Timeout }, - { SYNONYM.NET, KEY.Network_Library }, - { SYNONYM.NETWORK, KEY.Network_Library }, - { SYNONYM.Pwd, KEY.Password }, - { SYNONYM.PERSISTSECURITYINFO, KEY.Persist_Security_Info }, - { SYNONYM.TRUSTSERVERCERTIFICATE, KEY.TrustServerCertificate }, - { SYNONYM.UID, KEY.User_ID }, - { SYNONYM.User, KEY.User_ID }, - { SYNONYM.WSID, KEY.Workstation_Id }, - { SYNONYM.IPADDRESSPREFERENCE, KEY.IPAddressPreference } - }; - Debug.Assert(synonyms.Count == count, "incorrect initial ParseSynonyms size"); - Interlocked.CompareExchange(ref s_sqlClientSynonyms, synonyms, null); - } - return synonyms; - } - - internal string ObtainWorkstationId() - { - // If not supplied by the user, the default value is the MachineName - // Note: In Longhorn you'll be able to rename a machine without - // rebooting. Therefore, don't cache this machine name. - string result = WorkstationId; - if (null == result) - { - // permission to obtain Environment.MachineName is Asserted - // since permission to open the connection has been granted - // the information is shared with the server, but not directly with the user - result = ADP.MachineName(); - ValidateValueLength(result, TdsEnums.MAXLEN_HOSTNAME, KEY.Workstation_Id); - } - return result; - } - - - private void ValidateValueLength(string value, int limit, string key) - { - if (limit < value.Length) - { - throw ADP.InvalidConnectionOptionValueLength(key, limit); - } - } - - internal static void VerifyLocalHostAndFixup(ref string host, bool enforceLocalHost, bool fixup) - { - if (string.IsNullOrEmpty(host)) - { - if (fixup) - { - host = "."; - } - } - else if (!CompareHostName(ref host, @".", fixup) && - !CompareHostName(ref host, @"(local)", fixup)) - { - // Fix-up completed in CompareHostName if return value true. - string name = GetComputerNameDnsFullyQualified(); // i.e, machine.location.corp.company.com - if (!CompareHostName(ref host, name, fixup)) - { - int separatorPos = name.IndexOf('.'); // to compare just 'machine' part - if ((separatorPos <= 0) || !CompareHostName(ref host, name.Substring(0, separatorPos), fixup)) - { - if (enforceLocalHost) - { - throw ADP.InvalidConnectionOptionValue(KEY.AttachDBFilename); - } - } - } - } - } - - private static string GetComputerNameDnsFullyQualified() - { - try - { - var domainName = "." + IPGlobalProperties.GetIPGlobalProperties().DomainName; - var hostName = Dns.GetHostName(); - if (domainName != "." && !hostName.EndsWith(domainName)) - hostName += domainName; - return hostName; - } - catch (System.Net.Sockets.SocketException) - { - return Environment.MachineName; - } - } - - internal ApplicationIntent ConvertValueToApplicationIntent() - { - string value; - if (!TryGetParsetableValue(KEY.ApplicationIntent, out value)) - { - return DEFAULT.ApplicationIntent; - } - - // when wrong value is used in the connection string provided to SqlConnection.ConnectionString or c-tor, - // wrap Format and Overflow exceptions with Argument one, to be consistent with rest of the keyword types (like int and bool) - try - { - return DbConnectionStringBuilderUtil.ConvertToApplicationIntent(KEY.ApplicationIntent, value); - } - catch (FormatException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.ApplicationIntent, e); - } - catch (OverflowException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.ApplicationIntent, e); - } - // ArgumentException and other types are raised as is (no wrapping) - } - - internal void ThrowUnsupportedIfKeywordSet(string keyword) - { - if (ContainsKey(keyword)) - { - throw SQL.UnsupportedKeyword(keyword); - } - } - - internal SqlAuthenticationMethod ConvertValueToAuthenticationType() - { - if (!TryGetParsetableValue(KEY.Authentication, out string value)) - { - return DEFAULT.Authentication; - } - - try - { - return DbConnectionStringBuilderUtil.ConvertToAuthenticationType(KEY.Authentication, value); - } - catch (FormatException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.Authentication, e); - } - catch (OverflowException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.Authentication, e); - } - } - - /// - /// Convert the value to SqlConnectionColumnEncryptionSetting. - /// - /// - internal SqlConnectionColumnEncryptionSetting ConvertValueToColumnEncryptionSetting() - { - if (!TryGetParsetableValue(KEY.ColumnEncryptionSetting, out string value)) - { - return DEFAULT.ColumnEncryptionSetting; - } - - try - { - return DbConnectionStringBuilderUtil.ConvertToColumnEncryptionSetting(KEY.ColumnEncryptionSetting, value); - } - catch (FormatException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.ColumnEncryptionSetting, e); - } - catch (OverflowException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.ColumnEncryptionSetting, e); - } - } - - /// - /// Convert the value to SqlConnectionAttestationProtocol - /// - /// - internal SqlConnectionAttestationProtocol ConvertValueToAttestationProtocol() - { - if (!TryGetParsetableValue(KEY.AttestationProtocol, out string value)) - { - return DEFAULT.AttestationProtocol; - } - - try - { - return DbConnectionStringBuilderUtil.ConvertToAttestationProtocol(KEY.AttestationProtocol, value); - } - catch (FormatException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.AttestationProtocol, e); - } - catch (OverflowException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.AttestationProtocol, e); - } - } - - /// - /// Convert the value to SqlConnectionIPAddressPreference - /// - /// - internal SqlConnectionIPAddressPreference ConvertValueToIPAddressPreference() - { - if (!TryGetParsetableValue(KEY.IPAddressPreference, out string value)) - { - return DEFAULT.s_IPAddressPreference; - } - - try - { - return DbConnectionStringBuilderUtil.ConvertToIPAddressPreference(KEY.IPAddressPreference, value); - } - catch (FormatException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.IPAddressPreference, e); - } - catch (OverflowException e) - { - throw ADP.InvalidConnectionOptionValue(KEY.IPAddressPreference, e); - } - } - - internal Microsoft.Data.SqlClient.PoolBlockingPeriod ConvertValueToPoolBlockingPeriod() - { - string value; - if (!TryGetParsetableValue(KEY.PoolBlockingPeriod, out value)) - { - return DEFAULT.PoolBlockingPeriod; - } - - try - { - return DbConnectionStringBuilderUtil.ConvertToPoolBlockingPeriod(KEY.PoolBlockingPeriod, value); - } - catch (Exception e) when (e is FormatException || e is OverflowException) - { - throw ADP.InvalidConnectionOptionValue(KEY.PoolBlockingPeriod, e); - } - } - } -} diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj index 1cc25bdf54..fba9d322bf 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj +++ b/src/Microsoft.Data.SqlClient/netfx/src/Microsoft.Data.SqlClient.csproj @@ -348,6 +348,9 @@ Microsoft\Data\SqlClient\SqlConnectionPoolProviderInfo.cs + + Microsoft\Data\SqlClient\SqlConnectionString.cs + Microsoft\Data\SqlClient\SqlDataAdapter.cs @@ -545,7 +548,6 @@ - Microsoft\Data\SqlClient\SqlConnectionTimeoutErrorInternal.cs diff --git a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs index 3cb7e0ef1c..047293a05a 100644 --- a/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/Common/DbConnectionStringCommon.cs @@ -952,6 +952,7 @@ internal static class DbConnectionStringDefaults internal const bool ContextConnection = false; internal static readonly bool TransparentNetworkIPResolution = !LocalAppContextSwitches.DisableTNIRByDefault; internal const string NetworkLibrary = ""; + internal const bool Asynchronous = false; #if ADONET_CERT_AUTH internal const string Certificate = ""; #endif @@ -982,7 +983,7 @@ internal static class DbConnectionStringDefaults internal const int ConnectRetryCount = 1; internal const int ConnectRetryInterval = 10; internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified; - internal static readonly SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled; + internal const SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled; internal const string EnclaveAttestationUrl = ""; internal const SqlConnectionAttestationProtocol AttestationProtocol = SqlConnectionAttestationProtocol.NotSpecified; internal const SqlConnectionIPAddressPreference IPAddressPreference = SqlConnectionIPAddressPreference.IPv4First; diff --git a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionString.cs b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs similarity index 66% rename from src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionString.cs rename to src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs index 84d032c389..41b81dbc66 100644 --- a/src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlConnectionString.cs +++ b/src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/SqlConnectionString.cs @@ -7,7 +7,12 @@ using System.Collections.Generic; using System.Diagnostics; using System.Globalization; +using System.Net; +using System.Net.NetworkInformation; +using System.Threading; using System.Runtime.Versioning; +using System.Security; +using System.Security.Permissions; using Microsoft.Data.Common; namespace Microsoft.Data.SqlClient @@ -20,176 +25,163 @@ internal sealed class SqlConnectionString : DbConnectionOptions internal static class DEFAULT { - private const string _emptyString = ""; internal const ApplicationIntent ApplicationIntent = DbConnectionStringDefaults.ApplicationIntent; - internal const string Application_Name = TdsEnums.SQL_PROVIDER_NAME; - internal const bool Asynchronous = false; - internal const string AttachDBFilename = _emptyString; - internal const PoolBlockingPeriod PoolBlockingPeriod = DbConnectionStringDefaults.PoolBlockingPeriod; - internal const int Command_Timeout = ADP.DefaultCommandTimeout; - internal const int Connect_Timeout = ADP.DefaultConnectionTimeout; - internal const bool Connection_Reset = true; - internal const bool Context_Connection = false; - internal const string Current_Language = _emptyString; - internal const string Data_Source = _emptyString; - internal const bool Encrypt = true; - internal const bool Enlist = true; - internal const string FailoverPartner = _emptyString; - internal const string Initial_Catalog = _emptyString; - internal const bool Integrated_Security = false; - internal const int Load_Balance_Timeout = 0; // default of 0 means don't use - internal const bool MARS = false; - internal const int Max_Pool_Size = 100; - internal const int Min_Pool_Size = 0; + internal const string Application_Name = DbConnectionStringDefaults.ApplicationName; + internal const string AttachDBFilename = DbConnectionStringDefaults.AttachDBFilename; + internal const int Command_Timeout = DbConnectionStringDefaults.CommandTimeout; + internal const int Connect_Timeout = DbConnectionStringDefaults.ConnectTimeout; + internal const string Current_Language = DbConnectionStringDefaults.CurrentLanguage; + internal const string Data_Source = DbConnectionStringDefaults.DataSource; + internal const bool Encrypt = DbConnectionStringDefaults.Encrypt; + internal const bool Enlist = DbConnectionStringDefaults.Enlist; + internal const string FailoverPartner = DbConnectionStringDefaults.FailoverPartner; + internal const string Initial_Catalog = DbConnectionStringDefaults.InitialCatalog; + internal const bool Integrated_Security = DbConnectionStringDefaults.IntegratedSecurity; + internal const int Load_Balance_Timeout = DbConnectionStringDefaults.LoadBalanceTimeout; + internal const bool MARS = DbConnectionStringDefaults.MultipleActiveResultSets; + internal const int Max_Pool_Size = DbConnectionStringDefaults.MaxPoolSize; + internal const int Min_Pool_Size = DbConnectionStringDefaults.MinPoolSize; internal const bool MultiSubnetFailover = DbConnectionStringDefaults.MultiSubnetFailover; + internal const int Packet_Size = DbConnectionStringDefaults.PacketSize; + internal const string Password = DbConnectionStringDefaults.Password; + internal const bool Persist_Security_Info = DbConnectionStringDefaults.PersistSecurityInfo; + internal const PoolBlockingPeriod PoolBlockingPeriod = DbConnectionStringDefaults.PoolBlockingPeriod; + internal const bool Pooling = DbConnectionStringDefaults.Pooling; + internal const bool TrustServerCertificate = DbConnectionStringDefaults.TrustServerCertificate; + internal const string Type_System_Version = DbConnectionStringDefaults.TypeSystemVersion; + internal const string User_ID = DbConnectionStringDefaults.UserID; + internal const bool User_Instance = DbConnectionStringDefaults.UserInstance; + internal const bool Replication = DbConnectionStringDefaults.Replication; + internal const int Connect_Retry_Count = DbConnectionStringDefaults.ConnectRetryCount; + internal const int Connect_Retry_Interval = DbConnectionStringDefaults.ConnectRetryInterval; + internal const string EnclaveAttestationUrl = DbConnectionStringDefaults.EnclaveAttestationUrl; + internal const SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = DbConnectionStringDefaults.ColumnEncryptionSetting; + internal static readonly SqlAuthenticationMethod Authentication = DbConnectionStringDefaults.Authentication; + internal static readonly SqlConnectionAttestationProtocol AttestationProtocol = DbConnectionStringDefaults.AttestationProtocol; + internal static readonly SqlConnectionIPAddressPreference IpAddressPreference = DbConnectionStringDefaults.IPAddressPreference; +#if NETFRAMEWORK internal static readonly bool TransparentNetworkIPResolution = DbConnectionStringDefaults.TransparentNetworkIPResolution; - internal const string Network_Library = _emptyString; - internal const int Packet_Size = 8000; - internal const string Password = _emptyString; - internal const bool Persist_Security_Info = false; - internal const bool Pooling = true; - internal const bool TrustServerCertificate = false; - internal const string Type_System_Version = _emptyString; - internal const string User_ID = _emptyString; - internal const bool User_Instance = false; - internal const bool Replication = false; - internal const int Connect_Retry_Count = 1; - internal const int Connect_Retry_Interval = 10; - internal static readonly SqlAuthenticationMethod Authentication = SqlAuthenticationMethod.NotSpecified; - internal static readonly SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting = SqlConnectionColumnEncryptionSetting.Disabled; - internal const string EnclaveAttestationUrl = _emptyString; - internal static readonly SqlConnectionAttestationProtocol AttestationProtocol = SqlConnectionAttestationProtocol.NotSpecified; - internal static readonly SqlConnectionIPAddressPreference s_IPAddressPreference = SqlConnectionIPAddressPreference.IPv4First; - + internal const bool Asynchronous = DbConnectionStringDefaults.Asynchronous; + internal const bool Connection_Reset = DbConnectionStringDefaults.ConnectionReset; + internal const bool Context_Connection = DbConnectionStringDefaults.ContextConnection; + internal const string Network_Library = DbConnectionStringDefaults.NetworkLibrary; #if ADONET_CERT_AUTH - internal const string Certificate = _emptyString; + internal const string Certificate = DbConnectionStringDefaults.Certificate; #endif +#endif // NETFRAMEWORK } // SqlConnection ConnectionString Options - // keys must be lowercase! internal static class KEY { - internal const string ApplicationIntent = "application intent"; - internal const string Application_Name = "application name"; - internal const string AttachDBFilename = "attachdbfilename"; - internal const string PoolBlockingPeriod = "pool blocking period"; - internal const string ColumnEncryptionSetting = "column encryption setting"; - internal const string EnclaveAttestationUrl = "enclave attestation url"; - internal const string AttestationProtocol = "attestation protocol"; - internal const string IPAddressPreference = "ip address preference"; - internal const string Connect_Timeout = "connect timeout"; - internal const string Command_Timeout = "command timeout"; - internal const string Connection_Reset = "connection reset"; - internal const string Context_Connection = "context connection"; - internal const string Current_Language = "current language"; - internal const string Data_Source = "data source"; - internal const string Encrypt = "encrypt"; - internal const string Enlist = "enlist"; - internal const string FailoverPartner = "failover partner"; - internal const string Initial_Catalog = "initial catalog"; - internal const string Integrated_Security = "integrated security"; - internal const string Load_Balance_Timeout = "load balance timeout"; - internal const string MARS = "multiple active result sets"; - internal const string Max_Pool_Size = "max pool size"; - internal const string Min_Pool_Size = "min pool size"; - internal const string MultiSubnetFailover = "multi subnet failover"; - internal const string TransparentNetworkIPResolution = "transparent network ip resolution"; - internal const string Network_Library = "network library"; - internal const string Packet_Size = "packet size"; - internal const string Password = "password"; - internal const string Persist_Security_Info = "persist security info"; - internal const string Pooling = "pooling"; - internal const string TransactionBinding = "transaction binding"; - internal const string TrustServerCertificate = "trust server certificate"; - internal const string Type_System_Version = "type system version"; - internal const string User_ID = "user id"; - internal const string User_Instance = "user instance"; - internal const string Workstation_Id = "workstation id"; - internal const string Replication = "replication"; - internal const string Connect_Retry_Count = "connect retry count"; - internal const string Connect_Retry_Interval = "connect retry interval"; - internal const string Authentication = "authentication"; - + internal const string ApplicationIntent = DbConnectionStringKeywords.ApplicationIntent; + internal const string Application_Name = DbConnectionStringKeywords.ApplicationName; + internal const string AttachDBFilename = DbConnectionStringKeywords.AttachDBFilename; + internal const string PoolBlockingPeriod = DbConnectionStringKeywords.PoolBlockingPeriod; + internal const string ColumnEncryptionSetting = DbConnectionStringKeywords.ColumnEncryptionSetting; + internal const string EnclaveAttestationUrl = DbConnectionStringKeywords.EnclaveAttestationUrl; + internal const string AttestationProtocol = DbConnectionStringKeywords.AttestationProtocol; + internal const string IPAddressPreference = DbConnectionStringKeywords.IPAddressPreference; + + internal const string Command_Timeout = DbConnectionStringKeywords.CommandTimeout; + internal const string Connect_Timeout = DbConnectionStringKeywords.ConnectTimeout; + internal const string Connection_Reset = DbConnectionStringKeywords.ConnectionReset; + internal const string Context_Connection = DbConnectionStringKeywords.ContextConnection; + internal const string Current_Language = DbConnectionStringKeywords.CurrentLanguage; + internal const string Data_Source = DbConnectionStringKeywords.DataSource; + internal const string Encrypt = DbConnectionStringKeywords.Encrypt; + internal const string Enlist = DbConnectionStringKeywords.Enlist; + internal const string FailoverPartner = DbConnectionStringKeywords.FailoverPartner; + internal const string Initial_Catalog = DbConnectionStringKeywords.InitialCatalog; + internal const string Integrated_Security = DbConnectionStringKeywords.IntegratedSecurity; + internal const string Load_Balance_Timeout = DbConnectionStringKeywords.LoadBalanceTimeout; + internal const string MARS = DbConnectionStringKeywords.MultipleActiveResultSets; + internal const string Max_Pool_Size = DbConnectionStringKeywords.MaxPoolSize; + internal const string Min_Pool_Size = DbConnectionStringKeywords.MinPoolSize; + internal const string MultiSubnetFailover = DbConnectionStringKeywords.MultiSubnetFailover; + internal const string Network_Library = DbConnectionStringKeywords.NetworkLibrary; + internal const string Packet_Size = DbConnectionStringKeywords.PacketSize; + internal const string Password = DbConnectionStringKeywords.Password; + internal const string Persist_Security_Info = DbConnectionStringKeywords.PersistSecurityInfo; + internal const string Pooling = DbConnectionStringKeywords.Pooling; + internal const string TransactionBinding = DbConnectionStringKeywords.TransactionBinding; + internal const string TrustServerCertificate = DbConnectionStringKeywords.TrustServerCertificate; + internal const string Type_System_Version = DbConnectionStringKeywords.TypeSystemVersion; + internal const string User_ID = DbConnectionStringKeywords.UserID; + internal const string User_Instance = DbConnectionStringKeywords.UserInstance; + internal const string Workstation_Id = DbConnectionStringKeywords.WorkstationID; + internal const string Replication = DbConnectionStringKeywords.Replication; + internal const string Connect_Retry_Count = DbConnectionStringKeywords.ConnectRetryCount; + internal const string Connect_Retry_Interval = DbConnectionStringKeywords.ConnectRetryInterval; + internal const string Authentication = DbConnectionStringKeywords.Authentication; +#if NETFRAMEWORK + internal const string TransparentNetworkIPResolution = DbConnectionStringKeywords.TransparentNetworkIPResolution; #if ADONET_CERT_AUTH - internal const string Certificate = "certificate"; + internal const string Certificate = DbConnectionStringKeywords.Certificate; #endif +#endif // NETFRAMEWORK } - // Constant for the number of duplicate options in the connnection string - + // Constant for the number of duplicate options in the connection string private static class SYNONYM { // ip address preference - internal const string IPADDRESSPREFERENCE = "ipaddresspreference"; - // application intent - internal const string APPLICATIONINTENT = "applicationintent"; + internal const string IPADDRESSPREFERENCE = DbConnectionStringSynonyms.IPADDRESSPREFERENCE; + //application intent + internal const string APPLICATIONINTENT = DbConnectionStringSynonyms.APPLICATIONINTENT; // application name - internal const string APP = "app"; + internal const string APP = DbConnectionStringSynonyms.APP; // attachDBFilename - internal const string EXTENDED_PROPERTIES = "extended properties"; - internal const string INITIAL_FILE_NAME = "initial file name"; - // connect retry count - internal const string CONNECTRETRYCOUNT = "connectretrycount"; - // connect retry interval - internal const string CONNECTRETRYINTERVAL = "connectretryinterval"; + internal const string EXTENDED_PROPERTIES = DbConnectionStringSynonyms.EXTENDEDPROPERTIES; + internal const string INITIAL_FILE_NAME = DbConnectionStringSynonyms.INITIALFILENAME; // connect timeout - internal const string CONNECTION_TIMEOUT = "connection timeout"; - internal const string TIMEOUT = "timeout"; + internal const string CONNECTION_TIMEOUT = DbConnectionStringSynonyms.CONNECTIONTIMEOUT; + internal const string TIMEOUT = DbConnectionStringSynonyms.TIMEOUT; // current language - internal const string LANGUAGE = "language"; + internal const string LANGUAGE = DbConnectionStringSynonyms.LANGUAGE; // data source - internal const string ADDR = "addr"; - internal const string ADDRESS = "address"; - internal const string SERVER = "server"; - internal const string NETWORK_ADDRESS = "network address"; + internal const string ADDR = DbConnectionStringSynonyms.ADDR; + internal const string ADDRESS = DbConnectionStringSynonyms.ADDRESS; + internal const string SERVER = DbConnectionStringSynonyms.SERVER; + internal const string NETWORK_ADDRESS = DbConnectionStringSynonyms.NETWORKADDRESS; // initial catalog - internal const string DATABASE = "database"; + internal const string DATABASE = DbConnectionStringSynonyms.DATABASE; // integrated security - internal const string TRUSTED_CONNECTION = "trusted_connection"; + internal const string TRUSTED_CONNECTION = DbConnectionStringSynonyms.TRUSTEDCONNECTION; + //connect retry count + internal const string CONNECTRETRYCOUNT = DbConnectionStringSynonyms.CONNECTRETRYCOUNT; + //connect retry interval + internal const string CONNECTRETRYINTERVAL = DbConnectionStringSynonyms.CONNECTRETRYINTERVAL; // load balance timeout - internal const string Connection_Lifetime = "connection lifetime"; + internal const string Connection_Lifetime = DbConnectionStringSynonyms.ConnectionLifetime; // multiple active result sets - internal const string MULTIPLEACTIVERESULTSETS = "multipleactiveresultsets"; + internal const string MULTIPLEACTIVERESULTSETS = DbConnectionStringSynonyms.MULTIPLEACTIVERESULTSETS; // multi subnet failover - internal const string MULTISUBNETFAILOVER = "multisubnetfailover"; + internal const string MULTISUBNETFAILOVER = DbConnectionStringSynonyms.MULTISUBNETFAILOVER; // network library - internal const string NET = "net"; - internal const string NETWORK = "network"; + internal const string NET = DbConnectionStringSynonyms.NET; + internal const string NETWORK = DbConnectionStringSynonyms.NETWORK; + // pool blocking period + internal const string POOLBLOCKINGPERIOD = DbConnectionStringSynonyms.POOLBLOCKINGPERIOD; // password - internal const string Pwd = "pwd"; + internal const string Pwd = DbConnectionStringSynonyms.Pwd; // persist security info - internal const string PERSISTSECURITYINFO = "persistsecurityinfo"; - // pool blocking period - internal const string POOLBLOCKINGPERIOD = "poolblockingperiod"; - // transparent network ip resolution - internal const string TRANSPARENTNETWORKIPRESOLUTION = "transparentnetworkipresolution"; + internal const string PERSISTSECURITYINFO = DbConnectionStringSynonyms.PERSISTSECURITYINFO; // trust server certificate - internal const string TRUSTSERVERCERTIFICATE = "trustservercertificate"; + internal const string TRUSTSERVERCERTIFICATE = DbConnectionStringSynonyms.TRUSTSERVERCERTIFICATE; // user id - internal const string UID = "uid"; - internal const string User = "user"; + internal const string UID = DbConnectionStringSynonyms.UID; + internal const string User = DbConnectionStringSynonyms.User; // workstation id - internal const string WSID = "wsid"; + internal const string WSID = DbConnectionStringSynonyms.WSID; +#if NETFRAMEWORK + internal const string TRANSPARENTNETWORKIPRESOLUTION = DbConnectionStringSynonyms.TRANSPARENTNETWORKIPRESOLUTION; +#endif + // make sure to update SynonymCount value below when adding or removing synonyms } - internal const int SynonymCount = 29; - - // the following are all inserted as keys into the _netlibMapping hash - internal static class NETLIB - { - internal const string AppleTalk = "dbmsadsn"; - internal const string BanyanVines = "dbmsvinn"; - internal const string IPXSPX = "dbmsspxn"; - internal const string Multiprotocol = "dbmsrpcn"; - internal const string NamedPipes = "dbnmpntw"; - internal const string SharedMemory = "dbmslpcn"; - internal const string TCPIP = "dbmssocn"; - internal const string VIA = "dbmsgnet"; - } - internal enum TypeSystem { Latest = 2008, @@ -214,30 +206,33 @@ internal enum TransactionBindingEnum ExplicitUnbind } - internal static class TRANSACIONBINDING + internal static class TRANSACTIONBINDING { internal const string ImplicitUnbind = "Implicit Unbind"; internal const string ExplicitUnbind = "Explicit Unbind"; } +#if NETFRAMEWORK + internal const int SynonymCount = 29; +#else + internal const int SynonymCount = 26; + internal const int DeprecatedSynonymCount = 2; +#endif // NETFRAMEWORK + private static Dictionary s_sqlClientSynonyms; - static private Hashtable _netlibMapping; private readonly bool _integratedSecurity; - private readonly PoolBlockingPeriod _poolBlockingPeriod; - private readonly bool _connectionReset; - private readonly bool _contextConnection; private readonly bool _encrypt; private readonly bool _trustServerCertificate; private readonly bool _enlist; private readonly bool _mars; private readonly bool _persistSecurityInfo; + private readonly PoolBlockingPeriod _poolBlockingPeriod; private readonly bool _pooling; private readonly bool _replication; private readonly bool _userInstance; private readonly bool _multiSubnetFailover; - private readonly bool _transparentNetworkIPResolution; private readonly SqlAuthenticationMethod _authType; private readonly SqlConnectionColumnEncryptionSetting _columnEncryptionSetting; private readonly string _enclaveAttestationUrl; @@ -263,48 +258,49 @@ internal static class TRANSACIONBINDING private readonly string _initialCatalog; private readonly string _password; private readonly string _userID; -#if ADONET_CERT_AUTH - private readonly string _certificate; -#endif - private readonly string _networkLibrary; + private readonly string _workstationId; + private readonly TransactionBindingEnum _transactionBinding; + private readonly TypeSystem _typeSystemVersion; private readonly Version _typeSystemAssemblyVersion; - private static readonly Version constTypeSystemAsmVersion10 = new Version("10.0.0.0"); - private static readonly Version constTypeSystemAsmVersion11 = new Version("11.0.0.0"); - - private readonly TransactionBindingEnum _transactionBinding; + private static readonly Version s_constTypeSystemAsmVersion10 = new("10.0.0.0"); + private static readonly Version s_constTypeSystemAsmVersion11 = new("11.0.0.0"); private readonly string _expandedAttachDBFilename; // expanded during construction so that CreatePermissionSet & Expand are consistent - // SxS: reading Software\\Microsoft\\MSSQLServer\\Client\\SuperSocketNetLib\Encrypt value from registry [ResourceExposure(ResourceScope.None)] [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)] internal SqlConnectionString(string connectionString) : base(connectionString, GetParseSynonyms()) { - +#if NETFRAMEWORK bool runningInProc = InOutOfProcHelper.InProc; +#else + ThrowUnsupportedIfKeywordSet(KEY.Connection_Reset); + ThrowUnsupportedIfKeywordSet(KEY.Context_Connection); - _integratedSecurity = ConvertValueToIntegratedSecurity(); + // Network Library has its own special error message + if (ContainsKey(KEY.Network_Library)) + { + throw SQL.NetworkLibraryKeywordNotSupported(); + } +#endif - // SQLPT 41700: Ignore ResetConnection=False (still validate the keyword/value) + _integratedSecurity = ConvertValueToIntegratedSecurity(); _poolBlockingPeriod = ConvertValueToPoolBlockingPeriod(); - _connectionReset = ConvertValueToBoolean(KEY.Connection_Reset, DEFAULT.Connection_Reset); - _contextConnection = ConvertValueToBoolean(KEY.Context_Connection, DEFAULT.Context_Connection); - _encrypt = ConvertValueToEncrypt(); - _enlist = ConvertValueToBoolean(KEY.Enlist, ADP.s_isWindowsNT); + _encrypt = ConvertValueToBoolean(KEY.Encrypt, DEFAULT.Encrypt); + _enlist = ConvertValueToBoolean(KEY.Enlist, DEFAULT.Enlist); _mars = ConvertValueToBoolean(KEY.MARS, DEFAULT.MARS); _persistSecurityInfo = ConvertValueToBoolean(KEY.Persist_Security_Info, DEFAULT.Persist_Security_Info); _pooling = ConvertValueToBoolean(KEY.Pooling, DEFAULT.Pooling); _replication = ConvertValueToBoolean(KEY.Replication, DEFAULT.Replication); _userInstance = ConvertValueToBoolean(KEY.User_Instance, DEFAULT.User_Instance); _multiSubnetFailover = ConvertValueToBoolean(KEY.MultiSubnetFailover, DEFAULT.MultiSubnetFailover); - _transparentNetworkIPResolution = ConvertValueToBoolean(KEY.TransparentNetworkIPResolution, DEFAULT.TransparentNetworkIPResolution); - _connectTimeout = ConvertValueToInt32(KEY.Connect_Timeout, DEFAULT.Connect_Timeout); _commandTimeout = ConvertValueToInt32(KEY.Command_Timeout, DEFAULT.Command_Timeout); + _connectTimeout = ConvertValueToInt32(KEY.Connect_Timeout, DEFAULT.Connect_Timeout); _loadBalanceTimeout = ConvertValueToInt32(KEY.Load_Balance_Timeout, DEFAULT.Load_Balance_Timeout); _maxPoolSize = ConvertValueToInt32(KEY.Max_Pool_Size, DEFAULT.Max_Pool_Size); _minPoolSize = ConvertValueToInt32(KEY.Min_Pool_Size, DEFAULT.Min_Pool_Size); @@ -320,7 +316,6 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G _localDBInstance = LocalDBAPI.GetLocalDbInstanceNameFromServerName(_dataSource); _failoverPartner = ConvertValueToString(KEY.FailoverPartner, DEFAULT.FailoverPartner); _initialCatalog = ConvertValueToString(KEY.Initial_Catalog, DEFAULT.Initial_Catalog); - _networkLibrary = ConvertValueToString(KEY.Network_Library, null); _password = ConvertValueToString(KEY.Password, DEFAULT.Password); _trustServerCertificate = ConvertValueToBoolean(KEY.TrustServerCertificate, DEFAULT.TrustServerCertificate); _authType = ConvertValueToAuthenticationType(); @@ -329,10 +324,6 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G _attestationProtocol = ConvertValueToAttestationProtocol(); _ipAddressPreference = ConvertValueToIPAddressPreference(); -#if ADONET_CERT_AUTH - _certificate = ConvertValueToString(KEY.Certificate, DEFAULT.Certificate); -#endif - // Temporary string - this value is stored internally as an enum. string typeSystemVersionString = ConvertValueToString(KEY.Type_System_Version, null); string transactionBindingString = ConvertValueToString(KEY.TransactionBinding, null); @@ -340,42 +331,6 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G _userID = ConvertValueToString(KEY.User_ID, DEFAULT.User_ID); _workstationId = ConvertValueToString(KEY.Workstation_Id, null); - if (_contextConnection) - { - // We have to be running in the engine for you to request a - // context connection. - - if (!runningInProc) - { - throw SQL.ContextUnavailableOutOfProc(); - } - - // When using a context connection, we need to ensure that no - // other connection string keywords are specified. - - foreach (KeyValuePair entry in Parsetable) - { - if (entry.Key != KEY.Context_Connection && - entry.Key != KEY.Type_System_Version) - { - throw SQL.ContextAllowsLimitedKeywords(); - } - } - } - - if (!_encrypt) - { // Support legacy registry encryption settings - const string folder = "Software\\Microsoft\\MSSQLServer\\Client\\SuperSocketNetLib"; - const string value = "Encrypt"; - - Object obj = ADP.LocalMachineRegistryValue(folder, value); - if ((obj is Int32) && (1 == (int)obj)) - { // If the registry key exists - _encrypt = true; - } - } - - if (_loadBalanceTimeout < 0) { throw ADP.InvalidConnectionOptionValue(KEY.Load_Balance_Timeout); @@ -410,6 +365,54 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G throw SQL.InvalidPacketSizeValue(); } +#if NETFRAMEWORK + // SQLPT 41700: Ignore ResetConnection=False (still validate the keyword/value) + _connectionReset = ConvertValueToBoolean(KEY.Connection_Reset, DEFAULT.Connection_Reset); + _contextConnection = ConvertValueToBoolean(KEY.Context_Connection, DEFAULT.Context_Connection); + _encrypt = ConvertValueToEncrypt(); + _enlist = ConvertValueToBoolean(KEY.Enlist, ADP.s_isWindowsNT); + _transparentNetworkIPResolution = ConvertValueToBoolean(KEY.TransparentNetworkIPResolution, DEFAULT.TransparentNetworkIPResolution); + _networkLibrary = ConvertValueToString(KEY.Network_Library, null); + +#if ADONET_CERT_AUTH + _certificate = ConvertValueToString(KEY.Certificate, DEFAULT.Certificate); +#endif + + if (_contextConnection) + { + // We have to be running in the engine for you to request a + // context connection. + + if (!runningInProc) + { + throw SQL.ContextUnavailableOutOfProc(); + } + + // When using a context connection, we need to ensure that no + // other connection string keywords are specified. + + foreach (KeyValuePair entry in Parsetable) + { + if (entry.Key != KEY.Context_Connection && + entry.Key != KEY.Type_System_Version) + { + throw SQL.ContextAllowsLimitedKeywords(); + } + } + } + + if (!_encrypt) + { // Support legacy registry encryption settings + const string folder = "Software\\Microsoft\\MSSQLServer\\Client\\SuperSocketNetLib"; + const string value = "Encrypt"; + + object obj = ADP.LocalMachineRegistryValue(folder, value); + if ((obj is int iObj) && (iObj == 1)) + { // If the registry key exists + _encrypt = true; + } + } + if (null != _networkLibrary) { // MDAC 83525 string networkLibrary = _networkLibrary.Trim().ToLower(CultureInfo.InvariantCulture); @@ -424,6 +427,7 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G { _networkLibrary = DEFAULT.Network_Library; } +#endif // NETFRAMEWORK ValidateValueLength(_applicationName, TdsEnums.MAXLEN_APPNAME, KEY.Application_Name); ValidateValueLength(_currentLanguage, TdsEnums.MAXLEN_LANGUAGE, KEY.Current_Language); @@ -437,7 +441,7 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G ValidateValueLength(_workstationId, TdsEnums.MAXLEN_HOSTNAME, KEY.Workstation_Id); } - if (!String.Equals(DEFAULT.FailoverPartner, _failoverPartner, StringComparison.OrdinalIgnoreCase)) + if (!string.Equals(DEFAULT.FailoverPartner, _failoverPartner, StringComparison.OrdinalIgnoreCase)) { // fail-over partner is set @@ -446,15 +450,19 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: false, internalConnection: null); } - if (String.Equals(DEFAULT.Initial_Catalog, _initialCatalog, StringComparison.OrdinalIgnoreCase)) + if (string.Equals(DEFAULT.Initial_Catalog, _initialCatalog, StringComparison.OrdinalIgnoreCase)) { throw ADP.MissingConnectionOptionValue(KEY.FailoverPartner, KEY.Initial_Catalog); } } // expand during construction so that CreatePermissionSet and Expand are consistent +#if NETFRAMEWORK string datadir = null; _expandedAttachDBFilename = ExpandDataDirectory(KEY.AttachDBFilename, _attachDBFileName, ref datadir); +#else + _expandedAttachDBFilename = ExpandDataDirectory(KEY.AttachDBFilename, _attachDBFileName); +#endif // NETFRAMEWORK if (null != _expandedAttachDBFilename) { if (0 <= _expandedAttachDBFilename.IndexOf('|')) @@ -467,8 +475,10 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G // fail fast to verify LocalHost when using |DataDirectory| // still must check again at connect time string host = _dataSource; +#if NETFRAMEWORK string protocol = _networkLibrary; TdsParserStaticMethods.AliasRegistryLookup(ref host, ref protocol); +#endif VerifyLocalHostAndFixup(ref host, true, false /*don't fix-up*/); } } @@ -480,15 +490,14 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G { ValidateValueLength(_attachDBFileName, TdsEnums.MAXLEN_ATTACHDBFILE, KEY.AttachDBFilename); } + _typeSystemAssemblyVersion = s_constTypeSystemAsmVersion10; - _typeSystemAssemblyVersion = constTypeSystemAsmVersion10; - - if (true == _userInstance && !ADP.IsEmpty(_failoverPartner)) + if (_userInstance && !string.IsNullOrEmpty(_failoverPartner)) { throw SQL.UserInstanceFailoverNotCompatible(); } - if (ADP.IsEmpty(typeSystemVersionString)) + if (string.IsNullOrEmpty(typeSystemVersionString)) { typeSystemVersionString = DbConnectionStringDefaults.TypeSystemVersion; } @@ -499,10 +508,12 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G } else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2000, StringComparison.OrdinalIgnoreCase)) { +#if NETFRAMEWORK if (_contextConnection) { throw SQL.ContextAllowsOnlyTypeSystem2005(); } +#endif _typeSystemVersion = TypeSystem.SQLServer2000; } else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2005, StringComparison.OrdinalIgnoreCase)) @@ -516,23 +527,23 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2012, StringComparison.OrdinalIgnoreCase)) { _typeSystemVersion = TypeSystem.SQLServer2012; - _typeSystemAssemblyVersion = constTypeSystemAsmVersion11; + _typeSystemAssemblyVersion = s_constTypeSystemAsmVersion11; } else { throw ADP.InvalidConnectionOptionValue(KEY.Type_System_Version); } - if (ADP.IsEmpty(transactionBindingString)) + if (string.IsNullOrEmpty(transactionBindingString)) { transactionBindingString = DbConnectionStringDefaults.TransactionBinding; } - if (transactionBindingString.Equals(TRANSACIONBINDING.ImplicitUnbind, StringComparison.OrdinalIgnoreCase)) + if (transactionBindingString.Equals(TRANSACTIONBINDING.ImplicitUnbind, StringComparison.OrdinalIgnoreCase)) { _transactionBinding = TransactionBindingEnum.ImplicitUnbind; } - else if (transactionBindingString.Equals(TRANSACIONBINDING.ExplicitUnbind, StringComparison.OrdinalIgnoreCase)) + else if (transactionBindingString.Equals(TRANSACTIONBINDING.ExplicitUnbind, StringComparison.OrdinalIgnoreCase)) { _transactionBinding = TransactionBindingEnum.ExplicitUnbind; } @@ -541,6 +552,11 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G throw ADP.InvalidConnectionOptionValue(KEY.TransactionBinding); } + if (_applicationIntent == ApplicationIntent.ReadOnly && !string.IsNullOrEmpty(_failoverPartner)) + { + throw SQL.ROR_FailoverNotSupportedConnString(); + } + if ((_connectRetryCount < 0) || (_connectRetryCount > 255)) { throw ADP.InvalidConnectRetryCountValue(); @@ -556,12 +572,19 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G throw SQL.AuthenticationAndIntegratedSecurity(); } +#if NETFRAMEWORK if (Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated && (_hasUserIdKeyword || _hasPasswordKeyword)) { throw SQL.IntegratedWithUserIDAndPassword(); } +#else + if (Authentication == SqlAuthenticationMethod.ActiveDirectoryIntegrated && _hasPasswordKeyword) + { + throw SQL.IntegratedWithPassword(); + } +#endif - if (Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive && (_hasPasswordKeyword)) + if (Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive && _hasPasswordKeyword) { throw SQL.InteractiveWithPassword(); } @@ -585,16 +608,18 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G { throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString); } +#if ADONET_CERT_AUTH && NETFRAMEWORK -#if ADONET_CERT_AUTH - - if (!DbConnectionStringBuilderUtil.IsValidCertificateValue(_certificate)) { + if (!DbConnectionStringBuilderUtil.IsValidCertificateValue(_certificate)) + { throw ADP.InvalidConnectionOptionValue(KEY.Certificate); } - if (!string.IsNullOrEmpty(_certificate)) { + if (!string.IsNullOrEmpty(_certificate)) + { - if (Authentication == SqlAuthenticationMethod.NotSpecified && !_integratedSecurity) { + if (Authentication == SqlAuthenticationMethod.NotSpecified && !_integratedSecurity) + { _authType = SqlAuthenticationMethod.SqlCertificate; } @@ -602,7 +627,8 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G throw SQL.InvalidCertAuth(); } } - else if (Authentication == SqlAuthenticationMethod.SqlCertificate) { + else if (Authentication == SqlAuthenticationMethod.SqlCertificate) + { throw ADP.InvalidConnectionOptionValue(KEY.Authentication); } #endif @@ -613,8 +639,6 @@ internal SqlConnectionString(string connectionString) : base(connectionString, G internal SqlConnectionString(SqlConnectionString connectionOptions, string dataSource, bool userInstance, bool? setEnlistValue) : base(connectionOptions) { _integratedSecurity = connectionOptions._integratedSecurity; - _connectionReset = connectionOptions._connectionReset; - _contextConnection = connectionOptions._contextConnection; _encrypt = connectionOptions._encrypt; if (setEnlistValue.HasValue) @@ -638,7 +662,6 @@ internal SqlConnectionString(SqlConnectionString connectionOptions, string dataS _maxPoolSize = connectionOptions._maxPoolSize; _minPoolSize = connectionOptions._minPoolSize; _multiSubnetFailover = connectionOptions._multiSubnetFailover; - _transparentNetworkIPResolution = connectionOptions._transparentNetworkIPResolution; _packetSize = connectionOptions._packetSize; _applicationName = connectionOptions._applicationName; _attachDBFileName = connectionOptions._attachDBFileName; @@ -649,11 +672,9 @@ internal SqlConnectionString(SqlConnectionString connectionOptions, string dataS _initialCatalog = connectionOptions._initialCatalog; _password = connectionOptions._password; _userID = connectionOptions._userID; - _networkLibrary = connectionOptions._networkLibrary; _workstationId = connectionOptions._workstationId; _expandedAttachDBFilename = connectionOptions._expandedAttachDBFilename; _typeSystemVersion = connectionOptions._typeSystemVersion; - _typeSystemAssemblyVersion = connectionOptions._typeSystemAssemblyVersion; _transactionBinding = connectionOptions._transactionBinding; _applicationIntent = connectionOptions._applicationIntent; _connectRetryCount = connectionOptions._connectRetryCount; @@ -662,95 +683,90 @@ internal SqlConnectionString(SqlConnectionString connectionOptions, string dataS _columnEncryptionSetting = connectionOptions._columnEncryptionSetting; _enclaveAttestationUrl = connectionOptions._enclaveAttestationUrl; _attestationProtocol = connectionOptions._attestationProtocol; +#if NETFRAMEWORK + _connectionReset = connectionOptions._connectionReset; + _contextConnection = connectionOptions._contextConnection; + _transparentNetworkIPResolution = connectionOptions._transparentNetworkIPResolution; + _networkLibrary = connectionOptions._networkLibrary; + _typeSystemAssemblyVersion = connectionOptions._typeSystemAssemblyVersion; #if ADONET_CERT_AUTH _certificate = connectionOptions._certificate; #endif +#endif // NETFRAMEWORK ValidateValueLength(_dataSource, TdsEnums.MAXLEN_SERVERNAME, KEY.Data_Source); } - internal bool IntegratedSecurity { get { return _integratedSecurity; } } + internal bool IntegratedSecurity => _integratedSecurity; // We always initialize in Async mode so that both synchronous and asynchronous methods // will work. In the future we can deprecate the keyword entirely. - internal bool Asynchronous { get { return true; } } - - internal PoolBlockingPeriod PoolBlockingPeriod { get { return _poolBlockingPeriod; } } - + internal bool Asynchronous => true; // SQLPT 41700: Ignore ResetConnection=False, always reset the connection for security - internal bool ConnectionReset { get { return true; } } - internal bool ContextConnection { get { return _contextConnection; } } - // internal bool EnableUdtDownload { get { return _enableUdtDownload;} } - internal bool Encrypt { get { return _encrypt; } } - internal bool TrustServerCertificate { get { return _trustServerCertificate; } } - internal bool Enlist { get { return _enlist; } } - internal bool MARS { get { return _mars; } } - internal bool MultiSubnetFailover { get { return _multiSubnetFailover; } } - internal bool TransparentNetworkIPResolution { get { return _transparentNetworkIPResolution; } } - internal SqlAuthenticationMethod Authentication { get { return _authType; } } - internal SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting { get { return _columnEncryptionSetting; } } - internal string EnclaveAttestationUrl { get { return _enclaveAttestationUrl; } } - internal SqlConnectionAttestationProtocol AttestationProtocol { get { return _attestationProtocol; } } + internal bool ConnectionReset => true; + // internal bool EnableUdtDownload => _enableUdtDownload;} } + internal bool Encrypt => _encrypt; + internal bool TrustServerCertificate => _trustServerCertificate; + internal bool Enlist => _enlist; + internal bool MARS => _mars; + internal bool MultiSubnetFailover => _multiSubnetFailover; + internal SqlAuthenticationMethod Authentication => _authType; + internal SqlConnectionColumnEncryptionSetting ColumnEncryptionSetting => _columnEncryptionSetting; + internal string EnclaveAttestationUrl => _enclaveAttestationUrl; + internal SqlConnectionAttestationProtocol AttestationProtocol => _attestationProtocol; internal SqlConnectionIPAddressPreference IPAddressPreference => _ipAddressPreference; -#if ADONET_CERT_AUTH - internal string Certificate { get { return _certificate; } } - internal bool UsesCertificate { get { return _authType == SqlClient.SqlAuthenticationMethod.SqlCertificate; } } -#else - internal string Certificate { get { return null; } } - internal bool UsesCertificate { get { return false; } } -#endif - internal bool PersistSecurityInfo { get { return _persistSecurityInfo; } } - internal bool Pooling { get { return _pooling; } } - internal bool Replication { get { return _replication; } } - internal bool UserInstance { get { return _userInstance; } } - - internal int CommandTimeout { get { return _commandTimeout; } } - internal int ConnectTimeout { get { return _connectTimeout; } } - internal int LoadBalanceTimeout { get { return _loadBalanceTimeout; } } - internal int MaxPoolSize { get { return _maxPoolSize; } } - internal int MinPoolSize { get { return _minPoolSize; } } - internal int PacketSize { get { return _packetSize; } } - internal int ConnectRetryCount { get { return _connectRetryCount; } } - internal int ConnectRetryInterval { get { return _connectRetryInterval; } } - - internal ApplicationIntent ApplicationIntent { get { return _applicationIntent; } } - internal string ApplicationName { get { return _applicationName; } } - internal string AttachDBFilename { get { return _attachDBFileName; } } - internal string CurrentLanguage { get { return _currentLanguage; } } - internal string DataSource { get { return _dataSource; } } - internal string LocalDBInstance { get { return _localDBInstance; } } - internal string FailoverPartner { get { return _failoverPartner; } } - internal string InitialCatalog { get { return _initialCatalog; } } - internal string NetworkLibrary { get { return _networkLibrary; } } - internal string Password { get { return _password; } } - internal string UserID { get { return _userID; } } - internal string WorkstationId { get { return _workstationId; } } - - internal TypeSystem TypeSystemVersion { get { return _typeSystemVersion; } } - internal Version TypeSystemAssemblyVersion { get { return _typeSystemAssemblyVersion; } } - internal TransactionBindingEnum TransactionBinding { get { return _transactionBinding; } } + internal bool PersistSecurityInfo => _persistSecurityInfo; + internal bool Pooling => _pooling; + internal bool Replication => _replication; + internal bool UserInstance => _userInstance; + + internal int CommandTimeout => _commandTimeout; + internal int ConnectTimeout => _connectTimeout; + internal int LoadBalanceTimeout => _loadBalanceTimeout; + internal int MaxPoolSize => _maxPoolSize; + internal int MinPoolSize => _minPoolSize; + internal int PacketSize => _packetSize; + internal int ConnectRetryCount => _connectRetryCount; + internal int ConnectRetryInterval => _connectRetryInterval; + + internal ApplicationIntent ApplicationIntent => _applicationIntent; + internal string ApplicationName => _applicationName; + internal string AttachDBFilename => _attachDBFileName; + internal string CurrentLanguage => _currentLanguage; + internal string DataSource => _dataSource; + internal string LocalDBInstance => _localDBInstance; + internal string FailoverPartner => _failoverPartner; + internal string InitialCatalog => _initialCatalog; + internal string Password => _password; + internal string UserID => _userID; + internal string WorkstationId => _workstationId; + internal PoolBlockingPeriod PoolBlockingPeriod => _poolBlockingPeriod; + + + internal TypeSystem TypeSystemVersion => _typeSystemVersion; + internal Version TypeSystemAssemblyVersion => _typeSystemAssemblyVersion; + + internal TransactionBindingEnum TransactionBinding => _transactionBinding; internal bool EnforceLocalHost { get { // so tdsparser.connect can determine if SqlConnection.UserConnectionOptions - // needs to enfoce local host after datasource alias lookup + // needs to enforce local host after datasource alias lookup return (null != _expandedAttachDBFilename) && (null == _localDBInstance); } } - protected internal override System.Security.PermissionSet CreatePermissionSet() - { - System.Security.PermissionSet permissionSet = new System.Security.PermissionSet(System.Security.Permissions.PermissionState.None); - permissionSet.AddPermission(new SqlClientPermission(this)); - return permissionSet; - } protected internal override string Expand() { if (null != _expandedAttachDBFilename) { +#if NETFRAMEWORK return ExpandKeyword(KEY.AttachDBFilename, _expandedAttachDBFilename); +#else + return ExpandAttachDbFileName(_expandedAttachDBFilename); +#endif } else { @@ -782,22 +798,26 @@ private static bool CompareHostName(ref string host, string name, bool fixup) return equal; } - // this hashtable is meant to be read-only translation of parsed string - // keywords/synonyms to a known keyword string + // This dictionary is meant to be read-only translation of parsed string + // keywords/synonyms to a known keyword string. internal static Dictionary GetParseSynonyms() { Dictionary synonyms = s_sqlClientSynonyms; - if (synonyms is null) + if (null == synonyms) { + int count = SqlConnectionStringBuilder.KeywordsCount + SynonymCount; - synonyms = new Dictionary(count) +#if !NETFRAMEWORK + count += SqlConnectionStringBuilder.DeprecatedKeywordsCount + DeprecatedSynonymCount; +#endif + synonyms = new Dictionary(count, StringComparer.OrdinalIgnoreCase) { - { KEY.ApplicationIntent, KEY.ApplicationIntent}, + { KEY.ApplicationIntent, KEY.ApplicationIntent }, { KEY.Application_Name, KEY.Application_Name }, { KEY.AttachDBFilename, KEY.AttachDBFilename }, - { KEY.PoolBlockingPeriod, KEY.PoolBlockingPeriod }, - { KEY.Connect_Timeout, KEY.Connect_Timeout }, + { KEY.PoolBlockingPeriod, KEY.PoolBlockingPeriod}, { KEY.Command_Timeout, KEY.Command_Timeout }, + { KEY.Connect_Timeout, KEY.Connect_Timeout }, { KEY.Connection_Reset, KEY.Connection_Reset }, { KEY.Context_Connection, KEY.Context_Connection }, { KEY.Current_Language, KEY.Current_Language }, @@ -812,7 +832,6 @@ internal static Dictionary GetParseSynonyms() { KEY.Max_Pool_Size, KEY.Max_Pool_Size }, { KEY.Min_Pool_Size, KEY.Min_Pool_Size }, { KEY.MultiSubnetFailover, KEY.MultiSubnetFailover }, - { KEY.TransparentNetworkIPResolution, KEY.TransparentNetworkIPResolution }, { KEY.Network_Library, KEY.Network_Library }, { KEY.Packet_Size, KEY.Packet_Size }, { KEY.Password, KEY.Password }, @@ -824,7 +843,7 @@ internal static Dictionary GetParseSynonyms() { KEY.Type_System_Version, KEY.Type_System_Version }, { KEY.ColumnEncryptionSetting, KEY.ColumnEncryptionSetting }, { KEY.EnclaveAttestationUrl, KEY.EnclaveAttestationUrl }, - { KEY.AttestationProtocol, KEY.AttestationProtocol }, + { KEY.AttestationProtocol, KEY.AttestationProtocol}, { KEY.User_ID, KEY.User_ID }, { KEY.User_Instance, KEY.User_Instance }, { KEY.Workstation_Id, KEY.Workstation_Id }, @@ -832,16 +851,14 @@ internal static Dictionary GetParseSynonyms() { KEY.Connect_Retry_Interval, KEY.Connect_Retry_Interval }, { KEY.Authentication, KEY.Authentication }, { KEY.IPAddressPreference, KEY.IPAddressPreference }, -#if ADONET_CERT_AUTH - { KEY.Certificate, KEY.Certificate }, -#endif - { SYNONYM.APPLICATIONINTENT, KEY.ApplicationIntent }, + { SYNONYM.APP, KEY.Application_Name }, + { SYNONYM.APPLICATIONINTENT, KEY.ApplicationIntent }, { SYNONYM.EXTENDED_PROPERTIES, KEY.AttachDBFilename }, { SYNONYM.INITIAL_FILE_NAME, KEY.AttachDBFilename }, - { SYNONYM.CONNECTION_TIMEOUT, KEY.Connect_Timeout }, { SYNONYM.CONNECTRETRYCOUNT, KEY.Connect_Retry_Count }, { SYNONYM.CONNECTRETRYINTERVAL, KEY.Connect_Retry_Interval }, + { SYNONYM.CONNECTION_TIMEOUT, KEY.Connect_Timeout }, { SYNONYM.TIMEOUT, KEY.Connect_Timeout }, { SYNONYM.LANGUAGE, KEY.Current_Language }, { SYNONYM.ADDR, KEY.Data_Source }, @@ -849,6 +866,7 @@ internal static Dictionary GetParseSynonyms() { SYNONYM.MULTIPLEACTIVERESULTSETS, KEY.MARS }, { SYNONYM.MULTISUBNETFAILOVER, KEY.MultiSubnetFailover }, { SYNONYM.NETWORK_ADDRESS, KEY.Data_Source }, + { SYNONYM.POOLBLOCKINGPERIOD, KEY.PoolBlockingPeriod}, { SYNONYM.SERVER, KEY.Data_Source }, { SYNONYM.DATABASE, KEY.Initial_Catalog }, { SYNONYM.TRUSTED_CONNECTION, KEY.Integrated_Security }, @@ -856,17 +874,22 @@ internal static Dictionary GetParseSynonyms() { SYNONYM.NET, KEY.Network_Library }, { SYNONYM.NETWORK, KEY.Network_Library }, { SYNONYM.Pwd, KEY.Password }, - { SYNONYM.POOLBLOCKINGPERIOD, KEY.PoolBlockingPeriod }, { SYNONYM.PERSISTSECURITYINFO, KEY.Persist_Security_Info }, - { SYNONYM.TRANSPARENTNETWORKIPRESOLUTION, KEY.TransparentNetworkIPResolution }, { SYNONYM.TRUSTSERVERCERTIFICATE, KEY.TrustServerCertificate }, { SYNONYM.UID, KEY.User_ID }, { SYNONYM.User, KEY.User_ID }, { SYNONYM.WSID, KEY.Workstation_Id }, +#if NETFRAMEWORK +#if ADONET_CERT_AUTH + { KEY.Certificate, KEY.Certificate }, +#endif + { KEY.TransparentNetworkIPResolution, KEY.TransparentNetworkIPResolution }, + { SYNONYM.TRANSPARENTNETWORKIPRESOLUTION, KEY.TransparentNetworkIPResolution }, +#endif // NETFRAMEWORK { SYNONYM.IPADDRESSPREFERENCE, KEY.IPAddressPreference } }; - Debug.Assert(count == synonyms.Count, "incorrect initial ParseSynonyms size"); - s_sqlClientSynonyms = synonyms; + Debug.Assert(synonyms.Count == count, "incorrect initial ParseSynonyms size"); + Interlocked.CompareExchange(ref s_sqlClientSynonyms, synonyms, null); } return synonyms; } @@ -888,47 +911,6 @@ internal string ObtainWorkstationId() return result; } - static internal Hashtable NetlibMapping() - { - const int NetLibCount = 8; - - Hashtable hash = _netlibMapping; - if (null == hash) - { - hash = new Hashtable(NetLibCount); - hash.Add(NETLIB.TCPIP, TdsEnums.TCP); - hash.Add(NETLIB.NamedPipes, TdsEnums.NP); - hash.Add(NETLIB.Multiprotocol, TdsEnums.RPC); - hash.Add(NETLIB.BanyanVines, TdsEnums.BV); - hash.Add(NETLIB.AppleTalk, TdsEnums.ADSP); - hash.Add(NETLIB.IPXSPX, TdsEnums.SPX); - hash.Add(NETLIB.VIA, TdsEnums.VIA); - hash.Add(NETLIB.SharedMemory, TdsEnums.LPC); - Debug.Assert(NetLibCount == hash.Count, "incorrect initial NetlibMapping size"); - _netlibMapping = hash; - } - return hash; - } - - static internal bool ValidProtocol(string protocol) - { - switch (protocol) - { - case TdsEnums.TCP: - case TdsEnums.NP: - case TdsEnums.VIA: - case TdsEnums.LPC: - return true; - - // case TdsEnums.RPC : Invalid Protocols - // case TdsEnums.BV : - // case TdsEnums.ADSP : - // case TdsEnums.SPX : - default: - return false; - } - } - private void ValidateValueLength(string value, int limit, string key) { if (limit < value.Length) @@ -939,7 +921,7 @@ private void ValidateValueLength(string value, int limit, string key) internal static void VerifyLocalHostAndFixup(ref string host, bool enforceLocalHost, bool fixup) { - if (ADP.IsEmpty(host)) + if (string.IsNullOrEmpty(host)) { if (fixup) { @@ -950,7 +932,7 @@ internal static void VerifyLocalHostAndFixup(ref string host, bool enforceLocalH !CompareHostName(ref host, @"(local)", fixup)) { // Fix-up completed in CompareHostName if return value true. - string name = ADP.GetComputerNameDnsFullyQualified(); // i.e, machine.location.corp.company.com + string name = GetComputerNameDnsFullyQualified(); // i.e, machine.location.corp.company.com if (!CompareHostName(ref host, name, fixup)) { int separatorPos = name.IndexOf('.'); // to compare just 'machine' part @@ -965,10 +947,25 @@ internal static void VerifyLocalHostAndFixup(ref string host, bool enforceLocalH } } - internal Microsoft.Data.SqlClient.ApplicationIntent ConvertValueToApplicationIntent() + private static string GetComputerNameDnsFullyQualified() { - string value; - if (!base.Parsetable.TryGetValue(KEY.ApplicationIntent, out value)) + try + { + var domainName = "." + IPGlobalProperties.GetIPGlobalProperties().DomainName; + var hostName = Dns.GetHostName(); + if (domainName != "." && !hostName.EndsWith(domainName)) + hostName += domainName; + return hostName; + } + catch (System.Net.Sockets.SocketException) + { + return Environment.MachineName; + } + } + + internal ApplicationIntent ConvertValueToApplicationIntent() + { + if (!TryGetParsetableValue(KEY.ApplicationIntent, out string value)) { return DEFAULT.ApplicationIntent; } @@ -990,39 +987,26 @@ internal Microsoft.Data.SqlClient.ApplicationIntent ConvertValueToApplicationInt // ArgumentException and other types are raised as is (no wrapping) } - internal Microsoft.Data.SqlClient.PoolBlockingPeriod ConvertValueToPoolBlockingPeriod() +#if NETCOREAPP || NETSTANDARD + internal void ThrowUnsupportedIfKeywordSet(string keyword) { - string value; - if (!base.Parsetable.TryGetValue(KEY.PoolBlockingPeriod, out value)) + if (ContainsKey(keyword)) { - 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); + throw SQL.UnsupportedKeyword(keyword); } } +#endif internal SqlAuthenticationMethod ConvertValueToAuthenticationType() { - string valStr; - if (!base.Parsetable.TryGetValue(KEY.Authentication, out valStr)) + if (!TryGetParsetableValue(KEY.Authentication, out string value)) { return DEFAULT.Authentication; } try { - return DbConnectionStringBuilderUtil.ConvertToAuthenticationType(KEY.Authentication, valStr); + return DbConnectionStringBuilderUtil.ConvertToAuthenticationType(KEY.Authentication, value); } catch (FormatException e) { @@ -1040,15 +1024,14 @@ internal SqlAuthenticationMethod ConvertValueToAuthenticationType() /// internal SqlConnectionColumnEncryptionSetting ConvertValueToColumnEncryptionSetting() { - string valStr; - if (!base.Parsetable.TryGetValue(KEY.ColumnEncryptionSetting, out valStr)) + if (!TryGetParsetableValue(KEY.ColumnEncryptionSetting, out string value)) { return DEFAULT.ColumnEncryptionSetting; } try { - return DbConnectionStringBuilderUtil.ConvertToColumnEncryptionSetting(KEY.ColumnEncryptionSetting, valStr); + return DbConnectionStringBuilderUtil.ConvertToColumnEncryptionSetting(KEY.ColumnEncryptionSetting, value); } catch (FormatException e) { @@ -1060,21 +1043,24 @@ internal SqlConnectionColumnEncryptionSetting ConvertValueToColumnEncryptionSett } } + /// + /// Convert the value to SqlConnectionAttestationProtocol + /// + /// internal SqlConnectionAttestationProtocol ConvertValueToAttestationProtocol() { - string valStr; - if (!base.Parsetable.TryGetValue(KEY.AttestationProtocol, out valStr)) + if (!TryGetParsetableValue(KEY.AttestationProtocol, out string value)) { return DEFAULT.AttestationProtocol; } try { - return DbConnectionStringBuilderUtil.ConvertToAttestationProtocol(KEY.AttestationProtocol, valStr); + return DbConnectionStringBuilderUtil.ConvertToAttestationProtocol(KEY.AttestationProtocol, value); } catch (FormatException e) { - throw ADP.InvalidConnectionOptionValue(KEY.AttestationProtocol, e); + throw ADP.InvalidConnectionOptionValue(KEY.AttestationProtocol, e); } catch (OverflowException e) { @@ -1088,15 +1074,14 @@ internal SqlConnectionAttestationProtocol ConvertValueToAttestationProtocol() /// internal SqlConnectionIPAddressPreference ConvertValueToIPAddressPreference() { - string valStr; - if (!base.Parsetable.TryGetValue(KEY.IPAddressPreference, out valStr)) + if (!TryGetParsetableValue(KEY.IPAddressPreference, out string value)) { - return DEFAULT.s_IPAddressPreference; + return DEFAULT.IpAddressPreference; } try { - return DbConnectionStringBuilderUtil.ConvertToIPAddressPreference(KEY.IPAddressPreference, valStr); + return DbConnectionStringBuilderUtil.ConvertToIPAddressPreference(KEY.IPAddressPreference, value); } catch (FormatException e) { @@ -1108,10 +1093,105 @@ internal SqlConnectionIPAddressPreference ConvertValueToIPAddressPreference() } } + internal PoolBlockingPeriod ConvertValueToPoolBlockingPeriod() + { + if (!TryGetParsetableValue(KEY.PoolBlockingPeriod, out string value)) + { + return DEFAULT.PoolBlockingPeriod; + } + + try + { + return DbConnectionStringBuilderUtil.ConvertToPoolBlockingPeriod(KEY.PoolBlockingPeriod, value); + } + catch (Exception e) when (e is FormatException || e is OverflowException) + { + throw ADP.InvalidConnectionOptionValue(KEY.PoolBlockingPeriod, e); + } + } + +#if NETFRAMEWORK + protected internal override PermissionSet CreatePermissionSet() + { + PermissionSet permissionSet = new(PermissionState.None); + permissionSet.AddPermission(new SqlClientPermission(this)); + return permissionSet; + } + internal bool ConvertValueToEncrypt() { - bool defaultEncryptValue = !base.Parsetable.ContainsKey(KEY.Authentication) ? DEFAULT.Encrypt : true; + bool defaultEncryptValue = !Parsetable.ContainsKey(KEY.Authentication) ? DEFAULT.Encrypt : true; return ConvertValueToBoolean(KEY.Encrypt, defaultEncryptValue); } + + static internal Hashtable NetlibMapping() + { + const int NetLibCount = 8; + + Hashtable hash = s_netlibMapping; + if (null == hash) + { + hash = new Hashtable(NetLibCount) + { + { NETLIB.TCPIP, TdsEnums.TCP }, + { NETLIB.NamedPipes, TdsEnums.NP }, + { NETLIB.Multiprotocol, TdsEnums.RPC }, + { NETLIB.BanyanVines, TdsEnums.BV }, + { NETLIB.AppleTalk, TdsEnums.ADSP }, + { NETLIB.IPXSPX, TdsEnums.SPX }, + { NETLIB.VIA, TdsEnums.VIA }, + { NETLIB.SharedMemory, TdsEnums.LPC } + }; + Debug.Assert(NetLibCount == hash.Count, "incorrect initial NetlibMapping size"); + s_netlibMapping = hash; + } + return hash; + } + static internal bool ValidProtocol(string protocol) + { + return protocol switch + { + TdsEnums.TCP or TdsEnums.NP or TdsEnums.VIA or TdsEnums.LPC => true, + // case TdsEnums.RPC : Invalid Protocols + // case TdsEnums.BV : + // case TdsEnums.ADSP : + // case TdsEnums.SPX : + _ => false, + }; + } + + // the following are all inserted as keys into the _netlibMapping hash + internal static class NETLIB + { + internal const string AppleTalk = "dbmsadsn"; + internal const string BanyanVines = "dbmsvinn"; + internal const string IPXSPX = "dbmsspxn"; + internal const string Multiprotocol = "dbmsrpcn"; + internal const string NamedPipes = "dbnmpntw"; + internal const string SharedMemory = "dbmslpcn"; + internal const string TCPIP = "dbmssocn"; + internal const string VIA = "dbmsgnet"; + } + + private static Hashtable s_netlibMapping; + private readonly bool _connectionReset; + private readonly bool _contextConnection; + private readonly bool _transparentNetworkIPResolution; + private readonly string _networkLibrary; + + internal bool ContextConnection => _contextConnection; + internal bool TransparentNetworkIPResolution => _transparentNetworkIPResolution; + internal string NetworkLibrary => _networkLibrary; + +#if ADONET_CERT_AUTH + private readonly string _certificate; + internal string Certificate => _certificate; + internal bool UsesCertificate => _authType == SqlAuthenticationMethod.SqlCertificate; +#else + internal string Certificate => null; + internal bool UsesCertificate => false; +#endif + +#endif // NETFRAMEWORK } } diff --git a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionTest.cs b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionTest.cs index 155a896f8a..1ca22db548 100644 --- a/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionTest.cs @@ -86,7 +86,7 @@ public void Constructor2_ConnectionString_Invalid() // Keyword not supported: 'invalidkeyword' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'invalidkeyword'") != -1); + Assert.True(ex.Message.IndexOf("'invalidkeyword'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // invalid packet size (< minimum) @@ -267,7 +267,7 @@ public void ConnectionString_Value_Invalid() // Keyword not supported: 'invalidkeyword' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'invalidkeyword'") != -1); + Assert.True(ex.Message.IndexOf("'invalidkeyword'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); } @@ -468,7 +468,7 @@ public void ConnectionString_ConnectTimeout_Invalid() // Invalid value for key 'connect timeout' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'connect timeout'") != -1); + Assert.True(ex.Message.IndexOf("'connect timeout'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // invalid number @@ -477,7 +477,7 @@ public void ConnectionString_ConnectTimeout_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(FormatException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'connect timeout'") != -13); + Assert.True(ex.Message.IndexOf("'connect timeout'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Input string was not in a correct format @@ -491,7 +491,7 @@ public void ConnectionString_ConnectTimeout_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(OverflowException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'connect timeout'") != -1); + Assert.True(ex.Message.IndexOf("'connect timeout'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Value was either too large or too small for an Int32 @@ -526,7 +526,7 @@ public void ConnectionString_CommandTimeout_Invalid() // Invalid value for key 'connect timeout' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'command timeout'") != -1); + Assert.True(ex.Message.IndexOf("'command timeout'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // invalid number @@ -535,7 +535,7 @@ public void ConnectionString_CommandTimeout_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(FormatException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'command timeout'") != -13); + Assert.True(ex.Message.IndexOf("'command timeout'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Input string was not in a correct format @@ -549,7 +549,7 @@ public void ConnectionString_CommandTimeout_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(OverflowException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'command timeout'") != -1); + Assert.True(ex.Message.IndexOf("'command timeout'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Value was either too large or too small for an Int32 @@ -634,7 +634,7 @@ public void ConnectionString_MaxPoolSize_Invalid() // Invalid value for key 'max pool size' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'max pool size'") != -1); + Assert.True(ex.Message.IndexOf("'max pool size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // invalid number @@ -643,7 +643,7 @@ public void ConnectionString_MaxPoolSize_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(FormatException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'max pool size'") != -1); + Assert.True(ex.Message.IndexOf("'max pool size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Input string was not in a correct format @@ -657,7 +657,7 @@ public void ConnectionString_MaxPoolSize_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(OverflowException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'max pool size'") != -1); + Assert.True(ex.Message.IndexOf("'max pool size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Value was either too large or too small for an Int32 @@ -670,7 +670,7 @@ public void ConnectionString_MaxPoolSize_Invalid() // Invalid value for key 'max pool size' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'max pool size'") != -1); + Assert.True(ex.Message.IndexOf("'max pool size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // less than min pool size @@ -702,7 +702,7 @@ public void ConnectionString_MinPoolSize_Invalid() // Invalid value for key 'min pool size' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'min pool size'") != -1); + Assert.True(ex.Message.IndexOf("'min pool size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // invalid number @@ -711,7 +711,7 @@ public void ConnectionString_MinPoolSize_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(FormatException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'min pool size'") != -1); + Assert.True(ex.Message.IndexOf("'min pool size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Input string was not in a correct format @@ -725,7 +725,7 @@ public void ConnectionString_MinPoolSize_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(OverflowException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'min pool size'") != -1); + Assert.True(ex.Message.IndexOf("'min pool size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Value was either too large or too small for an Int32 @@ -750,7 +750,7 @@ public void ConnectionString_MultipleActiveResultSets_Invalid() // Invalid value for key 'multiple active result sets' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'multiple active result sets'") != -1); + Assert.True(ex.Message.IndexOf("'multiple active result sets'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); } @@ -781,7 +781,7 @@ public void ConnectionString_PacketSize_Invalid() // integer >= 512 and <= 32768 Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'Packet Size'") != -1); + Assert.True(ex.Message.IndexOf("'Packet Size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // invalid packet size (> maximum) @@ -790,7 +790,7 @@ public void ConnectionString_PacketSize_Invalid() // integer >= 512 and <= 32768 Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'Packet Size'") != -1); + Assert.True(ex.Message.IndexOf("'Packet Size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // overflow @@ -799,7 +799,7 @@ public void ConnectionString_PacketSize_Invalid() Assert.NotNull(ex.InnerException); Assert.Equal(typeof(OverflowException), ex.InnerException.GetType()); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'packet size'") != -1); + Assert.True(ex.Message.IndexOf("'packet size'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); // Value was either too large or too small for an Int32 @@ -849,7 +849,7 @@ public void ConnectionString_UserInstance_Invalid() // Invalid value for key 'user instance' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.True(ex.Message.IndexOf("'user instance'") != -1); + Assert.True(ex.Message.IndexOf("'user instance'", StringComparison.OrdinalIgnoreCase) != -1); Assert.Null(ex.ParamName); } @@ -1009,7 +1009,7 @@ public void ConnectionString_IPAddressPreference_Invalid(string value) // Invalid value for key 'ip address preference' Assert.Null(ex.InnerException); Assert.NotNull(ex.Message); - Assert.Contains("'ip address preference'", ex.Message); + Assert.Contains("'ip address preference'", ex.Message, StringComparison.OrdinalIgnoreCase); Assert.Null(ex.ParamName); } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/AADConnectionTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/AADConnectionTest.cs index 9ba857b7c3..90405689ab 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/AADConnectionTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/AADConnectionTest.cs @@ -186,7 +186,7 @@ public static void InvalidAuthTypeTest() ArgumentException e = Assert.Throws(() => ConnectAndDisconnect(connStr)); string expectedMessage = "Invalid value for key 'authentication'."; - Assert.Contains(expectedMessage, e.Message); + Assert.Contains(expectedMessage, e.Message, StringComparison.OrdinalIgnoreCase); } [ConditionalFact(nameof(IsAADConnStringsSetup))]