Author: markt Date: Thu Sep 4 13:12:55 2014 New Revision: 1622470 URL: http://svn.apache.org/r1622470 Log: Correct the previous fix for bug 56825 that enabled pre-emptive authentication to work with the SSL authenticator. An SSL handshake is now triggered if: - premetive authentication is enabled; - CLIENT-CERT is being used; and - the previous handshake did not include a client cert
Modified: tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java tomcat/trunk/test/org/apache/tomcat/util/net/TestClientCert.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java?rev=1622470&r1=1622469&r2=1622470&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/AuthenticatorBase.java Thu Sep 4 13:12:55 2014 @@ -25,6 +25,7 @@ import java.util.Locale; import javax.servlet.ServletException; import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.catalina.Authenticator; @@ -567,8 +568,9 @@ public abstract class AuthenticatorBase "authorization") != null; } - if (!authRequired && context.getPreemptiveAuthentication()) { - X509Certificate[] certs = getRequestCertificates(request, false); + if (!authRequired && context.getPreemptiveAuthentication() && + HttpServletRequest.CLIENT_CERT_AUTH.equals(getAuthMethod())) { + X509Certificate[] certs = getRequestCertificates(request); authRequired = certs != null && certs.length > 0; } @@ -626,13 +628,11 @@ public abstract class AuthenticatorBase * extracting the certificate chain from the Coyote request. * * @param request Request to be processed - * @param force Should a renegotiation be forced to request certificates - * from the user agent if none have been provided * * @return The X509 certificate chain if found, <code>null</code> * otherwise. */ - protected X509Certificate[] getRequestCertificates(final Request request, boolean force) + protected X509Certificate[] getRequestCertificates(final Request request) throws IllegalStateException { X509Certificate certs[] = @@ -640,7 +640,7 @@ public abstract class AuthenticatorBase if ((certs == null) || (certs.length < 1)) { try { - request.getCoyoteRequest().action(ActionCode.REQ_SSL_CERTIFICATE, Boolean.valueOf(force)); + request.getCoyoteRequest().action(ActionCode.REQ_SSL_CERTIFICATE, null); certs = (X509Certificate[]) request.getAttribute(Globals.CERTIFICATES_ATTR); } catch (IllegalStateException ise) { // Request body was too large for save buffer Modified: tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java?rev=1622470&r1=1622469&r2=1622470&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java (original) +++ tomcat/trunk/java/org/apache/catalina/authenticator/SSLAuthenticator.java Thu Sep 4 13:12:55 2014 @@ -95,7 +95,7 @@ public class SSLAuthenticator extends Au containerLog.debug(" Looking up certificates"); } - X509Certificate certs[] = getRequestCertificates(request, true); + X509Certificate certs[] = getRequestCertificates(request); if ((certs == null) || (certs.length < 1)) { if (containerLog.isDebugEnabled()) { Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java?rev=1622470&r1=1622469&r2=1622470&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11AprProcessor.java Thu Sep 4 13:12:55 2014 @@ -419,26 +419,18 @@ public class Http11AprProcessor extends } case REQ_SSL_CERTIFICATE: { if (endpoint.isSSLEnabled() && (socketRef != 0)) { - boolean force = ((Boolean) param).booleanValue(); - if (force) { - /* Forced triggers a handshake so consume and buffer the - * request body, so that it does not interfere with the - * client's handshake messages - */ - InputFilter[] inputFilters = inputBuffer.getFilters(); - ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]) - .setLimit(maxSavePostSize); - inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]); - } + // Consume and buffer the request body, so that it does not + // interfere with the client's handshake messages + InputFilter[] inputFilters = inputBuffer.getFilters(); + ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]).setLimit(maxSavePostSize); + inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]); try { - if (force) { - // Configure connection to require a certificate - SSLSocket.setVerify(socketRef, SSL.SSL_CVERIFY_REQUIRE, - ((AprEndpoint)endpoint).getSSLVerifyDepth()); - } - if (!force || SSLSocket.renegotiate(socketRef) == 0) { - // Only look for certs if not forcing a renegotiation or - // if we know renegotiation worked. + // Configure connection to require a certificate + SSLSocket.setVerify(socketRef, SSL.SSL_CVERIFY_REQUIRE, + ((AprEndpoint)endpoint).getSSLVerifyDepth()); + // Renegotiate certificates + if (SSLSocket.renegotiate(socketRef) == 0) { + // Don't look for certs unless we know renegotiation worked. // Get client certificate and the certificate chain if present // certLength == -1 indicates an error int certLength = SSLSocket.getInfoI(socketRef,SSL.SSL_INFO_CLIENT_CERT_CHAIN); Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java?rev=1622470&r1=1622469&r2=1622470&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Nio2Processor.java Thu Sep 4 13:12:55 2014 @@ -465,20 +465,18 @@ public class Http11Nio2Processor extends } case REQ_SSL_CERTIFICATE: { if (sslSupport != null && socketWrapper.getSocket() != null) { - boolean force = ((Boolean) param).booleanValue(); - if (force) { - /* Forced triggers a handshake so consume and buffer the - * request body, so that it does not interfere with the - * client's handshake messages - */ - InputFilter[] inputFilters = inputBuffer.getFilters(); - ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]) - .setLimit(maxSavePostSize); - inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]); - } + /* + * Consume and buffer the request body, so that it does not + * interfere with the client's handshake messages + */ + InputFilter[] inputFilters = inputBuffer.getFilters(); + ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]) + .setLimit(maxSavePostSize); + inputBuffer.addActiveFilter + (inputFilters[Constants.BUFFERED_FILTER]); SecureNio2Channel sslChannel = (SecureNio2Channel) socketWrapper.getSocket(); SSLEngine engine = sslChannel.getSslEngine(); - if (!engine.getNeedClientAuth() && force) { + if (!engine.getNeedClientAuth()) { // Need to re-negotiate SSL connection engine.setNeedClientAuth(true); try { @@ -495,8 +493,9 @@ public class Http11Nio2Processor extends // use force=false since re-negotiation is handled above // (and it is a NO-OP for NIO anyway) Object sslO = sslSupport.getPeerCertificateChain(false); - if (sslO != null) { - request.setAttribute(SSLSupport.CERTIFICATE_KEY, sslO); + if( sslO != null) { + request.setAttribute + (SSLSupport.CERTIFICATE_KEY, sslO); } } catch (Exception e) { log.warn(sm.getString("http11processor.socket.ssl"), e); Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java?rev=1622470&r1=1622469&r2=1622470&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11NioProcessor.java Thu Sep 4 13:12:55 2014 @@ -434,20 +434,18 @@ public class Http11NioProcessor extends } case REQ_SSL_CERTIFICATE: { if (sslSupport != null) { - boolean force = ((Boolean) param).booleanValue(); - if (force) { - /* Forced triggers a handshake so consume and buffer the - * request body, so that it does not interfere with the - * client's handshake messages - */ - InputFilter[] inputFilters = inputBuffer.getFilters(); - ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]) - .setLimit(maxSavePostSize); - inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]); - } + /* + * Consume and buffer the request body, so that it does not + * interfere with the client's handshake messages + */ + InputFilter[] inputFilters = inputBuffer.getFilters(); + ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]) + .setLimit(maxSavePostSize); + inputBuffer.addActiveFilter + (inputFilters[Constants.BUFFERED_FILTER]); SecureNioChannel sslChannel = (SecureNioChannel) socketWrapper.getSocket(); SSLEngine engine = sslChannel.getSslEngine(); - if (!engine.getNeedClientAuth() && force) { + if (!engine.getNeedClientAuth()) { // Need to re-negotiate SSL connection engine.setNeedClientAuth(true); try { @@ -464,8 +462,9 @@ public class Http11NioProcessor extends // use force=false since re-negotiation is handled above // (and it is a NO-OP for NIO anyway) Object sslO = sslSupport.getPeerCertificateChain(false); - if (sslO != null) { - request.setAttribute(SSLSupport.CERTIFICATE_KEY, sslO); + if( sslO != null) { + request.setAttribute + (SSLSupport.CERTIFICATE_KEY, sslO); } } catch (Exception e) { log.warn(sm.getString("http11processor.socket.ssl"), e); Modified: tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java?rev=1622470&r1=1622469&r2=1622470&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/Http11Processor.java Thu Sep 4 13:12:55 2014 @@ -350,19 +350,17 @@ public class Http11Processor extends Abs } case REQ_SSL_CERTIFICATE: { if (sslSupport != null) { - boolean force = ((Boolean) param).booleanValue(); - if (force) { - /* Forced triggers a handshake so consume and buffer the - * request body, so that it does not interfere with the - * client's handshake messages - */ - InputFilter[] inputFilters = inputBuffer.getFilters(); - ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]) - .setLimit(maxSavePostSize); - inputBuffer.addActiveFilter(inputFilters[Constants.BUFFERED_FILTER]); - } + /* + * Consume and buffer the request body, so that it does not + * interfere with the client's handshake messages + */ + InputFilter[] inputFilters = inputBuffer.getFilters(); + ((BufferedInputFilter) inputFilters[Constants.BUFFERED_FILTER]) + .setLimit(maxSavePostSize); + inputBuffer.addActiveFilter + (inputFilters[Constants.BUFFERED_FILTER]); try { - Object sslO = sslSupport.getPeerCertificateChain(force); + Object sslO = sslSupport.getPeerCertificateChain(true); if( sslO != null) { request.setAttribute (SSLSupport.CERTIFICATE_KEY, sslO); Modified: tomcat/trunk/test/org/apache/tomcat/util/net/TestClientCert.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/net/TestClientCert.java?rev=1622470&r1=1622469&r2=1622470&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/net/TestClientCert.java (original) +++ tomcat/trunk/test/org/apache/tomcat/util/net/TestClientCert.java Thu Sep 4 13:12:55 2014 @@ -55,10 +55,6 @@ public class TestClientCert extends Tomc Context c = (Context) tomcat.getHost().findChildren()[0]; // Enable pre-emptive auth c.setPreemptiveAuthentication(true); - - // Connector needs to advertise is accepts client certs for - // pre-emptive to work - tomcat.getConnector().setAttribute("clientAuth", "want"); } getTomcatInstance().start(); Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1622470&r1=1622469&r2=1622470&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Thu Sep 4 13:12:55 2014 @@ -102,6 +102,10 @@ Fix some potential resource leaks when reading properties, files and other resources. Reported by Coverity Scan. (violetagg) </fix> + <fix> + Correct the previous fix for <bug>56825</bug> that enabled pre-emptive + authentication to work with the SSL authenticator. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org