You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2020/09/30 12:54:47 UTC

[tomcat] branch 9.0.x updated (f258efe -> e44fd93)

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

markt pushed a change to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git.


    from f258efe  Optimize the iteration when closing idle streams
     new 5e7c765  Align with 10.0.x
     new e44fd93  Fix 64735 ServletContext.addJspFile() always fails with SecurityManager

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 build.xml                                          |  17 ++-
 .../catalina/core/ApplicationContextFacade.java    |   5 +
 ...estApplicationContextFacadeSecurityManager.java | 148 +++++++++++++++++++++
 .../util/security/SecurityManagerBaseTest.java     |  50 +++++++
 webapps/docs/changelog.xml                         |   5 +
 5 files changed, 222 insertions(+), 3 deletions(-)
 create mode 100644 test/org/apache/catalina/core/TestApplicationContextFacadeSecurityManager.java
 create mode 100644 test/org/apache/tomcat/util/security/SecurityManagerBaseTest.java


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


[tomcat] 01/02: Align with 10.0.x

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 5e7c765448993975a575af836ad900c13b29960c
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Sep 30 13:48:47 2020 +0100

    Align with 10.0.x
---
 build.xml | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/build.xml b/build.xml
index f09f209..6a1d141 100644
--- a/build.xml
+++ b/build.xml
@@ -1958,7 +1958,7 @@
            />
         <batchtest todir="${test.reports}" unless="test.entry">
           <!-- Include all by default -->
-          <fileset dir="test" includes="${test.name}">
+          <fileset dir="test" includes="${test.name}" excludes="${test.exclude}">
             <!-- Exclude helper classes -->
             <exclude name="**/Tester*.java" />
             <!-- Exclude the tests known to fail -->
@@ -1969,8 +1969,6 @@
             <exclude name="**/*Performance.java" if="${test.excludePerformance}" />
             <!-- Exclude tests that Gump can't compile -->
             <exclude name="org/apache/tomcat/buildutil/**" />
-            <!-- Exclude a configurable list of tests -->
-            <exclude name="${test.exclude}" />
           </fileset>
         </batchtest>
       </junit>


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


[tomcat] 02/02: Fix 64735 ServletContext.addJspFile() always fails with SecurityManager

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit e44fd931075f63acd0405603fa47e9ee335d667a
Author: Kyle Stiemann <ky...@contrastsecurity.com>
AuthorDate: Thu Sep 10 16:47:21 2020 -0400

    Fix 64735 ServletContext.addJspFile() always fails with SecurityManager
---
 build.xml                                          |  13 ++
 .../catalina/core/ApplicationContextFacade.java    |   5 +
 ...estApplicationContextFacadeSecurityManager.java | 148 +++++++++++++++++++++
 .../util/security/SecurityManagerBaseTest.java     |  50 +++++++
 webapps/docs/changelog.xml                         |   5 +
 5 files changed, 221 insertions(+)

diff --git a/build.xml b/build.xml
index 6a1d141..56a9701 100644
--- a/build.xml
+++ b/build.xml
@@ -1969,8 +1969,21 @@
             <exclude name="**/*Performance.java" if="${test.excludePerformance}" />
             <!-- Exclude tests that Gump can't compile -->
             <exclude name="org/apache/tomcat/buildutil/**" />
+            <!--
+              Avoid running tests which require the SecurityManager with other
+              tests. See below for more details.
+            -->
+            <exclude name="**/*SecurityManager.java" />
           </fileset>
         </batchtest>
+        <!--
+           Run tests which require the SecurityManager in their own forked
+           batch to ensure that global/system security settings don't pollute
+           other tests. See SecurityManagerBaseTest.java for more details.
+        -->
+        <batchtest todir="${test.reports}" unless="test.entry" fork="true">
+          <fileset dir="test" includes="**/SecurityManager.java" excludes="${test.exclude}" />
+        </batchtest>
       </junit>
     </sequential>
   </macrodef>
