26 package com.sun.security.auth.callback; |
26 package com.sun.security.auth.callback; |
27 |
27 |
28 /* JAAS imports */ |
28 /* JAAS imports */ |
29 import javax.security.auth.callback.Callback; |
29 import javax.security.auth.callback.Callback; |
30 import javax.security.auth.callback.CallbackHandler; |
30 import javax.security.auth.callback.CallbackHandler; |
31 import javax.security.auth.callback.ConfirmationCallback; |
31 import javax.security.auth.callback.NameCallback; // javadoc |
32 import javax.security.auth.callback.NameCallback; |
32 import javax.security.auth.callback.PasswordCallback; // javadoc |
33 import javax.security.auth.callback.PasswordCallback; |
|
34 import javax.security.auth.callback.TextOutputCallback; |
|
35 import javax.security.auth.callback.UnsupportedCallbackException; |
33 import javax.security.auth.callback.UnsupportedCallbackException; |
36 |
34 |
37 /* Java imports */ |
35 /* Java imports */ |
38 import java.io.BufferedReader; |
|
39 import java.io.IOException; |
36 import java.io.IOException; |
40 import java.io.InputStream; |
|
41 import java.io.InputStreamReader; |
|
42 import java.io.PushbackInputStream; |
|
43 import java.util.Arrays; |
|
44 |
37 |
45 import sun.security.util.Password; |
38 import sun.security.util.ConsoleCallbackHandler; |
46 |
39 |
47 /** |
40 /** |
48 * <p> |
41 * <p> |
49 * Prompts and reads from the command line for answers to authentication |
42 * Prompts and reads from the command line for answers to authentication |
50 * questions. |
43 * questions. |
74 * instance of NameCallback or PasswordCallback |
70 * instance of NameCallback or PasswordCallback |
75 */ |
71 */ |
76 public void handle(Callback[] callbacks) |
72 public void handle(Callback[] callbacks) |
77 throws IOException, UnsupportedCallbackException |
73 throws IOException, UnsupportedCallbackException |
78 { |
74 { |
79 ConfirmationCallback confirmation = null; |
75 // delegate to console handler |
80 |
76 consoleHandler.handle(callbacks); |
81 for (int i = 0; i < callbacks.length; i++) { |
|
82 if (callbacks[i] instanceof TextOutputCallback) { |
|
83 TextOutputCallback tc = (TextOutputCallback) callbacks[i]; |
|
84 |
|
85 String text; |
|
86 switch (tc.getMessageType()) { |
|
87 case TextOutputCallback.INFORMATION: |
|
88 text = ""; |
|
89 break; |
|
90 case TextOutputCallback.WARNING: |
|
91 text = "Warning: "; |
|
92 break; |
|
93 case TextOutputCallback.ERROR: |
|
94 text = "Error: "; |
|
95 break; |
|
96 default: |
|
97 throw new UnsupportedCallbackException( |
|
98 callbacks[i], "Unrecognized message type"); |
|
99 } |
|
100 |
|
101 String message = tc.getMessage(); |
|
102 if (message != null) { |
|
103 text += message; |
|
104 } |
|
105 if (text != null) { |
|
106 System.err.println(text); |
|
107 } |
|
108 |
|
109 } else if (callbacks[i] instanceof NameCallback) { |
|
110 NameCallback nc = (NameCallback) callbacks[i]; |
|
111 |
|
112 if (nc.getDefaultName() == null) { |
|
113 System.err.print(nc.getPrompt()); |
|
114 } else { |
|
115 System.err.print(nc.getPrompt() + |
|
116 " [" + nc.getDefaultName() + "] "); |
|
117 } |
|
118 System.err.flush(); |
|
119 |
|
120 String result = readLine(); |
|
121 if (result.equals("")) { |
|
122 result = nc.getDefaultName(); |
|
123 } |
|
124 |
|
125 nc.setName(result); |
|
126 |
|
127 } else if (callbacks[i] instanceof PasswordCallback) { |
|
128 PasswordCallback pc = (PasswordCallback) callbacks[i]; |
|
129 |
|
130 System.err.print(pc.getPrompt()); |
|
131 System.err.flush(); |
|
132 |
|
133 pc.setPassword(Password.readPassword(System.in, pc.isEchoOn())); |
|
134 |
|
135 } else if (callbacks[i] instanceof ConfirmationCallback) { |
|
136 confirmation = (ConfirmationCallback) callbacks[i]; |
|
137 |
|
138 } else { |
|
139 throw new UnsupportedCallbackException( |
|
140 callbacks[i], "Unrecognized Callback"); |
|
141 } |
|
142 } |
|
143 |
|
144 /* Do the confirmation callback last. */ |
|
145 if (confirmation != null) { |
|
146 doConfirmation(confirmation); |
|
147 } |
|
148 } |
|
149 |
|
150 /* Reads a line of input */ |
|
151 private String readLine() throws IOException { |
|
152 String result = new BufferedReader |
|
153 (new InputStreamReader(System.in)).readLine(); |
|
154 if (result == null) { |
|
155 throw new IOException("Cannot read from System.in"); |
|
156 } |
|
157 return result; |
|
158 } |
|
159 |
|
160 private void doConfirmation(ConfirmationCallback confirmation) |
|
161 throws IOException, UnsupportedCallbackException |
|
162 { |
|
163 String prefix; |
|
164 int messageType = confirmation.getMessageType(); |
|
165 switch (messageType) { |
|
166 case ConfirmationCallback.WARNING: |
|
167 prefix = "Warning: "; |
|
168 break; |
|
169 case ConfirmationCallback.ERROR: |
|
170 prefix = "Error: "; |
|
171 break; |
|
172 case ConfirmationCallback.INFORMATION: |
|
173 prefix = ""; |
|
174 break; |
|
175 default: |
|
176 throw new UnsupportedCallbackException( |
|
177 confirmation, "Unrecognized message type: " + messageType); |
|
178 } |
|
179 |
|
180 class OptionInfo { |
|
181 String name; |
|
182 int value; |
|
183 OptionInfo(String name, int value) { |
|
184 this.name = name; |
|
185 this.value = value; |
|
186 } |
|
187 } |
|
188 |
|
189 OptionInfo[] options; |
|
190 int optionType = confirmation.getOptionType(); |
|
191 switch (optionType) { |
|
192 case ConfirmationCallback.YES_NO_OPTION: |
|
193 options = new OptionInfo[] { |
|
194 new OptionInfo("Yes", ConfirmationCallback.YES), |
|
195 new OptionInfo("No", ConfirmationCallback.NO) |
|
196 }; |
|
197 break; |
|
198 case ConfirmationCallback.YES_NO_CANCEL_OPTION: |
|
199 options = new OptionInfo[] { |
|
200 new OptionInfo("Yes", ConfirmationCallback.YES), |
|
201 new OptionInfo("No", ConfirmationCallback.NO), |
|
202 new OptionInfo("Cancel", ConfirmationCallback.CANCEL) |
|
203 }; |
|
204 break; |
|
205 case ConfirmationCallback.OK_CANCEL_OPTION: |
|
206 options = new OptionInfo[] { |
|
207 new OptionInfo("OK", ConfirmationCallback.OK), |
|
208 new OptionInfo("Cancel", ConfirmationCallback.CANCEL) |
|
209 }; |
|
210 break; |
|
211 case ConfirmationCallback.UNSPECIFIED_OPTION: |
|
212 String[] optionStrings = confirmation.getOptions(); |
|
213 options = new OptionInfo[optionStrings.length]; |
|
214 for (int i = 0; i < options.length; i++) { |
|
215 options[i] = new OptionInfo(optionStrings[i], i); |
|
216 } |
|
217 break; |
|
218 default: |
|
219 throw new UnsupportedCallbackException( |
|
220 confirmation, "Unrecognized option type: " + optionType); |
|
221 } |
|
222 |
|
223 int defaultOption = confirmation.getDefaultOption(); |
|
224 |
|
225 String prompt = confirmation.getPrompt(); |
|
226 if (prompt == null) { |
|
227 prompt = ""; |
|
228 } |
|
229 prompt = prefix + prompt; |
|
230 if (!prompt.equals("")) { |
|
231 System.err.println(prompt); |
|
232 } |
|
233 |
|
234 for (int i = 0; i < options.length; i++) { |
|
235 if (optionType == ConfirmationCallback.UNSPECIFIED_OPTION) { |
|
236 // defaultOption is an index into the options array |
|
237 System.err.println( |
|
238 i + ". " + options[i].name + |
|
239 (i == defaultOption ? " [default]" : "")); |
|
240 } else { |
|
241 // defaultOption is an option value |
|
242 System.err.println( |
|
243 i + ". " + options[i].name + |
|
244 (options[i].value == defaultOption ? " [default]" : "")); |
|
245 } |
|
246 } |
|
247 System.err.print("Enter a number: "); |
|
248 System.err.flush(); |
|
249 int result; |
|
250 try { |
|
251 result = Integer.parseInt(readLine()); |
|
252 if (result < 0 || result > (options.length - 1)) { |
|
253 result = defaultOption; |
|
254 } |
|
255 result = options[result].value; |
|
256 } catch (NumberFormatException e) { |
|
257 result = defaultOption; |
|
258 } |
|
259 |
|
260 confirmation.setSelectedIndex(result); |
|
261 } |
77 } |
262 } |
78 } |