InfoCenter Home >
5: Securing applications -- special topics >
5.2: Introduction to custom registries >
5.2.4: Custom-registry source code >
5.2.4.1: Source code for the FileRegistrySample application >
5.2.4.1.1: The FileRegistrySample.java file

5.2.4.1.1: The FileRegistrySample.java file

//
//  5639-D57 (C) COPYRIGHT International Business Machines Corp. 2001
//
//  All Rights Reserved *  Licensed Materials - Property of IBM
//

//----------------------------------------------------------------------
// This program may be used, executed, copied, modified and distributed
// without royalty for the purpose of developing, using, marketing, or
// distributing.
//----------------------------------------------------------------------
//

// This sample is for the Custom User Registry feature in WebSphere

//----------------------------------------------------------------------
// The main purpose of this sample is to demonstrate the use of the
// Custom Registry feature available in WebSphere Application Server. This sample is a very
// simple file based registry sample where the user and the group information
// is listed in files (users.props and groups.props). As such, simplicity and
// not  performance is the major factor. This sample should be
// used only to get familiarized with this feature. An actual implementation
// of a realistic registry should consider various factors like performance,
// scalability, and others.
//----------------------------------------------------------------------

import java.util.*;
import java.io.*;
import java.security.cert.X509Certificate;
import com.ibm.websphere.security.*;


public class FileRegistrySample implements CustomRegistry {

private static String USERFILENAME = null;
private static String GROUPFILENAME = null;

public FileRegistrySample() {}    // Default Constructor

/**
* Initializes the registry.
* @param props the registry-specific properties with which to
* initialize the registry object.
* @exception CustomRegistryException if there is a problem.
**/
public void initialize(java.util.Properties props)
throws CustomRegistryException {
try {
/* try getting the USERFILENAME and the GROUPFILENAME from
* properties that are passed in (that is,  from the GUI).
* These values should be set in the security center GUI in the
* Special Custom Settings in the Custom User Registry section of
* the Authentication panel.
* For example:
* usersFile   c:/temp/users.props
* groupsFile  c:/temp/groups.props
*/
if (props != null) {
USERFILENAME = props.getProperty("usersFile");
GROUPFILENAME = props.getProperty("groupsFile");
}

} catch(Exception ex) {
throw new CustomRegistryException(ex.getMessage());
}

if (USERFILENAME == null || GROUPFILENAME == null) {
throw new CustomRegistryException("users/groups information missing");
}

}
/**
* Checks the Password of the user.
* @param userId the user name data to authenticate.
* @param passwd the password of the user.
* @return the userId that will be used for authentication.
* @exception WrongPasswordException if passwd is not valid.
* @exception CustomRegistryException if there are any other problems.
**/
public String checkPassword(String userId, String passwd)
throws PasswordCheckFailedException,
CustomRegistryException {
String s,userName = null;
BufferedReader in = null;

try {
in = fileOpen(USERFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.indexOf(":",index+1);
// check if the userId:passwd combination exists
if ((s.substring(0,index)).equals(userId) &&
s.substring(index+1,index1).equals(passwd)) {
// Authentication successful, return the userId.
userName = userId;
break;
}
}
}
} catch(Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}


if (userName == null) {
throw new PasswordCheckFailedException(userId);
}

return userName;
}

/**
* Maps a Certificate (of X509 format) to a valid userId in the Registry.
* @param cert the certificate that needs to be mapped.
* @return the mapped name of the user (userId).
* @exception CertificateMapNotSupportedException if the particular
* certificate is not supported.
* @exception CertificateMapFailedException if the mapping of the
* certificate fails.
* @exception CustomRegistryException if there are any other problems.
**/
public String mapCertificate(X509Certificate cert)
throws CertificateMapNotSupportedException,
CertificateMapFailedException,
CustomRegistryException {
String name=null;
try {
// map the SubjectDN in the certificate to a userID.
name = cert.getSubjectDN().getName();
} catch(Exception ex) {
throw new CertificateMapNotSupportedException(ex.getMessage());
}

if(!isValidUser(name)) {
throw new CertificateMapFailedException(name);
}
return name;
}

