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 2019/09/16 08:14:20 UTC

[tomcat] branch 8.5.x updated (5ee1614 -> c76bfc2)

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

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


    from 5ee1614  Clean-up. Remove unused code. Align with 9.0.x.
     new b58f02a  PropertySource: Add an environment variable based source
     new c76bfc2  Additional changes required to enable EnvironmentPropertySource

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:
 .../org/apache/tomcat/util/IntrospectionUtils.java | 49 ++++++++++++++++++++--
 java/org/apache/tomcat/util/digester/Digester.java | 40 ++++++++++++++----
 webapps/docs/changelog.xml                         |  6 +++
 webapps/docs/config/systemprops.xml                |  9 +++-
 4 files changed, 91 insertions(+), 13 deletions(-)


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


[tomcat] 01/02: PropertySource: Add an environment variable based source

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

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

commit b58f02a0f88fead8ab5210566a396dae476d9362
Author: Thomas Meyer <th...@m3y3r.de>
AuthorDate: Sat Jul 20 22:22:42 2019 +0200

    PropertySource: Add an environment variable based source
    
    When tomcat runs in an Openshift based container a Secret containing passwords
    can be map as environment variables (with an additional prefix).
    An webapp containing an embedded context.xml which defines JDBC datasources and
    placeholder variables can be used with this new PropertySource to easily inject
    configuration from a Secret or ConfigMap.
---
 java/org/apache/tomcat/util/digester/Digester.java | 15 +++++++++++++++
 webapps/docs/changelog.xml                         |  6 ++++++
 webapps/docs/config/systemprops.xml                |  9 +++++++--
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/java/org/apache/tomcat/util/digester/Digester.java b/java/org/apache/tomcat/util/digester/Digester.java
index 59d59f0..f31518c 100644
--- a/java/org/apache/tomcat/util/digester/Digester.java
+++ b/java/org/apache/tomcat/util/digester/Digester.java
@@ -139,6 +139,21 @@ public class Digester extends DefaultHandler2 {
     }
 
 
+    public class EnvironmentPropertySource implements IntrospectionUtils.PropertySource {
+        @Override
+        public String getProperty(String key) {
+            ClassLoader cl = getClassLoader();
+            if (cl instanceof PermissionCheck) {
+                Permission p = new RuntimePermission("getenv." + key, null);
+                if (!((PermissionCheck) cl).check(p)) {
+                    return null;
+                }
+            }
+            return System.getenv(key);
+        }
+    }
+
+
     protected IntrospectionUtils.PropertySource source[] = new IntrospectionUtils.PropertySource[] {
             new SystemPropertySource() };
 
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 75c640c..2cf2b54 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -57,6 +57,12 @@
         Service is embedded directly (i.e. with no Server) in an applciation
         and JNDI is enabled. Patch provided by S. Ali Tokmen. (markt)
       </fix>
+      <add>
+        Add a new <code>PropertySource</code> implementation,
+        <code>EnvironmentPropertySource</code>, that can be used to do property
+        replacement in configuration files with environment variables. Pull
+        request provided by Thomas Meyer. (markt)
+      </add>
     </changelog>
   </subsection>
   <subsection name="Coyote">
diff --git a/webapps/docs/config/systemprops.xml b/webapps/docs/config/systemprops.xml
index cb39fb1..5e37c42 100644
--- a/webapps/docs/config/systemprops.xml
+++ b/webapps/docs/config/systemprops.xml
@@ -43,11 +43,16 @@
       <p>Set this to a fully qualified name of a class that implements
          <code>org.apache.tomcat.util.IntrospectionUtils.PropertySource</code>.
          Required to have a public constructor with no arguments.</p>
-      <p>Use this to add a property source, that will be invoked when <code>${parameter}</code>
-         denoted parameters are found in the XML files that Tomcat parses.</p>
+      <p>Use this to add a property source, that will be invoked when
+         <code>${parameter}</code> denoted parameters are found in the XML files
+         that Tomcat parses.</p>
       <p>Property replacement from the specified property source on the JVM
          system properties can also be done using the
          <code>REPLACE_SYSTEM_PROPERTIES</code> system property.</p>
