/// <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 }
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)); } }
/// <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); }
/// <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; }
public Task SetHashAlgorithmAsync(FtpHashAlgorithm algorithm, CancellationToken token = default(CancellationToken)) { #if NET45 return(Task.FromResult(true)); #else return(Task.CompletedTask); #endif }
/// <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); }
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; }
/// <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); }
/// <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]); }
/// <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]); }
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; }
/// <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; }
/// <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); }
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 } } }
/// <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); }
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)); }
/// <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); } }
/// <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); } }
/// <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 }
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; } }
/// <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 }
public async Task SetHashAlgorithmAsync(FtpHashAlgorithm algorithm, CancellationToken token = default(CancellationToken)) { }
/// <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); } }
public void SetHashAlgorithm(FtpHashAlgorithm algorithm) { }
/// <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); } }
/// <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); } }
/// <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; } } } } } }
/// <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); } } }
public static bool HasFlag(this FtpHashAlgorithm flags, FtpHashAlgorithm flag) { return((flags & flag) == flag); }