| 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 */  | 
 | 
 | 
 | 
package com.sun.security.auth.callback;  | 
 | 
 | 
 | 
 | 
 | 
import javax.security.auth.callback.Callback;  | 
 | 
import javax.security.auth.callback.CallbackHandler;  | 
 | 
import javax.security.auth.callback.ConfirmationCallback;  | 
 | 
import javax.security.auth.callback.NameCallback;  | 
 | 
import javax.security.auth.callback.PasswordCallback;  | 
 | 
import javax.security.auth.callback.TextOutputCallback;  | 
 | 
import javax.security.auth.callback.UnsupportedCallbackException;  | 
 | 
 | 
 | 
 | 
 | 
import java.io.BufferedReader;  | 
 | 
import java.io.IOException;  | 
 | 
import java.io.InputStream;  | 
 | 
import java.io.InputStreamReader;  | 
 | 
import java.io.PushbackInputStream;  | 
 | 
import java.util.Arrays;  | 
 | 
 | 
 | 
import sun.security.util.Password;  | 
 | 
 | 
 | 
/**  | 
 | 
 * <p>  | 
 | 
 * Prompts and reads from the command line for answers to authentication  | 
 | 
 * questions.  | 
 | 
 * This can be used by a JAAS application to instantiate a  | 
 | 
 * CallbackHandler  | 
 | 
 * @see javax.security.auth.callback  | 
 | 
 */  | 
 | 
 | 
 | 
@jdk.Exported  | 
 | 
