Example #1
0
  /**
   * Utility method which loads the given properties file and returns a Properties object containing
   * the key,value pairs in that file. The properties files should be in the class path as this
   * method looks to the thread context class loader (TCL) to locate the resource. If the TCL is a
   * URLClassLoader the findResource(String) method is first tried. If this fails or the TCL is not
   * a URLClassLoader getResource(String) is tried. If not, an absolute path is tried.
   *
   * @param propertiesName - the name of the properties file resource
   * @return the loaded properties file if found
   * @exception java.io.IOException thrown if the properties file cannot be found or loaded
   */
  static Properties loadProperties(String propertiesName) throws IOException {
    Properties bundle = null;
    ClassLoader loader = SecurityActions.getContextClassLoader();
    URL url = null;
    // First check for local visibility via a URLClassLoader.findResource
    if (loader instanceof URLClassLoader) {
      URLClassLoader ucl = (URLClassLoader) loader;
      url = SecurityActions.findResource(ucl, propertiesName);
      PicketBoxLogger.LOGGER.traceAttemptToLoadResource(propertiesName);
    }
    // Do a general resource search
    if (url == null) {
      url = loader.getResource(propertiesName);
      if (url == null) {
        try {
          url = new URL(propertiesName);
        } catch (MalformedURLException mue) {
          PicketBoxLogger.LOGGER.debugFailureToOpenPropertiesFromURL(mue);
          File tmp = new File(propertiesName);
          if (tmp.exists()) url = tmp.toURI().toURL();
        }
      }
    }
    if (url == null) {
      throw PicketBoxMessages.MESSAGES.unableToFindPropertiesFile(propertiesName);
    }

    Properties defaults = new Properties();
    bundle = new Properties(defaults);
    if (url != null) {
      InputStream is = null;
      try {
        is = SecurityActions.openStream(url);
      } catch (PrivilegedActionException e) {
        throw new IOException(e.getLocalizedMessage());
      }
      if (is != null) {
        try {
          bundle.load(is);
        } finally {
          safeClose(is);
        }
      } else {
        throw PicketBoxMessages.MESSAGES.unableToLoadPropertiesFile(propertiesName);
      }
      PicketBoxLogger.LOGGER.tracePropertiesFileLoaded(propertiesName, bundle.keySet());
    }

    return bundle;
  }
  private InitialLdapContext constructInitialLdapContext(String dn, Object credential)
      throws NamingException {
    Properties env = new Properties();
    for (Entry<String, String> entry : options.entrySet()) {
      env.put(entry.getKey(), entry.getValue());
    }

    // Set defaults for key values if they are missing
    String factoryName = env.getProperty(Context.INITIAL_CONTEXT_FACTORY);
    if (factoryName == null) {
      factoryName = "com.sun.jndi.ldap.LdapCtxFactory";
      env.setProperty(Context.INITIAL_CONTEXT_FACTORY, factoryName);
    }
    String authType = env.getProperty(Context.SECURITY_AUTHENTICATION);
    if (authType == null) env.setProperty(Context.SECURITY_AUTHENTICATION, "simple");
    String protocol = env.getProperty(Context.SECURITY_PROTOCOL);
    String providerURL = options.get(Context.PROVIDER_URL);
    if (providerURL == null)
      providerURL =
          "ldap://localhost:" + ((protocol != null && protocol.equals("ssl")) ? "636" : "389");

    env.setProperty(Context.PROVIDER_URL, providerURL);

    distinguishedNameAttribute = options.get(DISTINGUISHED_NAME_ATTRIBUTE_OPT);
    if (distinguishedNameAttribute == null) distinguishedNameAttribute = "distinguishedName";

    // JBAS-3555, allow anonymous login with no bindDN and bindCredential
    if (dn != null) env.setProperty(Context.SECURITY_PRINCIPAL, dn);
    if (credential != null) env.put(Context.SECURITY_CREDENTIALS, credential);
    PicketBoxLogger.LOGGER.traceLDAPConnectionEnv(env);
    return new InitialLdapContext(env, null);
  }
 protected String getBindDN() {
   String bindDN = options.get(BIND_DN);
   if (bindDN == null || bindDN.length() == 0) {
     PicketBoxLogger.LOGGER.traceBindDNNotFound();
   }
   return bindDN;
 }
