Modified: river/jtsk/trunk/src/net/jini/jeri/ssl/SslServerEndpointImpl.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/jeri/ssl/SslServerEndpointImpl.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/jeri/ssl/SslServerEndpointImpl.java (original) +++ river/jtsk/trunk/src/net/jini/jeri/ssl/SslServerEndpointImpl.java Fri Feb 10 11:53:29 2012 @@ -101,10 +101,10 @@ class SslServerEndpointImpl extends Util * to facilitate testing. Use 24 hours to allow the client, which uses * 23.5 hours, to renegotiate a new session before the server timeout. */ - static long maxServerSessionDuration = + private final long maxServerSessionDuration = ((Long) Security.doPrivileged( new GetLongAction("com.sun.jini.jeri.ssl.maxServerSessionDuration", - 24 * 60 * 60 * 1000))).longValue(); + 24L * 60L * 60L * 1000L))).longValue(); /** * Executes a Runnable in a system thread -- used for listener accept @@ -118,10 +118,10 @@ class SslServerEndpointImpl extends Util new BasicServerConnManager(); /** The associated server endpoint. */ - final ServerEndpoint serverEndpoint; + private final ServerEndpoint serverEndpoint; /** The server subject, or null if the server is anonymous. */ - final Subject serverSubject; + private final Subject serverSubject; /** * The principals to use for authentication, or null if the server is @@ -146,21 +146,21 @@ class SslServerEndpointImpl extends Util /** * The permissions needed to authenticate when listening on this endpoint, - * or null if the server is anonymous. + * or null if the server is anonymous. Effectively immutable array. */ - Permission[] listenPermissions; + private final Permission[] listenPermissions; /** The listen endpoint. */ private final ListenEndpoint listenEndpoint; /** The factory for creating JSSE sockets -- set by sslInit */ - private SSLSocketFactory sslSocketFactory; + private SSLSocketFactory sslSocketFactory; // Synchronized on this /** * The authentication manager for the SSLContext for this endpoint -- set * by sslInit. */ - private ServerAuthManager authManager; + private ServerAuthManager authManager; // Synchronized on this /** The server connection manager. */ ServerConnManager serverConnectionManager = defaultServerConnectionManager; @@ -191,9 +191,10 @@ class SslServerEndpointImpl extends Util ? computePrincipals(serverSubject) : checkPrincipals(serverPrincipals); /* Set listenPermissions before calling hasListenPermissions */ + Permission [] listenPermissions; if (this.serverPrincipals == null) { listenPermissions = null; - } else { + } else { listenPermissions = new AuthenticationPermission[this.serverPrincipals.size()]; int i = 0; @@ -213,10 +214,11 @@ class SslServerEndpointImpl extends Util !hasListenPermissions())) { this.serverSubject = null; - this.listenPermissions = null; + listenPermissions = null; } else { - this.serverSubject = serverSubject; + this.serverSubject = serverSubject; } + this.listenPermissions = listenPermissions; this.serverHost = serverHost; if (port < 0 || port > 0xFFFF) { throw new IllegalArgumentException("Invalid port: " + port); @@ -526,12 +528,12 @@ class SslServerEndpointImpl extends Util if (resolvedHost == null) { InetAddress localAddr; try { - localAddr = (InetAddress) AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws UnknownHostException { - return InetAddress.getLocalHost(); - } - }); + localAddr = AccessController.doPrivileged( + new PrivilegedExceptionAction<InetAddress>() { + public InetAddress run() throws UnknownHostException { + return InetAddress.getLocalHost(); + } + }); } catch (PrivilegedActionException e) { UnknownHostException uhe = (UnknownHostException) e.getCause(); @@ -673,15 +675,18 @@ class SslServerEndpointImpl extends Util checkListenPermissions(false); Set principals = serverSubject.getPrincipals(); /* Keep track of progress; remove entry when check is done */ - Map progress = new HashMap(serverPrincipals.size()); - for (Iterator i = serverPrincipals.iterator(); i.hasNext(); ) { - X500Principal p = (X500Principal) i.next(); - if (!principals.contains(p)) { - throw new UnsupportedConstraintException( - "Missing principal: " + p); - } - progress.put(p, X500Principal.class); - } + boolean nullServerPrincipals = serverPrincipals == null; + Map progress = new HashMap(nullServerPrincipals ? 0 : serverPrincipals.size()); + if (!nullServerPrincipals){ + for (Iterator i = serverPrincipals.iterator(); i.hasNext(); ) { + X500Principal p = (X500Principal) i.next(); + if (!principals.contains(p)) { + throw new UnsupportedConstraintException( + "Missing principal: " + p); + } + progress.put(p, X500Principal.class); + } + } X500PrivateCredential[] privateCredentials = (X500PrivateCredential[]) AccessController.doPrivileged( new SubjectCredentials.GetAllPrivateCredentialsAction( @@ -803,8 +808,9 @@ class SslServerEndpointImpl extends Util private final Set connections = new HashSet(); /** Used to throttle accept failures */ + private final Object failureLock = new Object(); private long acceptFailureTime = 0; - private int acceptFailureCount; + private int acceptFailureCount = 0; /** Creates a listen handle */ SslListenHandle(RequestDispatcher requestDispatcher, @@ -936,23 +942,34 @@ class SslServerEndpointImpl extends Util final int NFAIL = 10; final int NMSEC = 5000; long now = System.currentTimeMillis(); - if (acceptFailureTime == 0L || - (now - acceptFailureTime) > NMSEC) - { - // failure time is very old, or this is first failure - acceptFailureTime = now; - acceptFailureCount = 0; - } else { - // failure window was started recently - acceptFailureCount++; - if (acceptFailureCount >= NFAIL) { - try { - Thread.sleep(10000); - } catch (InterruptedException ignore) { - } - // no need to reset counter/timer - } - } + boolean fail = false; + synchronized (failureLock){ + if (acceptFailureTime == 0L || + (now - acceptFailureTime) > NMSEC) + { + // failure time is very old, or this is first failure + acceptFailureTime = now; + acceptFailureCount = 0; + } else { + // failure window was started recently + acceptFailureCount++; + if (acceptFailureCount >= NFAIL) { + fail = true; + } + } + } + if (fail) { + try { + Thread.sleep(10000); + } catch (InterruptedException ignore) { + /* Why are we ignoring the interrupt and not + * restoring the interrupted status? + */ + Thread.currentThread().interrupt(); + } + // no need to reset counter/timer + } + return true; } @@ -1063,31 +1080,31 @@ class SslServerEndpointImpl extends Util * yet. Check that the current session matches to prevent new * handshakes. */ - private SSLSession session; + private final SSLSession session; /** * The client subject -- depends on session being set. This instance * is read-only. */ - private Subject clientSubject; + private final Subject clientSubject; /** The client principal -- depends on session being set. */ - private X500Principal clientPrincipal; + private final X500Principal clientPrincipal; /** The server principal -- depends on session being set. */ - private X500Principal serverPrincipal; + private final X500Principal serverPrincipal; /** * The authentication permission required for this connection, or null * if the server is anonymous -- depends on session being set. */ - private AuthenticationPermission authPermission; + private final AuthenticationPermission authPermission; /** The cipher suite -- depends on session being set. */ - private String cipherSuite; - + private final String cipherSuite; + /** True if the connection has been closed. */ - boolean closed; + volatile boolean closed; /** Creates a server connection */ SslServerConnection(SslListenHandle listenHandle, Socket socket) @@ -1103,7 +1120,34 @@ class SslServerEndpointImpl extends Util /* Need to put in server mode before requesting client auth. */ sslSocket.setUseClientMode(false); sslSocket.setWantClientAuth(true); - + try { + session = sslSocket.getSession(); + sslSocket.setEnableSessionCreation(false); + cipherSuite = session.getCipherSuite(); + if ("NULL".equals(getKeyExchangeAlgorithm(cipherSuite))) { + throw new SecurityException("Handshake failed"); + } + clientSubject = getClientSubject(sslSocket); + clientPrincipal = clientSubject != null + ? ((X500Principal) + clientSubject.getPrincipals().iterator().next()) + : null; + X509Certificate serverCert = + getAuthManager().getServerCertificate(session); + serverPrincipal = serverCert != null + ? serverCert.getSubjectX500Principal() : null; + if (serverPrincipal != null) { + authPermission = new AuthenticationPermission( + Collections.singleton(serverPrincipal), + (clientPrincipal != null + ? Collections.singleton(clientPrincipal) : null), + "accept"); + } else { + authPermission = null; + } + } catch (SecurityException e){ + throw new IOException("Unable to create session", e); + } logger.log(Level.FINE, "created {0}", this); } @@ -1193,43 +1237,21 @@ class SslServerEndpointImpl extends Util * fields if needed. */ private void decacheSession() { - synchronized (this) { - SSLSession socketSession = sslSocket.getSession(); - if (session == socketSession) { - return; - } else if (session != null) { - /* - * We disable session creation as soon as we notice the - * first session, but it is possible that a second - * handshake could have started by then, so check that we - * have the same session. -tjb[31.Jan.2003] - */ - throw new SecurityException( - "New handshake occurred on socket"); - } - session = socketSession; - sslSocket.setEnableSessionCreation(false); - cipherSuite = session.getCipherSuite(); - if ("NULL".equals(getKeyExchangeAlgorithm(cipherSuite))) { - throw new SecurityException("Handshake failed"); - } - clientSubject = getClientSubject(sslSocket); - clientPrincipal = clientSubject != null - ? ((X500Principal) - clientSubject.getPrincipals().iterator().next()) - : null; - X509Certificate serverCert = - getAuthManager().getServerCertificate(session); - serverPrincipal = serverCert != null - ? serverCert.getSubjectX500Principal() : null; - if (serverPrincipal != null) { - authPermission = new AuthenticationPermission( - Collections.singleton(serverPrincipal), - (clientPrincipal != null - ? Collections.singleton(clientPrincipal) : null), - "accept"); - } - } + SSLSession socketSession = sslSocket.getSession(); + if (session == socketSession) { + return; + } else if ( !session.isValid()){ + throw new SecurityException("Session invalid"); + } else { + /* + * We disable session creation as soon as we notice the + * first session, but it is possible that a second + * handshake could have started by then, so check that we + * have the same session. -tjb[31.Jan.2003] + */ + throw new SecurityException( + "New handshake occurred on socket"); + } } /**
Modified: river/jtsk/trunk/src/net/jini/jeri/tcp/TcpServerEndpoint.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/jeri/tcp/TcpServerEndpoint.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/jeri/tcp/TcpServerEndpoint.java (original) +++ river/jtsk/trunk/src/net/jini/jeri/tcp/TcpServerEndpoint.java Fri Feb 10 11:53:29 2012 @@ -854,7 +854,7 @@ public final class TcpServerEndpoint imp if (!(t instanceof SecurityException)) { try { - // NYI: shed idle connections + // TODO: NYI: shed idle connections } catch (OutOfMemoryError e) { } catch (Exception e) { } Modified: river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java (original) +++ river/jtsk/trunk/src/net/jini/loader/pref/PreferredClassLoader.java Fri Feb 10 11:53:29 2012 @@ -1011,6 +1011,22 @@ public class PreferredClassLoader extend return getPackage(name); } } + + protected Class<?> findClass(final String name) + throws ClassNotFoundException + { + /* TODO: Override and create our own CodeSource + * implementation that contains permissions.perm + * After we retrieve the manifest, class bytes and + * certificates, create the CodeSource we call + * defineClass(String name, byte[]b, int off, int len, CodeSource cs) + * + * This will be utilised by a class that overrides + * BasicProxyPreparer.getPermissions() + * to retrieve the advisory permissions. + */ + return super.findClass(name); + } /** * {@inheritDoc} @@ -1143,9 +1159,9 @@ public class PreferredClassLoader extend * Create an AccessControlContext that consists of a single * protection domain with only the permissions calculated above. * Comment added 7th May 2010 by Peter Firmstone: - * This calls the pre java 1.4 constructor which causes the + * This did call the pre java 1.4 constructor which causes the * ProtectionDomain to not consult the Policy, this - * has the effect of not allowing Dynamic Permission changes to be + * had the effect of not allowing Dynamic Permission changes to be * effected by the Policy. It doesn't affect the existing * DynamicPolicy implementation as it returns the Permissions * allowing the ProtectionDomain domain combiner to combine Modified: river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java (original) +++ river/jtsk/trunk/src/net/jini/lookup/ServiceDiscoveryManager.java Fri Feb 10 11:53:29 2012 @@ -804,7 +804,7 @@ public class ServiceDiscoveryManager { /** A wrapper class for a ServiceRegistrar. */ private final static class ProxyReg { - private final ServiceRegistrar proxy; + public ServiceRegistrar proxy; public ProxyReg(ServiceRegistrar proxy) { if(proxy == null) throw new IllegalArgumentException ("proxy cannot be null"); @@ -813,21 +813,14 @@ public class ServiceDiscoveryManager { public boolean equals(Object obj) { if (obj instanceof ProxyReg){ - return getProxy().equals(((ProxyReg)obj).getProxy()); + return proxy.equals(((ProxyReg)obj).proxy); } else return false; }//end equals public int hashCode() { - return getProxy().hashCode(); + return proxy.hashCode(); }//end hashCode - /** - * @return the proxy - */ - public ServiceRegistrar getProxy() { - return proxy; - } - }//end class ServiceDiscoveryManager.ProxyReg /** The Listener class for the LeaseRenewalManager. */ @@ -914,7 +907,7 @@ public class ServiceDiscoveryManager { long duration = getLeaseDuration(); if(duration < 0) return; try { - EventReg eventReg = registerListener(reg.getProxy(), + EventReg eventReg = registerListener(reg.proxy, tmpl, lookupListenerProxy, duration); @@ -936,7 +929,7 @@ public class ServiceDiscoveryManager { cacheTerminated = bCacheTerminated; }//end sync ServiceDiscoveryManager.this.fail - (e, reg.getProxy(),this.getClass().getName(),"run", + (e,reg.proxy,this.getClass().getName(),"run", "Exception occurred while attempting to register " +"with the lookup service event mechanism", cacheTerminated); @@ -955,7 +948,7 @@ public class ServiceDiscoveryManager { } public void run() { logger.finest("ServiceDiscoveryManager - LookupTask started"); - ServiceRegistrar proxy = reg.getProxy(); + ServiceRegistrar proxy = reg.proxy; ServiceMatches matches; /* For the given lookup, get all services matching the tmpl */ try { @@ -1154,7 +1147,7 @@ public class ServiceDiscoveryManager { * item, or a newly discovered item. */ if(transition == ServiceRegistrar.TRANSITION_MATCH_NOMATCH) { - handleMatchNoMatch(reg.getProxy(), sid, item); + handleMatchNoMatch(reg.proxy, sid, item); } else {//(transition == NOMATCH_MATCH or MATCH_MATCH) (new NewOldServiceTask(reg, item, (transition == ServiceRegistrar.TRANSITION_MATCH_MATCH), @@ -1408,18 +1401,18 @@ public class ServiceDiscoveryManager { +"NewOldServiceTask completed"); return; }//endif - itemReg = new ServiceItemReg( reg.getProxy(), srvcItem ); + itemReg = new ServiceItemReg( reg.proxy, srvcItem ); serviceIdMap.put( thisTaskSid, itemReg ); } else { changed = true; } }//end sync(serviceIdMap) if(changed) {//a. old, previously discovered item - itemMatchMatchChange(reg.getProxy(), srvcItem, + itemMatchMatchChange(reg.proxy, srvcItem, itemReg, matchMatchEvent); } else {//b. newly discovered item ServiceItem newFilteredItem = - filterMaybeDiscard(srvcItem, reg.getProxy(),false); + filterMaybeDiscard(srvcItem,reg.proxy,false); if(newFilteredItem != null) { addServiceNotify(newFilteredItem); }//endif @@ -1477,7 +1470,7 @@ public class ServiceDiscoveryManager { ServiceRegistrar proxy = null; ServiceItem item; synchronized(itemReg) { - item = itemReg.removeProxy(reg.getProxy());//disassociate the LUS + item = itemReg.removeProxy(reg.proxy);//disassociate the LUS if (item != null) {// new LUS chosen to track changes proxy = itemReg.proxy; } else if( itemReg.hasNoProxys() ) {//no more LUSs, remove from map @@ -1886,18 +1879,16 @@ public class ServiceDiscoveryManager { eReg.lookupsPending++; t = new LookupTask(reg, taskSeqN++, eReg); if( logger.isLoggable(Levels.HANDLED) ) { - StringBuilder sb = new StringBuilder(300); - sb.append("notifyServiceMap - GAP in event sequence ") - .append("[serviceRegistrar={0}], ") - .append("[serviceItem={1}, ") - .append("serviceID={2}], ") - .append("[eventSource={3}, ") - .append("eventID={4,number,#}, ") - .append("oldSeqN={5,number,#}, ") - .append("newSeqN={6,number,#}]"); - String msg = sb.toString(); - Object[] params = new Object[] { reg !=null ? reg.getProxy() : "", - item != null ? item.service : "", + String msg ="notifyServiceMap - GAP in event sequence " + +"[serviceRegistrar={0}], " + +"[serviceItem={1}, " + +"serviceID={2}], " + +"[eventSource={3}, " + +"eventID={4,number,#}, " + +"oldSeqN={5,number,#}, " + +"newSeqN={6,number,#}]"; + Object[] params = new Object[] { reg.proxy, + item.service, sid, eventSource, new Long(eventID), @@ -2520,7 +2511,7 @@ public class ServiceDiscoveryManager { while(iter.hasNext()) { ProxyReg reg = (ProxyReg)iter.next(); cacheAddProxy(reg); - if(notifies != null) listenerDiscovered(reg.getProxy(), notifies); + if(notifies != null) listenerDiscovered(reg.proxy, notifies); }//end loop }//end DiscMgrListener.discovered @@ -2855,7 +2846,7 @@ public class ServiceDiscoveryManager { Iterator iter = proxyRegSet.iterator(); while(iter.hasNext()) { ProxyReg reg = (ProxyReg)iter.next(); - proxys[k++] = reg.getProxy(); + proxys[k++] = reg.proxy; }//end loop return proxys; }//end buildServiceRegistrar @@ -3622,7 +3613,7 @@ public class ServiceDiscoveryManager { Iterator iter = proxyRegSet.iterator(); while(iter.hasNext()) { ProxyReg reg =(ProxyReg)iter.next(); - if(reg.getProxy().equals(proxy)) return reg; + if(reg.proxy.equals(proxy)) return reg; }//end loop return null; }//end findReg Modified: river/jtsk/trunk/src/net/jini/security/GrantPermission.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/security/GrantPermission.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/security/GrantPermission.java (original) +++ river/jtsk/trunk/src/net/jini/security/GrantPermission.java Fri Feb 10 11:53:29 2012 @@ -18,6 +18,7 @@ package net.jini.security; +import org.apache.river.api.security.PermissionComparator; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InvalidObjectException; @@ -36,11 +37,13 @@ import java.security.Permissions; import java.security.UnresolvedPermission; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.TreeSet; import net.jini.security.policy.DynamicPolicy; /** @@ -555,7 +558,7 @@ public final class GrantPermission exten * of permissions. */ private static String constructName(Permission[] pa) { - StringBuffer sb = new StringBuffer(); + StringBuffer sb = new StringBuffer(60); for (int i = 0; i < pa.length; i++) { Permission p = pa[i]; if (p instanceof UnresolvedPermission) { @@ -762,8 +765,9 @@ public final class GrantPermission exten private static final ObjectStreamField[] serialPersistentFields = { new ObjectStreamField("perms", List.class, true) }; - - private List perms = new ArrayList(); + + // Serial form. + private List<Permission> perms = new ArrayList<Permission>(); private Implier implier = new Implier(); public synchronized void add(Permission p) { @@ -774,11 +778,14 @@ public final class GrantPermission exten throw new SecurityException( "can't add to read-only PermissionCollection"); } - perms.add(p); - implier.add((GrantPermission) p); + // No longer rely on TreeSet to ensure correctness, just don't + // add twice, in other words check must be external. + perms.add(p); + implier.add((GrantPermission) p); + } - public synchronized Enumeration elements() { + public synchronized Enumeration<Permission> elements() { return Collections.enumeration(perms); } Modified: river/jtsk/trunk/src/net/jini/security/Security.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/security/Security.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/security/Security.java (original) +++ river/jtsk/trunk/src/net/jini/security/Security.java Fri Feb 10 11:53:29 2012 @@ -43,6 +43,7 @@ import java.util.Map; import java.util.Set; import java.util.StringTokenizer; import java.util.WeakHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; @@ -461,26 +462,7 @@ public final class Security { } final AccessControlContext acc = AccessController.getContext(); - return new SecurityContext() { - public PrivilegedAction wrap(PrivilegedAction a) { - if (a == null) { - throw new NullPointerException(); - } - return a; - } - - public PrivilegedExceptionAction wrap(PrivilegedExceptionAction a) - { - if (a == null) { - throw new NullPointerException(); - } - return a; - } - - public AccessControlContext getAccessControlContext() { - return acc; - } - }; + return new SecurityContextImpl(acc); } /** @@ -497,15 +479,17 @@ public final class Security { * principals of the <code>Subject</code>, as well as the ability to use * credentials of the <code>Subject</code> for authentication. * + * @param <T> * @param action the action to be executed * @return the object returned by the action's <code>run</code> method * @throws NullPointerException if the action is <code>null</code> */ - public static Object doPrivileged(final PrivilegedAction action) { + public static <T> T doPrivileged(final PrivilegedAction<T> action) { final Class caller = ctxAccess.getCaller(); final AccessControlContext acc = AccessController.getContext(); - return AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { + return AccessController.doPrivileged(new PrivilegedAction<T>() { + + public T run() { return AccessController.doPrivileged( action, createPrivilegedContext(caller, acc)); } @@ -526,19 +510,21 @@ public final class Security { * to principals of the <code>Subject</code>, as well as the ability to use * credentials of the <code>Subject</code> for authentication. * + * @param <T> * @param action the action to be executed * @return the object returned by the action's <code>run</code> method * @throws PrivilegedActionException if the action's <code>run</code> * method throws a checked exception * @throws NullPointerException if the action is <code>null</code> */ - public static Object doPrivileged(final PrivilegedExceptionAction action) + public static <T> T doPrivileged(final PrivilegedExceptionAction<T> action) throws PrivilegedActionException { final Class caller = ctxAccess.getCaller(); final AccessControlContext acc = AccessController.getContext(); - return AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws Exception { + return AccessController.doPrivileged(new PrivilegedExceptionAction<T>() { + + public T run() throws Exception { try { return AccessController.doPrivileged( action, createPrivilegedContext(caller, acc)); @@ -765,21 +751,24 @@ public final class Security { * Returns current thread's context class loader. */ private static ClassLoader getContextClassLoader() { - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return Thread.currentThread().getContextClassLoader(); - } - }); + return AccessController.doPrivileged( + new PrivilegedAction<ClassLoader>() { + + public ClassLoader run() { + return Thread.currentThread().getContextClassLoader(); + } + } + ); } /** * Returns currently installed security policy, if any. */ private static Policy getPolicy() { - return (Policy) AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { return Policy.getPolicy(); } - }); + return AccessController.doPrivileged(new PrivilegedAction<Policy>() { + + public Policy run() { return Policy.getPolicy(); } + }); } /** @@ -799,7 +788,7 @@ public final class Security { } catch (SecurityException e) { } - ArrayList list = new ArrayList(permissions.length); + ArrayList<Permission> list = new ArrayList<Permission>(permissions.length); for (int i = 0; i < permissions.length; i++) { try { Permission p = permissions[i]; @@ -808,7 +797,7 @@ public final class Security { } catch (SecurityException e) { } } - return (Permission[]) list.toArray(new Permission[list.size()]); + return list.toArray(new Permission[list.size()]); } /** @@ -816,20 +805,23 @@ public final class Security { */ private static Principal[] getCurrentPrincipals() { final AccessControlContext acc = AccessController.getContext(); - Subject s = (Subject) AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { return Subject.getSubject(acc); } + Subject s = AccessController.doPrivileged( + new PrivilegedAction<Subject>() { + + public Subject run() { return Subject.getSubject(acc); } }); if (s != null) { - Set ps = s.getPrincipals(); - return (Principal[]) ps.toArray(new Principal[ps.size()]); + Set<Principal> ps = s.getPrincipals(); + return ps.toArray(new Principal[ps.size()]); } else { return null; } } /** - * TrustVerifier.Context implementation. + * TrustVerifier.Context implementation. This implementation is only + * used to verify trust it is never handed outside this class, + * so we never bother to defensively copy state. */ private static class Context implements TrustVerifier.Context { /** @@ -872,9 +864,10 @@ public final class Security { final ArrayList list = new ArrayList(1); final ClassLoader scl = cl; AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { for (Iterator iter = - Service.providers(TrustVerifier.class, scl); + Service.providers(TrustVerifier.class, scl); iter.hasNext(); ) { list.add(iter.next()); @@ -891,7 +884,7 @@ public final class Security { new TrustVerifier[list.size()]); synchronized (map) { map.put(cl, new SoftReference(verifiers)); - } + } } this.verifiers = verifiers; this.context = context; @@ -970,4 +963,48 @@ public final class Security { return getClassContext()[2]; } } + + private static class SecurityContextImpl implements SecurityContext { + + private final AccessControlContext acc; + private final int hashCode; + + public SecurityContextImpl(AccessControlContext acc) { + this.acc = acc; + int hash = 7; + hash = 23 * hash + (this.acc != null ? this.acc.hashCode() : 0); + hashCode = hash; + } + + public <T> PrivilegedAction<T> wrap(PrivilegedAction<T> a) { + if (a == null) { + throw new NullPointerException(); + } + return a; + } + + public <T> PrivilegedExceptionAction<T> wrap(PrivilegedExceptionAction<T> a) + { + if (a == null) { + throw new NullPointerException(); + } + return a; + } + + public AccessControlContext getAccessControlContext() { + return acc; + } + + @Override + public int hashCode() { + return hashCode; + } + + @Override + public boolean equals(Object o){ + if (!(o instanceof SecurityContextImpl)) return false; + SecurityContext that = (SecurityContext) o; + return getAccessControlContext().equals(that.getAccessControlContext()); + } + } } Modified: river/jtsk/trunk/src/net/jini/security/SecurityContext.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/security/SecurityContext.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/security/SecurityContext.java (original) +++ river/jtsk/trunk/src/net/jini/security/SecurityContext.java Fri Feb 10 11:53:29 2012 @@ -51,7 +51,11 @@ import java.security.PrivilegedException * AccessController.doPrivileged( * ctx.wrap(action), ctx.getAccessControlContext()); * </pre> - * + * + * <BOLD> + * Implementations must override Object equals and hashCode. + * </BOLD> + * * @author Sun Microsystems, Inc. * * @since 2.0 @@ -71,12 +75,13 @@ public interface SecurityContext { * <code>run</code> method is propagated through the <code>run</code> * method of the wrapper action. * + * @param <T> return type of PrivilegedAction * @param action the action to be wrapped * @return security context-restoring action wrapping <code>action</code>, * or <code>action</code> if no wrapping is necessary * @throws NullPointerException if <code>action</code> is <code>null</code> */ - PrivilegedAction wrap(PrivilegedAction action); + <T> PrivilegedAction<T> wrap(PrivilegedAction<T> action); /** * Returns a security context-restoring @@ -91,12 +96,13 @@ public interface SecurityContext { * thrown by the wrapped action's <code>run</code> method is propagated * through the <code>run</code> method of the wrapper action. * + * @param <T> return type of PrivilegedExceptionAction * @param action the action to be wrapped * @return security context-restoring action wrapping <code>action</code>, * or <code>action</code> if no wrapping is necessary * @throws NullPointerException if <code>action</code> is <code>null</code> */ - PrivilegedExceptionAction wrap(PrivilegedExceptionAction action); + <T> PrivilegedExceptionAction<T> wrap(PrivilegedExceptionAction<T> action); /** * Returns access control context portion of snapshotted security context. Modified: river/jtsk/trunk/src/net/jini/security/policy/PolicyFileProvider.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/security/policy/PolicyFileProvider.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/security/policy/PolicyFileProvider.java (original) +++ river/jtsk/trunk/src/net/jini/security/policy/PolicyFileProvider.java Fri Feb 10 11:53:29 2012 @@ -26,8 +26,13 @@ import java.security.Policy; import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.security.Security; +import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; +import java.util.Enumeration; +import java.util.HashSet; import java.util.List; +import java.util.Set; import net.jini.security.GrantPermission; /** @@ -47,20 +52,22 @@ import net.jini.security.GrantPermission * @com.sun.jini.impl <!-- Implementation Specifics --> * * This implementation's no-argument constructor uses a default class name of - * <code>"sun.security.provider.PolicyFile"</code> to instantiate base policy - * objects, if the + * <code>"org.apache.river.impl.security.policy.se.ConcurrentPolicyFile"</code> + * to instantiate base policy objects, if the * <code>net.jini.security.policy.PolicyFileProvider.basePolicyClass</code> * security property is not set. */ public class PolicyFileProvider extends Policy { private static final String basePolicyClassProperty = - "net.jini.security.policy." + - "PolicyFileProvider.basePolicyClass"; + "net.jini.security.policy.PolicyFileProvider.basePolicyClass"; private static final String defaultBasePolicyClass = - "sun.security.provider.PolicyFile"; + // Having our own implementation removes a platform dependency + "org.apache.river.api.security.ConcurrentPolicyFile"; +// "sun.security.provider.PolicyFile"; private static final String policyProperty = "java.security.policy"; private static final Object propertyLock = new Object(); + private static final Permission umbrella = new UmbrellaGrantPermission(); private final String policyFile; private final Policy basePolicy; @@ -101,7 +108,9 @@ public class PolicyFileProvider extends * <code>net.jini.security.policy.PolicyFileProvider.basePolicyClass</code> * security property, or if the calling context does not have * adequate permissions to access the base policy class + * @deprecated DynamicPolicyProvider now supports Umbrella grants directly. */ + @Deprecated public PolicyFileProvider() throws PolicyInitializationException { policyFile = null; @@ -266,14 +275,25 @@ public class PolicyFileProvider extends */ private void ensureDependenciesResolved() { // force resolution of GrantPermission and UmbrellaGrantPermission - new GrantPermission(new UmbrellaGrantPermission()); + new GrantPermission(umbrella); } - private static void expandUmbrella(PermissionCollection pc) { - if (pc.implies(new UmbrellaGrantPermission())) { - List l = Collections.list(pc.elements()); - pc.add(new GrantPermission( - (Permission[]) l.toArray(new Permission[l.size()]))); + static void expandUmbrella(PermissionCollection pc) { + if (pc.implies(umbrella)) { + // Don't use Set, avoid calling equals and hashCode on SocketPermission. + Collection<Permission> perms = new ArrayList<Permission>(120); + Enumeration<Permission> e = pc.elements(); + while (e.hasMoreElements()){ + Permission p = e.nextElement(); + // Avoid unintended granting of GrantPermission + // and recursive UmbrellaGrantPermission + if ( p instanceof GrantPermission || + p instanceof UmbrellaGrantPermission){ + continue; + } + perms.add(p); + } + pc.add(new GrantPermission(perms.toArray(new Permission[perms.size()]))); } } @@ -287,7 +307,8 @@ public class PolicyFileProvider extends public Object run() { if (value == null) { // TODO: Use System.clearProperty when we move to 1.5 - System.getProperties().remove(policyProperty); + System.clearProperty(policyProperty); + //System.getProperties().remove(policyProperty); } else { System.setProperty(policyProperty, value); } Modified: river/jtsk/trunk/src/net/jini/url/httpmd/Handler.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/net/jini/url/httpmd/Handler.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/src/net/jini/url/httpmd/Handler.java (original) +++ river/jtsk/trunk/src/net/jini/url/httpmd/Handler.java Fri Feb 10 11:53:29 2012 @@ -226,6 +226,29 @@ public class Handler extends URLStreamHa } } } + + /** + * The default superclass implementation performs dns lookup to determine + * if hosts are equal, this allows two URL's with different hashCode's + * to be equal, breaking the hashCode equals contract. + * + * It also causes a test failure in the jtreg test suite. + * + * + * *** Start test: Mon Jan 23 08:11:26 EST 2012 + * [jtreg] Test 9: TestEqual: httpmd://foo:88/bar/baz;p1=v1;md5=abcd?q#r, httpmd://alpha:88/bar/baz;p1=v1;md5=abcd?q#r + * [jtreg] FAIL: Should be: false + * [jtreg] Result: true + * + * URL.implies(URL url) is better suited to perform this function, why + * it was originally implemented in equals is unknown. + */ + protected boolean hostsEqual(URL u1, URL u2) { + if (u1.getHost() != null && u2.getHost() != null) + return u1.getHost().equalsIgnoreCase(u2.getHost()); + else + return u1.getHost() == null && u2.getHost() == null; + } /** * Compares two HTTPMD URLs to see if they refer to the same file. Performs @@ -317,15 +340,15 @@ public class Handler extends URLStreamHa } /* Generate the host part */ - InetAddress addr = getHostAddress(u); - if (addr != null) { - h += addr.hashCode(); - } else { +// InetAddress addr = getHostAddress(u); +// if (addr != null) { +// h += addr.hashCode(); +// } else { String host = u.getHost(); if (host != null) { h += host.toLowerCase().hashCode(); } - } +// } /* * Generate the path part, ignoring case in the message digest and Modified: river/jtsk/trunk/test/src/net/jini/core/event/RemoteEventTest.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/test/src/net/jini/core/event/RemoteEventTest.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/test/src/net/jini/core/event/RemoteEventTest.java (original) +++ river/jtsk/trunk/test/src/net/jini/core/event/RemoteEventTest.java Fri Feb 10 11:53:29 2012 @@ -18,8 +18,6 @@ package net.jini.core.event; -import static org.junit.Assert.assertEquals; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -28,9 +26,10 @@ import java.io.ObjectOutputStream; import java.rmi.MarshalledObject; import java.util.logging.Level; import java.util.logging.Logger; - +import net.jini.io.MarshalledInstance; import org.junit.Before; import org.junit.Test; +import static org.junit.Assert.*; /** * @@ -49,12 +48,12 @@ public class RemoteEventTest { @Before @SuppressWarnings("deprecation") public void setUp() { - try { - this.m = new MarshalledObject(this.s); - } catch (IOException ex) { - Logger.getLogger(RemoteEventTest.class.getName()).log(Level.SEVERE, null, ex); - } - this.e = new RemoteEvent(this.source, 10L, 25L,this.m); + try { + m = new MarshalledObject(s); + } catch (IOException ex) { + Logger.getLogger(RemoteEventTest.class.getName()).log(Level.SEVERE, null, ex); + } + e = new RemoteEvent(source, 10L, 25L,m); } /** @@ -62,11 +61,11 @@ public class RemoteEventTest { */ @Test public void getID() { - System.out.println("getID"); - RemoteEvent instance = this.e; - long expResult = 10L; - long result = instance.getID(); - assertEquals(expResult, result); + System.out.println("getID"); + RemoteEvent instance = e; + long expResult = 10L; + long result = instance.getID(); + assertEquals(expResult, result); } /** @@ -74,11 +73,11 @@ public class RemoteEventTest { */ @Test public void getSequenceNumber() { - System.out.println("getSequenceNumber"); - RemoteEvent instance = this.e; - long expResult = 25L; - long result = instance.getSequenceNumber(); - assertEquals(expResult, result); + System.out.println("getSequenceNumber"); + RemoteEvent instance = e; + long expResult = 25L; + long result = instance.getSequenceNumber(); + assertEquals(expResult, result); } /** @@ -86,47 +85,47 @@ public class RemoteEventTest { */ @Test public void getRegistrationObject() { - System.out.println("getRegistrationObject"); - RemoteEvent instance = this.e; - MarshalledObject expResult = this.m; - @SuppressWarnings("deprecation") - MarshalledObject result = instance.getRegistrationObject(); - assertEquals(expResult, result); + System.out.println("getRegistrationObject"); + RemoteEvent instance = e; + MarshalledObject expResult = m; + @SuppressWarnings("deprecation") + MarshalledObject result = instance.getRegistrationObject(); + assertEquals(expResult, result); } - + @Test public void testSerialization() { - ObjectOutputStream oos = null; - System.out.println("test serialization"); - MarshalledObject expResult = this.m; - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - oos = new ObjectOutputStream(baos); - oos.writeObject(this.e); - oos.flush(); - byte[] bytes = baos.toByteArray(); - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - ObjectInputStream ois = new ObjectInputStream(bais); - RemoteEvent result = (RemoteEvent) ois.readObject(); - MarshalledObject moResult = result.getRegistrationObject(); - Object srcResult = result.getSource(); - long iDResult = result.getID(); - long seqResult = result.getSequenceNumber(); - assertEquals(expResult, moResult); - assertEquals(this.source, srcResult); - assertEquals(10L, iDResult); - assertEquals(25L, seqResult); - } catch (IOException ex) { - Logger.getLogger(RemoteEventTest.class.getName()).log(Level.SEVERE, null, ex); - } catch (ClassNotFoundException ex) { - Logger.getLogger(RemoteEventTest.class.getName()).log(Level.SEVERE, null, ex); - } finally { - try { - oos.close(); - } catch (IOException ex) { - Logger.getLogger(RemoteEventTest.class.getName()).log(Level.SEVERE, null, ex); - } - } + ObjectOutputStream oos = null; + System.out.println("test serialization"); + MarshalledObject expResult = m; + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(baos); + oos.writeObject(e); + oos.flush(); + byte[] bytes = baos.toByteArray(); + ByteArrayInputStream bais = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(bais); + RemoteEvent result = (RemoteEvent) ois.readObject(); + MarshalledObject moResult = result.getRegistrationObject(); + Object srcResult = result.getSource(); + long iDResult = result.getID(); + long seqResult = result.getSequenceNumber(); + assertEquals(expResult, moResult); + assertEquals(source, srcResult); + assertEquals(10L, iDResult); + assertEquals(25L, seqResult); + } catch (IOException ex) { + Logger.getLogger(RemoteEventTest.class.getName()).log(Level.SEVERE, null, ex); + } catch (ClassNotFoundException ex) { + Logger.getLogger(RemoteEventTest.class.getName()).log(Level.SEVERE, null, ex); + } finally { + try { + oos.close(); + } catch (IOException ex) { + Logger.getLogger(RemoteEventTest.class.getName()).log(Level.SEVERE, null, ex); + } + } } } \ No newline at end of file Modified: river/jtsk/trunk/test/src/net/jini/security/GrantPermissionTest.java URL: http://svn.apache.org/viewvc/river/jtsk/trunk/test/src/net/jini/security/GrantPermissionTest.java?rev=1242750&r1=1242749&r2=1242750&view=diff ============================================================================== --- river/jtsk/trunk/test/src/net/jini/security/GrantPermissionTest.java (original) +++ river/jtsk/trunk/test/src/net/jini/security/GrantPermissionTest.java Fri Feb 10 11:53:29 2012 @@ -1,6 +1,19 @@ /* - * To change this template, choose Tools | Templates - * and open the template in the editor. + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package net.jini.security; @@ -38,33 +51,29 @@ public class GrantPermissionTest { public void tearDown() throws Exception { } - /** - * Test of getActions method, of class GrantPermission. - */ -// @org.junit.Test -// public void getActions() { -// System.out.println("getActions"); -// GrantPermission instance = null; -// String expResult = ""; -// String result = instance.getActions(); -// assertEquals(expResult, result); -// // TODO review the generated test code and remove the default call to fail. -// fail("The test case is a prototype."); -// } - - /** - * Test of newPermissionCollection method, of class GrantPermission. + /** + * Test of string construction, of class GrantPermission. */ -// @org.junit.Test -// public void newPermissionCollection() { -// System.out.println("newPermissionCollection"); -// GrantPermission instance = null; -// PermissionCollection expResult = null; -// PermissionCollection result = instance.newPermissionCollection(); -// assertEquals(expResult, result); -// // TODO review the generated test code and remove the default call to fail. -// fail("The test case is a prototype."); -// } + @org.junit.Test + public void construct() { + System.out.println("String constructor"); + RuntimePermission rpD = new RuntimePermission("D", ""); +// RuntimePermission rpD1 = new RuntimePermission("D1"); +// RuntimePermission rpC = new RuntimePermission("C"); +// RuntimePermission rpC1 = new RuntimePermission("C1"); + + String rpDS = "delim=' java.lang.RuntimePermission 'D'"; + + GrantPermission gpS = new GrantPermission(rpDS); + GrantPermission gpP = new GrantPermission(rpD); + System.out.print(gpS.toString()); + System.out.print(gpP.toString()); + boolean result = gpS.implies(gpP); + boolean expResult = true; + assertEquals(expResult, result); + result = gpP.implies(gpS); + assertEquals(expResult, result); + } /** * Test of implies method, of class GrantPermission. @@ -199,7 +208,7 @@ public class GrantPermissionTest { System.out.println(msg); return ret == exp; } - + /** * Test of equals method, of class GrantPermission. */
