1 /*
2  * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 import java.io.*;
25 import java.util.Arrays;
26 import javax.security.auth.callback.*;
27 
28 /**
29  * A default CallbackHandler implementation.
30  */
31 public class DefaultHandlerImpl implements CallbackHandler {
32 
33     /**
34      * Invoke an array of Callbacks.
35      *
36      * <p>
37      *
38      * @param callbacks an array of <code>Callback</code> objects which contain
39      *                  the information requested by an underlying security
40      *                  service to be retrieved or displayed.
41      *
42      * @exception java.io.IOException if an input or output error occurs. <p>
43      *
44      * @exception UnsupportedCallbackException if the implementation of this
45      *                  method does not support one or more of the Callbacks
46      *                  specified in the <code>callbacks</code> parameter.
47      */
handle(Callback[] callbacks)48     public void handle(Callback[] callbacks)
49     throws IOException, UnsupportedCallbackException {
50 
51         for (int i = 0; i < callbacks.length; i++) {
52             if (callbacks[i] instanceof TextOutputCallback) {
53 
54                 // display the message according to the specified type
55                 TextOutputCallback toc = (TextOutputCallback)callbacks[i];
56                 switch (toc.getMessageType()) {
57                 case TextOutputCallback.INFORMATION:
58                     System.out.println(toc.getMessage());
59                     break;
60                 case TextOutputCallback.ERROR:
61                     System.out.println("ERROR: " + toc.getMessage());
62                     break;
63                 case TextOutputCallback.WARNING:
64                     System.out.println("WARNING: " + toc.getMessage());
65                     break;
66                 default:
67                     throw new IOException("Unsupported message type: " +
68                                         toc.getMessageType());
69                 }
70 
71             } else if (callbacks[i] instanceof NameCallback) {
72 
73                 // prompt the user for a username
74                 NameCallback nc = (NameCallback)callbacks[i];
75 
76                 // ignore the provided defaultName
77                 System.err.print(nc.getPrompt());
78                 System.err.flush();
79                 nc.setName((new BufferedReader
80                         (new InputStreamReader(System.in))).readLine());
81 
82             } else if (callbacks[i] instanceof PasswordCallback) {
83 
84                 // prompt the user for sensitive information
85                 PasswordCallback pc = (PasswordCallback)callbacks[i];
86                 System.err.print(pc.getPrompt());
87                 System.err.flush();
88                 pc.setPassword(readPassword(System.in));
89 
90             } else {
91                 throw new UnsupportedCallbackException
92                         (callbacks[i], "Unrecognized Callback");
93             }
94         }
95     }
96 
97     // Reads user password from given input stream.
readPassword(InputStream in)98     private char[] readPassword(InputStream in) throws IOException {
99 
100         char[] lineBuffer;
101         char[] buf;
102         int i;
103 
104         buf = lineBuffer = new char[128];
105 
106         int room = buf.length;
107         int offset = 0;
108         int c;
109 
110 loop:   while (true) {
111             switch (c = in.read()) {
112             case -1:
113             case '\n':
114                 break loop;
115 
116             case '\r':
117                 int c2 = in.read();
118                 if ((c2 != '\n') && (c2 != -1)) {
119                     if (!(in instanceof PushbackInputStream)) {
120                         in = new PushbackInputStream(in);
121                     }
122                     ((PushbackInputStream)in).unread(c2);
123                 } else
124                     break loop;
125 
126             default:
127                 if (--room < 0) {
128                     buf = new char[offset + 128];
129                     room = buf.length - offset - 1;
130                     System.arraycopy(lineBuffer, 0, buf, 0, offset);
131                     Arrays.fill(lineBuffer, ' ');
132                     lineBuffer = buf;
133                 }
134                 buf[offset++] = (char) c;
135                 break;
136             }
137         }
138 
139         if (offset == 0) {
140             return null;
141         }
142 
143         char[] ret = new char[offset];
144         System.arraycopy(buf, 0, ret, 0, offset);
145         Arrays.fill(buf, ' ');
146 
147         return ret;
148     }
149 }
150