View Javadoc
1 /* 2 * Copyright (C) The Spice Group. All rights reserved. 3 * 4 * This software is published under the terms of the Spice 5 * Software License version 1.1, a copy of which has been included 6 * with this distribution in the LICENSE.txt file. 7 */ 8 package org.codehaus.spice.xmlpolicy.builder; 9 10 import java.io.InputStream; 11 import java.lang.reflect.Constructor; 12 import java.net.MalformedURLException; 13 import java.net.URL; 14 import java.security.CodeSource; 15 import java.security.KeyStore; 16 import java.security.KeyStoreException; 17 import java.security.Permission; 18 import java.security.Policy; 19 import java.security.UnresolvedPermission; 20 import java.security.cert.Certificate; 21 import java.util.ArrayList; 22 import java.util.HashMap; 23 import java.util.List; 24 import java.util.Map; 25 import java.util.PropertyPermission; 26 import java.util.StringTokenizer; 27 import org.codehaus.spice.xmlpolicy.metadata.GrantMetaData; 28 import org.codehaus.spice.xmlpolicy.metadata.KeyStoreMetaData; 29 import org.codehaus.spice.xmlpolicy.metadata.PermissionMetaData; 30 import org.codehaus.spice.xmlpolicy.metadata.PolicyMetaData; 31 32 /*** 33 * A Utility class that builds a Policy object from a specified 34 * PolicyMetaData. 35 * 36 * @author Peter Donald 37 * @version $Revision: 1.1 $ $Date: 2003/12/02 09:16:06 $ 38 */ 39 public class PolicyBuilder 40 { 41 /*** 42 * Build a policy for a specified meta data. 43 * 44 * @param policy the policy metadata 45 * @return the Policy object 46 * @throws Exception if unable to create Policy object 47 */ 48 public Policy buildPolicy( final PolicyMetaData policy, 49 final PolicyResolver resolver ) 50 throws Exception 51 { 52 if( null == policy ) 53 { 54 throw new NullPointerException( "policy" ); 55 } 56 if( null == resolver ) 57 { 58 throw new NullPointerException( "resolver" ); 59 } 60 61 final Map keyStores = 62 createKeyStores( policy.getKeyStores(), resolver ); 63 final Map grants = new HashMap(); 64 processGrants( policy.getGrants(), keyStores, grants, resolver ); 65 66 final CodeSource codeSource = createDefaultCodeSource(); 67 final Permission[] permissions = getDefaultPermissions(); 68 grants.put( codeSource, permissions ); 69 70 return resolver.createPolicy( grants ); 71 } 72 73 /*** 74 * Porcess all the grants and build up a grant map. 75 * 76 * @param metaDatas the metadata 77 * @param keyStores the configured keystores 78 * @param grants the grant map 79 * @param resolver the resolver to use to resolve locations etc 80 * @throws Exception if unable to create grant map 81 */ 82 private void processGrants( final GrantMetaData[] metaDatas, 83 final Map keyStores, 84 final Map grants, 85 final PolicyResolver resolver ) 86 throws Exception 87 { 88 for( int i = 0; i < metaDatas.length; i++ ) 89 { 90 processGrant( metaDatas[ i ], keyStores, grants, resolver ); 91 } 92 } 93 94 /*** 95 * Porcess a grants and add to the grant map. 96 * 97 * @param metaData the metadata 98 * @param keyStores the configured keystores 99 * @param grants the grant map 100 * @param resolver the resolver to use to resolve locations etc 101 * @throws Exception if unable to create grant map 102 */ 103 private void processGrant( final GrantMetaData metaData, 104 final Map keyStores, 105 final Map grants, 106 final PolicyResolver resolver ) 107 throws Exception 108 { 109 final URL url = 110 resolver.resolveLocation( metaData.getCodebase() ); 111 112 final Certificate[] signers = 113 getSigners( metaData.getSignedBy(), 114 metaData.getKeyStore(), 115 keyStores ); 116 final CodeSource codeSource = new CodeSource( url, signers ); 117 118 final Permission[] permissions = 119 createPermissions( metaData.getPermissions(), 120 keyStores ); 121 grants.put( codeSource, permissions ); 122 } 123 124 /*** 125 * Create all permissions for specified metadata. 126 * 127 * @param metaDatas the metadata 128 * @param keyStores the keystores to use when loading signers 129 * @return the created permissions 130 * @throws Exception if unabel to create permissions 131 */ 132 private Permission[] createPermissions( final PermissionMetaData[] metaDatas, 133 final Map keyStores ) 134 throws Exception 135 { 136 final List set = new ArrayList(); 137 138 for( int i = 0; i < metaDatas.length; i++ ) 139 { 140 final Permission permission = 141 createPermission( metaDatas[ i ], keyStores ); 142 set.add( permission ); 143 } 144 145 return (Permission[])set.toArray( new Permission[ set.size() ] ); 146 } 147 148 /*** 149 * Create a permission for metadata. 150 * 151 * @param metaData the permission metadata 152 * @param keyStores the keystore to use (if needed) 153 * @return the created permission 154 * @throws Exception if unable to create permission 155 */ 156 private Permission createPermission( final PermissionMetaData metaData, 157 final Map keyStores ) 158 throws Exception 159 { 160 final String type = metaData.getClassname(); 161 final String actions = metaData.getAction(); 162 final String signedBy = metaData.getSignedBy(); 163 final String keyStoreName = metaData.getKeyStore(); 164 final String target = metaData.getTarget(); 165 166 final Certificate[] signers = 167 getSigners( signedBy, keyStoreName, keyStores ); 168 return createPermission( type, target, actions, signers ); 169 } 170 171 /*** 172 * Create a mpa of keystores from specified metadata. 173 * 174 * @param metaDatas the metadata 175 * @return the keystore map 176 * @throws Exception if unable to create all keystores 177 */ 178 private Map createKeyStores( final KeyStoreMetaData[] metaDatas, 179 final PolicyResolver resolver ) 180 throws Exception 181 { 182 final Map keyStores = new HashMap(); 183 184 for( int i = 0; i < metaDatas.length; i++ ) 185 { 186 final KeyStoreMetaData metaData = metaDatas[ i ]; 187 final String name = metaData.getName(); 188 189 try 190 { 191 final URL url = 192 resolver.resolveLocation( metaData.getLocation() ); 193 final KeyStore keyStore = 194 createKeyStore( metaData.getType(), url ); 195 196 keyStores.put( name, keyStore ); 197 } 198 catch( final Exception e ) 199 { 200 final String message = 201 "Error creating keystore " + name + ". Due to " + e; 202 throw new Exception( message ); 203 } 204 } 205 206 return keyStores; 207 } 208 209 /*** 210 * Create a permission of specified class and 211 * with specified target, action and signers. 212 * 213 * @param type the classname of Permission object 214 * @param target the target of permission 215 * @param actions the actions allowed on permission (if any) 216 * @param signers the signers (if any) 217 * @return the created Permission object 218 * @throws Exception if unable to create permission 219 */ 220 private final Permission createPermission( final String type, 221 final String target, 222 final String actions, 223 final Certificate[] signers ) 224 throws Exception 225 { 226 if( null != signers ) 227 { 228 return new UnresolvedPermission( type, target, actions, signers ); 229 } 230 231 try 232 { 233 final Class clazz = Class.forName( type ); 234 235 Class paramClasses[] = null; 236 Object params[] = null; 237 238 if( null == actions && null == target ) 239 { 240 paramClasses = new Class[ 0 ]; 241 params = new Object[ 0 ]; 242 } 243 else if( null == actions ) 244 { 245 paramClasses = new Class[ 1 ]; 246 paramClasses[ 0 ] = String.class; 247 params = new Object[ 1 ]; 248 params[ 0 ] = target; 249 } 250 else 251 { 252 paramClasses = new Class[ 2 ]; 253 paramClasses[ 0 ] = String.class; 254 paramClasses[ 1 ] = String.class; 255 params = new Object[ 2 ]; 256 params[ 0 ] = target; 257 params[ 1 ] = actions; 258 } 259 260 final Constructor constructor = clazz.getConstructor( paramClasses ); 261 return (Permission)constructor.newInstance( params ); 262 } 263 catch( final ClassNotFoundException cnfe ) 264 { 265 return new UnresolvedPermission( type, target, actions, signers ); 266 } 267 } 268 269 /*** 270 * Create a keystore of specified type and loading from specified url. 271 * 272 * @param type the type of key store 273 * @param url the location of key store data 274 * @return the create and configured keystore 275 * @throws Exception if unable to create or load keystore 276 */ 277 protected KeyStore createKeyStore( final String type, 278 final URL url ) 279 throws Exception 280 { 281 final KeyStore keyStore = KeyStore.getInstance( type ); 282 final InputStream ins = url.openStream(); 283 keyStore.load( ins, null ); 284 return keyStore; 285 } 286 287 /*** 288 * Retrieve Certificates for specified signers 289 * as loaded from keyStore. 290 * 291 * @param signedBy the signers 292 * @param keyStoreName the name of keystore 293 * @param keyStores the list of keystores to lookup 294 * @return the certificates 295 * @throws Exception if unable to get signers 296 */ 297 private Certificate[] getSigners( final String signedBy, 298 final String keyStoreName, 299 final Map keyStores ) 300 throws Exception 301 { 302 if( null == signedBy ) 303 { 304 return null; 305 } 306 else 307 { 308 final KeyStore keyStore = getKeyStore( keyStoreName, keyStores ); 309 return getCertificates( signedBy, keyStore ); 310 } 311 } 312 313 /*** 314 * Retrieve the set of Ceritificates for all signers. 315 * 316 * @param signedBy the comma separated list of signers 317 * @param keyStore the keystore to look for signers certificates in 318 * @return the certificate set 319 * @throws Exception if unabel to create certificates 320 */ 321 private Certificate[] getCertificates( final String signedBy, 322 final KeyStore keyStore ) 323 throws Exception 324 { 325 final List certificateSet = new ArrayList(); 326 327 final StringTokenizer st = new StringTokenizer( signedBy, "," ); 328 while( st.hasMoreTokens() ) 329 { 330 final String alias = st.nextToken().trim(); 331 Certificate certificate = null; 332 333 try 334 { 335 certificate = keyStore.getCertificate( alias ); 336 } 337 catch( final KeyStoreException kse ) 338 { 339 final String message = 340 "Unable to get certificate for alias " + 341 alias + " due to " + kse; 342 throw new Exception( message ); 343 } 344 345 if( null == certificate ) 346 { 347 final String message = 348 "Missing certificate for alias " + alias; 349 throw new Exception( message ); 350 } 351 352 if( !certificateSet.contains( certificate ) ) 353 { 354 certificateSet.add( certificate ); 355 } 356 } 357 358 return (Certificate[])certificateSet.toArray( new Certificate[ certificateSet.size() ] ); 359 } 360 361 /*** 362 * Retrieve keystore with specified name from map. 363 * If missing throw an exception. 364 * 365 * @param keyStoreName the name of key store 366 * @param keyStores the map of stores 367 * @return the keystore 368 * @throws Exception thrown if unable to locate keystore 369 */ 370 private KeyStore getKeyStore( final String keyStoreName, final Map keyStores ) throws Exception 371 { 372 final KeyStore keyStore = (KeyStore)keyStores.get( keyStoreName ); 373 if( null == keyStore ) 374 { 375 final String message = "Missing keystore named: " + keyStoreName; 376 throw new Exception( message ); 377 } 378 else 379 { 380 return keyStore; 381 } 382 } 383 384 /*** 385 * A utility method to get a default codesource 386 * that covers all files on fielsystem 387 * 388 * @return the code source 389 */ 390 private CodeSource createDefaultCodeSource() 391 { 392 //Create a URL that covers whole file system. 393 final URL url; 394 try 395 { 396 url = new URL( "file:/-" ); 397 } 398 catch( final MalformedURLException mue ) 399 { 400 //will never happen 401 throw new IllegalStateException( mue.getMessage() ); 402 } 403 final CodeSource codeSource = new CodeSource( url, null ); 404 return codeSource; 405 } 406 407 /*** 408 * A utility method to get all the default permissions. 409 */ 410 private Permission[] getDefaultPermissions() 411 { 412 final ArrayList list = new ArrayList(); 413 //these properties straight out ot ${java.home}/lib/security/java.policy 414 list.add( new PropertyPermission( "os.name", "read" ) ); 415 list.add( new PropertyPermission( "os.arch", "read" ) ); 416 list.add( new PropertyPermission( "os.version", "read" ) ); 417 list.add( new PropertyPermission( "file.separator", "read" ) ); 418 list.add( new PropertyPermission( "path.separator", "read" ) ); 419 list.add( new PropertyPermission( "line.separator", "read" ) ); 420 421 list.add( new PropertyPermission( "java.version", "read" ) ); 422 list.add( new PropertyPermission( "java.vendor", "read" ) ); 423 list.add( new PropertyPermission( "java.vendor.url", "read" ) ); 424 425 list.add( new PropertyPermission( "java.class.version", "read" ) ); 426 list.add( new PropertyPermission( "java.vm.version", "read" ) ); 427 list.add( new PropertyPermission( "java.vm.vendor", "read" ) ); 428 list.add( new PropertyPermission( "java.vm.name", "read" ) ); 429 430 list.add( new PropertyPermission( "java.specification.version", "read" ) ); 431 list.add( new PropertyPermission( "java.specification.vendor", "read" ) ); 432 list.add( new PropertyPermission( "java.specification.name", "read" ) ); 433 list.add( new PropertyPermission( "java.vm.specification.version", "read" ) ); 434 list.add( new PropertyPermission( "java.vm.specification.vendor", "read" ) ); 435 list.add( new PropertyPermission( "java.vm.specification.name", "read" ) ); 436 437 return (Permission[])list.toArray( new Permission[ list.size() ] ); 438 } 439 }

This page was automatically generated by Maven