Example #4
0
  /**
   * Create the set of roles the user belongs to by parsing the roles.properties data for
   * username=role1,role2,... and username.XXX=role1,role2,... patterns.
   *
   * @param targetUser - the username to obtain roles for
   * @param roles - the Properties containing the user=roles mappings
   * @param roleGroupSeperator - the character that seperates a username from a group name, e.g.,
   *     targetUser[.GroupName]=roles
   * @param aslm - the login module to use for Principal creation
   * @return Group[] containing the sets of roles
   */
  static Group[] getRoleSets(
      String targetUser,
      Properties roles,
      char roleGroupSeperator,
      AbstractServerLoginModule aslm) {
    Enumeration<?> users = roles.propertyNames();
    SimpleGroup rolesGroup = new SimpleGroup("Roles");
    ArrayList<Group> groups = new ArrayList<Group>();
    groups.add(rolesGroup);
    while (users.hasMoreElements() && targetUser != null) {
      String user = (String) users.nextElement();
      String value = roles.getProperty(user);

      // See if this entry is of the form targetUser[.GroupName]=roles
      // JBAS-3742 - skip potential '.' in targetUser
      int index = user.indexOf(roleGroupSeperator, targetUser.length());
      boolean isRoleGroup = false;
      boolean userMatch = false;
      if (index > 0 && targetUser.regionMatches(0, user, 0, index) == true) isRoleGroup = true;
      else userMatch = targetUser.equals(user);

      String groupName = "Roles";
      // Check for username.RoleGroup pattern
      if (isRoleGroup == true) {
        groupName = user.substring(index + 1);
        PicketBoxLogger.LOGGER.traceAdditionOfRoleToGroup(value, groupName);
        if (groupName.equals("Roles")) {
          parseGroupMembers(rolesGroup, value, aslm);
        } else {
          SimpleGroup group = new SimpleGroup(groupName);
          parseGroupMembers(group, value, aslm);
          groups.add(group);
        }
      } else if (userMatch == true) {
        PicketBoxLogger.LOGGER.traceAdditionOfRoleToGroup(value, groupName);
        // Place these roles into the Default "Roles" group
        parseGroupMembers(rolesGroup, value, aslm);
      }
    }
    Group[] roleSets = new Group[groups.size()];
    groups.toArray(roleSets);
    return roleSets;
  }
Example #5
0
 /**
  * Parse the comma delimited roles names given by value and add them to group. The type of
  * Principal created for each name is determined by the createIdentity method.
  *
  * @see AbstractServerLoginModule#createIdentity(String)
  * @param group - the Group to add the roles to.
  * @param roles - the comma delimited role names.
  */
 static void parseGroupMembers(Group group, String roles, AbstractServerLoginModule aslm) {
   StringTokenizer tokenizer = new StringTokenizer(roles, ",");
   while (tokenizer.hasMoreTokens()) {
     String token = tokenizer.nextToken();
     try {
       Principal p = aslm.createIdentity(token);
       group.addMember(p);
     } catch (Exception e) {
       PicketBoxLogger.LOGGER.debugFailureToCreatePrincipal(token, e);
     }
   }
 }
 protected String getBindCredential() {
   String bindCredential = options.get(BIND_CREDENTIAL);
   if (bindCredential.startsWith("{EXT}")) {
     try {
       bindCredential = new String(org.jboss.security.Util.loadPassword(bindCredential));
     } catch (Exception e1) {
       PicketBoxLogger.LOGGER.errorDecryptingBindCredential(e1);
     }
   }
   String securityDomain = options.get(SECURITY_DOMAIN_OPT);
   if (securityDomain != null) {
     try {
       ObjectName serviceName = new ObjectName(securityDomain);
       char[] tmp = DecodeAction.decode(bindCredential, serviceName);
       bindCredential = new String(tmp);
     } catch (Exception e) {
       PicketBoxLogger.LOGGER.errorDecryptingBindCredential(e);
     }
   }
   return bindCredential;
 }
