Ejemplo n.º 1
0
        /// <summary>
        /// Get the first checksum algorithm mutually supported by both servers.
        /// </summary>
        private FtpHashAlgorithm GetFirstMutualChecksum(FtpClient destination)
        {
            // special handling for HASH command which is a meta-command supporting all hash types
            if (HasFeature(FtpCapability.HASH) && destination.HasFeature(FtpCapability.HASH))
            {
                if (HashAlgorithms.HasFlag(FtpHashAlgorithm.MD5) && destination.HashAlgorithms.HasFlag(FtpHashAlgorithm.MD5))
                {
                    return(FtpHashAlgorithm.MD5);
                }
                if (HashAlgorithms.HasFlag(FtpHashAlgorithm.SHA1) && destination.HashAlgorithms.HasFlag(FtpHashAlgorithm.SHA1))
                {
                    return(FtpHashAlgorithm.SHA1);
                }
                if (HashAlgorithms.HasFlag(FtpHashAlgorithm.SHA256) && destination.HashAlgorithms.HasFlag(FtpHashAlgorithm.SHA256))
                {
                    return(FtpHashAlgorithm.SHA256);
                }
                if (HashAlgorithms.HasFlag(FtpHashAlgorithm.SHA512) && destination.HashAlgorithms.HasFlag(FtpHashAlgorithm.SHA512))
                {
                    return(FtpHashAlgorithm.SHA512);
                }
                if (HashAlgorithms.HasFlag(FtpHashAlgorithm.CRC) && destination.HashAlgorithms.HasFlag(FtpHashAlgorithm.CRC))
                {
                    return(FtpHashAlgorithm.CRC);
                }
            }

            // handling for non-standard specific hashing commands
            if (HasFeature(FtpCapability.MD5) && destination.HasFeature(FtpCapability.MD5))
            {
                return(FtpHashAlgorithm.MD5);
            }
            if (HasFeature(FtpCapability.XMD5) && destination.HasFeature(FtpCapability.XMD5))
            {
                return(FtpHashAlgorithm.MD5);
            }
            if (HasFeature(FtpCapability.MMD5) && destination.HasFeature(FtpCapability.MMD5))
            {
                return(FtpHashAlgorithm.MD5);
            }
            if (HasFeature(FtpCapability.XSHA1) && destination.HasFeature(FtpCapability.XSHA1))
            {
                return(FtpHashAlgorithm.SHA1);
            }
            if (HasFeature(FtpCapability.XSHA256) && destination.HasFeature(FtpCapability.XSHA256))
            {
                return(FtpHashAlgorithm.SHA256);
            }
            if (HasFeature(FtpCapability.XSHA512) && destination.HasFeature(FtpCapability.XSHA512))
            {
                return(FtpHashAlgorithm.SHA512);
            }
            if (HasFeature(FtpCapability.XCRC) && destination.HasFeature(FtpCapability.XCRC))
            {
                return(FtpHashAlgorithm.CRC);
            }
            return(FtpHashAlgorithm.NONE);
        }
Ejemplo n.º 2
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
                }
            }
        }
Ejemplo n.º 3
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);
            }
        }
Ejemplo n.º 4
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);
            }
        }
Ejemplo n.º 5
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);
            }
        }