/**
* Returns the realm of the registry.
* @return the realm. The realm is a registry-specific string indicating the
* realm or domain for which this registry applies.  For example, for
* OS400 or AIX,  this would be the host name of the system whose user registry
* this object represents.
* If null is returned by this method, realm defaults to the value of
* "customRealm".
* @exception CustomRegistryException if there are any other problems.
**/
public String getRealm()
throws CustomRegistryException {
String name = "customRealm";
return name;
}

/**
* Returns the names of all  users in the registry.
* @return a List of the names of all the users.
* @exception CustomRegistryException if there are any other problems.
**/
public List getUsers()
throws CustomRegistryException {
String s;
BufferedReader in = null;
List allUsers = new ArrayList();
try {
in = fileOpen(USERFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
allUsers.add(s.substring(0,index));
}
}
} catch (Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return allUsers;
}

/**
* Returns names of the users in the registry that match a pattern.
* @param pattern the pattern to match (for example, a* will match all
* userNames starting with a). At a minimum when a full name is used
* as the pattern, the full name should be returned  if it is a
* valid user.
* @return a List of the names of all  users that match the pattern.
* @exception CustomRegistryException if there are any other problems.
**/
public List getUsers(String pattern)
throws CustomRegistryException {
String s;
BufferedReader in = null;
List allUsers = new ArrayList();
try {
in = fileOpen(USERFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
String user = s.substring(0,index);
if (match(user,pattern))
allUsers.add(user);
}
}
} catch (Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return allUsers;
}

/**
* Returns the names of all the users in a group.
* @param groupName the name of the group.
* @return a List of all the names of the users in the group.
* @exception EntryNotFoundException if groupName does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public List getUsersForGroup(String groupName)
throws CustomRegistryException,
EntryNotFoundException {
String s;
BufferedReader in = null;
List usrsForGroup = new ArrayList();
try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
if ((s.substring(0,index)).equals(groupName))
{
StringTokenizer st = new StringTokenizer(s, ":");
for (int i=0; i<2; i++)
st.nextToken();
String subs = st.nextToken();
StringTokenizer st1 = new StringTokenizer(subs, ",");
while (st1.hasMoreTokens())
usrsForGroup.add(st1.nextToken());
}
}
}
} catch (Exception ex) {
if (!isValidGroup(groupName)) {
throw new EntryNotFoundException(groupName);
}
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return usrsForGroup;
}

/**
* Returns the display name for the user specified by userName.
* @param userName the name of the user.
* @return the display name for the user. The display name
* is a registry-specific string that represents a descriptive, not
* necessarily a unique, name for a user. If a display name does not exist,
* return null.
* @exception EntryNotFoundException if userName does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public String getUserDisplayName(String userName)
throws CustomRegistryException,
EntryNotFoundException {

String s,displayName = null;
BufferedReader in = null;

if(!isValidUser(userName)) {
EntryNotFoundException nsee = new EntryNotFoundException(userName);
throw nsee;
}

try {
in = fileOpen(USERFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.lastIndexOf(":");
if ((s.substring(0,index)).equals(userName)) {
displayName = s.substring(index1+1);
break;
}
}
}
} catch(Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return displayName;
}

/**
* Returns the UniqueId for a userName.
* @param userName the name of the user.
* @return the UniqueId of the user. The UniqueId for an user is
* the stringified form of some unique, registry-specific, data that
* serves to represent the user.  For example,  for the UNIX user registry, the
* UniqueId for a user can be the UID.
* @exception EntryNotFoundException if userName does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public String getUniqueUserId(String userName)
throws CustomRegistryException,
EntryNotFoundException {

String s,uniqueUsrId = null;
BufferedReader in = null;
try {
in = fileOpen(USERFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.indexOf(":", index+1);
if ((s.substring(0,index)).equals(userName)) {
int index2 = s.indexOf(":", index1+1);
uniqueUsrId = s.substring(index1+1,index2);
break;
}
}
}
} catch(Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

if (uniqueUsrId == null) {
EntryNotFoundException nsee = new EntryNotFoundException(userName);
throw nsee;
}

return uniqueUsrId;
}

/**
* Returns the UniqueIds for all the users that belong to a group.
* @param uniqueGroupId is the uniqueId of the group.
* @return a List of all the user Unique ids that are contained in the
* group whose Unique id matches the uniqueGroupId.
* The Unique id for an entry is the stringified form of some unique,
* registry-specific, data that serves to represent the entry.  For example, for the
* Unix user registry, the Unique id for a group could be the GID and the
* Unique Id for the user could be the UID.
* @exception EntryNotFoundException if uniqueGroupId does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public List getUniqueUserIds(String uniqueGroupId)
throws CustomRegistryException,
EntryNotFoundException {

String s = null;
List uniqueUserIds = new ArrayList();
BufferedReader in = null;
try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.indexOf(":", index+1);
if ((s.substring(index+1,index1)).equals(uniqueGroupId)) {
StringTokenizer st = new StringTokenizer(s, ":");
for (int i=0; i<2; i++)
st.nextToken();
String subs = st.nextToken();
StringTokenizer st1 = new StringTokenizer(subs, ",");
while (st1.hasMoreTokens())
uniqueUserIds.add(getUniqueUserId(st1.nextToken()));
break;
}
}
}
} catch(Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return uniqueUserIds;
}

/**
* Returns the name for a user given its uniqueId.
* @param uniqueUserId the UniqueId of the user.
* @return the name of the user.
* @exception EntryNotFoundException if the uniqueUserId does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public String getUserSecurityName(String uniqueUserId)
throws CustomRegistryException,
EntryNotFoundException {
String s,usrSecName = null;
BufferedReader in = null;
try {
in = fileOpen(USERFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.indexOf(":", index+1);
int index2 = s.indexOf(":", index1+1);
if ((s.substring(index1+1,index2)).equals(uniqueUserId)) {
usrSecName = s.substring(0,index);
break;
}
}
}
} catch (Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

if (usrSecName == null) {
EntryNotFoundException ex =
new EntryNotFoundException(uniqueUserId);
throw ex;
}

return usrSecName;

}

/**
* Determines if a user exists.
* @param userName is the name of the user.
* @return true if the user exists; false otherwise.
* @exception CustomRegistryException if there are any other problems.
**/
public boolean isValidUser(String userName)
throws CustomRegistryException {
String s;
boolean isValid = false;
BufferedReader in = null;
try {
in = fileOpen(USERFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
if ((s.substring(0,index)).equals(userName)) {
isValid=true;
break;
}
}
}
} catch (Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return isValid;
}

