View Javadoc
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      /**
96       * Set limit by property name and state
97       * @param propertyName property name
98       * @param state the state of the property
99       * @param value the value of the property
100      * @return true if the property is managed by the security property manager;
101      *         false if otherwise.
102      */
103     public boolean setValue(String propertyName, State state, Object value) {
104         int index = getIndex(propertyName);
105         if (index > -1) {
106             setValue(index, state, (String)value);
107             return true;
108         }
109         return false;
110     }
111 
112     /**
113      * Set the value for a specific property.
114      *
115      * @param property the property
116      * @param state the state of the property
117      * @param value the value of the property
118      */
119     public void setValue(Property property, State state, String value) {
120         //only update if it shall override
121         if (state.compareTo(states[property.ordinal()]) >= 0) {
122             values[property.ordinal()] = value;
123             states[property.ordinal()] = state;
124         }
125     }
126 
127     /**
128      * Set the value of a property by its index
129      * @param index the index of the property
130      * @param state the state of the property
131      * @param value the value of the property
132      */
133     public void setValue(int index, State state, String value) {
134         //only update if it shall override
135         if (state.compareTo(states[index]) >= 0) {
136             values[index] = value;
137             states[index] = state;
138         }
139     }
140 
141 
142     /**
143      * Return the value of the specified property
144      *
145      * @param propertyName the property name
146      * @return the value of the property as a string
147      */
148     public String getValue(String propertyName) {
149         int index = getIndex(propertyName);
150         if (index > -1) {
151             return getValueByIndex(index);
152         }
153 
154         return null;
155     }
156 
157     /**
158      * Return the value of the specified property
159      *
160      * @param property the property
161      * @return the value of the property
162      */
163     public String getValue(Property property) {
164         return values[property.ordinal()];
165     }
166 
167     /**
168      * Return the value of a property by its ordinal
169      * @param index the index of a property
170      * @return value of a property
171      */
172     public String getValueByIndex(int index) {
173         return values[index];
174     }
175 
176     /**
177      * Get the index by property name
178      * @param propertyName property name
179      * @return the index of the property if found; return -1 if not
180      */
181     public int getIndex(String propertyName){
182         for (Property property : Property.values()) {
183             if (property.equalsName(propertyName)) {
184                 //internally, ordinal is used as index
185                 return property.ordinal();
186             }
187         }
188         return -1;
189     }
190 
191     /**
192      * Read from system properties, or those in jaxp.properties
193      */
194     private void readSystemProperties() {
195         getSystemProperty(Property.ACCESS_EXTERNAL_DTD,
196                 Constants.SP_ACCESS_EXTERNAL_DTD);
197         getSystemProperty(Property.ACCESS_EXTERNAL_SCHEMA,
198                 Constants.SP_ACCESS_EXTERNAL_SCHEMA);
199     }
200 
201     /**
202      * Read from system properties, or those in jaxp.properties
203      *
204      * @param property the property
205      * @param systemProperty the name of the system property
206      */
207     private void getSystemProperty(Property property, String systemProperty) {
208         try {
209             String value = SecuritySupport.getSystemProperty(systemProperty);
210             if (value != null) {
211                 values[property.ordinal()] = value;
212                 states[property.ordinal()] = State.SYSTEMPROPERTY;
213                 return;
214             }
215 
216             value = SecuritySupport.readJAXPProperty(systemProperty);
217             if (value != null) {
218                 values[property.ordinal()] = value;
219                 states[property.ordinal()] = State.JAXPDOTPROPERTIES;
220             }
221         } catch (NumberFormatException e) {
222             //invalid setting ignored
223         }
224     }
225 }