User: stark
Date: 01/03/05 01:53:39
Added: src/main/org/jboss/test NamespacePermission.java
NamespacePermissionCollection.java
PermissionName.java SimpleSRPServer.java
TestLogin.java TestLoginModule.java
TestProtocol.java TestSRPLogin.java
TestSecurityPolicyParser.java TstClient.java
TstTimedCache.java
Log:
Initial version of the JBossSX module
Revision Changes Path
1.1 jbosssx/src/main/org/jboss/test/NamespacePermission.java
Index: NamespacePermission.java
===================================================================
package org.jboss.test.security.test;
import java.security.BasicPermission;
import java.security.Permission;
import java.security.PermissionCollection;
import javax.naming.Name;
/** A path like heirarchical permission.
@author [EMAIL PROTECTED]
@version $Revsiion:$
*/
public class NamespacePermission extends BasicPermission
{
private PermissionName fullName;
private String actions;
/** Creates new NamespacePermission */
public NamespacePermission(String name, String actions)
{
super(name, actions);
this.actions = actions;
fullName = new PermissionName(name);
}
public NamespacePermission(Name name, String actions)
{
super(name.toString(), actions);
this.actions = actions;
fullName = new PermissionName(name);
}
public String getActions()
{
return actions;
}
public PermissionName getFullName()
{
return fullName;
}
public boolean implies(Permission p)
{
String pactions = p.getActions();
boolean implied = true;
for(int n = 0; n < actions.length(); n ++)
{
char a = actions.charAt(n);
char pa = pactions.charAt(n);
if( (a != '-' && pa != '-' && pa != a) )
{
implied = false;
break;
}
else if( a == '-' && pa != '-' )
{
implied = false;
break;
}
}
return implied;
}
public PermissionCollection newPermissionCollection()
{
return new NamespacePermissionCollection();
}
}
1.1
jbosssx/src/main/org/jboss/test/NamespacePermissionCollection.java
Index: NamespacePermissionCollection.java
===================================================================
package org.jboss.test.security.test;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;
/** The PermissionCollection object for NamespacePermissions.
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class NamespacePermissionCollection extends PermissionCollection
{
private TreeMap namespacePerms = new TreeMap();
private TreeMap namespaceKeys = new TreeMap(new
PermissionName.NameLengthComparator());
/** Creates new NamespacePermission */
public NamespacePermissionCollection()
{
}
public void add(Permission permission)
{
if( this.isReadOnly() )
throw new SecurityException("Cannot add permission to read-only
collection");
if( (permission instanceof NamespacePermission) == false )
throw new IllegalArgumentException("Only NamespacePermission can be
added, invalid="+permission);
NamespacePermission np = (NamespacePermission) permission;
PermissionName key = np.getFullName();
ArrayList tmp = (ArrayList) namespacePerms.get(key);
if( tmp == null )
{
tmp = new ArrayList();
namespacePerms.put(key, tmp);
namespaceKeys.put(key, key);
}
tmp.add(np);
}
/** Locate the closest permissions assigned to the namespace. This is based
*on the viewing the permission name as a heirarchical PermissionName and
*/
public boolean implies(Permission permission)
{
boolean implies = false;
if( namespacePerms.isEmpty() == true )
return false;
NamespacePermission np = (NamespacePermission) permission;
// See if there is an exact permission for the name
PermissionName key = np.getFullName();
ArrayList tmp = (ArrayList) namespacePerms.get(key);
if( tmp == null )
{ // Find the closest parent position.
SortedMap headMap = namespacePerms.headMap(key);
try
{
PermissionName lastKey = (PermissionName) headMap.lastKey();
if( lastKey.isParent(key) == true )
tmp = (ArrayList) namespacePerms.get(lastKey);
else
{
PermissionName[] keys = {};
keys = (PermissionName[]) headMap.keySet().toArray(keys);
for(int k = keys.length-1; k >= 0; k --)
{
lastKey = keys[k];
if( lastKey.isParent(key) == true )
{
tmp = (ArrayList) namespacePerms.get(lastKey);
break;
}
}
}
}
catch(NoSuchElementException e)
{ /* Assign the first permission
Object firstKey = namespacePerms.firstKey();
tmp = (ArrayList) namespacePerms.get(firstKey);
*/
}
}
// See if the permission is implied by any we found
if( tmp != null )
implies = isImplied(tmp, np);
//System.out.println("NPC["+this+"].implies("+np+") -> "+implies);
return implies;
}
public Enumeration elements()
{
Set s = namespaceKeys.keySet();
final Iterator iter = s.iterator();
Enumeration elements = new Enumeration()
{
ArrayList activeEntry;
int index;
public boolean hasMoreElements()
{
boolean hasMoreElements = true;
if( activeEntry == null || index >= activeEntry.size() )
{
hasMoreElements = iter.hasNext();
activeEntry = null;
}
return hasMoreElements;
}
public Object nextElement()
{
Object next = null;
if( activeEntry == null )
{
Object key = iter.next();
activeEntry = (ArrayList) namespacePerms.get(key);
index = 0;
next = activeEntry.get(index ++);
}
else
{
next = activeEntry.get(index ++);
}
return next;
}
};
return elements;
}
private boolean isImplied(ArrayList permissions, NamespacePermission np)
{
boolean isImplied = false;
for(int p = 0; p < permissions.size(); p ++)
{
Permission perm = (Permission) permissions.get(p);
isImplied |= perm.implies(np);
if( isImplied == true )
break;
}
return isImplied;
}
}
1.1 jbosssx/src/main/org/jboss/test/PermissionName.java
Index: PermissionName.java
===================================================================
package org.jboss.test;
import java.io.Serializable;
import java.security.BasicPermission;
import java.util.Comparator;
import java.util.Properties;
import javax.naming.CompoundName;
import javax.naming.Name;
import javax.naming.NamingException;
/** A javax.naming.Name based key class used as the name attribute
by NamespacePermissions.
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class PermissionName implements Comparable, Serializable
{
/** The Properties used for the project directory heirarchical names */
static Name emptyName;
static Properties nameSyntax = new Properties();
static
{
nameSyntax.put("jndi.syntax.direction", "left_to_right");
nameSyntax.put("jndi.syntax.separator", "/");
try
{
emptyName = new CompoundName("", nameSyntax);
}
catch(NamingException e)
{
}
}
private Name name;
/** An alternate PermissionName comparator that first orders names by
length(longer names before shorter names) to ensure that the most
precise names are seen first.
*/
public static class NameLengthComparator implements Comparator
{
public int compare(Object o1, Object o2)
{
PermissionName p1 = (PermissionName) o1;
PermissionName p2 = (PermissionName) o2;
// if p1 is longer than p2, its < p2 -> < 0
int compare = p2.size() - p1.size();
if( compare == 0 )
compare = p1.compareTo(p2);
return compare;
}
}
/** Creates new NamespacePermission */
public PermissionName(String name) throws IllegalArgumentException
{
try
{
this.name = new CompoundName(name, nameSyntax);
}
catch(NamingException e)
{
throw new IllegalArgumentException(e.toString(true));
}
}
public PermissionName(Name name)
{
this.name = name;
}
public int compareTo(Object obj)
{
PermissionName pn = (PermissionName) obj;
/* Each level must be compared. The first level to not be equals
determines the ordering of the names.
*/
int compare = name.size() - pn.name.size();
int length = Math.min(name.size(), pn.name.size());
for(int n = 0; compare == 0 && n < length; n ++)
{
String atom0 = name.get(n);
String atom1 = pn.name.get(n);
compare = atom0.compareTo(atom1);
}
return compare;
}
public boolean equals(Object obj)
{
return compareTo(obj) == 0;
}
public int hashCode()
{
return name.hashCode();
}
public int size()
{
return name.size();
}
public boolean isParent(PermissionName childName)
{
boolean isParent = childName.name.startsWith(name);
return isParent;
}
public String toString()
{
return name.toString();
}
}
1.1 jbosssx/src/main/org/jboss/test/SimpleSRPServer.java
Index: SimpleSRPServer.java
===================================================================
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.test;
import java.io.IOException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import org.jboss.security.Util;
import org.jboss.security.srp.SerialObjectStore;
import org.jboss.security.srp.SRPRemoteServer;
/** An RMI application that creates a SRPRemoteServer instance and
exports it on the standard RMI register 1099 port. It creates a
SerialObjectStore as the SRPVerifierStore for the SRPRemoteServer.
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class SimpleSRPServer
{
SerialObjectStore store;
void run() throws IOException, AlreadyBoundException, RemoteException
{
store = new SerialObjectStore();
SRPRemoteServer server = new SRPRemoteServer(store);
Registry reg = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
reg.bind("SimpleSRPServer", server);
}
public static void main(String[] args) throws Exception
{
SimpleSRPServer server = new SimpleSRPServer();
server.run();
}
}
1.1 jbosssx/src/main/org/jboss/test/TestLogin.java
Index: TestLogin.java
===================================================================
package org.jboss.test;
import java.security.*;
import javax.security.auth.*;
public class TestLogin
{
public static void main(String[] args) throws Exception
{
System.setProperty("java.security.policy", "policy");
System.out.println("java.security.manager =
"+System.getProperty("java.security.manager"));
Permission p = new AuthPermission("getLoginConfiguration");
AccessController.checkPermission(p);
}
}
1.1 jbosssx/src/main/org/jboss/test/TestLoginModule.java
Index: TestLoginModule.java
===================================================================
package org.jboss.test;
import java.security.*;
import java.util.*;
import javax.security.auth.*;
import javax.security.auth.callback.*;
import javax.security.auth.login.*;
import javax.security.auth.spi.*;
public class TestLoginModule implements LoginModule
{
Subject subject;
String principal;
public TestLoginModule()
{
}
public void initialize(Subject subject, CallbackHandler handler, Map
sharedState, Map options)
{
this.subject = subject;
principal = (String) options.get("principal");
if( principal == null )
principal = "guest";
}
public boolean login() throws LoginException
{
subject.getPrincipals().add(new SimplePrincipal(principal));
return true;
}
public boolean commit() throws LoginException
{
return true;
}
public boolean abort() throws LoginException
{
return true;
}
public boolean logout() throws LoginException
{
return true;
}
public static class SimplePrincipal implements Principal
{
String name;
public SimplePrincipal(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
}
1.1 jbosssx/src/main/org/jboss/test/TestProtocol.java
Index: TestProtocol.java
===================================================================
/*
* JBoss, the OpenSource EJB server
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package org.jboss.test;
import java.io.Serializable;
import java.math.BigInteger;
import java.rmi.RemoteException;
import java.security.KeyException;
import java.security.MessageDigest;
import org.apache.log4j.Category;
import org.apache.log4j.FileAppender;
import org.apache.log4j.NDC;
import org.apache.log4j.PatternLayout;
import org.jboss.security.Util;
import org.jboss.security.srp.SRPConf;
import org.jboss.security.srp.SRPServerInterface;
import org.jboss.security.srp.SRPServerInterface.SRPParameters;
import org.jboss.security.srp.SRPClientSession;
import org.jboss.security.srp.SRPServerSession;
import org.jboss.security.srp.TracePriority;
/** Test of the SRP protocol msg exchange sequence.
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class TestProtocol extends junit.framework.TestCase
{
String username = "stark";
String password = "scott";
SRPServerInterface server;
/** A simple hard coded implementation of SRPServerInterface that validates
any given username to the password and salt provided to its constructor.
*/
static class TstImpl implements SRPServerInterface
{
SRPParameters params = new SRPParameters();
SRPServerSession session;
String password;
TstImpl(String password, String salt)
{
params.N = SRPConf.getDefaultParams().Nbytes();
params.g = SRPConf.getDefaultParams().gbytes();
params.s = Util.fromb64(salt);
this.password = password;
}
public SRPParameters getSRPParameters(String username) throws KeyException,
RemoteException
{
return params;
}
public byte[] init(String username,byte[] A) throws SecurityException,
RemoteException
{
// Calculate the password verfier v
byte[] v = Util.calculateVerifier(username, password, params.s,
params.N, params.g);
// Create an SRP session
session = new SRPServerSession(username, params.s, v, params.N,
params.g);
byte[] B = session.exponential();
session.buildSessionKey(A);
return B;
}
public byte[] verify(String username, byte[] M1) throws SecurityException,
RemoteException
{
if( session.verify(M1) == false )
throw new SecurityException("Failed to verify M1");
return session.getServerResponse();
}
}
public TestProtocol(String name)
{
super(name);
}
protected void setUp() throws Exception
{
// Set up a simple configuration that logs on the console.
Category root = Category.getRoot();
root.setPriority(TracePriority.TRACE);
root.addAppender(new FileAppender(new PatternLayout("%x%m%n"), System.out));
Util.init();
NDC.push("S,");
server = new TstImpl(password, "123456");
NDC.pop();
}
public void testProtocol() throws Exception
{
SRPParameters params = server.getSRPParameters(username);
NDC.push("C,");
SRPClientSession client = new SRPClientSession(username, password, params.s,
params.N, params.g);
byte[] A = client.exponential();
NDC.pop();
NDC.push("S,");
byte[] B = server.init(username, A);
NDC.pop();
NDC.push("C,");
byte[] M1 = client.response(B);
NDC.pop();
NDC.push("S,");
byte[] M2 = server.verify(username, M1);
NDC.pop();
NDC.push("C,");
if( client.verify(M2) == false )
throw new SecurityException("Failed to validate server reply");
NDC.pop();
}
/**
* @param args the command line arguments
*/
public static void main(String args[])
{
long start = System.currentTimeMillis();
try
{
TestProtocol tst = new TestProtocol("main");
tst.setUp();
tst.testProtocol();
}
catch(Exception e)
{
e.printStackTrace(System.out);
}
finally
{
long end = System.currentTimeMillis();
System.out.println("Elapsed time = "+(end - start));
}
}
}
1.1 jbosssx/src/main/org/jboss/test/TestSRPLogin.java
Index: TestSRPLogin.java
===================================================================
package org.jboss.test;
import java.net.URL;
import javax.security.auth.Policy;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.SecurityPolicy;
import org.jboss.security.SecurityPolicyParser;
import org.jboss.security.plugins.UsernamePasswordHandler;
/** A test of the SRPLogin module
@see org.jboss.security.srp.jaas.SRPLoginModule
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class TestSRPLogin extends junit.framework.TestCase
{
public TestSRPLogin(String name)
{
super(name);
}
/** Create a SecurityPolicy from a xml policy file and install it as the
JAAS Policy and Configuration implementations.
*/
protected void setUp() throws Exception
{
// Create a subject security policy
String policyName = "tst-policy.xml";
URL policyURL = getClass().getClassLoader().getResource(policyName);
if( policyURL == null )
throw new IllegalStateException("Failed to find "+policyName+" in
classpath");
SecurityPolicyParser policyStore = new SecurityPolicyParser(policyURL);
SecurityPolicy policy = new SecurityPolicy(policyStore);
policy.refresh();
Policy.setPolicy(policy);
Configuration.setConfiguration(policy.getLoginConfiguration());
}
public void testLogin()
{
CallbackHandler handler = new UsernamePasswordHandler("scott",
"stark".toCharArray());
try
{
LoginContext lc = new LoginContext("srp-login", handler);
lc.login();
Subject subject = lc.getSubject();
System.out.println("Subject="+subject);
}
catch(LoginException e)
{
e.printStackTrace();
fail(e.getMessage());
}
}
public static void main(String args[])
{
try
{
TestSRPLogin tst = new TestSRPLogin("main");
tst.setUp();
}
catch(Exception e)
{
e.printStackTrace(System.out);
}
}
}
1.1 jbosssx/src/main/org/jboss/test/TestSecurityPolicyParser.java
Index: TestSecurityPolicyParser.java
===================================================================
package org.jboss.test;
import java.net.URL;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
import java.util.PropertyPermission;
import javax.security.auth.Policy;
import javax.security.auth.Subject;
import javax.security.auth.login.Configuration;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
import org.jboss.security.SimplePrincipal;
import org.jboss.security.SecurityPolicy;
import org.jboss.security.SecurityPolicyParser;
/** Tests of the SecurityPolicyParser and SecurityPolicy classes.
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class TestSecurityPolicyParser extends junit.framework.TestCase
{
public TestSecurityPolicyParser(String name)
{
super(name);
}
protected void setUp() throws Exception
{
String policyName = "tst-policy.xml";
URL policyURL = getClass().getClassLoader().getResource(policyName);
SecurityPolicyParser policyStore = new SecurityPolicyParser(policyURL);
SecurityPolicy policy = new SecurityPolicy(policyStore);
Policy.setPolicy(policy);
policy.refresh();
Configuration.setConfiguration(policy.getLoginConfiguration());
}
public void testParser()
{
Subject subject = new Subject();
subject.getPrincipals().add(new SimplePrincipal("starksm"));
CodeSource cs = new CodeSource(null, null);
Policy policy = Policy.getPolicy();
SecurityPolicy.setActiveApp("test-domain");
PermissionCollection perms = policy.getPermissions(subject, cs);
Permission p = new NamespacePermission("Project1/Documents/Public", "r---");
boolean implied = perms.implies(p);
assert(p.toString(), implied);
}
public void testSubject() throws LoginException
{
LoginContext lc = new LoginContext("test-domain");
lc.login();
Subject subject = lc.getSubject();
System.out.println("Subject="+subject);
SecurityPolicy.setActiveApp("test-domain");
CodeSource cs = new CodeSource(null, null);
ProtectionDomain pd = getClass().getProtectionDomain();
cs = pd.getCodeSource();
Subject.doAsPrivileged(subject, new PrivilegedAction()
{
public Object run()
{
SecurityDelegate.accessProject("Project1", "r---", false);
SecurityDelegate.accessProject("Project1", "rw--", false);
SecurityDelegate.accessProject("Project1", "rw-d", false);
SecurityDelegate.accessProject("Project1/Documents/Private",
"rwxd", false);
SecurityDelegate.accessProject("Project1/Documents/Public",
"r---", true);
SecurityDelegate.accessProject("Project1/Documents/Public/readme.html", "r---", true);
SecurityDelegate.accessProject("Project1/Documents/Public/readme.html", "rw--", false);
return null;
}
},
null
);
}
/** The code that executes the custom permission check needs to be in a
separate class so that we can jar it up to create a codesource whcich
is disticnt from the TestSecurityPolicyParser codesource.
*/
static class SecurityDelegate
{
static void accessProject(String path, String action, boolean shouldAllow)
{
Permission p = new NamespacePermission(path, action);
try
{
AccessController.checkPermission(p);
if( shouldAllow == false )
throw new IllegalStateException("Access allowed for: "+path+",
action="+action);
}
catch(SecurityException e)
{
if( shouldAllow == true )
throw new IllegalStateException("Access denied for: "+path+",
action="+action);
}
try
{
// Try a Java2 permission check that should fail for everyone
p = new PropertyPermission("java.class.path", "write");
AccessController.checkPermission(p);
throw new IllegalStateException("access allowed for: "+p);
}
catch(SecurityException e)
{
}
}
}
public static void main(String[] args) throws Exception
{
TestSecurityPolicyParser tst = new TestSecurityPolicyParser("main");
tst.setUp();
//tst.testParser();
tst.testSubject();
}
}
1.1 jbosssx/src/main/org/jboss/test/TstClient.java
Index: TstClient.java
===================================================================
package org.jboss.test;
import java.io.IOException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import org.jboss.security.srp.SRPClientSession;
import org.jboss.security.srp.SRPServerInterface;
import org.jboss.security.srp.SRPServerInterface.SRPParameters;
/** A simple test client that looks up the SimpleSRPServer in the RMI
registry and attempts to validate the username and password passed
on the command line.
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class TstClient
{
public static void main(String[] args) throws Exception
{
String username = args[0];
String password = args[1];
SRPServerInterface server = (SRPServerInterface)
Naming.lookup("SimpleSRPServer");
System.out.println("Found SRPServerInterface");
SRPParameters params = server.getSRPParameters(username);
System.out.println("Found params for username: "+username);
SRPClientSession client = new SRPClientSession(username, password, params.s,
params.N, params.g);
byte[] A = client.exponential();
byte[] B = server.init(username, A);
System.out.println("Sent A public key, got B public key");
byte[] M1 = client.response(B);
byte[] M2 = server.verify(username, M1);
System.out.println("Sent M1 challenge, got M2 challenge");
if( client.verify(M2) == false )
throw new SecurityException("Failed to validate server reply");
System.out.println("Validation successful");
}
}
1.1 jbosssx/src/main/org/jboss/test/TstTimedCache.java
Index: TstTimedCache.java
===================================================================
package org.jboss.test;
import java.io.FilePermission;
import java.net.URL;
import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.Policy;
import org.jboss.util.TimedCachePolicy;
/** Tests of the TimedCachePolicy class.
@see org.jboss.util.TimedCachePolicy
@author [EMAIL PROTECTED]
@version $Revision: 1.1 $
*/
public class TstTimedCache
{
static class Refreshable implements TimedCachePolicy.TimedEntry
{
int refreshes;
long expirationTime;
Object value;
Refreshable(long lifetime, Object value, int refreshes)
{
this.expirationTime = 1000 * lifetime;
this.value = value;
this.refreshes = refreshes;
}
public void init(long now)
{
expirationTime += now;
System.out.println(value+".init("+now+"),
expirationTime="+expirationTime);
}
public boolean isCurrent(long now)
{
System.out.println(value+".isCurrent("+now+") = "+(expirationTime >
now));
return expirationTime > now;
}
public boolean refresh()
{
refreshes --;
System.out.println(value+".refresh() = "+(refreshes > 0));
return refreshes > 0;
}
public Object getValue()
{
return value;
}
}
/**
* @param args the command line arguments
*/
public static void main(String args[])
{
TimedCachePolicy cache = new TimedCachePolicy(20, false, 1);
cache.init();
cache.start();
cache.insert("1", new Refreshable(5, "value1", 4));
cache.insert("2", new Refreshable(3, "value2", 10));
cache.insert("3", "value3");
long start = System.currentTimeMillis();
// Loop until the longest lived value is gone
while( cache.peek("2") != null )
{
long now = System.currentTimeMillis();
System.out.println("Elapsed: "+(now - start) / 1000);
System.out.println("get(1) -> "+cache.get("1"));
System.out.println("get(2) -> "+cache.get("2"));
System.out.println("get(3) -> "+cache.get("3"));
try
{
Thread.currentThread().sleep(3*1000);
}
catch(InterruptedException e)
{
}
}
long now = System.currentTimeMillis();
System.out.println("End, elapsed: "+(now - start) / 1000);
System.out.println("get(1) -> "+cache.get("1"));
System.out.println("get(2) -> "+cache.get("2"));
System.out.println("get(3) -> "+cache.get("3"));
}
}