jdk/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java
changeset 22973 616ad2891b71
parent 20742 4ae78e8060d6
child 23010 6dadb192ad81
equal deleted inserted replaced
22972:a956e9de07ed 22973:616ad2891b71
    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.
    53  * @see javax.security.auth.callback
    46  * @see javax.security.auth.callback
    54  */
    47  */
    55 
    48 
    56 @jdk.Exported
    49 @jdk.Exported
    57 public class TextCallbackHandler implements CallbackHandler {
    50 public class TextCallbackHandler implements CallbackHandler {
       
    51     private final CallbackHandler consoleHandler;
    58 
    52 
    59     /**
    53     /**
    60      * <p>Creates a callback handler that prompts and reads from the
    54      * <p>Creates a callback handler that prompts and reads from the
    61      * command line for answers to authentication questions.
    55      * command line for answers to authentication questions.
    62      * This can be used by JAAS applications to instantiate a
    56      * This can be used by JAAS applications to instantiate a
    63      * CallbackHandler.
    57      * CallbackHandler.
    64 
    58 
    65      */
    59      */
    66     public TextCallbackHandler() { }
    60     public TextCallbackHandler() {
       
    61         this.consoleHandler = new ConsoleCallbackHandler();
       
    62     }
    67 
    63 
    68     /**
    64     /**
    69      * Handles the specified set of callbacks.
    65      * Handles the specified set of callbacks.
    70      *
    66      *
    71      * @param callbacks the callbacks to handle
    67      * @param callbacks the callbacks to handle
    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 }