Author: markt Date: Thu Dec 9 18:10:38 2010 New Revision: 1044058 URL: http://svn.apache.org/viewvc?rev=1044058&view=rev Log: Re-factoring in support of https://issues.apache.org/bugzilla/show_bug.cgi?id=50360 Move ad-hoc attribute handling from the ProtocolHandler to the Endpoint and expose the Endpoint to ServerSocketFactory objects so they can retrieve additional configuration if required. All default components now use explicit configuration rather than relying on the ad-hoc mechanism. Ensure the hooks for alternative SSL implementations are in place (were partially removed). Remove the hooks for alternative ServerSocketFactory implementations (had been hard-coded / half implemented for some time). Make the sslEnabledProtocols attribute work with BIO as well.
Modified: tomcat/trunk/java/org/apache/catalina/connector/Connector.java tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java tomcat/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java tomcat/trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java tomcat/trunk/webapps/docs/config/http.xml Modified: tomcat/trunk/java/org/apache/catalina/connector/Connector.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/connector/Connector.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/connector/Connector.java (original) +++ tomcat/trunk/java/org/apache/catalina/connector/Connector.java Thu Dec 9 18:10:38 2010 @@ -249,7 +249,6 @@ public class Connector extends Lifecycle replacements.put("connectionTimeout", "soTimeout"); replacements.put("randomFile", "randomfile"); replacements.put("rootFile", "rootfile"); - replacements.put("sslProtocols", "protocols"); } Modified: tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java (original) +++ tomcat/trunk/java/org/apache/coyote/AbstractProtocolHandler.java Thu Dec 9 18:10:38 2010 @@ -17,8 +17,6 @@ package org.apache.coyote; import java.net.InetAddress; -import java.util.HashMap; -import java.util.Iterator; import java.util.concurrent.Executor; import javax.management.MBeanRegistration; @@ -65,55 +63,6 @@ public abstract class AbstractProtocolHa // ----------------------------------------------- Generic property handling /** - * Attributes provide a way for configuration to be passed to sub-components - * without the {...@link ProtocolHandler} being aware of the properties - * available on those sub-components. One example of such a sub-component is - * the {...@link org.apache.tomcat.util.net.ServerSocketFactory}. - */ - protected HashMap<String, Object> attributes = - new HashMap<String, Object>(); - - - /** - * Generic property setter called when a property for which a specific - * setter already exists within the {...@link ProtocolHandler} needs to be - * made available to sub-components. The specific setter will call this - * method to populate the attributes. - */ - @Override - public void setAttribute(String name, Object value) { - if (getLog().isTraceEnabled()) { - getLog().trace(sm.getString("abstractProtocolHandler.setAttribute", - name, value)); - } - attributes.put(name, value); - } - - - /** - * Used by sub-components to retrieve configuration information. - */ - @Override - public Object getAttribute(String key) { - Object value = attributes.get(key); - if (getLog().isTraceEnabled()) { - getLog().trace(sm.getString("abstractProtocolHandler.getAttribute", - key, value)); - } - return value; - } - - - /** - * Used by sub-components to retrieve configuration information. - */ - @Override - public Iterator<String> getAttributeNames() { - return attributes.keySet().iterator(); - } - - - /** * Generic property setter used by the digester. Other code should not need * to use this. The digester will only use this method if it can't find a * more specific setter. That means the property belongs to the Endpoint, @@ -121,7 +70,6 @@ public abstract class AbstractProtocolHa * ensures that it is visible to both. */ public boolean setProperty(String name, String value) { - setAttribute(name, value); return endpoint.setProperty(name, value); } @@ -131,9 +79,7 @@ public abstract class AbstractProtocolHa * to use this. */ public String getProperty(String name) { - // Since all calls to setProperty() will place the property in the - // attributes list, just retrieve it from there. - return (String)getAttribute(name); + return endpoint.getProperty(name); } @@ -217,14 +163,12 @@ public abstract class AbstractProtocolHa public InetAddress getAddress() { return endpoint.getAddress(); } public void setAddress(InetAddress ia) { endpoint.setAddress(ia); - setAttribute("address", ia.toString()); } public int getPort() { return endpoint.getPort(); } public void setPort(int port) { endpoint.setPort(port); - setAttribute("port", Integer.toString(port)); } @@ -239,10 +183,6 @@ public abstract class AbstractProtocolHa public void setConnectionTimeout(int timeout) { // Note that the endpoint uses the alternative name endpoint.setSoTimeout(timeout); - String str = Integer.toString(timeout); - setAttribute("connectionTimeout", str); - // Also set the attribute for the alternative name - setAttribute("soTimeout", str); } /* Modified: tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java (original) +++ tomcat/trunk/java/org/apache/coyote/ProtocolHandler.java Thu Dec 9 18:10:38 2010 @@ -17,7 +17,6 @@ package org.apache.coyote; -import java.util.Iterator; import java.util.concurrent.Executor; @@ -37,14 +36,6 @@ import java.util.concurrent.Executor; public interface ProtocolHandler { /** - * Pass config info. - */ - public void setAttribute(String name, Object value); - public Object getAttribute(String name); - public Iterator<String> getAttributeNames(); - - - /** * The adapter, used to call the connector. */ public void setAdapter(Adapter adapter); Modified: tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/ajp/AjpProtocol.java Thu Dec 9 18:10:38 2010 @@ -34,6 +34,7 @@ import org.apache.tomcat.util.modeler.Re import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.net.JIoEndpoint; import org.apache.tomcat.util.net.JIoEndpoint.Handler; +import org.apache.tomcat.util.net.SSLImplementation; import org.apache.tomcat.util.net.SocketStatus; import org.apache.tomcat.util.net.SocketWrapper; @@ -145,6 +146,12 @@ public class AjpProtocol extends Abstrac } @Override + public SSLImplementation getSslImplementation() { + // AJP does not support SSL + return null; + } + + @Override public void recycle() { recycledProcessors.clear(); } @@ -251,7 +258,6 @@ public class AjpProtocol extends Abstrac } } } - } } Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11JsseProtocol.java Thu Dec 9 18:10:38 2010 @@ -17,7 +17,6 @@ package org.apache.coyote.http11; import org.apache.tomcat.util.net.SSLImplementation; -import org.apache.tomcat.util.net.jsse.JSSEImplementation; public abstract class AbstractHttp11JsseProtocol extends AbstractHttp11Protocol { @@ -104,12 +103,19 @@ public abstract class AbstractHttp11Jsse return endpoint.getAllowUnsafeLegacyRenegotiation(); } + private String sslImplemenationName = null; + public String getSslImplemenationName() { return sslImplemenationName; } + public void setSslImplemenationName(String s) { + this.sslImplemenationName = s; + } // ------------------------------------------------------- Lifecycle methods @Override public void init() throws Exception { + // SSL implementation needs to be in place before end point is + // initialized + sslImplementation = SSLImplementation.getInstance(sslImplemenationName); super.init(); - sslImplementation = new JSSEImplementation(); } } Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Thu Dec 9 18:10:38 2010 @@ -166,7 +166,6 @@ public abstract class AbstractHttp11Prot public boolean getSecure() { return secure; } public void setSecure(boolean b) { secure = b; - setAttribute("secure", "" + b); } @@ -179,7 +178,6 @@ public abstract class AbstractHttp11Prot } public void setMaxKeepAliveRequests(int mkar) { endpoint.setMaxKeepAliveRequests(mkar); - setAttribute("maxKeepAliveRequests", "" + mkar); } Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProtocol.java Thu Dec 9 18:10:38 2010 @@ -37,6 +37,7 @@ import org.apache.tomcat.util.net.Abstra import org.apache.tomcat.util.net.NioChannel; import org.apache.tomcat.util.net.NioEndpoint; import org.apache.tomcat.util.net.NioEndpoint.Handler; +import org.apache.tomcat.util.net.SSLImplementation; import org.apache.tomcat.util.net.SecureNioChannel; import org.apache.tomcat.util.net.SocketStatus; @@ -110,12 +111,10 @@ public class Http11NioProtocol extends A public void setAcceptorThreadPriority(int threadPriority) { ((NioEndpoint)endpoint).setAcceptorThreadPriority(threadPriority); - setAttribute("acceptorThreadPriority", "" + threadPriority); } public void setPollerThreadPriority(int threadPriority) { ((NioEndpoint)endpoint).setPollerThreadPriority(threadPriority); - setAttribute("pollerThreadPriority", "" + threadPriority); } public int getAcceptorThreadPriority() { @@ -142,12 +141,10 @@ public class Http11NioProtocol extends A public void setSocketCloseDelay( int d ) { socketCloseDelay=d; - setAttribute("socketCloseDelay", "" + d); } public void setOomParachute(int oomParachute) { ((NioEndpoint)endpoint).setOomParachute(oomParachute); - setAttribute("oomParachute", Integer.valueOf(oomParachute)); } // -------------------- SSL related properties -------------------- @@ -217,6 +214,10 @@ public class Http11NioProtocol extends A recycledProcessors.clear(); } + public SSLImplementation getSslImplementation() { + return proto.sslImplementation; + } + @Override public void release(SocketChannel socket) { if (log.isDebugEnabled()) Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Protocol.java Thu Dec 9 18:10:38 2010 @@ -35,6 +35,7 @@ import org.apache.tomcat.util.modeler.Re import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.net.JIoEndpoint; import org.apache.tomcat.util.net.JIoEndpoint.Handler; +import org.apache.tomcat.util.net.SSLImplementation; import org.apache.tomcat.util.net.SocketStatus; import org.apache.tomcat.util.net.SocketWrapper; @@ -142,6 +143,10 @@ public class Http11Protocol extends Abst return global; } + public SSLImplementation getSslImplementation() { + return proto.sslImplementation; + } + @Override public void recycle() { recycledProcessors.clear(); Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractEndpoint.java Thu Dec 9 18:10:38 2010 @@ -20,6 +20,8 @@ import java.io.File; import java.io.OutputStreamWriter; import java.net.InetAddress; import java.net.InetSocketAddress; +import java.util.ArrayList; +import java.util.HashMap; import java.util.StringTokenizer; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; @@ -320,10 +322,44 @@ public abstract class AbstractEndpoint { protected abstract boolean getDeferAccept(); + /** - * Generic properties, introspected - */ + * Attributes provide a way for configuration to be passed to sub-components + * without the {...@link ProtocolHandler} being aware of the properties + * available on those sub-components. One example of such a sub-component is + * the {...@link org.apache.tomcat.util.net.ServerSocketFactory}. + */ + protected HashMap<String, Object> attributes = + new HashMap<String, Object>(); + /** + * Generic property setter called when a property for which a specific + * setter already exists within the {...@link ProtocolHandler} needs to be + * made available to sub-components. The specific setter will call this + * method to populate the attributes. + */ + public void setAttribute(String name, Object value) { + if (getLog().isTraceEnabled()) { + getLog().trace(sm.getString("abstractProtocolHandler.setAttribute", + name, value)); + } + attributes.put(name, value); + } + /** + * Used by sub-components to retrieve configuration information. + */ + public Object getAttribute(String key) { + Object value = attributes.get(key); + if (getLog().isTraceEnabled()) { + getLog().trace(sm.getString("abstractProtocolHandler.getAttribute", + key, value)); + } + return value; + } + + + public boolean setProperty(String name, String value) { + setAttribute(name, value); final String socketName = "socket."; try { if (name.startsWith(socketName)) { @@ -336,7 +372,10 @@ public abstract class AbstractEndpoint { return false; } } - + public String getProperty(String name) { + return (String) getAttribute(name); + } + /** * Return the amount of threads that are managed by the pool. * @@ -632,11 +671,24 @@ public abstract class AbstractEndpoint { private String[] sslEnabledProtocolsarr = new String[0]; - public String[] getSslEnabledProtocolsArray() { return this.sslEnabledProtocolsarr;} + public String[] getSslEnabledProtocolsArray() { + return this.sslEnabledProtocolsarr; + } public void setSslEnabledProtocols(String s) { - StringTokenizer t = new StringTokenizer(s,","); - sslEnabledProtocolsarr = new String[t.countTokens()]; - for (int i=0; i<sslEnabledProtocolsarr.length; i++ ) sslEnabledProtocolsarr[i] = t.nextToken(); + if (s == null) { + this.sslEnabledProtocolsarr = new String[0]; + } else { + ArrayList<String> sslEnabledProtocols = new ArrayList<String>(); + StringTokenizer t = new StringTokenizer(s,","); + while (t.hasMoreTokens()) { + String p = t.nextToken().trim(); + if (p.length() > 0) { + sslEnabledProtocols.add(p); + } + } + sslEnabledProtocolsarr = sslEnabledProtocols.toArray( + new String[sslEnabledProtocols.size()]); + } } } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/DefaultServerSocketFactory.java Thu Dec 9 18:10:38 2010 @@ -29,48 +29,38 @@ import java.net.Socket; * @author d...@eng.sun.com * @author Harish Prabandham */ +public class DefaultServerSocketFactory implements ServerSocketFactory { -// Default implementation of server sockets. + private AbstractEndpoint endpoint; -// -// WARNING: Some of the APIs in this class are used by J2EE. -// Please talk to hari...@eng.sun.com before making any changes. -// -class DefaultServerSocketFactory extends ServerSocketFactory { - - DefaultServerSocketFactory () { - /* NOTHING */ + public DefaultServerSocketFactory(AbstractEndpoint endpoint) { + this.endpoint = endpoint; } @Override - public ServerSocket createSocket (int port) - throws IOException { + public ServerSocket createSocket (int port) throws IOException { return new ServerSocket (port); } @Override public ServerSocket createSocket (int port, int backlog) - throws IOException { + throws IOException { return new ServerSocket (port, backlog); } @Override public ServerSocket createSocket (int port, int backlog, - InetAddress ifAddress) - throws IOException { + InetAddress ifAddress) throws IOException { return new ServerSocket (port, backlog, ifAddress); } - + @Override - public Socket acceptSocket(ServerSocket socket) - throws IOException { + public Socket acceptSocket(ServerSocket socket) throws IOException { return socket.accept(); } - + @Override - public void handshake(Socket sock) - throws IOException { + public void handshake(Socket sock) throws IOException { // NOOP } - } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/JIoEndpoint.java Thu Dec 9 18:10:38 2010 @@ -119,7 +119,9 @@ public class JIoEndpoint extends Abstrac */ public interface Handler extends AbstractEndpoint.Handler { public SocketState process(SocketWrapper<Socket> socket); - public SocketState process(SocketWrapper<Socket> socket, SocketStatus status); + public SocketState process(SocketWrapper<Socket> socket, + SocketStatus status); + public SSLImplementation getSslImplementation(); } @@ -333,57 +335,22 @@ public class JIoEndpoint extends Abstrac acceptorThreadCount = 1; } if (serverSocketFactory == null) { - serverSocketFactory = ServerSocketFactory.getDefault(); - } - if (isSSLEnabled()) { - serverSocketFactory.setAttribute(SSL_ATTR_ALGORITHM, - getAlgorithm()); - serverSocketFactory.setAttribute(SSL_ATTR_CLIENT_AUTH, - getClientAuth()); - serverSocketFactory.setAttribute(SSL_ATTR_KEYSTORE_FILE, - getKeystoreFile()); - serverSocketFactory.setAttribute(SSL_ATTR_KEYSTORE_PASS, - getKeystorePass()); - serverSocketFactory.setAttribute(SSL_ATTR_KEYSTORE_TYPE, - getKeystoreType()); - serverSocketFactory.setAttribute(SSL_ATTR_KEYSTORE_PROVIDER, - getKeystoreProvider()); - serverSocketFactory.setAttribute(SSL_ATTR_SSL_PROTOCOL, - getSslProtocol()); - serverSocketFactory.setAttribute(SSL_ATTR_CIPHERS, - getCiphers()); - serverSocketFactory.setAttribute(SSL_ATTR_KEY_ALIAS, - getKeyAlias()); - serverSocketFactory.setAttribute(SSL_ATTR_KEY_PASS, - getKeyPass()); - serverSocketFactory.setAttribute(SSL_ATTR_TRUSTSTORE_FILE, - getTruststoreFile()); - serverSocketFactory.setAttribute(SSL_ATTR_TRUSTSTORE_PASS, - getTruststorePass()); - serverSocketFactory.setAttribute(SSL_ATTR_TRUSTSTORE_TYPE, - getTruststoreType()); - serverSocketFactory.setAttribute(SSL_ATTR_TRUSTSTORE_PROVIDER, - getTruststoreProvider()); - serverSocketFactory.setAttribute(SSL_ATTR_TRUSTSTORE_ALGORITHM, - getTruststoreAlgorithm()); - serverSocketFactory.setAttribute(SSL_ATTR_CRL_FILE, - getCrlFile()); - serverSocketFactory.setAttribute(SSL_ATTR_TRUST_MAX_CERT_LENGTH, - getTrustMaxCertLength()); - serverSocketFactory.setAttribute(SSL_ATTR_SESSION_CACHE_SIZE, - getSessionCacheSize()); - serverSocketFactory.setAttribute(SSL_ATTR_SESSION_TIMEOUT, - getSessionTimeout()); - serverSocketFactory.setAttribute(SSL_ATTR_ALLOW_UNSAFE_RENEG, - getAllowUnsafeLegacyRenegotiation()); + if (isSSLEnabled()) { + serverSocketFactory = + handler.getSslImplementation().getServerSocketFactory(this); + } else { + serverSocketFactory = new DefaultServerSocketFactory(this); + } } if (serverSocket == null) { try { if (getAddress() == null) { - serverSocket = serverSocketFactory.createSocket(getPort(), getBacklog()); + serverSocket = serverSocketFactory.createSocket(getPort(), + getBacklog()); } else { - serverSocket = serverSocketFactory.createSocket(getPort(), getBacklog(), getAddress()); + serverSocket = serverSocketFactory.createSocket(getPort(), + getBacklog(), getAddress()); } } catch (BindException orig) { String msg; @@ -397,11 +364,8 @@ public class JIoEndpoint extends Abstrac throw be; } } - //if( serverTimeout >= 0 ) - // serverSocket.setSoTimeout( serverTimeout ); initialized = true; - } @Override @@ -475,8 +439,6 @@ public class JIoEndpoint extends Abstrac * Configure the socket. */ protected boolean setSocketOptions(Socket socket) { - serverSocketFactory.initSocket(socket); - try { // 1: Set socket options: timeout, linger, etc socketProperties.setProperties(socket); Modified: tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/NioEndpoint.java Thu Dec 9 18:10:38 2010 @@ -1500,6 +1500,7 @@ public class NioEndpoint extends Abstrac public SocketState event(NioChannel socket, SocketStatus status); public void release(NioChannel socket); public void release(SocketChannel socket); + public SSLImplementation getSslImplementation(); } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLImplementation.java Thu Dec 9 18:10:38 2010 @@ -80,7 +80,8 @@ public abstract class SSLImplementation public abstract String getImplementationName(); - public abstract ServerSocketFactory getServerSocketFactory(); + public abstract ServerSocketFactory getServerSocketFactory( + AbstractEndpoint endpoint); public abstract SSLSupport getSSLSupport(Socket sock); Modified: tomcat/trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/ServerSocketFactory.java Thu Dec 9 18:10:38 2010 @@ -14,91 +14,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.apache.tomcat.util.net; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.net.Socket; -import java.util.Hashtable; /** - * This class creates server sockets. It may be subclassed by other factories, - * which create particular types of server sockets. This provides a general - * framework for the addition of public socket-level functionality. It it is the - * server side analogue of a socket factory, and similarly provides a way to - * capture a variety of policies related to the sockets being constructed. - * <P> - * Like socket factories, Server Socket factory instances have two categories of - * methods. First are methods used to create sockets. Second are methods which - * set properties used in the production of sockets, such as networking options. - * There is also an environment specific default server socket factory; - * frameworks will often use their own customized factory. - * <P> - * <hr> - * <em> It may be desirable to move this interface into the - * <b>java.net</b> package, so that is not an extension but the preferred - * interface. Should this be serializable, making it a JavaBean which can - * be saved along with its networking configuration? - * </em> - * - * @author d...@eng.sun.com - * @author Harish Prabandham + * The common interface through which the {...@link JIoEndpoint} interacts with + * both non-SSL and SSL sockets. */ -public abstract class ServerSocketFactory implements Cloneable { - - // - // NOTE: JDK 1.1 bug in class GC, this can get collected - // even though it's always accessible via getDefault(). - // - - private static ServerSocketFactory theFactory; - protected Hashtable<String, Object> attributes = new Hashtable<String, Object>(); - - /** - * Constructor is used only by subclasses. - */ - protected ServerSocketFactory() { - /* NOTHING */ - } - - /** - * General mechanism to pass attributes from the ServerConnector to the - * socket factory. Note that the "preferred" mechanism is to use bean - * setters and explicit methods, but this allows easy configuration via - * server.xml or simple Properties - */ - public void setAttribute(String name, Object value) { - if (name != null && value != null) - attributes.put(name, value); - } - - /** - * Returns a copy of the environment's default socket factory. - */ - public static synchronized ServerSocketFactory getDefault() { - // - // optimize typical case: no synch needed - // - - if (theFactory == null) { - // - // Different implementations of this method could - // work rather differently. For example, driving - // this from a system property, or using a different - // implementation than JavaSoft's. - // - - theFactory = new DefaultServerSocketFactory(); - } - - try { - return (ServerSocketFactory) theFactory.clone(); - } catch (CloneNotSupportedException e) { - throw new RuntimeException(e.getMessage()); - } - } +public interface ServerSocketFactory { /** * Returns a server socket which uses all network interfaces on the host, @@ -112,7 +39,7 @@ public abstract class ServerSocketFactor * @exception InstantiationException * for construction errors */ - public abstract ServerSocket createSocket(int port) throws IOException, + ServerSocket createSocket(int port) throws IOException, InstantiationException; /** @@ -130,8 +57,8 @@ public abstract class ServerSocketFactor * @exception InstantiationException * for construction errors */ - public abstract ServerSocket createSocket(int port, int backlog) - throws IOException, InstantiationException; + ServerSocket createSocket(int port, int backlog) throws IOException, + InstantiationException; /** * Returns a server socket which uses only the specified network interface @@ -150,26 +77,21 @@ public abstract class ServerSocketFactor * @exception InstantiationException * for construction errors */ - public abstract ServerSocket createSocket(int port, int backlog, - InetAddress ifAddress) throws IOException, InstantiationException; - - public void initSocket(Socket s) { - } + ServerSocket createSocket(int port, int backlog, InetAddress ifAddress) + throws IOException, InstantiationException; /** * Wrapper function for accept(). This allows us to trap and translate - * exceptions if necessary + * exceptions if necessary. * * @exception IOException - * ; */ - public abstract Socket acceptSocket(ServerSocket socket) throws IOException; + Socket acceptSocket(ServerSocket socket) throws IOException; /** - * Extra function to initiate the handshake. Sometimes necessary for SSL + * Triggers the SSL handshake. This will be a no-op for non-SSL sockets. * * @exception IOException - * ; */ - public abstract void handshake(Socket sock) throws IOException; + void handshake(Socket sock) throws IOException; } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEFactory.java Thu Dec 9 18:10:38 2010 @@ -22,6 +22,7 @@ import java.net.Socket; import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSocket; +import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.net.SSLSupport; import org.apache.tomcat.util.net.ServerSocketFactory; @@ -38,8 +39,8 @@ public class JSSEFactory { /** * Returns the ServerSocketFactory to use. */ - public ServerSocketFactory getSocketFactory() { - return new JSSESocketFactory(); + public ServerSocketFactory getSocketFactory(AbstractEndpoint endpoint) { + return new JSSESocketFactory(endpoint); } /** Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java Thu Dec 9 18:10:38 2010 @@ -21,6 +21,7 @@ import java.net.Socket; import javax.net.ssl.SSLSession; +import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.net.SSLImplementation; import org.apache.tomcat.util.net.SSLSupport; import org.apache.tomcat.util.net.ServerSocketFactory; @@ -47,8 +48,8 @@ public class JSSEImplementation extends } @Override - public ServerSocketFactory getServerSocketFactory() { - ServerSocketFactory ssf = factory.getSocketFactory(); + public ServerSocketFactory getServerSocketFactory(AbstractEndpoint endpoint) { + ServerSocketFactory ssf = factory.getSocketFactory(endpoint); return ssf; } Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSESocketFactory.java Thu Dec 9 18:10:38 2010 @@ -60,6 +60,7 @@ import javax.net.ssl.X509KeyManager; import org.apache.catalina.Globals; import org.apache.tomcat.util.net.AbstractEndpoint; +import org.apache.tomcat.util.net.ServerSocketFactory; import org.apache.tomcat.util.res.StringManager; /** @@ -75,8 +76,7 @@ import org.apache.tomcat.util.res.String * @author Jan Luehe * @author Bill Barker */ -public class JSSESocketFactory - extends org.apache.tomcat.util.net.ServerSocketFactory { +public class JSSESocketFactory implements ServerSocketFactory { private static final StringManager sm = StringManager.getManager("org.apache.tomcat.util.net.jsse.res"); @@ -94,6 +94,8 @@ public class JSSESocketFactory static final org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory.getLog(JSSESocketFactory.class); + private AbstractEndpoint endpoint; + protected boolean initialized; protected SSLServerSocketFactory sslProxy = null; protected String[] enabledCiphers; @@ -110,8 +112,8 @@ public class JSSESocketFactory protected boolean wantClientAuth = false; - public JSSESocketFactory () { - // NOOP + public JSSESocketFactory (AbstractEndpoint endpoint) { + this.endpoint = endpoint; } @Override @@ -256,13 +258,11 @@ public class JSSESocketFactory * Gets the SSL server's keystore password. */ protected String getKeystorePassword() { - String keyPass = (String)attributes.get( - AbstractEndpoint.SSL_ATTR_KEY_PASS); + String keyPass = endpoint.getKeyPass(); if (keyPass == null) { keyPass = DEFAULT_KEY_PASS; } - String keystorePass = (String)attributes.get( - AbstractEndpoint.SSL_ATTR_KEYSTORE_PASS); + String keystorePass = endpoint.getKeystorePass(); if (keystorePass == null) { keystorePass = keyPass; } @@ -275,8 +275,7 @@ public class JSSESocketFactory protected KeyStore getKeystore(String type, String provider, String pass) throws IOException { - String keystoreFile = (String)attributes.get( - AbstractEndpoint.SSL_ATTR_KEYSTORE_FILE); + String keystoreFile = endpoint.getKeystoreFile(); if (keystoreFile == null) keystoreFile = defaultKeystoreFile; @@ -290,8 +289,7 @@ public class JSSESocketFactory String keystoreProvider) throws IOException { KeyStore trustStore = null; - String truststoreFile = (String)attributes.get( - AbstractEndpoint.SSL_ATTR_TRUSTSTORE_FILE); + String truststoreFile = endpoint.getTruststoreFile(); if(truststoreFile == null) { truststoreFile = System.getProperty("javax.net.ssl.trustStore"); } @@ -299,8 +297,7 @@ public class JSSESocketFactory log.debug("Truststore = " + truststoreFile); } - String truststorePassword = (String)attributes.get( - AbstractEndpoint.SSL_ATTR_TRUSTSTORE_PASS); + String truststorePassword = endpoint.getTruststorePass(); if( truststorePassword == null) { truststorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); @@ -309,8 +306,7 @@ public class JSSESocketFactory log.debug("TrustPass = " + truststorePassword); } - String truststoreType = (String)attributes.get( - AbstractEndpoint.SSL_ATTR_TRUSTSTORE_TYPE); + String truststoreType = endpoint.getTruststoreType(); if( truststoreType == null) { truststoreType = System.getProperty("javax.net.ssl.trustStoreType"); } @@ -321,9 +317,7 @@ public class JSSESocketFactory log.debug("trustType = " + truststoreType); } - String truststoreProvider = - (String)attributes.get( - AbstractEndpoint.SSL_ATTR_TRUSTSTORE_PROVIDER); + String truststoreProvider = endpoint.getTruststoreProvider(); if( truststoreProvider == null) { truststoreProvider = System.getProperty("javax.net.ssl.trustStoreProvider"); @@ -419,8 +413,7 @@ public class JSSESocketFactory void init() throws IOException { try { - String clientAuthStr = (String) attributes.get( - AbstractEndpoint.SSL_ATTR_CLIENT_AUTH); + String clientAuthStr = endpoint.getClientAuth(); if("true".equalsIgnoreCase(clientAuthStr) || "yes".equalsIgnoreCase(clientAuthStr)) { requireClientAuth = true; @@ -429,32 +422,25 @@ public class JSSESocketFactory } // SSL protocol variant (e.g., TLS, SSL v3, etc.) - String protocol = (String) attributes.get( - AbstractEndpoint.SSL_ATTR_SSL_PROTOCOL); + String protocol = endpoint.getSslProtocol(); if (protocol == null) { protocol = defaultProtocol; } // Certificate encoding algorithm (e.g., SunX509) - String algorithm = (String) attributes.get( - AbstractEndpoint.SSL_ATTR_ALGORITHM); + String algorithm = endpoint.getAlgorithm(); if (algorithm == null) { algorithm = KeyManagerFactory.getDefaultAlgorithm(); } - String keystoreType = (String) attributes.get( - AbstractEndpoint.SSL_ATTR_KEYSTORE_TYPE); + String keystoreType = endpoint.getKeystoreType(); if (keystoreType == null) { keystoreType = defaultKeystoreType; } - String keystoreProvider = - (String) attributes.get( - AbstractEndpoint.SSL_ATTR_KEYSTORE_PROVIDER); - - String trustAlgorithm = - (String)attributes.get( - AbstractEndpoint.SSL_ATTR_TRUSTSTORE_ALGORITHM); + String keystoreProvider = endpoint.getKeystoreProvider(); + + String trustAlgorithm = endpoint.getTruststoreAlgorithm(); if( trustAlgorithm == null ) { trustAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); } @@ -463,27 +449,22 @@ public class JSSESocketFactory SSLContext context = SSLContext.getInstance(protocol); context.init(getKeyManagers(keystoreType, keystoreProvider, algorithm, - (String) attributes.get(AbstractEndpoint.SSL_ATTR_KEY_ALIAS)), + endpoint.getKeyAlias()), getTrustManagers(keystoreType, keystoreProvider, trustAlgorithm), new SecureRandom()); // Configure SSL session cache int sessionCacheSize; - if (attributes.get( - AbstractEndpoint.SSL_ATTR_SESSION_CACHE_SIZE) != null) { + if (endpoint.getSessionCacheSize() != null) { sessionCacheSize = Integer.parseInt( - (String)attributes.get( - AbstractEndpoint.SSL_ATTR_SESSION_CACHE_SIZE)); + endpoint.getSessionCacheSize()); } else { sessionCacheSize = defaultSessionCacheSize; } int sessionTimeout; - if (attributes.get( - AbstractEndpoint.SSL_ATTR_SESSION_TIMEOUT) != null) { - sessionTimeout = Integer.parseInt( - (String)attributes.get( - AbstractEndpoint.SSL_ATTR_SESSION_TIMEOUT)); + if (endpoint.getSessionTimeout() != null) { + sessionTimeout = Integer.parseInt(endpoint.getSessionTimeout()); } else { sessionTimeout = defaultSessionTimeout; } @@ -498,14 +479,12 @@ public class JSSESocketFactory sslProxy = context.getServerSocketFactory(); // Determine which cipher suites to enable - String requestedCiphers = (String)attributes.get( - AbstractEndpoint.SSL_ATTR_CIPHERS); + String requestedCiphers = endpoint.getCiphers(); enabledCiphers = getEnabledCiphers(requestedCiphers, sslProxy.getSupportedCipherSuites()); - allowUnsafeLegacyRenegotiation = - "true".equals(attributes.get( - AbstractEndpoint.SSL_ATTR_ALLOW_UNSAFE_RENEG)); + allowUnsafeLegacyRenegotiation = "true".equals( + endpoint.getAllowUnsafeLegacyRenegotiation()); // Check the SSL config is OK checkConfig(); @@ -559,8 +538,7 @@ public class JSSESocketFactory protected TrustManager[] getTrustManagers(String keystoreType, String keystoreProvider, String algorithm) throws Exception { - String crlf = (String) attributes.get( - AbstractEndpoint.SSL_ATTR_CRL_FILE); + String crlf = endpoint.getCrlFile(); TrustManager[] tms = null; @@ -608,8 +586,7 @@ public class JSSESocketFactory CertStore store = CertStore.getInstance("Collection", csp); xparams.addCertStore(store); xparams.setRevocationEnabled(true); - String trustLength = (String)attributes.get( - AbstractEndpoint.SSL_ATTR_TRUST_MAX_CERT_LENGTH); + String trustLength = endpoint.getTrustMaxCertLength(); if(trustLength != null) { try { xparams.setMaxPathLength(Integer.parseInt(trustLength)); @@ -677,68 +654,36 @@ public class JSSESocketFactory * Determines the SSL protocol variants to be enabled. * * @param socket The socket to get supported list from. - * @param requestedProtocols Comma-separated list of requested SSL - * protocol variants + * @param requestedProtocols Array of requested protocol names all of which + * must be non-null and non-zero length * * @return Array of SSL protocol variants to be enabled, or null if none of * the requested protocol variants are supported */ protected String[] getEnabledProtocols(SSLServerSocket socket, - String requestedProtocols){ + String[] requestedProtocols){ String[] supportedProtocols = socket.getSupportedProtocols(); String[] enabledProtocols = null; - if (requestedProtocols != null) { + if (requestedProtocols != null && requestedProtocols.length > 0) { Vector<String> vec = null; - String protocol = requestedProtocols; - int index = requestedProtocols.indexOf(','); - if (index != -1) { - int fromIndex = 0; - while (index != -1) { - protocol = - requestedProtocols.substring(fromIndex, index).trim(); - if (protocol.length() > 0) { - /* - * Check to see if the requested protocol is among the - * supported protocols, i.e., may be enabled - */ - for (int i=0; supportedProtocols != null - && i<supportedProtocols.length; i++) { - if (supportedProtocols[i].equals(protocol)) { - if (vec == null) { - vec = new Vector<String>(); - } - vec.addElement(protocol); - break; - } - } - } - fromIndex = index+1; - index = requestedProtocols.indexOf(',', fromIndex); - } // while - protocol = requestedProtocols.substring(fromIndex); - } - - if (protocol != null) { - protocol = protocol.trim(); - if (protocol.length() > 0) { - /* - * Check to see if the requested protocol is among the - * supported protocols, i.e., may be enabled - */ - for (int i=0; supportedProtocols != null - && i<supportedProtocols.length; i++) { - if (supportedProtocols[i].equals(protocol)) { - if (vec == null) { - vec = new Vector<String>(); - } - vec.addElement(protocol); - break; + for (String protocol : requestedProtocols) { + /* + * Check to see if the requested protocol is among the supported + * protocols, i.e., may be enabled + */ + for (int i=0; supportedProtocols != null && + i < supportedProtocols.length; i++) { + if (supportedProtocols[i].equals(protocol)) { + if (vec == null) { + vec = new Vector<String>(); } + vec.addElement(protocol); + break; } } - } + } if (vec != null) { enabledProtocols = new String[vec.size()]; @@ -775,7 +720,7 @@ public class JSSESocketFactory socket.setEnabledCipherSuites(enabledCiphers); } - String requestedProtocols = (String) attributes.get("protocols"); + String[] requestedProtocols = endpoint.getSslEnabledProtocolsArray(); setEnabledProtocols(socket, getEnabledProtocols(socket, requestedProtocols)); Modified: tomcat/trunk/webapps/docs/config/http.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/http.xml?rev=1044058&r1=1044057&r2=1044058&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/config/http.xml (original) +++ tomcat/trunk/webapps/docs/config/http.xml Thu Dec 9 18:10:38 2010 @@ -817,7 +817,7 @@ connector uses OpenSSL. Therefore, in addition to using different attributes to configure SSL, the APR/native connector also requires keys and certificates to be provided in a different format.</p> - + <p>The BIO and NIO connectors use the following attributes to configure SSL: </p> @@ -916,8 +916,15 @@ </attribute> <attribute name="sslEnabledProtocols" required="false"> - <p><strong>NIO only</strong>. The version of the SSL protocols to use. If - not specified, the default is "<code>TLSv1,SSLv3,SSLv2Hello</code>".</p> + <p>The list of SSL protocols to use. If not specified, the JVM default is + used.</p> + </attribute> + + <attribute name="sslImplemenationName" required="false"> + <p>The class name of the SSL implementation to use. If not specified, the + default of <code>org.apache.tomcat.util.net.jsse.JSSEImplementation</code> + will be used which wraps JVM's default JSSE provider. Note that the + JVM can be configured to use a different JSSE provider as the default.</p> </attribute> <attribute name="sslProtocol" required="false"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org