Author: markt
Date: Sun Jun 11 15:38:34 2017
New Revision: 1798371

URL: http://svn.apache.org/viewvc?rev=1798371&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61154
Introduce a new custom permission, DeployXmlPermisasion, that allows a web 
application running under a security manager to use a META-INF/context.xml even 
when Host.deployXML is false.

Added:
    tomcat/trunk/java/org/apache/catalina/security/DeployXmlPermission.java   
(with props)
Modified:
    tomcat/trunk/conf/catalina.policy
    tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java
    tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
    tomcat/trunk/webapps/docs/changelog.xml
    tomcat/trunk/webapps/docs/config/host.xml

Modified: tomcat/trunk/conf/catalina.policy
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/conf/catalina.policy?rev=1798371&r1=1798370&r2=1798371&view=diff
==============================================================================
--- tomcat/trunk/conf/catalina.policy (original)
+++ tomcat/trunk/conf/catalina.policy Sun Jun 11 15:38:34 2017
@@ -193,8 +193,9 @@ grant {
 
 
 // The Manager application needs access to the following packages to support 
the
-// session display functionality. These settings support the following
-// configurations:
+// session display functionality. It also requires the custom Tomcat
+// DeployXmlPermission to enable the use of META_INF/context.xml
+// These settings support the following configurations:
 // - default CATALINA_HOME == CATALINA_BASE
 // - CATALINA_HOME != CATALINA_BASE, per instance Manager in CATALINA_BASE
 // - CATALINA_HOME != CATALINA_BASE, shared Manager in CATALINA_HOME
@@ -204,6 +205,7 @@ grant codeBase "file:${catalina.base}/we
     permission java.lang.RuntimePermission 
"accessClassInPackage.org.apache.catalina.manager";
     permission java.lang.RuntimePermission 
"accessClassInPackage.org.apache.catalina.manager.util";
     permission java.lang.RuntimePermission 
"accessClassInPackage.org.apache.catalina.util";
+    permission org.apache.catalina.security.DeployXmlPermission "manager";
 };
 grant codeBase "file:${catalina.home}/webapps/manager/-" {
     permission java.lang.RuntimePermission 
"accessClassInPackage.org.apache.catalina";
@@ -211,8 +213,23 @@ grant codeBase "file:${catalina.home}/we
     permission java.lang.RuntimePermission 
"accessClassInPackage.org.apache.catalina.manager";
     permission java.lang.RuntimePermission 
"accessClassInPackage.org.apache.catalina.manager.util";
     permission java.lang.RuntimePermission 
"accessClassInPackage.org.apache.catalina.util";
+    permission org.apache.catalina.security.DeployXmlPermission "manager";
 };
 
+// The Host Manager application needs the custom Tomcat DeployXmlPermission to
+// enable the use of META_INF/context.xml
+// These settings support the following configurations:
+// - default CATALINA_HOME == CATALINA_BASE
+// - CATALINA_HOME != CATALINA_BASE, per instance Host Manager in CATALINA_BASE
+// - CATALINA_HOME != CATALINA_BASE, shared Host Manager in CATALINA_HOME
+grant codeBase "file:${catalina.base}/webapps/host-manager/-" {
+    permission org.apache.catalina.security.DeployXmlPermission "host-manager";
+};
+grant codeBase "file:${catalina.home}/webapps/host-manager/-" {
+    permission org.apache.catalina.security.DeployXmlPermission "host-manager";
+};
+
+
 // You can assign additional permissions to particular web applications by
 // adding additional "grant" entries here, based on the code base for that
 // application, /WEB-INF/classes/, or /WEB-INF/lib/ jar files.

Added: tomcat/trunk/java/org/apache/catalina/security/DeployXmlPermission.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/security/DeployXmlPermission.java?rev=1798371&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/security/DeployXmlPermission.java 
(added)
+++ tomcat/trunk/java/org/apache/catalina/security/DeployXmlPermission.java Sun 
Jun 11 15:38:34 2017
@@ -0,0 +1,38 @@
+/*
+ * 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.security;
+
+import java.security.BasicPermission;
+
+/**
+ * Grant this permission to a docBase to permit the web application to use any
+ * <code>META-INF/context.xml</code> that might be present with in the
+ * application when <code>deployXML</code> has been disabled at the Host level.
+ * The name of the permission should be the base name for the web application.
+ */
+public class DeployXmlPermission extends BasicPermission {
+
+    private static final long serialVersionUID = 1L;
+
+    public DeployXmlPermission(String name) {
+        super(name);
+    }
+
+    public DeployXmlPermission(String name, String actions) {
+        super(name, actions);
+    }
+}

