User: stark   
  Date: 01/03/05 01:53:30

  Added:       src/main/org/jboss/security AbstractSecurityProxy.java
                        AppPolicy.java AuthenticationInfo.java
                        AuthorizationInfo.java ClientLoginModule.java
                        EJBSecurityManager.java IAppPolicyStore.java
                        RealmMapping.java SecurityAssociation.java
                        SecurityPolicy.java SecurityPolicyParser.java
                        SecurityProxy.java SecurityProxyFactory.java
                        SimpleGroup.java SimplePrincipal.java
                        SubjectSecurityManager.java
                        SubjectSecurityProxy.java
                        SubjectSecurityProxyFactory.java Util.java
  Log:
  Initial version of the JBossSX module
  
  Revision  Changes    Path
  1.1                  jbosssx/src/main/org/jboss/security/AbstractSecurityProxy.java
  
  Index: AbstractSecurityProxy.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.Method;
  import java.util.HashMap;
  import javax.ejb.EJBContext;
  
  import org.jboss.ejb.MethodInvocation;
  
  /** An abstract implementation of SecurityProxy that wraps a non-SecurityProxy
  object. Subclasses of this class are used to create a SecurityProxy given
  a security delegate that implements methods in the EJB home or remote
  interface for security checks. This allows custom security classes to be
  written without using a JBoss specific interface. It also allows the security
  delegate to follow a natural proxy pattern implementation.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public abstract class AbstractSecurityProxy implements SecurityProxy
  {
      private HashMap methodMap;
      private Method setContextMethod;
      private Method setBeanMethod;
      protected Object delegate;
  
      AbstractSecurityProxy(Object delegate)
      {
          this.delegate = delegate;
          methodMap = new HashMap();
      }
  
      /** Subclasses implement this method to actually invoke the given home
          method on the proxy delegate.
      @param m, the delegate method that was mapped from the ejb home method.
      @param args, the method invocation arguments.
      @param delegate, the proxy delegate object associated with the
          AbstractSecurityProxy
      @see invokeHome(Method, Object[])
      */
      protected abstract void invokeHomeOnDelegate(Method m, Object[] args, Object 
delegate) throws SecurityException;
      /** Subclasses implement this method to actually invoke the given remote
          method on the proxy delegate.
      @param m, the delegate method that was mapped from the ejb remote method.
      @param args, the method invocation arguments.
      @param delegate, the proxy delegate object associated with the
          AbstractSecurityProxy
      @see invoke(Method, Object[], Object)
      */
      protected abstract void invokeOnDelegate(Method m, Object[] args, Object 
delegate) throws SecurityException;
  
      /** This method is called by the container SecurityInterceptor to intialize
          the proxy with the EJB home and remote interface classes that the
          container is housing. This method creates a mapping from the home and
          remote classes to the proxy delegate instance. The mapping is based on
          method name and paramter types. In addition, the proxy delegate is
          inspected for a setEJBContext(EJBContext) and a setBean(Object) method
          so that the active EJBContext and EJB instance can be passed to the
          delegate prior to method invocations.
  
      @param beanHome, the class for the EJB home interface
      @param beanRemote, the class for the EJB remote interface
      @param securityMgr, The security manager instance assigned to the container.
          It is not used by this class.
      */
      public void init(Class beanHome, Class beanRemote, Object securityMgr) throws 
InstantiationException
      {
          mapHomeMethods(beanHome);
          mapRemoteMethods(beanRemote);
          try
          {
              Class[] parameterTypes = {EJBContext.class};
              setContextMethod = delegate.getClass().getMethod("setEJBContext", 
parameterTypes);
          }
          catch(Exception e)
          {
          }
          try
          {
              Class[] parameterTypes = {Object.class};
              setBeanMethod = delegate.getClass().getMethod("setBean", parameterTypes);
          }
          catch(Exception e)
          {
          }
      }
  
      /**
      */
      public void setEJBContext(EJBContext ctx)
      {
          if( setContextMethod != null )
          {
              Object[] args = {ctx};
              try
              {
                  setContextMethod.invoke(delegate, args);
              }
              catch(Exception e)
              {
                  e.printStackTrace();
              }
          }
      }
  
      /** Called by the SecurityInterceptor to allow the proxy delegate to perform
          a security check of the indicated home interface method.
      @param m, the EJB home interface method
      @param args, the method arguments
      */
      public void invokeHome(final Method m, Object[] args) throws SecurityException
      {
          Method delegateMethod = (Method) methodMap.get(m);
          if( delegateMethod != null )
              invokeHomeOnDelegate(delegateMethod, args, delegate);
      }
  
      /** Called by the SecurityInterceptor to allow the proxy delegate to perform
          a security check of the indicated remote interface method.
      @param m, the EJB remote interface method
      @param args, the method arguments
      @param bean, the EJB bean instance
      */
      public void invoke(final Method m, final Object[] args, final Object bean) 
