This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 11.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/11.0.x by this push:
new ac7a8b00eb Fix BZ 68947 - remove remaining references to removed
package
ac7a8b00eb is described below
commit ac7a8b00eb50838300a40f9ca65abce60f39bdc3
Author: Mark Thomas <[email protected]>
AuthorDate: Wed Oct 8 15:44:08 2025 +0100
Fix BZ 68947 - remove remaining references to removed package
https://bz.apache.org/bugzilla/show_bug.cgi?id=69847
---
modules/stuffed/tomcat-resource.json | 1 -
res/bnd/tomcat-embed-core.jar.tmp.bnd | 1 -
res/bnd/tomcat-util.jar.tmp.bnd | 1 -
.../native-image/resource-config.json | 1 -
.../native-image/resource-config.json | 1 -
.../authenticator/TestSSOChangeSessionId.java | 269 +++++++++++++++++++++
webapps/docs/changelog.xml | 9 +
7 files changed, 278 insertions(+), 5 deletions(-)
diff --git a/modules/stuffed/tomcat-resource.json
b/modules/stuffed/tomcat-resource.json
index ff0c539734..0edb46a322 100644
--- a/modules/stuffed/tomcat-resource.json
+++ b/modules/stuffed/tomcat-resource.json
@@ -53,7 +53,6 @@
{"name":"org.apache.tomcat.dbcp.dbcp2.LocalStrings"},
{"name":"org.apache.tomcat.util.LocalStrings"},
{"name":"org.apache.tomcat.util.buf.LocalStrings"},
- {"name":"org.apache.tomcat.util.codec.binary.LocalStrings"},
{"name":"org.apache.tomcat.util.compat.LocalStrings"},
{"name":"org.apache.tomcat.util.descriptor.LocalStrings"},
{"name":"org.apache.tomcat.util.descriptor.tld.LocalStrings"},
diff --git a/res/bnd/tomcat-embed-core.jar.tmp.bnd
b/res/bnd/tomcat-embed-core.jar.tmp.bnd
index 77d285b6d7..570cacfb31 100644
--- a/res/bnd/tomcat-embed-core.jar.tmp.bnd
+++ b/res/bnd/tomcat-embed-core.jar.tmp.bnd
@@ -61,7 +61,6 @@ Export-Package: \
org.apache.tomcat.util,\
org.apache.tomcat.util.bcel.classfile,\
org.apache.tomcat.util.buf,\
- org.apache.tomcat.util.codec.binary,\
org.apache.tomcat.util.collections,\
org.apache.tomcat.util.compat,\
org.apache.tomcat.util.concurrent,\
diff --git a/res/bnd/tomcat-util.jar.tmp.bnd b/res/bnd/tomcat-util.jar.tmp.bnd
index 458231a52c..b837c81ac8 100644
--- a/res/bnd/tomcat-util.jar.tmp.bnd
+++ b/res/bnd/tomcat-util.jar.tmp.bnd
@@ -20,7 +20,6 @@ Bundle-SymbolicName: org.apache.tomcat-util
Export-Package: \
org.apache.tomcat.util,\
org.apache.tomcat.util.buf,\
- org.apache.tomcat.util.codec.binary,\
org.apache.tomcat.util.collections,\
org.apache.tomcat.util.compat,\
org.apache.tomcat.util.concurrent,\
diff --git a/res/graal/tomcat-embed-core/native-image/resource-config.json
b/res/graal/tomcat-embed-core/native-image/resource-config.json
index ee0f815bcc..9081bf9e23 100644
--- a/res/graal/tomcat-embed-core/native-image/resource-config.json
+++ b/res/graal/tomcat-embed-core/native-image/resource-config.json
@@ -32,7 +32,6 @@
{"name":"org.apache.naming.factory.LocalStrings"},
{"name":"org.apache.tomcat.util.LocalStrings"},
{"name":"org.apache.tomcat.util.buf.LocalStrings"},
- {"name":"org.apache.tomcat.util.codec.binary.LocalStrings"},
{"name":"org.apache.tomcat.util.compat.LocalStrings"},
{"name":"org.apache.tomcat.util.descriptor.LocalStrings"},
{"name":"org.apache.tomcat.util.descriptor.web.LocalStrings"},
diff --git
a/res/graal/tomcat-embed-programmatic/native-image/resource-config.json
b/res/graal/tomcat-embed-programmatic/native-image/resource-config.json
index ea7243d531..7e6f6795f5 100644
--- a/res/graal/tomcat-embed-programmatic/native-image/resource-config.json
+++ b/res/graal/tomcat-embed-programmatic/native-image/resource-config.json
@@ -25,7 +25,6 @@
{"name":"org.apache.naming.factory.LocalStrings"},
{"name":"org.apache.tomcat.util.LocalStrings"},
{"name":"org.apache.tomcat.util.buf.LocalStrings"},
- {"name":"org.apache.tomcat.util.codec.binary.LocalStrings"},
{"name":"org.apache.tomcat.util.compat.LocalStrings"},
{"name":"org.apache.tomcat.util.http.LocalStrings"},
{"name":"org.apache.tomcat.util.http.parser.LocalStrings"},
diff --git a/test/org/apache/catalina/authenticator/TestSSOChangeSessionId.java
b/test/org/apache/catalina/authenticator/TestSSOChangeSessionId.java
new file mode 100644
index 0000000000..a2165f1490
--- /dev/null
+++ b/test/org/apache/catalina/authenticator/TestSSOChangeSessionId.java
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.authenticator;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jakarta.servlet.ServletException;
+import jakarta.servlet.http.HttpServlet;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Manager;
+import org.apache.catalina.Session;
+import org.apache.catalina.connector.Request;
+import org.apache.catalina.connector.Response;
+import org.apache.catalina.startup.TesterServlet;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.catalina.startup.TomcatBaseTest;
+import org.apache.catalina.valves.ValveBase;
+import org.apache.tomcat.util.buf.ByteChunk;
+import org.apache.tomcat.util.descriptor.web.LoginConfig;
+import org.apache.tomcat.util.descriptor.web.SecurityCollection;
+import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
+
+public class TestSSOChangeSessionId extends TomcatBaseTest {
+
+ protected static final boolean USE_COOKIES = true;
+
+ private static final String NOTSORANDOMID = "NOTSORANNDOMID";
+ private static final String USER = "user";
+ private static final String PWD = "pwd";
+ private static final String ROLE = "role";
+
+ private static final String HTTP_PREFIX = "http://localhost:";
+ private static final String CONTEXT_PATH = "/test";
+ private static final String URI_PROTECTED = "/protected";
+ private static final String URI_AUTHENTICATION = "/authentication";
+
+ private Context testContext;
+ private SingleSignOn singleSignOn;
+
+ private static final String SERVER_COOKIE_HEADER = "Set-Cookie";
+ private static final String CLIENT_COOKIE_HEADER = "Cookie";
+
+ private List<String> cookies;
+
+ /*
+ * setup two webapps for every test
+ *
+ * note: the super class tearDown method will stop tomcat
+ */
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+
+ // create a tomcat server using the default in-memory Realm
+ final Tomcat tomcat = getTomcatInstance();
+
+ // Must have a real docBase for webapps - just use temp
+ testContext = tomcat.addContext(CONTEXT_PATH,
System.getProperty("java.io.tmpdir"));
+
+ singleSignOn = new SingleSignOn();
+ tomcat.getHost().getPipeline().addValve(singleSignOn);
+
+ testContext.getPipeline().addValve(new SessionManipulationFilter());
+
+ // Add protected servlet to the context
+ Tomcat.addServlet(testContext, "TesterServlet1", new TesterServlet());
+ testContext.addServletMappingDecoded(URI_PROTECTED, "TesterServlet1");
+
+ SecurityCollection collection1 = new SecurityCollection();
+ collection1.addPatternDecoded(URI_PROTECTED);
+ SecurityConstraint sc1 = new SecurityConstraint();
+ sc1.addAuthRole(ROLE);
+ sc1.addCollection(collection1);
+ testContext.addConstraint(sc1);
+
+ // Add Authenticator
+ Tomcat.addServlet(testContext, "LoginServlet", new LoginServlet());
+ testContext.addServletMappingDecoded(URI_AUTHENTICATION,
"LoginServlet");
+
+ SecurityCollection collection2 = new SecurityCollection();
+ collection2.addPatternDecoded(URI_AUTHENTICATION);
+ SecurityConstraint sc2 = new SecurityConstraint();
+ // do not add a role - which signals access permitted without one
+ sc2.addCollection(collection2);
+ testContext.addConstraint(sc2);
+
+ // Configure the authenticator and inherit the Realm from Engine
+ LoginConfig lc = new LoginConfig();
+ lc.setAuthMethod("NONE");
+ testContext.setLoginConfig(lc);
+ AuthenticatorBase nonloginAuthenticator = new NonLoginAuthenticator();
+ testContext.getPipeline().addValve(nonloginAuthenticator);
+
+ // add the test user and role to the Realm
+ tomcat.addUser(USER, PWD);
+ tomcat.addRole(USER, ROLE);
+
+ tomcat.start();
+ }
+
+ private static class SessionManipulationFilter extends ValveBase {
+ @Override
+ public void invoke(Request request, Response response) throws
IOException, ServletException {
+
+ if (request.getPrincipal() != null) {
+ final Manager manager = request.getContext().getManager();
+ final Session session =
manager.findSession(request.getSession().getId());
+ manager.changeSessionId(session, NOTSORANDOMID);
+ }
+
+ getNext().invoke(request, response);
+ }
+ }
+
+ private static class LoginServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ protected void doGet(HttpServletRequest request, HttpServletResponse
response)
+ throws ServletException, IOException {
+
+ if (request.getUserPrincipal() == null) {
+ request.login(USER, PWD);
+
+ response.setContentType("text/plain");
+ PrintWriter out = response.getWriter();
+ out.print("OK");
+
+ } else {
+ response.setStatus(HttpServletResponse.SC_CONFLICT);
+ }
+ }
+ }
+
+ @Test
+ public void testChangeSessionId() throws Exception {
+ final Map<String,SingleSignOnEntry> cache = singleSignOn.cache;
+ Assert.assertTrue("No SSO entries should be present at startup",
cache.isEmpty());
+
+ // Authenticate a session
+ doTest(CONTEXT_PATH + URI_AUTHENTICATION, USE_COOKIES,
HttpServletResponse.SC_OK);
+
+ Assert.assertFalse("SSO must now be present", cache.isEmpty());
+
+ Assert.assertEquals("Only one SSO entry must be present", 1,
cache.size());
+ final Collection<SingleSignOnEntry> ssoEntries = cache.values();
+ Assert.assertEquals("Only one session should be present, as there is
only one context in the test", 1,
+ ssoEntries.size());
+
+ final SingleSignOnEntry singleSignOnEntry =
ssoEntries.iterator().next();
+ final Set<SingleSignOnSessionKey> sessions =
singleSignOnEntry.findSessions();
+
+ Assert.assertEquals(1, sessions.size());
+
+ final SingleSignOnSessionKey singleSignOnSessionKey1 =
sessions.iterator().next();
+ Assert.assertNotEquals("A random SessionId is expected", NOTSORANDOMID,
+ singleSignOnSessionKey1.getSessionId());
+
+ // Perform the request that changes the session id:
+ doTest(CONTEXT_PATH + URI_PROTECTED, USE_COOKIES,
HttpServletResponse.SC_OK);
+
+ Assert.assertEquals("2 sessions means we have a zombie
SingleSignOnSessionKey", 1, sessions.size());
+
+ final SingleSignOnSessionKey singleSignOnSessionKey2 =
sessions.iterator().next();
+ Assert.assertEquals(NOTSORANDOMID,
singleSignOnSessionKey2.getSessionId());
+
+ final Session session =
testContext.getManager().findSession(NOTSORANDOMID);
+ Assert.assertNotNull("We need a session in order to test expiry",
session);
+
+ session.expire();
+
+ Assert.assertTrue("No SSO entries should be present after expiration
of the session", cache.isEmpty());
+
+ // Shouldn't this return 401?
+ doTest(CONTEXT_PATH + URI_PROTECTED, USE_COOKIES,
HttpServletResponse.SC_FORBIDDEN);
+ }
+
+ @After
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ public void doTest(String uri, boolean useCookie, int expectedRC) throws
Exception {
+
+ Map<String,List<String>> reqHeaders = new HashMap<>();
+ Map<String,List<String>> respHeaders = new HashMap<>();
+
+ if (useCookie && (cookies != null)) {
+ addCookies(reqHeaders);
+ }
+
+ ByteChunk bc = new ByteChunk();
+ int rc = getUrl(HTTP_PREFIX + getPort() + uri, bc, reqHeaders,
respHeaders);
+ if (expectedRC != HttpServletResponse.SC_OK) {
+ Assert.assertEquals(expectedRC, rc);
+ Assert.assertTrue(bc.getLength() > 0);
+ } else {
+ Assert.assertEquals("OK", bc.toString());
+ saveCookies(respHeaders);
+ }
+ }
+
+ /*
+ * add all saved cookies to the outgoing request
+ */
+ protected void addCookies(Map<String,List<String>> reqHeaders) {
+ if ((cookies != null) && (cookies.size() > 0)) {
+ StringBuilder cookieHeader = new StringBuilder();
+ boolean first = true;
+ for (String cookie : cookies) {
+ if (!first) {
+ cookieHeader.append(';');
+ } else {
+ first = false;
+ }
+ cookieHeader.append(cookie);
+ }
+ List<String> cookieHeaderList = new ArrayList<>(1);
+ cookieHeaderList.add(cookieHeader.toString());
+ reqHeaders.put(CLIENT_COOKIE_HEADER, cookieHeaderList);
+ }
+ }
+
+ /*
+ * extract and save the server cookies from the incoming response
+ */
+ protected void saveCookies(Map<String,List<String>> respHeaders) {
+ // we only save the Cookie values, not header prefix
+ List<String> cookieHeaders = respHeaders.get(SERVER_COOKIE_HEADER);
+ if (cookieHeaders == null) {
+ cookies = null;
+ } else {
+ cookies = new ArrayList<>(cookieHeaders.size());
+ for (String cookieHeader : cookieHeaders) {
+ cookies.add(cookieHeader.substring(0,
cookieHeader.indexOf(';')));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index d1753c6286..86261a896b 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -132,6 +132,15 @@
</fix>
</changelog>
</subsection>
+ <subsection name="Other">
+ <changelog>
+ <fix>
+ <bug>69847</bug>: Remove remaining references to the
+ <code>org.apache.tomcat.util.codec.binary</code> package which has been
+ deleted. (markt)
+ </fix>
+ </changelog>
+ </subsection>
</section>
<section name="Tomcat 11.0.12 (markt)" rtext="2025-10-07">
<subsection name="Catalina">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]