Propchange: 
tomcat/trunk/java/org/apache/catalina/security/DeployXmlPermission.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java?rev=1798371&r1=1798370&r2=1798371&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java (original)
+++ tomcat/trunk/java/org/apache/catalina/startup/HostConfig.java Sun Jun 11 
15:38:34 2017
@@ -22,7 +22,14 @@ import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
 import java.nio.file.Files;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.Policy;
+import java.security.cert.Certificate;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -47,6 +54,7 @@ import javax.management.ObjectName;
 import org.apache.catalina.Container;
 import org.apache.catalina.Context;
 import org.apache.catalina.DistributedManager;
+import org.apache.catalina.Globals;
 import org.apache.catalina.Host;
 import org.apache.catalina.Lifecycle;
 import org.apache.catalina.LifecycleEvent;
@@ -54,6 +62,7 @@ import org.apache.catalina.LifecycleList
 import org.apache.catalina.Manager;
 import org.apache.catalina.core.StandardContext;
 import org.apache.catalina.core.StandardHost;
+import org.apache.catalina.security.DeployXmlPermission;
 import org.apache.catalina.util.ContextName;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
@@ -196,7 +205,34 @@ public class HostConfig implements Lifec
      * @param deployXML The new deploy XML flag
      */
     public void setDeployXML(boolean deployXML) {
-        this.deployXML= deployXML;
+        this.deployXML = deployXML;
+    }
+
+
+    private boolean isDeployThisXML(File docBase, ContextName cn) {
+        boolean deployThisXML = isDeployXML();
+        if (Globals.IS_SECURITY_ENABLED && !deployThisXML) {
+            // When running under a SecurityManager, deployXML may be 
overridden
+            // on a per Context basis by the granting of a specific permission
+            Policy currentPolicy = Policy.getPolicy();
+            if (currentPolicy != null) {
+                URL contextRootUrl;
+                try {
+                    contextRootUrl = docBase.toURI().toURL();
+                    CodeSource cs = new CodeSource(contextRootUrl, 
(Certificate[]) null);
+                    PermissionCollection pc = currentPolicy.getPermissions(cs);
+                    Permission p = new DeployXmlPermission(cn.getBaseName());
+                    if (pc.implies(p)) {
+                        deployThisXML = true;
+                    }
+                } catch (MalformedURLException e) {
+                    // Should never happen
+                    log.warn("hostConfig.docBaseUrlInvalid", e);
+                }
+            }
+        }
+
+        return deployThisXML;
     }
 
 
@@ -809,8 +845,10 @@ public class HostConfig implements Lifec
         }
 
         Context context = null;
