Author: rwinston
Date: Sat Aug 26 05:09:50 2006
New Revision: 437151

URL: http://svn.apache.org/viewvc?rev=437151&view=rev
Log:
Added FTPS impl based on submission inb 
https://issues.apache.org/jira/browse/NET-28

Added:
    
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java
    
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSReply.java
Modified:
    
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
    
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java

Modified: 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSClient.java?rev=437151&r1=437150&r2=437151&view=diff
==============================================================================
--- 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
 (original)
+++ 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSClient.java
 Sat Aug 26 05:09:50 2006
@@ -1,12 +1,11 @@
-/*
- * Copyright 2001-2006 The Apache Software Foundation
- *
+/**
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -23,160 +22,629 @@
 import java.net.InetAddress;
 import java.net.Socket;
 import java.net.SocketException;
+import java.security.KeyManagementException;
 import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.NoSuchProviderException;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.Enumeration;
+import java.util.Vector;
 
+import javax.net.ssl.KeyManager;
 import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManager;
-
+import javax.net.ssl.TrustManagerFactory;
 
 /**
- * 
- * This class extends [EMAIL PROTECTED] org.apache.commons.net.ftp.FTPClient} 
to add
- * the necessary methods that implement SSL/TLS-FTPS.
- *
+ * FTP over SSL processing.
  */
 public class FTPSClient extends FTPClient {
 
-       // Represent the method to the FTP command AUTH...
-       private String sslContext;
-       
-       // Secure context (can be "TLS" or "SSL")
-       private SSLContext context;
-       
-       private String pbsz;
-       private String prot;
-
-       /**
-        * Default constructor that selects some default options (TLS 
encryption)
-        *
-        */
-       public FTPSClient() {
-               this("JCEKS", "TLS", "password", "0", "P");
-       }
-       
-       
-       /**
-        * 
-        * Constructor that initializes the secure connection. 
-        * 
-        * @param keyStoreName Type of instance KeyStore, JKS for Java 1.3 y 
JCEKS for Java 1.4 
-        * @param sslContext Type of the instance SSLContext, can be SSL or TLS.
-        * @param password The password to access the KeyStore.
-        * @param pbsz Protection buffer size (Use 0 to indicate streaming) 
-        * @param prot The protection level for the data channel
-        */
-       public FTPSClient(String keyStoreName, String sslContext, String 
password, String pbsz, String prot) {
-               this.sslContext = sslContext;
-               this.pbsz = pbsz;
-               this.prot = prot;
-               
-               try {
-                       KeyStore keyStore = KeyStore.getInstance(keyStoreName);
-                       
-                       keyStore.load(null, password.toCharArray());
-
-                       KeyManagerFactory keyManagerFactory = 
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
-                       
-                       keyManagerFactory.init(keyStore, 
password.toCharArray());
-
-                       this.context = SSLContext.getInstance(sslContext);
-
-                       this.context.init(
-                               keyManagerFactory.getKeyManagers(), 
-                               new TrustManager[] { (TrustManager) new 
FTPSTrustManager() }, null
-                       );
-               } catch (Exception e) {
-                       e.printStackTrace();
-               }
-       }
-       
-       /**
-        * @see 
org.apache.commons.net.SocketClient#connect(java.net.InetAddress, int, 
java.net.InetAddress, int)
-        */
-       public void connect(InetAddress address, int port, InetAddress 
localAddress, int localPort) throws SocketException, IOException
-       {
-               super.connect(address, port, localAddress, localPort);
-               
-               this.secure(this.pbsz,this.prot);
-       }
-
-       /**
-        * @see 
org.apache.commons.net.SocketClient#connect(java.net.InetAddress, int)
-        */
-       public void connect(InetAddress address, int port) throws 
SocketException, IOException
-       {
-               super.connect(address, port);
-               
-               this.secure(this.pbsz,this.prot);
-       }
-
-       /**
-        * @see org.apache.commons.net.SocketClient#connect(java.lang.String, 
int, java.net.InetAddress, int)
-        */
-       public void connect(String address, int port, InetAddress localAddress, 
int localPort) throws SocketException, IOException
-       {
-               super.connect(address, port, localAddress, localPort);
-               
-               this.secure(this.pbsz,this.prot);
-       }
-
-       /**
-        * @see org.apache.commons.net.SocketClient#connect(java.lang.String, 
int)
-        */
-       public void connect(String address, int port) throws SocketException, 
IOException
-       {
-               super.connect(address, port);
-               
-               this.secure(this.pbsz,this.prot);
-       }
-       
-       /**
-        *
-        * Initialize the secure connection with the FTP server, throw the AUTH 
SSL o TLS command.
-        * Get the socket with the server, starting the "handshake" making the 
socket, with a layer of securety,
-        * and initializing the stream of connection.
-        * 
-        * 
-        * @param pbsz Protection Buffer Size: "0" is a good value
-        * @param prot Data Channel Protection Level:
-        * Posible values:
-        * C - Clear
-        * S - Safe
-        * E - Confidential 
-        * P - PrivateType of secure connection
-        *  
-        * @throws IOException If there is any problem with the connection.
-        */
-       protected void secure(String pbsz, String prot) throws IOException {
-               this.sendCommand("AUTH", sslContext);
-               
-               SSLSocket socket = 
(SSLSocket)this.context.getSocketFactory().createSocket(this._socket_, 
this.getRemoteAddress().getHostAddress(), this.getRemotePort(), true);
-               
-               socket.startHandshake();
-
-               this._socket_ = socket;
-               
-               this._controlInput_ = new BufferedReader(new 
InputStreamReader(socket.getInputStream(), getControlEncoding()));
-               this._controlOutput_ = new BufferedWriter(new 
OutputStreamWriter(socket.getOutputStream(), getControlEncoding()));
-
-               this.setSocketFactory(new FTPSSocketFactory(this.context));
-
-               this.sendCommand("PBSZ", pbsz);
-               this.sendCommand("PROT", prot);
-       }
-
-       /**
-        * @see 
org.apache.commons.net.ftp.FTPCliente#_openDataConnection_(java.lang.String, 
int)
-        */     
-       protected Socket _openDataConnection_(int command, String arg) throws 
IOException {
-               Socket socket = super._openDataConnection_(command, arg);
-               if (socket != null) {
-                       ((SSLSocket)socket).startHandshake();
-               }
-               return socket;
-       }       
-
+    /** keystore algorithm name. */
+    public static String KEYSTORE_ALGORITHM;
+    /** truststore algorithm name. */
+    public static String TRUSTSTORE_ALGORITHM;
+    /** provider name. */
+    public static String PROVIDER;
+    /** truststore type. */
+    public static String STORE_TYPE;
+
+    /** The value that I can set in PROT command */
+    private static final String[] PROT_COMMAND_VALUE = {"C","E","S","P"}; 
+    /** Default PROT Command */
+    private static final String DEFAULT_PROT = "C";
+    /** Default protocol name */
+    private static final String DEFAULT_PROTOCOL = "TLS";
+
+    /** The security mode. (True - Implicit Mode / False - Explicit Mode) */
+    private boolean isImplicit;
+    /** The use SSL/TLS protocol. */
+    private String protocol = DEFAULT_PROTOCOL;
+    /** The AUTH Command value */
+    private String auth = DEFAULT_PROTOCOL;
+    /** The KeyManager object. */
+    private KeyManager[] keyManager = null;
+    /** The TrustManager object */
+    private TrustManager[] trustManager = null;
+    /** The context object. */
+    private SSLContext context;
+    /** The socket object. */
+    private Socket planeSocket;
+    /** The established socket flag. */
+    private boolean isCreation = true;
+    /** The use client mode flag. */
+    private boolean isClientMode = true;
+    /** The need client auth flag. */
+    private boolean isNeedClientAuth = false;
+    /** The want client auth flag. */
+    private boolean isWantClientAuth = false;
+    /** The cipher suites */
+    private String[] suites = null;
+    /** The protocol versions */
+    private String[] protocols = null;
+
+    /**
+     * Constructor for FTPSClient.
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     */
+    public FTPSClient() throws NoSuchAlgorithmException {
+        this.protocol = DEFAULT_PROTOCOL;
+        this.isImplicit = false;
+        context = SSLContext.getInstance(protocol);
+    }
+
+    /**
+     * Constructor for FTPSClient.
+     * @param isImplicit The secutiry mode(Implicit/Explicit).
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     */
+    public FTPSClient(boolean isImplicit) throws NoSuchAlgorithmException {
+        this.protocol = DEFAULT_PROTOCOL;
+        this.isImplicit = isImplicit;
+        context = SSLContext.getInstance(protocol);
+    }
+
+    /**
+     * Constructor for FTPSClient.
+     * @param conType The context type
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     */
+    public FTPSClient(String protocol) throws NoSuchAlgorithmException {
+        this.protocol = protocol;
+        this.isImplicit = false;
+        context = SSLContext.getInstance(protocol);
+    }
+
+    /**
+     * Constructor for FTPSClient.
+     * @param conType The context type
+     * @param isImplicit The secutiry mode(Implicit/Explicit).
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     */
+    public FTPSClient(String protocol, boolean isImplicit) 
+            throws NoSuchAlgorithmException {
+        this.protocol = protocol;
+        this.isImplicit = isImplicit;
+        context = SSLContext.getInstance(protocol);
+    }
+
+    /**
+     * Create KeyManager[] object.
+     * @param ks The KeyStore objects.
+     * @param storePass The Store password.
+     * @throws NoSuchAlgorithmException A requested cryptographic 
+     * algorithm is not available in the environment.
+     * @throws NoSuchProviderException A requested cryptographic provider 
+     * is not available in the environment.
+     * @throws UnrecoverableKeyException This exception is thrown 
+     * if a key in the keystore cannot be recovered.
+     * @throws KeyStoreException This is the generic KeyStore exception.
+     * @throws KeyManagementException It is the generic KeyManager exception.
+     */
+    public void createKeyManager(KeyStore ks, String storePass)
+            throws NoSuchAlgorithmException, NoSuchProviderException,
+            KeyStoreException,UnrecoverableKeyException,KeyManagementException{
+        if (ks == null) {
+            keyManager = null;
+            return;
+        }
+        if (KEYSTORE_ALGORITHM == null)
+            KEYSTORE_ALGORITHM = KeyManagerFactory.getDefaultAlgorithm();
+        KeyManagerFactory kmf;
+        if (PROVIDER == null) {
+            kmf = KeyManagerFactory.getInstance(KEYSTORE_ALGORITHM);
+        } else {
+            kmf = KeyManagerFactory.getInstance(KEYSTORE_ALGORITHM, PROVIDER);
+        }
+        if (kmf == null) {
+            keyManager = null;
+            return;
+        }
+        kmf.init(ks, storePass.toCharArray());
+        keyManager = kmf.getKeyManagers();
+        context.init(keyManager, trustManager, null);
+    }
+
+    /**
+     * Create TrustManager[] object.
+     * @param ks The KeyStore object.
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     * @throws NoSuchProviderException A requested cryptographic provider 
+     * is not available in the environment.
+     * @throws KeyStoreException This is the generic KeyStore exception.
+     * @throws KeyManagementException It is the generic KeyManager exception.
+     */
+    public void createTrustManager(KeyStore ks) 
+            throws NoSuchAlgorithmException, NoSuchProviderException, 
+            KeyStoreException, KeyManagementException {
+        if (ks == null) trustManager = null;
+        if (TRUSTSTORE_ALGORITHM == null)
+            TRUSTSTORE_ALGORITHM = TrustManagerFactory.getDefaultAlgorithm();
+        TrustManagerFactory tmf;
+        if (PROVIDER == null) {
+            tmf = TrustManagerFactory.getInstance(TRUSTSTORE_ALGORITHM);
+        } else {
+            tmf = TrustManagerFactory.getInstance(
+                    TRUSTSTORE_ALGORITHM, PROVIDER);
+        }
+        if (tmf == null) {
+            trustManager = null;
+            return;
+        }
+        tmf.init(ks);
+        trustManager = tmf.getTrustManagers();
+        context.init(keyManager, trustManager, null);
+    }
+
+    /**
+     * Create TrustManager[] object.
+     * @param _ks The KeyStore objects.
+     * @throws KeyStoreException This is the generic KeyStore exception.
+     * @throws CertificateException This exception indicates one of 
+     * a variety of certificate problems.
+     * @throws NoSuchAlgorithmException A requested cryptographic algorithm 
+     * is not available in the environment.
+     * @throws NoSuchProviderException A requested cryptographic provider 
+     * is not available in the environment.
+     * @throws KeyManagementException It is the generic KeyManager exception.
+     * @throws IOException
+     */
+    public void createTrustManager(Vector ks) throws KeyStoreException, 
+            NoSuchAlgorithmException, CertificateException, 
+            IOException, NoSuchProviderException, KeyManagementException {
+        if (ks == null) {
+            trustManager = null;
+            return;
+        }
+        KeyStore _ks;
+        if (STORE_TYPE == null) {
+            _ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        } else {
+            _ks = KeyStore.getInstance(STORE_TYPE);
+        }
+        _ks.load(null, null);
+        int n = 0;
+        // as for every keystore
+        for (int i = 0; i < ks.size(); i++) {
+            // as for every alias
+            KeyStore wks = ((KeyStore) ks.get(i));
+            for (Enumeration e = wks.aliases(); e.hasMoreElements();) {
+                String alias = (String) e.nextElement();
+                _ks.setCertificateEntry(String.valueOf(n), 
+                        wks.getCertificate(alias));
+                n++;
+            }
+        }
+        createTrustManager(_ks);
+    }
+
+    /**
+     * Set AUTH command use value.
+     * This processing is done before connected processing.
+     * @param auth AUTH command use value.
+     */
+    public void setAuthValue(String auth) {
+        this.auth = auth;
+    }
+
+    /**
+     * Return AUTH command use value.
+     * @return AUTH command use value.
+     */
+    public String getAuthValue() {
+        return this.auth;
+    }
+
+    /**
+     * I work to be connected. Opens a Socket connected to a remote host 
+     * at the specified port and originating from the current host at 
+     * a system assigned port.
+     * @param address The name of the remote host.
+     * @param port The port to connect to on the remote host.
+     * @throws SocketException If the socket timeout could not be set.
+     * @throws IOException If the socket could not be opened.
+     * In most cases you will only want to catch IOException since 
+     * SocketException is derived from it.
+     * @see org.apache.commons.net.SocketClient#connect(java.lang.String, int)
+     */
+    public void connect(String address, int port) 
+            throws SocketException, IOException {
+        super.connect(address, port);
+    }
+
+    /**
+     * I work to be connected. Opens a Socket connected to a remote host 
+     * at the specified port and originating from the current host at 
+     * a system assigned port.
+     * @param address The name of the remote host.
+     * @param port The port to connect to on the remote host.
+     * @throws SocketException If the socket timeout could not be set.
+     * @throws IOException If the socket could not be opened.
+     * In most cases you will only want to catch IOException since 
+     * SocketException is derived from it.
+     * @see org.apache.commons.net.SocketClient 
+     * #connect(java.net.InetAddress, int)
+     */
+    public void connect(InetAddress address, int port) 
+            throws SocketException, IOException {
+        super.connect(address, port);
+    }
+
+    /**
+     * I work to be connected. Opens a Socket connected to a remote host 
+     * at the specified port and originating from the specified 
+     * local address and port.
+     * @param address The name of the remote host.
+     * @param port The port to connect to on the remote host.
+     * @param localAddress The local address to use.
+     * @param localPort The local port to use.
+     * @throws SocketException If the socket timeout could not be set.
+     * @throws IOException If the socket could not be opened.
+     * In most cases you will only want to catch IOException since 
+     * SocketException is derived from it.
+     * @see org.apache.commons.net.SocketClient
+     * #connect(java.net.InetAddress, int, java.net.InetAddress, int)
+     */
+    public void connect(InetAddress address, int port, 
+            InetAddress localAddress, int localPort) 
+            throws SocketException, IOException {
+        super.connect(address, port, localAddress, localPort);
+    }
+
+    /**
+     * I work to be connected. Opens a Socket connected to a remote host 
+     * at the specified port and originating from the specified 
+     * local address and port.
+     * @param address The name of the remote host.
+     * @param port The port to connect to on the remote host.
+     * @param localAddress The local address to use.
+     * @param localPort The local port to use.
+     * @throws SocketException If the socket timeout could not be set.
+     * @throws IOException If the socket could not be opened. 
+     * In most cases you will only want to catch IOException since 
+     * SocketException is derived from it.
+     * @see org.apache.commons.net.SocketClient 
+     * #connect(java.lang.String, int, java.net.InetAddress, int)
+     */
+    public void connect(String address, int port, InetAddress localAddress,
+            int localPort) throws SocketException, IOException {
+        super.connect(address, port, localAddress, localPort);
+    }
+
+    /**
+     * Because there are so many connect() methods, 
+     * the _connectAction_() method is provided as a means of performing 
+     * some action immediately after establishing a connection, 
+     * rather than reimplementing all of the connect() methods.
+     * @throws IOException If it throw by _connectAction_.
+     * @see org.apache.commons.net.SocketClient#_connectAction_()
+     */
+    protected void _connectAction_() throws IOException {
+        // Implicit mode.
+        if (isImplicit) sslNegotiation();
+        super._connectAction_();
+        // Explicit mode.
+        if (!isImplicit) {
+            execAUTH();
+            sslNegotiation();
+        }
+    }
+
+    /**
+     * I carry out an AUTH command.
+     * @throws SSLException If it server reply code not equal "234" and "334".
+     * @throws IOException If an I/O error occurs while either sending 
+     * the command.
+     */
+    private void execAUTH() throws SSLException, IOException {
+        int replyCode = sendCommand(
+                FTPSCommand._commands[FTPSCommand.AUTH], auth);
+        if (FTPSReply.SECURITY_MECHANISM_IS_OK == replyCode) {
+            // replyCode = 334
+            // I carry out an ADAT command.
+        } else if (FTPSReply.SECURITY_DATA_EXCHANGE_COMPLETE != replyCode) {
+            throw new SSLException(getReplyString());
+        }
+    }
+
+    /**
+     * SSL/TLS negotiation. I acquire an SSL socket of a control 
+     * connection and carry out handshake processing.
+     * @throws IOException A handicap breaks out by sever negotiation.
+     */
+    private void sslNegotiation() throws IOException {
+        // Evacuation not ssl socket.
+        planeSocket = _socket_;
+
+        SSLSocketFactory ssf = context.getSocketFactory();
+        String ip = _socket_.getInetAddress().getHostAddress();
+        int port = _socket_.getPort();
+        SSLSocket socket = 
+            (SSLSocket) ssf.createSocket(_socket_, ip, port, true);
+        socket.setEnableSessionCreation(isCreation);
+        socket.setUseClientMode(isClientMode);
+        // server mode
+        if (!isClientMode) {
+            socket.setNeedClientAuth(isNeedClientAuth);
+            socket.setWantClientAuth(isWantClientAuth);
+        }
+        if (protocols != null) socket.setEnabledProtocols(protocols);
+        if (suites != null) socket.setEnabledCipherSuites(suites);
+
+        socket.startHandshake();
+
+        _socket_ = socket;
+        _controlInput = new BufferedReader(new InputStreamReader(
+                socket .getInputStream(), getControlEncoding()));
+        _controlOutput = new BufferedWriter(new OutputStreamWriter(
+                socket.getOutputStream(), getControlEncoding()));
+    }
+
+    /**
+     * Controls whether new SSL session may be established by this socket.
+     * @param isCreation The established socket flag.
+     */
+    public void setEnabledSessionCreation(boolean isCreation) {
+        this.isCreation = isCreation;
+    }
+
+    /**
+     * Returns true if new SSL sessions may be established by this socket.
+     * When a socket does not have a ssl socket, This return False.
+     * @return true - Indicates that sessions may be created;
+     * this is the default. 
+     * false - indicates that an existing session must be resumed.
+     */
+    public boolean getEnableSeeionCreation() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getEnableSessionCreation();
+        return false;
+    }
+
+    /**
+     * Configures the socket to require client authentication.
+     * @param isNeedClientAuth The need client auth flag.
+     */
+    public void setNeedClientAuth(boolean isNeedClientAuth) {
+        this.isNeedClientAuth = isNeedClientAuth;
+    }
+
+    /**
+     * Returns true if the socket will require client authentication.
+     * When a socket does not have a ssl socket, This return False.
+     * @return true - If the server mode socket should request 
+     * that the client authenticate itself.
+     */
+    public boolean getNeedClientAuth() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getNeedClientAuth();
+        return false;
+    }
+
+    /**
+     * Configures the socket to request client authentication, 
+     * but only if such a request is appropriate to the cipher 
+     * suite negotiated.
+     * @param isWantClientAuth The want client auth flag.
+     */
+    public void setWantClientAuth(boolean isWantClientAuth) {
+        this.isWantClientAuth = isWantClientAuth;
+    }
+
+    /**
+     * Returns true if the socket will request client authentication.
+     * When a socket does not have a ssl socket, This return False.
+     * @return true - If the server mode socket should request 
+     * that the client authenticate itself.
+     */
+    public boolean getWantClientAuth() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getWantClientAuth();
+        return false;
+    }
+
+    /**
+     * Configures the socket to use client (or server) mode in its first 
+     * handshake.
+     * @param isClientMode The use client mode flag.
+     */
+    public void setUseClientMode(boolean isClientMode) {
+        this.isClientMode = isClientMode;
+    }
+
+    /**
+     * Returns true if the socket is set to use client mode 
+     * in its first handshake.
+     * When a socket does not have a ssl socket, This return False.
+     * @return true - If the socket should start its first handshake 
+     * in "client" mode.
+     */
+    public boolean getUseClientMode() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getUseClientMode();
+        return false;
+    }
+
+    /**
+     * Controls which particular cipher suites are enabled for use on this 
+     * connection. I perform setting before a server negotiation.
+     * @param suites The cipher suites.
+     */
+    public void setEnabledCipherSuites(String[] suites) {
+        this.suites = suites;
+    }
+
+    /**
+     * Returns the names of the cipher suites which could be enabled 
+     * for use on this connection.
+     * When a socket does not have a ssl socket, This return null.
+     * @return An array of cipher suite names.
+     */
+    public String[] getEnabledCipherSuites() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getEnabledCipherSuites();
+        return null;
+    }
+
+    /**
+     * Controls which particular protocol versions are enabled for use on this
+     * connection. I perform setting before a server negotiation.
+     * @param protocols The protocol versions.
+     */
+    public void setEnabledProtocols(String[] protocols) {
+        this.protocols = protocols;
+    }
+
+    /**
+     * Returns the names of the protocol versions which are currently 
+     * enabled for use on this connection.
+     * When a socket does not have a ssl socket, This return null.
+     * @return An array of protocols.
+     */
+    public String[] getEnabledProtocols() {
+        if (_socket_ instanceof SSLSocket) 
+            return ((SSLSocket)_socket_).getEnabledProtocols();
+        return null;
+    }
+
+    /**
+     * I carry out an PBSZ command. pbsz value: 0 to (2^32)-1 decimal integer.
+     * @param pbsz Protection Buffer Size.
+     * @throws SSLException If it server reply code not equal "200".
+     * @throws IOException If an I/O error occurs while either sending 
+     * the command.
+     */
+    public void execPBSZ(long pbsz) throws SSLException, IOException {
+        if (pbsz < 0 || 4294967295L < pbsz) 
+            throw new IllegalArgumentException();
+        if (FTPSReply.COMMAND_OK != sendCommand(
+                FTPSCommand._commands[FTPSCommand.PBSZ],String.valueOf(pbsz)))
+            throw new SSLException(getReplyString());
+    }
+
+    /**
+     * I carry out an PROT command.</br>
+     * C - Clear</br>
+     * S - Safe(SSL protocol only)</br>
+     * E - Confidential(SSL protocol only)</br>
+     * P - Private
+     * @param prot Data Channel Protection Level.
+     * @throws SSLException If it server reply code not equal "200".
+     * @throws IOException If an I/O error occurs while either sending 
+     * the command.
+     */
+    public void execPROT(String prot) throws SSLException, IOException {
+        if (prot == null) prot = DEFAULT_PROT;
+        if (!checkPROTValue(prot)) throw new IllegalArgumentException();
+        if (FTPSReply.COMMAND_OK != sendCommand(
+                FTPSCommand._commands[FTPSCommand.PROT], prot)) 
+            throw new SSLException(getReplyString());
+        if (DEFAULT_PROT.equals(prot)) {
+            setSocketFactory(null);
+        } else {
+            setSocketFactory(new FTPSSocketFactory(context));
+        }
+    }
+
+    /**
+     * I check the value that I can set in PROT Command value.
+     * @param prot Data Channel Protection Level.
+     * @return True - A set point is right / False - A set point is not right
+     */
+    private boolean checkPROTValue(String prot) {
+        for (int p = 0; p < PROT_COMMAND_VALUE.length; p++) {
+            if (PROT_COMMAND_VALUE[p].equals(prot)) return true;
+        }
+        return false;
+    }
+
+    /**
+     * I carry out an ftp command.
+     * When a CCC command was carried out, I steep socket and SocketFactory 
+     * in a state of not ssl.
+     * @parm command ftp command.
+     * @return server reply.
+     * @throws IOException If an I/O error occurs while either sending 
+     * the command.
+     * @see org.apache.commons.net.ftp.FTP#sendCommand(java.lang.String)
+     */
+    public int sendCommand(String command, String args) throws IOException {
+        int repCode = super.sendCommand(command, args);
+        if (FTPSCommand._commands[FTPSCommand.CCC].equals(command)) {
+            if (FTPSReply.COMMAND_OK == repCode) {
+                _socket_ = planeSocket;
+                setSocketFactory(null);
+            } else {
+                throw new SSLException(getReplyString());
+            }
+        }
+        return repCode;
+    }
+
+    /**
+     * I return a socket of the data connection that I acquired. 
+     * When I ssl it and communicate, I return the SSL socket which 
+     * carried out handshake processing.
+     * @pram command The text representation of the FTP command to send.
+     * @param arg The arguments to the FTP command. 
+     * If this parameter is set to null, then the command is sent with 
+     * no argument.
+     * @return A Socket corresponding to the established data connection. 
+     * Null is returned if an FTP protocol error is reported at any point 
+     * during the establishment and initialization of the connection.
+     * @throws IOException If there is any problem with the connection.
+     * @see org.apache.commons.net.ftp.FTPCliente
+     * #_openDataConnection_(java.lang.String, int)
+     */
+    protected Socket _openDataConnection_(int command, String arg)
+            throws IOException {
+        Socket socket = super._openDataConnection_(command, arg);
+        if (socket != null && socket instanceof SSLSocket) {
+            SSLSocket sslSocket = (SSLSocket)socket;
+            sslSocket.setUseClientMode(isClientMode);
+            sslSocket.setEnableSessionCreation(isCreation);
+            // server mode
+            if (!isClientMode) {
+                sslSocket.setNeedClientAuth(isNeedClientAuth);
+                sslSocket.setWantClientAuth(isWantClientAuth);
+            }
+            if (suites != null)
+                sslSocket.setEnabledCipherSuites(suites);
+            if (protocols != null)
+                sslSocket.setEnabledProtocols(protocols);
+            sslSocket.startHandshake();
+        }
+        return socket;
+    }
 }
