diff --git a/AdvancedConnectivityPolicyTests.ps1 b/AdvancedConnectivityPolicyTests.ps1 index fee642e..64c7a08 100644 --- a/AdvancedConnectivityPolicyTests.ps1 +++ b/AdvancedConnectivityPolicyTests.ps1 @@ -137,6 +137,9 @@ $EncryptionProtocol = $parameters['EncryptionProtocol'] $RepositoryBranch = $parameters['RepositoryBranch'] $Local = $parameters['Local'] $LocalPath = $parameters['LocalPath'] +$TrustServerCertificate = $parameters['TrustServerCertificate'] +$EncryptionOption = $parameters['EncryptionOption'] + if ([string]::IsNullOrEmpty($env:TEMP)) { @@ -153,6 +156,7 @@ try { else { $path = $env:TEMP + "/AzureSQLConnectivityChecker/TDSClient.dll" Invoke-WebRequest -Uri $('https://github.com/Azure/SQL-Connectivity-Checker/raw/' + $RepositoryBranch + '/netstandard2.0/TDSClient.dll') -OutFile $path -UseBasicParsing + } $path = $env:TEMP + "/AzureSQLConnectivityChecker/TDSClient.dll" @@ -185,7 +189,7 @@ try { $encryption = [System.Security.Authentication.SslProtocols]::Tls12 -bor [System.Security.Authentication.SslProtocols]::Tls11 -bor [System.Security.Authentication.SslProtocols]::Default } } - $tdsClient = [TDSClient.TDS.Client.TDSSQLTestClient]::new($Server, $Port, $User, $Password, $Database, $encryption) + $tdsClient = [TDSClient.TDS.Client.TDSSQLTestClient]::new($Server, $Port, $User, $Password, $Database, $TrustServerCertificate, $EncryptionOption, $encryption) $tdsClient.Connect() $tdsClient.Disconnect() } diff --git a/AzureSQLConnectivityChecker.ps1 b/AzureSQLConnectivityChecker.ps1 index 421df96..56f28a8 100644 --- a/AzureSQLConnectivityChecker.ps1 +++ b/AzureSQLConnectivityChecker.ps1 @@ -57,6 +57,14 @@ if ($null -ne $parameters) { if ($null -ne $parameters['RepositoryBranch']) { $RepositoryBranch = $parameters['RepositoryBranch'] } + if($null -ne $parameters['TrustServerCertificate']){ + $TrustServerCertificate = $parameters['TrustServerCertificate'] + } + write-host $TrustServerCertificate + if($null -ne $parameters['EncryptionOption']){ + $EncryptionOption = $parameters['EncryptionOption'] + } + write-host $EncryptionOption } $Server = $Server.Trim() @@ -65,6 +73,8 @@ $Server = $Server.Replace(',1433', '') $Server = $Server.Replace(',3342', '') $Server = $Server.Replace(';', '') +$flag = $false + if ($null -eq $User -or '' -eq $User) { $User = 'AzSQLConnCheckerUser' } @@ -224,7 +234,50 @@ function PrintDNSResults($dnsResult, [string] $dnsSource) { } } -function ValidateDNS([String] $Server) { +function ValidateDnsHelper([string] $Server1){ + $flag = ValidateDNS $Server + if($flag -eq $false){ + $flag = ValidateDNS ($Server1 + '.database.windows.net') + if($flag -eq $true){ + $Server1 = ($Server + '.database.windows.net') + } + } + if($flag -eq $false){ + $flag = ValidateDNS $Server1 + '.database.cloudapi.de' + if($flag -eq $true){ + $Server1 = ($Server + '.database.cloudapi.de') + } + } + if($flag -eq $false){ + $flag = ValidateDNS ($Server1 + '.database.chinacloudapi.cn') + if($flag -eq $true){ + $Server1 = ($Server + '.database.chinacloudapi.cn') + } + } + if($flag -eq $false){ + $flag = ValidateDNS ($Server1 + '.database.usgovcloudapi.net') + if($flag -eq $true){ + $Server1 = ($Server + '.database.usgovcloudapi.net') + } + } + if($flag -eq $false){ + $flag = ValidateDNS ($Server1 + '.sql.azuresynapse.net') + if($flag -eq $true){ + $Server1 = ($Server + '.sql.azuresynapse.net') + } + } + if($flag -eq $true){ + $Server = $Server1 + Write-Host $Server + return [bool]($flag), $Server1 + }else{ + Write-Host "Error at ValidateDNS" -Foreground Red + Write-Host "Server cant be Validated" -Foreground Red + $host.exit() + } +} + +function ValidateDNS([string] $Server) { Try { Write-Host 'Validating DNS record for' $Server -ForegroundColor Green @@ -239,6 +292,8 @@ function ValidateDNS([String] $Server) { $DNSfromAzureDNS = Resolve-DnsName -Name $Server -DnsOnly -Server 208.67.222.222 -ErrorAction SilentlyContinue PrintDNSResults $DNSfromAzureDNS 'Open DNS' + + return [bool]($DNSfromAzureDNS -or $DNSfromCache -or $DNSfromCustomerServer -or $DNSfromHosts) } Catch { Write-Host "Error at ValidateDNS" -Foreground Red @@ -246,6 +301,14 @@ function ValidateDNS([String] $Server) { } } +function CheckIfIpAddress([string] $Server){ + if($Server -match "\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"){ + return $true + }else{ + return $false + } +} + function IsManagedInstance([String] $Server) { return [bool]((($Server.ToCharArray() | Where-Object { $_ -eq '.' } | Measure-Object).Count) -ge 4) } @@ -476,7 +539,7 @@ function RunSqlDBConnectivityTests($resolvedAddress) { } $gateway = $SQLDBGateways | Where-Object { $_.Gateways -eq $resolvedAddress } - if (!$gateway) { + if (!$gateway -and !($resolvedAddress -eq '127.0.0.1') -and !($resolvedAddress -eq '::1')) { Write-Host ' ERROR:' $resolvedAddress 'is not a valid gateway address' -ForegroundColor Red Write-Host ' Please review your DNS configuration, it should resolve to a valid gateway address' -ForegroundColor Red Write-Host ' See the valid gateway addresses at https://docs.microsoft.com/en-us/azure/sql-database/sql-database-connectivity-architecture#azure-sql-database-gateway-ip-addresses' -ForegroundColor Red @@ -574,6 +637,8 @@ function RunConnectivityPolicyTests($port) { RepositoryBranch = $RepositoryBranch Local = $Local LocalPath = $LocalPath + TrustServerCertificate = $TrustServerCertificate + EncryptionOption = $EncryptionOption } if (Test-Path "$env:TEMP\AzureSQLConnectivityChecker\") { @@ -584,6 +649,7 @@ function RunConnectivityPolicyTests($port) { if ($Local) { Copy-Item -Path $($LocalPath + './AdvancedConnectivityPolicyTests.ps1') -Destination "$env:TEMP\AzureSQLConnectivityChecker\AdvancedConnectivityPolicyTests.ps1" + } else { Invoke-WebRequest -Uri $('https://raw.githubusercontent.com/Azure/SQL-Connectivity-Checker/' + $RepositoryBranch + '/AdvancedConnectivityPolicyTests.ps1') -OutFile "$env:TEMP\AzureSQLConnectivityChecker\AdvancedConnectivityPolicyTests.ps1" -UseBasicParsing @@ -694,13 +760,13 @@ try { throw } - if (!$Server.EndsWith('.database.windows.net') ` - -and !$Server.EndsWith('.database.cloudapi.de') ` - -and !$Server.EndsWith('.database.chinacloudapi.cn') ` - -and !$Server.EndsWith('.database.usgovcloudapi.net') ` - -and !$Server.EndsWith('.sql.azuresynapse.net')) { - $Server = $Server + '.database.windows.net' - } + #if (!$Server.EndsWith('.database.windows.net') ` + # -and !$Server.EndsWith('.database.cloudapi.de') ` + # -and !$Server.EndsWith('.database.chinacloudapi.cn') ` + # -and !$Server.EndsWith('.database.usgovcloudapi.net') ` + # -and !$Server.EndsWith('.sql.azuresynapse.net')) { + # $Server = $Server + '.database.windows.net' + #} #Print local network configuration PrintLocalNetworkConfiguration @@ -718,20 +784,33 @@ try { } } - ValidateDNS $Server + $checkIP = CheckIfIpAddress $Server - try { - $dnsResult = [System.Net.DNS]::GetHostEntry($Server) - } - catch { - Write-Host ' ERROR: Name resolution of' $Server 'failed' -ForegroundColor Red - Write-Host ' Please make sure the server name FQDN is correct and that your machine can resolve it.' -ForegroundColor Red - Write-Host ' Failure to resolve domain name for your logical server is almost always the result of specifying an invalid/misspelled server name,' -ForegroundColor Red - Write-Host ' or a client-side networking issue that you will need to pursue with your local network administrator.' -ForegroundColor Red - Write-Error '' -ErrorAction Stop + if($checkIP -eq $false){ + $return = ValidateDnsHelper $Server + $Server = $return[1] + $success = $return[0] + + + try { + $dnsResult = [System.Net.DNS]::GetHostEntry($Server) + } + + catch { + Write-Host ' ERROR: Name resolution of' $Server 'failed' -ForegroundColor Red + Write-Host ' Please make sure the server name FQDN is correct and that your machine can resolve it.' -ForegroundColor Red + Write-Host ' Failure to resolve domain name for your logical server is almost always the result of specifying an invalid/misspelled server name,' -ForegroundColor Red + Write-Host ' or a client-side networking issue that you will need to pursue with your local network administrator.' -ForegroundColor Red + Write-Error '' -ErrorAction Stop } - $resolvedAddress = $dnsResult.AddressList[0].IPAddressToString - $dbPort = 1433 + $resolvedAddress = $dnsResult.AddressList[0].IPAddressToString + $dbPort = 1433 + }else{ + $resolvedAddress = $Server + $dbPort = 1433 + } + + write-host $resolvedAddress #Run connectivity tests Write-Host diff --git a/README.md b/README.md index 4f9a28c..bb54ee8 100644 --- a/README.md +++ b/README.md @@ -18,14 +18,16 @@ $parameters = @{ # Supports Single, Elastic Pools and Managed Instance (please provide FQDN, MI public endpoint is supported) # Supports Azure Synapse / Azure SQL Data Warehouse (*.sql.azuresynapse.net / *.database.windows.net) # Supports Public Cloud (*.database.windows.net), Azure China (*.database.chinacloudapi.cn), Azure Germany (*.database.cloudapi.de) and Azure Government (*.database.usgovcloudapi.net) - Server = '.database.windows.net' # or any other supported FQDN - Database = '' # Set the name of the database you wish to test, 'master' will be used by default if nothing is set - User = '' # Set the login username you wish to use, 'AzSQLConnCheckerUser' will be used by default if nothing is set - Password = '' # Set the login password you wish to use, 'AzSQLConnCheckerPassword' will be used by default if nothing is set + Server = 'localhost' # or any other supported FQDN + Database = 'master' # Set the name of the database you wish to test, 'master' will be used by default if nothing is set + User = 'admin' # Set the login username you wish to use, 'AzSQLConnCheckerUser' will be used by default if nothing is set + Password = 'admin' # Set the login password you wish to use, 'AzSQLConnCheckerPassword' will be used by default if nothing is set + TrustServerCertificate = '' #Boolean value, 'true' will be used by default if nothing is set + EncryptionOption = '' # TDS Encryption option sent by the client, can be: 'EncryptOn', 'EncryptOff', 'EncryptNotSup', 'EncryptReq', 'EncryptClientCertOff', 'EncryptClientCertOn', 'EncryptClientCertReq', 'EncryptOn' will be used by default if nothing is set ## Optional parameters (default values will be used if omitted) SendAnonymousUsageData = $true # Set as $true (default) or $false - RunAdvancedConnectivityPolicyTests = $true # Set as $true (default) or $false, this will load the library from Microsoft's GitHub repository needed for running advanced connectivity tests + RunAdvancedConnectivityPolicyTests = $false # Set as $true (default) or $false, this will load the library from Microsoft's GitHub repository needed for running advanced connectivity tests CollectNetworkTrace = $true # Set as $true (default) or $false #EncryptionProtocol = '' # Supported values: 'Tls 1.0', 'Tls 1.1', 'Tls 1.2'; Without this parameter operating system will choose the best protocol to use } diff --git a/ReducedSQLConnectivityChecker.ps1 b/ReducedSQLConnectivityChecker.ps1 index 0506439..7bae41f 100644 --- a/ReducedSQLConnectivityChecker.ps1 +++ b/ReducedSQLConnectivityChecker.ps1 @@ -9,6 +9,8 @@ if ($null -ne $parameters) { if ($null -ne $parameters['RepositoryBranch']) { $RepositoryBranch = $parameters['RepositoryBranch'] } + $TrustServerCertificate = $parameters['TrustServerCertificate'] + $EncryptionOption = $parameters['EncryptionOption'] } $Server = $Server.Trim() @@ -35,6 +37,14 @@ if ($null -eq $Local) { if ($null -eq $RepositoryBranch) { $RepositoryBranch = 'master' +} + +if ($null -eq $TrustServerCertificate -or '' -eq $TrustServerCertificate){ + $TrustServerCertificate = $true +} + +if ($null -eq $EncryptionOption -or '' -eq $EncryptionOption){ + $EncryptionOption = 'EncryptOn' } # PowerShell Container Image Support Start @@ -223,13 +233,13 @@ try { throw } - if (!$Server.EndsWith('.database.windows.net') ` - -and !$Server.EndsWith('.database.cloudapi.de') ` - -and !$Server.EndsWith('.database.chinacloudapi.cn') ` - -and !$Server.EndsWith('.sql.azuresynapse.net')) { - $Server = $Server + '.database.windows.net' - } - + # if (!$Server.EndsWith('.database.windows.net') ` + # -and !$Server.EndsWith('.database.cloudapi.de') ` + # -and !$Server.EndsWith('.database.chinacloudapi.cn') ` + # -and !$Server.EndsWith('.sql.azuresynapse.net')) { + # $Server = $Server + '.database.windows.net' + # } + if ($SendAnonymousUsageData) { SendAnonymousUsageData } @@ -281,7 +291,7 @@ try { $Port = 3342 } - $tdsClient = [TDSClient.TDS.Client.TDSSQLTestClient]::new($Server, $Port, $User, $Password, $Database, $encryption) + $tdsClient = [TDSClient.TDS.Client.TDSSQLTestClient]::new($Server, $Port, $User, $Password, $Database, $encryption, $TrustServerCertificate, $EncryptionOption) $tdsClient.Connect() $tdsClient.Disconnect() } diff --git a/RunLocally.ps1 b/RunLocally.ps1 index 3692295..0fff80f 100644 --- a/RunLocally.ps1 +++ b/RunLocally.ps1 @@ -3,16 +3,20 @@ $LocalPath = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definiti # Script parameters $parameters = @{ - Server = '.database.windows.net' - Database = '' # Set the name of the database you wish to test, 'master' will be used by default if nothing is set - User = '' # Set the login username you wish to use, 'AzSQLConnCheckerUser' will be used by default if nothing is set - Password = '' # Set the login password you wish to use, 'AzSQLConnCheckerPassword' will be used by default if nothing is set + Server = 'localhost' + Database = 'master' # Set the name of the database you wish to test, 'master' will be used by default if nothing is set + User = 'admin' # Set the login username you wish to use, 'AzSQLConnCheckerUser' will be used by default if nothing is set + Password = 'admin' # Set the login password you wish to use, 'AzSQLConnCheckerPassword' will be used by default if nothing is set + TrustServerCertificate = 'true' #Boolean value, 'true' will be used by default if nothing is set + EncryptionOption = 'EncryptNotSup' # TDS Encryption option sent by the client, can be: 'EncryptOn', 'EncryptOff', 'EncryptNotSup', 'EncryptReq', 'EncryptClientCertOff', 'EncryptClientCertOn', 'EncryptClientCertReq', 'EncryptOn' will be used by default if nothing is set + + ## Optional parameters (default values will be used if ommited) SendAnonymousUsageData = $true # Set as $true (default) or $false RunAdvancedConnectivityPolicyTests = $true # Set as $true (default) or $false, this will download the library needed for running advanced connectivity tests CollectNetworkTrace = $true # Set as $true (default) or $false - #EncryptionProtocol = '' # Supported values: 'Tls 1.0', 'Tls 1.1', 'Tls 1.2'; Without this parameter operating system will choose the best protocol to use + EncryptionProtocol = 'Tls 1.2' # Supported values: 'Tls 1.0', 'Tls 1.1', 'Tls 1.2'; Without this parameter operating system will choose the best protocol to use ## Run locally parameters Local = $true # Do Not Change diff --git a/TDSClient/TDSClient.UnitTests/TDSClient.UnitTests.csproj b/TDSClient/TDSClient.UnitTests/TDSClient.UnitTests.csproj index 981ab35..88056de 100644 --- a/TDSClient/TDSClient.UnitTests/TDSClient.UnitTests.csproj +++ b/TDSClient/TDSClient.UnitTests/TDSClient.UnitTests.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + netcoreapp2.1 false diff --git a/TDSClient/TDSClient/TDS/Client/TDSClientVersion.cs b/TDSClient/TDSClient/TDS/Client/TDSClientVersion.cs index 51577b2..caa6aea 100644 --- a/TDSClient/TDSClient/TDS/Client/TDSClientVersion.cs +++ b/TDSClient/TDSClient/TDS/Client/TDSClientVersion.cs @@ -111,4 +111,4 @@ public bool Equals(TDSClientVersion other) this.SubBuildNumber == other.SubBuildNumber; } } -} +} \ No newline at end of file diff --git a/TDSClient/TDSClient/TDS/Client/TDSSQLTestClient.cs b/TDSClient/TDSClient/TDS/Client/TDSSQLTestClient.cs index 8715521..24fe080 100644 --- a/TDSClient/TDSClient/TDS/Client/TDSSQLTestClient.cs +++ b/TDSClient/TDSClient/TDS/Client/TDSSQLTestClient.cs @@ -35,13 +35,13 @@ public class TDSSQLTestClient /// User password /// Database to connect to /// Encryption Protocol - public TDSSQLTestClient(string server, int port, string userID, string password, string database, SslProtocols encryptionProtocol = SslProtocols.Tls12) + public TDSSQLTestClient(string server, int port, string userID, string password, string database, Boolean TrustServerCertficate, string EncryptionOption, SslProtocols encryptionProtocol = SslProtocols.Tls12) { if (string.IsNullOrEmpty(server) || string.IsNullOrEmpty(userID) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(database)) { throw new ArgumentNullException(); } - + LoggingUtilities.WriteLog($"Nije sa githuba"); this.Client = null; this.Version = new TDSClientVersion(1, 0, 0, 0); this.Server = server; @@ -51,6 +51,52 @@ public TDSSQLTestClient(string server, int port, string userID, string password, this.Password = password; this.Database = database; this.EncryptionProtocol = encryptionProtocol; + this.TrustServerCertificate = TrustServerCertficate; + LoggingUtilities.WriteLog(EncryptionOption); + + switch (EncryptionOption) + { + case "EncryptOn": + { + this.EncryptionOption = TDSEncryptionOption.EncryptOn; + break; + } + case "EncryptOff": + { + this.EncryptionOption = TDSEncryptionOption.EncryptOff; + break; + } + case "EncryptReq": + { + this.EncryptionOption = TDSEncryptionOption.EncryptReq; + break; + } + case "EncryptNotSup": + { + this.EncryptionOption = TDSEncryptionOption.EncryptNotSup; + break; + } + case "EncryptClientCertOn": + { + this.EncryptionOption = TDSEncryptionOption.EncryptClientCertOn; + break; + } + case "EncryptClientCertOff": + { + this.EncryptionOption = TDSEncryptionOption.EncryptClientCertOff; + break; + } + case "EncryptClientCertReq": + { + this.EncryptionOption = TDSEncryptionOption.EncryptClientCertReq; + break; + } + default: + { + + throw new InvalidOperationException(); + } + } LoggingUtilities.WriteLog($" Instantiating TDSSQLTestClient with the following parameters:"); @@ -58,12 +104,28 @@ public TDSSQLTestClient(string server, int port, string userID, string password, LoggingUtilities.WriteLog($" Port: {port}."); LoggingUtilities.WriteLog($" UserID: {userID}."); LoggingUtilities.WriteLog($" Database: {database}."); + LoggingUtilities.WriteLog($" TrustServerCertificate: {TrustServerCertificate}."); + LoggingUtilities.WriteLog($" EncryptionOption: {EncryptionOption}."); } + /// + /// Gets or sets the Encryption Option + /// + public TDSEncryptionOption EncryptionOption { get; set; } + + /// + /// Gets or sets TrustServerCertificate. + /// + public Boolean TrustServerCertificate { get; set; } + /// /// Gets or sets the Server. /// public string Server { get; set; } + /// + /// Server Encryption Reply sent in PreLoginResponse package. + /// + public static TDSEncryptionOption flag = TDSEncryptionOption.EncryptOn; /// /// Gets or sets the Server Name. @@ -118,7 +180,8 @@ public void SendPreLogin() LoggingUtilities.WriteLog($" SendPreLogin initiated."); var tdsMessageBody = new TDSPreLoginPacketData(this.Version); - tdsMessageBody.AddOption(TDSPreLoginOptionTokenType.Encryption, TDSEncryptionOption.EncryptOff); + //tdsMessageBody.AddOption(TDSPreLoginOptionTokenType.Encryption, TDSEncryptionOption.EncryptOn); + tdsMessageBody.AddOption(TDSPreLoginOptionTokenType.Encryption, this.EncryptionOption); tdsMessageBody.AddOption(TDSPreLoginOptionTokenType.TraceID, new TDSClientTraceID(Guid.NewGuid().ToByteArray(), Guid.NewGuid().ToByteArray(), 0)); tdsMessageBody.Terminate(); @@ -153,6 +216,8 @@ public void SendLogin7() tdsMessageBody.OptionFlags2.Language = TDSLogin7OptionFlags2Language.InitLangFatal; tdsMessageBody.OptionFlags2.ODBC = TDSLogin7OptionFlags2ODBC.OdbcOn; tdsMessageBody.OptionFlags2.UserType = TDSLogin7OptionFlags2UserType.UserNormal; + //Row below added + //tdsMessageBody.OptionFlags2.IntSecurity = TDSLogin7OptionFlags2IntSecurity.IntegratedSecurityOn; tdsMessageBody.OptionFlags3.ChangePassword = TDSLogin7OptionFlags3ChangePassword.NoChangeRequest; tdsMessageBody.OptionFlags3.UserInstanceProcess = TDSLogin7OptionFlags3UserInstanceProcess.DontRequestSeparateProcess; @@ -177,8 +242,14 @@ public void ReceivePreLoginResponse() if (this.TdsCommunicator.ReceiveTDSMessage() is TDSPreLoginPacketData response) { - if (response.Options.Exists(opt => opt.Type == TDSPreLoginOptionTokenType.Encryption) && response.Encryption == TDSEncryptionOption.EncryptReq) + if (response.Options.Exists(opt => opt.Type == TDSPreLoginOptionTokenType.Encryption) && (response.Encryption == TDSEncryptionOption.EncryptReq && this.EncryptionOption == TDSEncryptionOption.EncryptNotSup)) + { + throw new NotSupportedException("Server requires encryption and has closed the connection"); + } + + if (response.Options.Exists(opt => opt.Type == TDSPreLoginOptionTokenType.Encryption) && (response.Encryption == TDSEncryptionOption.EncryptReq || response.Encryption == TDSEncryptionOption.EncryptOn || response.Encryption == TDSEncryptionOption.EncryptOff)) { + flag = response.Encryption; LoggingUtilities.WriteLog($" Server requires encryption, enabling encryption."); this.TdsCommunicator.EnableEncryption(this.Server, this.EncryptionProtocol); LoggingUtilities.WriteLog($" Encryption enabled."); @@ -188,6 +259,8 @@ public void ReceivePreLoginResponse() { throw new NotSupportedException("FedAuth is being requested but the client doesn't support FedAuth."); } + + } else { @@ -271,10 +344,14 @@ public void Connect() { this.reconnect = false; this.Client = new TcpClient(this.Server, this.Port); - this.TdsCommunicator = new TDSCommunicator(this.Client.GetStream(), 4096); + this.TdsCommunicator = new TDSCommunicator(this.Client.GetStream(), 4096, this.TrustServerCertificate); this.SendPreLogin(); this.ReceivePreLoginResponse(); this.SendLogin7(); + if (flag == TDSEncryptionOption.EncryptOff) + { + this.TdsCommunicator = new TDSCommunicator(this.Client.GetStream(), 4096, this.TrustServerCertificate); + } this.ReceiveLogin7Response(); if (this.reconnect) diff --git a/TDSClient/TDSClient/TDS/Comms/TDSCommunicator.cs b/TDSClient/TDSClient/TDS/Comms/TDSCommunicator.cs index 136c9de..6bf9b3e 100644 --- a/TDSClient/TDSClient/TDS/Comms/TDSCommunicator.cs +++ b/TDSClient/TDSClient/TDS/Comms/TDSCommunicator.cs @@ -12,6 +12,7 @@ namespace TDSClient.TDS.Comms using System.Net.Sockets; using System.Security.Authentication; using System.Security.Cryptography.X509Certificates; + using TDSClient.TDS.Client; using TDSClient.TDS.Header; using TDSClient.TDS.Interfaces; using TDSClient.TDS.Login7; @@ -39,6 +40,11 @@ public class TDSCommunicator /// private readonly ushort packetSize; + /// + /// TrustServerCertificate + /// + private static Boolean TrustServerCertificate; + /// /// Current TDS Communicator State /// @@ -49,11 +55,12 @@ public class TDSCommunicator /// /// NetworkStream used for communication /// TDS packet size - public TDSCommunicator(Stream stream, ushort packetSize) + public TDSCommunicator(Stream stream, ushort packetSize, Boolean TrustServerCertificate) { this.packetSize = packetSize; this.innerTdsStream = new TDSStream(stream, new TimeSpan(0, 0, 30), packetSize); this.innerStream = this.innerTdsStream; + TDSCommunicator.TrustServerCertificate = TrustServerCertificate; } /// @@ -66,15 +73,26 @@ public TDSCommunicator(Stream stream, ushort packetSize) /// Returns true if no errors occurred. public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { - if (sslPolicyErrors == SslPolicyErrors.None) + if(TrustServerCertificate == false) + { + if (sslPolicyErrors == SslPolicyErrors.None) + { + return true; + } + + LoggingUtilities.WriteLog($"Certificate error: {sslPolicyErrors}"); + + return false; + } + else { return true; } + + } - LoggingUtilities.WriteLog($"Certificate error: {sslPolicyErrors}"); - return false; - } + /// /// Enable Transport Layer Security over TDS @@ -85,9 +103,11 @@ public void EnableEncryption(string server, SslProtocols encryptionProtocol) { var tempStream0 = new TDSTemporaryStream(this.innerTdsStream); var tempStream1 = new SslStream(tempStream0, true, ValidateServerCertificate); + //var tempStream1 = new SslStream(tempStream0, true); + tempStream1.AuthenticateAsClient(server, new X509CertificateCollection(), encryptionProtocol, true); - + tempStream0.InnerStream = this.innerTdsStream.InnerStream; this.innerTdsStream.InnerStream = tempStream1; @@ -121,15 +141,24 @@ public void EnableEncryption(string server, SslProtocols encryptionProtocol) } } + /// /// Receive TDS Message from the server. /// /// Returns received TDS Message. public ITDSPacketData ReceiveTDSMessage() { + if(TDSSQLTestClient.flag == TDSEncryptionOption.EncryptOff && this.communicatorState == TDSCommunicatorState.Initial) + { + this.communicatorState = TDSCommunicatorState.SentLogin7RecordWithCompleteAuthToken; + } + TDSSQLTestClient.flag = TDSEncryptionOption.EncryptOn; byte[] resultBuffer = null; var curOffset = 0; - + if(this.communicatorState == TDSCommunicatorState.SentLogin7RecordWithCompleteAuthToken) + { + + } do { Array.Resize(ref resultBuffer, curOffset + this.packetSize); diff --git a/TDSClient/TDSClient/TDS/Comms/TDSStream.cs b/TDSClient/TDSClient/TDS/Comms/TDSStream.cs index 0563106..877d545 100644 --- a/TDSClient/TDSClient/TDS/Comms/TDSStream.cs +++ b/TDSClient/TDSClient/TDS/Comms/TDSStream.cs @@ -9,6 +9,8 @@ namespace TDSClient.TDS.Comms using System; using System.IO; using TDSClient.TDS.Header; + using TDSClient.TDS.Utilities; + using System.Text; /// /// Stream used to pass TDS messages. @@ -133,6 +135,7 @@ public override int Read(byte[] buffer, int offset, int count) do { curPos += this.InnerStream.Read(headerBuffer, curPos, 8 - curPos); + //LoggingUtilities.WriteLog(Encoding.UTF8.GetString(headerBuffer, 0, 8)); if (curPos == 0) { diff --git a/TDSClient/TDSClient/TDSClient.csproj b/TDSClient/TDSClient/TDSClient.csproj index 8967eb1..ed704fa 100644 --- a/TDSClient/TDSClient/TDSClient.csproj +++ b/TDSClient/TDSClient/TDSClient.csproj @@ -5,6 +5,10 @@ false Copyright (c) Microsoft Corporation. + + Library + + diff --git a/TDSClient/TDSClientLiveTest/Program.cs b/TDSClient/TDSClientLiveTest/Program.cs index cc61e45..e219b26 100644 --- a/TDSClient/TDSClientLiveTest/Program.cs +++ b/TDSClient/TDSClientLiveTest/Program.cs @@ -1,23 +1,25 @@ using System; using TDSClient.TDS.Client; +using TDSClient.TDS.Header; namespace TDSClientLiveTest { class Program { - public static string Server = ""; + public static string Server = "localhost"; public static int Port = 1433; - public static string Username = ""; - public static string Password = ""; - public static string Database = ""; - - + public static string Username = "admin"; + public static string Password = "admin"; + public static string Database = "master"; + public static bool TrustServerCertificate = true; + public static string EncryptionOption = "EncryptOff"; + static void Main(string[] args) { - TDSSQLTestClient tdsClient = new TDSSQLTestClient(Server, Port, Username, Password, Database); + TDSSQLTestClient tdsClient = new TDSSQLTestClient(Server, Port, Username, Password, Database, TrustServerCertificate, EncryptionOption); TDSClient.TDS.Utilities.LoggingUtilities.SetVerboseLog(Console.Out); tdsClient.Connect(); tdsClient.Disconnect(); } } -} +} \ No newline at end of file diff --git a/TDSClient/TDSClientLiveTest/TDSClientLiveTest.csproj b/TDSClient/TDSClientLiveTest/TDSClientLiveTest.csproj index b223a2c..c60a6b6 100644 --- a/TDSClient/TDSClientLiveTest/TDSClientLiveTest.csproj +++ b/TDSClient/TDSClientLiveTest/TDSClientLiveTest.csproj @@ -2,7 +2,7 @@ Exe - netcoreapp3.1 + netcoreapp2.1 diff --git a/netstandard2.0/TDSClient.dll b/netstandard2.0/TDSClient.dll index 51713b2..5a6f72c 100644 Binary files a/netstandard2.0/TDSClient.dll and b/netstandard2.0/TDSClient.dll differ