Example #1
0
 /// <summary>
 /// Connects to a FTP server using the provided parameters. 
 /// The default representation tipe is set to Binary.
 /// The text encoding is set to UTF8, if supported by the server via the FEAT command.
 /// </summary>
 /// <param name="hostname"></param>
 /// <param name="port"></param>
 /// <param name="credential"></param>
 /// <param name="sslSupportMode"></param>
 /// <param name="userValidateServerCertificate"></param>
 /// <param name="x509ClientCert"></param>
 /// <param name="sslMinKeyExchangeAlgStrength"></param>
 /// <param name="sslMinCipherAlgStrength"></param>
 /// <param name="sslMinHashAlgStrength"></param>
 /// <param name="timeout">Connection timeout in ms. <c>null</c> can be specifiad to keep the default value of 120s.</param>
 /// <param name="useCtrlEndPointAddressForData"><c>true</c> to use the control channel remote address for data connections instead of the address returned by PASV</param>
 /// <returns>The text of the \"welcome message\" sent by the server.</returns>
 public string Connect(string hostname, int port, NetworkCredential credential, EsslSupportMode sslSupportMode,
                     RemoteCertificateValidationCallback userValidateServerCertificate, X509Certificate x509ClientCert,
                     int sslMinKeyExchangeAlgStrength, int sslMinCipherAlgStrength, int sslMinHashAlgStrength,
                     int? timeout, bool useCtrlEndPointAddressForData)
 {
     return Connect(hostname, port, credential, sslSupportMode, userValidateServerCertificate, x509ClientCert,
                    sslMinKeyExchangeAlgStrength, sslMinCipherAlgStrength, sslMinHashAlgStrength, timeout, true, EDataConnectionMode.Passive);
 }
Example #2
0
        /// <summary>
        /// Connects to a FTP server using the provided parameters. 
        /// The default representation tipe is set to Binary.
        /// The text encoding is set to UTF8, if supported by the server via the FEAT command.
        /// </summary>
        /// <param name="hostname"></param>
        /// <param name="port"></param>
        /// <param name="credential"></param>
        /// <param name="sslSupportMode"></param>
        /// <param name="userValidateServerCertificate"></param>
        /// <param name="x509ClientCert"></param>
        /// <param name="sslMinKeyExchangeAlgStrength"></param>
        /// <param name="sslMinCipherAlgStrength"></param>
        /// <param name="sslMinHashAlgStrength"></param>
        /// <param name="timeout">Connection timeout in ms. <c>null</c> can be specifiad to keep the default value of 120s.</param>
        /// <param name="useCtrlEndPointAddressForData"><c>true</c> to use the control channel remote address for data connections instead of the address returned by PASV</param>
        /// <param name="dataConnectionMode">Active or Passive data connection mode</param>
        /// <returns>The text of the \"welcome message\" sent by the server.</returns>
        public string Connect(string hostname, int port, NetworkCredential credential, EsslSupportMode sslSupportMode,
                            RemoteCertificateValidationCallback userValidateServerCertificate, X509Certificate x509ClientCert,
                            int sslMinKeyExchangeAlgStrength, int sslMinCipherAlgStrength, int sslMinHashAlgStrength,
                            int? timeout, bool useCtrlEndPointAddressForData, EDataConnectionMode dataConnectionMode)
        {
            Close();

            // Anonymous authentication
            if (credential == null)
                credential = new NetworkCredential(AnonUsername, AnonPassword);

            if (timeout != null)
                _timeout = timeout.Value;

            _sslClientCert = x509ClientCert;

            _userValidateServerCertificate = userValidateServerCertificate;

            _sslMinKeyExchangeAlgStrength = sslMinKeyExchangeAlgStrength;
            _sslMinCipherAlgStrength = sslMinCipherAlgStrength;
            _sslMinHashAlgStrength = sslMinHashAlgStrength;

            _sslSupportRequestedMode = sslSupportMode;
            _sslSupportCurrentMode = sslSupportMode;

            _useCtrlEndPointAddressForData = useCtrlEndPointAddressForData;

            _dataConnectionMode = dataConnectionMode;

            _sslInfo = null;

            _features = null;

            _transferMode = ETransferMode.Ascii;
            _textEncoding = ETextEncoding.Ascii;

            _bannerMessage = null;
            _welcomeMessage = null;

            _currDirStack.Clear();

            // Ok, member initialization is done. Start with setting up a control connection
            SetupCtrlConnection(hostname, port, Encoding.ASCII);

            // Used later for SSL/TLS auth
            _hostname = hostname;

            // Implicit SSL/TLS
            bool isImplicitSsl = (sslSupportMode & EsslSupportMode.Implicit) == EsslSupportMode.Implicit;
            if (isImplicitSsl)
                SwitchCtrlToSslMode();

            // Wait fot server message
            _bannerMessage = GetReply().Message;

            // Explicit SSL/TLS
            if (!isImplicitSsl)
                SslControlChannelCheckExplicitEncryptionRequest(sslSupportMode);

            // Login. Note that a password might not be required
            // TODO: check if the welcomeMessage is returned by the USER command in case the PASS command is not required.
            if (UserCmd(credential.UserName))
                _welcomeMessage = PassCmd(credential.Password);

            GetFeaturesFromServer();

            if (IsControlChannelEncrypted)
                if (!isImplicitSsl) {
                    SslDataChannelCheckExplicitEncryptionRequest();

                    if ((sslSupportMode & EsslSupportMode.ControlChannelRequested) != EsslSupportMode.ControlChannelRequested)
                        SSlCtrlChannelCheckRevertToClearText();
                } else
                    SslDataChannelImplicitEncryptionRequest();

            try {
                // This is required by some FTP servers and must precede any OPTS command
                if (CheckFeature("CLNT"))
                    ClntCmd(ClntName);

                // Set UTF8 as character encoding, but only if listed among the FEAT features
                if (CheckFeature("UTF8"))
                    SetTextEncoding(ETextEncoding.Utf8);
            } catch (Exception) {
                //TODO: add warning info
            }

            // Default binary transfers
            SetTransferMode(ETransferMode.Binary);

            return _welcomeMessage;
        }
