1 /* 2 * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.org.apache.xerces.internal.utils; 27 28 import com.sun.org.apache.xerces.internal.impl.Constants; 29 import javax.xml.XMLConstants; 30 import jdk.xml.internal.SecuritySupport; 31 32 /** 33 * This class manages security related properties 34 * 35 */ 36 public final class XMLSecurityPropertyManager { 37 38 /** 39 * States of the settings of a property, in the order: default value, value 40 * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system 41 * properties, and jaxp api properties 42 */ 43 public static enum State { 44 //this order reflects the overriding order 45 DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY 46 } 47 48 /** 49 * Limits managed by the security manager 50 */ 51 public static enum Property { 52 ACCESS_EXTERNAL_DTD(XMLConstants.ACCESS_EXTERNAL_DTD, 53 Constants.EXTERNAL_ACCESS_DEFAULT), 54 ACCESS_EXTERNAL_SCHEMA(XMLConstants.ACCESS_EXTERNAL_SCHEMA, 55 Constants.EXTERNAL_ACCESS_DEFAULT); 56 57 final String name; 58 final String defaultValue; 59 Property(String name, String value)60 Property(String name, String value) { 61 this.name = name; 62 this.defaultValue = value; 63 } 64 equalsName(String propertyName)65 public boolean equalsName(String propertyName) { 66 return (propertyName == null) ? false : name.equals(propertyName); 67 } 68 defaultValue()69 String defaultValue() { 70 return defaultValue; 71 } 72 } 73 74 /** 75 * Values of the properties as defined in enum Properties 76 */ 77 private final String[] values; 78 /** 79 * States of the settings for each property in Properties above 80 */ 81 private State[] states = {State.DEFAULT, State.DEFAULT}; 82 83 /** 84 * Default constructor. Establishes default values 85 */ XMLSecurityPropertyManager()86 public XMLSecurityPropertyManager() { 87 values = new String[Property.values().length]; 88 for (Property property : Property.values()) { 89 values[property.ordinal()] = property.defaultValue(); 90 } 91 //read system properties or jaxp.properties 92 readSystemProperties(); 93 } 94 95 96 /** 97 * Set limit by property name and state 98 * @param propertyName property name 99 * @param state the state of the property 100 * @param value the value of the property 101 * @return true if the property is managed by the security property manager; 102 * false if otherwise. 103 */ setValue(String propertyName, State state, Object value)104 public boolean setValue(String propertyName, State state, Object value) { 105 int index = getIndex(propertyName); 106 if (index > -1) { 107 setValue(index, state, (String)value); 108 return true; 109 } 110 return false; 111 } 112 113 /** 114 * Set the value for a specific property. 115 * 116 * @param property the property 117 * @param state the state of the property 118 * @param value the value of the property 119 */ setValue(Property property, State state, String value)120 public void setValue(Property property, State state, String value) { 121 //only update if it shall override 122 if (state.compareTo(states[property.ordinal()]) >= 0) { 123 values[property.ordinal()] = value; 124 states[property.ordinal()] = state; 125 } 126 } 127 128 /** 129 * Set the value of a property by its index 130 * @param index the index of the property 131 * @param state the state of the property 132 * @param value the value of the property 133 */ setValue(int index, State state, String value)134 public void setValue(int index, State state, String value) { 135 //only update if it shall override 136 if (state.compareTo(states[index]) >= 0) { 137 values[index] = value; 138 states[index] = state; 139 } 140 } 141 142 143 /** 144 * Return the value of the specified property 145 * 146 * @param propertyName the property name 147 * @return the value of the property as a string 148 */ getValue(String propertyName)149 public String getValue(String propertyName) { 150 int index = getIndex(propertyName); 151 if (index > -1) { 152 return getValueByIndex(index); 153 } 154 155 return null; 156 } 157 158 /** 159 * Return the value of the specified property 160 * 161 * @param property the property 162 * @return the value of the property 163 */ getValue(Property property)164 public String getValue(Property property) { 165 return values[property.ordinal()]; 166 } 167 168 /** 169 * Return the value of a property by its ordinal 170 * @param index the index of a property 171 * @return value of a property 172 */ getValueByIndex(int index)173 public String getValueByIndex(int index) { 174 return values[index]; 175 } 176 177 /** 178 * Get the index by property name 179 * @param propertyName property name 180 * @return the index of the property if found; return -1 if not 181 */ getIndex(String propertyName)182 public int getIndex(String propertyName){ 183 for (Property property : Property.values()) { 184 if (property.equalsName(propertyName)) { 185 //internally, ordinal is used as index 186 return property.ordinal(); 187 } 188 } 189 return -1; 190 } 191 192 /** 193 * Read from system properties, or those in jaxp.properties 194 */ readSystemProperties()195 private void readSystemProperties() { 196 getSystemProperty(Property.ACCESS_EXTERNAL_DTD, 197 Constants.SP_ACCESS_EXTERNAL_DTD); 198 getSystemProperty(Property.ACCESS_EXTERNAL_SCHEMA, 199 Constants.SP_ACCESS_EXTERNAL_SCHEMA); 200 } 201 202 /** 203 * Read from system properties, or those in jaxp.properties 204 * 205 * @param property the property 206 * @param systemProperty the name of the system property 207 */ getSystemProperty(Property property, String systemProperty)208 private void getSystemProperty(Property property, String systemProperty) { 209 try { 210 String value = SecuritySupport.getSystemProperty(systemProperty); 211 if (value != null) { 212 values[property.ordinal()] = value; 213 states[property.ordinal()] = State.SYSTEMPROPERTY; 214 return; 215 } 216 217 value = SecuritySupport.readJAXPProperty(systemProperty); 218 if (value != null) { 219 values[property.ordinal()] = value; 220 states[property.ordinal()] = State.JAXPDOTPROPERTIES; 221 } 222 } catch (NumberFormatException e) { 223 //invalid setting ignored 224 } 225 } 226 } 227