+      <p><code>org.apache.tomcat.util.digester.Digester$EnvironmentPropertySource</code>
+         can be used to replace parameters from the process' environment
+         variables, e.g. injected ConfigMaps or Secret objects in container
+         based systems like OpenShift or Kubernetes.</p>
     </property>
     <property name="org.apache.tomcat.util.digester. REPLACE_SYSTEM_PROPERTIES">
       <p>Set this boolean system property to <code>true</code> to cause


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


[tomcat] 02/02: Additional changes required to enable EnvironmentPropertySource

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

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

commit c76bfc27a8c6a027bc4a139f3b07d9c75878f537
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Sep 12 15:31:26 2019 +0100

    Additional changes required to enable EnvironmentPropertySource
---
 .../org/apache/tomcat/util/IntrospectionUtils.java | 49 ++++++++++++++++++++--
 java/org/apache/tomcat/util/digester/Digester.java | 33 ++++++++++-----
 webapps/docs/changelog.xml                         |  4 +-
 3 files changed, 69 insertions(+), 17 deletions(-)

diff --git a/java/org/apache/tomcat/util/IntrospectionUtils.java b/java/org/apache/tomcat/util/IntrospectionUtils.java
index e3d6c76..10fafa8 100644
--- a/java/org/apache/tomcat/util/IntrospectionUtils.java
+++ b/java/org/apache/tomcat/util/IntrospectionUtils.java
@@ -25,6 +25,7 @@ import java.util.Hashtable;
 
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
+import org.apache.tomcat.util.security.PermissionCheck;
 
 /**
  * Utils for introspection and reflection
@@ -237,9 +238,27 @@ public final class IntrospectionUtils {
      * @param staticProp Replacement properties
      * @param dynamicProp Replacement properties
      * @return the replacement value
+     * @deprecated Use {@link #replaceProperties(String, Hashtable, PropertySource[], ClassLoader)}
      */
