/// <summary> /// Close connection to server /// </summary> public void Disconnect() { if (FTP) { _ftpc.Close(); } else { _sftpc.Disconnect(); } }
/// <summary> /// Connect to the remote servers, with the details from Profile /// </summary> /// <param name="reconnecting">True if this is an attempt to re-establish a closed connection</param> public void Connect(bool reconnecting = false) { Notifications.ChangeTrayText(reconnecting ? MessageType.Reconnecting : MessageType.Connecting); Log.Write(l.Debug, "{0} client...", reconnecting ? "Reconnecting" : "Connecting"); if (FTP) { _ftpc = new FtpClient(controller.Account.Host, controller.Account.Port); _ftpc.ConnectionClosed += (o, e) => { Notifications.ChangeTrayText(MessageType.Nothing); if (ConnectionClosed != null) { ConnectionClosed(null, new ConnectionClosedEventArgs { Text = _ftpc.LastResponse.Text }); } Reconnect(); }; if (controller.Account.Protocol == FtpProtocol.FTPS) { _ftpc.ValidateServerCertificate += (sender, x) => { // if ValidateCertificate handler isn't set, accept the certificate and move on if (ValidateCertificate == null || Settings.TrustedCertificates.Contains(x.Certificate.Thumbprint)) { Log.Write(l.Client, "Trusted: {0}", x.Certificate.Thumbprint); x.IsCertificateValid = true; return; } var e = new ValidateCertificateEventArgs { Fingerprint = x.Certificate.Thumbprint, SerialNumber = x.Certificate.SerialNumber, Algorithm = x.Certificate.SignatureAlgorithm.FriendlyName, ValidFrom = x.Certificate.NotBefore.ToString("MM/dd/yy"), ValidTo = x.Certificate.NotAfter.ToString("MM/dd/yy"), Issuer = x.Certificate.IssuerName.Name }; ValidateCertificate(null, e); x.IsCertificateValid = e.IsTrusted; }; // Change Security Protocol if (controller.Account.FtpsMethod == FtpsMethod.Explicit) { _ftpc.SecurityProtocol = FtpSecurityProtocol.Tls1OrSsl3Explicit; } else if (controller.Account.FtpsMethod == FtpsMethod.Implicit) { _ftpc.SecurityProtocol = FtpSecurityProtocol.Tls1OrSsl3Implicit; } } try { _ftpc.Open(controller.Account.Username, controller.Account.Password); } catch (Exception) { if (controller.Account.FtpsMethod == FtpsMethod.None) { throw; } bool connected = false; // Try connecting with the other available Security Protocols foreach (FtpSecurityProtocol p in Enum.GetValues(typeof(FtpSecurityProtocol))) { if ((controller.Account.FtpsMethod == FtpsMethod.Explicit && p.ToString().Contains("Explicit")) || (controller.Account.FtpsMethod == FtpsMethod.Implicit && p.ToString().Contains("Implicit"))) { Log.Write(l.Debug, "Testing with {0}", p.ToString()); try { _ftpc.Close(); _ftpc.SecurityProtocol = p; _ftpc.Open(controller.Account.Username, controller.Account.Password); } catch (Exception exe) { Log.Write(l.Warning, "Unable to connect: {0}", exe.GetType().ToString()); continue; } connected = true; controller.Account.FtpSecurityProtocol = p; break; } } if (!connected) { Notifications.ChangeTrayText(MessageType.Nothing); throw; } } } else // SFTP { ConnectionInfo connectionInfo; if (controller.isPrivateKeyValid) { connectionInfo = new PrivateKeyConnectionInfo(controller.Account.Host, controller.Account.Port, controller.Account.Username, new PrivateKeyFile(controller.Account.PrivateKeyFile, controller.Account.Password)); } else { connectionInfo = new PasswordConnectionInfo(controller.Account.Host, controller.Account.Port, controller.Account.Username, controller.Account.Password); } _sftpc = new SftpClient(connectionInfo); _sftpc.ConnectionInfo.AuthenticationBanner += (o, x) => Log.Write(l.Warning, x.BannerMessage); _sftpc.HostKeyReceived += (o, x) => { var fingerPrint = x.FingerPrint.GetCertificateData(); // if ValidateCertificate handler isn't set, accept the certificate and move on if (ValidateCertificate == null || Settings.TrustedCertificates.Contains(fingerPrint)) { Log.Write(l.Client, "Trusted: {0}", fingerPrint); x.CanTrust = true; return; } var e = new ValidateCertificateEventArgs { Fingerprint = fingerPrint, Key = x.HostKeyName, KeySize = x.KeyLength.ToString() }; ValidateCertificate(null, e); x.CanTrust = e.IsTrusted; }; _sftpc.Connect(); _sftpc.ErrorOccurred += (o, e) => { if (!isConnected) { Notifications.ChangeTrayText(MessageType.Nothing); } if (ConnectionClosed != null) { ConnectionClosed(null, new ConnectionClosedEventArgs { Text = e.Exception.Message }); } if (e.Exception is Renci.SshNet.Common.SftpPermissionDeniedException) { Log.Write(l.Warning, "Permission denied error occured"); } if (e.Exception is Renci.SshNet.Common.SshConnectionException) { Reconnect(); } }; } controller.HomePath = WorkingDirectory; if (isConnected) { if (!string.IsNullOrWhiteSpace(controller.Paths.Remote) && !controller.Paths.Remote.Equals("/")) { WorkingDirectory = controller.Paths.Remote; } } Log.Write(l.Debug, "Client connected sucessfully"); Notifications.ChangeTrayText(MessageType.Ready); if (Settings.IsDebugMode) { LogServerInfo(); } }