package org.eclipse.jetty.policy.entry; //======================================================================== //Copyright (c) Webtide LLC //------------------------------------------------------------------------ //All rights reserved. This program and the accompanying materials //are made available under the terms of the Eclipse Public License v1.0 //and Apache License v2.0 which accompanies this distribution. // //The Eclipse Public License is available at //http://www.eclipse.org/legal/epl-v10.html // //The Apache License v2.0 is available at //http://www.apache.org/licenses/LICENSE-2.0.txt // //You may elect to redistribute this code under either of these licenses. //======================================================================== import java.net.URI; import java.net.URL; import java.security.CodeSource; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.PermissionCollection; import java.security.Permissions; import java.security.Principal; import java.security.cert.Certificate; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.StringTokenizer; import org.eclipse.jetty.policy.PolicyContext; import org.eclipse.jetty.policy.PolicyException; public class GrantEntry extends AbstractEntry { /** * The signers part of grant clause. This is a comma-separated list of certificate aliases. */ private String signers; /** * The codebase part of grant clause. This is an URL from which code originates. */ private String codebase; /** * Collection of PrincipalEntries of grant clause. */ private Collection<PrincipalEntry> principalNodes; /** * Collection of PermissionEntries of grant clause. */ private Collection<PermissionEntry> permissionNodes; // cached permissions private PermissionCollection permissions; private Certificate[] signerArray; private CodeSource codesource; private Principal[] principals; /** * Adds specified element to the <code>principals</code> collection. If collection does not exist yet, creates a * new one. */ public void addPrincipal( PrincipalEntry pe ) { if ( principalNodes == null ) { principalNodes = new HashSet<PrincipalEntry>(); } principalNodes.add( pe ); } public void expand( PolicyContext context ) throws PolicyException { if ( signers != null ) { signerArray = resolveToCertificates( context.getKeystore(), signers ); // TODO alter to support self:: etc } codebase = context.evaluate( codebase ); if ( principalNodes != null ) { Set<Principal> principalSet = new HashSet<Principal>(); for ( Iterator<PrincipalEntry> i = principalNodes.iterator(); i.hasNext(); ) { PrincipalEntry node = i.next(); node.expand( context ); principalSet.add( node.toPrincipal( context ) ); } principals = principalSet.toArray( new Principal[principalSet.size()] ); } context.setPrincipals( principals ); permissions = new Permissions(); for ( Iterator<PermissionEntry> i = permissionNodes.iterator(); i.hasNext(); ) { PermissionEntry node = i.next(); node.expand( context ); permissions.add( node.toPermission() ); } context.setPrincipals( null ); setExpanded( true ); } public PermissionCollection getPermissions() throws PolicyException { return permissions; } public Principal[] getPrincipals() throws PolicyException { return principals; } public CodeSource getCodeSource() throws PolicyException { if ( !isExpanded() ) { throw new PolicyException("GrantNode needs to be expanded."); } try { if ( codesource == null && codebase != null ) { URL url = new URI( codebase ).toURL(); codesource = new CodeSource( url, signerArray ); } return codesource; } catch ( Exception e ) { throw new PolicyException( e ); } } /** * resolve signers into an array of certificates using a given keystore * * @param keyStore * @param signers * @return * @throws Exception */ private Certificate[] resolveToCertificates( KeyStore keyStore, String signers ) throws PolicyException { if ( keyStore == null ) { Certificate[] certs = null; return certs; } Set<Certificate> certificateSet = new HashSet<Certificate>(); StringTokenizer strTok = new StringTokenizer( signers, ","); for ( int i = 0; strTok.hasMoreTokens(); ++i ) { try { Certificate certificate = keyStore.getCertificate( strTok.nextToken().trim() ); if ( certificate != null ) { certificateSet.add( certificate ); } } catch ( KeyStoreException kse ) { throw new PolicyException( kse ); } } return certificateSet.toArray( new Certificate[certificateSet.size()] ); } public void setSigners( String signers ) { this.signers = signers; } public void setCodebase( String codebase ) { this.codebase = codebase; } public void setPrincipals( Collection<PrincipalEntry> principals ) { this.principalNodes = principals; } public void setPermissions( Collection<PermissionEntry> permissions ) { this.permissionNodes = permissions; } }