Exemplo n.º 1
0
        /// <summary>
        /// Sets the hash algorithm on the server to use for the HASH command.
        /// </summary>
        internal void SetHashAlgorithmInternal(FtpHashAlgorithm algorithm)
        {
            FtpReply reply;

            // skip setting the hash algo if the server is already configured to it
            if (_LastHashAlgo == algorithm)
            {
                return;
            }

#if !CORE14
            lock (m_lock) {
#endif
            if ((HashAlgorithms & algorithm) != algorithm)
            {
                throw new NotImplementedException("The hash algorithm " + algorithm.ToString() + " was not advertised by the server.");
            }

            string algoName = HashAlgos.PrintToString(algorithm);

            if (!(reply = Execute("OPTS HASH " + algoName)).Success)
            {
                throw new FtpCommandException(reply);
            }

            // save the current hash algo so no need to repeat this command
            _LastHashAlgo = algorithm;

#if !CORE14
        }
#endif
        }
Exemplo n.º 2
0
 public bool Verify(string hash, string file, FtpHashAlgorithm m_algorithm)
 {
     using (FileStream istream = new FileStream(file, FileMode.Open, FileAccess.Read))
     {
         return(Verify(istream, hash, m_algorithm));
     }
 }
Exemplo n.º 3
0
        /// <summary>
        /// Gets the currently selected hash algorithm for the HASH command.
        /// </summary>
        /// <remarks>
        ///  This feature is experimental. See this link for details:
        /// http://tools.ietf.org/html/draft-bryan-ftpext-hash-02
        /// </remarks>
        /// <returns>The <see cref="FtpHashAlgorithm"/> flag or <see cref="FtpHashAlgorithm.NONE"/> if there was a problem.</returns>
        /// <example><code source="..\Examples\GetHashAlgorithm.cs" lang="cs" /></example>
        public FtpHashAlgorithm GetHashAlgorithm()
        {
            FtpReply         reply;
            FtpHashAlgorithm type = FtpHashAlgorithm.NONE;

#if !CORE14
            lock (m_lock) {
#endif
            if ((reply = Execute("OPTS HASH")).Success)
            {
                switch (reply.Message)
                {
                case "SHA-1":
                    type = FtpHashAlgorithm.SHA1;
                    break;

                case "SHA-256":
                    type = FtpHashAlgorithm.SHA256;
                    break;

                case "SHA-512":
                    type = FtpHashAlgorithm.SHA512;
                    break;

                case "MD5":
                    type = FtpHashAlgorithm.MD5;
                    break;
                }
            }
#if !CORE14
        }
#endif

            return(type);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Sets the hash algorithm on the server to be used with the HASH command asynchronously.
        /// </summary>
        internal async Task SetHashAlgorithmInternalAsync(FtpHashAlgorithm algorithm, CancellationToken token = default(CancellationToken))
        {
            FtpReply reply;

            // skip setting the hash algo if the server is already configured to it
            if (_LastHashAlgo == algorithm)
            {
                return;
            }

            if ((HashAlgorithms & algorithm) != algorithm)
            {
                throw new NotImplementedException("The hash algorithm " + algorithm.ToString() + " was not advertised by the server.");
            }

            string algoName = HashAlgos.PrintToString(algorithm);

            if (!(reply = await ExecuteAsync("OPTS HASH " + algoName, token)).Success)
            {
                throw new FtpCommandException(reply);
            }

            // save the current hash algo so no need to repeat this command
            _LastHashAlgo = algorithm;
        }
Exemplo n.º 5
0
        public Task SetHashAlgorithmAsync(FtpHashAlgorithm algorithm, CancellationToken token = default(CancellationToken))
        {
#if NET45
            return(Task.FromResult(true));
#else
            return(Task.CompletedTask);
#endif
        }
Exemplo n.º 6
0
 /// <summary>
 /// Sets the hash algorithm on the server to be used with the HASH command asynchronously.
 /// </summary>
 /// <param name="type">Hash algorithm to use</param>
 /// <exception cref="System.NotImplementedException">Thrown if the selected algorithm is not available on the server</exception>
 public async Task SetHashAlgorithmAsync(FtpHashAlgorithm type)
 {
     //TODO:  Rewrite as true async method with cancellation support
     await Task.Factory.FromAsync <FtpHashAlgorithm>(
         (t, ac, s) => BeginSetHashAlgorithm(t, ac, s),
         ar => EndSetHashAlgorithm(ar),
         type, null);
 }
Exemplo n.º 7
0
 public PackDownloadResult(FileInfo file, bool success, FtpHashAlgorithm hashAlgorithm = default, string checksum = null, bool isChecksumMatch = false)
 {
     File            = file;
     Success         = success;
     HashAlgorithm   = hashAlgorithm;
     Checksum        = checksum;
     IsChecksumMatch = isChecksumMatch;
 }
Exemplo n.º 8
0
        /// <summary>
        /// Hash verify
        /// </summary>
        /// <param name="istream"></param>
        /// <returns></returns>
        bool Verify(Stream istream, string input_hash, FtpHashAlgorithm m_algorithm)
        {
            HashAlgorithm hashAlg = null;

            switch (m_algorithm)
            {
            case FtpHashAlgorithm.SHA1:
                hashAlg = new SHA1CryptoServiceProvider();
                break;

#if !NET2
            case FtpHashAlgorithm.SHA256:
                hashAlg = new SHA256CryptoServiceProvider();
                break;

            case FtpHashAlgorithm.SHA512:
                hashAlg = new SHA512CryptoServiceProvider();
                break;
#endif
            case FtpHashAlgorithm.MD5:
                hashAlg = new MD5CryptoServiceProvider();
                break;

            case FtpHashAlgorithm.CRC:
                throw new NotImplementedException("There is no built in support for computing CRC hashes.");

            default:
                throw new NotImplementedException("Unknown hash algorithm: " + m_algorithm.ToString());
            }

            try
            {
                byte[] data = null;
                string hash = "";

                data = hashAlg.ComputeHash(istream);
                if (data != null)
                {
                    foreach (byte b in data)
                    {
                        hash += b.ToString("x2");
                    }

                    return(hash.ToUpper() == input_hash.ToUpper());
                }
            }
            finally
            {
#if !NET2 // .NET 2.0 doesn't provide access to Dispose() for HashAlgorithm
                if (hashAlg != null)
                {
                    hashAlg.Dispose();
                }
#endif
            }

            return(false);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Get string representation of FtpHashAlgorithm
        /// </summary>
        /// <param name="name">FtpHashAlgorithm to be converted into string</param>
        /// <returns>Name of the hash algorithm</returns>
        public static string PrintToString(this FtpHashAlgorithm name)
        {
            if (!EnumToName.ContainsKey(name))
            {
                return(name.ToString());
            }

            return(EnumToName[name]);
        }
Exemplo n.º 10
0
        /// <summary>
        /// Get string representation of FtpHashAlgorithm
        /// </summary>
        /// <param name="ftpHashAlgorithm">FtpHashAlgorithm to be converted into string</param>
        /// <returns>Name of the hash algorithm</returns>
        public static string ToString(FtpHashAlgorithm ftpHashAlgorithm)
        {
            if (!EnumToName.ContainsKey(ftpHashAlgorithm))
            {
                return(ftpHashAlgorithm.ToString());
            }

            return(EnumToName[ftpHashAlgorithm]);
        }
Exemplo n.º 11
0
 public FileDownloadResult(bool successful, string filePath, string checksum = null, FtpHashAlgorithm hashAlgorithm = default, bool doesHashMatch = false)
 {
     Successful    = successful;
     FilePath      = filePath;
     Checksum      = checksum;
     HashAlgorithm = hashAlgorithm;
     DoesHashMatch = doesHashMatch;
     Exception     = null;
 }
Exemplo n.º 12
0
 /// <summary>
 /// These flags must be reset every time we connect, to allow for users to connect to
 /// different FTP servers with the same client object.
 /// </summary>
 private void ResetStateFlags()
 {
     _EPSVNotSupported          = false;
     _FileSizeASCIINotSupported = false;
     _RecursiveListSupported    = false;
     _LastWorkingDir            = null;
     _LastHashAlgo          = FtpHashAlgorithm.NONE;
     _ConnectionFTPSFailure = false;
     _ConnectionUTF8Success = false;
 }
Exemplo n.º 13
0
 /// <summary>
 /// Get the first supported algorithm, in the standard order of preference. If no hashing algos found, returns NONE.
 /// </summary>
 public static FtpHashAlgorithm FirstSupported(FtpHashAlgorithm supportedFlags)
 {
     foreach (var algo in AlgoPreference)
     {
         if (supportedFlags.HasFlag(algo))
         {
             return(algo);
         }
     }
     return(FtpHashAlgorithm.NONE);
 }
Exemplo n.º 14
0
        private void ValidateHashAlgorithm(FtpHashAlgorithm algorithm)
        {
            // if NO hashing algos or commands supported, throw here
            if (!HasFeature(FtpCapability.HASH) &&
                !HasFeature(FtpCapability.MD5) &&
                !HasFeature(FtpCapability.XMD5) &&
                !HasFeature(FtpCapability.MMD5) &&
                !HasFeature(FtpCapability.XSHA1) &&
                !HasFeature(FtpCapability.XSHA256) &&
                !HasFeature(FtpCapability.XSHA512) &&
                !HasFeature(FtpCapability.XCRC))
            {
                throw new FtpHashUnsupportedException();
            }

            // only if the user has specified a certain hash algorithm
            var useFirst = (algorithm == FtpHashAlgorithm.NONE);

            if (!useFirst)
            {
                // first check if the HASH command supports the required algo
                if (HasFeature(FtpCapability.HASH) && HashAlgorithms.HasFlag(algorithm))
                {
                    // we are good
                }
                else
                {
                    // second check if the special FTP command is supported based on the algo
                    if (algorithm == FtpHashAlgorithm.MD5 && !HasFeature(FtpCapability.MD5) &&
                        !HasFeature(FtpCapability.XMD5) && !HasFeature(FtpCapability.MMD5))
                    {
                        throw new FtpHashUnsupportedException(FtpHashAlgorithm.MD5, "MD5, XMD5, MMD5");
                    }
                    if (algorithm == FtpHashAlgorithm.SHA1 && !HasFeature(FtpCapability.XSHA1))
                    {
                        throw new FtpHashUnsupportedException(FtpHashAlgorithm.SHA1, "XSHA1");
                    }
                    if (algorithm == FtpHashAlgorithm.SHA256 && !HasFeature(FtpCapability.XSHA256))
                    {
                        throw new FtpHashUnsupportedException(FtpHashAlgorithm.SHA256, "XSHA256");
                    }
                    if (algorithm == FtpHashAlgorithm.SHA512 && !HasFeature(FtpCapability.XSHA512))
                    {
                        throw new FtpHashUnsupportedException(FtpHashAlgorithm.SHA512, "XSHA512");
                    }
                    if (algorithm == FtpHashAlgorithm.CRC && !HasFeature(FtpCapability.XCRC))
                    {
                        throw new FtpHashUnsupportedException(FtpHashAlgorithm.CRC, "XCRC");
                    }

                    // we are good
                }
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// Begins an asynchronous operation to set the hash algorithm on the server to use for the HASH command.
        /// </summary>
        /// <remarks>
        /// If you specify an algorithm not listed in <see cref="FtpClient.HashAlgorithms"/>
        /// a <see cref="NotImplementedException"/> will be thrown
        /// so be sure to query that list of Flags before
        /// selecting a hash algorithm. Support for the
        /// HASH command is experimental. Please see
        /// the following link for more details:
        /// http://tools.ietf.org/html/draft-bryan-ftpext-hash-02
        /// </remarks>
        /// <param name="type">Hash algorithm to use</param>
        /// <param name="callback">Async Callback</param>
        /// <param name="state">State object</param>
        /// <returns>IAsyncResult</returns>
        public IAsyncResult BeginSetHashAlgorithm(FtpHashAlgorithm type, AsyncCallback callback, object state)
        {
            AsyncSetHashAlgorithm func;
            IAsyncResult          ar;

            lock (m_asyncmethods) {
                ar = (func = SetHashAlgorithm).BeginInvoke(type, callback, state);
                m_asyncmethods.Add(ar, func);
            }

            return(ar);
        }
Exemplo n.º 16
0
        protected virtual PackDownloadResult Download(Uri uri)
        {
            string path = Path.Combine(DownloadsDirectory.FullName, Path.GetFileName(uri.ToString()));

            if (uri.IsAbsoluteUri)
            {
                if (uri.Scheme.Equals("http") || uri.Scheme.Equals("https"))
                {
                    using (WebClient client = new WebClient())
                    {
                        client.DownloadFile(uri, path);
                        return(new PackDownloadResult(path, true));
                    }
                }
                else if (uri.Scheme.Equals("ftp") || uri.Scheme.Equals("ftps"))
                {
                    using FtpClient client = FtpClient.Connect(uri);

                    // Get the hash of the file, if supported.

                    string           hash = null;
                    FtpHashAlgorithm algo = FtpHashAlgorithm.NONE;

                    if (!client.HashAlgorithms.HasFlag(FtpHashAlgorithm.NONE))
                    {
                        // CRC32 is prefered due to its speed.
                        if (client.HashAlgorithms.HasFlag(FtpHashAlgorithm.CRC))
                        {
                            client.SetHashAlgorithm(FtpHashAlgorithm.CRC);
                        }

                        // Take the hash.
                        FtpHash ftpHash = client.GetChecksum(uri.AbsolutePath);
                        hash = ftpHash.Value;
                        algo = ftpHash.Algorithm;
                    }

                    // Download the file.
                }
            }
            else
            {
                string source = uri.ToString();

                if (File.Exists(source))
                {
                    File.Copy(source, path);
                    return(new PackDownloadResult(path, true));
                }
            }

            return(new PackDownloadResult(default(FileInfo), false));
        }
Exemplo n.º 17
0
        /// <summary>
        /// Begins an asynchronous operation to retrieve a checksum of the given file using a checksum method that the server supports, if any.
        /// </summary>
        /// <remarks>
        /// The algorithm used goes in this order:
        /// 1. HASH command; server preferred algorithm. See <see cref="FtpClient.SetHashAlgorithm"/>
        /// 2. MD5 / XMD5 / MMD5 commands
        /// 3. XSHA1 command
        /// 4. XSHA256 command
        /// 5. XSHA512 command
        /// 6. XCRC command
        /// </remarks>
        /// <param name="path">Full or relative path to remote file</param>
        /// <param name="callback">AsyncCallback</param>
        /// <param name="state">State Object</param>
        /// <returns>IAsyncResult</returns>
        public IAsyncResult BeginGetChecksum(string path, AsyncCallback callback,
                                             object state, FtpHashAlgorithm algorithm = FtpHashAlgorithm.NONE)
        {
            var func = new AsyncGetChecksum(GetChecksum);
            IAsyncResult ar;

            lock (m_asyncmethods) {
                ar = func.BeginInvoke(path, algorithm, callback, state);
                m_asyncmethods.Add(ar, func);
            }

            return(ar);
        }
            private static FileHashAlgorithm GetHashAlgorithm(FtpHashAlgorithm algorithm)
            {
                switch (algorithm)
                {
                case FtpHashAlgorithm.SHA1: return(FileHashAlgorithm.Sha1);

                case FtpHashAlgorithm.SHA256: return(FileHashAlgorithm.Sha256);

                case FtpHashAlgorithm.SHA512: return(FileHashAlgorithm.Sha512);

                case FtpHashAlgorithm.MD5: return(FileHashAlgorithm.Md5);

                case FtpHashAlgorithm.CRC: return(FileHashAlgorithm.Crc);

                default: return(FileHashAlgorithm.None);
                }
            }
Exemplo n.º 19
0
        /// <summary>
        /// Sets the hash algorithm on the server to be used with the HASH command asynchronously.
        /// </summary>
        /// <param name="type">Hash algorithm to use</param>
        /// <param name="token">The token that can be used to cancel the entire process</param>
        /// <exception cref="System.NotImplementedException">Thrown if the selected algorithm is not available on the server</exception>
        public async Task SetHashAlgorithmAsync(FtpHashAlgorithm type, CancellationToken token = default(CancellationToken))
        {
            FtpReply reply;
            string   algorithm;

            if ((HashAlgorithms & type) != type)
            {
                throw new NotImplementedException("The hash algorithm " + type.ToString() + " was not advertised by the server.");
            }

            algorithm = FtpHashAlgorithms.ToString(type);

            if (!(reply = await ExecuteAsync("OPTS HASH " + algorithm, token)).Success)
            {
                throw new FtpCommandException(reply);
            }
        }
Exemplo n.º 20
0
        /// <summary>
        /// Sets the hash algorithm on the server to use for the HASH command.
        /// </summary>
        /// <remarks>
        /// If you specify an algorithm not listed in <see cref="FtpClient.HashAlgorithms"/>
        /// a <see cref="NotImplementedException"/> will be thrown
        /// so be sure to query that list of Flags before
        /// selecting a hash algorithm. Support for the
        /// HASH command is experimental. Please see
        /// the following link for more details:
        /// http://tools.ietf.org/html/draft-bryan-ftpext-hash-02
        /// </remarks>
        /// <param name="type">Hash Algorithm</param>
        /// <exception cref="System.NotImplementedException">Thrown if the selected algorithm is not available on the server</exception>
        /// <example><code source="..\Examples\SetHashAlgorithm.cs" lang="cs" /></example>
        public void SetHashAlgorithm(FtpHashAlgorithm type)
        {
            FtpReply reply;
            string   algorithm;

#if !CORE14
            lock (m_lock) {
#endif
            if ((HashAlgorithms & type) != type)
            {
                throw new NotImplementedException("The hash algorithm " + type.ToString() + " was not advertised by the server.");
            }

            switch (type)
            {
            case FtpHashAlgorithm.SHA1:
                algorithm = "SHA-1";
                break;

            case FtpHashAlgorithm.SHA256:
                algorithm = "SHA-256";
                break;

            case FtpHashAlgorithm.SHA512:
                algorithm = "SHA-512";
                break;

            case FtpHashAlgorithm.MD5:
                algorithm = "MD5";
                break;

            default:
                algorithm = type.ToString();
                break;
            }

            if (!(reply = Execute("OPTS HASH " + algorithm)).Success)
            {
                throw new FtpCommandException(reply);
            }

#if !CORE14
        }
#endif
        }
Exemplo n.º 21
0
        public async Task <string> GetCheckSumAsync(string path, string fileName, FtpHashAlgorithm algorithm)
        {
            try
            {
                string result = string.Empty;

                FtpHash remoteHash = await _ftpClient.GetChecksumAsync(path + fileName);

                if (remoteHash.IsValid)
                {
                    result = remoteHash.Value;
                }

                return(result);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Exemplo n.º 22
0
        /// <summary>
        /// Sets the hash algorithm on the server to use for the HASH command.
        /// </summary>
        /// <remarks>
        /// If you specify an algorithm not listed in <see cref="FtpClient.HashAlgorithms"/>
        /// a <see cref="NotImplementedException"/> will be thrown
        /// so be sure to query that list of Flags before
        /// selecting a hash algorithm. Support for the
        /// HASH command is experimental. Please see
        /// the following link for more details:
        /// http://tools.ietf.org/html/draft-bryan-ftpext-hash-02
        /// </remarks>
        /// <param name="type">Hash Algorithm</param>
        /// <exception cref="System.NotImplementedException">Thrown if the selected algorithm is not available on the server</exception>
        /// <example><code source="..\Examples\SetHashAlgorithm.cs" lang="cs" /></example>
        public void SetHashAlgorithm(FtpHashAlgorithm type)
        {
            FtpReply reply;
            string   algorithm;

#if !CORE14
            lock (m_lock) {
#endif
            if ((HashAlgorithms & type) != type)
            {
                throw new NotImplementedException("The hash algorithm " + type.ToString() + " was not advertised by the server.");
            }

            algorithm = FtpHashAlgorithms.ToString(type);

            if (!(reply = Execute("OPTS HASH " + algorithm)).Success)
            {
                throw new FtpCommandException(reply);
            }

#if !CORE14
        }
#endif
        }
Exemplo n.º 23
0
 public async Task SetHashAlgorithmAsync(FtpHashAlgorithm algorithm, CancellationToken token = default(CancellationToken))
 {
 }
Exemplo n.º 24
0
        /// <summary>
        /// Retrieves a checksum of the given file using the specified checksum algorithum, or using the first available algorithm that the server supports.
        /// </summary>
        /// <remarks>
        /// The algorithm used goes in this order:
        /// 1. HASH command; server preferred algorithm. See <see cref="FtpClient.SetHashAlgorithm"/>
        /// 2. MD5 / XMD5 / MMD5 commands
        /// 3. XSHA1 command
        /// 4. XSHA256 command
        /// 5. XSHA512 command
        /// 6. XCRC command
        /// </remarks>
        /// <param name="path">Full or relative path of the file to checksum</param>
        /// <param name="algorithm">Specify an algorithm that you prefer, or NONE to use the first available algorithm. If the preferred algorithm is not supported, a blank hash is returned.</param>
        /// <returns><see cref="FtpHash"/> object containing the value and algorithm. Use the <see cref="FtpHash.IsValid"/> property to
        /// determine if this command was successful. <see cref="FtpCommandException"/>s can be thrown from
        /// the underlying calls.</returns>
        /// <example><code source="..\Examples\GetChecksum.cs" lang="cs" /></example>
        /// <exception cref="FtpCommandException">The command fails</exception>
        public FtpHash GetChecksum(string path, FtpHashAlgorithm algorithm = FtpHashAlgorithm.NONE)
        {
            // if HASH is supported and the caller prefers an algorithm and that algorithm is supported
            var useFirst = algorithm == FtpHashAlgorithm.NONE;

            if (HasFeature(FtpCapability.HASH) && !useFirst && HashAlgorithms.HasFlag(algorithm))
            {
                // switch to that algorithm
                SetHashAlgorithm(algorithm);

                // get the hash of the file
                return(GetHash(path));
            }

            // if HASH is supported and the caller does not prefer any specific algorithm
            else if (HasFeature(FtpCapability.HASH) && useFirst)
            {
                return(GetHash(path));
            }
            else
            {
                var result = new FtpHash();

                // execute the first available algorithm, or the preferred algorithm if specified

                if (HasFeature(FtpCapability.MD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value     = GetMD5(path);
                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.XMD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value     = GetXMD5(path);
                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.MMD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value     = GetMD5(path);
                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.XSHA1) && (useFirst || algorithm == FtpHashAlgorithm.SHA1))
                {
                    result.Value     = GetXSHA1(path);
                    result.Algorithm = FtpHashAlgorithm.SHA1;
                }
                else if (HasFeature(FtpCapability.XSHA256) && (useFirst || algorithm == FtpHashAlgorithm.SHA256))
                {
                    result.Value     = GetXSHA256(path);
                    result.Algorithm = FtpHashAlgorithm.SHA256;
                }
                else if (HasFeature(FtpCapability.XSHA512) && (useFirst || algorithm == FtpHashAlgorithm.SHA512))
                {
                    result.Value     = GetXSHA512(path);
                    result.Algorithm = FtpHashAlgorithm.SHA512;
                }
                else if (HasFeature(FtpCapability.XCRC) && (useFirst || algorithm == FtpHashAlgorithm.CRC))
                {
                    result.Value     = GetXCRC(path);
                    result.Algorithm = FtpHashAlgorithm.CRC;
                }

                return(result);
            }
        }
Exemplo n.º 25
0
 public void SetHashAlgorithm(FtpHashAlgorithm algorithm)
 {
 }
Exemplo n.º 26
0
        /// <summary>
        /// Retrieves a checksum of the given file using the specified checksum algorithm, or using the first available algorithm that the server supports.
        /// </summary>
        /// <remarks>
        /// The algorithm used goes in this order:
        /// 1. HASH command using the first supported algorithm.
        /// 2. MD5 / XMD5 / MMD5 commands
        /// 3. XSHA1 command
        /// 4. XSHA256 command
        /// 5. XSHA512 command
        /// 6. XCRC command
        /// </remarks>
        /// <param name="path">Full or relative path of the file to checksum</param>
        /// <param name="algorithm">Specify an algorithm that you prefer, or NONE to use the first available algorithm. If the preferred algorithm is not supported, a blank hash is returned.</param>
        /// <returns><see cref="FtpHash"/> object containing the value and algorithm. Use the <see cref="FtpHash.IsValid"/> property to
        /// determine if this command was successful. <see cref="FtpCommandException"/>s can be thrown from
        /// the underlying calls.</returns>
        /// <exception cref="FtpCommandException">The command fails</exception>
        public FtpHash GetChecksum(string path, FtpHashAlgorithm algorithm = FtpHashAlgorithm.NONE)
        {
            if (path == null)
            {
                throw new ArgumentException("Required argument is null", "path");
            }

            ValidateHashAlgorithm(algorithm);

            path = path.GetFtpPath();

            LogFunc(nameof(GetChecksum), new object[] { path });

            var useFirst = (algorithm == FtpHashAlgorithm.NONE);

            // if HASH is supported and the caller prefers an algorithm and that algorithm is supported
            if (HasFeature(FtpCapability.HASH) && !useFirst && HashAlgorithms.HasFlag(algorithm))
            {
                // switch to that algorithm
                SetHashAlgorithmInternal(algorithm);

                // get the hash of the file using HASH Command
                return(HashCommandInternal(path));
            }

            // if HASH is supported and the caller does not prefer any specific algorithm
            else if (HasFeature(FtpCapability.HASH) && useFirst)
            {
                // switch to the first preferred algorithm
                SetHashAlgorithmInternal(HashAlgos.FirstSupported(HashAlgorithms));

                // get the hash of the file using HASH Command
                return(HashCommandInternal(path));
            }
            else
            {
                var result = new FtpHash();

                // execute the first available algorithm, or the preferred algorithm if specified

                if (HasFeature(FtpCapability.MD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value     = GetHashInternal(path, "MD5");
                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.XMD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value     = GetHashInternal(path, "XMD5");
                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.MMD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value     = GetHashInternal(path, "MMD5");
                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.XSHA1) && (useFirst || algorithm == FtpHashAlgorithm.SHA1))
                {
                    result.Value     = GetHashInternal(path, "XSHA1");
                    result.Algorithm = FtpHashAlgorithm.SHA1;
                }
                else if (HasFeature(FtpCapability.XSHA256) && (useFirst || algorithm == FtpHashAlgorithm.SHA256))
                {
                    result.Value     = GetHashInternal(path, "XSHA256");
                    result.Algorithm = FtpHashAlgorithm.SHA256;
                }
                else if (HasFeature(FtpCapability.XSHA512) && (useFirst || algorithm == FtpHashAlgorithm.SHA512))
                {
                    result.Value     = GetHashInternal(path, "XSHA512");
                    result.Algorithm = FtpHashAlgorithm.SHA512;
                }
                else if (HasFeature(FtpCapability.XCRC) && (useFirst || algorithm == FtpHashAlgorithm.CRC))
                {
                    result.Value     = GetHashInternal(path, "XCRC");
                    result.Algorithm = FtpHashAlgorithm.CRC;
                }

                return(result);
            }
        }
Exemplo n.º 27
0
        /// <summary>
        /// Retrieves a checksum of the given file using the specified checksum algorithum, or using the first available algorithm that the server supports.
        /// </summary>
        /// <remarks>
        /// The algorithm used goes in this order:
        /// 1. HASH command; server preferred algorithm. See <see cref="FtpClient.SetHashAlgorithm"/>
        /// 2. MD5 / XMD5 / MMD5 commands
        /// 3. XSHA1 command
        /// 4. XSHA256 command
        /// 5. XSHA512 command
        /// 6. XCRC command
        /// </remarks>
        /// <param name="path">Full or relative path of the file to checksum</param>
        /// <param name="token">The token that can be used to cancel the entire process</param>
        /// <param name="algorithm">Specify an algorithm that you prefer, or NONE to use the first available algorithm. If the preferred algorithm is not supported, a blank hash is returned.</param>
        /// <returns><see cref="FtpHash"/> object containing the value and algorithm. Use the <see cref="FtpHash.IsValid"/> property to
        /// determine if this command was successful. <see cref="FtpCommandException"/>s can be thrown from
        /// the underlying calls.</returns>
        /// <example><code source="..\Examples\GetChecksum.cs" lang="cs" /></example>
        /// <exception cref="FtpCommandException">The command fails</exception>
        public async Task <FtpHash> GetChecksumAsync(string path, CancellationToken token = default(CancellationToken), FtpHashAlgorithm algorithm = FtpHashAlgorithm.NONE)
        {
            // if HASH is supported and the caller prefers an algorithm and that algorithm is supported
            var useFirst = algorithm == FtpHashAlgorithm.NONE;

            if (HasFeature(FtpCapability.HASH) && !useFirst && HashAlgorithms.HasFlag(algorithm))
            {
                // switch to that algorithm
                await SetHashAlgorithmAsync(algorithm, token);

                // get the hash of the file
                return(await GetHashAsync(path, token));
            }

            // if HASH is supported and the caller does not prefer any specific algorithm
            else if (HasFeature(FtpCapability.HASH) && useFirst)
            {
                return(await GetHashAsync(path, token));
            }

            else
            {
                var result = new FtpHash();

                // execute the first available algorithm, or the preferred algorithm if specified

                if (HasFeature(FtpCapability.MD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value = await GetMD5Async(path, token);

                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.XMD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value = await GetXMD5Async(path, token);

                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.MMD5) && (useFirst || algorithm == FtpHashAlgorithm.MD5))
                {
                    result.Value = await GetMD5Async(path, token);

                    result.Algorithm = FtpHashAlgorithm.MD5;
                }
                else if (HasFeature(FtpCapability.XSHA1) && (useFirst || algorithm == FtpHashAlgorithm.SHA1))
                {
                    result.Value = await GetXSHA1Async(path, token);

                    result.Algorithm = FtpHashAlgorithm.SHA1;
                }
                else if (HasFeature(FtpCapability.XSHA256) && (useFirst || algorithm == FtpHashAlgorithm.SHA256))
                {
                    result.Value = await GetXSHA256Async(path, token);

                    result.Algorithm = FtpHashAlgorithm.SHA256;
                }
                else if (HasFeature(FtpCapability.XSHA512) && (useFirst || algorithm == FtpHashAlgorithm.SHA512))
                {
                    result.Value = await GetXSHA512Async(path, token);

                    result.Algorithm = FtpHashAlgorithm.SHA512;
                }
                else if (HasFeature(FtpCapability.XCRC) && (useFirst || algorithm == FtpHashAlgorithm.CRC))
                {
                    result.Value = await GetXCRCAsync(path, token);

                    result.Algorithm = FtpHashAlgorithm.CRC;
                }

                return(result);
            }
        }
Exemplo n.º 28
0
        /// <summary>
        /// Populates the capabilities flags based on capabilities given in the list of strings.
        /// </summary>
        public static void GetFeatures(FtpClient client, List <FtpCapability> m_capabilities, ref FtpHashAlgorithm m_hashAlgorithms, string[] features)
        {
            foreach (var feat in features)
            {
                var featName = feat.Trim().ToUpper();

                if (featName.StartsWith("MLST") || featName.StartsWith("MLSD"))
                {
                    m_capabilities.AddOnce(FtpCapability.MLSD);
                }
                else if (featName.StartsWith("MDTM"))
                {
                    m_capabilities.AddOnce(FtpCapability.MDTM);
                }
                else if (featName.StartsWith("REST STREAM"))
                {
                    m_capabilities.AddOnce(FtpCapability.REST);
                }
                else if (featName.StartsWith("SIZE"))
                {
                    m_capabilities.AddOnce(FtpCapability.SIZE);
                }
                else if (featName.StartsWith("UTF8"))
                {
                    m_capabilities.AddOnce(FtpCapability.UTF8);
                }
                else if (featName.StartsWith("PRET"))
                {
                    m_capabilities.AddOnce(FtpCapability.PRET);
                }
                else if (featName.StartsWith("MFMT"))
                {
                    m_capabilities.AddOnce(FtpCapability.MFMT);
                }
                else if (featName.StartsWith("MFCT"))
                {
                    m_capabilities.AddOnce(FtpCapability.MFCT);
                }
                else if (featName.StartsWith("MFF"))
                {
                    m_capabilities.AddOnce(FtpCapability.MFF);
                }
                else if (featName.StartsWith("MMD5"))
                {
                    m_capabilities.AddOnce(FtpCapability.MMD5);
                }
                else if (featName.StartsWith("XMD5"))
                {
                    m_capabilities.AddOnce(FtpCapability.XMD5);
                }
                else if (featName.StartsWith("XCRC"))
                {
                    m_capabilities.AddOnce(FtpCapability.XCRC);
                }
                else if (featName.StartsWith("XSHA1"))
                {
                    m_capabilities.AddOnce(FtpCapability.XSHA1);
                }
                else if (featName.StartsWith("XSHA256"))
                {
                    m_capabilities.AddOnce(FtpCapability.XSHA256);
                }
                else if (featName.StartsWith("XSHA512"))
                {
                    m_capabilities.AddOnce(FtpCapability.XSHA512);
                }
                else if (featName.StartsWith("EPSV"))
                {
                    m_capabilities.AddOnce(FtpCapability.EPSV);
                }
                else if (featName.StartsWith("CPSV"))
                {
                    m_capabilities.AddOnce(FtpCapability.CPSV);
                }
                else if (featName.StartsWith("NOOP"))
                {
                    m_capabilities.AddOnce(FtpCapability.NOOP);
                }
                else if (featName.StartsWith("CLNT"))
                {
                    m_capabilities.AddOnce(FtpCapability.CLNT);
                }
                else if (featName.StartsWith("SSCN"))
                {
                    m_capabilities.AddOnce(FtpCapability.SSCN);
                }
                else if (featName.StartsWith("SITE MKDIR"))
                {
                    m_capabilities.AddOnce(FtpCapability.SITE_MKDIR);
                }
                else if (featName.StartsWith("SITE RMDIR"))
                {
                    m_capabilities.AddOnce(FtpCapability.SITE_RMDIR);
                }
                else if (featName.StartsWith("SITE UTIME"))
                {
                    m_capabilities.AddOnce(FtpCapability.SITE_UTIME);
                }
                else if (featName.StartsWith("SITE SYMLINK"))
                {
                    m_capabilities.AddOnce(FtpCapability.SITE_SYMLINK);
                }
                else if (featName.StartsWith("AVBL"))
                {
                    m_capabilities.AddOnce(FtpCapability.AVBL);
                }
                else if (featName.StartsWith("THMB"))
                {
                    m_capabilities.AddOnce(FtpCapability.THMB);
                }
                else if (featName.StartsWith("RMDA"))
                {
                    m_capabilities.AddOnce(FtpCapability.RMDA);
                }
                else if (featName.StartsWith("DSIZ"))
                {
                    m_capabilities.AddOnce(FtpCapability.DSIZ);
                }
                else if (featName.StartsWith("HOST"))
                {
                    m_capabilities.AddOnce(FtpCapability.HOST);
                }
                else if (featName.StartsWith("CCC"))
                {
                    m_capabilities.AddOnce(FtpCapability.CCC);
                }
                else if (featName.StartsWith("MODE Z"))
                {
                    m_capabilities.AddOnce(FtpCapability.MODE_Z);
                }
                else if (featName.StartsWith("LANG"))
                {
                    m_capabilities.AddOnce(FtpCapability.LANG);
                }
                else if (featName.StartsWith("HASH"))
                {
                    Match m;

                    m_capabilities.AddOnce(FtpCapability.HASH);

                    if ((m = Regex.Match(featName, @"^HASH\s+(?<types>.*)$")).Success)
                    {
                        foreach (var type in m.Groups["types"].Value.Split(';'))
                        {
                            switch (type.ToUpper().Trim())
                            {
                            case "SHA-1":
                            case "SHA-1*":
                                m_hashAlgorithms |= FtpHashAlgorithm.SHA1;
                                break;

                            case "SHA-256":
                            case "SHA-256*":
                                m_hashAlgorithms |= FtpHashAlgorithm.SHA256;
                                break;

                            case "SHA-512":
                            case "SHA-512*":
                                m_hashAlgorithms |= FtpHashAlgorithm.SHA512;
                                break;

                            case "MD5":
                            case "MD5*":
                                m_hashAlgorithms |= FtpHashAlgorithm.MD5;
                                break;

                            case "CRC":
                            case "CRC*":
                                m_hashAlgorithms |= FtpHashAlgorithm.CRC;
                                break;
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 29
0
 /// <summary>
 /// Assume the FTP Server's capabilities if it does not support the FEAT command.
 /// </summary>
 public static void AssumeCapabilities(FtpClient client, FtpBaseServer handler, List <FtpCapability> m_capabilities, ref FtpHashAlgorithm m_hashAlgorithms)
 {
     // ask the server handler to assume its capabilities
     if (handler != null)
     {
         var caps = handler.DefaultCapabilities();
         if (caps != null)
         {
             // add the assumed capabilities to our set
             GetFeatures(client, m_capabilities, ref m_hashAlgorithms, caps);
         }
     }
 }
Exemplo n.º 30
0
 public static bool HasFlag(this FtpHashAlgorithm flags, FtpHashAlgorithm flag)
 {
     return((flags & flag) == flag);
 }