+        boolean deployThisXML = isDeployThisXML(war, cn);
+
         try {
-            if (deployXML && useXml && !copyXML) {
+            if (deployThisXML && useXml && !copyXML) {
                 synchronized (digesterLock) {
                     try {
                         context = (Context) digester.parse(xml);
@@ -826,7 +864,7 @@ public class HostConfig implements Lifec
                     }
                 }
                 context.setConfigFile(xml.toURI().toURL());
-            } else if (deployXML && xmlInWar) {
+            } else if (deployThisXML && xmlInWar) {
                 synchronized (digesterLock) {
                     try (JarFile jar = new JarFile(war)) {
                         JarEntry entry = 
jar.getJarEntry(Constants.ApplicationContextXml);
@@ -846,7 +884,7 @@ public class HostConfig implements Lifec
                                 UriUtil.buildJarUrl(war, 
Constants.ApplicationContextXml));
                     }
                 }
-            } else if (!deployXML && xmlInWar) {
+            } else if (!deployThisXML && xmlInWar) {
                 // Block deployment as META-INF/context.xml may contain 
security
                 // configuration necessary for a secure deployment.
                 log.error(sm.getString("hostConfig.deployDescriptor.blocked",
@@ -866,7 +904,7 @@ public class HostConfig implements Lifec
         }
 
         boolean copyThisXml = false;
-        if (deployXML) {
+        if (deployThisXML) {
             if (host instanceof StandardHost) {
                 copyThisXml = ((StandardHost) host).isCopyXML();
             }
@@ -902,7 +940,7 @@ public class HostConfig implements Lifec
         }
 
         DeployedApplication deployedApp = new DeployedApplication(cn.getName(),
-                xml.exists() && deployXML && copyThisXml);
+                xml.exists() && deployThisXML && copyThisXml);
 
         long startTime = 0;
         // Deploy the application in this WAR file
@@ -917,7 +955,7 @@ public class HostConfig implements Lifec
             deployedApp.redeployResources.put
                 (war.getAbsolutePath(), Long.valueOf(war.lastModified()));
 
-            if (deployXML && xml.exists() && copyThisXml) {
+            if (deployThisXML && xml.exists() && copyThisXml) {
                 deployedApp.redeployResources.put(xml.getAbsolutePath(),
                         Long.valueOf(xml.lastModified()));
             } else {
@@ -955,7 +993,7 @@ public class HostConfig implements Lifec
                         Long.valueOf(docBase.lastModified()));
                 addWatchedResources(deployedApp, docBase.getAbsolutePath(),
                         context);
-                if (deployXML && !copyThisXml && (xmlInWar || xml.exists())) {
+                if (deployThisXML && !copyThisXml && (xmlInWar || 
xml.exists())) {
                     deployedApp.redeployResources.put(xml.getAbsolutePath(),
                             Long.valueOf(xml.lastModified()));
                 }
@@ -1042,10 +1080,11 @@ public class HostConfig implements Lifec
 
 
         DeployedApplication deployedApp;
-        boolean copyThisXml = copyXML;
+        boolean copyThisXml = isCopyXML();
+        boolean deployThisXML = isDeployThisXML(dir, cn);
 
         try {
-            if (deployXML && xml.exists()) {
+            if (deployThisXML && xml.exists()) {
                 synchronized (digesterLock) {
                     try {
                         context = (Context) digester.parse(xml);
@@ -1073,7 +1112,7 @@ public class HostConfig implements Lifec
                 } else {
                     context.setConfigFile(xml.toURI().toURL());
                 }
-            } else if (!deployXML && xml.exists()) {
+            } else if (!deployThisXML && xml.exists()) {
                 // Block deployment as META-INF/context.xml may contain 
security
                 // configuration necessary for a secure deployment.
                 log.error(sm.getString("hostConfig.deployDescriptor.blocked",
@@ -1099,7 +1138,7 @@ public class HostConfig implements Lifec
                     dir.getAbsolutePath()), t);
         } finally {
             deployedApp = new DeployedApplication(cn.getName(),
-                    xml.exists() && deployXML && copyThisXml);
+                    xml.exists() && deployThisXML && copyThisXml);
 
             // Fake re-deploy resource to detect if a WAR is added at a later
             // point
@@ -1107,7 +1146,7 @@ public class HostConfig implements Lifec
                     Long.valueOf(0));
             deployedApp.redeployResources.put(dir.getAbsolutePath(),
                     Long.valueOf(dir.lastModified()));
-            if (deployXML && xml.exists()) {
+            if (deployThisXML && xml.exists()) {
                 if (copyThisXml) {
                     deployedApp.redeployResources.put(
                             xmlCopy.getAbsolutePath(),

Modified: tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties?rev=1798371&r1=1798370&r2=1798371&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties 
(original)
+++ tomcat/trunk/java/org/apache/catalina/startup/LocalStrings.properties Sun 
Jun 11 15:38:34 2017
@@ -108,6 +108,7 @@ hostConfig.deployWar.threaded.error=Erro
 hostConfig.deployWar.finished=Deployment of web application archive [{0}] has 
finished in [{1}] ms
 hostConfig.deploy.error=Exception while deploying web application directory 
[{0}]
 hostConfig.deploying=Deploying discovered web applications
+hostConfig.docBaseUrlInvalid=The provided docBase cannot be expressed as a URL
 hostConfig.expand=Expanding web application archive [{0}]
 hostConfig.expand.error=Exception while expanding web application archive [{0}]
 hostConfig.expanding=Expanding discovered web application archives

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1798371&r1=1798370&r2=1798371&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Sun Jun 11 15:38:34 2017
@@ -86,6 +86,15 @@
         text fragments when generating the default error pages. Patch provided
         by Katya Todorova. (violetagg)
       </fix>
+      <fix>
+        <bug>61154</bug>: Allow the Manager and Host Manager web applciations 
to
+        start by default when running under a security manager. This was
+        accomplished by adding a custom permission,
+        <code>org.apache.catalina.security.DeployXmlPermisasion</code>, that
+        permits an application to use a <code>META-INF/context.xml</code> file
+        and then granting that permission to the Manager and Host Manager.
+        (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Coyote">

Modified: tomcat/trunk/webapps/docs/config/host.xml
URL: 
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/host.xml?rev=1798371&r1=1798370&r2=1798371&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/host.xml (original)
+++ tomcat/trunk/webapps/docs/config/host.xml Sun Jun 11 15:38:34 2017
@@ -261,7 +261,13 @@
         fail to start in case the descriptor contains necessary configuration
         for secure deployment (such as a RemoteAddrValve) which should not be
         ignored. The flag's value defaults to <code>true</code> unless a
-        security manager is enabled when the default is <code>false</code>.</p>
+        security manager is enabled when the default is <code>false</code>.
+        When running under a security manager this may be enabled on a per web
+        application basis by granting the
+        <code>org.apache.catalina.security.DeployXmlPermission</code> to the 
web
+        application. The Manager and Host Manager applications are granted this
+        permission by default so that they continue to work when running under 
a
+        security manager.</p>
       </attribute>
 
       <attribute name="errorReportValveClass" required="false">



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

Reply via email to