Author: norman
Date: Wed Sep 30 13:32:33 2009
New Revision: 820264

URL: http://svn.apache.org/viewvc?rev=820264&view=rev
Log:
Fix generic STARTTLS. Thx to Stefano to help me out via Skype (JAMES-290 , 
JAMES-924)

Added:
    
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableInputStream.java
    
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableOutputStream.java
Modified:
    
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/JamesConnectionBridge.java

Modified: 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/JamesConnectionBridge.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/JamesConnectionBridge.java?rev=820264&r1=820263&r2=820264&view=diff
==============================================================================
--- 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/JamesConnectionBridge.java
 (original)
+++ 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/JamesConnectionBridge.java
 Wed Sep 30 13:32:33 2009
@@ -123,6 +123,8 @@
     
     private SSLSocketFactory factory;
     private boolean secureEnabled = false;
+    private SwitchableInputStream switchableIn;
+    private SwitchableOutputStream switchableOut;
     
     public JamesConnectionBridge(final ProtocolHandler delegated, final 
DNSService dnsServer, final String name, 
             final Logger logger, final SSLSocketFactory factory) {
@@ -199,32 +201,53 @@
     }
 
 
-       private SSLSocket secureSocket(Socket socket) throws IOException {
-               SSLSocket sslsock = (SSLSocket) factory.createSocket(socket, 
socket
-                               .getInetAddress().getHostName(), 
socket.getPort(), true);
-               sslsock.setUseClientMode(false);
-               getLogger().debug("Finished negotiating SSL - algorithm is " +
-                                sslsock.getSession().getCipherSuite());
-               return sslsock;
-       }
-
+    /**
+     * Create a SSLSocket which wraps the given one
+     * 
+     * @param socket
+     * @return sslsocket
+     * @throws IOException
+     */
+    private SSLSocket secureSocket(Socket socket) throws IOException {
+        SSLSocket sslsock = (SSLSocket) factory.createSocket(socket, socket
+                .getInetAddress().getHostName(), socket.getPort(), true);
+        sslsock.setUseClientMode(false);
+        getLogger().debug("Finished negotiating SSL - algorithm is "
+                        + sslsock.getSession().getCipherSuite());
+        return sslsock;
+    }
        
+    /**
+     * Connect all streams of the given socket
+     * 
+     * @param socket
+     * @throws IOException
+     */
     private void connectStreams(Socket socket) throws IOException {
-        in = new BufferedInputStream(socket.getInputStream(), 
DEFAULT_INPUT_BUFFER_SIZE);
-        outs = new BufferedOutputStream(socket.getOutputStream(), 
DEFAULT_OUTPUT_BUFFER_SIZE);
+
+        InputStream is = socket.getInputStream();
+        OutputStream out2 = socket.getOutputStream();
+        switchableIn = new SwitchableInputStream(is);
+        switchableOut = new SwitchableOutputStream(out2);
+        in = new BufferedInputStream(switchableIn, DEFAULT_INPUT_BUFFER_SIZE);
+        outs = new BufferedOutputStream(switchableOut,
+                DEFAULT_OUTPUT_BUFFER_SIZE);
+
         // enable tcp dump for debug
         if (tcplogprefix != null) {
-            outs = new SplitOutputStream(outs, new 
FileOutputStream(tcplogprefix+"out"));
-            in = new CopyInputStream(in, new 
FileOutputStream(tcplogprefix+"in"));
+            outs = new SplitOutputStream(outs, new FileOutputStream(
+                    tcplogprefix + "out"));
+            in = new CopyInputStream(in, new FileOutputStream(tcplogprefix
+                    + "in"));
         }
-        
+
         // An ASCII encoding can be used because all transmissions other
         // that those in the message body command are guaranteed
         // to be ASCII
         inReader = new CRLFTerminatedReader(in, "ASCII");
-        
+
         out = new InternetPrintWriter(outs, true);
-       }
+    }
 
        /**
      * The method clean up and close the allocated resources
@@ -522,10 +545,16 @@
         return log;
     }
 
+    /**
+     * @see org.apache.james.socket.ProtocolContext#isDisconnected()
+     */
     public boolean isDisconnected() {
         return socket == null;
     }
 