+    @Deprecated
     public static String replaceProperties(String value,
             Hashtable<Object,Object> staticProp, PropertySource dynamicProp[]) {
+        return replaceProperties(value, staticProp, dynamicProp, null);
+    }
+
+    /**
+     * Replace ${NAME} with the property value.
+     * @param value The value
+     * @param staticProp Replacement properties
+     * @param dynamicProp Replacement properties
+     * @param classLoader Class loader associated with the code requesting the
+     *                    property
+     * @return the replacement value
+     */
+    public static String replaceProperties(String value,
+            Hashtable<Object,Object> staticProp, PropertySource dynamicProp[],
+            ClassLoader classLoader) {
+
         if (value.indexOf('$') < 0) {
             return value;
         }
@@ -270,8 +289,12 @@ public final class IntrospectionUtils {
                     v = (String) staticProp.get(n);
                 }
                 if (v == null && dynamicProp != null) {
-                    for (int i = 0; i < dynamicProp.length; i++) {
-                        v = dynamicProp[i].getProperty(n);
+                    for (PropertySource propertySource : dynamicProp) {
+                        if (propertySource instanceof SecurePropertySource) {
+                            v = ((SecurePropertySource) propertySource).getProperty(n, classLoader);
+                        } else {
+                            v = propertySource.getProperty(n);
+                        }
                         if (v != null) {
                             break;
                         }
@@ -478,9 +501,27 @@ public final class IntrospectionUtils {
     // This provides a layer of abstraction
 
     public static interface PropertySource {
-
         public String getProperty(String key);
-
     }
 
+
+    public static interface SecurePropertySource extends PropertySource {
+
+        /**
+         * Obtain a property value, checking that code associated with the
+         * provided class loader has permission to access the property. If the
+         * {@code classLoader} is {@code null} or if {@code classLoader} does
+         * not implement {@link PermissionCheck} then the property value will be
+         * looked up <b>without</b> a call to
+         * {@link PermissionCheck#check(java.security.Permission)}
+         *
+         * @param key           The key of the requested property
+         * @param classLoader   The class loader associated with the code that
+         *                      trigger the property lookup
+         * @return The property value or {@code null} if it could not be found
+         *         or if {@link PermissionCheck#check(java.security.Permission)}
+         *         fails
+         */
+        public String getProperty(String key, ClassLoader classLoader);
+    }
 }
diff --git a/java/org/apache/tomcat/util/digester/Digester.java b/java/org/apache/tomcat/util/digester/Digester.java
index f31518c..8466241 100644
--- a/java/org/apache/tomcat/util/digester/Digester.java
+++ b/java/org/apache/tomcat/util/digester/Digester.java
@@ -124,13 +124,19 @@ public class Digester extends DefaultHandler2 {
     // --------------------------------------------------- Instance Variables
 
 
-    private class SystemPropertySource implements IntrospectionUtils.PropertySource {
+    private static class SystemPropertySource implements IntrospectionUtils.SecurePropertySource {
+
         @Override
         public String getProperty(String key) {
-            ClassLoader cl = getClassLoader();
-            if (cl instanceof PermissionCheck) {
+            // For backward compatibility
+            return getProperty(key, null);
+        }
+
+        @Override
+        public String getProperty(String key, ClassLoader classLoader) {
+            if (classLoader instanceof PermissionCheck) {
                 Permission p = new PropertyPermission(key, "read");
-                if (!((PermissionCheck) cl).check(p)) {
+                if (!((PermissionCheck) classLoader).check(p)) {
                     return null;
                 }
             }
@@ -139,13 +145,18 @@ public class Digester extends DefaultHandler2 {
     }
 
 
-    public class EnvironmentPropertySource implements IntrospectionUtils.PropertySource {
+    public static class EnvironmentPropertySource implements IntrospectionUtils.SecurePropertySource {
+
         @Override
         public String getProperty(String key) {
-            ClassLoader cl = getClassLoader();
-            if (cl instanceof PermissionCheck) {
+            return null;
+        }
+
+        @Override
+        public String getProperty(String key, ClassLoader classLoader) {
+            if (classLoader instanceof PermissionCheck) {
                 Permission p = new RuntimePermission("getenv." + key, null);
-                if (!((PermissionCheck) cl).check(p)) {
+                if (!((PermissionCheck) classLoader).check(p)) {
                     return null;
                 }
             }
@@ -352,7 +363,7 @@ public class Digester extends DefaultHandler2 {
                 String value = System.getProperty(name);
                 if (value != null) {
                     try {
-                        String newValue = IntrospectionUtils.replaceProperties(value, null, propertySources);
+                        String newValue = IntrospectionUtils.replaceProperties(value, null, propertySources, null);
                         if (!value.equals(newValue)) {
                             System.setProperty(name, newValue);
                         }
@@ -1980,7 +1991,7 @@ public class Digester extends DefaultHandler2 {
         for (int i = 0; i < nAttributes; ++i) {
             String value = newAttrs.getValue(i);
             try {
-                newAttrs.setValue(i, IntrospectionUtils.replaceProperties(value, null, source).intern());
+                newAttrs.setValue(i, IntrospectionUtils.replaceProperties(value, null, source, getClassLoader()).intern());
             } catch (Exception e) {
                 log.warn(sm.getString("digester.failedToUpdateAttributes", newAttrs.getLocalName(i), value), e);
             }
@@ -1999,7 +2010,7 @@ public class Digester extends DefaultHandler2 {
         String in = bodyText.toString();
         String out;
         try {
-            out = IntrospectionUtils.replaceProperties(in, null, source);
+            out = IntrospectionUtils.replaceProperties(in, null, source, getClassLoader());
         } catch (Exception e) {
             return bodyText; // return unchanged data
         }
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 2cf2b54..2b63d25 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -60,8 +60,8 @@
       <add>
         Add a new <code>PropertySource</code> implementation,
         <code>EnvironmentPropertySource</code>, that can be used to do property
-        replacement in configuration files with environment variables. Pull
-        request provided by Thomas Meyer. (markt)
+        replacement in configuration files with environment variables. Based on
+        a pull request provided by Thomas Meyer. (markt)
       </add>
     </changelog>
   </subsection>


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