public class TextCallbackHandler implements CallbackHandler { | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public TextCallbackHandler() { } | 
 | 
 | 
 | 
      | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
 | 
     */  | 
 | 
    public void handle(Callback[] callbacks)  | 
 | 
        throws IOException, UnsupportedCallbackException  | 
 | 
    { | 
 | 
        ConfirmationCallback confirmation = null;  | 
 | 
 | 
 | 
        for (int i = 0; i < callbacks.length; i++) { | 
 | 
            if (callbacks[i] instanceof TextOutputCallback) { | 
 | 
                TextOutputCallback tc = (TextOutputCallback) callbacks[i];  | 
 | 
 | 
 | 
                String text;  | 
 | 
                switch (tc.getMessageType()) { | 
 | 
                case TextOutputCallback.INFORMATION:  | 
 | 
                    text = "";  | 
 | 
                    break;  | 
 | 
                case TextOutputCallback.WARNING:  | 
 | 
                    text = "Warning: ";  | 
 | 
                    break;  | 
 | 
                case TextOutputCallback.ERROR:  | 
 | 
                    text = "Error: ";  | 
 | 
                    break;  | 
 | 
                default:  | 
 | 
                    throw new UnsupportedCallbackException(  | 
 | 
                        callbacks[i], "Unrecognized message type");  | 
 | 
                }  | 
 | 
 | 
 | 
                String message = tc.getMessage();  | 
 | 
                if (message != null) { | 
 | 
                    text += message;  | 
 | 
                }  | 
 | 
                if (text != null) { | 
 | 
                    System.err.println(text);  | 
 | 
                }  | 
 | 
 | 
 | 
            } else if (callbacks[i] instanceof NameCallback) { | 
 | 
                NameCallback nc = (NameCallback) callbacks[i];  | 
 | 
 | 
 | 
                if (nc.getDefaultName() == null) { | 
 | 
                    System.err.print(nc.getPrompt());  | 
 | 
                } else { | 
 | 
                    System.err.print(nc.getPrompt() +  | 
 | 
                                " [" + nc.getDefaultName() + "] ");  | 
 | 
                }  | 
 | 
                System.err.flush();  | 
 | 
 | 
 | 
                String result = readLine();  | 
 | 
                if (result.equals("")) { | 
 | 
                    result = nc.getDefaultName();  | 
 | 
                }  | 
 | 
 | 
 | 
                nc.setName(result);  | 
 | 
 | 
 | 
            } else if (callbacks[i] instanceof PasswordCallback) { | 
 | 
                PasswordCallback pc = (PasswordCallback) callbacks[i];  | 
 | 
 | 
 | 
                System.err.print(pc.getPrompt());  | 
 | 
                System.err.flush();  | 
 | 
 | 
 | 
                pc.setPassword(Password.readPassword(System.in, pc.isEchoOn()));  | 
 | 
 | 
 | 
            } else if (callbacks[i] instanceof ConfirmationCallback) { | 
 | 
                confirmation = (ConfirmationCallback) callbacks[i];  | 
 | 
 | 
 | 
            } else { | 
 | 
                throw new UnsupportedCallbackException(  | 
 | 
                    callbacks[i], "Unrecognized Callback");  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
          | 
 | 
        if (confirmation != null) { | 
 | 
            doConfirmation(confirmation);  | 
 | 
        }  | 
 | 
    }  | 
 | 
 | 
 | 
      | 
 | 
    private String readLine() throws IOException { | 
 | 
        String result = new BufferedReader  | 
 | 
            (new InputStreamReader(System.in)).readLine();  | 
 | 
        if (result == null) { | 
 | 
            throw new IOException("Cannot read from System.in"); | 
 | 
        }  | 
 | 
        return result;  | 
 | 
    }  | 
 | 
 | 
 | 
    private void doConfirmation(ConfirmationCallback confirmation)  | 
 | 
        throws IOException, UnsupportedCallbackException  | 
 | 
    { | 
 | 
        String prefix;  | 
 | 
        int messageType = confirmation.getMessageType();  | 
 | 
        switch (messageType) { | 
 | 
        case ConfirmationCallback.WARNING:  | 
 | 
            prefix =  "Warning: ";  | 
 | 
            break;  | 
 | 
        case ConfirmationCallback.ERROR:  | 
 | 
            prefix = "Error: ";  | 
 | 
            break;  | 
 | 
        case ConfirmationCallback.INFORMATION:  | 
 | 
            prefix = "";  | 
 | 
            break;  | 
 | 
        default:  | 
 | 
            throw new UnsupportedCallbackException(  | 
 | 
                confirmation, "Unrecognized message type: " + messageType);  | 
 | 
        }  | 
 | 
 | 
 | 
        class OptionInfo { | 
 | 
            String name;  | 
 | 
            int value;  | 
 | 
            OptionInfo(String name, int value) { | 
 | 
                this.name = name;  | 
 | 
                this.value = value;  | 
 | 
            }  | 
 | 
        }  | 
 | 
 | 
 | 
        OptionInfo[] options;  | 
 | 
        int optionType = confirmation.getOptionType();  | 
 | 
        switch (optionType) { | 
 | 
        case ConfirmationCallback.YES_NO_OPTION:  | 
 | 
            options = new OptionInfo[] { | 
 | 
                new OptionInfo("Yes", ConfirmationCallback.YES), | 
 | 
                new OptionInfo("No", ConfirmationCallback.NO) | 
 | 
            };  | 
 | 
            break;  | 
 | 
        case ConfirmationCallback.YES_NO_CANCEL_OPTION:  | 
 | 
            options = new OptionInfo[] { | 
 | 
                new OptionInfo("Yes", ConfirmationCallback.YES), | 
 | 
                new OptionInfo("No", ConfirmationCallback.NO), | 
 | 
                new OptionInfo("Cancel", ConfirmationCallback.CANCEL) | 
 | 
            };  | 
 | 
            break;  | 
 | 
        case ConfirmationCallback.OK_CANCEL_OPTION:  | 
 | 
            options = new OptionInfo[] { | 
 | 
                new OptionInfo("OK", ConfirmationCallback.OK), | 
 | 
                new OptionInfo("Cancel", ConfirmationCallback.CANCEL) | 
 | 
            };  | 
 | 
            break;  | 
 | 
        case ConfirmationCallback.UNSPECIFIED_OPTION:  | 
 | 
            String[] optionStrings = confirmation.getOptions();  | 
 | 
            options = new OptionInfo[optionStrings.length];  | 
 | 
            for (int i = 0; i < options.length; i++) { | 
 | 
                options[i] = new OptionInfo(optionStrings[i], i);  | 
 | 
            }  | 
 | 
            break;  | 
 | 
        default:  | 
 | 
            throw new UnsupportedCallbackException(  | 
 | 
                confirmation, "Unrecognized option type: " + optionType);  | 
 | 
        }  | 
 | 
 | 
 | 
        int defaultOption = confirmation.getDefaultOption();  | 
 | 
 | 
 | 
        String prompt = confirmation.getPrompt();  | 
 | 
        if (prompt == null) { | 
 | 
            prompt = "";  | 
 | 
        }  | 
 | 
        prompt = prefix + prompt;  | 
 | 
        if (!prompt.equals("")) { | 
 | 
            System.err.println(prompt);  | 
 | 
        }  | 
 | 
 | 
 | 
        for (int i = 0; i < options.length; i++) { | 
 | 
            if (optionType == ConfirmationCallback.UNSPECIFIED_OPTION) { | 
 | 
                  | 
 | 
                System.err.println(  | 
 | 
                    i + ". " + options[i].name +  | 
 | 
                    (i == defaultOption ? " [default]" : ""));  | 
 | 
            } else { | 
 | 
                  | 
 | 
                System.err.println(  | 
 | 
                    i + ". " + options[i].name +  | 
 | 
                    (options[i].value == defaultOption ? " [default]" : ""));  | 
 | 
            }  | 
 | 
        }  | 
 | 
        System.err.print("Enter a number: "); | 
 | 
        System.err.flush();  | 
 | 
        int result;  | 
 | 
        try { | 
 | 
            result = Integer.parseInt(readLine());  | 
 | 
            if (result < 0 || result > (options.length - 1)) { | 
 | 
                result = defaultOption;  | 
 | 
            }  | 
 | 
            result = options[result].value;  | 
 | 
        } catch (NumberFormatException e) { | 
 | 
            result = defaultOption;  | 
 | 
        }  | 
 | 
 | 
 | 
        confirmation.setSelectedIndex(result);  | 
 | 
    }  | 
 | 
}  |