Checksum and move functions

May 23, 2013 at 10:03 AM
I am considering to start using System.Net.FtpClient instead of JSCAPE Secure FTP for which I have a lot of problems with interruptions to the FTP server with the components that I use today. But I have some questions I need answered before I dare to change.

Is it possible to compares checksum of the local data and remote file after uploading?

And is there support for moving files between different paths on the FTP server? I can not find any Move() function in the documentatiton, can move be done with Rename() function?
/ Jens
Coordinator
May 23, 2013 at 12:32 PM
Is it possible to compares checksum of the local data and remote file after uploading?
Nope, don't think the protocol supports any way to do that. TCP checksums the data it sends. If you need more guarantee than that FTP might be the wrong solution to your problem.
And is there support for moving files between different paths on the FTP server? I can not find any Move() function in the documentatiton, can move be done with Rename() function?
Yes, Rename() calls RNFR and RNTO which can effectively move files.
May 23, 2013 at 1:38 PM
Edited May 23, 2013 at 1:40 PM
Ok thanks any way, JSCAPE Secure FTP support MD5 checksum validation on local and remote file.
Jscape.Ftp Namespace

public bool Checksum(
   FileInfo localFile,
   string remoteFile
);
Hope that you implement that some day. I think you handel interuption better.
The problem with implementing a Checksum funktion is to calculate the remote file hash. To calculate the hach on the local file i do like this
using System.Security.Cryptography;

        protected static string CalculateMD5(string fileName) {
            using (FileStream file = new FileStream(fileName, FileMode.Open)) {
                using (MD5 md5 = new MD5CryptoServiceProvider()) {
                    byte[] retVal = md5.ComputeHash(file);
                    file.Close();
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < retVal.Length; i++) {
                        sb.Append(retVal[i].ToString("x2"));
                    }
                    return sb.ToString();
                }
            }
        }
Coordinator
May 23, 2013 at 1:45 PM
Edited May 23, 2013 at 1:46 PM
Unless you can point me to where RFC959 or an extension there of describes checksum'ing over FTP you won't see it in this code. As far as I know there is no way to perform such a task without proprietary extensions to the protocol or trying (and hoping for the best) to use the SITE command to execute something on the server to generate checksums. In the case of a non-standard function, you can utilize the Execute() method to send commands not implemented by the code provided here.
May 23, 2013 at 2:00 PM
Edited May 23, 2013 at 2:01 PM
I think thay use XCRC. The XCRC hash command asks the server to perform a cyclic redundancy check using the CRC-32 algorithm on the specified file. If the XCRC command is supported, the server will respond with the result of the calculation. FTP clients can use this command to verify that the file was transferred without corruption by comparing the server's response with its own calculation.
Coordinator
May 23, 2013 at 2:18 PM
XCRC and XMD5 are non-standard commands. You can implement them yourself using something along the lines of:
FtpReply reply;

if((reply = client.Execute("XCRC {0}", some_file)).Success) {
     // the reply message, presumably the CRC value, is in reply.Message
     // compare it to a locally computed crc value.
}
Coordinator
May 23, 2013 at 2:20 PM
I'm adding a link to this discussion to the documentation page for future reference.
Coordinator
May 23, 2013 at 4:34 PM
Edited May 23, 2013 at 4:36 PM
I've added support for the HASH command which is on standards track according to this draft. The new properties and methods are:
FtpClient.HashAlgorithms
FtpClient.SetHashAlgorithm
FtpClient.GetHashAlgorithm
FtpClient.GetHash(string path)
Coordinator
May 24, 2013 at 6:01 PM
I've added support for XCRC, XMD5, XSHA1, XSHA256 and XSHA512 to the latest revision. They are implemented as extension methods. If you add using System.Net.FtpClient.Extensions to your code you will gain the following methods:
GetXCRC()
BeginGetXCRC()
EndGetXCRC()
GetXMD5()
BeginGetXMD5()
EndGetXMD5()
GetXSHA1()
BeginGetXSHA1()
EndGetXSHA1()
GetX256()
BeginGetX256()
EndGetX256()
GetX512()
BeginGetX512()
EndGetX512()
As far as I know there is no built in way to compute CRC values in the .net framework however MD5, SHA[1,256,512] are included in the System.Security.Cryptography namespace so comparing hashes for those should be trivial to implement.
Coordinator
May 24, 2013 at 6:19 PM
And I've added the MD5 command, GetMD5(), BeginGetMD5(), EndGetMD5().
Coordinator
May 25, 2013 at 3:53 AM
I've added one last (I hope) method for this functionality called GetChecksum() which returns a FtpHash object containing the returned hash and the algorithm used. The object also has a Verify() method that can do comparisons of a stream or file for MD5, SHA1, SHA256 and SHA512 but not CRC. CRC is not supported natively by the framework and an implementation really exceeds the scope of this project so it's something you'll have to take-on yourself if you want CRC support. The commands are there though, how well they work I don't know. I only know of 2 servers that implement the X??? checksumming command and they both cost money so I'm not fooling around with testing against them. From what I've read, their implementation seemed trivial so here's to hoping they work as I've only tested HASH against FileZilla and it's an experimental feature there.
May 27, 2013 at 4:38 PM
Nice work, i will try it out.
Thanks!