+    /**
+     * @see org.apache.james.socket.WatchdogTarget#execute()
+     */
     public void execute() {
         idleClose();
     }
@@ -533,22 +562,23 @@
     /**
      * @see org.apache.james.socket.ProtocolContext#isSecure()
      */
-       public boolean isSecure() {
-               return secureEnabled;
-       }
+    public boolean isSecure() {
+        return secureEnabled;
+    }
+
+    /**
+     * @see org.apache.james.socket.ProtocolContext#secure()
+     */
+    public void secure() throws IOException {
+        if (factory == null) {
+            throw new UnsupportedOperationException("StartTLS not supported");
+        }
 
-       /**
-        * @see org.apache.james.socket.ProtocolContext#secure()
-        */
-       public void secure() throws IOException {
-               if (factory == null) {
-                       throw new UnsupportedOperationException("StartTLS not 
supported");
-               }
-               
-               socket = secureSocket(socket);
+        socket = secureSocket(socket);
 
-               connectStreams(socket);
-               this.secureEnabled = true;
+        switchableIn.setWrappedInputStream(socket.getInputStream());
+        switchableOut.setWrappedOutputStream(socket.getOutputStream());
+        this.secureEnabled = true;
 
-       }
+    }
 }

Added: 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableInputStream.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableInputStream.java?rev=820264&view=auto
==============================================================================
--- 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableInputStream.java
 (added)
+++ 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableInputStream.java
 Wed Sep 30 13:32:33 2009
@@ -0,0 +1,44 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.james.socket;
+
+import java.io.FilterInputStream;
+import java.io.InputStream;
+
+/**
+ * InputStream which allows to replace the wrapped InputStream
+ * 
+ * 
+ */
+public class SwitchableInputStream extends FilterInputStream {
+
+    protected SwitchableInputStream(InputStream in) {
+        super(in);
+    }
+
+    /**
+     * Set the wrapped InputStream
+     * 
+     * @param in
+     */
+    public void setWrappedInputStream(InputStream in) {
+        this.in = in;
+    }
+}

Added: 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableOutputStream.java
URL: 
http://svn.apache.org/viewvc/james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableOutputStream.java?rev=820264&view=auto
==============================================================================
--- 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableOutputStream.java
 (added)
+++ 
james/server/trunk/avalon-socket-library/src/main/java/org/apache/james/socket/SwitchableOutputStream.java
 Wed Sep 30 13:32:33 2009
@@ -0,0 +1,75 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you 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.james.socket;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * OutputStream which allows to replace the wrapped InputStream
+ * 
+ * NOTE: This extends OutputStream because SSLSocket was not be able to 
complete the SSL
+ * negoation when using this class to wrap the socket.getOutputStream() while 
extending FilterOutputStream. 
+ * No clue why...
+ * 
+ * 
+ */
+public class SwitchableOutputStream extends OutputStream {
+    private OutputStream out;
+
+    public SwitchableOutputStream(OutputStream out) {
+        this.out = out;
+    }
+
+    /**
+     * Set the wrapped OutputStream
+     * 
+     * @param in
+     */
+    public void setWrappedOutputStream(OutputStream out) {
+        this.out = out;
+    }
+
+    @Override
+    public void write(int b) throws IOException {
+        out.write(b);
+    }
+
+    @Override
+    public void close() throws IOException {
+        out.close();
+    }
+
+    @Override
+    public void flush() throws IOException {
+        out.flush();
+    }
+
+    @Override
+    public void write(byte[] b, int off, int len) throws IOException {
+        out.write(b, off, len);
+    }
+
+    @Override
+    public void write(byte[] b) throws IOException {
+        out.write(b);
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to