Example #3
0
 public string Connect(string hostname, int port, NetworkCredential credential, EsslSupportMode sslSupportMode, int? timeout)
 {
     return Connect(hostname, port, credential, sslSupportMode, null, null, 0, 0, 0, timeout);
 }
Example #4
0
 public string Connect(string hostname, NetworkCredential credential, EsslSupportMode sslSupportMode,
                     RemoteCertificateValidationCallback userValidateServerCertificate)
 {
     // Default implicit FTPS port is 990, default standard and explicit FTPS port is 21
     int port = (sslSupportMode & EsslSupportMode.Implicit) == EsslSupportMode.Implicit ? 990 : 21;
     return Connect(hostname, port, credential, sslSupportMode, userValidateServerCertificate, null, 0, 0, 0, null);
 }
Example #5
0
 public string Connect(string hostname, NetworkCredential credential, EsslSupportMode sslSupportMode)
 {
     return Connect(hostname, credential, sslSupportMode, null);
 }
Example #6
0
 /// <summary>
 /// Anonymous authentication
 /// </summary>
 /// <param name="hostname"></param>
 /// <returns>The text of the \"welcome message\" sent by the server.</returns>
 public string Connect(string hostname, EsslSupportMode sslSupportMode)
 {
     return Connect(hostname, null, sslSupportMode);
 }
Example #7
0
        private void SslDataChannelCheckExplicitEncryptionRequest()
        {
            if ((_sslSupportCurrentMode & EsslSupportMode.DataChannelRequested) == EsslSupportMode.DataChannelRequested) {
                PbszCmd(0);

                try {
                    ProtCmd(EProtCode.P);
                } catch (FtpCommandException ex) {
                    // Note: MS FTP 7.0 returns 536, but RFC 2228 requires 534
                    if ((_sslSupportCurrentMode & EsslSupportMode.DataChannelRequired) == EsslSupportMode.DataChannelRequired)
                        if (ex.ErrorCode == 534 || ex.ErrorCode == 536)
                            throw new FtpSslException("The server policy denies SSL/TLS", ex);
                        else
                            throw;

                    _sslSupportCurrentMode ^= EsslSupportMode.DataChannelRequired;

                    // Data channel transfers will be done in clear text
                    ProtCmd(EProtCode.C);
                }
            }
        }
Example #8
0
 private void SSlCtrlChannelCheckRevertToClearText()
 {
     // Back to clear text mode, but only if supported by the server
     if (CheckFeature("CCC"))
         CccCmd();
     else
         _sslSupportCurrentMode |= EsslSupportMode.ControlChannelRequested;
 }
Example #9
0
        private void SslControlChannelCheckExplicitEncryptionRequest(EsslSupportMode sslSupportMode)
        {
            if ((sslSupportMode & EsslSupportMode.CredentialsRequested) == EsslSupportMode.CredentialsRequested)
                try {
                    AuthCmd(EAuthMechanism.Tls);
                } catch (FtpCommandException ex) {
                    if ((sslSupportMode & EsslSupportMode.CredentialsRequired) == EsslSupportMode.CredentialsRequired)
                        if (ex.ErrorCode == 530 || ex.ErrorCode == 534)
                            throw new FtpSslException("SSL/TLS connection not supported on server", ex);
                        else
                            throw;

                    _sslSupportCurrentMode = EsslSupportMode.ClearText;
                }
        }