This is an automated email from the ASF dual-hosted git repository. markt pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit cae17a52598393680952aa21cee0e27b13a73455 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 3ffa702..f6ac737 100644 --- a/java/org/apache/tomcat/util/IntrospectionUtils.java +++ b/java/org/apache/tomcat/util/IntrospectionUtils.java @@ -26,6 +26,7 @@ import java.util.Hashtable; import org.apache.juli.logging.Log; import org.apache.juli.logging.LogFactory; import org.apache.tomcat.util.res.StringManager; +import org.apache.tomcat.util.security.PermissionCheck; /** * Utils for introspection and reflection @@ -224,9 +225,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; } @@ -257,8 +276,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 PropertySourceSecure) { + v = ((PropertySourceSecure) propertySource).getProperty(n, classLoader); + } else { + v = propertySource.getProperty(n); + } if (v != null) { break; } @@ -476,9 +499,27 @@ public final class IntrospectionUtils { // This provides a layer of abstraction public static interface PropertySource { - public String getProperty(String key); - } + + public static interface PropertySourceSecure 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 810274b..610e83c 100644 --- a/java/org/apache/tomcat/util/digester/Digester.java +++ b/java/org/apache/tomcat/util/digester/Digester.java @@ -123,13 +123,19 @@ public class Digester extends DefaultHandler2 { // --------------------------------------------------- Instance Variables - private class SystemPropertySource implements IntrospectionUtils.PropertySource { + private static class SystemPropertySource implements IntrospectionUtils.PropertySourceSecure { + @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; } } @@ -138,13 +144,18 @@ public class Digester extends DefaultHandler2 { } - public class EnvironmentPropertySource implements IntrospectionUtils.PropertySource { + public static class EnvironmentPropertySource implements IntrospectionUtils.PropertySourceSecure { + @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; } } @@ -351,7 +362,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); } @@ -1933,7 +1944,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); } @@ -1952,7 +1963,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 e89ca90..bec625b 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -69,8 +69,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-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org