/**
* Returns names of all the groups in the registry.
* @return a List of the names of all the groups.
* @exception CustomRegistryException if there are any other problems.
**/
public List getGroups()
throws CustomRegistryException {
String s;
BufferedReader in = null;
List allGroups = new ArrayList();
try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
allGroups.add(s.substring(0,index));
}
}
} catch (Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return allGroups;
}

/**
* Returns names of the groups in the registry that match a pattern.
* @param pattern is the pattern to match. (For example, a*  matches all
* group names starting with a). At a minimum when a full name is used
* as the pattern, the full name should be returned  if it is a
* valid group.
* @return a List of the names of the groups.
* @exception CustomRegistryException if there are any other problems.
**/
public List getGroups(String pattern)
throws CustomRegistryException {
String s;
BufferedReader in = null;
List allGroups = new ArrayList();
try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
String group = s.substring(0,index);
if (match(group,pattern))
allGroups.add(group);
}
}
} catch (Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return allGroups;
}

/**
* Returns the names of the groups to which userName belongs.
* @param userName is the username of the user.
* @return a List of the names of all the groups to which the user belongs.
* @exception EntryNotFoundException if userName does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public List getGroupsForUser(String userName)
throws CustomRegistryException,
EntryNotFoundException {
String s;
List grpsForUser = new ArrayList();
BufferedReader in = null;
try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
StringTokenizer st = new StringTokenizer(s, ":");
for (int i=0; i<2; i++)
st.nextToken();
String subs = st.nextToken();
StringTokenizer st1 = new StringTokenizer(subs, ",");
while (st1.hasMoreTokens()) {
if((st1.nextToken()).equals(userName)) {
int index = s.indexOf(":");
grpsForUser.add(s.substring(0,index));
}
}
}
}
} catch (Exception ex) {
if (!isValidUser(userName)) {
throw new EntryNotFoundException(userName);
}
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return grpsForUser;
}

/**
* Returns the display name for a group.
* @param groupName is the name of the group.
* @return the display name for the group. The display name
* is a registry-specific string that represents a descriptive, not
* necessarily a unique, name for a group.
* @exception EntryNotFoundException if the groupName does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public String getGroupDisplayName(String groupName)
throws CustomRegistryException,
EntryNotFoundException {
String s,displayName = null;
BufferedReader in = null;

if(!isValidGroup(groupName)) {
EntryNotFoundException nsee = new EntryNotFoundException(groupName);
throw nsee;
}

try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.lastIndexOf(":");
if ((s.substring(0,index)).equals(groupName)) {
displayName = s.substring(index1+1);
break;
}
}
}
} catch(Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return displayName;
}

/**
* Returns the Unique id for a group.
* @param groupName is the name of the group.
* @return the Unique id of the group. The Unique id for
* a group is the stringified form of some unique, registry-specific,
* data that serves to represent the entry.  For exmaple, for the
* Unix user registry, the Unique id could be the GID for the entry.
* @exception EntryNotFoundException if groupName does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public String getUniqueGroupId(String groupName)
throws CustomRegistryException,
EntryNotFoundException {
String s,uniqueGrpId = null;
BufferedReader in = null;
try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.indexOf(":", index+1);
if ((s.substring(0,index)).equals(groupName)) {
uniqueGrpId = s.substring(index+1,index1);
break;
}
}
}
} catch(Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

if (uniqueGrpId == null) {
EntryNotFoundException nsee = new EntryNotFoundException(groupName);
throw nsee;
}

return uniqueGrpId;
}

/**
* Returns the Unique id for a group.
* @param groupName is the name of the group.
* @return the Unique id of the group. The Unique id for
* a group is the stringified form of some unique, registry-specific,
* data that serves to represent the entry. For example, for the
* Unix user registry, the Unique id could be the GID for the entry.
* @exception EntryNotFoundException if groupName does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public List getUniqueGroupIds(String uniqueUserId)
throws CustomRegistryException,
EntryNotFoundException {
String s,uniqueGrpId = null;
BufferedReader in = null;
List uniqueGrpIds=new ArrayList();
try {
in = fileOpen(USERFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.indexOf(":", index+1);
int index2 = s.indexOf(":", index1+1);
if ((s.substring(index1+1,index2)).equals(uniqueUserId)) {
int lastIndex = s.lastIndexOf(":");
String subs = s.substring(index2+1,lastIndex);
StringTokenizer st1 = new StringTokenizer(subs, ",");
while (st1.hasMoreTokens())
uniqueGrpIds.add(st1.nextToken());
break;
}
}
}
} catch(Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return uniqueGrpIds;
}

/**
* Returns the name for a group given its uniqueId.
* @param uniqueGroupId is the UniqueId of the group.
* @return the name of the group.
* @exception EntryNotFoundException if the uniqueGroupId does not exist.
* @exception CustomRegistryException if there are any other problems.
**/
public String getGroupSecurityName(String uniqueGroupId)
throws CustomRegistryException,
EntryNotFoundException {
String s,grpSecName = null;
BufferedReader in = null;
try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
int index1 = s.indexOf(":", index+1);
if ((s.substring(index+1,index1)).equals(uniqueGroupId)) {
grpSecName = s.substring(0,index);
break;
}
}
}
} catch (Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

if (grpSecName == null) {
EntryNotFoundException ex =
new EntryNotFoundException(uniqueGroupId);
throw ex;
}

return grpSecName;

}

