harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From lvj...@apache.org
Subject svn commit: r596091 - in /harmony/enhanced/classlib/trunk/modules/jndi/src: main/java/javax/naming/ldap/ main/java/org/apache/harmony/jndi/provider/ldap/ main/java/org/apache/harmony/jndi/provider/ldap/ext/ test/java/org/apache/harmony/jndi/provider/ld...
Date Sun, 18 Nov 2007 15:19:54 GMT
Author: lvjing
Date: Sun Nov 18 07:19:54 2007
New Revision: 596091

URL: http://svn.apache.org/viewvc?rev=596091&view=rev
Log:
Apply for Harmony-5132

Added:
    harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ext/
    harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImpl.java
  (with props)
    harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/ext/
    harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImplTest.java
  (with props)
Modified:
    harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java
    harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java

Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java?rev=596091&r1=596090&r2=596091&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/javax/naming/ldap/StartTlsRequest.java
Sun Nov 18 07:19:54 2007
@@ -97,7 +97,13 @@
             // ignore
         }
 
-        // TODO: return a provider default implementation
+        try {
+            return  (StartTlsResponse) Class.forName(
+                    "org.apache.harmony.jndi.provider.ldap.ext.StartTlsResponseImpl", true,
cl).newInstance();
+        } catch (Exception e) {
+            // ignore
+        }
+        
         throw new NamingException(Messages.getString("ldap.09")); //$NON-NLS-1$
     }
 }

Modified: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java?rev=596091&r1=596090&r2=596091&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java
(original)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/LdapClient.java
Sun Nov 18 07:19:54 2007
@@ -29,6 +29,7 @@
 import javax.naming.Context;
 import javax.naming.NamingException;
 import javax.naming.ldap.Control;
+import javax.naming.ldap.StartTlsRequest;
 import javax.net.SocketFactory;
 import javax.net.ssl.SSLSocketFactory;
 
@@ -230,6 +231,16 @@
                      * notify the thread which send request and wait for
                      * response
                      */
+                    if (element.response.getOperationIndex() == LdapASN1Constant.OP_EXTENDED_RESPONSE
+                            && ((ExtendedOp) element.response.getResponseOp())
+                                    .getExtendedRequest().getID().equals(
+                                            StartTlsRequest.OID)) {
+                        /*
+                         * When establishing TLS by StartTls extended operation, no 
+                         */
+                        isStopped = true;
+                    }
+                    
                     synchronized (element.lock) {
                         element.lock.notify();
                     }
@@ -611,5 +622,21 @@
     @Override
     protected void finalize() {
         close();
+    }
+    
+    public Socket getSocket() {
+        return this.socket;
+    }
+
+    public void setSocket(Socket socket) throws IOException {
+        this.socket = socket;
+        this.in = new InputStreamWrap(socket.getInputStream());
+        this.out = socket.getOutputStream();
+        if (dispatcher != null) {
+            dispatcher.setStopped(true);
+            dispatcher.interrupt();
+        }
+        this.dispatcher = new Dispatcher();
+        this.dispatcher.start();
     }
 }