-

Added: 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java?rev=437151&view=auto
==============================================================================
--- 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java
 (added)
+++ 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSCommand.java
 Sat Aug 26 05:09:50 2006
@@ -0,0 +1,46 @@
+/**
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.net.ftp;
+
+/**
+ * I acquire a command added in FTPS.
+ */
+public final class FTPSCommand {
+    public static final int AUTH = 0;
+    public static final int ADAT = 1;
+    public static final int PBSZ = 2;
+    public static final int PROT = 3;
+    public static final int CCC = 4;
+
+    public static final int AUTHENTICATION_SECURITY_MECHANISM = AUTH;
+    public static final int AUTHENTICATION_SECURITY_DATA = ADAT;
+    public static final int PROTECTION_BUFFER_SIZE = PBSZ;
+    public static final int DATA_CHANNEL_PROTECTION_LEVEL = PROT;
+    public static final int CLEAR_COMMAND_CHANNEL = CCC;
+
+    static final String[] _commands = {"AUTH","ADAT","PBSZ","PROT","CCC"};
+
+    /**
+     * Retrieve the FTPS command string corresponding to a specified
+     * command code.
+     * <p>
+     * @param command The command code.
+     * @return The FTPS command string corresponding to a specified 
+     *  command code.
+     */
+    public static final String getCommand(int command) {
+        return _commands[command];
+    }
+}