/**
* Determines if a group exists.
* @param groupName is the name of the group.
* @return true if the group exists; false otherwise.
* @exception CustomRegistryException if there are any other problems.
**/
public boolean isValidGroup(String groupName)
throws CustomRegistryException {
String s;
boolean isValid = false;
BufferedReader in = null;
try {
in = fileOpen(GROUPFILENAME);
while ((s=in.readLine())!=null)
{
if (!s.startsWith("#")) {
int index = s.indexOf(":");
if ((s.substring(0,index)).equals(groupName)) {
isValid=true;
break;
}
}
}
} catch (Exception ex) {
throw new CustomRegistryException(ex.getMessage());
} finally {
fileClose(in);
}

return isValid;
}
// private methods
private BufferedReader fileOpen(String fileName)
throws FileNotFoundException {
try {
return new BufferedReader(new FileReader(fileName));
} catch(FileNotFoundException e) {
throw e;
}
}

private void fileClose(BufferedReader in) {
try {
if (in != null) in.close();
} catch(Exception e) {
System.out.println("Error closing file" + e);
}
}

private boolean match(String name, String pattern) {
RegExpSample regexp = new RegExpSample(pattern);
boolean matches = false;
if(regexp.match(name))
matches = true;
return matches;
}
}


//----------------------------------------------------------------------
// The program provides the Regular Expression implementation used in the
// Sample for the Custom User Registry (FileRegistrySample). The pattern
// matching in the sample uses this program to search for the pattern (for
// users and groups).
//----------------------------------------------------------------------

