001: /**
002: * JOnAS: Java(TM) Open Application Server
003: * Copyright (C) 1999-2004 Bull S.A.
004: * Contact: jonas-team@objectweb.org
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2.1 of the License, or 1any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
019: * USA
020: *
021: * Initial developer: Copyright 2001-2002 Sun Microsystems, Inc. All Rights Reserved.
022: * --------------------------------------------------------------------------
023: * $Id: LoginCallbackHandler.java 4804 2004-05-25 15:13:29Z benoitf $
024: * --------------------------------------------------------------------------
025: */package org.objectweb.jonas.security.auth.callback;
026:
027: import java.io.IOException;
028: import java.io.PushbackInputStream;
029: import java.io.InputStream;
030: import java.io.BufferedReader;
031: import java.io.InputStreamReader;
032: import java.util.Arrays;
033:
034: import javax.security.auth.callback.CallbackHandler;
035: import javax.security.auth.callback.Callback;
036: import javax.security.auth.callback.NameCallback;
037: import javax.security.auth.callback.PasswordCallback;
038: import javax.security.auth.callback.TextOutputCallback;
039: import javax.security.auth.callback.UnsupportedCallbackException;
040:
041: /**
042: * Come from the JAAS authentication tutorial The application implements the
043: * CallbackHandler. <p>This application is text-based. Therefore it displays
044: * information to the user using the OutputStreams System.out and System.err,
045: * and gathers input from the user using the InputStream System.in.
046: * @author Sun Tutorial
047: */
048: public class LoginCallbackHandler implements CallbackHandler {
049:
050: /**
051: * Size of the buffer
052: */
053: private static final int BUFFER_SIZE = 128;
054:
055: /**
056: * Invoke an array of Callbacks.
057: * @param callbacks an array of <code>Callback</code> objects which
058: * contain the information requested by an underlying security
059: * service to be retrieved or displayed.
060: * @throws IOException if an input or output error occurs. <p>
061: * @throws UnsupportedCallbackException if the implementation of this method
062: * does not support one or more of the Callbacks specified in the
063: * <code>callbacks</code> parameter.
064: */
065: public void handle(Callback[] callbacks) throws IOException,
066: UnsupportedCallbackException {
067:
068: for (int i = 0; i < callbacks.length; i++) {
069: if (callbacks[i] instanceof TextOutputCallback) {
070:
071: // display the message according to the specified type
072: TextOutputCallback toc = (TextOutputCallback) callbacks[i];
073: switch (toc.getMessageType()) {
074: case TextOutputCallback.INFORMATION:
075: System.out.println(toc.getMessage());
076: break;
077: case TextOutputCallback.ERROR:
078: System.out.println("ERROR: " + toc.getMessage());
079: break;
080: case TextOutputCallback.WARNING:
081: System.out.println("WARNING: " + toc.getMessage());
082: break;
083: default:
084: throw new IOException("Unsupported message type: "
085: + toc.getMessageType());
086: }
087:
088: } else if (callbacks[i] instanceof NameCallback) {
089:
090: // prompt the user for a username
091: NameCallback nc = (NameCallback) callbacks[i];
092:
093: System.err.print(nc.getPrompt());
094: System.err.flush();
095: nc.setName((new BufferedReader(new InputStreamReader(
096: System.in))).readLine());
097:
098: } else if (callbacks[i] instanceof PasswordCallback) {
099:
100: // prompt the user for sensitive information
101: PasswordCallback pc = (PasswordCallback) callbacks[i];
102: System.err.print(pc.getPrompt());
103: System.err.flush();
104: pc.setPassword(readPassword(System.in));
105: } else {
106: throw new UnsupportedCallbackException(callbacks[i],
107: "Unrecognized Callback");
108: }
109: }
110: }
111:
112: /**
113: * Reads user password from given input stream.
114: * @param in given input stream
115: * @return the password
116: * @throws IOException if it fails
117: */
118: private char[] readPassword(InputStream in) throws IOException {
119:
120: char[] lineBuffer;
121: char[] buf;
122: int i;
123:
124: lineBuffer = new char[BUFFER_SIZE];
125: buf = lineBuffer;
126:
127: int room = buf.length;
128: int offset = 0;
129: int c;
130:
131: loop: while (true) {
132: switch (c = in.read()) {
133: case -1:
134: case '\n':
135: break loop;
136:
137: case '\r':
138: int c2 = in.read();
139: if ((c2 != '\n') && (c2 != -1)) {
140: if (!(in instanceof PushbackInputStream)) {
141: in = new PushbackInputStream(in);
142: }
143: ((PushbackInputStream) in).unread(c2);
144: } else {
145: break loop;
146: }
147: default:
148: if (--room < 0) {
149: buf = new char[offset + BUFFER_SIZE];
150: room = buf.length - offset - 1;
151: System.arraycopy(lineBuffer, 0, buf, 0, offset);
152: Arrays.fill(lineBuffer, ' ');
153: lineBuffer = buf;
154: }
155: buf[offset++] = (char) c;
156: break;
157: }
158: }
159:
160: if (offset == 0) {
161: return null;
162: }
163:
164: char[] ret = new char[offset];
165: System.arraycopy(buf, 0, ret, 0, offset);
166: Arrays.fill(buf, ' ');
167:
168: return ret;
169: }
170: }
|