diff --git a/java/org/apache/catalina/core/ApplicationContextFacade.java b/java/org/apache/catalina/core/ApplicationContextFacade.java
index 8d506b9..67065b0 100644
--- a/java/org/apache/catalina/core/ApplicationContextFacade.java
+++ b/java/org/apache/catalina/core/ApplicationContextFacade.java
@@ -117,6 +117,11 @@ public class ApplicationContextFacade implements ServletContext {
         classCache.put("getAttribute", clazz);
         classCache.put("log", clazz);
         classCache.put("setSessionTrackingModes", new Class[]{Set.class} );
+        classCache.put("addJspFile", new Class[]{String.class, String.class});
+        classCache.put("declareRoles", new Class[]{String[].class});
+        classCache.put("setSessionTimeout", new Class[]{int.class});
+        classCache.put("setRequestCharacterEncoding", new Class[]{String.class});
+        classCache.put("setResponseCharacterEncoding", new Class[]{String.class});
     }
 
 
diff --git a/test/org/apache/catalina/core/TestApplicationContextFacadeSecurityManager.java b/test/org/apache/catalina/core/TestApplicationContextFacadeSecurityManager.java
new file mode 100644
index 0000000..fc5a5d5
--- /dev/null
+++ b/test/org/apache/catalina/core/TestApplicationContextFacadeSecurityManager.java
@@ -0,0 +1,148 @@
+/*
+ * 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.core;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+
+import org.apache.catalina.security.SecurityUtil;
+import org.apache.tomcat.util.security.SecurityManagerBaseTest;
+import org.easymock.EasyMock;
+import org.easymock.IExpectationSetters;
+import org.easymock.internal.LastControl;
+
+@RunWith(Parameterized.class)
+public final class TestApplicationContextFacadeSecurityManager extends SecurityManagerBaseTest {
+
+    /**
+     * @return {@link Collection} of non-static, non-object, public {@link
+     * Method}s in {@link ApplicationContextFacade} to be run with the the Java
+     * 2 {@link SecurityManager} been enabled.
+     */
+    @Parameterized.Parameters(name = "{index}: method={0}")
+    public static Collection<Method> publicApplicationContextFacadeMethods() {
+        return Arrays.stream(ApplicationContextFacade.class.getMethods())
+                .filter(method -> !Modifier.isStatic(method.getModifiers()))
+                .filter(method -> {
+                    try {
+                        Object.class.getMethod(method.getName(), method.getParameterTypes());
+                        return false;
+                    } catch (final NoSuchMethodException e) {
+                        return true;
+                    }
+                })
+                .collect(Collectors.toList());
+    }
+
+
+    private static Object[] getDefaultParams(final Method method) {
+        final int paramsCount = method.getParameterCount();
+        final Object[] params = new Object[paramsCount];
+        final Class<?>[] paramTypes = method.getParameterTypes();
+        for (int i = 0; i < params.length; i++) {
+            params[i] = getDefaultValue(paramTypes[i]);
+        }
+        return params;
+    }
+
+
+    @SuppressWarnings("unchecked")
+    private static <T> T getDefaultValue(final Class<T> clazz) {
+        return !isVoid(clazz) ? (T) Array.get(Array.newInstance(clazz, 1), 0) : null;
+    }
+
+
+    private static <T> boolean isVoid(Class<T> clazz) {
+        return void.class.equals(clazz) || Void.class.equals(clazz);
+    }
+
+
+    @Parameter(0)
+    public Method methodToTest;
+
+
+    /**
+     * Test for
+     * <a href="https://bz.apache.org/bugzilla/show_bug.cgi?id=64735">Bug
+     * 64735</a> which confirms that {@link ApplicationContextFacade} behaves
+     * correctly when the Java 2 {@link SecurityManager} has been enabled.
+     *
+     * @throws NoSuchMethodException     Should never happen
+     * @throws IllegalAccessException    Should never happen
+     * @throws InvocationTargetException Should never happen
+     */
+    @Test
+    public void testBug64735()
+            throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+        Assert.assertTrue(SecurityUtil.isPackageProtectionEnabled());
+
+        // Mock the ApplicationContext that we provide to the ApplicationContextFacade.
+        final ApplicationContext mockAppContext = EasyMock.createMock(ApplicationContext.class);
+        final Method expectedAppContextMethod =
+                ApplicationContext.class.getMethod(
+                        methodToTest.getName(),
+                        methodToTest.getParameterTypes());
+
+        // Expect that only the provided method which is being tested will be called exactly once.
+        final IExpectationSetters<Object> expectationSetters;
+        if (isVoid(expectedAppContextMethod.getReturnType())) {
+            expectedAppContextMethod.invoke(mockAppContext, getDefaultParams(methodToTest));
+            expectationSetters = EasyMock.expectLastCall();
+        } else {
+            expectationSetters =
+                    EasyMock.expect(expectedAppContextMethod.invoke(
+                            mockAppContext, getDefaultParams(methodToTest)));
+        }
+        expectationSetters
+                .andAnswer(() -> {
+                    Assert.assertEquals(
+                            expectedAppContextMethod,
+                            LastControl.getCurrentInvocation().getMethod());
+                    return getDefaultValue(expectedAppContextMethod.getReturnType());
+                }).once();
+        EasyMock.replay(mockAppContext);
+        EasyMock.verifyUnexpectedCalls(mockAppContext);
+
+        // Invoke the method on ApplicationContextFacade. Fail if any unexpected exceptions are
+        // thrown.
+        try {
+            methodToTest.invoke(
+                    new ApplicationContextFacade(mockAppContext),
+                    getDefaultParams(methodToTest));
+        } catch (final IllegalAccessException | InvocationTargetException e) {
+            throw new AssertionError(
+                    "Failed to call " +
+                            methodToTest +
+                            " with SecurityManager enabled.",
+                    e);
+        }
+
+        // Verify that the method called through to the wrapped ApplicationContext correctly.
+        EasyMock.verifyRecording();
+    }
+}
diff --git a/test/org/apache/tomcat/util/security/SecurityManagerBaseTest.java b/test/org/apache/tomcat/util/security/SecurityManagerBaseTest.java
new file mode 100644
index 0000000..af7ff8f
--- /dev/null
+++ b/test/org/apache/tomcat/util/security/SecurityManagerBaseTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.tomcat.util.security;
+
+import java.security.Permission;
+
+import org.apache.catalina.security.SecurityUtil;
+
+/**
+ * Base test class for unit tests which require the Java 2 {@link
+ * SecurityManager} to be enabled. Tests that extend this class must be run in a
+ * forked SecurityManager test batch since this class modifies global {@link
+ * System} settings which may interfere with other tests. On static class
+ * initialization, this class sets up the {@code "package.definition"} and
+ * {@code "package.access"} system properties and adds a no-op SecurityManager
+ * which does not check permissions. These settings are required in order to
+ * make {@link org.apache.catalina.Globals#IS_SECURITY_ENABLED} and {@link
+ * SecurityUtil#isPackageProtectionEnabled()} return true.
+ */
+public abstract class SecurityManagerBaseTest {
+    static {
+        System.setProperty("package.definition", "test");
+        System.setProperty("package.access", "test");
+        System.setSecurityManager(new SecurityManager() {
+            @Override
+            public void checkPermission(final Permission permission) {
+                // no-op
+            }
+
+            @Override
+            public void checkPermission(final Permission permission, Object context) {
+                // no-op
+            }
+        });
+    }
+}
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index a82ec7b..08a8aad 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -89,6 +89,11 @@
         database. (kfujino)
       </fix>
       <fix>
+        <bug>64735</bug>: Ensure that none of the methods on a
+        <code>ServletContext</code> instance always fail when running under a
+        SecurityManager. Pull request provided by Kyle Stiemann. (markt)
+      </fix>
+      <fix>
         <bug>64765</bug>: Ensure that the number of currently processing threads
         is tracked correctly when a web application is undeployed, long running
         requests are being processed and


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