class RegExpSample
{

private boolean match(String s, int i, int j, int k)
{
for(; k < expr.length; k++)
label0:
{
Object obj = expr[k];
if(obj == STAR)
{
if(++k >= expr.length)
return true;
if(expr[k] instanceof String)
{
String s1 = (String)expr[k++];
int l = s1.length();
for(; (i = s.indexOf(s1, i)) >= 0; i++)
if(match(s, i + l, j, k))
return true;

return false;
}
for(; i < j; i++)
if(match(s, i, j, k))
return true;

return false;
}
if(obj == ANY)
{
if(++i > j)
return false;
break label0;
}
if(obj instanceof char[][])
{
if(i >= j)
return false;
char c = s.charAt(i++);
char ac[][] = (char[][])obj;
if(ac[0] == NOT)
{
for(int j1 = 1; j1 < ac.length; j1++)
if(ac[j1][0] <= c && c <= ac[j1][1])
return false;

break label0;
}
for(int k1 = 0; k1 < ac.length; k1++)
if(ac[k1][0] <= c && c <= ac[k1][1])
break label0;

return false;
}
if(obj instanceof String)
{
String s2 = (String)obj;
int i1 = s2.length();
if(!s.regionMatches(i, s2, 0, i1))
return false;
i += i1;
}
}

return i == j;
}

public boolean match(String s)
{
return match(s, 0, s.length(), 0);
}

public boolean match(String s, int i, int j)
{
return match(s, i, j, 0);
}

public RegExpSample(String s)
{
Vector vector = new Vector();
int i = s.length();
StringBuffer stringbuffer = null;
Object obj = null;
for(int j = 0; j < i; j++)
{
char c = s.charAt(j);
switch(c)
{
case 63: /* '?' */
obj = ANY;
break;

case 42: /* '*' */
obj = STAR;
break;

case 91: /* '[' */
int k = ++j;
Vector vector1 = new Vector();
for(; j < i; j++)
{
c = s.charAt(j);
if(j == k && c == '^')
{
vector1.addElement(NOT);
continue;
}
if(c == '\\')
{
if(j + 1 < i)
c = s.charAt(++j);
}
else
if(c == ']')
break;
char c1 = c;
if(j + 2 < i && s.charAt(j + 1) == '-')
c1 = s.charAt(j += 2);
char ac1[] = {
c, c1
};
vector1.addElement(ac1);
}

char ac[][] = new char[vector1.size()][];
vector1.copyInto(ac);
obj = ac;
break;

case 92: /* '\\' */
if(j + 1 < i)
c = s.charAt(++j);
break;

}
if(obj != null)
{
if(stringbuffer != null)
{
vector.addElement(stringbuffer.toString());
stringbuffer = null;
}
vector.addElement(obj);
obj = null;
}
else
{
if(stringbuffer == null)
stringbuffer = new StringBuffer();
stringbuffer.append(c);
}
}

if(stringbuffer != null)
vector.addElement(stringbuffer.toString());
expr = new Object[vector.size()];
vector.copyInto(expr);
}

static final char NOT[] = new char[2];
static final Integer ANY = new Integer(0);
static final Integer STAR = new Integer(1);
Object expr[];

}
Go to previous article: FileRegistrySample source code Go to next article: FlieRegistrySample properties

 

 
Go to previous article: FileRegistrySample source code Go to next article: FlieRegistrySample properties