Esempio n. 1
0
        /// <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 override void Connect(bool reconnecting = false)
        {
            Notifications.ChangeTrayText(reconnecting ? MessageType.Reconnecting : MessageType.Connecting);
            Log.Write(l.Debug, "{0} client...", reconnecting ? "Reconnecting" : "Connecting");


            lock (ftpcLock)
            {
                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()
                    };
                    // Prompt user to validate
                    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 SftpPermissionDeniedException)
                    {
                        Log.Write(l.Warning, "Permission denied error occured");
                    }
                    if (e.Exception is SshConnectionException)
                    {
                        Reconnect();
                    }
                };
            }

            _controller.HomePath = WorkingDirectory;

            if (isConnected)
            {
                if (!string.IsNullOrWhiteSpace(_controller.Paths.Remote) && !_controller.Paths.Remote.Equals("/"))
                {
                    WorkingDirectory = _controller.Paths.Remote;
                }

                if (connectionState == null)
                {
                    connectionState         = new BackgroundWorker();
                    connectionState.DoWork += new DoWorkEventHandler((o, e) =>
                    {
                        while (true)
                        {
                            if (!isConnected)
                            {
                                // RECONNECT
                                //_controller.Client.Reconnect();
                            }
                            Thread.Sleep(5000);
                        }
                    });

                    connectionState.RunWorkerAsync();
                }
            }

            Log.Write(l.Debug, "Client connected sucessfully");
            Notifications.ChangeTrayText(MessageType.Ready);

            if (Settings.IsDebugMode)
            {
                LogServerInfo();
            }

            // Periodically send NOOP (KeepAlive) to server if a non-zero interval is set
            SetKeepAlive();
        }
Esempio n. 2
0
        /// <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 {
                    Host = controller.Account.Host, Port = controller.Account.Port
                };

                // Add accepted certificates
                _ftpc.ClientCertificates.AddRange(Certificates);

                if (controller.Account.Protocol == FtpProtocol.FTPS)
                {
                    _ftpc.ValidateCertificate += (sender, x) =>
                    {
                        var fingerPrint = new X509Certificate2(x.Certificate).Thumbprint;

                        if (_ftpc.ClientCertificates.Count <= 0 && x.PolicyErrors != SslPolicyErrors.None)
                        {
                            Certificates.Add(x.Certificate);
                            x.Accept = false;
                            return;
                        }

                        // 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.Accept = true;
                            return;
                        }

                        var e = new ValidateCertificateEventArgs
                        {
                            Fingerprint  = fingerPrint,
                            SerialNumber = x.Certificate.GetSerialNumberString(),
                            Algorithm    = x.Certificate.GetKeyAlgorithmParametersString(),
                            ValidFrom    = x.Certificate.GetEffectiveDateString(),
                            ValidTo      = x.Certificate.GetExpirationDateString(),
                            Issuer       = x.Certificate.Issuer
                        };
                        // Prompt user to validate
                        ValidateCertificate(null, e);
                        x.Accept = e.IsTrusted;
                    };

                    // Change Security Protocol
                    if (controller.Account.FtpsMethod == FtpsMethod.Explicit)
                    {
                        _ftpc.EncryptionMode = FtpEncryptionMode.Explicit;
                    }
                    else if (controller.Account.FtpsMethod == FtpsMethod.Implicit)
                    {
                        _ftpc.EncryptionMode = FtpEncryptionMode.Implicit;
                    }
                }

                _ftpc.Credentials = new NetworkCredential(controller.Account.Username, controller.Account.Password);

                try
                {
                    _ftpc.Connect();
                }
                catch (Exception exc)
                {
                    // Since the ClientCertificates are added when accepted in ValidateCertificate, the first
                    // attempt to connect will fail with an AuthenticationException. If this is the case, a
                    // re-connect is attempted, this time with the certificates properly set.
                    // This is a workaround to avoid storing Certificate files locally...
                    if (exc is System.Security.Authentication.AuthenticationException &&
                        _ftpc.ClientCertificates.Count <= 0)
                    {
                        Connect();
                    }
                    else
                    {
                        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()
                    };
                    // Prompt user to validate
                    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();
            }

            // Periodically send NOOP (KeepAlive) to server if a non-zero interval is set
            SetKeepAlive();
        }
Esempio n. 3
0
        /// <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();
            }
        }