Example #7
0
  /**
   * Calculate a password hash using a MessageDigest.
   *
   * @param hashAlgorithm - the MessageDigest algorithm name
   * @param hashEncoding - either base64 or hex to specify the type of encoding the MessageDigest as
   *     a string.
   * @param hashCharset - the charset used to create the byte[] passed to the MessageDigestfrom the
   *     password String. If null the platform default is used.
   * @param username - ignored in default version
   * @param password - the password string to be hashed
   * @param callback - the callback used to allow customization of the hash to occur. The preDigest
   *     method is called before the password is added and the postDigest method is called after the
   *     password has been added.
   * @return the hashed string if successful, null if there is a digest exception
   */
  public static String createPasswordHash(
      String hashAlgorithm,
      String hashEncoding,
      String hashCharset,
      String username,
      String password,
      DigestCallback callback) {
    byte[] passBytes;
    String passwordHash = null;

    // convert password to byte data
    try {
      if (hashCharset == null) passBytes = password.getBytes();
      else passBytes = password.getBytes(hashCharset);
    } catch (UnsupportedEncodingException uee) {
      PicketBoxLogger.LOGGER.errorFindingCharset(hashCharset, uee);
      passBytes = password.getBytes();
    }

    // calculate the hash and apply the encoding.
    try {
      MessageDigest md = MessageDigest.getInstance(hashAlgorithm);
      if (callback != null) callback.preDigest(md);
      md.update(passBytes);
      if (callback != null) callback.postDigest(md);
      byte[] hash = md.digest();
      if (hashEncoding.equalsIgnoreCase(BASE64_ENCODING)) {
        passwordHash = Util.encodeBase64(hash);
      } else if (hashEncoding.equalsIgnoreCase(BASE16_ENCODING)) {
        passwordHash = Util.encodeBase16(hash);
      } else if (hashEncoding.equalsIgnoreCase(RFC2617_ENCODING)) {
        passwordHash = Util.encodeRFC2617(hash);
      } else {
        PicketBoxLogger.LOGGER.unsupportedHashEncodingFormat(hashEncoding);
      }
    } catch (Exception e) {
      PicketBoxLogger.LOGGER.errorCalculatingPasswordHash(e);
    }
    return passwordHash;
  }
  /** @see IdentityTrustManager#isTrusted(org.jboss.security.SecurityContext) */
  public TrustDecision isTrusted(SecurityContext securityContext) {
    if (securityContext == null)
      throw PicketBoxMessages.MESSAGES.invalidNullArgument("securityContext");
    if (this.identityTrustContext == null)
      this.identityTrustContext = new JBossIdentityTrustContext(securityDomain, securityContext);
    TrustDecision td = TrustDecision.NotApplicable;
    if (this.identityTrustContext == null)
      throw PicketBoxMessages.MESSAGES.invalidNullProperty("identityTrustContext");

    try {
      td = this.identityTrustContext.isTrusted();
    } catch (IdentityTrustException e) {
      PicketBoxLogger.LOGGER.debugIgnoredException(e);
    }
    return td;
  }
  /**
   * Handle a {@code Callback}
   *
   * @param c callback
   * @throws UnsupportedCallbackException If the callback is not supported by this handler
   * @throws NamingException
   */
  protected void handleCallBack(Callback c) throws UnsupportedCallbackException, NamingException {
    if (c instanceof VerifyPasswordCallback) {
      verifyPassword((VerifyPasswordCallback) c);
      return;
    }

    if (c instanceof PasswordCallback == false) return;

    PasswordCallback passwdCallback = (PasswordCallback) c;

    String bindDN = getBindDN();

    String bindCredential = getBindCredential();

    String tmp = options.get(PASSWORD_ATTRIBUTE_ID);
    if (tmp != null && tmp.length() > 0) {
      passwordAttributeID = tmp;
    }

    InitialLdapContext ctx;
    ClassLoader currentTCCL = SecurityActions.getContextClassLoader();
    try {
      if (currentTCCL != null) SecurityActions.setContextClassLoader(null);
      ctx = this.constructInitialLdapContext(bindDN, bindCredential);
    } catch (NamingException e) {
      throw new RuntimeException(e);
    }

    String timeLimit = (String) options.get(SEARCH_TIME_LIMIT_OPT);
    if (timeLimit != null) {
      try {
        searchTimeLimit = Integer.parseInt(timeLimit);
      } catch (NumberFormatException e) {
      }
    }
    if (searchTimeLimit == 0) searchTimeLimit = 10000;

    String baseDN = options.get(BASE_CTX_DN);
    String baseFilter = options.get(BASE_FILTER_OPT);

    SearchControls constraints = new SearchControls();
    constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

    constraints.setTimeLimit(searchTimeLimit);

    NamingEnumeration<SearchResult> results = null;

    Object[] filterArgs = {userName};
    try {
      if (baseDN == null) throw PicketBoxMessages.MESSAGES.invalidNullBaseContextDN();
      results = ctx.search(baseDN, baseFilter, filterArgs, constraints);
      if (results.hasMore() == false) {
        safeClose(results);
        throw PicketBoxMessages.MESSAGES.failedToFindBaseContextDN(baseDN);
      }
      SearchResult sr = results.next();
      String name = sr.getName();
      String userDN = null;
      if (sr.isRelative() == true) userDN = name + "," + baseDN;
      else throw PicketBoxMessages.MESSAGES.unableToFollowReferralForAuth(name);
      ;

      safeClose(results);

      // Finished Authentication.  Lets look for the attributes
      filterArgs = new Object[] {userName, userDN};
      results = ctx.search(userDN, baseFilter, filterArgs, constraints);
      try {
        while (results.hasMore()) {
          sr = results.next();
          Attributes attributes = sr.getAttributes();
          NamingEnumeration<? extends javax.naming.directory.Attribute> ne = attributes.getAll();

          while (ne != null && ne.hasMoreElements()) {
            javax.naming.directory.Attribute ldapAtt = ne.next();
            if (passwordAttributeID.equalsIgnoreCase(ldapAtt.getID())) {
              Object thePass = ldapAtt.get();
              setPasswordCallbackValue(thePass, passwdCallback);
            }
          }
        }
      } finally {
        safeClose(results);
        safeClose(ctx);
        if (currentTCCL != null) SecurityActions.setContextClassLoader(currentTCCL);
      }
    } catch (NamingException ne) {
      PicketBoxLogger.LOGGER.error(ne);
    }
  }