You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2005/07/07 15:38:38 UTC
cvs commit: jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11 Http11AprProtocol.java
remm 2005/07/07 06:38:38
Modified: util/java/org/apache/tomcat/util/net AprEndpoint.java
http11/src/java/org/apache/coyote/http11
Http11AprProtocol.java
Log:
- Add basic SSL support (no cert extraction yet).
- Untested.
Revision Changes Path
1.58 +160 -37 jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/AprEndpoint.java
Index: AprEndpoint.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/util/java/org/apache/tomcat/util/net/AprEndpoint.java,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- AprEndpoint.java 3 Jul 2005 10:12:51 -0000 1.57
+++ AprEndpoint.java 7 Jul 2005 13:38:38 -0000 1.58
@@ -31,10 +31,12 @@
import org.apache.tomcat.jni.Pool;
import org.apache.tomcat.jni.Socket;
import org.apache.tomcat.jni.Status;
+import org.apache.tomcat.jni.SSL;
+import org.apache.tomcat.jni.SSLContext;
+import org.apache.tomcat.jni.SSLSocket;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tomcat.util.threads.ThreadWithAttributes;
-
/**
* APR tailored thread pool, providing the following services:
* <ul>
@@ -149,6 +151,12 @@
*/
protected long serverSockPool = 0;
+
+ /**
+ * SSL context.
+ */
+ protected long sslContext = 0;
+
// ------------------------------------------------------------- Properties
@@ -205,7 +213,7 @@
* Handling of accepted sockets.
*/
protected Handler handler = null;
- public void setHandler(Handler handler ) { this.handler=handler; }
+ public void setHandler(Handler handler ) { this.handler = handler; }
public Handler getHandler() { return handler; }
@@ -325,7 +333,104 @@
*/
public int getMinSpareThreads() { return 0; }
+
+ /**
+ * SSL engine.
+ */
+ protected String SSLEngine = "off";
+ public String getSSLEngine() { return SSLEngine; }
+ public void setSSLEngine(String SSLEngine) { this.SSLEngine = SSLEngine; }
+
+
+ /**
+ * SSL password (if a cert is encrypted, and no password has been provided, a callback
+ * will ask for a password).
+ */
+ protected String SSLPassword = null;
+ public String getSSLPassword() { return SSLPassword; }
+ public void setSSLPassword(String SSLPassword) { this.SSLPassword = SSLPassword; }
+
+ /**
+ * SSL cipher suite.
+ */
+ protected String SSLCipherSuite = "ALL";
+ public String getSSLCipherSuite() { return SSLCipherSuite; }
+ public void setSSLCipherSuite(String SSLCipherSuite) { this.SSLCipherSuite = SSLCipherSuite; }
+
+
+ /**
+ * SSL certificate file.
+ */
+ protected String SSLCertificateFile = null;
+ public String getSSLCertificateFile() { return SSLCertificateFile; }
+ public void setSSLCertificateFile(String SSLCertificateFile) { this.SSLCertificateFile = SSLCertificateFile; }
+
+
+ /**
+ * SSL certificate key file.
+ */
+ protected String SSLCertificateKeyFile = null;
+ public String getSSLCertificateKeyFile() { return SSLCertificateKeyFile; }
+ public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { this.SSLCertificateKeyFile = SSLCertificateKeyFile; }
+
+
+ /**
+ * SSL certificate chain file.
+ */
+ protected String SSLCertificateChainFile = null;
+ public String getSSLCertificateChainFile() { return SSLCertificateChainFile; }
+ public void setSSLCertificateChainFile(String SSLCertificateChainFile) { this.SSLCertificateChainFile = SSLCertificateChainFile; }
+
+
+ /**
+ * SSL CA certificate path.
+ */
+ protected String SSLCACertificatePath = null;
+ public String getSSLCACertificatePath() { return SSLCACertificatePath; }
+ public void setSSLCACertificatePath(String SSLCACertificatePath) { this.SSLCACertificatePath = SSLCACertificatePath; }
+
+
+ /**
+ * SSL CA certificate file.
+ */
+ protected String SSLCACertificateFile = null;
+ public String getSSLCACertificateFile() { return SSLCACertificateFile; }
+ public void setSSLCACertificateFile(String SSLCACertificateFile) { this.SSLCACertificateFile = SSLCACertificateFile; }
+
+
+ /**
+ * SSL CA revocation path.
+ */
+ protected String SSLCARevocationPath = null;
+ public String getSSLCARevocationPath() { return SSLCARevocationPath; }
+ public void setSSLCARevocationPath(String SSLCARevocationPath) { this.SSLCARevocationPath = SSLCARevocationPath; }
+
+
+ /**
+ * SSL CA revocation file.
+ */
+ protected String SSLCARevocationFile = null;
+ public String getSSLCARevocationFile() { return SSLCARevocationFile; }
+ public void setSSLCARevocationFile(String SSLCARevocationFile) { this.SSLCARevocationFile = SSLCARevocationFile; }
+
+
+ /**
+ * SSL verify client.
+ */
+ protected boolean SSLVerifyClient = false;
+ public boolean getSSLVerifyClient() { return SSLVerifyClient; }
+ public void setSSLVerifyClient(boolean SSLVerifyClient) { this.SSLVerifyClient = SSLVerifyClient; }
+
+
+ /**
+ * SSL verify depth.
+ */
+ protected int SSLVerifyDepth = 10;
+ public int getSSLVerifyDepth() { return SSLVerifyDepth; }
+ public void setSSLVerifyDepth(int SSLVerifyDepth) { this.SSLVerifyDepth = SSLVerifyDepth; }
+
+
// --------------------------------------------------------- Public Methods
@@ -411,8 +516,32 @@
// Delay accepting of new connections until data is available
// Only Linux kernels 2.4 + have that implemented
// on other platforms this call is noop and will return APR_ENOTIMPL.
- Socket.optSet(serverSock, Socket.APR_TCP_DEFER_ACCEPT, 1);
-
+ Socket.optSet(serverSock, Socket.APR_TCP_DEFER_ACCEPT, 1);
+
+ // Initialize SSL if needed
+ if (!"off".equalsIgnoreCase(SSLEngine)) {
+ // Initialize SSL
+ // FIXME: one per VM call ?
+ if ("on".equalsIgnoreCase(SSLEngine)) {
+ SSL.initialize(null);
+ } else {
+ SSL.initialize(SSLEngine);
+ }
+ // Create SSL Context
+ sslContext = SSLContext.make(rootPool, SSL.SSL_PROTOCOL_SSLV2 | SSL.SSL_PROTOCOL_SSLV3, SSL.SSL_MODE_SERVER);
+ // List the ciphers that the client is permitted to negotiate
+ SSLContext.setCipherSuite(sslContext, SSLCipherSuite);
+ // Load Server key and certificate
+ SSLContext.setCertificate(sslContext, SSLCertificateFile, SSLCertificateKeyFile, SSLPassword, SSL.SSL_AIDX_RSA);
+ // Support Client Certificates
+ SSLContext.setVerify(sslContext, SSLVerifyClient ? 1 : 0, SSLVerifyDepth);
+ if (SSLCACertificateFile != null) {
+ SSLContext.setCACertificate(sslContext, SSLCACertificateFile, null);
+ }
+ // For now, sendfile is not supported with SSL
+ useSendfile = false;
+ }
+
initialized = true;
}
@@ -509,6 +638,7 @@
serverSockPool = 0;
// Close server socket
Socket.close(serverSock);
+ sslContext = 0;
// Close all APR memory pools and resources
Pool.destroy(rootPool);
rootPool = 0;
@@ -559,44 +689,32 @@
/**
- * Set options on a newly accepted socket.
- *
- * @param socket "pointer" to the accepted socket
- */
- protected void setSocketOptions(long socket) {
- if (soLinger >= 0)
- Socket.optSet(socket, Socket.APR_SO_LINGER, soLinger);
- if (tcpNoDelay)
- Socket.optSet(socket, Socket.APR_TCP_NODELAY, (tcpNoDelay ? 1 : 0));
- if (soTimeout > 0)
- Socket.timeoutSet(socket, soTimeout * 1000);
- }
-
-
- /**
* Process the specified connection.
*/
- protected boolean processSocket(long socket) {
+ protected boolean setSocketOptions(long socket) {
// Process the connection
int step = 1;
- boolean result = true;
try {
// 1: Set socket options: timeout, linger, etc
- setSocketOptions(socket);
+ if (soLinger >= 0)
+ Socket.optSet(socket, Socket.APR_SO_LINGER, soLinger);
+ if (tcpNoDelay)
+ Socket.optSet(socket, Socket.APR_TCP_NODELAY, (tcpNoDelay ? 1 : 0));
+ if (soTimeout > 0)
+ Socket.timeoutSet(socket, soTimeout * 1000);
// 2: SSL handshake
step = 2;
- // FIXME: SSL implementation so that Bill is happy
- /*
- if (getServerSocketFactory() != null) {
- getServerSocketFactory().handshake(s);
- }
- */
-
- // 3: Process the connection
- step = 3;
- result = getHandler().process(socket);
+ if (sslContext != 0) {
+ SSLSocket.attach(sslContext, socket);
+ if (SSLSocket.handshake(socket) != 0) {
+ if (log.isDebugEnabled()) {
+ log.debug(sm.getString("endpoint.err.handshake") + ": " + SSL.getLastError());
+ }
+ return false;
+ }
+ }
} catch (Throwable t) {
if (step == 2) {
@@ -607,9 +725,9 @@
log.error(sm.getString("endpoint.err.unexpected"), t);
}
// Tell to close the socket
- result = false;
+ return false;
}
- return result;
+ return true;
}
@@ -723,7 +841,12 @@
try {
long socket = Socket.accept(serverSock);
// Hand this socket off to an appropriate processor
- workerThread.assign(socket);
+ if (setSocketOptions(socket)) {
+ workerThread.assign(socket);
+ } else {
+ // Close socket and pool right away
+ Socket.destroy(socket);
+ }
} catch (Exception e) {
log.error(sm.getString("endpoint.accept.fail"), e);
}
@@ -1011,7 +1134,7 @@
continue;
// Process the request from this socket
- if (!processSocket(socket)) {
+ if (!handler.process(socket)) {
// Close socket and pool
Socket.destroy(socket);
socket = 0;
@@ -1289,7 +1412,7 @@
} else {
// Close the socket since this is
// the end of not keep-alive request.
- Socket.destroy(state.socket);
+ Socket.destroy(state.socket);
}
}
}
1.12 +84 -166 jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11AprProtocol.java
Index: Http11AprProtocol.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-connectors/http11/src/java/org/apache/coyote/http11/Http11AprProtocol.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- Http11AprProtocol.java 27 Jun 2005 13:44:04 -0000 1.11
+++ Http11AprProtocol.java 7 Jul 2005 13:38:38 -0000 1.12
@@ -18,7 +18,6 @@
import java.net.InetAddress;
import java.net.URLEncoder;
-import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
@@ -34,8 +33,6 @@
import org.apache.coyote.RequestGroupInfo;
import org.apache.coyote.RequestInfo;
import org.apache.tomcat.util.net.AprEndpoint;
-import org.apache.tomcat.util.net.SSLImplementation;
-import org.apache.tomcat.util.net.ServerSocketFactory;
import org.apache.tomcat.util.net.AprEndpoint.Handler;
import org.apache.tomcat.util.res.StringManager;
@@ -113,24 +110,7 @@
public void init() throws Exception {
ep.setName(getName());
ep.setHandler(cHandler);
- try {
- checkSocketFactory();
- } catch( Exception ex ) {
- log.error(sm.getString("http11protocol.socketfactory.initerror"),
- ex);
- throw ex;
- }
- if( socketFactory!=null ) {
- Enumeration attE=attributes.keys();
- while( attE.hasMoreElements() ) {
- String key=(String)attE.nextElement();
- Object v=attributes.get( key );
- socketFactory.setAttribute( key, v );
- }
- }
-
- // XXX get domain from registration
try {
ep.init();
} catch (Exception ex) {
@@ -148,8 +128,6 @@
public void start() throws Exception {
if( this.domain != null ) {
try {
- // XXX We should be able to configure it separately
- // XXX It should be possible to use a single TP
tpOname=new ObjectName
(domain + ":" + "type=ThreadPool,name=" + getName());
Registry.getRegistry(null, null)
@@ -209,18 +187,13 @@
protected AprEndpoint ep=new AprEndpoint();
protected boolean secure;
- protected ServerSocketFactory socketFactory;
- protected SSLImplementation sslImplementation;
// socket factory attriubtes ( XXX replace with normal setters )
protected Hashtable attributes = new Hashtable();
- protected String socketFactoryName=null;
- protected String sslImplementationName=null;
private int maxKeepAliveRequests=100; // as in Apache HTTPD server
private int timeout = 300000; // 5 minutes as in Apache HTTPD server
private int maxSavePostSize = 4 * 1024;
private int maxHttpHeaderSize = 4 * 1024;
- private String reportedname;
private int socketCloseDelay=-1;
private boolean disableUploadTimeout = true;
private int socketBuffer = 9000;
@@ -342,25 +315,6 @@
return ("http-" + encodedAddr + ep.getPort());
}
- public String getSocketFactory() {
- return socketFactoryName;
- }
-
- public void setSocketFactory( String valueS ) {
- socketFactoryName = valueS;
- setAttribute("socketFactory", valueS);
- }
-
- public String getSSLImplementation() {
- return sslImplementationName;
- }
-
- public void setSSLImplementation( String valueS) {
- sslImplementationName = valueS;
- setSecure(true);
- setAttribute("sslImplementation", valueS);
- }
-
public boolean getTcpNoDelay() {
return ep.getTcpNoDelay();
}
@@ -467,50 +421,6 @@
setAttribute("soTimeout", "" + i);
}
- /*
- public int getServerSoTimeout() {
- return ep.getServerSoTimeout();
- }
-
- public void setServerSoTimeout( int i ) {
- ep.setServerSoTimeout(i);
- setAttribute("serverSoTimeout", "" + i);
- }
- */
-
- public String getKeystore() {
- return getProperty("keystore");
- }
-
- public void setKeystore( String k ) {
- setAttribute("keystore", k);
- }
-
- public String getKeypass() {
- return getProperty("keypass");
- }
-
- public void setKeypass( String k ) {
- attributes.put("keypass", k);
- //setAttribute("keypass", k);
- }
-
- public String getKeytype() {
- return getProperty("keystoreType");
- }
-
- public void setKeytype( String k ) {
- setAttribute("keystoreType", k);
- }
-
- public String getClientauth() {
- return getProperty("clientauth");
- }
-
- public void setClientauth( String k ) {
- setAttribute("clientauth", k);
- }
-
public String getProtocol() {
return getProperty("protocol");
}
@@ -520,22 +430,6 @@
setAttribute("protocol", k);
}
- public String getProtocols() {
- return getProperty("protocols");
- }
-
- public void setProtocols(String k) {
- setAttribute("protocols", k);
- }
-
- public String getAlgorithm() {
- return getProperty("algorithm");
- }
-
- public void setAlgorithm( String k ) {
- setAttribute("algorithm", k);
- }
-
public boolean getSecure() {
return secure;
}
@@ -545,22 +439,6 @@
setAttribute("secure", "" + b);
}
- public String getCiphers() {
- return getProperty("ciphers");
- }
-
- public void setCiphers(String ciphers) {
- setAttribute("ciphers", ciphers);
- }
-
- public String getKeyAlias() {
- return getProperty("keyAlias");
- }
-
- public void setKeyAlias(String keyAlias) {
- setAttribute("keyAlias", keyAlias);
- }
-
public int getMaxKeepAliveRequests() {
return maxKeepAliveRequests;
}
@@ -605,14 +483,6 @@
return server;
}
-
- private static ServerSocketFactory string2SocketFactory( String val)
- throws ClassNotFoundException, IllegalAccessException,
- InstantiationException {
- Class chC=Class.forName( val );
- return (ServerSocketFactory)chC.newInstance();
- }
-
public int getTimeout() {
return timeout;
}
@@ -622,13 +492,91 @@
setAttribute("timeout", "" + timeouts);
}
- public String getReportedname() {
- return reportedname;
- }
+ // -------------------- SSL related properties --------------------
- public void setReportedname( String reportedName) {
- reportedname = reportedName;
- }
+ /**
+ * SSL engine.
+ */
+ public String getSSLEngine() { return ep.getSSLEngine(); }
+ public void setSSLEngine(String SSLEngine) { ep.setSSLEngine(SSLEngine); }
+
+
+ /**
+ * SSL password (if a cert is encrypted, and no password has been provided, a callback
+ * will ask for a password).
+ */
+ public String getSSLPassword() { return ep.getSSLPassword(); }
+ public void setSSLPassword(String SSLPassword) { ep.setSSLPassword(SSLPassword); }
+
+
+ /**
+ * SSL cipher suite.
+ */
+ public String getSSLCipherSuite() { return ep.getSSLCipherSuite(); }
+ public void setSSLCipherSuite(String SSLCipherSuite) { ep.setSSLCipherSuite(SSLCipherSuite); }
+
+
+ /**
+ * SSL certificate file.
+ */
+ public String getSSLCertificateFile() { return ep.getSSLCertificateFile(); }
+ public void setSSLCertificateFile(String SSLCertificateFile) { ep.setSSLCertificateFile(SSLCertificateFile); }
+
+
+ /**
+ * SSL certificate key file.
+ */
+ public String getSSLCertificateKeyFile() { return ep.getSSLCertificateKeyFile(); }
+ public void setSSLCertificateKeyFile(String SSLCertificateKeyFile) { ep.setSSLCertificateKeyFile(SSLCertificateKeyFile); }
+
+
+ /**
+ * SSL certificate chain file.
+ */
+ public String getSSLCertificateChainFile() { return ep.getSSLCertificateChainFile(); }
+ public void setSSLCertificateChainFile(String SSLCertificateChainFile) { ep.setSSLCertificateChainFile(SSLCertificateChainFile); }
+
+
+ /**
+ * SSL CA certificate path.
+ */
+ public String getSSLCACertificatePath() { return ep.getSSLCACertificatePath(); }
+ public void setSSLCACertificatePath(String SSLCACertificatePath) { ep.setSSLCACertificatePath(SSLCACertificatePath); }
+
+
+ /**
+ * SSL CA certificate file.
+ */
+ public String getSSLCACertificateFile() { return ep.getSSLCACertificateFile(); }
+ public void setSSLCACertificateFile(String SSLCACertificateFile) { ep.setSSLCACertificateFile(SSLCACertificateFile); }
+
+
+ /**
+ * SSL CA revocation path.
+ */
+ public String getSSLCARevocationPath() { return ep.getSSLCARevocationPath(); }
+ public void setSSLCARevocationPath(String SSLCARevocationPath) { ep.setSSLCARevocationPath(SSLCARevocationPath); }
+
+
+ /**
+ * SSL CA revocation file.
+ */
+ public String getSSLCARevocationFile() { return ep.getSSLCARevocationFile(); }
+ public void setSSLCARevocationFile(String SSLCARevocationFile) { ep.setSSLCARevocationFile(SSLCARevocationFile); }
+
+
+ /**
+ * SSL verify client.
+ */
+ public boolean getSSLVerifyClient() { return ep.getSSLVerifyClient(); }
+ public void setSSLVerifyClient(boolean SSLVerifyClient) { ep.setSSLVerifyClient(SSLVerifyClient); }
+
+
+ /**
+ * SSL verify depth.
+ */
+ public int getSSLVerifyDepth() { return ep.getSSLVerifyDepth(); }
+ public void setSSLVerifyDepth(int SSLVerifyDepth) { ep.setSSLVerifyDepth(SSLVerifyDepth); }
// -------------------- Connection handler --------------------
@@ -734,36 +682,6 @@
// -------------------- Various implementation classes --------------------
- /** Sanity check and socketFactory setup.
- * IMHO it is better to stop the show on a broken connector,
- * then leave Tomcat running and broken.
- * @exception TomcatException Unable to resolve classes
- */
- private void checkSocketFactory() throws Exception {
- /*
- if (secure) {
- try {
- // The SSL setup code has been moved into
- // SSLImplementation since SocketFactory doesn't
- // provide a wide enough interface
- sslImplementation =
- SSLImplementation.getInstance(sslImplementationName);
- socketFactory = sslImplementation.getServerSocketFactory();
- ep.setServerSocketFactory(socketFactory);
- } catch (ClassNotFoundException e){
- throw e;
- }
- } else if (socketFactoryName != null) {
- try {
- socketFactory = string2SocketFactory(socketFactoryName);
- ep.setServerSocketFactory(socketFactory);
- } catch(Exception sfex) {
- throw sfex;
- }
- }
- */
- }
-
protected String domain;
protected ObjectName oname;
protected MBeanServer mserver;
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org