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 <[email protected]>
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>
* <IfModule ssl_module>
* 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: [email protected]
For additional commands, e-mail: [email protected]