Mon, 28 May 2018 10:29:43 +0800
Merge
1 /*
2 * Copyright (c) 2002, 2004, 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 */
26 package com.sun.corba.se.impl.orb ;
28 import com.sun.corba.se.impl.orbutil.GetPropertyAction ;
30 import java.security.PrivilegedAction ;
31 import java.security.AccessController ;
33 import java.applet.Applet ;
35 import java.util.Properties ;
36 import java.util.Vector ;
37 import java.util.Set ;
38 import java.util.HashSet ;
39 import java.util.Enumeration ;
40 import java.util.Iterator ;
41 import java.util.StringTokenizer ;
43 import java.net.URL ;
45 import java.security.AccessController ;
47 import java.io.File ;
48 import java.io.FileInputStream ;
50 import com.sun.corba.se.spi.orb.DataCollector ;
51 import com.sun.corba.se.spi.orb.PropertyParser ;
53 import com.sun.corba.se.impl.orbutil.ORBConstants ;
54 import com.sun.corba.se.impl.orbutil.ORBUtility;
56 public abstract class DataCollectorBase implements DataCollector {
57 private PropertyParser parser ;
58 private Set propertyNames ;
59 private Set propertyPrefixes ;
60 private Set URLPropertyNames ;
61 protected String localHostName ;
62 protected String configurationHostName ;
63 private boolean setParserCalled ;
64 private Properties originalProps ;
65 private Properties resultProps ;
67 public DataCollectorBase( Properties props, String localHostName,
68 String configurationHostName )
69 {
70 // XXX This is fully initialized here. So do we ever want to
71 // generalize this (or perhaps this is the wrong place for this?)
72 URLPropertyNames = new HashSet() ;
73 URLPropertyNames.add( ORBConstants.INITIAL_SERVICES_PROPERTY ) ;
75 propertyNames = new HashSet() ;
77 // Make sure that we are ready to handle -ORBInitRef. This is special
78 // due to the need to handle multiple -ORBInitRef args as prefix
79 // parsing.
80 propertyNames.add( ORBConstants.ORB_INIT_REF_PROPERTY ) ;
82 propertyPrefixes = new HashSet() ;
84 this.originalProps = props ;
85 this.localHostName = localHostName ;
86 this.configurationHostName = configurationHostName ;
87 setParserCalled = false ;
88 resultProps = new Properties() ;
89 }
91 //////////////////////////////////////////////////////////
92 // Public interface defined in DataCollector
93 //////////////////////////////////////////////////////////
95 public boolean initialHostIsLocal()
96 {
97 checkSetParserCalled() ;
98 return localHostName.equals( resultProps.getProperty(
99 ORBConstants.INITIAL_HOST_PROPERTY ) ) ;
100 }
102 public void setParser( PropertyParser parser )
103 {
104 Iterator iter = parser.iterator() ;
105 while (iter.hasNext()) {
106 ParserAction pa = (ParserAction)(iter.next()) ;
107 if (pa.isPrefix())
108 propertyPrefixes.add( pa.getPropertyName() ) ;
109 else
110 propertyNames.add( pa.getPropertyName() ) ;
111 }
113 collect() ;
114 setParserCalled = true ;
115 }
117 public Properties getProperties()
118 {
119 checkSetParserCalled() ;
120 return resultProps ;
121 }
123 //////////////////////////////////////////////////////////
124 // public interface from DataCollector that must be defined
125 // in subclasses
126 //////////////////////////////////////////////////////////
128 public abstract boolean isApplet() ;
130 //////////////////////////////////////////////////////////
131 // Implementation methods needed in subclasses
132 //////////////////////////////////////////////////////////
134 protected abstract void collect() ;
136 //////////////////////////////////////////////////////////
137 // methods for use by subclasses
138 //////////////////////////////////////////////////////////
140 protected void checkPropertyDefaults()
141 {
142 String host =
143 resultProps.getProperty( ORBConstants.INITIAL_HOST_PROPERTY ) ;
145 if ((host == null) || (host.equals("")))
146 setProperty( ORBConstants.INITIAL_HOST_PROPERTY,
147 configurationHostName );
149 String serverHost =
150 resultProps.getProperty( ORBConstants.SERVER_HOST_PROPERTY ) ;
152 if (serverHost == null ||
153 serverHost.equals("") ||
154 serverHost.equals("0.0.0.0") ||
155 serverHost.equals("::") ||
156 serverHost.toLowerCase().equals("::ffff:0.0.0.0"))
157 {
158 setProperty(ORBConstants.SERVER_HOST_PROPERTY,
159 localHostName);
160 setProperty(ORBConstants.LISTEN_ON_ALL_INTERFACES,
161 ORBConstants.LISTEN_ON_ALL_INTERFACES);
162 }
163 }
165 protected void findPropertiesFromArgs( String[] params )
166 {
167 if (params == null)
168 return;
170 // All command-line args are of the form "-ORBkey value".
171 // The key is mapped to <prefix>.ORBkey.
173 String name ;
174 String value ;
176 for ( int i=0; i<params.length; i++ ) {
177 value = null ;
178 name = null ;
180 if ( params[i] != null && params[i].startsWith("-ORB") ) {
181 String argName = params[i].substring( 1 ) ;
182 name = findMatchingPropertyName( propertyNames, argName ) ;
184 if (name != null)
185 if ( i+1 < params.length && params[i+1] != null ) {
186 value = params[++i];
187 }
188 }
190 if (value != null) {
191 setProperty( name, value ) ;
192 }
193 }
194 }
196 protected void findPropertiesFromApplet( final Applet app )
197 {
198 // Cannot use propertyPrefixes here, since there is no
199 // way to fetch properties by prefix from an Applet.
200 if (app == null)
201 return;
203 PropertyCallback callback = new PropertyCallback() {
204 public String get(String name) {
205 return app.getParameter(name);
206 }
207 } ;
209 findPropertiesByName( propertyNames.iterator(), callback ) ;
211 // Special Case:
212 //
213 // Convert any applet parameter relative URLs to an
214 // absolute URL based on the Document Root. This is so HTML
215 // URLs can be kept relative which is sometimes useful for
216 // managing the Document Root layout.
217 PropertyCallback URLCallback = new PropertyCallback() {
218 public String get( String name ) {
219 String value = resultProps.getProperty(name);
220 if (value == null)
221 return null ;
223 try {
224 URL url = new URL( app.getDocumentBase(), value ) ;
225 return url.toExternalForm() ;
226 } catch (java.net.MalformedURLException exc) {
227 // Just preserve the original (malformed) value:
228 // the error will be handled later.
229 return value ;
230 }
231 }
232 } ;
234 findPropertiesByName( URLPropertyNames.iterator(),
235 URLCallback ) ;
236 }
238 private void doProperties( final Properties props )
239 {
240 PropertyCallback callback = new PropertyCallback() {
241 public String get(String name) {
242 return props.getProperty(name);
243 }
244 } ;
246 findPropertiesByName( propertyNames.iterator(), callback ) ;
248 findPropertiesByPrefix( propertyPrefixes,
249 makeIterator( props.propertyNames()), callback );
250 }
252 protected void findPropertiesFromFile()
253 {
254 final Properties fileProps = getFileProperties() ;
255 if (fileProps==null)
256 return ;
258 doProperties( fileProps ) ;
259 }
261 protected void findPropertiesFromProperties()
262 {
263 if (originalProps == null)
264 return;
266 doProperties( originalProps ) ;
267 }
269 //
270 // Map System properties to ORB properties.
271 // Security bug fix 4278205:
272 // Only allow reading of system properties with ORB prefixes.
273 // Previously a malicious subclass was able to read ANY system property.
274 // Note that other prefixes are fine in other contexts; it is only
275 // system properties that should impose a restriction.
276 protected void findPropertiesFromSystem()
277 {
278 Set normalNames = getCORBAPrefixes( propertyNames ) ;
279 Set prefixNames = getCORBAPrefixes( propertyPrefixes ) ;
281 PropertyCallback callback = new PropertyCallback() {
282 public String get(String name) {
283 return getSystemProperty(name);
284 }
285 } ;
287 findPropertiesByName( normalNames.iterator(), callback ) ;
289 findPropertiesByPrefix( prefixNames,
290 getSystemPropertyNames(), callback ) ;
291 }
293 //////////////////////////////////////////////////////////
294 // internal implementation
295 //////////////////////////////////////////////////////////
297 // Store name, value in resultProps, with special
298 // treatment of ORBInitRef. All updates to resultProps
299 // must happen through this method.
300 private void setProperty( String name, String value )
301 {
302 if( name.equals( ORBConstants.ORB_INIT_REF_PROPERTY ) ) {
303 // Value is <name>=<URL>
304 StringTokenizer st = new StringTokenizer( value, "=" ) ;
305 if (st.countTokens() != 2)
306 throw new IllegalArgumentException() ;
308 String refName = st.nextToken() ;
309 String refValue = st.nextToken() ;
311 resultProps.setProperty( name + "." + refName, refValue ) ;
312 } else {
313 resultProps.setProperty( name, value ) ;
314 }
315 }
317 private void checkSetParserCalled()
318 {
319 if (!setParserCalled)
320 throw new IllegalStateException( "setParser not called." ) ;
321 }
323 // For each prefix in prefixes, For each name in propertyNames,
324 // if (prefix is a prefix of name) get value from getProperties and
325 // setProperty (name, value).
326 private void findPropertiesByPrefix( Set prefixes,
327 Iterator propertyNames, PropertyCallback getProperty )
328 {
329 while (propertyNames.hasNext()) {
330 String name = (String)(propertyNames.next()) ;
331 Iterator iter = prefixes.iterator() ;
332 while (iter.hasNext()) {
333 String prefix = (String)(iter.next()) ;
334 if (name.startsWith( prefix )) {
335 String value = getProperty.get( name ) ;
337 // Note: do a put even if value is null since just
338 // the presence of the property may be significant.
339 setProperty( name, value ) ;
340 }
341 }
342 }
343 }
345 // For each prefix in names, get the corresponding property
346 // value from the callback, and store the name/value pair in
347 // the result.
348 private void findPropertiesByName( Iterator names,
349 PropertyCallback getProperty )
350 {
351 while (names.hasNext()) {
352 String name = (String)(names.next()) ;
353 String value = getProperty.get( name ) ;
354 if (value != null)
355 setProperty( name, value ) ;
356 }
357 }
359 private static String getSystemProperty(final String name)
360 {
361 return (String)AccessController.doPrivileged(
362 new GetPropertyAction(name));
363 }
365 // Map command-line arguments to ORB properties.
366 //
367 private String findMatchingPropertyName( Set names,
368 String suffix )
369 {
370 Iterator iter = names.iterator() ;
371 while (iter.hasNext()) {
372 String name = (String)(iter.next()) ;
373 if (name.endsWith( suffix ))
374 return name ;
375 }
377 return null ;
378 }
380 private static Iterator makeIterator( final Enumeration enumeration )
381 {
382 return new Iterator() {
383 public boolean hasNext() { return enumeration.hasMoreElements() ; }
384 public Object next() { return enumeration.nextElement() ; }
385 public void remove() { throw new UnsupportedOperationException() ; }
386 } ;
387 }
389 private static Iterator getSystemPropertyNames()
390 {
391 // This will not throw a SecurityException because this
392 // class was loaded from rt.jar using the bootstrap classloader.
393 Enumeration enumeration = (Enumeration)
394 AccessController.doPrivileged(
395 new PrivilegedAction() {
396 public java.lang.Object run() {
397 return System.getProperties().propertyNames();
398 }
399 }
400 );
402 return makeIterator( enumeration ) ;
403 }
405 private void getPropertiesFromFile( Properties props, String fileName )
406 {
407 try {
408 File file = new File( fileName ) ;
409 if (!file.exists())
410 return ;
412 FileInputStream in = new FileInputStream( file ) ;
414 try {
415 props.load( in ) ;
416 } finally {
417 in.close() ;
418 }
419 } catch (Exception exc) {
420 // if (ORBInitDebug)
421 // dprint( "ORB properties file " + fileName + " not found: " +
422 // exc) ;
423 }
424 }
426 private Properties getFileProperties()
427 {
428 Properties defaults = new Properties() ;
430 String javaHome = getSystemProperty( "java.home" ) ;
431 String fileName = javaHome + File.separator + "lib" + File.separator +
432 "orb.properties" ;
434 getPropertiesFromFile( defaults, fileName ) ;
436 Properties results = new Properties( defaults ) ;
438 String userHome = getSystemProperty( "user.home" ) ;
439 fileName = userHome + File.separator + "orb.properties" ;
441 getPropertiesFromFile( results, fileName ) ;
442 return results ;
443 }
445 private boolean hasCORBAPrefix( String prefix )
446 {
447 return prefix.startsWith( ORBConstants.ORG_OMG_PREFIX ) ||
448 prefix.startsWith( ORBConstants.SUN_PREFIX ) ||
449 prefix.startsWith( ORBConstants.SUN_LC_PREFIX ) ||
450 prefix.startsWith( ORBConstants.SUN_LC_VERSION_PREFIX ) ;
451 }
453 // Return only those element of prefixes for which hasCORBAPrefix
454 // is true.
455 private Set getCORBAPrefixes( final Set prefixes )
456 {
457 Set result = new HashSet() ;
458 Iterator iter = prefixes.iterator() ;
459 while (iter.hasNext()) {
460 String element = (String)(iter.next()) ;
461 if (hasCORBAPrefix( element ))
462 result.add( element ) ;
463 }
465 return result ;
466 }
467 }
469 // Used to collect properties from various sources.
470 abstract class PropertyCallback
471 {
472 abstract public String get(String name);
473 }