Ejemplo n.º 1
0
        public override async Task Connect(bool reconnecting = false)
        {
            Notifications.ChangeTrayText(reconnecting ? MessageType.Reconnecting : MessageType.Connecting);
            Log.Write(l.Debug, "{0} client...", reconnecting ? "Reconnecting" : "Connecting");

            _ftpc = new System.Net.FtpClient.FtpClient
            {
                Host = Controller.Account.Host,
                Port = Controller.Account.Port
            };

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

            if (Controller.Account.Protocol == FtpProtocol.FTPS)
            {
                _ftpc.SslProtocols         = SslProtocols.Tls11 | SslProtocols.Tls12;
                _ftpc.ValidateCertificate += (sender, x) =>
                {
                    var certificate = new X509Certificate2(x.Certificate);

                    Log.Write(l.Warning, $"Policy errors: {x.PolicyErrors}");

                    // if ValidateCertificate handler isn't set, accept the certificate and move on
                    if (ValidateCertificate == null || Settings.TrustedCertificates.Contains(certificate.Thumbprint))
                    {
                        Log.Write(l.Client, "Trusted: {0}", certificate.Thumbprint);
                        x.Accept = true;
                        return;
                    }

                    var e = new ValidateCertificateEventArgs
                    {
                        cert        = certificate,
                        Fingerprint = certificate.Thumbprint
                    };

                    // Prompt user to validate
                    ValidateCertificate?.Invoke(null, e);

                    if (e.IsTrusted)
                    {
                        _certificates.Add(x.Certificate);
                    }

                    x.Accept = e.IsTrusted;
                };
            }

            // Change Security Protocol
            _ftpc.EncryptionMode = (FtpEncryptionMode)Controller.Account.FtpsMethod;

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

            try
            {
                await _ftpc.ConnectAsync();
            }
            catch (AuthenticationException ex) when(ex.Message.StartsWith("The remote certificate is invalid"))
            {
                throw new CertificateDeclinedException(ex.Message, ex);
            }
            catch (FtpCommandException ex)
            {
                ex.LogException();
                throw new AuthenticationException(ex.Message, ex.InnerException);
            }
            catch (Exception ex)
            {
                ex.LogException();
                throw;
            }

            _ftpc.Encoding = this.Charset;

            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();
        }
Ejemplo n.º 2
0
        public override async Task Connect(bool reconnecting = false)
        {
            Notifications.ChangeTrayText(reconnecting ? MessageType.Reconnecting : MessageType.Connecting);
            Log.Write(l.Debug, "{0} client...", reconnecting ? "Reconnecting" : "Connecting");

            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);
            }
            connectionInfo.Encoding = this.Charset;

            connectionInfo.AuthenticationBanner += (o, x) =>
                                                   Log.Write(l.Warning, x.BannerMessage);

            _sftpc = new Renci.SshNet.SftpClient(connectionInfo);

            _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?.Invoke(null, e);
                x.CanTrust = e.IsTrusted;
            };

            var caughtException = default(Exception);
            await Task.Run(() =>
            {
                try
                {
                    _sftpc.Connect();
                }
                catch (SshAuthenticationException ex)
                {
                    ex.LogException();
                    caughtException = new AuthenticationException(ex.Message, ex.InnerException);
                }
                catch (SshConnectionException ex)
                {
                    ex.LogException();
                    caughtException = new CertificateDeclinedException(ex.Message, ex.InnerException);
                }
                catch (Exception ex)
                {
                    ex.LogException();
                    caughtException = ex;
                }
            });

            if (caughtException != default(Exception))
            {
                throw caughtException;
            }

            _sftpc.ErrorOccurred += async(o, e) =>
            {
                if (!IsConnected)
                {
                    Notifications.ChangeTrayText(MessageType.Nothing);
                }

                OnConnectionClosed(new ConnectionClosedEventArgs {
                    Text = e.Exception.Message
                });

                if (e.Exception is SftpPermissionDeniedException)
                {
                    Log.Write(l.Warning, "Permission denied error occured");
                }
                if (e.Exception is SshConnectionException)
                {
                    await 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();
            }
        }