1. /*
  2. * @(#)DataCollectorBase.java 1.19 04/03/01
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.impl.orb ;
  8. import com.sun.corba.se.impl.orbutil.GetPropertyAction ;
  9. import java.security.PrivilegedAction ;
  10. import java.security.AccessController ;
  11. import java.applet.Applet ;
  12. import java.util.Properties ;
  13. import java.util.Vector ;
  14. import java.util.Set ;
  15. import java.util.HashSet ;
  16. import java.util.Enumeration ;
  17. import java.util.Iterator ;
  18. import java.util.StringTokenizer ;
  19. import java.net.URL ;
  20. import java.security.AccessController ;
  21. import java.io.File ;
  22. import java.io.FileInputStream ;
  23. import com.sun.corba.se.spi.orb.DataCollector ;
  24. import com.sun.corba.se.spi.orb.PropertyParser ;
  25. import com.sun.corba.se.impl.orbutil.ORBConstants ;
  26. import com.sun.corba.se.impl.orbutil.ORBUtility;
  27. public abstract class DataCollectorBase implements DataCollector {
  28. private PropertyParser parser ;
  29. private Set propertyNames ;
  30. private Set propertyPrefixes ;
  31. private Set URLPropertyNames ;
  32. protected String localHostName ;
  33. protected String configurationHostName ;
  34. private boolean setParserCalled ;
  35. private Properties originalProps ;
  36. private Properties resultProps ;
  37. public DataCollectorBase( Properties props, String localHostName,
  38. String configurationHostName )
  39. {
  40. // XXX This is fully initialized here. So do we ever want to
  41. // generalize this (or perhaps this is the wrong place for this?)
  42. URLPropertyNames = new HashSet() ;
  43. URLPropertyNames.add( ORBConstants.INITIAL_SERVICES_PROPERTY ) ;
  44. propertyNames = new HashSet() ;
  45. // Make sure that we are ready to handle -ORBInitRef. This is special
  46. // due to the need to handle multiple -ORBInitRef args as prefix
  47. // parsing.
  48. propertyNames.add( ORBConstants.ORB_INIT_REF_PROPERTY ) ;
  49. propertyPrefixes = new HashSet() ;
  50. this.originalProps = props ;
  51. this.localHostName = localHostName ;
  52. this.configurationHostName = configurationHostName ;
  53. setParserCalled = false ;
  54. resultProps = new Properties() ;
  55. }
  56. //////////////////////////////////////////////////////////
  57. // Public interface defined in DataCollector
  58. //////////////////////////////////////////////////////////
  59. public boolean initialHostIsLocal()
  60. {
  61. checkSetParserCalled() ;
  62. return localHostName.equals( resultProps.getProperty(
  63. ORBConstants.INITIAL_HOST_PROPERTY ) ) ;
  64. }
  65. public void setParser( PropertyParser parser )
  66. {
  67. Iterator iter = parser.iterator() ;
  68. while (iter.hasNext()) {
  69. ParserAction pa = (ParserAction)(iter.next()) ;
  70. if (pa.isPrefix())
  71. propertyPrefixes.add( pa.getPropertyName() ) ;
  72. else
  73. propertyNames.add( pa.getPropertyName() ) ;
  74. }
  75. collect() ;
  76. setParserCalled = true ;
  77. }
  78. public Properties getProperties()
  79. {
  80. checkSetParserCalled() ;
  81. return resultProps ;
  82. }
  83. //////////////////////////////////////////////////////////
  84. // public interface from DataCollector that must be defined
  85. // in subclasses
  86. //////////////////////////////////////////////////////////
  87. public abstract boolean isApplet() ;
  88. //////////////////////////////////////////////////////////
  89. // Implementation methods needed in subclasses
  90. //////////////////////////////////////////////////////////
  91. protected abstract void collect() ;
  92. //////////////////////////////////////////////////////////
  93. // methods for use by subclasses
  94. //////////////////////////////////////////////////////////
  95. protected void checkPropertyDefaults()
  96. {
  97. String host =
  98. resultProps.getProperty( ORBConstants.INITIAL_HOST_PROPERTY ) ;
  99. if ((host == null) || (host.equals("")))
  100. setProperty( ORBConstants.INITIAL_HOST_PROPERTY,
  101. configurationHostName );
  102. String serverHost =
  103. resultProps.getProperty( ORBConstants.SERVER_HOST_PROPERTY ) ;
  104. if (serverHost == null ||
  105. serverHost.equals("") ||
  106. serverHost.equals("0.0.0.0") ||
  107. serverHost.equals("::") ||
  108. serverHost.toLowerCase().equals("::ffff:0.0.0.0"))
  109. {
  110. setProperty(ORBConstants.SERVER_HOST_PROPERTY,
  111. localHostName);
  112. setProperty(ORBConstants.LISTEN_ON_ALL_INTERFACES,
  113. ORBConstants.LISTEN_ON_ALL_INTERFACES);
  114. }
  115. }
  116. protected void findPropertiesFromArgs( String[] params )
  117. {
  118. if (params == null)
  119. return;
  120. // All command-line args are of the form "-ORBkey value".
  121. // The key is mapped to <prefix>.ORBkey.
  122. String name ;
  123. String value ;
  124. for ( int i=0; i<params.length; i++ ) {
  125. value = null ;
  126. name = null ;
  127. if ( params[i] != null && params[i].startsWith("-ORB") ) {
  128. String argName = params[i].substring( 1 ) ;
  129. name = findMatchingPropertyName( propertyNames, argName ) ;
  130. if (name != null)
  131. if ( i+1 < params.length && params[i+1] != null ) {
  132. value = params[++i];
  133. }
  134. }
  135. if (value != null) {
  136. setProperty( name, value ) ;
  137. }
  138. }
  139. }
  140. protected void findPropertiesFromApplet( final Applet app )
  141. {
  142. // Cannot use propertyPrefixes here, since there is no
  143. // way to fetch properties by prefix from an Applet.
  144. if (app == null)
  145. return;
  146. PropertyCallback callback = new PropertyCallback() {
  147. public String get(String name) {
  148. return app.getParameter(name);
  149. }
  150. } ;
  151. findPropertiesByName( propertyNames.iterator(), callback ) ;
  152. // Special Case:
  153. //
  154. // Convert any applet parameter relative URLs to an
  155. // absolute URL based on the Document Root. This is so HTML
  156. // URLs can be kept relative which is sometimes useful for
  157. // managing the Document Root layout.
  158. PropertyCallback URLCallback = new PropertyCallback() {
  159. public String get( String name ) {
  160. String value = resultProps.getProperty(name);
  161. if (value == null)
  162. return null ;
  163. try {
  164. URL url = new URL( app.getDocumentBase(), value ) ;
  165. return url.toExternalForm() ;
  166. } catch (java.net.MalformedURLException exc) {
  167. // Just preserve the original (malformed) value:
  168. // the error will be handled later.
  169. return value ;
  170. }
  171. }
  172. } ;
  173. findPropertiesByName( URLPropertyNames.iterator(),
  174. URLCallback ) ;
  175. }
  176. private void doProperties( final Properties props )
  177. {
  178. PropertyCallback callback = new PropertyCallback() {
  179. public String get(String name) {
  180. return props.getProperty(name);
  181. }
  182. } ;
  183. findPropertiesByName( propertyNames.iterator(), callback ) ;
  184. findPropertiesByPrefix( propertyPrefixes,
  185. makeIterator( props.propertyNames()), callback );
  186. }
  187. protected void findPropertiesFromFile()
  188. {
  189. final Properties fileProps = getFileProperties() ;
  190. if (fileProps==null)
  191. return ;
  192. doProperties( fileProps ) ;
  193. }
  194. protected void findPropertiesFromProperties()
  195. {
  196. if (originalProps == null)
  197. return;
  198. doProperties( originalProps ) ;
  199. }
  200. //
  201. // Map System properties to ORB properties.
  202. // Security bug fix 4278205:
  203. // Only allow reading of system properties with ORB prefixes.
  204. // Previously a malicious subclass was able to read ANY system property.
  205. // Note that other prefixes are fine in other contexts; it is only
  206. // system properties that should impose a restriction.
  207. protected void findPropertiesFromSystem()
  208. {
  209. Set normalNames = getCORBAPrefixes( propertyNames ) ;
  210. Set prefixNames = getCORBAPrefixes( propertyPrefixes ) ;
  211. PropertyCallback callback = new PropertyCallback() {
  212. public String get(String name) {
  213. return getSystemProperty(name);
  214. }
  215. } ;
  216. findPropertiesByName( normalNames.iterator(), callback ) ;
  217. findPropertiesByPrefix( prefixNames,
  218. getSystemPropertyNames(), callback ) ;
  219. }
  220. //////////////////////////////////////////////////////////
  221. // internal implementation
  222. //////////////////////////////////////////////////////////
  223. // Store name, value in resultProps, with special
  224. // treatment of ORBInitRef. All updates to resultProps
  225. // must happen through this method.
  226. private void setProperty( String name, String value )
  227. {
  228. if( name.equals( ORBConstants.ORB_INIT_REF_PROPERTY ) ) {
  229. // Value is <name>=<URL>
  230. StringTokenizer st = new StringTokenizer( value, "=" ) ;
  231. if (st.countTokens() != 2)
  232. throw new IllegalArgumentException() ;
  233. String refName = st.nextToken() ;
  234. String refValue = st.nextToken() ;
  235. resultProps.setProperty( name + "." + refName, refValue ) ;
  236. } else {
  237. resultProps.setProperty( name, value ) ;
  238. }
  239. }
  240. private void checkSetParserCalled()
  241. {
  242. if (!setParserCalled)
  243. throw new IllegalStateException( "setParser not called." ) ;
  244. }
  245. // For each prefix in prefixes, For each name in propertyNames,
  246. // if (prefix is a prefix of name) get value from getProperties and
  247. // setProperty (name, value).
  248. private void findPropertiesByPrefix( Set prefixes,
  249. Iterator propertyNames, PropertyCallback getProperty )
  250. {
  251. while (propertyNames.hasNext()) {
  252. String name = (String)(propertyNames.next()) ;
  253. Iterator iter = prefixes.iterator() ;
  254. while (iter.hasNext()) {
  255. String prefix = (String)(iter.next()) ;
  256. if (name.startsWith( prefix )) {
  257. String value = getProperty.get( name ) ;
  258. // Note: do a put even if value is null since just
  259. // the presence of the property may be significant.
  260. setProperty( name, value ) ;
  261. }
  262. }
  263. }
  264. }
  265. // For each prefix in names, get the corresponding property
  266. // value from the callback, and store the name/value pair in
  267. // the result.
  268. private void findPropertiesByName( Iterator names,
  269. PropertyCallback getProperty )
  270. {
  271. while (names.hasNext()) {
  272. String name = (String)(names.next()) ;
  273. String value = getProperty.get( name ) ;
  274. if (value != null)
  275. setProperty( name, value ) ;
  276. }
  277. }
  278. private static String getSystemProperty(final String name)
  279. {
  280. return (String)AccessController.doPrivileged(
  281. new GetPropertyAction(name));
  282. }
  283. // Map command-line arguments to ORB properties.
  284. //
  285. private String findMatchingPropertyName( Set names,
  286. String suffix )
  287. {
  288. Iterator iter = names.iterator() ;
  289. while (iter.hasNext()) {
  290. String name = (String)(iter.next()) ;
  291. if (name.endsWith( suffix ))
  292. return name ;
  293. }
  294. return null ;
  295. }
  296. private static Iterator makeIterator( final Enumeration enumeration )
  297. {
  298. return new Iterator() {
  299. public boolean hasNext() { return enumeration.hasMoreElements() ; }
  300. public Object next() { return enumeration.nextElement() ; }
  301. public void remove() { throw new UnsupportedOperationException() ; }
  302. } ;
  303. }
  304. private static Iterator getSystemPropertyNames()
  305. {
  306. // This will not throw a SecurityException because this
  307. // class was loaded from rt.jar using the bootstrap classloader.
  308. Enumeration enumeration = (Enumeration)
  309. AccessController.doPrivileged(
  310. new PrivilegedAction() {
  311. public java.lang.Object run() {
  312. return System.getProperties().propertyNames();
  313. }
  314. }
  315. );
  316. return makeIterator( enumeration ) ;
  317. }
  318. private void getPropertiesFromFile( Properties props, String fileName )
  319. {
  320. try {
  321. File file = new File( fileName ) ;
  322. if (!file.exists())
  323. return ;
  324. FileInputStream in = new FileInputStream( file ) ;
  325. try {
  326. props.load( in ) ;
  327. } finally {
  328. in.close() ;
  329. }
  330. } catch (Exception exc) {
  331. // if (ORBInitDebug)
  332. // dprint( "ORB properties file " + fileName + " not found: " +
  333. // exc) ;
  334. }
  335. }
  336. private Properties getFileProperties()
  337. {
  338. Properties defaults = new Properties() ;
  339. String javaHome = getSystemProperty( "java.home" ) ;
  340. String fileName = javaHome + File.separator + "lib" + File.separator +
  341. "orb.properties" ;
  342. getPropertiesFromFile( defaults, fileName ) ;
  343. Properties results = new Properties( defaults ) ;
  344. String userHome = getSystemProperty( "user.home" ) ;
  345. fileName = userHome + File.separator + "orb.properties" ;
  346. getPropertiesFromFile( results, fileName ) ;
  347. return results ;
  348. }
  349. private boolean hasCORBAPrefix( String prefix )
  350. {
  351. return prefix.startsWith( ORBConstants.ORG_OMG_PREFIX ) ||
  352. prefix.startsWith( ORBConstants.SUN_PREFIX ) ||
  353. prefix.startsWith( ORBConstants.SUN_LC_PREFIX ) ||
  354. prefix.startsWith( ORBConstants.SUN_LC_VERSION_PREFIX ) ;
  355. }
  356. // Return only those element of prefixes for which hasCORBAPrefix
  357. // is true.
  358. private Set getCORBAPrefixes( final Set prefixes )
  359. {
  360. Set result = new HashSet() ;
  361. Iterator iter = prefixes.iterator() ;
  362. while (iter.hasNext()) {
  363. String element = (String)(iter.next()) ;
  364. if (hasCORBAPrefix( element ))
  365. result.add( element ) ;
  366. }
  367. return result ;
  368. }
  369. }
  370. // Used to collect properties from various sources.
  371. abstract class PropertyCallback
  372. {
  373. abstract public String get(String name);
  374. }