throws SecurityException
      {
          Method delegateMethod = (Method) methodMap.get(m);
          if( delegateMethod != null )
          {
              if( setBeanMethod != null )
              {
                  Object[] bargs = {bean};
                  try
                  {
                      setBeanMethod.invoke(delegate, bargs);
                  }
                  catch(Exception e)
                  {
                      e.printStackTrace();
                      throw new SecurityException("Failed to set bean on 
proxy"+e.getMessage());
                  }
              }
              invokeOnDelegate(delegateMethod, args, delegate);
          }
      }
  
      /** Performs a mapping from the methods declared in the beanHome
          class to the proxy delegate class.
      */
      protected void mapHomeMethods(Class beanHome)
      {
          Class delegateClass = delegate.getClass();
          Method[] methods = beanHome.getMethods();
          for(int m = 0; m < methods.length; m ++)
          {
              // Check for ejbCreate... methods
              Method hm = methods[m];
              Class[] parameterTypes = hm.getParameterTypes();
              String name = hm.getName();
              name = "ejb" + Character.toUpperCase(name.charAt(0)) + name.substring(1);
              try
              {
                  Method match = delegateClass.getMethod(name, parameterTypes);
                  methodMap.put(hm, match);
              }
              catch(NoSuchMethodException e)
              {
              }
          }
      }
   
      /** Performs a mapping from the methods declared in the beanRemote
          class to the proxy delegate class.
      */
      protected void mapRemoteMethods(Class beanRemote)
      {
          Class delegateClass = delegate.getClass();
          Method[] methods = beanRemote.getMethods();
          for(int m = 0; m < methods.length; m ++)
          {
              // Check for ejbCreate... methods
              Method rm = methods[m];
              Class[] parameterTypes = rm.getParameterTypes();
              String name = rm.getName();
              try
              {
                  Method match = delegateClass.getMethod(name, parameterTypes);
                  methodMap.put(rm, match);
              }
              catch(NoSuchMethodException e)
              {
              }
          }
      }
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/AppPolicy.java
  
  Index: AppPolicy.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.io.IOException;
  import java.security.AccessController;
  import java.security.AllPermission;
  import java.security.CodeSource;
  import java.security.KeyStore;
  import java.security.Permission;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.Principal;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Set;
  import javax.security.auth.AuthPermission;
  import javax.security.auth.Policy;
  import javax.security.auth.Refreshable;
  import javax.security.auth.RefreshFailedException;
  import javax.security.auth.Subject;
  import javax.security.auth.login.AppConfigurationEntry;
  
  /** A combination of keystore, authentication and authorization entries.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public class AppPolicy
  {
      /** A PermissionCollection that allows no permissions */
      public static final PermissionCollection NO_PERMISSIONS =  new Permissions();
      /** A PermissionCollection that allows all permissions */
      private static PermissionCollection ALL_PERMISSIONS;
  
      /**
       * @label defaultAppPolicy 
       */
      private static AppPolicy defaultAppPolicy;
  
      // Setup the class statics
      static
      {
          // A PermissionCollection that allows all permissions
          AllPermission all = new AllPermission();
          ALL_PERMISSIONS = all.newPermissionCollection();
          ALL_PERMISSIONS.add(all);
          // A default policy with no authentication and NO_PERMISSIONS
          defaultAppPolicy = new AppPolicy("other");
      }
  
      private String appName;
      private KeyStore keyStore;
  
      /**
       * @label permissions 
       */
      private AuthorizationInfo permissionInfo;
  
      /**
       * @label login 
       */
      private AuthenticationInfo loginInfo;
  
      public KeyStore getKeyStore()
      {
          return keyStore;
      }
      public void setKeyStore(KeyStore keyStore)
      {
          this.keyStore = keyStore;
      }
  
      public static void setDefaultAppPolicy(AppPolicy policy)
      {
          if( policy == null )
              throw new IllegalArgumentException("The policy argument cannot be null");
          defaultAppPolicy = policy;
      }
      public static AppPolicy getDefaultAppPolicy()
      {
          return defaultAppPolicy;
      }
  
      public AppPolicy(String appName)
      {
          this.appName = appName;
      }
  
      public AuthenticationInfo getLoginInfo()
      {
          AccessController.checkPermission(AuthenticationInfo.GET_CONFIG_ENTRY_PERM);
          return loginInfo;
      }
      public void setLoginInfo(AuthenticationInfo loginInfo)
      {
          AccessController.checkPermission(AuthenticationInfo.SET_CONFIG_ENTRY_PERM);
          this.loginInfo = loginInfo;
      }
      public AuthorizationInfo getPermissionInfo()
      {
          return permissionInfo;
      }
      public void setPermissionInfo(AuthorizationInfo permissionInfo)
      {
          this.permissionInfo = permissionInfo;
      }
  
      public AppConfigurationEntry[] getAppConfigurationEntry()
      {
          AppConfigurationEntry[] appConfig = null;
          if( loginInfo != null )
              appConfig = loginInfo.getAppConfigurationEntry();
          if( appConfig == null )
              appConfig = defaultAppPolicy.getAppConfigurationEntry();
          AppConfigurationEntry[] copy = null;
          if( appConfig != null )
          {
              copy = new AppConfigurationEntry[appConfig.length];
              for(int c = 0; c < copy.length; c ++)
              {
                  AppConfigurationEntry e0 = appConfig[c];
                  AppConfigurationEntry e1 = new AppConfigurationEntry(
                      e0.getLoginModuleName(),
                      e0.getControlFlag(),
                      e0.getOptions()
                      );
                  copy[c] = e1;
              }
          }
          return copy;
      }
        public PermissionCollection getPermissions(Subject subject, CodeSource 
codesource)
        {
          PermissionCollection perms = NO_PERMISSIONS;
          AuthorizationInfo info = getPermissionInfo();
          if( info == null )
              info = defaultAppPolicy.getPermissionInfo();
          if( info != null )
          {
              perms = info.getPermissions(subject, codesource);
          }
  
          return perms;
        }
  
      public String toString()
      {
          StringBuffer buffer = new StringBuffer(appName);
          buffer.append('\n');
          buffer.append("AuthenticationInfo:\n");
          if( loginInfo != null )
              buffer.append(loginInfo);
          buffer.append("AuthorizationInfo:\n");
          if( permissionInfo != null )
              buffer.append(permissionInfo);
          return buffer.toString();
      }
     
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/AuthenticationInfo.java
  
  Index: AuthenticationInfo.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.security.AccessController;
  import javax.security.auth.AuthPermission;
  import javax.security.auth.callback.CallbackHandler;
  import javax.security.auth.login.Configuration;
  import javax.security.auth.login.AppConfigurationEntry;
  
  /** The login module configuration information.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public class AuthenticationInfo
  {
      public static final AuthPermission GET_CONFIG_ENTRY_PERM = new 
AuthPermission("getLoginConfiguration");
      public static final AuthPermission SET_CONFIG_ENTRY_PERM = new 
AuthPermission("setLoginConfiguration");
      private AppConfigurationEntry[] loginModules;
      private CallbackHandler callbackHandler;
  
      /** Get an application authentication configuration. This requires an
      AuthPermission("getLoginConfiguration") access.
      */
      public AppConfigurationEntry[] getAppConfigurationEntry()
      {
          AccessController.checkPermission(GET_CONFIG_ENTRY_PERM);
          return loginModules;
      }
      /** Set an application authentication configuration. This requires an
      AuthPermission("setLoginConfiguration") access.
      */
      public void setAppConfigurationEntry(AppConfigurationEntry[] loginModules)
      {
          AccessController.checkPermission(SET_CONFIG_ENTRY_PERM);
          this.loginModules = loginModules;
      }
  
      /**
      */
      public CallbackHandler getAppCallbackHandler()
      {
          return callbackHandler;
      }
      public void setAppCallbackHandler(CallbackHandler handler)
      {
          this.callbackHandler = handler;
      }
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/AuthorizationInfo.java
  
  Index: AuthorizationInfo.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.io.IOException;
  import java.security.AccessController;
  import java.security.CodeSource;
  import java.security.Permission;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.Principal;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Set;
  import javax.security.auth.AuthPermission;
  import javax.security.auth.Subject;
  
  /**
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public class AuthorizationInfo
  {
      private static Set emptySet = new HashSet();
      private ArrayList policyMap = new ArrayList();
      private PolicyEntry[] policyEntries;
  
      /** An inner class that represents a grant entry in policyMap. It is composed
       *of a CodeSource and an array of Prinicpals along with the granted
       *permissions.
       */
      static class PolicyEntry
      {
          private CodeSource cs;
          private Principal[] principals;
          private ArrayList permissions;
  
          PolicyEntry(CodeSource cs, Principal[] principals, ArrayList permissions)
          {
              this.cs = cs;
              this.principals = principals;
              this.permissions = permissions;
          }
  
          public void getPermissions(PermissionCollection perms)
          {
              int length = permissions == null ? 0 : permissions.size();
              for(int n = 0; n < length; n ++)
              {
                  Permission permission = (Permission) permissions.get(n);
                  perms.add(permission);
              }
          }
  
          public boolean implies(CodeSource codesrc, Set subjectPrincipals)
          {
              boolean implies = false;
              // Check codesources
              if( this.cs == codesrc )
              {   // Both null or the same object
                  implies = true;
              }
              else if( this.cs != null && codesrc != null && this.cs.implies(codesrc) )
              {
                  implies = true;
              }
  
              // Check Principals
              if( implies == true )
              {
                  if( this.principals != null )
                  {   // Every one of our principals must be in subjectPrincipals
                      for(int p = 0; p < this.principals.length; p ++)
                      {
                          if( subjectPrincipals.contains(this.principals[p]) == false )
                          {
                              implies = false;
                              break;
                          }
                      }
                  }
              }
  
              return implies;
          }
          public boolean equals(Object obj)
          {
              PolicyEntry key = (PolicyEntry) obj;
              boolean equals = this.cs == key.cs;
              if( equals == false )
              {
                  if( this.cs != null && key.cs != null )
                      equals = this.cs.equals(key.cs);
                  if( equals == true )
                  {   // Every principal in this must equal 
                      if( this.principals != null && key.principals != null && 
this.principals.length == key.principals.length )
                      {
                          for(int p = 0; p < this.principals.length; p ++)
                          {
                              if( this.principals[p].equals(key.principals[p]) == 
false )
                              {
                                  equals = false;
                                  break;
                              }
                          }
                      }
                      else if( this.principals != null || key.principals != null )
                      {
                          equals = false;
                      }
                  }
              }
              return equals;
          }
          public int hashCode()
          {
              int hashCode = 0;
              if( cs != null )
                  hashCode = cs.hashCode();
              int length = (this.principals == null ? 0 : this.principals.length);
              for(int p = 0; p < length; p ++)
              {
                  hashCode += this.principals[p].hashCode();
              }
              return hashCode;
          }
  
          public String toString()
          {
              StringBuffer buffer = new StringBuffer();
              buffer.append("cs=");
              buffer.append(cs);
              buffer.append("; principals=");
              for(int p = 0; principals != null && p < principals.length; p ++)
                  buffer.append(principals[p]);
              buffer.append("; permissions=");
              buffer.append(permissions);
              return buffer.toString();
          }
      }
  
      public AuthorizationInfo()
      {
      }
  
        public PermissionCollection getPermissions(Subject subject, CodeSource 
codesource)
        {
                PermissionCollection perms = new Permissions();
          Set subjectPrincipals = emptySet;
          if( subject != null )
              subjectPrincipals = subject.getPrincipals();
          for(int n = 0; n < policyMap.size(); n ++)
          {
              PolicyEntry entry = (PolicyEntry) policyMap.get(n);
              if( entry.implies(codesource, subjectPrincipals) == true )
                  entry.getPermissions(perms);
          }
                return perms;
        }
  
      public String toString()
      {
          StringBuffer buffer = new StringBuffer("permissions:");
          return buffer.toString();
      }
  
      public void grant(CodeSource cs, ArrayList permissions)
      {
          grant(cs, permissions, null);
      }
      public void grant(CodeSource cs, ArrayList permissions, Principal[] principals)
      {
          PolicyEntry entry = new PolicyEntry(cs, principals, permissions);
          policyMap.add(entry);
      }
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/ClientLoginModule.java
  
  Index: ClientLoginModule.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
   
  package org.jboss.security;
  
  
  import java.util.Map;
  import javax.security.auth.Subject;
  import javax.security.auth.callback.Callback;
  import javax.security.auth.callback.CallbackHandler;
  import javax.security.auth.callback.NameCallback;
  import javax.security.auth.callback.PasswordCallback;
  import javax.security.auth.callback.UnsupportedCallbackException;
  import javax.security.auth.login.LoginException;
  import javax.security.auth.spi.LoginModule;
  
  /** A simple implementation of LoginModule for use by JBoss clients for
  the establishment of the caller identity and credentials. This simply sets
  the SecurityAssociation principal to the value of the NameCallback
  filled in by the CallbackHandler, and the SecurityAssociation credential
  to the value of the PasswordCallback filled in by the CallbackHandler.
  
  It has the following options:
  <ul>
  <li>multi-threaded=[true|false]
  When the multi-threaded option is set to true, the SecurityAssociation.setServer()
  so that each login thread has its own principal and credential storage.
  <li>password-stacking=tryFirstPass|useFirstPass
  When password-stacking option is set, this module first looks for a shared
  username and password using "javax.security.auth.login.name" and
  "javax.security.auth.login.password" respectively. This allows a module configured
  prior to this one to establish a valid username and password that should be passed
  to JBoss.
  </ul>
  
  @author <a href="mailto:[EMAIL PROTECTED]">Oleg Nitz</a>
  @author [EMAIL PROTECTED]
  */
  public class ClientLoginModule implements LoginModule
  {
      private CallbackHandler _callbackHandler;
      /** Shared state between login modules */
      private Map _sharedState;
      /** Flag indicating if the shared password should be used */
      private boolean _useFirstPass;
  
      /**
       * Initialize this LoginModule.
       */
      public void initialize(Subject subject, CallbackHandler callbackHandler,
              Map sharedState, Map options)
      {
          this._callbackHandler = callbackHandler;
          this._sharedState = sharedState;
          // Check for multi-threaded option
          String mt = (String) options.get("multi-threaded");
          if( mt != null && Boolean.valueOf(mt).booleanValue() == true )
          {   /* Turn on the server mode which uses thread local storage for
                  the principal information.
              */
              SecurityAssociation.setServer();
          }
  
          /* Check for password sharing options. Any non-null value for
              password_stacking sets useFirstPass as this module has no way to
              validate any shared password.
           */
          String passwordStacking = (String) options.get("password-stacking");
          _useFirstPass = passwordStacking != null;
      }
  
      /**
       * Method to authenticate a Subject (phase 1).
       */
      public boolean login() throws LoginException
      {
          // If useFirstPass is true, look for the shared password
          if( _useFirstPass == true )
          {
              try
              {
                  String username = (String) 
_sharedState.get("javax.security.auth.login.name");
                  Object credential = 
_sharedState.get("javax.security.auth.login.password");
                  SecurityAssociation.setPrincipal(new SimplePrincipal(username));
                  SecurityAssociation.setCredential(credential);
                  return true;
              }
              catch(Exception e)
              {   // Dump the exception and continue
                  e.printStackTrace();
              }
          }
  
          /* There is no password sharing or we are the first login module. Get
              the username and password from the callback hander.
          */
          if (_callbackHandler == null)
              throw new LoginException("Error: no CallbackHandler available " +
                  "to garner authentication information from the user");
  
          PasswordCallback pc = new PasswordCallback("Password: ", false);
          NameCallback nc = new NameCallback("User name: ", "guest");
          Callback[] callbacks = {nc, pc};
          try {
              String username;
              char[] password = null;
              char[] tmpPassword;
  
              _callbackHandler.handle(callbacks);
              username = nc.getName();
              SecurityAssociation.setPrincipal(new SimplePrincipal(username));
              tmpPassword = pc.getPassword();
              if (tmpPassword != null) {
                  password = new char[tmpPassword.length];
                  System.arraycopy(tmpPassword, 0, password, 0, tmpPassword.length);
                  pc.clearPassword();
              }
              SecurityAssociation.setCredential(password);
          } catch (java.io.IOException ioe) {
              throw new LoginException(ioe.toString());
          } catch (UnsupportedCallbackException uce) {
              throw new LoginException("Error: " + uce.getCallback().toString() +
                      " not available to garner authentication information " +
                      "from the user");
          }
          return true;
      }
            
      /**
       * Method to commit the authentication process (phase 2).
       */
      public boolean commit() throws LoginException {
          return true;
      }    
            
      /**
       * Method to abort the authentication process (phase 2).
       */
      public boolean abort() throws LoginException {
          SecurityAssociation.setPrincipal(null);
          SecurityAssociation.setCredential(null);
          return true;
      }
  
      public boolean logout() throws LoginException {
          SecurityAssociation.setPrincipal(null);
          SecurityAssociation.setCredential(null);
          return true;
      }
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/EJBSecurityManager.java
  
  Index: EJBSecurityManager.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
   
  package org.jboss.security;
  
  import java.security.Principal;
  
  
  /**
   *      The EJBSecurityManager is responsible for validating credentials
   *      associated with principals.
   *      
   *   @author Daniel O'Connor [EMAIL PROTECTED]
   */
  public interface EJBSecurityManager
  {
        public boolean isValid( Principal principal, Object credential );
  }
  
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/IAppPolicyStore.java
  
  Index: IAppPolicyStore.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.security.CodeSource;
  import java.security.Principal;
  import java.util.ArrayList;
  
  /** An interface describing an AppPolicy security store. It is used by
  the SecurityPolicy class to isolate the source of security information
  from the SecurityPolicy.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public interface IAppPolicyStore
  {
      public AppPolicy getAppPolicy(String appName);
      public void refresh();
  
      /** @link aggregation 
       * @supplierCardinality 1..*
       * @clientCardinality 1*/
      /*#AppPolicy lnkAppPolicy;*/
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/RealmMapping.java
  
  Index: RealmMapping.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.security;
  
  import java.security.Principal;
  import java.util.Set;
  
  public interface RealmMapping
  {
      /**
       * This method should return Principal for the bean that may differ 
       * from the original Principal in the operational environment.
       */
      public Principal getPrincipal( Principal principal );
  
      /**
       * This method checks if the given ("original") Principal has
       * at least on of the roles in the given set.
       */
      public boolean doesUserHaveRole( Principal principal, Set roleNames );
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SecurityAssociation.java
  
  Index: SecurityAssociation.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.security;
  
  import java.security.Principal;
  
  /**
   *      <description> 
   *      
   *      @see <related>
   *      @author Daniel O'Connor ([EMAIL PROTECTED])
   */
  
  public final class SecurityAssociation
  {
      private static boolean server;
      private static Principal principal;
      private static Object credential;
      private static ThreadLocal thread_principal = new ThreadLocal();
      private static ThreadLocal thread_credential = new ThreadLocal();
  
      public static Principal getPrincipal()
      {
        if (server)
          return (Principal) thread_principal.get();
        else
          return principal;
      }
  
      public static Object getCredential()
      {
        if (server)
          return thread_credential.get();
        else
          return credential;
      }
  
      public static void setPrincipal( Principal principal )
      {
        if (server)
          thread_principal.set( principal );
        else
          SecurityAssociation.principal = principal;
      }
  
      public static void setCredential( Object credential )
      {
        if (server)
          thread_credential.set( credential );
        else
          SecurityAssociation.credential = credential;
      }
  
      public static void setServer()
      {
        server = true;
      }
  }
  
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SecurityPolicy.java
  
  Index: SecurityPolicy.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.net.URL;
  import java.security.AccessController;
  import java.security.CodeSource;
  import java.security.Permission;
  import java.security.PermissionCollection;
  import java.security.Permissions;
  import java.security.Principal;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.Set;
  import javax.security.auth.AuthPermission;
  import javax.security.auth.Policy;
  import javax.security.auth.RefreshFailedException;
  import javax.security.auth.Subject;
  import javax.security.auth.login.Configuration;
  import javax.security.auth.login.AppConfigurationEntry;
  
  import org.jboss.security.SimplePrincipal;
  
  /** An concrete implementation of the javax.security.auth.Policy class that
  categorizes authorization info by application.
  
  @see javax.security.auth.Policy
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public class SecurityPolicy extends Policy
  {
      private static final AuthPermission REFRESH_PERM = new 
AuthPermission("refreshPolicy");
      private static final Set emptySet = new HashSet();
      private static final ThreadLocal activeApp = new ThreadLocal();
  
      /**
       * @clientCardinality 1
       * @supplierCardinality 1
       * @clientRole Policy/Configuration Impl
       * @supplierRole Policy/Configuration data 
       */
      private IAppPolicyStore policyStore;
      private LoginConfiguration loginConfig = new LoginConfiguration();
  
      public class LoginConfiguration extends Configuration
      {
          public AppConfigurationEntry[] getAppConfigurationEntry(String appName)
          {
              AppConfigurationEntry[] entry = null;
              AppPolicy appPolicy = policyStore.getAppPolicy(appName);
              if( appPolicy != null )
              {
                  entry = appPolicy.getAppConfigurationEntry();
              }
              return entry;
          }
  
          public void refresh()
          {
              SecurityPolicy.this.refresh();
          }
      }
  
      public static void setActiveApp(String appName)
      {
          activeApp.set(appName);
      }
      public static void unsetActiveApp()
      {
          activeApp.set(null);
      }
  
      public SecurityPolicy(IAppPolicyStore policyStore)
      {
          this.policyStore = policyStore;
      }
  
      public Configuration getLoginConfiguration()
      {
          return loginConfig;
      }
  
      public PermissionCollection getPermissions(Subject subject, CodeSource 
codesource)
      {
          String appName = (String) activeApp.get();
          if( appName == null )
              appName = "other";
          PermissionCollection perms = getPermissions(subject, codesource, appName);
          return perms;
      }
  
      public PermissionCollection getPermissions(Subject subject, CodeSource 
codesource, String appName)
      {
          AppPolicy policy = policyStore.getAppPolicy(appName);
          PermissionCollection perms = AppPolicy.NO_PERMISSIONS;
          if( policy != null )
              perms = policy.getPermissions(subject, codesource);
          return perms;
      }
      public AppPolicy getAppPolicy(String appName)
      {
          AppPolicy appPolicy = policyStore.getAppPolicy(appName);
          return appPolicy;
      }
  
      public void refresh()
      {
          AccessController.checkPermission(REFRESH_PERM);
          policyStore.refresh();
      }
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SecurityPolicyParser.java
  
  Index: SecurityPolicyParser.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.io.InputStream;
  import java.io.IOException;
  import java.lang.reflect.Constructor;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.security.CodeSource;
  import java.security.KeyStore;
  import java.security.GeneralSecurityException;
  import java.security.Permission;
  import java.security.Principal;
  import java.security.UnresolvedPermission;
  import java.security.cert.Certificate;
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.StringTokenizer;
  import javax.security.auth.login.AppConfigurationEntry;
  import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
  
  import org.w3c.dom.Document;
  import org.w3c.dom.DOMException;
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  import org.w3c.dom.NamedNodeMap;
  
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  import org.xml.sax.SAXParseException;
  import org.xml.sax.EntityResolver;
  
  import javax.xml.parsers.DocumentBuilderFactory;
  import javax.xml.parsers.DocumentBuilder;
  
  
  /** A class that parses a XML document that conforms to the security-policy.dtd
  DTD that implements IAppPolicyStore for use with the SecurityPolicy class.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public class SecurityPolicyParser implements IAppPolicyStore
  {
      private static String DEFAULT_APP_POLICY_NAME = "other";
      private URL policyURL;
      private HashMap policyMap = new HashMap();
  
        /** Creates new SecurityPolicyParser */
      public SecurityPolicyParser(URL policyURL)
      {
          this.policyURL = policyURL;
      }
  
  
      public AppPolicy getAppPolicy(String appName)
      {
          AppPolicy appPolicy = (AppPolicy) policyMap.get(appName);
          if( appPolicy == null )
              appPolicy = AppPolicy.getDefaultAppPolicy();
          return appPolicy;
      }
  
      /** Load/reload the security policy
       */
      public void refresh()
      {
          Document doc = null;
          try
          {
              doc = loadURL();
          }
          catch(Exception e)
          {
              e.printStackTrace();
              return;
          }
  
          Element root = doc.getDocumentElement();
          NodeList apps = root.getElementsByTagName("application-policy");
          for(int n = 0; n < apps.getLength(); n ++)
          {
              Element app = (Element) apps.item(n);
              String name = app.getAttribute("name");
              AppPolicy appPolicy = new AppPolicy(name);
              try
              {
                  parse(app, appPolicy);
                  if( name.equals(DEFAULT_APP_POLICY_NAME) )
                      AppPolicy.setDefaultAppPolicy(appPolicy);
                  else
                      policyMap.put(name, appPolicy);
              }
              catch(Exception e)
              {
                  e.printStackTrace();
              }
          }
      }
  
      private Document loadURL() throws Exception
      {
          InputStream is = policyURL.openStream();
          DocumentBuilderFactory docBuilderFactory = 
DocumentBuilderFactory.newInstance();
          DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
          EntityResolver resolver = new LocalResolver();
          docBuilder.setEntityResolver(resolver);
          Document doc = docBuilder.parse(is);
          return doc;
      }
      private void parse(Element policy, AppPolicy appPolicy) throws Exception
      {
          parseKeyStore(policy, appPolicy);
          parseAuthentication(policy, appPolicy);
          parseAuthorization(policy, appPolicy);
      }
  
      /** Parse the application-policy/keystore element
      @param policy, the application-policy element
      */
      private void parseKeyStore(Element policy, AppPolicy appPolicy) throws Exception
      {
          // Load the keystore
          NodeList keystore = policy.getElementsByTagName("keystore");
          String keystoreHref = ".keystore";
          String keystoreType = "JKS";
          if( keystore.getLength() > 0 )
          {   // Load the cert KeyStore. This needs more work to be complete...
              Element e = (Element) keystore.item(0);
              keystoreHref = e.getAttribute("href");
              keystoreType = e.getAttribute("type");
              InputStream keystoreStream = null;
              try
              {
                  URL keystoreURL = new URL(keystoreHref);
                  keystoreStream = keystoreURL.openStream();
              }
              catch(MalformedURLException ex)
              {   // Assume this is just a resource name and look for in
                  ClassLoader loader = Thread.currentThread().getContextClassLoader();
                  keystoreStream = loader.getResourceAsStream(keystoreHref);
              }
              KeyStore keyStore = KeyStore.getInstance(keystoreType);
              // Where to get the password from...
              char[] password = {};
              keyStore.load(keystoreStream, password);
              appPolicy.setKeyStore(keyStore);
          }
      }
  
      /** Parse the application-policy/authentication element
      @param policy, the application-policy element
      */
      private void parseAuthentication(Element policy, AppPolicy appPolicy) throws 
Exception
      {
          // Parse the permissions
          NodeList authentication = policy.getElementsByTagName("authentication");
          if( authentication.getLength() == 0 )
              return;
          Element auth = (Element) authentication.item(0);
          NodeList modules = auth.getElementsByTagName("login-module");
          ArrayList tmp = new ArrayList();
          for(int n = 0; n < modules.getLength(); n ++)
          {
              Element grant = (Element) modules.item(n);
              parseModule(grant, tmp);
          }
          AppConfigurationEntry[] entries = new AppConfigurationEntry[tmp.size()];
          tmp.toArray(entries);
          AuthenticationInfo info = new AuthenticationInfo();
          info.setAppConfigurationEntry(entries);
          appPolicy.setLoginInfo(info);
      }
      private void parseModule(Element module, ArrayList entries) throws Exception
      {
          LoginModuleControlFlag controlFlag = LoginModuleControlFlag.OPTIONAL;
          String className = module.getAttribute("code");
          String flag = module.getAttribute("flag");
          if( flag != null )
          {
              if( flag.equals(LoginModuleControlFlag.REQUIRED.toString()) )
                  controlFlag = LoginModuleControlFlag.REQUIRED;
              else if( flag.equals(LoginModuleControlFlag.REQUISITE.toString()) )
                  controlFlag = LoginModuleControlFlag.REQUISITE;
              else if( flag.equals(LoginModuleControlFlag.SUFFICIENT.toString()) )
                  controlFlag = LoginModuleControlFlag.SUFFICIENT;
              else if( flag.equals(LoginModuleControlFlag.OPTIONAL.toString()) )
                  controlFlag = LoginModuleControlFlag.OPTIONAL;
          }
          NodeList opts = module.getElementsByTagName("module-option");
          HashMap options = new HashMap();
          for(int n = 0; n < opts.getLength(); n ++)
          {
              Element opt = (Element) opts.item(n);
              String name = opt.getAttribute("name");
              String value = getContent(opt, "");
              options.put(name, value);
          }
          AppConfigurationEntry entry = new AppConfigurationEntry(className, 
controlFlag, options);
          entries.add(entry);
      }
  
      /** Parse the application-policy/authorization element
      @param policy, the application-policy element
      */
      private void parseAuthorization(Element policy, AppPolicy appPolicy) throws 
Exception
      {
          // Parse the permissions
          NodeList authorization = policy.getElementsByTagName("authorization");
          if( authorization.getLength() == 0 )
              return;
          Element auth = (Element) authorization.item(0);
          NodeList grants = auth.getElementsByTagName("grant");
          for(int n = 0; n < grants.getLength(); n ++)
          {
              Element grant = (Element) grants.item(n);
              parseGrant(grant, appPolicy);
          }
      }
      private void parseGrant(Element grant, AppPolicy appPolicy) throws Exception
      {
          // Look for the codebase
          URL codebase = null;
          if( grant.getAttribute("codebase") != null )
          {
              String attr = grant.getAttribute("codebase");
              if( attr.length() > 0 )
                  codebase = new URL(attr);
          }
          // Look for the code signers
          String[] signerAliases = {};
          Certificate[] signedBy = null;
          if( grant.getAttribute("signedBy") != null )
          {
              String signers = grant.getAttribute("signedBy");
              if( signers.length() > 0 )
                  signedBy = getCertificates(signers, appPolicy.getKeyStore());
          }
          CodeSource cs = new CodeSource(codebase, signedBy);
  
          // Look for the principals
          ArrayList principals = null;
          NodeList tmp = grant.getElementsByTagName("principal");
          ClassLoader loader = Thread.currentThread().getContextClassLoader();
          for(int n = 0; n < tmp.getLength(); n ++)
          {
              Element principal = (Element) tmp.item(n);
              String code = principal.getAttribute("code");
              String name = principal.getAttribute("name");
              try
              {
                  Class cls = loader.loadClass(code);
                  // Assume there exists a constructor(String)
                  Class[] parameterTypes = {String.class};
                  Constructor ctor = cls.getConstructor(parameterTypes);
                  Object[] args = {name};
                  Principal p = (Principal) ctor.newInstance(args);
                  if( principals == null )
                      principals = new ArrayList();
                  principals.add(p);
              }
              catch(Exception e)
              {
                  throw new 
GeneralSecurityException(e.getClass().getName()+','+e.getMessage());
              }
          }
  
          // Get the permissions
          ArrayList permissions = null;
          tmp = grant.getElementsByTagName("permission");
          for(int n = 0; n < tmp.getLength(); n ++)
          {
              Element perm = (Element) tmp.item(n);
              String code = perm.getAttribute("code");
              String name = perm.getAttribute("name");
              String actions = perm.getAttribute("actions");
              String signers = perm.getAttribute("signedBy"); // Currently ignored...
              name = expandString(name);
              try
              {
                  Class cls = null;
                  // Assume there exists a ctor(String) or a ctor(String, String)
                  Constructor ctor = null;
                  Permission p = null;
                  try
                  {
                      cls = loader.loadClass(code);
                      Class[] parameterTypes2 = {String.class, String.class};
                      Object[] args2 = {name, actions};
                      ctor = cls.getConstructor(parameterTypes2);
                      p = (Permission) ctor.newInstance(args2);
                  }
                  catch(ClassNotFoundException e)
                  {   // Use an UnresolvedPermission
                      Certificate[] certs = null;
                      if( signers != null )
                          certs = getCertificates(signers, appPolicy.getKeyStore());
                      p = new UnresolvedPermission(code, name, actions, certs);
                  }
                  catch(Exception e)
                  {   // Try ctor(String)
                      Class[] parameterTypes = {String.class};
                      Object[] args = {name};
                      ctor = cls.getConstructor(parameterTypes);
                      p = (Permission) ctor.newInstance(args);
                  }
                  if( permissions == null )
                      permissions = new ArrayList();
                  if( p != null )
                      permissions.add(p);
              }
              catch(Exception e)
              {
                  throw new 
GeneralSecurityException(e.getClass().getName()+','+e.getMessage());
              }
          }
  
          Principal[] roles = new Principal[0];
          AuthorizationInfo authInfo = appPolicy.getPermissionInfo();
          if( authInfo == null )
          {
              authInfo = new AuthorizationInfo();
              appPolicy.setPermissionInfo(authInfo);
          }
  
          if( principals == null )
          {
              authInfo.grant(cs, permissions);
          }
          else
          {
              roles = (Principal[]) principals.toArray(roles);
              authInfo.grant(cs, permissions, roles);
          }
      }
  
      private String expandString(String str)
      {
          int index = str.indexOf("${/}");
          if( index >= 0 )
          {
              int start = 0;
              StringBuffer sb = new StringBuffer();
              while( index >= 0 )
              {
                  sb.append(str.substring(start, index));
                  sb.append(java.io.File.separatorChar);
                  start = index + 4;
                  index = str.indexOf("${/}", start);
              }
              if( start <= str.length()-1 )
                  sb.append(str.substring(start));
              str = sb.toString();
          }
          return str;
      }
  
      private Certificate[] getCertificates(String signedBy, KeyStore keyStore)
      {
          Certificate[] signedByCerts = null;
          StringTokenizer tokenizer = new StringTokenizer(signedBy, ",");
          ArrayList certs = new ArrayList();
          while( tokenizer.hasMoreTokens() )
          {
              String alias = tokenizer.nextToken();
              try
              {
                  Certificate cert = keyStore.getCertificate(alias);
                  certs.add(cert);
              }
              catch(GeneralSecurityException e)
              {
                  e.printStackTrace();
              }
          }
          if( certs.size() > 0 )
          {
              signedByCerts = new Certificate[certs.size()];
              certs.toArray(signedByCerts);
          }
          return signedByCerts;
      }
  
        public static String getContent(Element element, String defaultContent)
      {
                NodeList children = element.getChildNodes();
          String content = defaultContent;
          if( children.getLength() > 0 )
          {
              content = "";
              for(int n = 0; n < children.getLength(); n ++)
              {
                  if( children.item(n).getNodeType() == Node.TEXT_NODE || 
                      children.item(n).getNodeType() == Node.CDATA_SECTION_NODE )
                     content += children.item(n).getNodeValue();
                  else
                     content += children.item(n).getFirstChild();   
              }
              return content;
          }
          return content;
        }
  
        /** Local entity resolver to handle the security-policy DTD public id.
        */
        private static class LocalResolver implements EntityResolver
        {
                private static final String SECURITY_POLICY_PUBLIC_ID = "-//JBoss//DTD 
JAAS SecurityPolicy//EN";
                private static final String SECURITY_POLICY_DTD_NAME = 
"security-policy.dtd";
  
                public InputSource resolveEntity(String publicId, String systemId)
                {
                        InputSource is = null;
                        if( publicId.equals(SECURITY_POLICY_PUBLIC_ID) )
                        {
                                try
                                {
                                        InputStream dtdStream = 
getClass().getResourceAsStream(SECURITY_POLICY_DTD_NAME);
                                        is = new InputSource(dtdStream);
                                }
                                catch(Exception ex )
                                {
                                }
                        }
                        return is;
                }
        }
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SecurityProxy.java
  
  Index: SecurityProxy.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.lang.reflect.Method;
  import javax.ejb.EJBContext;
  
  /** An interface describing the requirements for a SecurityInterceptor proxy.
  A SecurityProxy allows for the externalization of custom security checks 
  on a per-method basis for both the EJB home and remote interface methods.
  Custom security checks are those that cannot be described using the
  standard EJB deployment time declarative role based security.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
   * @stereotype plug-in point
  */
  public interface SecurityProxy
  {
      public void init(Class beanHome, Class beanRemote, Object securityMgr) throws 
InstantiationException;
      /** Called prior to any method invocation to set the current EJB context.
      */
      public void setEJBContext(EJBContext ctx);
      /** Called to allow the security proxy to perform any custom security
          checks required for the EJB home interface method.
      @param m, the EJB home interface method? Or is this the EJB bean impl method?
      */
      public void invokeHome(Method m, Object[] args) throws SecurityException;
      /** Called to allow the security proxy to perform any custom security
          checks required for the EJB remote interface method.
      @param m, the EJB remote interface method? Or is this the EJB bean impl method?
      @param bean, the EJB implementation class instance
      */
      public void invoke(Method m, Object[] args, Object bean) throws 
SecurityException;
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SecurityProxyFactory.java
  
  Index: SecurityProxyFactory.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  /** An interface for factories of SecurityProxy objects. It is used
  to create a SecurityProxy from a security delegate object that is
  not a SecurityProxy instance.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public interface SecurityProxyFactory
  {
      public SecurityProxy create(Object proxyDelegate);
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SimpleGroup.java
  
  Index: SimpleGroup.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.security;
  
  import java.security.Principal;
  import java.security.acl.Group;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.Enumeration;
  import java.util.Iterator;
  import java.util.HashMap;
  
  /** An implementation of Group that manages a collection of
  Principal objects based on their getName() values. This class
  is not thread safe.
  
  @author [EMAIL PROTECTED]
  */
  public class SimpleGroup extends SimplePrincipal implements Group
  {
      private HashMap members;
  
      public SimpleGroup(String groupName)
      {
          super(groupName);
          members = new HashMap(3);
      }
  
      /** Adds the specified member to the group.
       @param user the principal to add to this group.
       @return true if the member was successfully added,
           false if the principal was already a member.
       */
      public boolean addMember(Principal user)
      {
          String key = user.getName();
          boolean isMember = members.containsKey(key);
          if( isMember == false )
              members.put(key, user);
          return isMember == false;
      }
      /** Returns true if the passed principal is a member of the group.
          This method does a recursive search, so if a principal belongs to a
          group which is a member of this group, true is returned.
  
      @param member the principal whose membership is to be checked.
      @return true if the principal is a member of this group,
          false otherwise.
      */
      public boolean isMember(Principal member)
      {
          // First see if there is a key with the member name
          String key = member.getName();
          boolean isMember = members.containsKey(key);
          if( isMember == false )
          {   // Check any Groups for membership
              Collection values = members.values();
              Iterator iter = values.iterator();
              while( isMember == false && iter.hasNext() )
              {
                  Object next = iter.next();
                  if( next instanceof Group )
                  {
                      Group group = (Group) next;
                      isMember = group.isMember(member);
                  }
              }
          }
          return isMember;
      }
  
      /** Returns an enumeration of the members in the group.
          The returned objects can be instances of either Principal
          or Group (which is a subinterface of Principal).
      @return an enumeration of the group members.
      */
      public Enumeration members()
      {
          return Collections.enumeration(members.values());
      }
  
      /** Removes the specified member from the group.
      @param user the principal to remove from this group.
      @return true if the principal was removed, or
          false if the principal was not a member.
      */
      public boolean removeMember(Principal user)
      {
          String key = user.getName();
          Object prev = members.remove(key);
          return prev != null;
      }
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SimplePrincipal.java
  
  Index: SimplePrincipal.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  
  package org.jboss.security;
  
  import java.security.Principal;
  
  /** A simple String based implementation of Principal. Typically
  a SimplePrincipal is created given a userID which is used
  as the Principal name.
  
  @author <a href="[EMAIL PROTECTED]">Oleg Nitz</a>
  @author [EMAIL PROTECTED]
  */
  public class SimplePrincipal implements Principal, java.io.Serializable
  {
    private String name;
  
    public SimplePrincipal(String name)
    {
      this.name = name;
    }
  
    /** Compare this SimplePrincipal's name against another SimplePrincipal
        name or null if this.getName() is null.
    @return true if name == another == null || name equals
        another.toString();
     */
    public boolean equals(Object another)
    {
      if (name == null)
        return (another == null);  
      if ((another == null) || !(another instanceof SimplePrincipal))
        return false;
      return name.equals( another.toString() );
    }
  
    public int hashCode()
    {
      return (name == null ? 0 : name.hashCode());
    }
  
    public String toString()
    {
      return name;
    }
  
    public String getName()
    {
      return name;
    }
  } 
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SubjectSecurityManager.java
  
  Index: SubjectSecurityManager.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
   
  package org.jboss.security;
  
  import javax.security.auth.Subject;
  
  
  /** An extension of the EJBSecurityManager that adds the notion of the active
  Subject and security domain.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public interface SubjectSecurityManager extends EJBSecurityManager
  {
      /** Get the security domain from which the security manager is from. Every
          security manager belongs to a named domain. The meaning of the security
          domain name depends on the implementation. Examples range from as fine
          grained as the name of EJBs to J2EE application names to DNS domain names.
      @return the security domain name. May be null in which case the security
          manager belongs to the logical default domain.
      */
      public String getSecurityDomain();
      /** Get the currently authenticated subject. After a successful isValid()
          call, a SubjectSecurityManager has a Subject associated with the current
          thread. This Subject will typically contain the Principal passed to isValid
          as well as any number of additional Principals, and credentials.
      @see EJBSecurityManager#isValid(Principal, Object)
      @return The previously authenticated Subject if isValid succeeded, null if
          isValid failed or has not been called for the active thread.
      */
      public Subject getActiveSubject();
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/SubjectSecurityProxy.java
  
  Index: SubjectSecurityProxy.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.lang.reflect.InvocationTargetException;
  import java.lang.reflect.UndeclaredThrowableException;
  import java.lang.reflect.Method;
  import java.security.PrivilegedExceptionAction;
  import java.security.PrivilegedActionException;
  import javax.ejb.EJBContext;
  import javax.security.auth.Subject;
  
  import org.jboss.ejb.MethodInvocation;
  
  import org.jboss.security.SecurityPolicy;
  import org.jboss.security.SubjectSecurityManager;
  
  /** A subclass of AbstractSecurityProxy that executes as the currently
  authenticated subject within the invokeHomeOnDelegate and invokeOnDelegate
  methods. The current subject is accessed via the security manager passed
  to the init() method, which must be an instance of SubjectSecurityManager.
  This results in AccessController.checkPermission() calls made from within the
  security delegate methods to be based on the Subject's permissions.
  
  @see javax.security.auth.Policy
  @see javax.security.auth.Subject
  @see org.jboss.security.SecurityPolicy
  @see org.jboss.security.SubjectSecurityManager
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public class SubjectSecurityProxy extends AbstractSecurityProxy
  {
      private SubjectSecurityManager subjectSecurityManager;
  
      SubjectSecurityProxy(Object delegate)
      {
          super(delegate);
      }
  
      public void init(Class beanHome, Class beanRemote, Object securityMgr) throws 
InstantiationException
      {
          if( (securityMgr instanceof SubjectSecurityManager) == false )
              throw new InstantiationException("SubjectSecurityProxy requires a 
SubjectSecurityManager instance, securityMgr="+securityMgr);
          subjectSecurityManager = (SubjectSecurityManager) securityMgr;
          super.init(beanHome, beanRemote, securityMgr);
      }
      protected void invokeHomeOnDelegate(final Method m, final Object[] args, final 
Object delegate) throws SecurityException
      {   // Get authenticated subject and invoke invokeAsSubject in 
Subject.doAsPrivaledged() block...
          final Subject subject = subjectSecurityManager.getActiveSubject();
          if( subject == null )
              throw new SecurityException("No subject associated with secure proxy");
  
          try
          {
              String domainName = subjectSecurityManager.getSecurityDomain();
              SecurityPolicy.setActiveApp(domainName);
              Subject.doAsPrivileged(subject, new PrivilegedExceptionAction()
                  {
                      public Object run() throws Exception
                      {
                          m.invoke(delegate, args);
                          return null;
                      }
                  },
                  null
              );
          }
          catch(PrivilegedActionException e)
          {
              Throwable t = e.getException();
              if( t instanceof InvocationTargetException )
              {
                  t = ((InvocationTargetException) t).getTargetException();
              }
              else if( t instanceof UndeclaredThrowableException )
              {
                  t = ((UndeclaredThrowableException) t).getUndeclaredThrowable();
              }
              if( t instanceof SecurityException )
                  throw (SecurityException) t;
              t.printStackTrace();
              throw new SecurityException("Unexpected error during security proxy 
execution:"+t.getMessage());
          }
      }
  
      protected void invokeOnDelegate(final Method m, final Object[] args, final 
Object delegate) throws SecurityException
      {   // Get authenticated subject and invoke invokeAsSubject in 
Subject.doAsPrivaledged() block...
          final Subject subject = subjectSecurityManager.getActiveSubject();
          if( subject == null )
              throw new SecurityException("No subject associated with secure proxy");
  
          try
          {
              String domainName = subjectSecurityManager.getSecurityDomain();
              SecurityPolicy.setActiveApp(domainName);
              Subject.doAsPrivileged(subject, new PrivilegedExceptionAction()
                  {
                      public Object run() throws Exception
                      {
                          m.invoke(delegate, args);
                          return null;
                      }
                  },
                  null
              );
          }
          catch(PrivilegedActionException e)
          {
              Throwable t = e.getException();
              if( t instanceof InvocationTargetException )
              {
                  t = ((InvocationTargetException) t).getTargetException();
              }
              else if( t instanceof UndeclaredThrowableException )
              {
                  t = ((UndeclaredThrowableException) t).getUndeclaredThrowable();
              }
              if( t instanceof SecurityException )
                  throw (SecurityException) t;
              t.printStackTrace();
              throw new SecurityException("Unexpected error during security proxy 
execution:"+t.getMessage());
          }
      }
  
  }
  
  
  
  1.1                  
jbosssx/src/main/org/jboss/security/SubjectSecurityProxyFactory.java
  
  Index: SubjectSecurityProxyFactory.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.io.Serializable;
  
  /** An implementation of SecurityProxyFactory that creates SubjectSecurityProxy
  objects to wrap the raw security proxy objects.
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public class SubjectSecurityProxyFactory implements SecurityProxyFactory, 
Serializable
  {
      public SecurityProxy create(Object proxyDelegate)
      {
          SecurityProxy proxy = new SubjectSecurityProxy(proxyDelegate);
          return proxy;
      }
  
  }
  
  
  
  1.1                  jbosssx/src/main/org/jboss/security/Util.java
  
  Index: Util.java
  ===================================================================
  /*
   * JBoss, the OpenSource EJB server
   *
   * Distributable under LGPL license.
   * See terms of license at gnu.org.
   */
  package org.jboss.security;
  
  import java.io.UnsupportedEncodingException;
  import java.math.BigInteger;
  import java.security.MessageDigest;
  import java.security.NoSuchAlgorithmException;
  import java.security.SecureRandom;
  import java.util.Random;
  
  /** Various security related utilities like MessageDigest
  factories, SecureRandom access, 
  
  This product includes software developed by Tom Wu and Eugene
  Jhong for the SRP Distribution (http://srp.stanford.edu/srp/).
  
  @author [EMAIL PROTECTED]
  @version $Revision: 1.1 $
  */
  public class Util
  {
      private static final int HASH_LEN = 20;
      private static final char[] base64Table =
      "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./".toCharArray();
      private static SecureRandom psuedoRng;
      private static MessageDigest sha1Digest;
      private static boolean initialized;
  
      public static void init() throws NoSuchAlgorithmException
      {
          if( initialized )
              return;
          init(null);
      }
      public static void init(byte[] prngSeed) throws NoSuchAlgorithmException
      {
          // Get an instance of the SHA-1 digest
          sha1Digest = MessageDigest.getInstance("SHA");
          // Get a cryptographically strong pseudo-random generator
          psuedoRng = SecureRandom.getInstance("SHA1PRNG");
          if( prngSeed != null )
              psuedoRng.setSeed(prngSeed);
          initialized = true;
      }
  
      public static MessageDigest newDigest()
      {
          MessageDigest md = null;
          try
          {
              md = (MessageDigest) sha1Digest.clone();
          }
          catch(CloneNotSupportedException e)
          {
          }
          return md;
      }
      public static MessageDigest copy(MessageDigest md)
      {
          MessageDigest copy = null;
          try
          {
              copy = (MessageDigest) md.clone();
          }
          catch(CloneNotSupportedException e)
          {
          }
          return copy;
      }
  
      public static Random getPRNG()
      {
          return psuedoRng;
      }
      /** Returns the next pseudorandom, uniformly distributed double value
          between 0.0 and 1.0 from this random number generator's sequence. 
      */
      public static double nextDouble()
      {
          return psuedoRng.nextDouble();
      }
      /** Returns the next pseudorandom, uniformly distributed long value from
          this random number generator's sequence. The general contract of
          nextLong is that one long value is pseudorandomly generated and
          returned. All 264 possible long values are produced with
          (approximately) equal probability.
       */
      public static long nextLong()
      {
          return psuedoRng.nextLong();
      }
      /** Generates random bytes and places them into a user-supplied byte
          array. The number of random bytes produced is equal to the length
          of the byte array.
       */
      public static void nextBytes(byte[] bytes)
      {
          psuedoRng.nextBytes(bytes);
      }
      /** Returns the given number of seed bytes, computed using the seed
          generation algorithm that this class uses to seed itself. This call
          may be used to seed other random number generators.
      */
      public static byte[] generateSeed(int numBytes)
      {
          return psuedoRng.generateSeed(numBytes);
      }
  
      public static byte[] calculatePasswordHash(String username, String password,
          byte[] salt, BigInteger N, BigInteger g)
      {
          // Calculate x = H(s | H(U | ':' | password))
          MessageDigest xd = newDigest();
          // Try to convert the username, password to a byte[] using UTF-8
          byte[] user = null;
          byte[] pass = null;
          try
          {
              user = username.getBytes("UTF-8");
              pass = password.getBytes("UTF-8");
          }
          catch(UnsupportedEncodingException e)
          {
              // Use the default platform encoding
              user = username.getBytes();
              pass = password.getBytes();
          }
          xd.update(user);
          xd.update(":".getBytes());
          xd.update(pass);
          byte[] h = xd.digest();
          xd.reset();
          xd.update(salt);
          xd.update(h);
          byte[] xb = xd.digest();
          // Calculate the password verfier v
          BigInteger x = new BigInteger(1, xb);
          return x.toByteArray();
      }
  
      /** Calculate x = H(s | H(U | ':' | password)) verifier
          described in RFC2945.
       */
      public static byte[] calculateVerifier(String username, String password,
          byte[] salt, byte[] Nb, byte[] gb)
      {
          BigInteger g = new BigInteger(1, gb);
          BigInteger N = new BigInteger(1, Nb);
          return calculateVerifier(username, password, salt, N, g);
      }
      /**
      */
      public static byte[] calculateVerifier(String username, String password,
          byte[] salt, BigInteger N, BigInteger g)
      {
          byte[] xb = calculatePasswordHash(username, password, salt, N, g);
          BigInteger x = new BigInteger(1, xb);
          BigInteger v = g.modPow(x, N);
          return v.toByteArray();
      }
  
      /** Perform an interleaved even-odd hash on the byte string
      */
      public static byte[] sessionKeyHash(byte[] number)
      {
          int i, offset;
  
          for(offset = 0; offset < number.length && number[offset] == 0; ++offset)
            ;
  
          byte[] key = new byte[2 * HASH_LEN];
          byte[] hout;
  
          int klen = (number.length - offset) / 2;
          byte[] hbuf = new byte[klen];
  
          for(i = 0; i < klen; ++i)
            hbuf[i] = number[number.length - 2 * i - 1];
          hout = newDigest().digest(hbuf);
          for(i = 0; i < HASH_LEN; ++i)
            key[2 * i] = hout[i];
  
          for(i = 0; i < klen; ++i)
            hbuf[i] = number[number.length - 2 * i - 2];
          hout = newDigest().digest(hbuf);
          for(i = 0; i < HASH_LEN; ++i)
            key[2 * i + 1] = hout[i];
  
          return key;
      }
  
      /** Treat the input as the MSB representation of a number,
          and lop off leading zero elements.  For efficiency, the
          input is simply returned if no leading zeroes are found.
      */ 
      public static byte[] trim(byte[] in)
      {
          if(in.length == 0 || in[0] != 0)
              return in;
  
          int len = in.length;
          int i = 1;
          while(in[i] == 0 && i < len)
            ++i;
          byte[] ret = new byte[len - i];
          System.arraycopy(in, i, ret, 0, len - i);
          return ret;
      }
  
      public static byte[] xor(byte[] b1, byte[] b2, int length)
      {
          byte[] result = new byte[length];
          for(int i = 0; i < length; ++i)
              result[i] = (byte) (b1[i] ^ b2[i]);
          return result;
      }
  
    // These functions assume that the byte array has MSB at 0, LSB at end.
    // Reverse the byte array (not the String) if this is not the case.
    // All base64 strings are in natural order, least significant digit last.
  
    public static String tob64(byte[] buffer) {
      boolean notleading = false;
      int len = buffer.length, pos = len % 3, c;
      byte b0 = 0, b1 = 0, b2 = 0;
      StringBuffer sb = new StringBuffer();
  
      switch(pos) {
      case 1:
        b2 = buffer[0];
        break;
      case 2:
        b1 = buffer[0];
        b2 = buffer[1];
        break;
      }
      do {
        c = (b0 & 0xfc) >>> 2;
        if(notleading || c != 0) {
        sb.append(base64Table[c]);
        notleading = true;
        }
        c = ((b0 & 3) << 4) | ((b1 & 0xf0) >>> 4);
        if(notleading || c != 0) {
        sb.append(base64Table[c]);
        notleading = true;
        }
        c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >>> 6);
        if(notleading || c != 0) {
        sb.append(base64Table[c]);
        notleading = true;
        }
        c = b2 & 0x3f;
        if(notleading || c != 0) {
        sb.append(base64Table[c]);
        notleading = true;
        }
        if(pos >= len)
        break;
        else
        try {
          b0 = buffer[pos++];
          b1 = buffer[pos++];
          b2 = buffer[pos++];
        } catch(ArrayIndexOutOfBoundsException e) { break; }
      } while(true);
  
      if(notleading)
        return sb.toString();
      else
        return "0";
    }
  
    public static byte[] fromb64(String str) throws NumberFormatException {
      int len = str.length();
      if(len == 0)
        throw new NumberFormatException("Empty Base64 string");
  
      byte[] a = new byte[len + 1];
      char c;
      int i, j;
  
      for(i = 0; i < len; ++i) {
        c = str.charAt(i);
        try {
        for(j = 0; c != base64Table[j]; ++j)
          ;
        } catch(Exception e) {
        throw new NumberFormatException("Illegal Base64 character");
        }
        a[i] = (byte) j;
      }
  
      i = len - 1;
      j = len;
      try {
        while(true) {
        a[j] = a[i];
        if(--i < 0)
          break;
        a[j] |= (a[i] & 3) << 6;
        --j;
        a[j] = (byte) ((a[i] & 0x3c) >>> 2);
        if(--i < 0)
          break;
        a[j] |= (a[i] & 0xf) << 4;
        --j;
        a[j] = (byte) ((a[i] & 0x30) >>> 4);
        if(--i < 0)
          break;
        a[j] |= (a[i] << 2);
  
        // Nasty, evil bug in Microsloth's Java interpreter under
        // Netscape:  The following three lines of code are supposed
        // to be equivalent, but under the Windows NT VM (Netscape3.0)
        // using either of the two commented statements would cause
        // the zero to be placed in a[j] *before* decrementing j.
        // Weeeeird.
        a[j-1] = 0; --j;
        // a[--j] = 0;
        // --j; a[j] = 0;
  
        if(--i < 0)
          break;
        }
      } catch(Exception e) {}
  
      try {
        while(a[j] == 0)
        ++j;
      } catch(Exception e) {
        return new byte[1];
      }
      
      byte[] result = new byte[len - j + 1];
      System.arraycopy(a, j, result, 0, len - j + 1);
      return result;
    }
  
  }
  
  
  

Reply via email to