dk.skat.clients.ftps
Class FTPSClient

java.lang.Object
  extended by dk.skat.clients.ftps.FTPSClient

public class FTPSClient
extends Object

 This client implements a subset of the FTP protocol defined in the standard http://www.ietf.org/rfc/rfc959.txt.
 Please note that this standard superceeds the earlier standard http://www.ietf.org/rfc/rfc765.txt, however,
 the older version is useful for understanding the purpose and protocol for the subset of FTP commands not implemented in this version.
 Furthermore, the standard http://www.ietf.org/rfc/rfc4217.txt defines how FTP is secured with SSL.

 Dependencies needed in order for the client to run:
   - Follow the guide http://www.bouncycastle.org/specifications.html#install
   - Download and install Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 5.0

 First copy certificate file that you created before into working directory and run server with these
   parameters (notice that you have to change keyStore name and/or trustStrorePassword if you specified different options creating certificate:
   java -Djavax.net.ssl.keyStore=mySrvKeystore -Djavax.net.ssl.keyStorePassword=123456 EchoServer

 And now again copy certificate file that you created before into working directory and run client with these
   parameters (notice that you have to change keyStore name and/or trustStrorePassword if you specified different options creating certificate:
   java -Djavax.net.ssl.trustStore=mySrvKeystore -Djavax.net.ssl.trustStorePassword=123456 EchoClient

 If you want SSL debug information just add these parameters when running server and/or client:
   java -Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol -Djavax.net.debug=ssl

 This client can connect to a FTPS server in explicit mode using two-way SSL connection
 and x509 OCES certificates. Both the client and server certificates are
 validated.

 When the connection is etablished a user determined number of files can be
 ftp'ed from the client to the server by using the standard ftp protocol,
 specified in http://www.ietf.org/rfc/rfc959.txt. This is accomplished by providing
 the FTP commands in a txt file which is passed to this program.

 Supported FTP commands:
   - USER : Username
   - PASS : Password
   - QUIT : current file transfers are allowed to complete.
   - LIST : Directory listing
   - STOR : Store a file on the server
   - RETR : Retrieve a file from the server
   - PASV : tells the Server-DTP to pick and listen on a data port which is different from the default. The Server responds with the host address and port that the server is listening on.
   - TYPE : Representation Type followed by A for ASCII, E for EBCDIC, I for Image etc. NB. E not implemented
   - DELE : Delete followed by the filename
   - RMD  : Remove Directory
   - MKD  : Make Directory
   - PWD  : Print Working Directory
   - HELP : gets the server to send helpful information regarding its parameters before file transfer perhaps
   - NOOP : No Operation results in an OK from the server
   - CWD  : Change Working Directory
   - CDUP : Change to Parent Directory
   - NLST : Name List
   - SITE : Site Parameters
   - SYST : System parameters e.g. Operating System.
   - APPE : Append
   - ALLO : Allocate, used by some servers to allocate enough space on the disk before transfer
   - ABOR : Abort

 Not tested due to connectivity restrictions on the server-side or due to unimplemented features:
   - PORT : changes from the default User data port number e.g. PORT 161,220,94,1,15,34 where 161.220.94.1 is the IP address of the host and the new data port is 1534.
   - REIN : Reinitialise flushes all account information just leaving the control connection and allowing current file transfers to complete. The user will need to use the USER command next
   - STAT : File statistics
   - RNFR : Rename From
   - RNTO : Rename To
   - ACCT : User Account

 Not supported FTP commands:
   - STOU : Store Unique i.e. as a unique file name in that directory
   - SMNT : Structure Mount i.e. mount a different directory without logging out
   - REST : Restart plus the marker used to indicate the position from which restart should take place.
   - STRU : File Structure followed by F for File (default), R for Record and P for Page.
   - MODE : Transfer Mode followed by S for Stream, B for Block and C for Compressed.

 Note that this program is supposed to be used with SKAT system modernisation
 some values are fixed, if and only if the solution requires a specific mode.
    - AUTH TLS is fixed, since we are running explicit SSL mode
    - PORT & PASV are fixed according to the ports utilized by Steria firewall

 Versioning 29 September 2009:
    - 1.1 Reusing sockets, hence if possible same ports are used during a FTP session
    - 1.1 Performance updates reading and writing to sockets with buffers
    - 1.1 Implemented SITE, SYST, APPE, ALLO, ABOR, RNFR, RNTO, ACCT, REIN, NLST
 

Version:
1.1
Author:
Rene Hjortskov Nielsen, SKAT

Field Summary
protected  boolean activeTransfer
          Default active transfers are used, since PASV must be called separately anyway
protected  String certPass
          Client certificate password
protected  String clientEndpoint
          Host DNS or IP address of FTPSClient
protected  Socket con
          Initial control connection without SSL protection
protected  int controlPort
          Default control for client is above 1024 and default for server is 990
protected  SSLSocket ctlcon
          Secure SSL control connection
protected  SSLSocket datacon
          Data connection
protected  int dataPort
          Default data for client is 990 and default for server is 989
protected  int dataPortServer
          Default data for client is 990 and default for server is 989
protected  Reader datareader
          Data connection reader
protected  ServerSocket dataServer
          Data connection used for default and active mode
protected  PrintWriter datawriter
          Data connection Writer
protected  Thread listenerThread
          Thread for listening for incoming data connections, used with PORT command
protected  InetAddress localDataAddress
          Reusing local address
protected  InetSocketAddress localSocketDataAddress
          Reusing local socket address
protected  int majorVersion
          Major version
protected  int minorVersion
          Minor version
protected  String mode
          Default mode is STREAM, BLOCK and COMPRESSED are not supported
protected  TrustManager[] myTrustCerts
          Implements TrustManager
protected  KeyManager[] myX509Certs
          Implements KeyManager
protected  Reader reader
          Control connection reader
protected  InetAddress remoteDataAddress
          Reusing remote address
protected  InetSocketAddress remoteSocketDataAddress
          Reusing remote socket address
protected  SSLContext sc
          SSLContext used for configuring SSL Socket
protected  String scriptFile
          The Scriptfile to read ftp commands from
protected  String serverDataEndpoint
          Host DNS or IP address of FTPSServer data connection
protected  String serverEndpoint
          Host DNS or IP address of FTPSServer control connection
protected  String structure
          Default mode is FILE, RECORD and PAGE are not supported
protected  String trustPass
          Client certificate password for truststore
protected  String type
          Default type is ASCII or TYPE A.
protected  PrintWriter writer
          Control connection Writer
 
Constructor Summary
FTPSClient(String clientEndpoint, String serverEndpoint, String certPass, String trustPass, int port, String script)
          Constructor used for getting an instance of the FTPS client.
 
Method Summary
protected  String cmdAppe(String cmd, Reader reader, PrintWriter writer)
          APPEND file in PASV mode
protected  void cmdAuth(Reader reader, PrintWriter writer)
          SSL type is forced to be TLS
protected  void cmdHelp(String str, Reader reader, PrintWriter writer)
          HELP
protected  String cmdList(Reader reader, PrintWriter writer)
          LIST
protected  String cmdNlst(Reader reader, PrintWriter writer)
          NAMED LIST
protected  int cmdPasv(Reader reader, PrintWriter writer)
          In Passive Mode FTP: The User opens two random port connections (>1024), x for the Control connection and x+1 for the data connection.
protected  void cmdPort(Reader reader, PrintWriter writer, String host, int p1, int p2)
          In Active Mode FTP: The User-PI initiates the control connection from a random port n>1024 to the Server-PI on port 21.
protected  String cmdRetr(String cmd, Reader reader, PrintWriter writer)
          RETR file in PASV mode
protected  String cmdStor(String cmd, Reader reader, PrintWriter writer)
          STOR file in PASV mode
protected  void cmdTLSNego(Reader reader, PrintWriter writer)
          Negociation of security
 void connect()
           This method is invoked when a FTPS connection should be established.
protected  void destroyDataClient()
          If the structure is file structure, the EOF is indicated by the sending Host closing the data connection and all bytes are data bytes.
protected  String ftpCmd(String cmd)
          Simple FTP commands
 void init()
          Reset everything excpt control connection.
protected  void initDataClient()
          Sets up a remote connected data client
protected  void initDataListener()
          Sets up a data connection listener thread
static void main(String[] argv)
          FTPSClient main Demonstrates how to use the FTPSClient API
 void parseCmd(String cmd)
          Parsing scripted ftp commands
protected  void parseDataCmd(Reader reader, PrintWriter writer)
          Not implemented, since the FTPS server did not allow PORT to be used!
 void parseScript()
          Parsing script with commands
protected  void parseSynonymCmd(String cmd)
          Parsing synonym ftp commands
protected  String read(Reader reader)
          Reads ascii from input
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

majorVersion

protected final int majorVersion
Major version

See Also:
Constant Field Values

minorVersion

protected final int minorVersion
Minor version

See Also:
Constant Field Values

myX509Certs

protected KeyManager[] myX509Certs
Implements KeyManager


myTrustCerts

protected TrustManager[] myTrustCerts
Implements TrustManager


serverEndpoint

protected String serverEndpoint
Host DNS or IP address of FTPSServer control connection


serverDataEndpoint

protected String serverDataEndpoint
Host DNS or IP address of FTPSServer data connection


clientEndpoint

protected String clientEndpoint
Host DNS or IP address of FTPSClient


certPass

protected String certPass
Client certificate password


trustPass

protected String trustPass
Client certificate password for truststore


controlPort

protected int controlPort
Default control for client is above 1024 and default for server is 990


dataPort

protected int dataPort
Default data for client is 990 and default for server is 989


dataPortServer

protected int dataPortServer
Default data for client is 990 and default for server is 989


con

protected Socket con
Initial control connection without SSL protection


ctlcon

protected SSLSocket ctlcon
Secure SSL control connection


dataServer

protected ServerSocket dataServer
Data connection used for default and active mode


datacon

protected SSLSocket datacon
Data connection


localDataAddress

protected InetAddress localDataAddress
Reusing local address


remoteDataAddress

protected InetAddress remoteDataAddress
Reusing remote address


localSocketDataAddress

protected InetSocketAddress localSocketDataAddress
Reusing local socket address


remoteSocketDataAddress

protected InetSocketAddress remoteSocketDataAddress
Reusing remote socket address


reader

protected Reader reader
Control connection reader


datareader

protected Reader datareader
Data connection reader


writer

protected PrintWriter writer
Control connection Writer


datawriter

protected PrintWriter datawriter
Data connection Writer


listenerThread

protected Thread listenerThread
Thread for listening for incoming data connections, used with PORT command


sc

protected SSLContext sc
SSLContext used for configuring SSL Socket


scriptFile

protected String scriptFile
The Scriptfile to read ftp commands from


type

protected String type
Default type is ASCII or TYPE A. Binary, TYPE I, is supported, EBCDIC, TYPE E, is not, use binary


mode

protected String mode
Default mode is STREAM, BLOCK and COMPRESSED are not supported


structure

protected String structure
Default mode is FILE, RECORD and PAGE are not supported


activeTransfer

protected boolean activeTransfer
Default active transfers are used, since PASV must be called separately anyway

Constructor Detail

FTPSClient

public FTPSClient(String clientEndpoint,
                  String serverEndpoint,
                  String certPass,
                  String trustPass,
                  int port,
                  String script)
Constructor used for getting an instance of the FTPS client. Note the EndOfLine is always \r\n as specied in the standard. This is set by the constructor.

Parameters:
clientEndpoint - IP, DNS address of the client
serverEndpoint - IP, DNS address of the server
certPass - Password for the client certificate and client certificate keystore
trustPass - Password for the truststore certificates
port - Server port for initial FTP Control Connection negociation
script - path to file containing the FTP commands to execute when running this client
Method Detail

init

public void init()
Reset everything excpt control connection. Next command is USER


connect

public void connect()
             throws Exception
 This method is invoked when a FTPS connection should be established.

 Note that this version assumes explicit SSL, which means that the FTP
 commands "AUTH TLS", "PBSZ 0", "PROT P" are executed when calling the
 connect() method.

 Other System.properties that NEEDS to be set:
   - javax.net.ssl.trustStore path to trust jks keystore
   - javax.net.ssl.keyStore path to client  pkcs12 certificate

 After successful connect it is required to send "USER anonymous" and  "PASS email@address",
 which can be anything, but be nice, use your email as identification.

 For test purposes it is possible to set the System.property test=true,
 which will apply a dummy trust manager ignoring all issues related to
 the server test certificate, e.g. expired timestamps.

Throws:
Exception - In case of any errors

initDataListener

protected void initDataListener()
                         throws Exception
Sets up a data connection listener thread

Throws:
Exception

destroyDataClient

protected void destroyDataClient()
                          throws Exception
If the structure is file structure, the EOF is indicated by the sending Host closing the data connection and all bytes are data bytes.

Throws:
Exception

initDataClient

protected void initDataClient()
                       throws Exception
Sets up a remote connected data client

Throws:
Exception

read

protected String read(Reader reader)
               throws Exception
Reads ascii from input

Parameters:
reader - Input
Returns:
String read data
Throws:
Exception

cmdPort

protected void cmdPort(Reader reader,
                       PrintWriter writer,
                       String host,
                       int p1,
                       int p2)
                throws Exception
In Active Mode FTP: The User-PI initiates the control connection from a random port n>1024 to the Server-PI on port 21. The User-PI issues a PORT command which tells the Server to connect back to the User on the specified User data port n+1. The User then listens on port n+1 which has become the User data port. The Server then sends data from its own data port 20 to the User data port n+1. Note this has NOT been tested since the server only supported PASV mode Port is calculated by p1 and p2 like this: port = p1 * 256 + p2

Parameters:
reader - Input
writer - Output
host - Host IP address
p1 - Host port p1
p2 - Host port p2
Throws:
Exception
To do:
Not implemented fully, since the FTPS server uses passive mode only!

cmdAuth

protected void cmdAuth(Reader reader,
                       PrintWriter writer)
                throws Exception
SSL type is forced to be TLS

Parameters:
reader - Input
writer - Output
Throws:
Exception

cmdTLSNego

protected void cmdTLSNego(Reader reader,
                          PrintWriter writer)
                   throws Exception
Negociation of security

Parameters:
reader - Input
writer - Output
Throws:
Exception

cmdList

protected String cmdList(Reader reader,
                         PrintWriter writer)
                  throws Exception
LIST

Parameters:
reader - Input
writer - Output
Returns:
String The server response
Throws:
Exception

cmdNlst

protected String cmdNlst(Reader reader,
                         PrintWriter writer)
                  throws Exception
NAMED LIST

Parameters:
reader - Input
writer - Output
Returns:
String The server response
Throws:
Exception

cmdHelp

protected void cmdHelp(String str,
                       Reader reader,
                       PrintWriter writer)
                throws Exception
HELP

Throws:
Exception

cmdPasv

protected int cmdPasv(Reader reader,
                      PrintWriter writer)
               throws Exception
In Passive Mode FTP: The User opens two random port connections (>1024), x for the Control connection and x+1 for the data connection. The User-PI issues a PASV command which tells the Server to open its own random data port y. The Server-PI then sends a PORT command back to the User informing the User of the Server's data port y. The User initiates a Data connection from its own data port x+1 to the Server's data port y.

Parameters:
reader - Input
writer - Output
Returns:
int Server port y
Throws:
Exception

cmdStor

protected String cmdStor(String cmd,
                         Reader reader,
                         PrintWriter writer)
                  throws Exception
STOR file in PASV mode

Parameters:
reader - Input
writer - Output
Returns:
String The server response
Throws:
Exception

cmdAppe

protected String cmdAppe(String cmd,
                         Reader reader,
                         PrintWriter writer)
                  throws Exception
APPEND file in PASV mode

Parameters:
reader - Input
writer - Output
Returns:
String The server response
Throws:
Exception

cmdRetr

protected String cmdRetr(String cmd,
                         Reader reader,
                         PrintWriter writer)
                  throws Exception
RETR file in PASV mode

Parameters:
reader - Input
writer - Output
Returns:
String The server response
Throws:
Exception

ftpCmd

protected String ftpCmd(String cmd)
                 throws Exception
Simple FTP commands

Parameters:
cmd - Command
Returns:
String The server response
Throws:
Exception

parseScript

public void parseScript()
                 throws Exception
Parsing script with commands

Throws:
Exception

parseCmd

public void parseCmd(String cmd)
              throws Exception
Parsing scripted ftp commands

Parameters:
cmd - The FTP command as specified in the standard
Throws:
Exception

parseSynonymCmd

protected void parseSynonymCmd(String cmd)
                        throws Exception
Parsing synonym ftp commands

Parameters:
cmd - The FTP command as known is various DOS versions implementing FTP
Throws:
Exception

parseDataCmd

protected void parseDataCmd(Reader reader,
                            PrintWriter writer)
                     throws Exception
Not implemented, since the FTPS server did not allow PORT to be used!

Parameters:
reader - Input
writer - Output
Throws:
Exception

main

public static void main(String[] argv)
                 throws Exception
FTPSClient main Demonstrates how to use the FTPSClient API

Throws:
Exception


Copyright © 2009 SKAT. All Rights Reserved.