Added: 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSReply.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSReply.java?rev=437151&view=auto
==============================================================================
--- 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSReply.java
 (added)
+++ 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSReply.java
 Sat Aug 26 05:09:50 2006
@@ -0,0 +1,131 @@
+/**
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.net.ftp;
+
+/**
+ * I confirm a response cord of a command added in FTPS.
+ */
+public final class FTPSReply {
+    public static final int CODE_200 = 200;
+    public static final int CODE_234 = 234;
+    public static final int CODE_235 = 235;
+    public static final int CODE_334 = 334;
+    public static final int CODE_335 = 335;
+    public static final int CODE_421 = 421;
+    public static final int CODE_431 = 431;
+    public static final int CODE_500 = 500;
+    public static final int CODE_501 = 501;
+    public static final int CODE_502 = 502;
+    public static final int CODE_503 = 503;
+    public static final int CODE_504 = 504;
+    public static final int CODE_530 = 530;
+    public static final int CODE_533 = 533;
+    public static final int CODE_534 = 534;
+    public static final int CODE_535 = 535;
+    public static final int CODE_536 = 536;
+    
+    public static final int COMMAND_OK = CODE_200;
+    public static final int SECURITY_DATA_EXCHANGE_COMPLETE = CODE_234;
+    public static final int SECURITY_DATA_EXCHANGE_SUCCESSFULLY = CODE_235;
+    public static final int SECURITY_MECHANISM_IS_OK = CODE_334;
+    public static final int SECURITY_DATA_IS_ACCEPTABLE = CODE_335;
+    public static final int SERVICE_NOT_AVAILABLE = CODE_421;
+    public static final int UNAVAILABLE_RESOURCE = CODE_431;
+    public static final int UNRECOGNIZED_COMMAND = CODE_500;
+    public static final int SYNTAX_ERROR_IN_ARGUMENTS = CODE_501;
+    public static final int COMMAND_NOT_IMPLEMENTED = CODE_502;
+    public static final int BAD_COMMAND_SEQUENCE = CODE_503;
+    public static final int COMMAND_NOT_IMPLEMENTED_FOR_PARAMETER=CODE_504;
+    public static final int NOT_LOGGED_IN = CODE_530;
+    public static final int DENIED_FOR_POLICY_REASONS = CODE_533;
+    public static final int REQUEST_DENIED = CODE_534;
+    public static final int FAILED_SECURITY_CHECK = CODE_535;
+    public static final int REQUESTED_PROT_LEVEL_NOT_SUPPORTED = CODE_536;
+
+    /**
+     * Determine if a reply code is a positive preliminary response.  All
+     * codes beginning with a 1 are positive preliminary responses.
+     * Postitive preliminary responses are used to indicate tentative success.
+     * No further commands can be issued to the FTP server after a positive
+     * preliminary response until a follow up response is received from the
+     * server.
+     * <p>
+     * @param reply The reply code.
+     * @return True if a reply code is a postive preliminary pesponse, 
+     *  false if not.
+     */
+    public static boolean isPositivePreliminary(int reply) {
+        return (reply >= 100 && reply < 200);
+    }
+
+    /**
+     * Determine if a reply code is a positive completion response.  All
+     * codes beginning with a 2 are positive completion responses.
+     * The FTP server will send a positive completion response on the final
+     * successful completion of a command.
+     * <p>
+     * @param reply  The reply code.
+     * @return True if a reply code is a postive completion response,
+     *  false if not.
+     */
+    public static boolean isPositiveCompletion(int reply) {
+        return (reply >= 200 && reply < 300);
+    }
+
+    /**
+     * Determine if a reply code is a positive intermediate response.  All
+     * codes beginning with a 3 are positive intermediate responses.
+     * The FTP server will send a positive intermediate response on the
+     * successful completion of one part of a multi-part sequence of
+     * commands.  For example, after a successful USER command, a positive
+     * intermediate response will be sent to indicate that the server is
+     * ready for the PASS command.
+     * <p>
+     * @param reply The reply code.
+     * @return True if a reply code is a postive intermediate response,
+     *  false if not.
+     */
+    public static boolean isPositiveIntermediate(int reply) {
+        return (reply >= 300 && reply < 400);
+    }
+
+    /**
+     * Determine if a reply code is a negative transient response.  All
+     * codes beginning with a 4 are negative transient responses.
+     * The FTP server will send a negative transient response on the
+     * failure of a command that can be reattempted with success.
+     * <p>
+     * @param reply The reply code.
+     * @return True if a reply code is a negative transient response,
+     *  false if not.
+     */
+    public static boolean isNegativeTransient(int reply) {
+        return (reply >= 400 && reply < 500);
+    }
+
+    /**
+     * Determine if a reply code is a negative permanent response.  All
+     * codes beginning with a 5 are negative permanent responses.
+     * The FTP server will send a negative permanent response on the
+     * failure of a command that cannot be reattempted with success.
+     * <p>
+     * @param reply The reply code.
+     * @return True if a reply code is a negative permanent response,
+     *  false if not.
+     */
+    public static boolean isNegativePermanent(int reply) {
+        return (reply >= 500 && reply < 600);
+    }
+}

