# HG changeset patch # User alanb # Date 1392391286 0 # Node ID 616ad2891b71b607313f8c65fec8754dd8bc6f7a # Parent a956e9de07ed5a0ae21d65085bea3c39931fbf6d 8034943: Eliminate Kerberos dependency on com.sun.security.auth to avoid circular dependency Reviewed-by: weijun diff -r a956e9de07ed -r 616ad2891b71 jdk/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java --- a/jdk/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java Fri Feb 14 11:23:58 2014 +0100 +++ b/jdk/src/share/classes/com/sun/security/auth/callback/TextCallbackHandler.java Fri Feb 14 15:21:26 2014 +0000 @@ -28,21 +28,14 @@ /* JAAS imports */ 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.NameCallback; // javadoc +import javax.security.auth.callback.PasswordCallback; // javadoc import javax.security.auth.callback.UnsupportedCallbackException; /* Java imports */ -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; +import sun.security.util.ConsoleCallbackHandler; /** *

@@ -55,6 +48,7 @@ @jdk.Exported public class TextCallbackHandler implements CallbackHandler { + private final CallbackHandler consoleHandler; /** *

Creates a callback handler that prompts and reads from the @@ -63,7 +57,9 @@ * CallbackHandler. */ - public TextCallbackHandler() { } + public TextCallbackHandler() { + this.consoleHandler = new ConsoleCallbackHandler(); + } /** * Handles the specified set of callbacks. @@ -76,187 +72,7 @@ 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"); - } - } - - /* Do the confirmation callback last. */ - if (confirmation != null) { - doConfirmation(confirmation); - } - } - - /* Reads a line of input */ - 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) { - // defaultOption is an index into the options array - System.err.println( - i + ". " + options[i].name + - (i == defaultOption ? " [default]" : "")); - } else { - // defaultOption is an option value - 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); + // delegate to console handler + consoleHandler.handle(callbacks); } } diff -r a956e9de07ed -r 616ad2891b71 jdk/src/share/classes/sun/security/jgss/GSSUtil.java --- a/jdk/src/share/classes/sun/security/jgss/GSSUtil.java Fri Feb 14 11:23:58 2014 +0100 +++ b/jdk/src/share/classes/sun/security/jgss/GSSUtil.java Fri Feb 14 15:21:26 2014 +0000 @@ -25,7 +25,6 @@ package sun.security.jgss; -import com.sun.security.auth.callback.TextCallbackHandler; import javax.security.auth.Subject; import javax.security.auth.kerberos.KerberosPrincipal; import javax.security.auth.kerberos.KerberosTicket; @@ -48,6 +47,7 @@ import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import sun.security.action.GetBooleanAction; +import sun.security.util.ConsoleCallbackHandler; /** * The GSSUtilImplementation that knows how to work with the internals of @@ -243,7 +243,7 @@ if ((defaultHandler != null) && (defaultHandler.length() != 0)) { cb = null; } else { - cb = new TextCallbackHandler(); + cb = new ConsoleCallbackHandler(); } } diff -r a956e9de07ed -r 616ad2891b71 jdk/src/share/classes/sun/security/util/ConsoleCallbackHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/sun/security/util/ConsoleCallbackHandler.java Fri Feb 14 15:21:26 2014 +0000 @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.util; + +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; + +/** + * A {@code CallbackHandler} that prompts and reads from the command line + * for answers to authentication questions. + */ +public class ConsoleCallbackHandler implements CallbackHandler { + + /** + * Creates a callback handler that prompts and reads from the + * command line for answers to authentication questions. + */ + public ConsoleCallbackHandler() { } + + /** + * Handles the specified set of callbacks. + * + * @param callbacks the callbacks to handle + * @throws IOException if an input or output error occurs. + * @throws UnsupportedCallbackException if the callback is not an + * instance of NameCallback or PasswordCallback + */ + 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"); + } + } + + /* Do the confirmation callback last. */ + if (confirmation != null) { + doConfirmation(confirmation); + } + } + + /* Reads a line of input */ + 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) { + // defaultOption is an index into the options array + System.err.println( + i + ". " + options[i].name + + (i == defaultOption ? " [default]" : "")); + } else { + // defaultOption is an option value + 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); + } +}