diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/DbConnectionOptions.Common.cs b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/DbConnectionOptions.Common.cs index 470425d3fb..635674dde8 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/DbConnectionOptions.Common.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Common/src/Microsoft/Data/Common/DbConnectionOptions.Common.cs @@ -101,7 +101,6 @@ private static class SYNONYM private readonly string _usersConnectionString; private readonly Dictionary _parsetable; internal readonly NameValuePair _keyChain; - internal readonly bool _hasPasswordKeyword; internal Dictionary Parsetable { @@ -114,14 +113,14 @@ public string UsersConnectionString(bool hidePassword) => private string UsersConnectionString(bool hidePassword, bool forceHidePassword) { string connectionString = _usersConnectionString; - if (_hasPasswordKeyword && (forceHidePassword || (hidePassword && !HasPersistablePassword))) + if (HasPasswordKeyword && (forceHidePassword || (hidePassword && !HasPersistablePassword))) { ReplacePasswordPwd(out connectionString, false); } return connectionString ?? string.Empty; } - internal bool HasPersistablePassword => _hasPasswordKeyword ? + internal bool HasPersistablePassword => HasPasswordKeyword ? ConvertValueToBoolean(KEY.Persist_Security_Info, false) : true; // no password means persistable password so we don't have to munge diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs index 8d1a7043ba..c90bb1f3bf 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/Common/DbConnectionOptions.cs @@ -32,8 +32,7 @@ public DbConnectionOptions(string connectionString, Dictionary s protected DbConnectionOptions(DbConnectionOptions connectionOptions) { // Clone used by SqlConnectionString - _usersConnectionString = connectionOptions._usersConnectionString; - _hasPasswordKeyword = connectionOptions._hasPasswordKeyword; + _usersConnectionString = connectionOptions._usersConnectionString; _parsetable = connectionOptions._parsetable; _keyChain = connectionOptions._keyChain; HasPasswordKeyword = connectionOptions.HasPasswordKeyword; diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 606a91e458..ea3def41a0 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -260,6 +260,11 @@ public static bool IsUTF8Supported() return retval; } + public static bool IsTCPConnectionStringPasswordIncluded() + { + return RetrieveValueFromConnStr(TCPConnectionString, new string[] { "Password", "PWD" }) != string.Empty; + } + // the name length will be no more then (16 + prefix.Length + escapeLeft.Length + escapeRight.Length) // some providers does not support names (Oracle supports up to 30) public static string GetUniqueName(string prefix) @@ -575,23 +580,26 @@ public static string RemoveKeysInConnStr(string connStr, string[] keysToRemove) { // tokenize connection string and remove input keys. string res = ""; - string[] keys = connStr.Split(';'); - foreach (var key in keys) + if (connStr != null && keysToRemove != null) { - if (!string.IsNullOrEmpty(key.Trim())) + string[] keys = connStr.Split(';'); + foreach (var key in keys) { - bool removeKey = false; - foreach (var keyToRemove in keysToRemove) + if (!string.IsNullOrEmpty(key.Trim())) { - if (key.Trim().ToLower().StartsWith(keyToRemove.Trim().ToLower())) + bool removeKey = false; + foreach (var keyToRemove in keysToRemove) { - removeKey = true; - break; + if (key.Trim().ToLower().StartsWith(keyToRemove.Trim().ToLower())) + { + removeKey = true; + break; + } + } + if (!removeKey) + { + res += key + ";"; } - } - if (!removeKey) - { - res += key + ";"; } } } @@ -602,17 +610,20 @@ public static string RetrieveValueFromConnStr(string connStr, string[] keywords) { // tokenize connection string and retrieve value for a specific key. string res = ""; - string[] keys = connStr.Split(';'); - foreach (var key in keys) + if (connStr != null && keywords != null) { - foreach (var keyword in keywords) + string[] keys = connStr.Split(';'); + foreach (var key in keys) { - if (!string.IsNullOrEmpty(key.Trim())) + foreach (var keyword in keywords) { - if (key.Trim().ToLower().StartsWith(keyword.Trim().ToLower())) + if (!string.IsNullOrEmpty(key.Trim())) { - res = key.Substring(key.IndexOf('=') + 1).Trim(); - break; + if (key.Trim().ToLower().StartsWith(keyword.Trim().ToLower())) + { + res = key.Substring(key.IndexOf('=') + 1).Trim(); + break; + } } } } diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs index eb2b0e9e65..2b9afa44b1 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ConnectivityTests/ConnectivityTest.cs @@ -10,7 +10,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests { - public static class ConnectivityParametersTest + public static class ConnectivityTest { private const string COL_SPID = "SPID"; private const string COL_PROGRAM_NAME = "ProgramName"; @@ -276,5 +276,33 @@ public static void ConnectionResiliencyTest() } } } + + [ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.IsTCPConnectionStringPasswordIncluded))] + public static void ConnectionStringPersistantInfoTest() + { + SqlConnectionStringBuilder connectionStringBuilder = new SqlConnectionStringBuilder(DataTestUtility.TCPConnectionString); + connectionStringBuilder.PersistSecurityInfo = false; + string cnnString = connectionStringBuilder.ConnectionString; + + connectionStringBuilder.Clear(); + using (SqlConnection sqlCnn = new SqlConnection(cnnString)) + { + sqlCnn.Open(); + connectionStringBuilder.ConnectionString = sqlCnn.ConnectionString; + Assert.True(connectionStringBuilder.Password == string.Empty, "Password must not persist according to set the PersistSecurityInfo by false!"); + } + + connectionStringBuilder.ConnectionString = DataTestUtility.TCPConnectionString; + connectionStringBuilder.PersistSecurityInfo = true; + cnnString = connectionStringBuilder.ConnectionString; + + connectionStringBuilder.Clear(); + using (SqlConnection sqlCnn = new SqlConnection(cnnString)) + { + sqlCnn.Open(); + connectionStringBuilder.ConnectionString = sqlCnn.ConnectionString; + Assert.True(connectionStringBuilder.Password != string.Empty, "Password must persist according to set the PersistSecurityInfo by true!"); + } + } } }