This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/main by this push:
     new 49a2799cb3 Add support for jakarta.servlet.request.secure_protocol
49a2799cb3 is described below

commit 49a2799cb3eae3b8a3e8ce6bc5b462394ab36bed
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Nov 23 12:18:56 2023 +0000

    Add support for jakarta.servlet.request.secure_protocol
    
    This request attribute is new in Servlet 6.1. The Tomcat specific
    request attribute org.apache.tomcat.util.net.secure_protocol_version has
    been deprecated and will be removed in Tomcat 12.
---
 java/org/apache/catalina/Globals.java             |  7 +++++++
 java/org/apache/catalina/connector/Request.java   | 11 +++++++----
 java/org/apache/catalina/util/TLSUtil.java        |  2 ++
 java/org/apache/catalina/valves/SSLValve.java     | 14 ++++++++++++++
 java/org/apache/coyote/AbstractProcessor.java     | 12 +++++++-----
 java/org/apache/coyote/ajp/AjpProcessor.java      |  3 +++
 java/org/apache/tomcat/util/net/SSLSupport.java   | 10 ++++++++++
 test/org/apache/catalina/valves/TestSSLValve.java | 11 +++++++++++
 webapps/docs/changelog.xml                        |  6 ++++++
 9 files changed, 67 insertions(+), 9 deletions(-)