Added: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImpl.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImpl.java?rev=596091&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImpl.java
(added)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImpl.java
Sun Nov 18 07:19:54 2007
@@ -0,0 +1,133 @@
+package org.apache.harmony.jndi.provider.ldap.ext;
+
+import java.io.IOException;
+import java.net.Socket;
+
+import javax.naming.ldap.StartTlsResponse;
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+public class StartTlsResponseImpl extends StartTlsResponse {
+
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -1199041712215453042L;
+
+    private String[] suites;
+
+    private HostnameVerifier verifier;
+
+    private Socket socket; // existing uderlying socket
+
+    private boolean isHandshaked = false; // is handshake finished
+
+    private SSLSocket negotiatedSslSocket = null; // negotiated ssl socket
+
+    @Override
+    public void close() throws IOException {
+        /*
+         * TODO Spec requires close the TLS connection gracefully and reverts
+         * back to the underlying connection. RI close the ssl socket but
+         * dosen't reverts to former socket when invoke this method. We follow
+         * RI here.
+         */
+        if (negotiatedSslSocket != null) {
+            negotiatedSslSocket.close();
+        }
+    }
+
+    @Override
+    public SSLSession negotiate() throws IOException {
+        return negotiate(null);
+    }
+
+    @Override
+    public SSLSession negotiate(SSLSocketFactory factory) throws IOException {
+
+        if (socket == null) {
+            // must set socket before negotiate
+            return null;
+        }
+
+        if (factory == null) {
+            factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+        }
+
+        SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket, socket
+                .getInetAddress().getHostName(), socket.getPort(), false);
+
+        if (suites != null) {
+            sslSocket.setEnabledCipherSuites(suites);
+        }
+
+        sslSocket
+                .addHandshakeCompletedListener(new HandshakeCompletedListener() {
+                    public void handshakeCompleted(HandshakeCompletedEvent event) {
+                        isHandshaked = true;
+                    }
+                });
+
+        sslSocket.startHandshake();
+
+        while (!isHandshaked) {
+            // Wait for handshake finish.
+        }
+
+        HostnameVerifier defaultVerifier = new HostnameVerifier() {
+
+            public boolean verify(String hostname, SSLSession session) {
+                // TODO: add verify logic here
+                return false;
+            }
+
+        };
+
+        /*
+         * TODO: the spec requires to verify server's hostname by default
+         * hostname verifier first, if failed, use the callback verifier. RI use
+         * callback verifier first then the dafault one. We follow the spec
+         * here.
+         */
+        if (defaultVerifier.verify(sslSocket.getInetAddress().getHostName(),
+                sslSocket.getSession())) {
+            this.negotiatedSslSocket = sslSocket;
+            return sslSocket.getSession();
+        } else if (verifier != null
+                && verifier.verify(sslSocket.getInetAddress().getHostName(),
+                        sslSocket.getSession())) {
+            this.negotiatedSslSocket = sslSocket;
+            return sslSocket.getSession();
+        }
+
+        // negotiation fails
+        /* 
+         * TODO: What to do if hostname verification failed? RI throws exception
+         * of hostname verification.
+         */
+        return null;
+    }
+
+    @Override
+    public void setEnabledCipherSuites(String[] suites) {
+        this.suites = suites;
+    }
+
+    @Override
+    public void setHostnameVerifier(HostnameVerifier verifier) {
+        this.verifier = verifier;
+    }
+
+    public void setSocket(Socket socket) {
+        this.socket = socket;
+    }
+
+    public SSLSocket getSSLSocket() {
+        return this.negotiatedSslSocket;
+    }
+}
+

