1 /* 2 * Copyright (c) 2013 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 31 /** 32 * This class manages security related properties 33 * 34 */ 35 public final class XMLSecurityPropertyManager { 36 37 /** 38 * States of the settings of a property, in the order: default value, value 39 * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system 40 * properties, and jaxp api properties 41 */ 42 public static enum State { 43 //this order reflects the overriding order 44 DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY 45 } 46 47 /** 48 * Limits managed by the security manager 49 */ 50 public static enum Property { 51 ACCESS_EXTERNAL_DTD(XMLConstants.ACCESS_EXTERNAL_DTD, 52 Constants.EXTERNAL_ACCESS_DEFAULT), 53 ACCESS_EXTERNAL_SCHEMA(XMLConstants.ACCESS_EXTERNAL_SCHEMA, 54 Constants.EXTERNAL_ACCESS_DEFAULT); 55 56 final String name; 57 final String defaultValue; 58 59 Property(String name, String value) { 60 this.name = name; 61 this.defaultValue = value; 62 } 63 64 public boolean equalsName(String propertyName) { 65 return (propertyName == null) ? false : name.equals(propertyName); 66 } 67 68 String defaultValue() { 69 return defaultValue; 70 } 71 } 72 73 /** 74 * Values of the properties as defined in enum Properties 75 */ 76 private final String[] values; 77 /** 78 * States of the settings for each property in Properties above 79 */ 80 private State[] states = {State.DEFAULT, State.DEFAULT}; 81 82 /** 83 * Default constructor. Establishes default values 84 */ 85 public XMLSecurityPropertyManager() { 86 values = new String[Property.values().length]; 87 for (Property property : Property.values()) { 88 values[property.ordinal()] = property.defaultValue(); 89 } 90 //read system properties or jaxp.properties 91 readSystemProperties(); 92 } 93 94 /** 95 * Clone a XMLSecurityPropertyManager 96 * @param propertyManager the base XMLSecurityPropertyManager 97 */ 98 public XMLSecurityPropertyManager(XMLSecurityPropertyManager propertyManager) { 99 values = new String[Property.values().length]; 100 if (propertyManager != null) { 101 for (Property property : Property.values()) { 102 values[property.ordinal()] = propertyManager.getValue(property); 103 states[property.ordinal()] = propertyManager.getState(property); 104 } 105 } 106 } 107 108 /** 109 * Set limit by property name and state 110 * @param propertyName property name 111 * @param state the state of the property 112 * @param value the value of the property 113 * @return true if the property is managed by the security property manager; 114 * false if otherwise. 115 */ 116 public boolean setValue(String propertyName, State state, Object value) { 117 int index = getIndex(propertyName); 118 if (index > -1) { 119 setValue(index, state, (String)value); 120 return true; 121 } 122 return false; 123 } 124 125 /** 126 * Set the value for a specific property. 127 * 128 * @param property the property 129 * @param state the state of the property 130 * @param value the value of the property 131 */ 132 public void setValue(Property property, State state, String value) { 133 //only update if it shall override 134 if (state.compareTo(states[property.ordinal()]) >= 0) { 135 values[property.ordinal()] = value; 136 states[property.ordinal()] = state; 137 } 138 } 139 140 /** 141 * Set the value of a property by its index 142 * @param index the index of the property 143 * @param state the state of the property 144 * @param value the value of the property 145 */ 146 public void setValue(int index, State state, String value) { 147 //only update if it shall override 148 if (state.compareTo(states[index]) >= 0) { 149 values[index] = value; 150 states[index] = state; 151 } 152 } 153 154 155 /** 156 * Return the value of the specified property 157 * 158 * @param propertyName the property name 159 * @return the value of the property as a string 160 */ 161 public String getValue(String propertyName) { 162 int index = getIndex(propertyName); 163 if (index > -1) { 164 return getValueByIndex(index); 165 } 166 167 return null; 168 } 169 170 /** 171 * Return the value of the specified property 172 * 173 * @param property the property 174 * @return the value of the property 175 */ 176 public String getValue(Property property) { 177 return values[property.ordinal()]; 178 } 179 180 /** 181 * Return the value of a property by its ordinal 182 * @param index the index of a property 183 * @return value of a property 184 */ 185 public String getValueByIndex(int index) { 186 return values[index]; 187 } 188 189 /** 190 * Get the index by property name 191 * @param propertyName property name 192 * @return the index of the property if found; return -1 if not 193 */ 194 public int getIndex(String propertyName){ 195 for (Property property : Property.values()) { 196 if (property.equalsName(propertyName)) { 197 //internally, ordinal is used as index 198 return property.ordinal(); 199 } 200 } 201 return -1; 202 } 203 204 /** 205 * Return the state of a property 206 * @param property 207 * @return return the state of the property 208 */ 209 public State getState(Property property) { 210 return states[property.ordinal()]; 211 } 212 213 /** 214 * Read from system properties, or those in jaxp.properties 215 */ 216 private void readSystemProperties() { 217 getSystemProperty(Property.ACCESS_EXTERNAL_DTD, 218 Constants.SP_ACCESS_EXTERNAL_DTD); 219 getSystemProperty(Property.ACCESS_EXTERNAL_SCHEMA, 220 Constants.SP_ACCESS_EXTERNAL_SCHEMA); 221 } 222 223 /** 224 * Read from system properties, or those in jaxp.properties 225 * 226 * @param property the property 227 * @param systemProperty the name of the system property 228 */ 229 private void getSystemProperty(Property property, String systemProperty) { 230 try { 231 String value = SecuritySupport.getSystemProperty(systemProperty); 232 if (value != null) { 233 values[property.ordinal()] = value; 234 states[property.ordinal()] = State.SYSTEMPROPERTY; 235 return; 236 } 237 238 value = SecuritySupport.readJAXPProperty(systemProperty); 239 if (value != null) { 240 values[property.ordinal()] = value; 241 states[property.ordinal()] = State.JAXPDOTPROPERTIES; 242 } 243 } catch (NumberFormatException e) { 244 //invalid setting ignored 245 } 246 } 247 }