This example illustrates the use of ProFTPClient in explicit FTPS mode with server validation.
The example performs the following operations:
You can view the source-code here.
Run the example by:
run host-name username password filename (hostname-checking)
where
The final argument is optional and should be left out initially. It determines whether or not host-name checking is enabled. Possible values are on and off. By default host-name checking is enabled (i.e. on). More details on this will be given later.
Verify that the output looks something like this:
INFO [ServerValidatingClient] 26 Jan 2005 16:45:27.462 : Creating FTPS (explicit) client INFO [ServerValidatingClient] 26 Jan 2005 16:45:27.482 : Host-name checking enabled INFO [ServerValidatingClient] 26 Jan 2005 16:45:27.482 : Connecting to server LOCALHOST INFO [ServerValidatingClient] 26 Jan 2005 16:45:28.573 : Switching to FTPS (explicit mode) INFO [ServerValidatingClient] 26 Jan 2005 16:45:29.044 : Logging in with username=test INFO [ServerValidatingClient] 26 Jan 2005 16:45:29.084 : Setting up passive, ASCII transfers INFO [ServerValidatingClient] 26 Jan 2005 16:45:29.084 : Directory before put: INFO [ServerValidatingClient] 26 Jan 2005 16:45:29.675 : no files INFO [ServerValidatingClient] 26 Jan 2005 16:45:29.675 : Putting ServerValidatingClient.exe to server INFO [ServerValidatingClient] 26 Jan 2005 16:45:29.995 : Directory after put: INFO [ServerValidatingClient] 26 Jan 2005 16:45:30.336 : -rw-r--r-- 1 SYSTEM None 16235 Jan 26 06:45 ServerValidatingClient.exe INFO [ServerValidatingClient] 26 Jan 2005 16:45:30.336 : Getting ServerValidatingClient.exe from server and saving as ServerValidatingClient.exe.copy INFO [ServerValidatingClient] 26 Jan 2005 16:45:30.776 : Deleting ServerValidatingClient.exe INFO [ServerValidatingClient] 26 Jan 2005 16:45:30.776 : Directory after delete: INFO [ServerValidatingClient] 26 Jan 2005 16:45:31.137 : no files INFO [ServerValidatingClient] 26 Jan 2005 16:45:31.137 : Quitting client INFO [ServerValidatingClient] 26 Jan 2005 16:45:31.157 : Test complete
There should now also be a file called YourFilename.copy in the local directory.
If, instead of the above, something like the following output is produced:
INFO [FullyValidatingClient] 25 Feb 2005 14:07:48.675 : Creating FTPS (explicit) client INFO [FullyValidatingClient] 25 Feb 2005 14:07:48.675 : Host-name checking enabled INFO [FullyValidatingClient] 25 Feb 2005 14:07:48.735 : Loading client cert from client.cert.pem and key from client.pvk with password password INFO [FullyValidatingClient] 25 Feb 2005 14:07:48.735 : Connecting to server localhost INFO [FullyValidatingClient] 25 Feb 2005 14:07:49.846 : Switching to FTPS (explicit mode) ERROR [FullyValidatingClient] 25 Feb 2005 14:07:49.906 : Caught exception Org.Mentalis.Security.Ssl.Shared.SslException The certificate could not be verified: NoCNMatch : The certificate could not be verified: NoCNMatch at e.a(b2 A_0) at s.c() at EnterpriseDT.Net.Ftp.Pro.ProFTPClient.Auth(SecurityMechanism securityMechanism, Boolean secureDataChannels) at EnterpriseDT.Net.Ftp.Pro.ProFTPClient.Auth(SecurityMechanism securityMechanism) at FullyValidatingClient.Main(String[] args)
then the name on the server's certificate does not match the actual server's host-name. In production environments this is a potentially serious issue (see Host-name Checking section below), but for the purposes of running this example, it is safe to disable host-name checking by running the example again with the hostname-checking command-line argument set to off.
Host-name checking is a simple check that is performed when a secure connection is being established. It involves comparing the following two items:
If they match then one can be confident that the server to which the client is connected is in fact the server to which the certificate was issued. If they do not match, then there's a possibility that the certificate has been stolen and that the server, to which the client is connected, is attempting to "impersonate" the actual server to which the client is actually connected. This is a form of "man-in-the-middle" attack, which gives the attacker complete control over the data being sent and received.
Unfortunately, the most widely compatible version of the X.509 certificate standard does not specify exactly how a host-name should be defined within a server certificate. The convention is that the Common Name (CN) field of the certificate should be used, and, while this is followed by the majority of Certificate Authorities (CAs), it is not universal.
If it is possible to configure the FTPS server's certificate then the Common Name (CN) field of the certificate must be the same as the host-name of the machine on which the FTPS server is running. If that server is an edtFTPD server then please refer to the following section for instructions on how to generate a suitable certificate.
Disabling host-name checking is strongly discouraged and should only be done as a last resort if the FTPS server's certificate cannot be configured so that its CN parameter contains its host-name.
For more information on keys, certificates, and Certification Authorities, please refer to the edtFTPnet/PRO Developer's Guide.
Before generating a certificate for edtFTPD, please note that the server certificate that is distributed with edtFTPD has a Common Name (CN) parameter of localhost. This means that domain-name matching will be successful if the client and server are run on the same machine and the example is run with the hostname localhost or 127.0.0.1. If this is not the case, then a new certificate will be needed.
edtFTPD uses certificates of the PEM format also employed by OpenSSL. In order to generate certificates in the PEM format, you may use the OpenSSL toolkit. Information on obtaining binary forms of OpenSSL may be found here.
Once an OpenSSL executable has been obtained, the following command will generate a suitable server key and certificate:
> openssl genrsa -out server.key.pem 2048 > openssl req -new -x509 -key server.key.pem -out server.cert.pem -days 1095
The second command will prompt the user for a series of parameters. The only one that is important from edtFTPnet/PRO's point of view is the Common Name parameter. This parameter must be the same as the host-name of the server.
Once the server.key.pem and server.cert.pem have been generated they should be placed in the [edtFTPD directory]/etc directory.
Windows does not use the PEM format. OpenSSL may be used to convert the new server certificate in PEM format to PFX format. This may then be installed as per the instructions above.
> openssl pkcs12 -export -in server.cert.pem -inkeyserver.key.pem -out certificate.pfx -name "My Certificate"