Modified: 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java
URL: 
http://svn.apache.org/viewvc/jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java?rev=437151&r1=437150&r2=437151&view=diff
==============================================================================
--- 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java
 (original)
+++ 
jakarta/commons/proper/net/branches/JDK_1_5_BRANCH/src/main/java/org/apache/commons/net/ftp/FTPSSocketFactory.java
 Sat Aug 26 05:09:50 2006
@@ -1,18 +1,19 @@
-/*
- * Copyright 2001-2006 The Apache Software Foundation
- *
+/**
+ * Copyright 2006 Paul Ferraro & Jose Juan Montiel
+ * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 package org.apache.commons.net.ftp;
 
 import java.io.IOException;
@@ -23,65 +24,52 @@
 
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLServerSocket;
-import javax.net.ssl.SSLSocket;
 
 import org.apache.commons.net.SocketFactory;
 
-public class FTPSSocketFactory implements SocketFactory
-{
-       private SSLContext context;
-       
-       public FTPSSocketFactory(SSLContext context)
-       {
-               this.context = context;
-       }
-       
-       public Socket createSocket(String address, int port) throws 
UnknownHostException, IOException
-       {
-               return 
this.init(this.context.getSocketFactory().createSocket(address, port));
-       }
-
-       public Socket createSocket(InetAddress address, int port) throws 
IOException
-       {
-               return 
this.init(this.context.getSocketFactory().createSocket(address, port));
-       }
-
-       public Socket createSocket(String address, int port, InetAddress 
localAddress, int localPort) throws UnknownHostException, IOException
-       {
-               return 
this.init(this.context.getSocketFactory().createSocket(address, port, 
localAddress, localPort));
-       }
-
-       public Socket createSocket(InetAddress address, int port, InetAddress 
localAddress, int localPort) throws IOException
-       {
-               return 
this.init(this.context.getSocketFactory().createSocket(address, port, 
localAddress, localPort));
-       }
-       
-       public ServerSocket createServerSocket(int port) throws IOException
-       {
-               return 
this.init(this.context.getServerSocketFactory().createServerSocket(port));
-       }
-
-       public ServerSocket createServerSocket(int port, int backlog) throws 
IOException
-       {
-               return 
this.init(this.context.getServerSocketFactory().createServerSocket(port, 
backlog));
-       }
-
-       public ServerSocket createServerSocket(int port, int backlog, 
InetAddress ifAddress) throws IOException
-       {
-               return 
this.init(this.context.getServerSocketFactory().createServerSocket(port, 
backlog, ifAddress));
-       }
-       
-       public Socket init(Socket socket) throws IOException
-       {
-               ((SSLSocket) socket).startHandshake();
-               
-               return socket;
-       }
-       
-       public ServerSocket init(ServerSocket socket) throws IOException
-       {
-               ((SSLServerSocket) socket).setUseClientMode(true);
-               
-               return socket;
-       }
+/**
+ * 
+ * Implementation of org.apache.commons.net.SocketFactory
+ *
+ */
+public class FTPSSocketFactory implements SocketFactory {
+
+    private SSLContext context;
+    
+    public FTPSSocketFactory(SSLContext context) {
+        this.context = context;
+    }
+    
+    public Socket createSocket(String address, int port) throws 
UnknownHostException, IOException {
+        return this.context.getSocketFactory().createSocket(address, port);
+    }
+
+    public Socket createSocket(InetAddress address, int port) throws 
IOException {
+        return this.context.getSocketFactory().createSocket(address, port);
+    }
+
+    public Socket createSocket(String address, int port, InetAddress 
localAddress, int localPort) throws UnknownHostException, IOException {
+        return this.context.getSocketFactory().createSocket(address, port, 
localAddress, localPort);
+    }
+
+    public Socket createSocket(InetAddress address, int port, InetAddress 
localAddress, int localPort) throws IOException {
+        return this.context.getSocketFactory().createSocket(address, port, 
localAddress, localPort);
+    }
+    
+    public ServerSocket createServerSocket(int port) throws IOException {
+        return 
this.init(this.context.getServerSocketFactory().createServerSocket(port));
+    }
+
+    public ServerSocket createServerSocket(int port, int backlog) throws 
IOException {
+        return 
this.init(this.context.getServerSocketFactory().createServerSocket(port, 
backlog));
+    }
+
+    public ServerSocket createServerSocket(int port, int backlog, InetAddress 
ifAddress) throws IOException {
+        return 
this.init(this.context.getServerSocketFactory().createServerSocket(port, 
backlog, ifAddress));
+    }
+        
+    public ServerSocket init(ServerSocket socket) throws IOException {
+        ((SSLServerSocket) socket).setUseClientMode(true);
+        return socket;
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to