You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by cr...@hyperreal.org on 1999/10/24 00:30:22 UTC
cvs commit: jakarta-tomcat/src/share/org/apache/tomcat/security/file FileRealmTool.java Constants.java FileRealmConnector.java FileRealmDatabase.java FileRealmUser.java LocalStrings.properties tomcat-users.xml
craigmcc 99/10/23 15:30:22
Modified: src/share/org/apache/tomcat/security/file Constants.java
FileRealmConnector.java FileRealmDatabase.java
FileRealmUser.java LocalStrings.properties
tomcat-users.xml
Added: src/share/org/apache/tomcat/security/file FileRealmTool.java
Log:
Flesh out a usable implementation of RealmConnector that stores its
database information in an XML file.
org.apache.tomcat.security.file.FileRealmTool is a command line
application that can be used to manipulate the contexts of an XML
database, in preparation for use by Tomcat. For example, you might
add a new user, and put them in a specified group, like this:
java org.apache.tomcat.security.file.FileRealmTool \
mydatabase.xml \
-addUser hans mypassword \
-addMember committer hans \
-addMember pmc hans
See the JavaDoc comments on FileRealmTool for all the possible commands.
Revision Changes Path
1.2 +13 -4 jakarta-tomcat/src/share/org/apache/tomcat/security/file/Constants.java
Index: Constants.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/Constants.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Constants.java 1999/10/18 03:34:03 1.1
+++ Constants.java 1999/10/23 22:30:16 1.2
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/Constants.java,v 1.1 1999/10/18 03:34:03 craigmcc Exp $
- * $Revision: 1.1 $
- * $Date: 1999/10/18 03:34:03 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/Constants.java,v 1.2 1999/10/23 22:30:16 craigmcc Exp $
+ * $Revision: 1.2 $
+ * $Date: 1999/10/23 22:30:16 $
*
* ====================================================================
*
@@ -78,7 +78,7 @@
/**
* The name of this Java package.
*/
- public static final String Package = "org.apache.tomcat.file.security";
+ public static final String Package = "org.apache.tomcat.security.file";
/**
@@ -101,6 +101,15 @@
public static class Attribute {
public static final String NAME = "name";
public static final String PASSWORD = "password";
+ }
+
+
+ /**
+ * Initialization parameters from the associated ServletContext.
+ */
+ public static class Parameter {
+ public static final String DATABASE =
+ Constants.Package + ".database";
}
1.2 +76 -18 jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmConnector.java
Index: FileRealmConnector.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmConnector.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FileRealmConnector.java 1999/10/18 03:34:04 1.1
+++ FileRealmConnector.java 1999/10/23 22:30:17 1.2
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmConnector.java,v 1.1 1999/10/18 03:34:04 craigmcc Exp $
- * $Revision: 1.1 $
- * $Date: 1999/10/18 03:34:04 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmConnector.java,v 1.2 1999/10/23 22:30:17 craigmcc Exp $
+ * $Revision: 1.2 $
+ * $Date: 1999/10/23 22:30:17 $
*
* ====================================================================
*
@@ -64,12 +64,18 @@
package org.apache.tomcat.security.file;
-
+import java.io.BufferedInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.io.IOException;
import java.security.Principal;
import java.util.Enumeration;
import org.apache.tomcat.core.Context;
import org.apache.tomcat.security.RealmConnector;
-
+import org.apache.tomcat.util.StringManager;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
/**
* Implementation of <code>RealmConnector</code> that uses a
@@ -77,7 +83,7 @@
* XML-stored database of users and their associated roles.
*
* @author Craig R. McClanahan
- * @version $Revision: 1.1 $ $Date: 1999/10/18 03:34:04 $
+ * @version $Revision: 1.2 $ $Date: 1999/10/23 22:30:17 $
*/
public final class FileRealmConnector
@@ -97,6 +103,13 @@
/**
+ * The internationalized string constants for this package.
+ */
+ private StringManager sm =
+ StringManager.getManager(Constants.Package);
+
+
+ /**
* No-arguments constructor so that an instance of this class can be
* instantiated dynamically.
*/
@@ -118,11 +131,9 @@
*/
public Principal authenticate(String username, String credentials) {
- if (context == null) {
- // XXX Internationalization
- throw new IllegalStateException("FileRealmConnector: " +
- "Not started");
- }
+ if (context == null)
+ throw new IllegalStateException(
+ sm.getString("file.authenticate.notstarted"));
FileRealmUser user = database.getUser(username);
if (user == null)
@@ -150,11 +161,9 @@
*/
public boolean hasRole(Principal principal, String role) {
- if (context == null) {
- // XXX Internationalization
- throw new IllegalStateException("FileRealmConnector: " +
- "Not started");
- }
+ if (context == null)
+ throw new IllegalStateException(
+ sm.getString("file.hasRole.notstarted"));
FileRealmUser user = database.getUser(principal.getName());
if (user == null)
@@ -178,13 +187,62 @@
*
* @param context The Context with which this RealmConnector is associated
*
- * XXX Should we support some formal exception to report initialization
- * problems?
+ * @exception IllegalArgumentException if the underlying database
+ * file cannot be successfully loaded
*/
public void start(Context context) {
+ // Open an input stream to the specified database file
+ String filename =
+ context.getInitParameter(Constants.Parameter.DATABASE);
+ if (filename == null)
+ throw new IllegalArgumentException(
+ sm.getString("file.start.missing",
+ Constants.Parameter.DATABASE));
+ InputStream stream = null;
+ try {
+ stream = new BufferedInputStream(new FileInputStream(filename));
+ } catch (FileNotFoundException e) {
+ throw new IllegalArgumentException(
+ sm.getString("file.start.open", filename));
+ }
+
+ // Configure a local database object based on this file
+ try {
+ this.database = new FileRealmDatabase(stream);
+ } catch (IOException e) {
+ try {
+ stream.close();
+ } catch (IOException f) {
+ ;
+ }
+ throw new IllegalArgumentException(
+ sm.getString("file.start.read", filename) + ": " + e);
+ } catch (SAXParseException e) {
+ try {
+ stream.close();
+ } catch (IOException f) {
+ ;
+ }
+ throw new IllegalArgumentException(
+ sm.getString("file.start.parse", filename) + ": " + e);
+ } catch (SAXException e) {
+ try {
+ stream.close();
+ } catch (IOException f) {
+ ;
+ }
+ throw new IllegalArgumentException(
+ sm.getString("file.start.process", filename) + ": " + e);
+ }
+ try {
+ stream.close();
+ } catch (IOException e) {
+ ;
+ }
+
+ // Store a local reference to our associated context
this.context = context;
- // XXX create and initialize the database object
}
1.3 +66 -9 jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmDatabase.java
Index: FileRealmDatabase.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmDatabase.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- FileRealmDatabase.java 1999/10/22 08:14:16 1.2
+++ FileRealmDatabase.java 1999/10/23 22:30:17 1.3
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmDatabase.java,v 1.2 1999/10/22 08:14:16 craigmcc Exp $
- * $Revision: 1.2 $
- * $Date: 1999/10/22 08:14:16 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmDatabase.java,v 1.3 1999/10/23 22:30:17 craigmcc Exp $
+ * $Revision: 1.3 $
+ * $Date: 1999/10/23 22:30:17 $
*
* ====================================================================
*
@@ -64,6 +64,7 @@
package org.apache.tomcat.security.file;
+import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
@@ -83,7 +84,7 @@
* <code>tomcat-users.dtd</code> file in this directory.
*
* @author Craig R. McClanahan
- * @version $Revision: 1.2 $ $Date: 1999/10/22 08:14:16 $
+ * @version $Revision: 1.3 $ $Date: 1999/10/23 22:30:17 $
*/
public final class FileRealmDatabase {
@@ -173,6 +174,41 @@
}
+ /** [Private] Convert the specified byte array representation of an
+ * encrypted password into the corresponding hexadecimal digit
+ * representation.
+ *
+ * @param bytes Byte array representation
+ */
+ private String convert(byte bytes[]) {
+
+ StringBuffer sb = new StringBuffer(bytes.length * 2);
+ for (int i = 0; i < bytes.length; i++) {
+ sb.append(convertDigit((int) (bytes[i] >> 4)));
+ sb.append(convertDigit((int) (bytes[i] & 0x0f)));
+ }
+ return (sb.toString());
+
+ }
+
+
+ /**
+ * [Private] Convert the specified value (0 .. 15) to the corresponding
+ * hexadecimal digit.
+ *
+ * @param value Value to be converted
+ */
+ private char convertDigit(int value) {
+
+ value &= 0x0f;
+ if (value >= 10)
+ return ((char) (value - 10 + 'a'));
+ else
+ return ((char) (value + '0'));
+
+ }
+
+
/**
* [Private] Convert the hexadecimal digit representation of an encrypted
* password into the corresponding byte array representation.
@@ -181,8 +217,28 @@
*/
private byte[] convert(String digits) {
- // XXX Any good hex->byte converters lying around?
- return (new byte[0]);
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ for (int i = 0; i < digits.length(); i += 2) {
+ char c1 = digits.charAt(i);
+ char c2 = '0';
+ if (i+1 < digits.length())
+ c2 = digits.charAt(i+1);
+ byte b = 0;
+ if ((c1 >= '0') && (c1 <= '9'))
+ b += ((c1 - '0') * 16);
+ else if ((c1 >= 'a') && (c1 <= 'f'))
+ b += ((c1 - 'a' + 10) * 16);
+ else if ((c1 >= 'A') && (c1 <= 'F'))
+ b += ((c1 - 'A' + 10) * 16);
+ if ((c2 >= '0') && (c2 <= '9'))
+ b += (c2 - '0');
+ else if ((c2 >= 'a') && (c2 <= 'f'))
+ b += (c2 - 'a' + 10);
+ else if ((c2 >= 'A') && (c2 <= 'F'))
+ b += (c2 - 'A' + 10);
+ baos.write(b);
+ }
+ return (baos.toByteArray());
}
@@ -505,14 +561,15 @@
while (users.hasMoreElements()) {
FileRealmUser user = (FileRealmUser) users.nextElement();
writer.println(" <user name=\"" + user.getName() +
- "\" password=\"" + user.getPassword() + "\" />");
+ "\" password=\"" + convert(user.getPassword()) +
+ "\" />");
}
// Render group elements for all defined groups
Enumeration groups = getGroups();
while (groups.hasMoreElements()) {
FileRealmGroup group = (FileRealmGroup) groups.nextElement();
- writer.println(" <group name=\"" + group.getName() + "\" />");
+ writer.println(" <group name=\"" + group.getName() + "\">");
users = group.getUsers();
while (users.hasMoreElements()) {
FileRealmUser user = (FileRealmUser) users.nextElement();
@@ -526,7 +583,7 @@
Enumeration roles = getRoles();
while (roles.hasMoreElements()) {
String role = (String) roles.nextElement();
- writer.println(" <role name=\"" + role + "\" />");
+ writer.println(" <role name=\"" + role + "\">");
users = getUsers();
while (users.hasMoreElements()) {
FileRealmUser user = (FileRealmUser) users.nextElement();
1.2 +15 -3 jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmUser.java
Index: FileRealmUser.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmUser.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- FileRealmUser.java 1999/10/18 03:34:05 1.1
+++ FileRealmUser.java 1999/10/23 22:30:19 1.2
@@ -1,7 +1,7 @@
/*
- * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmUser.java,v 1.1 1999/10/18 03:34:05 craigmcc Exp $
- * $Revision: 1.1 $
- * $Date: 1999/10/18 03:34:05 $
+ * $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmUser.java,v 1.2 1999/10/23 22:30:19 craigmcc Exp $
+ * $Revision: 1.2 $
+ * $Date: 1999/10/23 22:30:19 $
*
* ====================================================================
*
@@ -87,7 +87,7 @@
* </ul>
*
* @author Craig R. McClanahan
- * @version $Revision: 1.1 $ $Date: 1999/10/18 03:34:05 $
+ * @version $Revision: 1.2 $ $Date: 1999/10/23 22:30:19 $
*/
final class FileRealmUser
@@ -283,6 +283,18 @@
public Enumeration getRoles() {
return (roles.keys());
+
+ }
+
+
+ /**
+ * Is this user a member of the specified group?
+ *
+ * @param group The group to be tested
+ */
+ public boolean hasGroup(FileRealmGroup group) {
+
+ return (groups.get(group.getName()) != null);
}
1.2 +26 -3 jakarta-tomcat/src/share/org/apache/tomcat/security/file/LocalStrings.properties
Index: LocalStrings.properties
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/LocalStrings.properties,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- LocalStrings.properties 1999/10/22 08:14:19 1.1
+++ LocalStrings.properties 1999/10/23 22:30:19 1.2
@@ -1,7 +1,30 @@
-# $Id: LocalStrings.properties,v 1.1 1999/10/22 08:14:19 craigmcc Exp $
+# $Id: LocalStrings.properties,v 1.2 1999/10/23 22:30:19 craigmcc Exp $
#
# Localized strings for package org.apache.tomcat.security.file
# This is the default locale and is en_US
-file.createGroup.exists=createGroup: Group $0 already exists
-file.createUser.exists=createUser: User $0 already exists
+file.authenticate.notstarted=authenticate: Connector not started
+file.createGroup.exists=createGroup: Group {0} already exists
+file.createUser.exists=createUser: User {0} already exists
+file.hasRole.notstarted=hasRole: Connector not started
+file.start.missing=start: Missing initialization parameter {0}
+file.start.open=start: Cannot open {0}
+file.start.parse=start: Cannot parse {0}
+file.start.process=start: Canont process {0}
+file.start.read=start: Cannot read {0}
+tool.close.open=close: Cannot open {0}
+tool.close.write=close: Cannot write {0}
+tool.missing.group=process: Missing group name
+tool.missing.password=process: Missing user password
+tool.missing.principal=process: Missing group or user name
+tool.missing.role=process: Missing role name
+tool.missing.user=process: Missing user name
+tool.open.missing=open: Missing database filename
+tool.open.open=open: Cannot open {0}
+tool.open.parse=open: Cannot parse {0}
+tool.open.process=open: Cannot process {0}
+tool.open.read=open: Cannot read {0}
+tool.process.command=process: Unknown command {0}
+tool.unknown.group=process: Unknown group {0}
+tool.missing.principal=process: Unknown group or user {0}
+tool.unknown.user=process: Unknown user {0}
1.2 +17 -20 jakarta-tomcat/src/share/org/apache/tomcat/security/file/tomcat-users.xml
Index: tomcat-users.xml
===================================================================
RCS file: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/tomcat-users.xml,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- tomcat-users.xml 1999/10/18 03:34:06 1.1
+++ tomcat-users.xml 1999/10/23 22:30:20 1.2
@@ -1,28 +1,25 @@
<tomcat-users>
-
- <user name="duncan" password="32ba13f902749387"/>
- <user name="craigmcc" password="234c199203df9448"/>
- <user name="costin" password="659a033904033938"/>
- <user name="brianb" password="a8c88c8a02192903"/>
-
- <group name="pmc">
- <user-member name="duncan"/>
- <user-member name="craigmcc"/>
- </group>
-
+ <user name="costin" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" />
+ <user name="craigmcc" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" />
+ <user name="brianb" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" />
+ <user name="duncan" password="5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8" />
<group name="committer">
- <user-member name="duncan"/>
- <user-member name="craigmcc"/>
- <user-member name="costin"/>
+ <user-member name="costin" />
+ <user-member name="craigmcc" />
+ <user-member name="duncan" />
+ </group>
+ <group name="pmc">
+ <user-member name="craigmcc" />
+ <user-member name="duncan" />
</group>
-
<role name="project-coordinator">
- <group-member name="pmc"/>
- <user-member name="brianb"/>
+ <user-member name="brianb" />
+ <group-member name="pmc" />
</role>
-
<role name="developer">
- <anyone/>
+ <user-member name="costin" />
+ <user-member name="craigmcc" />
+ <user-member name="brianb" />
+ <user-member name="duncan" />
</role>
-
</tomcat-users>
1.1 jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmTool.java
Index: FileRealmTool.java
===================================================================
/*
* $Header: /home/cvs/jakarta-tomcat/src/share/org/apache/tomcat/security/file/FileRealmTool.java,v 1.1 1999/10/23 22:30:18 craigmcc Exp $
* $Revision: 1.1 $
* $Date: 1999/10/23 22:30:18 $
*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 1999 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution, if
* any, must include the following acknowlegement:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowlegement may appear in the software itself,
* if and wherever such third-party acknowlegements normally appear.
*
* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
* Foundation" must not be used to endorse or promote products derived
* from this software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache"
* nor may "Apache" appear in their names without prior written
* permission of the Apache Group.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* [Additional notices, if required by prior licensing conditions]
*
*/
package org.apache.tomcat.security.file;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import org.apache.tomcat.util.StringManager;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* Command-line tool to manipulate database files containing FileRealmDatabase
* information. Usage:
* <pre>
* java org.apache.tomcat.security.file.FileRealmTool {path} {commands}
* </pre>
* where <code>{path}</code> is the pathname to a local file containing the
* database information, and <code>{commands}</code> is a series of zero or
* more commands (each of which including command parameters) from the
* following list:
* <ul>
* <li><b>-addGroup {group}</b> - Add a new group with the specified name
* <li><b>-addMember {group} {user}</b> - Make {user} a member of {group}
* <li><b>-addRole {group/user} {role}</b> - Add an explicit assignment of
* {role} to the specified {group} or {user}.
* <li><b>-addUser {user} {password}</b> - Add a new user with the specified
* username and (cleartext) password.
* <li><b>-dropGroup {group}</b> - Drop this group and all its associated
* memberships and roles
* <li><b>-dropMember {group} {user}</b> - Make {user} no longer a member
* of {group}
* <li><b>-dropRole {group/user} {role}</b> - Drop this explicitly assigned
* {role} from the specified {group} or {user}.
* <li><b>-dropUser {user}</b> - Drop this user and all its associated
* memberships and roles
* <li><b>-list</b> - List the users, groups, and roles in this database
* </ul>
* <p>
* To initialize a new database file for use by this tool, create a text file
* (whose name ends in ".xml") with the following contents:
* <pre>
* <tomcat-users>
* </tomcat-users>
* </pre>
*
* @author Craig R. McClanahan
* @version $Revision: 1.1 $ $Date: 1999/10/23 22:30:18 $
*/
public final class FileRealmTool {
/**
* The command line arguments we are processing
*/
private static String args[] = null;
/**
* The subscript of the next argument to be returned by getArg().
*/
private static int current = 0;
/**
* The database we are processing.
*/
private static FileRealmDatabase database = null;
/**
* The name of the database file we are processing.
*/
private static String filename = null;
/**
* Has the cached database information been modified?
*/
private static boolean modified = false;
/**
* The internationalized string constants for this package.
*/
private static StringManager sm =
StringManager.getManager(Constants.Package);
/**
* The application main program.
*/
public static void main(String arguments[]) {
args = arguments;
open();
process();
close();
}
/**
* Add a new group, if it is not already present.
*/
private static void addGroup() {
String name = getArg();
if (name.length() < 1) {
System.err.println(sm.getString("tool.missing.group"));
System.exit(2);
}
FileRealmGroup group = database.getGroup(name);
if (group != null)
return;
group = database.createGroup(name);
modified = true;
}
/**
* Add a new group membership, if not already present.
*/
private static void addMember() {
String groupName = getArg();
if (groupName.length() < 1) {
System.err.println(sm.getString("tool.missing.group"));
System.exit(2);
}
FileRealmGroup group = database.getGroup(groupName);
if (group == null) {
System.err.println(sm.getString("tool.unknown.group", groupName));
System.exit(2);
}
String userName = getArg();
if (userName.length() < 1) {
System.err.println(sm.getString("tool.missing.user"));
System.exit(2);
}
FileRealmUser user = database.getUser(userName);
if (user == null) {
System.err.println(sm.getString("tool.unknown.user", userName));
System.exit(2);
}
if (!user.hasGroup(group)) {
user.add(group);
modified = true;
}
}
/**
* Add a new assigned role to a group or user, if not already present.
*/
private static void addRole() {
String principalName = getArg();
if (principalName.length() < 1) {
System.err.println(sm.getString("tool.missing.principal"));
System.exit(2);
}
FileRealmGroup group = database.getGroup(principalName);
FileRealmUser user = database.getUser(principalName);
if ((group == null) && (user == null)) {
System.err.println(sm.getString("tool.unknown.principal",
principalName));
System.exit(2);
}
String role = getArg();
if (role.length() < 1) {
System.err.println(sm.getString("tool.missing.role"));
System.exit(2);
}
if (group != null) {
if (!group.hasRole(role)) {
group.add(role);
modified = true;
}
}
if (user != null) {
if (!user.hasRole(role)) {
user.add(role);
modified = true;
}
}
}
/**
* Add a new user, if it is not already present. If the user is already
* present, update the password to the specified value.
*/
private static void addUser() {
String name = getArg();
if (name.length() < 1) {
System.err.println(sm.getString("tool.missing.user"));
System.exit(2);
}
String password = getArg();
if (password.length() < 1) {
System.err.println(sm.getString("tool.missing.password"));
System.exit(2);
}
FileRealmUser user = database.getUser(name);
if (user != null)
user.setPassword(password);
else
user = database.createUser(name, password);
modified = true;
}
/**
* Close the database, flushing any changes first.
*/
private static void close() {
if (!modified)
return;
OutputStream stream = null;
try {
stream = new BufferedOutputStream(new FileOutputStream(filename));
} catch (IOException e) {
System.err.println(sm.getString("tool.close.open", filename) +
": " + e);
e.printStackTrace();
System.exit(1);
}
try {
database.write(stream);
} catch (IOException e) {
System.err.println(sm.getString("tool.close.write", filename) +
": " + e);
e.printStackTrace();
System.exit(1);
}
try {
stream.close();
} catch (IOException e) {
;
}
}
/** [Private] Convert the specified byte array representation of an
* encrypted password into the corresponding hexadecimal digit
* representation.
*
* @param bytes Byte array representation
*/
private static String convert(byte bytes[]) {
StringBuffer sb = new StringBuffer(bytes.length * 2);
for (int i = 0; i < bytes.length; i++) {
sb.append(convertDigit((int) (bytes[i] >> 4)));
sb.append(convertDigit((int) (bytes[i] & 0x0f)));
}
return (sb.toString());
}
/**
* [Private] Convert the specified value (0 .. 15) to the corresponding
* hexadecimal digit.
*
* @param value Value to be converted
*/
private static char convertDigit(int value) {
value &= 0x0f;
if (value >= 10)
return ((char) (value - 10 + 'a'));
else
return ((char) (value + '0'));
}
/**
* Drop an existing group, if it is already present.
*/
private static void dropGroup() {
String name = getArg();
if (name.length() < 1) {
System.err.println(sm.getString("tool.missing.group"));
System.exit(2);
}
FileRealmGroup group = database.getGroup(name);
if (group == null) {
System.err.println(sm.getString("tool.unknown.group"));
System.exit(2);
}
database.remove(group);
modified = true;
}
/**
* Drop an existing group membership.
*/
private static void dropMember() {
String groupName = getArg();
if (groupName.length() < 1) {
System.err.println(sm.getString("tool.missing.group"));
System.exit(2);
}
FileRealmGroup group = database.getGroup(groupName);
if (group == null) {
System.err.println(sm.getString("tool.unknown.group", groupName));
System.exit(2);
}
String userName = getArg();
if (userName.length() < 1) {
System.err.println(sm.getString("tool.missing.user"));
System.exit(2);
}
FileRealmUser user = database.getUser(userName);
if (user == null) {
System.err.println(sm.getString("tool.unknown.user", userName));
System.exit(2);
}
if (user.hasGroup(group)) {
user.remove(group);
modified = true;
}
}
/**
* Drop an existing assigned role for a group or user.
*/
private static void dropRole() {
String principalName = getArg();
if (principalName.length() < 1) {
System.err.println(sm.getString("tool.missing.principal"));
System.exit(2);
}
FileRealmGroup group = database.getGroup(principalName);
FileRealmUser user = database.getUser(principalName);
if ((group == null) && (user == null)) {
System.err.println(sm.getString("tool.unknown.principal",
principalName));
System.exit(2);
}
String role = getArg();
if (role.length() < 1) {
System.err.println(sm.getString("tool.missing.role"));
System.exit(2);
}
if (group != null) {
if (group.hasRole(role)) {
group.remove(role);
modified = true;
}
}
if (user != null) {
if (user.hasRole(role)) {
user.remove(role);
modified = true;
}
}
}
/**
* Drop an existing user, if it is already present.
*/
private static void dropUser() {
String name = getArg();
if (name.length() < 1) {
System.err.println(sm.getString("tool.missing.user"));
System.exit(2);
}
FileRealmUser user = database.getUser(name);
if (user == null) {
System.err.println(sm.getString("tool.unknown.user"));
System.exit(2);
}
database.remove(user);
modified = true;
}
/**
* Return the next command line argument, if there is one. Otherwise,
* return a zero-length string.
*/
private static String getArg() {
if (current >= args.length)
return ("");
else
return (args[current++]);
}
/**
* List the users and groups, and their associated roles, in this database.
*/
private static void list() {
Enumeration users = database.getUsers();
while (users.hasMoreElements()) {
FileRealmUser user = (FileRealmUser) users.nextElement();
System.out.print("User '" + user.getName() +
"', password='" + convert(user.getPassword()) +
"'");
Enumeration groups = user.getGroups();
while (groups.hasMoreElements()) {
FileRealmGroup group = (FileRealmGroup) groups.nextElement();
System.out.print(", group='" + group.getName() + "'");
}
Enumeration roles = user.getRoles();
while (roles.hasMoreElements()) {
String role = (String) roles.nextElement();
System.out.print(", role='" + role + "'");
}
System.out.println();
}
Enumeration groups = database.getGroups();
while (groups.hasMoreElements()) {
FileRealmGroup group = (FileRealmGroup) groups.nextElement();
System.out.print("Group '" + group.getName() + "'");
Enumeration roles = group.getRoles();
while (roles.hasMoreElements()) {
String role = (String) roles.nextElement();
System.out.print(", role='" + role + "'");
}
System.out.println();
}
System.out.println("===============================================");
}
/**
* Open the database file specified by the next command line argument.
*/
private static void open() {
filename = getArg();
if (filename.length() < 1) {
System.err.println(sm.getString("tool.open.missing"));
System.exit(1);
}
InputStream stream = null;
try {
stream = new BufferedInputStream(new FileInputStream(filename));
} catch (FileNotFoundException e) {
System.err.println(sm.getString("tool.open.open", filename) +
": " + e);
e.printStackTrace();
System.exit(1);
}
try {
database = new FileRealmDatabase(stream);
} catch (IOException e) {
System.err.println(sm.getString("tool.open.read", filename) +
": " + e);
e.printStackTrace();
System.exit(1);
} catch (SAXParseException e) {
System.err.println(sm.getString("tool.open.parse", filename) +
": " + e);
e.printStackTrace();
System.exit(1);
} catch (SAXException e) {
System.err.println(sm.getString("tool.open.process", filename) +
": " + e);
e.printStackTrace();
System.exit(1);
}
try {
stream.close();
} catch (IOException e) {
;
}
}
/**
* Process all valid command from the command line arguments.
*/
private static void process() {
while (true) {
String command = getArg();
if (command.length() < 1)
break;
else if (command.equals("-addGroup"))
addGroup();
else if (command.equals("-addMember"))
addMember();
else if (command.equals("-addRole"))
addRole();
else if (command.equals("-addUser"))
addUser();
else if (command.equals("-dropGroup"))
dropGroup();
else if (command.equals("-dropMember"))
dropMember();
else if (command.equals("-dropRole"))
dropRole();
else if (command.equals("-dropUser"))
dropUser();
else if (command.equals("-list"))
list();
else {
System.err.println(sm.getString("tool.process.command",
command));
modified = false;
System.exit(2);
}
}
}
}