diff --git a/java/org/apache/catalina/Globals.java 
b/java/org/apache/catalina/Globals.java
index 0e52e18339..a3c127ecd1 100644
--- a/java/org/apache/catalina/Globals.java
+++ b/java/org/apache/catalina/Globals.java
@@ -129,6 +129,13 @@ public final class Globals {
     public static final String CERTIFICATES_ATTR = 
"jakarta.servlet.request.X509Certificate";
 
 
+    /**
+     * The request attribute under which we store the name of the security 
protocol (e.g. TLSv1.3) being used on a
+     * secured connection (as an object of type {@link String}).
+     */
+    public static final String SECURE_PROTOCOL_ATTR = 
"jakarta.servlet.request.secure_protocol";
+
+
     /**
      * The request attribute under which we store the name of the cipher suite
      * being used on an SSL connection (as an object of type {@link String}).
diff --git a/java/org/apache/catalina/connector/Request.java 
b/java/org/apache/catalina/connector/Request.java
index 7883212a1c..508b279edf 100644
--- a/java/org/apache/catalina/connector/Request.java
+++ b/java/org/apache/catalina/connector/Request.java
@@ -836,6 +836,7 @@ public class Request implements HttpServletRequest {
      *
      * @param name Name of the request attribute to return
      */
+    @SuppressWarnings("deprecation")
     @Override
     public Object getAttribute(String name) {
         // Special attributes
@@ -860,6 +861,11 @@ public class Request implements HttpServletRequest {
             if (attr != null) {
                 attributes.put(Globals.CERTIFICATES_ATTR, attr);
             }
+            attr = coyoteRequest.getAttribute(Globals.SECURE_PROTOCOL_ATTR);
+            if (attr != null) {
+                attributes.put(Globals.SECURE_PROTOCOL_ATTR, attr);
+                attributes.put(SSLSupport.PROTOCOL_VERSION_KEY, attr);
+            }
             attr = coyoteRequest.getAttribute(Globals.CIPHER_SUITE_ATTR);
             if (attr != null) {
                 attributes.put(Globals.CIPHER_SUITE_ATTR, attr);
@@ -876,10 +882,6 @@ public class Request implements HttpServletRequest {
             if (attr != null) {
                 attributes.put(Globals.SSL_SESSION_MGR_ATTR, attr);
             }
-            attr = coyoteRequest.getAttribute(SSLSupport.PROTOCOL_VERSION_KEY);
-            if (attr != null) {
-                attributes.put(SSLSupport.PROTOCOL_VERSION_KEY, attr);
-            }
             attr = 
coyoteRequest.getAttribute(SSLSupport.REQUESTED_PROTOCOL_VERSIONS_KEY);
             if (attr != null) {
                 attributes.put(SSLSupport.REQUESTED_PROTOCOL_VERSIONS_KEY, 
attr);
@@ -911,6 +913,7 @@ public class Request implements HttpServletRequest {
      * <li>{@link Globals#DISPATCHER_REQUEST_PATH_ATTR}</li>
      * <li>{@link Globals#ASYNC_SUPPORTED_ATTR}</li>
      * <li>{@link Globals#CERTIFICATES_ATTR} (SSL connections only)</li>
+     * <li>{@link Globals#SECURE_PROTOCOL_ATTR} (SSL connections only)</li>
      * <li>{@link Globals#CIPHER_SUITE_ATTR} (SSL connections only)</li>
      * <li>{@link Globals#KEY_SIZE_ATTR} (SSL connections only)</li>
      * <li>{@link Globals#SSL_SESSION_ID_ATTR} (SSL connections only)</li>
diff --git a/java/org/apache/catalina/util/TLSUtil.java 
b/java/org/apache/catalina/util/TLSUtil.java
index 7f895ddb8f..43644d9082 100644
--- a/java/org/apache/catalina/util/TLSUtil.java
+++ b/java/org/apache/catalina/util/TLSUtil.java
@@ -32,9 +32,11 @@ public class TLSUtil {
      * @return {@code true} if the attribute is used to pass TLS configuration
      *         information, otherwise {@code false}
      */
+    @SuppressWarnings("deprecation")
     public static boolean isTLSRequestAttribute(String name) {
         switch (name) {
             case Globals.CERTIFICATES_ATTR:
+            case Globals.SECURE_PROTOCOL_ATTR:
             case Globals.CIPHER_SUITE_ATTR:
             case Globals.KEY_SIZE_ATTR:
             case Globals.SSL_SESSION_ID_ATTR:
diff --git a/java/org/apache/catalina/valves/SSLValve.java 
b/java/org/apache/catalina/valves/SSLValve.java
index 2daeb5e0aa..e5a8878339 100644
--- a/java/org/apache/catalina/valves/SSLValve.java
+++ b/java/org/apache/catalina/valves/SSLValve.java
@@ -46,6 +46,7 @@ import org.apache.tomcat.util.buf.UDecoder;
  * <pre>
  * &lt;IfModule ssl_module&gt;
  *   RequestHeader set SSL_CLIENT_CERT "%{SSL_CLIENT_CERT}s"
+ *   RequestHeader set SSL_SECURE_PROTOCOL "%{SSL_PROTOCOL}s"
  *   RequestHeader set SSL_CIPHER "%{SSL_CIPHER}s"
  *   RequestHeader set SSL_SESSION_ID "%{SSL_SESSION_ID}s"
  *   RequestHeader set SSL_CIPHER_USEKEYSIZE "%{SSL_CIPHER_USEKEYSIZE}s"
@@ -67,6 +68,7 @@ public class SSLValve extends ValveBase {
 
     private String sslClientCertHeader = "ssl_client_cert";
     private String sslClientEscapedCertHeader = "ssl_client_escaped_cert";
+    private String sslSecureProtocolHeader = "ssl_secure_protocol";
     private String sslCipherHeader = "ssl_cipher";
     private String sslSessionIdHeader = "ssl_session_id";
     private String sslCipherUserKeySizeHeader = "ssl_cipher_usekeysize";
@@ -93,6 +95,14 @@ public class SSLValve extends ValveBase {
         this.sslClientEscapedCertHeader = sslClientEscapedCertHeader;
     }
 
+    public String getSslSecureProtocolHeader() {
+        return sslSecureProtocolHeader;
+    }
+
+    public void setSslSecureProtocolHeader(String sslSecureProtocolHeader) {
+        this.sslSecureProtocolHeader = sslSecureProtocolHeader;
+    }
+
     public String getSslCipherHeader() {
         return sslCipherHeader;
     }
@@ -178,6 +188,10 @@ public class SSLValve extends ValveBase {
                 request.setAttribute(Globals.CERTIFICATES_ATTR, jsseCerts);
             }
         }
+        headerValue = mygetHeader(request, sslSecureProtocolHeader);
+        if (headerValue != null) {
+            request.setAttribute(Globals.SECURE_PROTOCOL_ATTR, headerValue);
+        }
         headerValue = mygetHeader(request, sslCipherHeader);
         if (headerValue != null) {
             request.setAttribute(Globals.CIPHER_SUITE_ATTR, headerValue);
diff --git a/java/org/apache/coyote/AbstractProcessor.java 
b/java/org/apache/coyote/AbstractProcessor.java
index 4e26dca6e5..6cb85ffee6 100644
--- a/java/org/apache/coyote/AbstractProcessor.java
+++ b/java/org/apache/coyote/AbstractProcessor.java
@@ -764,10 +764,16 @@ public abstract class AbstractProcessor extends 
AbstractProcessorLight implement
      * Populate the TLS related request attributes from the {@link SSLSupport} 
instance associated with this processor.
      * Protocols that populate TLS attributes from a different source (e.g. 
AJP) should override this method.
      */
+    @SuppressWarnings("deprecation")
     protected void populateSslRequestAttributes() {
         try {
             if (sslSupport != null) {
-                Object sslO = sslSupport.getCipherSuite();
+                Object sslO = sslSupport.getProtocol();
+                if (sslO != null) {
+                    request.setAttribute(SSLSupport.SECURE_PROTOCOL_KEY, sslO);
+                    request.setAttribute(SSLSupport.PROTOCOL_VERSION_KEY, 
sslO);
+                }
+                sslO = sslSupport.getCipherSuite();
                 if (sslO != null) {
                     request.setAttribute(SSLSupport.CIPHER_SUITE_KEY, sslO);
                 }
@@ -783,10 +789,6 @@ public abstract class AbstractProcessor extends 
AbstractProcessorLight implement
                 if (sslO != null) {
                     request.setAttribute(SSLSupport.SESSION_ID_KEY, sslO);
                 }
-                sslO = sslSupport.getProtocol();
-                if (sslO != null) {
-                    request.setAttribute(SSLSupport.PROTOCOL_VERSION_KEY, 
sslO);
-                }
                 sslO = sslSupport.getRequestedProtocols();
                 if (sslO != null) {
                     
request.setAttribute(SSLSupport.REQUESTED_PROTOCOL_VERSIONS_KEY, sslO);
diff --git a/java/org/apache/coyote/ajp/AjpProcessor.java 
b/java/org/apache/coyote/ajp/AjpProcessor.java
index ef22da9c68..c8a070b362 100644
--- a/java/org/apache/coyote/ajp/AjpProcessor.java
+++ b/java/org/apache/coyote/ajp/AjpProcessor.java
@@ -132,6 +132,7 @@ public class AjpProcessor extends AbstractProcessor {
 
         // Build Map of Java Servlet to Jakarta Servlet attribute names
         Map<String, String> m = new HashMap<>();
+        m.put("jakarta.servlet.request.secure_protocol", 
"jakarta.servlet.request.secure_protocol");
         m.put("jakarta.servlet.request.cipher_suite", 
"jakarta.servlet.request.cipher_suite");
         m.put("jakarta.servlet.request.key_size", 
"jakarta.servlet.request.key_size");
         m.put("jakarta.servlet.request.ssl_session", 
"jakarta.servlet.request.ssl_session");
@@ -643,6 +644,7 @@ public class AjpProcessor extends AbstractProcessor {
     /**
      * After reading the request headers, we have to setup the request filters.
      */
+    @SuppressWarnings("deprecation")
     private void prepareRequest() {
 
         // Translate the HTTP method code to a String.
@@ -751,6 +753,7 @@ public class AjpProcessor extends AbstractProcessor {
                             // Ignore invalid value
                         }
                     } else if (n.equals(Constants.SC_A_SSL_PROTOCOL)) {
+                        request.setAttribute(SSLSupport.SECURE_PROTOCOL_KEY, 
v);
                         request.setAttribute(SSLSupport.PROTOCOL_VERSION_KEY, 
v);
                     } else if (n.equals("JK_LB_ACTIVATION")) {
                         request.setAttribute(n, v);
diff --git a/java/org/apache/tomcat/util/net/SSLSupport.java 
b/java/org/apache/tomcat/util/net/SSLSupport.java
index d98e205ba4..528df94925 100644
--- a/java/org/apache/tomcat/util/net/SSLSupport.java
+++ b/java/org/apache/tomcat/util/net/SSLSupport.java
@@ -23,6 +23,13 @@ import java.security.cert.X509Certificate;
  * Defines an interface to interact with SSL sessions.
  */
 public interface SSLSupport {
+    /**
+     * The Request attribute key for the cipher suite.
+     */
+    String SECURE_PROTOCOL_KEY =
+            "jakarta.servlet.request.secure_protocol";
+
+
     /**
      * The Request attribute key for the cipher suite.
      */
@@ -57,7 +64,10 @@ public interface SSLSupport {
     /**
      * The request attribute key under which the String indicating the protocol
      * that created the SSL socket is recorded - e.g. TLSv1 or TLSv1.2 etc.
+     *
+     * @deprecated Replaced by {@link #SECURE_PROTOCOL_KEY}. This constant 
will be removed in Tomcat 12.
      */
+    @Deprecated
     String PROTOCOL_VERSION_KEY =
             "org.apache.tomcat.util.net.secure_protocol_version";
 
diff --git a/test/org/apache/catalina/valves/TestSSLValve.java 
b/test/org/apache/catalina/valves/TestSSLValve.java
index 5c7753e1dc..702606e5db 100644
--- a/test/org/apache/catalina/valves/TestSSLValve.java
+++ b/test/org/apache/catalina/valves/TestSSLValve.java
@@ -268,6 +268,17 @@ public class TestSSLValve {
     }
 
 
+    @Test
+    public void testSslSecureProtocolHeaderPresent() throws Exception {
+        String protocol = "secured-with";
+        mockRequest.setHeader(valve.getSslSecureProtocolHeader(), protocol);
+
+        valve.invoke(mockRequest, null);
+
+        Assert.assertEquals(protocol, 
mockRequest.getAttribute(Globals.SECURE_PROTOCOL_ATTR));
+    }
+
+
     @Test
     public void testSslCipherHeaderPresent() throws Exception {
         String cipher = "ciphered-with";
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 9ae058456d..9a7e836924 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -111,6 +111,12 @@
         Background processes should not be run concurrently with lifecycle
         oprations of a container. (remm)
       </fix>
+      <add>
+        Add support for the 
<code>jakarta.servlet.request.secure_protocol</code>
+        request attribute that has been added in Jakarta Servlet 6.1. This
+        replaces the now deprecated Tomcat specific request attribute
+        <code>org.apache.tomcat.util.net.secure_protocol_version</code>. 
(markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Coyote">


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to