Propchange: harmony/enhanced/classlib/trunk/modules/jndi/src/main/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImplTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImplTest.java?rev=596091&view=auto
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImplTest.java
(added)
+++ harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImplTest.java
Sun Nov 18 07:19:54 2007
@@ -0,0 +1,275 @@
+package org.apache.harmony.jndi.provider.ldap.ext;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+import junit.framework.TestCase;
+
+public class StartTlsResponseImplTest extends TestCase {
+
+    private final String HOST = "127.0.0.1";
+
+    private final int PORT = 12345;
+
+    public StartTlsResponseImplTest(String name) {
+        super(name);
+    }
+
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /*
+     * After negotiation, a SSlSocket will be created and attach to the
+     * underlying Socket which is used before negotiation. This test case
+     * compare the local port, peer's host, peer' port before and after the
+     * negotiation. Test case fail If they are different.
+     */
+    public void test_negotiate() throws IOException {
+
+        // This serverSocket is never used, just for creating a client socket.
+        ServerSocket server = new ServerSocket(PORT);
+
+        Socket socket = new Socket(HOST, PORT);
+        MockSSLSocketFactory factory = new MockSSLSocketFactory();
+
+        StartTlsResponseImpl tls = new StartTlsResponseImpl();
+
+        tls.setSocket(socket);
+
+        tls.setHostnameVerifier(new HostnameVerifier() {
+            public boolean verify(String hostname, SSLSession session) {
+                return true;
+            }
+        });
+
+        tls.negotiate(factory);
+
+        //Fail if SSLSocket is not created.
+        assertTrue(tls.getSSLSocket() instanceof SSLSocket);
+
+        assertEquals(socket.getInetAddress().getHostName(), tls.getSSLSocket()
+                .getInetAddress().getHostName());
+        assertEquals(socket.getPort(), tls.getSSLSocket().getPort());
+        assertEquals(socket.getLocalPort(), tls.getSSLSocket().getLocalPort());
+
+        socket.close();
+    }
+
+    /*
+     * This MockSSLSocketFactory is used for create and SSLSocket above an
+     * underlying simple socket. It won't do any connection.
+     */
+    public static class MockSSLSocketFactory extends SSLSocketFactory {
+
+        /*
+         * Create a MockSSLSocket, and attach it to an underlying simple socket.
+         * Won't do any connection.
+         */
+        @Override
+        public Socket createSocket(Socket s, String host, int port,
+                boolean autoClose) throws IOException {
+            SSLSocket sslSocket = new MockSSLSocket(s, host, port);
+            return sslSocket;
+        }
+
+        @Override
+        public String[] getDefaultCipherSuites() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public String[] getSupportedCipherSuites() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public Socket createSocket(String host, int port) throws IOException,
+                UnknownHostException {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public Socket createSocket(String host, int port,
+                InetAddress localHost, int localPort) throws IOException,
+                UnknownHostException {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public Socket createSocket(InetAddress host, int port)
+                throws IOException {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public Socket createSocket(InetAddress address, int port,
+                InetAddress localAddress, int localPort) throws IOException {
+            throw new Error("should not be here");
+        }
+
+    }
+
+    /*
+     * This MocketSSLSocket won't do any connection, nor any communication with
+     * a peer. It only stores peer host name, peer port, local host name and
+     * local port.
+     */
+    public static class MockSSLSocket extends SSLSocket {
+
+        private int port; // peer's port
+
+        private String localHost;
+
+        private int localPort;
+
+        private String[] suites;
+
+        private List<HandshakeCompletedListener> listeners;
+
+        private InetAddress address; // peer's address
+
+        protected MockSSLSocket(Socket socket, String host, int port)
+                throws UnknownHostException {
+            this.port = port;
+            this.localHost = socket.getLocalAddress().getHostAddress();
+            this.localPort = socket.getLocalPort();
+            address = InetAddress.getByName(host);
+            listeners = new LinkedList<HandshakeCompletedListener>();
+        }
+
+        /*
+         * Won't do any handshake with the peer, just notify registed listeners.
+         */
+        @Override
+        public void startHandshake() throws IOException {
+            for (HandshakeCompletedListener listener : listeners) {
+                if (this.listeners != null) {
+                    listener.handshakeCompleted(null);
+                } else {
+                    throw new Error(
+                            "should not be here, at MockHandshake.startHandshake()");
+                }
+            }
+        }
+
+        @Override
+        public void addHandshakeCompletedListener(
+                HandshakeCompletedListener listener) {
+            listeners.add(listener);
+        }
+
+        @Override
+        public SSLSession getSession() {
+            return null;
+        }
+
+        @Override
+        public void setEnabledCipherSuites(String[] suites) {
+            this.suites = suites;
+        }
+
+        @Override
+        public String[] getEnabledCipherSuites() {
+            return this.suites;
+        }
+
+        public InetAddress getInetAddress() {
+            return this.address;
+        }
+
+        public int getPort() {
+            return this.port;
+        }
+
+        public String getLocalHost() {
+            return this.localHost;
+        }
+
+        public int getLocalPort() {
+            return this.localPort;
+        }
+
+        @Override
+        public boolean getEnableSessionCreation() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public String[] getEnabledProtocols() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public boolean getNeedClientAuth() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public String[] getSupportedCipherSuites() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public String[] getSupportedProtocols() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public boolean getUseClientMode() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public boolean getWantClientAuth() {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public void removeHandshakeCompletedListener(
+                HandshakeCompletedListener listener) {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public void setEnableSessionCreation(boolean flag) {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public void setEnabledProtocols(String[] protocols) {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public void setNeedClientAuth(boolean need) {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public void setUseClientMode(boolean mode) {
+            throw new Error("should not be here");
+        }
+
+        @Override
+        public void setWantClientAuth(boolean want) {
+            throw new Error("should not be here");
+        }
+    }
+
+}

Propchange: harmony/enhanced/classlib/trunk/modules/jndi/src/test/java/org/apache/harmony/jndi/provider/ldap/ext/StartTlsResponseImplTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message