/// <summary> /// Connect to the server. /// </summary> public void Connect() { LoggingUtilities.WriteLog($" Connect initiated."); do { this.reconnect = false; this.Client = new TcpClient(this.Server, this.Port); 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) { this.Disconnect(); LoggingUtilities.WriteLog($" Routing to: {this.Server}:{this.Port}."); } }while (this.reconnect); LoggingUtilities.WriteLog($" Connect done."); }
/// <summary> /// Receive PreLogin response from the server. /// </summary> public void ReceivePreLoginResponse() { LoggingUtilities.WriteLog($" ReceivePreLoginResponse initiated."); if (this.TdsCommunicator.ReceiveTDSMessage() is TDSPreLoginPacketData response) { if (response.Options.Exists(opt => opt.Type == TDSPreLoginOptionTokenType.Encryption) && response.Encryption == TDSEncryptionOption.EncryptReq) { LoggingUtilities.WriteLog($" Server requires encryption, enabling encryption."); this.TdsCommunicator.EnableEncryption(this.Server, this.EncryptionProtocol); LoggingUtilities.WriteLog($" Encryption enabled."); } if (response.Options.Exists(opt => opt.Type == TDSPreLoginOptionTokenType.FedAuthRequired) && response.FedAuthRequired == true) { throw new NotSupportedException("FedAuth is being requested but the client doesn't support FedAuth."); } } else { throw new InvalidOperationException(); } LoggingUtilities.WriteLog($" ReceivePreLoginResponse done."); }
/// <summary> /// Receive Login7 response from the server. /// </summary> public void ReceiveLogin7Response() { LoggingUtilities.WriteLog($" ReceiveLogin7Response initiated."); if (this.TdsCommunicator.ReceiveTDSMessage() is TDSTokenStreamPacketData response) { foreach (var token in response.Tokens) { if (token is TDSEnvChangeToken) { var envChangeToken = token as TDSEnvChangeToken; if (envChangeToken.Type == Tokens.EnvChange.TDSEnvChangeType.Routing) { LoggingUtilities.WriteLog($" Client received EnvChange routing token, client is being routed."); this.Server = envChangeToken.Values["AlternateServer"]; this.ServerName = this.Server; this.Port = int.Parse(envChangeToken.Values["ProtocolProperty"]); this.reconnect = true; } } else if (token is TDSErrorToken) { var errorToken = token as TDSErrorToken; LoggingUtilities.WriteLog($" Client received Error token:"); LoggingUtilities.WriteLog($" Number: {errorToken.Number}"); LoggingUtilities.WriteLog($" State: {errorToken.State}"); LoggingUtilities.WriteLog($" Class: {errorToken.Class}"); LoggingUtilities.WriteLog($" MsgText: {errorToken.MsgText}"); LoggingUtilities.WriteLog($" ServerName: {errorToken.ServerName}"); LoggingUtilities.WriteLog($" ProcName: {errorToken.ProcName}"); LoggingUtilities.WriteLog($" LineNumber: {errorToken.LineNumber}"); if (errorToken.Number == 18456) { throw new Exception("Login failure."); } } else if (token is TDSInfoToken) { var infoToken = token as TDSInfoToken; LoggingUtilities.WriteLog($" Client received Info token:"); LoggingUtilities.WriteLog($" Number: {infoToken.Number}"); LoggingUtilities.WriteLog($" State: {infoToken.State}"); LoggingUtilities.WriteLog($" Class: {infoToken.Class}"); LoggingUtilities.WriteLog($" MsgText: {infoToken.MsgText}"); LoggingUtilities.WriteLog($" ServerName: {infoToken.ServerName}"); LoggingUtilities.WriteLog($" ProcName: {infoToken.ProcName}"); LoggingUtilities.WriteLog($" LineNumber: {infoToken.LineNumber}"); } } } else { throw new InvalidOperationException(); } LoggingUtilities.WriteLog($" ReceiveLogin7Response done."); }
/// <summary> /// Terminate TDS PreLogin Packet. /// </summary> public void Terminate() { this.Terminated = true; this.Options.Add(new TDSPreLoginOptionToken(TDSPreLoginOptionTokenType.Terminator)); LoggingUtilities.WriteLog($" Adding PreLogin message terminator."); }
/// <summary> /// Disconnect from the server. /// </summary> public void Disconnect() { LoggingUtilities.WriteLog($" Disconnect initiated."); this.Client.Close(); this.Client = null; LoggingUtilities.WriteLog($" Disconnect done."); }
/// <summary> /// Add TDS Login7 Option. /// </summary> /// <param name="optionName">Option Name</param> /// <param name="data">Option Data</param> public void AddOption(string optionName, string data) { if (optionName == null || data == null) { throw new ArgumentNullException(); } if (this.Options.Where(opt => opt.Name == optionName).Any()) { throw new Exception("Login7 option already set!"); } if (optionName != "Password" && optionName != "ChangePassword") { LoggingUtilities.WriteLog($" Adding Login7 option {optionName} [{data}]."); } else { LoggingUtilities.WriteLog($" Adding Login7 option {optionName}."); } var option = TDSLogin7OptionFactory.CreateOption(optionName, data); this.Options.Add(option); }
/// <summary> /// Validate Server Certificate /// </summary> /// <param name="sender">Sender object</param> /// <param name="certificate">X509 Certificate</param> /// <param name="chain">X509 Chain</param> /// <param name="sslPolicyErrors">SSL Policy Errors</param> /// <returns>Returns true if no errors occurred.</returns> public static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) { if (sslPolicyErrors == SslPolicyErrors.None) { return(true); } LoggingUtilities.WriteLog($"Certificate error: {sslPolicyErrors}"); return(false); }
public void SendPreLogin() { LoggingUtilities.WriteLog($" SendPreLogin initiated."); var tdsMessageBody = new TDSPreLoginPacketData(Version); tdsMessageBody.AddOption(TDSPreLoginOptionTokenType.Encryption, TDSEncryptionOption.EncryptOff); tdsMessageBody.Terminate(); TdsCommunicator.SendTDSMessage(tdsMessageBody); LoggingUtilities.WriteLog($" SendPreLogin done."); }
/// <summary> /// Sends PreLogin message to the server. /// </summary> public void SendPreLogin() { LoggingUtilities.WriteLog($" SendPreLogin initiated."); var tdsMessageBody = new TDSPreLoginPacketData(this.Version); tdsMessageBody.AddOption(TDSPreLoginOptionTokenType.Encryption, TDSEncryptionOption.EncryptOff); tdsMessageBody.AddOption(TDSPreLoginOptionTokenType.TraceID, new TDSClientTraceID(Guid.NewGuid().ToByteArray(), Guid.NewGuid().ToByteArray(), 0)); tdsMessageBody.Terminate(); this.TdsCommunicator.SendTDSMessage(tdsMessageBody); LoggingUtilities.WriteLog($" SendPreLogin done."); }
/// <summary> /// Connect to the server. /// </summary> public void Connect() { DateTime connectStartTime = DateTime.UtcNow; bool preLoginDone = false; LoggingUtilities.WriteLog($" Connect initiated."); try { do { preLoginDone = false; this.reconnect = false; this.Client = new TcpClient(this.Server, this.Port); this.TdsCommunicator = new TDSCommunicator(this.Client.GetStream(), 4096); this.SendPreLogin(); this.ReceivePreLoginResponse(); preLoginDone = true; LoggingUtilities.WriteLog($" PreLogin phase took {(int)(DateTime.UtcNow - connectStartTime).TotalMilliseconds} milliseconds."); this.SendLogin7(); this.ReceiveLogin7Response(); if (this.reconnect) { this.Disconnect(); LoggingUtilities.WriteLog($" Routing to: {this.Server}:{this.Port}."); } }while (this.reconnect); LoggingUtilities.WriteLog($" Connect done."); } catch (SocketException socketException) { LoggingUtilities.WriteLog($" Networking error {socketException.NativeErrorCode} while trying to connect to {this.Server}:{this.Port}."); } catch (Exception ex) { if (!preLoginDone && DateTime.UtcNow >= connectStartTime.AddSeconds(5)) { LoggingUtilities.WriteLog($" Possible SNI timeout"); } LoggingUtilities.WriteLog($"Exception:"); LoggingUtilities.WriteLog($"{ex.Message}"); if (ex.InnerException != null) { LoggingUtilities.WriteLog($"InnerException: {ex.InnerException.Message}"); } throw ex; } }
/// <summary> /// Enable Transport Layer Security over TDS /// </summary> /// <param name="server">Server FQDN</param> /// <param name="encryptionProtocol">Encryption Protocol</param> 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; LoggingUtilities.WriteLog($" Cipher: {tempStream1.CipherAlgorithm} strength {tempStream1.CipherStrength}"); LoggingUtilities.WriteLog($" Hash: {tempStream1.HashAlgorithm} strength {tempStream1.HashStrength}"); LoggingUtilities.WriteLog($" Key exchange: {tempStream1.KeyExchangeAlgorithm} strength {tempStream1.KeyExchangeStrength}"); LoggingUtilities.WriteLog($" Protocol: {tempStream1.SslProtocol}"); LoggingUtilities.WriteLog($" Is authenticated: {tempStream1.IsAuthenticated}"); LoggingUtilities.WriteLog($" IsSigned: {tempStream1.IsSigned}"); LoggingUtilities.WriteLog($" Is Encrypted: {tempStream1.IsEncrypted}"); X509Certificate localCertificate = tempStream1.LocalCertificate; if (tempStream1.LocalCertificate != null) { LoggingUtilities.WriteLog($" Local cert was issued to {localCertificate.Subject} and is valid from {localCertificate.GetEffectiveDateString()} until {localCertificate.GetExpirationDateString()}."); } else { LoggingUtilities.WriteLog(" Local certificate is null."); } X509Certificate remoteCertificate = tempStream1.RemoteCertificate; if (tempStream1.RemoteCertificate != null) { LoggingUtilities.WriteLog($" Remote cert was issued to {remoteCertificate.Subject} and is valid from {remoteCertificate.GetEffectiveDateString()} until {remoteCertificate.GetExpirationDateString()}."); } else { LoggingUtilities.WriteLog(" Remote certificate is null."); } }
private void MeasureDNSResolutionTime() { try { var stopwatch = Stopwatch.StartNew(); var addresses = Dns.GetHostAddresses(this.Server); stopwatch.Stop(); var addressListString = string.Join(",", addresses.AsEnumerable()); LoggingUtilities.WriteLog($" DNS resolution took {stopwatch.ElapsedMilliseconds} ms, ({addressListString})", writeToSummaryLog: true); } catch (SocketException socketException) { LoggingUtilities.WriteLog($" DNS resolution failed with \"{socketException.Message}\", error {socketException.NativeErrorCode} for address {this.Server}", writeToSummaryLog: true); } catch (Exception ex) { LoggingUtilities.WriteLog($" DNS resolution failed with \"{ex.Message}\", for address {this.Server}", writeToSummaryLog: true); } }
/// <summary> /// Sends Login7 message to the server /// </summary> public void SendLogin7() { LoggingUtilities.WriteLog($" SendLogin7 initiated."); var tdsMessageBody = new TDSLogin7PacketData(); tdsMessageBody.AddOption("HostName", Environment.MachineName); tdsMessageBody.AddOption("UserName", this.UserID); tdsMessageBody.AddOption("ServerName", this.ServerName); tdsMessageBody.AddOption("Password", this.Password); tdsMessageBody.AddOption("Database", this.Database); tdsMessageBody.AddOption("CltIntName", "TDSSQLTestClient"); tdsMessageBody.OptionFlags1.Char = TDSLogin7OptionFlags1Char.CharsetASCII; tdsMessageBody.OptionFlags1.Database = TDSLogin7OptionFlags1Database.InitDBFatal; tdsMessageBody.OptionFlags1.DumpLoad = TDSLogin7OptionFlags1DumpLoad.DumploadOn; tdsMessageBody.OptionFlags1.Float = TDSLogin7OptionFlags1Float.FloatIEEE754; tdsMessageBody.OptionFlags1.SetLang = TDSLogin7OptionFlags1SetLang.SetLangOn; tdsMessageBody.OptionFlags1.ByteOrder = TDSLogin7OptionFlags1ByteOrder.OrderX86; tdsMessageBody.OptionFlags1.UseDB = TDSLogin7OptionFlags1UseDB.UseDBOff; 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; tdsMessageBody.OptionFlags3.UnknownCollationHandling = TDSLogin7OptionFlags3UnknownCollationHandling.On; tdsMessageBody.OptionFlags3.Extension = TDSLogin7OptionFlags3Extension.DoesntExist; tdsMessageBody.TypeFlags.OLEDB = TDSLogin7TypeFlagsOLEDB.On; tdsMessageBody.TypeFlags.SQLType = TDSLogin7TypeFlagsSQLType.DFLT; tdsMessageBody.TypeFlags.ReadOnlyIntent = TDSLogin7TypeFlagsReadOnlyIntent.On; this.TdsCommunicator.SendTDSMessage(tdsMessageBody); LoggingUtilities.WriteLog($" SendLogin7 done."); }
/// <summary> /// Reads a TDS Token from a given MemoryStream /// </summary> /// <param name="stream">Stream that contains the token</param> /// <returns>Returns read TDS Token</returns> public static TDSToken ReadTokenFromStream(MemoryStream stream) { var tokenType = (TDSTokenType)stream.ReadByte(); LoggingUtilities.WriteLog($" Received {tokenType} token in Login7 response."); switch (tokenType) { case TDSTokenType.Error: { var token = new TDSErrorToken(); token.Unpack(stream); return(token); } case TDSTokenType.EnvChange: { var token = new TDSEnvChangeToken(); token.Unpack(stream); return(token); } case TDSTokenType.Info: { var token = new TDSInfoToken(); token.Unpack(stream); return(token); } default: { IgnoreToken(tokenType, stream); return(null); } } }
public void Connect() { LoggingUtilities.WriteLog($" Connect initiated."); do { Reconnect = false; Client = new TcpClient(Server, Port); TdsCommunicator = new TDSCommunicator(Client.GetStream(), 4096); SendPreLogin(); ReceivePreLoginResponse(); SendLogin7(); ReceiveLogin7Response(); if (Reconnect) { Disconnect(); LoggingUtilities.WriteLog($" Routing to: {Server}:{Port}."); } }while (Reconnect); LoggingUtilities.WriteLog($" Connect done."); }
/// <summary> /// Initializes a new instance of the <see cref="TDSSQLTestClient"/> class. /// </summary> /// <param name="server">Server to connect to</param> /// <param name="port">Port to connect to</param> /// <param name="userID">Used ID</param> /// <param name="password">User password</param> /// <param name="database">Database to connect to</param> /// <param name="encryptionProtocol">Encryption Protocol</param> public TDSSQLTestClient(string server, int port, string userID, string password, string database, SslProtocols encryptionProtocol = SslProtocols.Tls12) { if (string.IsNullOrEmpty(server) || string.IsNullOrEmpty(userID) || string.IsNullOrEmpty(password) || string.IsNullOrEmpty(database)) { throw new ArgumentNullException(); } this.Client = null; this.Version = new TDSClientVersion(1, 0, 0, 0); this.Server = server; this.ServerName = server; this.Port = port; this.UserID = userID; this.Password = password; this.Database = database; this.EncryptionProtocol = encryptionProtocol; LoggingUtilities.WriteLog($" Instantiating TDSSQLTestClient with the following parameters:"); LoggingUtilities.WriteLog($" Server: {server}."); LoggingUtilities.WriteLog($" Port: {port}."); LoggingUtilities.WriteLog($" UserID: {userID}."); LoggingUtilities.WriteLog($" Database: {database}."); }
/// <summary> /// Adds PreLogin option to the PreLogin packet /// </summary> /// <param name="type">Option type</param> /// <param name="data">Option data</param> public void AddOption(TDSPreLoginOptionTokenType type, object data) { if (this.Terminated) { throw new InvalidOperationException(); } switch (type) { case TDSPreLoginOptionTokenType.Version: { if (data is TDSClientVersion && this.ClientVersion == null) { this.ClientVersion = (TDSClientVersion)data; //LoggingUtilities.WriteLog($" Adding PreLogin option {type}."); } else { throw new ArgumentException(); } break; } case TDSPreLoginOptionTokenType.Encryption: { if (data is TDSEncryptionOption) { this.Encryption = (TDSEncryptionOption)data; LoggingUtilities.WriteLog($" Adding PreLogin option {type} [{this.Encryption}]."); } else { throw new ArgumentException(); } break; } case TDSPreLoginOptionTokenType.FedAuthRequired: { if (data is bool) { this.FedAuthRequired = (bool)data; LoggingUtilities.WriteLog($" Adding PreLogin option {type} [{(bool)data}]."); } else { throw new ArgumentException(); } break; } case TDSPreLoginOptionTokenType.MARS: { if (data is bool) { this.MARS = (bool)data; LoggingUtilities.WriteLog($" Adding PreLogin option {type} [{(bool)data}]."); } else { throw new ArgumentException(); } break; } case TDSPreLoginOptionTokenType.ThreadID: { if (data is uint) { this.ThreadID = (uint)data; LoggingUtilities.WriteLog($" Adding PreLogin option {type} [{this.ThreadID}]."); } else { throw new ArgumentException(); } break; } case TDSPreLoginOptionTokenType.TraceID: { if (data is TDSClientTraceID) { this.TraceID = (TDSClientTraceID)data; LoggingUtilities.WriteLog($" Adding PreLogin option {type}"); LoggingUtilities.WriteLog($" ConnectionID: {new Guid(this.TraceID.TraceID).ToString().ToUpper()}", writeToSummaryLog: true); LoggingUtilities.WriteLog($" ActivityID: {new Guid(this.TraceID.ActivityID).ToString().ToUpper()}"); LoggingUtilities.WriteLog($" ActivitySequence: {this.TraceID.ActivitySequence}"); } else { throw new ArgumentException(); } break; } case TDSPreLoginOptionTokenType.NonceOpt: { if (data is byte[]) { this.Nonce = (byte[])data; LoggingUtilities.WriteLog($" Adding PreLogin option {type}."); } else { throw new ArgumentException(); } break; } default: { throw new NotSupportedException(); } } this.Options.Add(new TDSPreLoginOptionToken(type)); }
/// <summary> /// Initializes a new instance of the <see cref="TDSSQLTestClient"/> class. /// </summary> /// <param name="server">Server to connect to</param> /// <param name="port">Port to connect to</param> /// <param name="userID">Used ID</param> /// <param name="password">User password</param> /// <param name="database">Database to connect to</param> /// <param name="encryptionProtocol">Encryption Protocol</param> 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; this.ServerName = server; this.Port = port; this.UserID = userID; 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:"); LoggingUtilities.WriteLog($" Server: {server}."); LoggingUtilities.WriteLog($" Port: {port}."); LoggingUtilities.WriteLog($" UserID: {userID}."); LoggingUtilities.WriteLog($" Database: {database}."); LoggingUtilities.WriteLog($" TrustServerCertificate: {TrustServerCertificate}."); LoggingUtilities.WriteLog($" EncryptionOption: {EncryptionOption}."); }
/// <summary> /// Connect to the server. /// </summary> public void Connect() { DateTime connectStartTime = DateTime.UtcNow; bool preLoginDone = false; var originalServerName = this.Server; var originalPort = this.Port; LoggingUtilities.WriteLog($"Connect initiated (attempt # {++connectionAttempt}).", writeToSummaryLog: true); try { do { preLoginDone = false; this.reconnect = false; MeasureDNSResolutionTime(); this.Client = new TcpClient(this.Server, this.Port); this.TdsCommunicator = new TDSCommunicator(this.Client.GetStream(), 4096); LoggingUtilities.WriteLog($" TCP connection open between local {this.Client.Client.LocalEndPoint} and remote {this.Client.Client.RemoteEndPoint}", writeToVerboseLog: false, writeToSummaryLog: true); LoggingUtilities.WriteLog($" TCP connection open"); LoggingUtilities.WriteLog($" Local endpoint is {this.Client.Client.LocalEndPoint}"); LoggingUtilities.WriteLog($" Remote endpoint is {this.Client.Client.RemoteEndPoint}"); connectStartTime = DateTime.UtcNow; this.SendPreLogin(); this.ReceivePreLoginResponse(); preLoginDone = true; LoggingUtilities.WriteLog($" PreLogin phase took {(int)(DateTime.UtcNow - connectStartTime).TotalMilliseconds} milliseconds."); this.SendLogin7(); this.ReceiveLogin7Response(); if (this.reconnect) { this.Disconnect(); LoggingUtilities.AddEmptyLine(); LoggingUtilities.WriteLog($" Routing to: {this.Server}:{this.Port}."); } }while (this.reconnect); LoggingUtilities.WriteLog($" Connect done.", writeToSummaryLog: true); } catch (SocketException socketException) { LoggingUtilities.WriteLog($" Networking error {socketException.NativeErrorCode} while trying to connect to {this.Server}:{this.Port}.", writeToSummaryLog: true); } catch (Exception ex) { if (!preLoginDone && DateTime.UtcNow >= connectStartTime.AddSeconds(5)) { LoggingUtilities.WriteLog($" SNI timeout detected, PreLogin phase was not complete after {(int)(DateTime.UtcNow - connectStartTime).TotalMilliseconds} milliseconds.", writeToSummaryLog: true); } LoggingUtilities.WriteLog($"Exception:"); LoggingUtilities.WriteLog($"{ex.Message}"); if (ex.InnerException != null) { LoggingUtilities.WriteLog($"InnerException: {ex.InnerException.Message}"); } //throw ex; } finally { this.Server = originalServerName; this.Port = originalPort; } }