You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by la...@apache.org on 2001/10/08 07:23:57 UTC
cvs commit: jakarta-tomcat/proposals/PasswordPrompter/WEB-INF/classes/org/apache/tomcat/util/io Prompter.java PrompterException.java
larryi 01/10/07 22:23:57
Added: proposals/PasswordPrompter build.xml
proposals/PasswordPrompter/WEB-INF interceptors.xml
proposals/PasswordPrompter/WEB-INF/classes/org/apache/tomcat/modules/config
PasswordPrompter.java
proposals/PasswordPrompter/WEB-INF/classes/org/apache/tomcat/util/io
Prompter.java PrompterException.java
Log:
Add sample add-on module. PasswordPrompter will prompt for pass words
for secure PoolTcpConnectors and JDBCRealms.
Revision Changes Path
1.1 jakarta-tomcat/proposals/PasswordPrompter/build.xml
Index: build.xml
===================================================================
<?xml version="1.0"?>
<project name="PasswordPrompter" default="main" basedir=".">
<!-- Compilation properties -->
<property name="build.compiler" value="classic"/>
<property name="optimize" value="false"/>
<property name="debug" value="on"/>
<!-- Directories -->
<property name="ws" value="../../.."/>
<property name="work.dir" value="${ws}/jakarta-tomcat"/>
<property name="tomcat.build" value="${ws}/jakarta-tomcat/build/tomcat"/>
<property name="tomcat.dist" value="${ws}/jakarta-tomcat/dist/tomcat"/>
<property name="tomcat.build.modules" value="${tomcat.build}/modules"/>
<property name="tomcat.dist.modules" value="${tomcat.dist}/modules"/>
<!-- ==================== Initialization - check if build and dist present ========== -->
<target name="init">
<available file="${tomcat.build.modules}" property="build.modules.available"/>
<available file="${tomcat.dist.modules}" property="dist.modules.available"/>
</target>
<!-- ==================== Preparation ==================== -->
<target name="prepare" depends="init">
</target>
<target name="build.modules.check" depends="prepare" unless="build.modules.available">
<echo message="You must build Tomcat first!"/>
</target>
<target name="dist.modules.check" depends="prepare" unless="dist.modules.available">
<echo message="You must build the Tomcat distribution first!"/>
</target>
<!-- ==================== Build the Password Prompter sample add-on ================== -->
<target name="password.prompter" depends="prepare" if="build.modules.available">
<mkdir dir="${tomcat.build.modules}/PasswordPrompter"/>
<copy todir="${tomcat.build.modules}/PasswordPrompter">
<fileset dir="${work.dir}/proposals/PasswordPrompter" excludes="build.xml"/>
</copy>
<javac srcdir="${tomcat.build.modules}/PasswordPrompter/WEB-INF/classes"
optimize="${optimize}"
debug="${debug}"
destdir="${tomcat.build.modules}/PasswordPrompter/WEB-INF/classes"
classpath="${tomcat.build}/classes"/>
<mkdir dir="${tomcat.build.modules}/PasswordPrompter/WEB-INF/lib"/>
<jar jarFile="${tomcat.build.modules}/PasswordPrompter/WEB-INF/lib/PasswordPrompter.jar"
basedir="${tomcat.build.modules}/PasswordPrompter/WEB-INF/classes"/>
<delete dir="${tomcat.build.modules}/PasswordPrompter/WEB-INF/classes"/>
</target>
<!-- ==================== Build the Password Prompter sample add-on WAR ================== -->
<target name="password.prompter.war"
depends="build.modules.check,dist.modules.check,password.prompter"
if="dist.modules.available">
<jar jarFile="${tomcat.dist.modules}/PasswordPrompter.war"
baseDir="${tomcat.build.modules}/PasswordPrompter"/>
</target>
<!-- ==================== Admin & agreagate ==================== -->
<target name="clean" depends="init">
<delete dir="${tomcat.build.modules}/PasswordPrompter"/>
<delete dir="${tomcat.dist.modules}/PasswordPrompter"/>
<delete file="${tomcat.dist.modules}/PasswordPrompter.war"/>
</target>
<target name="main" depends="build.modules.check,password.prompter"/>
</project>
1.1 jakarta-tomcat/proposals/PasswordPrompter/WEB-INF/interceptors.xml
Index: interceptors.xml
===================================================================
<?xml version="1.0" encoding="UTF-8"?>
<Server>
<module name="PasswordPrompter" javaClass="org.apache.tomcat.modules.config.PasswordPrompter" />
<ContextManager>
<PasswordPrompter />
</ContextManager>
</Server>
1.1 jakarta-tomcat/proposals/PasswordPrompter/WEB-INF/classes/org/apache/tomcat/modules/config/PasswordPrompter.java
Index: PasswordPrompter.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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.modules.config;
import java.io.IOException;
import org.apache.tomcat.core.*;
import org.apache.tomcat.modules.aaa.*;
import org.apache.tomcat.modules.server.*;
import org.apache.tomcat.util.log.Log;
import org.apache.tomcat.util.io.*;
/**
* <code>PasswordPrompter</code> is a add-on module for the Tomcat 3.3
* server. By installing this module, any secure connectors listed in the
* <code>server.xml</code> configuration file can be defined without the
* "keystorePass" attribute (where the password for the certificate
* keystore is traditionally set). At startup, each secure connector without
* a predefined password will result in a command-line prompt for the password.
* This has the advantage of increased security, as the certificate password
* need not be stored in the configuration files.
*
* Also, any JDBCRealm in <code>server.xml</code> defined without a
* connectionPassword will result in a command-line prompt for the password.
*
* <p>
* <strong>Installation</strong>
* <p>
*
* Place the PasswordPrompter.war file in Tomcat 3.3's modules directory
* prior to starting Tomcat.
*
* <p>
* <strong>Notes</strong>
* <p>
*
* This module does NOT attempt any additional validation on the supplied
* password. It will simply pass the value on just as if it had been entered
* into the <code>server.xml</code> file.
*
* Finally, this is primarily a simple example of an add-on module for Tomcat 3.3.
* It tries to do something usefull as well, but leaves a fair amount of
* room for improvement. It should not be considered a finished solution to
* the security issue of protecting passwords.
*
* @author Larry Isaacs
* @author Christopher Cain
* @version $Revision: 1.1 $ $Date: 2001/10/08 05:23:57 $
*/
public class PasswordPrompter extends BaseInterceptor {
// ----------------------------------------------------------------- Fields
/** The name of the module */
public static final String MOD_NAME = "PasswordPrompter";
/** The current version number */
public static final String MOD_VERSION = "1.0";
/** Number of lines to scroll to hide password */
private int scroll = 25;
// ------------------------------------------------------------ Constructor
/** Default constructor. */
public PasswordPrompter() {
}
// ------------------------------------------------------------- Attributes
/** Set number of lines to scroll display to hide the password */
public void setScroll( int lines ) {
scroll = lines;
}
// ------------------------------------------------ Implementation (Public)
/**
* Returns the name of this module.
*
* @return the module name
*/
public static String getModName() {
return MOD_NAME;
}
/**
* Returns the current verion number of the module.
*
* @return the current version number
*/
public static String getModVersion() {
return MOD_VERSION;
}
// -------------------------------------------------------------- Callbacks
/**
* This callback is automatically executed by the startup process each time
* an interceptor is added to a context. For the purposes of this
* particular module, processing is only done when this interceptor itself
* is added.
*
* @param cm the <code>ContextManager</code> for which the interceptor
* is being added
* @param ctx the <code>Context</code> for which the interceptor is being
* added
* @param i the interceptor being added to the Context
*/
public void addInterceptor( ContextManager cm, Context ctx,
BaseInterceptor i )
{
// If executing config generation, don't prompt for passwords
if ( cm.getProperty("jkconf") != null )
return;
if ( i == this ) {
BaseInterceptor[] interceptors = cm.getContainer().getInterceptors(
Container.H_engineInit
);
for ( int idx = 0; idx < interceptors.length; idx++ )
{
if ( interceptors[idx] instanceof PoolTcpConnector )
{
// We have an Http connector, set certificate password if appropriate
processTcpConnector( (PoolTcpConnector)interceptors[idx] );
}
else if ( interceptors[idx] instanceof JDBCRealm )
{
// We have a JDBC realm, set DB connection password if appropriate
processJDBCRealm( (JDBCRealm)interceptors[idx] );
}
}
} else {
if ( i instanceof PoolTcpConnector ) {
processTcpConnector( (PoolTcpConnector)i );
}
}
}
private void processTcpConnector( PoolTcpConnector connector )
{
// We have an Http connector, check to see if it's secure
if ( connector.isSecure() )
{
// It's secure, now check to see if the keystore pass was
// already specified in the config file
if (!connector.isKeypassSet()) {
// insure log flushed
Log logger = getLog();
if (logger != null )
logger.flush();
// Go ahead with the prompting
String certpwd = null;
try {
certpwd = Prompter.promptForInput(
"SSL socket detected, please enter " +
"the certificate password:", scroll );
} catch (IOException ioe) {
log( "IO problem with command line: " + ioe.toString() );
} catch (PrompterException pe) {
log( "Prompter problem: " + pe.toString() );
}
if ( certpwd != null )
connector.setKeypass(certpwd);
}
}
}
private void processJDBCRealm( JDBCRealm realm )
{
// Check to see if the connection password was
// already specified in the config file
if (!realm.isConnectionPasswordSet()) {
// insure log flushed
Log logger = getLog();
if (logger != null )
logger.flush();
// Go ahead with the prompting
String connpwd = null;
try {
connpwd = Prompter.promptForInput(
"JDBC Realm detected, please enter " +
"the connection password:", scroll );
} catch (IOException ioe) {
log( "IO problem with command line: " + ioe.toString() );
} catch (PrompterException pe) {
log( "Prompter problem: " + pe.toString() );
}
if ( connpwd != null )
realm.setConnectionPassword(connpwd);
}
}
}
1.1 jakarta-tomcat/proposals/PasswordPrompter/WEB-INF/classes/org/apache/tomcat/util/io/Prompter.java
Index: Prompter.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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.
* ====================================================================
*
*/
package org.apache.tomcat.util.io;
import java.io.*;
/**
* This utility class allows for command-line interaction with
* the user during Tomcat startup. This is particularly useful in capturing
* sensitive information, such as resource passwords, that may not be suitable
* for inclusion in the various configuration files due to security concerns.
* <p>
* It is designed primarily as a "building block" utility.
* Its purpose is to provide a common API for any Tomcat listeners/interceptors
* that may wish to communicate via the command-line during container startup.
* <p>
* All public methods in this class should be synchronized, and they should
* follow the general layout described below (see
* <a href="#promptForInput(java.lang.String)">promptForInput</a> for an
* example implementation):
*
* <ol>
* <li>Get a copy of the current <code>stdout</code> stream by calling
* <a href="#cloneStdOut()">cloneStdOut</a>
* <li>Temporarily seize control of the <code>stdout</code> stream by
* calling <a href="#setStdOut()">setStdOut</a>
* <li>(Process the required interaction)
* <li>Restore <code>stdout</code> to its original value by calling
* <a href="#restoreStdOut(java.io.PrintStream)">restoreStdOut</a> with
* the clone
* </ol>
*
* <i>Threading Considerations</i>
* <p>
* Note that sychronizing the interaction methods prevents multiple threads
* from attempting command-line interaction at the same time. Modules calling
* this utility will therefore be guaranteed a single atmoic
* challenge/response, but not necessarily a single atomic "session" with the
* command line. For example, if a module prompts for a password, determines
* that the password is invalid, and then reprompts, there is no guarantee that
* another thread has not prompted for something else in the meantime. In
* practice, this would have to involve multiple threads from a single
* command-line/JVM attempting to start multiple instances for Tomcat with a
* single command. Nevertheless, modules should send very specific prompt
* messages to avoid any potential user confusion.
*
* @author Christopher Cain
* @version $Revision: 1.1 $ $Date: 2001/10/08 05:23:57 $
*/
public class Prompter {
// ----------------------------------------------------- Fields (Constants)
/** The maximum allowed input size */
public static final int MAX_INPUT_LENGTH = 1024;
// ------------------------------------------------------------ Constructor
/**
* The default constructor is <code>private</code>, as instantiation of
* this class is not permitted.
*/
private Prompter() {
}
/**
* StringBuffer containing EOL character sequence
*/
private static final StringBuffer eol =
new StringBuffer(System.getProperty("line.separator"));
// --------------------------------------------------------- Public Methods
/**
* Request a value from the user, using the given text as a prompt.
* <p>
* @param promptMessage the prompt text to display to the user
* @return This method returns a non-null string containing the user
* input. If the user didn't enter a value, an empty string is
* returned. If the value exceeds the arbitrary size limit
* (currently 1k), or if it fails the
* <a href="#isMalformed(java.lang.String)">isMalformed</a>
* check, a <code>PrompterException</code> is thrown.
* @exception IOException any IO problems communicating with the terminal
* @exception PrompterException any validator exceptions with the given input
*/
public static synchronized String promptForInput( String promptMessage, int scroll )
throws IOException, PrompterException {
/* Setup */
String userInput = "";
BufferedReader br = null;
IOException ioeThrow = null;
// Aim stdout at the terminal
PrintStream initialStdOut = cloneStdOut();
setStdOut();
/* Execution */
try {
// Display the prompt
System.out.println();
System.out.println( promptMessage );
// Read the input
br = new BufferedReader(new InputStreamReader(System.in));
userInput = br.readLine();
// Hide the input by scrolling the display
for ( int i = 0; i < scroll; i++ )
System.out.println();
// Basic validation
if ( userInput == null )
throw new PrompterException("Unable to read password from System.in");
else if ( userInput.length() > MAX_INPUT_LENGTH )
throw new PrompterException("Input limit exceeded");
else if ( isMalformed(userInput) )
throw new PrompterException("Input contains illegal character(s)");
// Return
return userInput;
} catch ( IOException ioe ) {
throw ioe;
} finally {
restoreStdOut(initialStdOut);
}
}
// ----------------------------------------- Private Implementation Methods
/**
* Return a cloned copy of the current <code>stdout</code>. This should
* only be called from synchronized methods.
* <p>
* @return a clone of <code>stdout</code>
*/
protected static PrintStream cloneStdOut() {
// Note: Deep cloning doesn't appear to be necessary
return new PrintStream(System.out);
}
/**
* Temporarily redirect <code>stdout</code> to the command line (in case
* it isn't already). This should only be called from synchronized methods.
*/
protected static void setStdOut() {
System.setOut(
new PrintStream(
new BufferedOutputStream(
new FileOutputStream(FileDescriptor.out),
128
),
true
)
);
}
/**
* Restore <code>stdout</code> to its original value. This should only be
* called from synchronized methods.
*/
protected static void restoreStdOut( PrintStream origStream ) {
System.setOut(origStream);
}
/**
* Perform a basic integrity check against the command-line user input.
* Arbitrary command-line input should <b>always</b> be scanned for
* unusual character sequences, primarily as a precaution against
* malicious code being embeded into the reply value.
* <p>
* This check is currently implemented as an search for non-printing
* characters, which usually indicates either an attempted attack or an
* accidental key-combination (CTRL + letter). It will also disallow tabs.
* <p>
* This check will help prevent problems such as sending a questionable
* string as a parameter to another program. It will <b>NOT</b> save you if
* you are using the arbitrary user input to directly construct a command
* string (a system-level command, a SQL statement through string
* concatenation, etc.). In general, you <i>really</i> don't want to do
* that.
* <p>
* @param inputValue the value supplied by the user
* @return <code>true</code> if the input contains
* immediately-suspicious characters, otherwise
* <code>false</code>
*/
protected static boolean isMalformed( String inputValue ) {
// Note: We don't care about line separators, as BufferedReader sees
// them as the input terminator. It is therefore impossible for the
// input value to contain them.
char nextChar;
int charType;
for ( int x = 0; x < inputValue.length(); x++ ) {
nextChar = inputValue.charAt(x);
if ( Character.isISOControl(nextChar) )
return true;
else {
charType = Character.getType(nextChar);
if ( charType == Character.CONTROL ||
charType == Character.FORMAT ||
charType == Character.UNASSIGNED ||
charType == Character.PRIVATE_USE ||
charType == Character.SURROGATE
)
return true;
}
}
return false;
}
}
1.1 jakarta-tomcat/proposals/PasswordPrompter/WEB-INF/classes/org/apache/tomcat/util/io/PrompterException.java
Index: PrompterException.java
===================================================================
/*
* ====================================================================
*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001 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.
* ====================================================================
*
*/
package org.apache.tomcat.util.io;
/**
* A general purpose exception class for the <code>Prompter</code> utility.
* An exception of this type indicates an internal <code>Prompter</code>
* problem.
*
* @author Christopher Cain
* @version $Revision: 1.1 $ $Date: 2001/10/08 05:23:57 $
*/
public class PrompterException extends Exception {
// -------------------------------------------------------- Instance Fields
/** The error message passed (if any) */
protected String message = null;
/** The underlying exception passed (if any) */
protected Throwable throwable = null;
// ----------------------------------------------------------- Constructors
/**
* Construct a new <code>PrompterException</code> with no additional
* information.
*/
public PrompterException() {
}
/**
* Construct a new <code>PrompterException</code> with the specified
* message.
*
* @param message message describing the exception
*/
public PrompterException( String message ) {
this(message, null);
}
/**
* Construct a new <code>PrompterException</code> with the specified
* throwable.
*
* @param throwable throwable that caused the exception
*/
public PrompterException( Throwable throwable ) {
this(null, throwable);
}
/**
* Construct a new <code>PrompterException</code> with the specified
* message and throwable.
*
* @param message message describing the exception
* @param throwable throwable that caused the exception
*/
public PrompterException( String message, Throwable throwable ) {
super();
this.message = message;
this.throwable = throwable;
}
//---------------------------------------------------------- Public Methods
/**
* Return the message associated with this exception.
*
* @return the exception message (if any)
*/
public String getMessage() {
return (message);
}
/**
* Return the throwable that caused this exception.
*
* @return the underlying exception (if any)
*/
public Throwable getThrowable() {
return (throwable);
}
/**
* Return a formatted string that describes this exception.
*
* @return a description of the exception
*/
public String toString() {
StringBuffer sb = new StringBuffer("PrompterException: ");
if (message != null) {
sb.append(message);
if (throwable != null)
sb.append(": ");
}
if (throwable != null)
sb.append(throwable.toString());
return (sb.toString());
}
}
Re: cvs commit: jakarta-tomcat/proposals/PasswordPrompter/WEB-INF/classes/org/apache/tomcat/util/io Prompter.java PrompterException.java
Posted by Christopher Cain <cc...@mhsoftware.com>.
Quoting larryi@apache.org:
[snip]
> // Hide the input by scrolling the display
> for ( int i = 0; i < scroll; i++ )
> System.out.println();
Very clever. I hadn't thought of that. A very nice, simple hack to at least vex
the simple over-the-shoulder peepers. That gets points for ingenuity, Larry-Man
=)
- Christopher
/**
* Pleurez, pleurez, mes yeux, et fondez vous en eau!
* La moitiƩ de ma vie a mis l'autre au tombeau.
* ---Corneille
*/