0N/A/*
2619N/A * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0N/A *
0N/A * This code is free software; you can redistribute it and/or modify it
0N/A * under the terms of the GNU General Public License version 2 only, as
2362N/A * published by the Free Software Foundation. Oracle designates this
0N/A * particular file as subject to the "Classpath" exception as provided
2362N/A * by Oracle in the LICENSE file that accompanied this code.
0N/A *
0N/A * This code is distributed in the hope that it will be useful, but WITHOUT
0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0N/A * version 2 for more details (a copy is included in the LICENSE file that
0N/A * accompanied this code).
0N/A *
0N/A * You should have received a copy of the GNU General Public License version
0N/A * 2 along with this work; if not, write to the Free Software Foundation,
0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0N/A *
2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2362N/A * or visit www.oracle.com if you need additional information or have any
2362N/A * questions.
0N/A */
0N/A
0N/Apackage sun.security.util;
0N/A
0N/Aimport java.math.BigInteger;
0N/Aimport java.util.regex.Pattern;
0N/Aimport java.util.regex.Matcher;
2619N/Aimport java.util.Locale;
0N/A
0N/A/**
0N/A * A utility class for debuging.
0N/A *
0N/A * @author Roland Schemers
0N/A */
0N/Apublic class Debug {
0N/A
0N/A private String prefix;
0N/A
0N/A private static String args;
0N/A
0N/A static {
0N/A args = java.security.AccessController.doPrivileged
0N/A (new sun.security.action.GetPropertyAction
0N/A ("java.security.debug"));
0N/A
0N/A String args2 = java.security.AccessController.doPrivileged
0N/A (new sun.security.action.GetPropertyAction
0N/A ("java.security.auth.debug"));
0N/A
0N/A if (args == null) {
0N/A args = args2;
0N/A } else {
0N/A if (args2 != null)
0N/A args = args + "," + args2;
0N/A }
0N/A
0N/A if (args != null) {
0N/A args = marshal(args);
0N/A if (args.equals("help")) {
0N/A Help();
0N/A }
0N/A }
0N/A }
0N/A
0N/A public static void Help()
0N/A {
0N/A System.err.println();
0N/A System.err.println("all turn on all debugging");
0N/A System.err.println("access print all checkPermission results");
0N/A System.err.println("combiner SubjectDomainCombiner debugging");
0N/A System.err.println("gssloginconfig");
0N/A System.err.println("configfile JAAS ConfigFile loading");
0N/A System.err.println("configparser JAAS ConfigFile parsing");
0N/A System.err.println(" GSS LoginConfigImpl debugging");
0N/A System.err.println("jar jar verification");
0N/A System.err.println("logincontext login context results");
0N/A System.err.println("policy loading and granting");
0N/A System.err.println("provider security provider debugging");
0N/A System.err.println("scl permissions SecureClassLoader assigns");
0N/A System.err.println();
0N/A System.err.println("The following can be used with access:");
0N/A System.err.println();
0N/A System.err.println("stack include stack trace");
0N/A System.err.println("domain dump all domains in context");
0N/A System.err.println("failure before throwing exception, dump stack");
0N/A System.err.println(" and domain that didn't have permission");
0N/A System.err.println();
0N/A System.err.println("The following can be used with stack and domain:");
0N/A System.err.println();
0N/A System.err.println("permission=<classname>");
0N/A System.err.println(" only dump output if specified permission");
0N/A System.err.println(" is being checked");
0N/A System.err.println("codebase=<URL>");
0N/A System.err.println(" only dump output if specified codebase");
0N/A System.err.println(" is being checked");
0N/A
0N/A System.err.println();
0N/A System.err.println("Note: Separate multiple options with a comma");
0N/A System.exit(0);
0N/A }
0N/A
0N/A
0N/A /**
0N/A * Get a Debug object corresponding to whether or not the given
0N/A * option is set. Set the prefix to be the same as option.
0N/A */
0N/A
0N/A public static Debug getInstance(String option)
0N/A {
0N/A return getInstance(option, option);
0N/A }
0N/A
0N/A /**
0N/A * Get a Debug object corresponding to whether or not the given
0N/A * option is set. Set the prefix to be prefix.
0N/A */
0N/A public static Debug getInstance(String option, String prefix)
0N/A {
0N/A if (isOn(option)) {
0N/A Debug d = new Debug();
0N/A d.prefix = prefix;
0N/A return d;
0N/A } else {
0N/A return null;
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * True if the system property "security.debug" contains the
0N/A * string "option".
0N/A */
0N/A public static boolean isOn(String option)
0N/A {
0N/A if (args == null)
0N/A return false;
0N/A else {
0N/A if (args.indexOf("all") != -1)
0N/A return true;
0N/A else
0N/A return (args.indexOf(option) != -1);
0N/A }
0N/A }
0N/A
0N/A /**
0N/A * print a message to stderr that is prefixed with the prefix
0N/A * created from the call to getInstance.
0N/A */
0N/A
0N/A public void println(String message)
0N/A {
0N/A System.err.println(prefix + ": "+message);
0N/A }
0N/A
0N/A /**
0N/A * print a blank line to stderr that is prefixed with the prefix.
0N/A */
0N/A
0N/A public void println()
0N/A {
0N/A System.err.println(prefix + ":");
0N/A }
0N/A
0N/A /**
0N/A * print a message to stderr that is prefixed with the prefix.
0N/A */
0N/A
0N/A public static void println(String prefix, String message)
0N/A {
0N/A System.err.println(prefix + ": "+message);
0N/A }
0N/A
0N/A /**
0N/A * return a hexadecimal printed representation of the specified
0N/A * BigInteger object. the value is formatted to fit on lines of
0N/A * at least 75 characters, with embedded newlines. Words are
0N/A * separated for readability, with eight words (32 bytes) per line.
0N/A */
0N/A public static String toHexString(BigInteger b) {
0N/A String hexValue = b.toString(16);
0N/A StringBuffer buf = new StringBuffer(hexValue.length()*2);
0N/A
0N/A if (hexValue.startsWith("-")) {
0N/A buf.append(" -");
0N/A hexValue = hexValue.substring(1);
0N/A } else {
0N/A buf.append(" "); // four spaces
0N/A }
0N/A if ((hexValue.length()%2) != 0) {
0N/A // add back the leading 0
0N/A hexValue = "0" + hexValue;
0N/A }
0N/A int i=0;
0N/A while (i < hexValue.length()) {
0N/A // one byte at a time
0N/A buf.append(hexValue.substring(i, i+2));
0N/A i+=2;
0N/A if (i!= hexValue.length()) {
0N/A if ((i%64) == 0) {
0N/A buf.append("\n "); // line after eight words
0N/A } else if (i%8 == 0) {
0N/A buf.append(" "); // space between words
0N/A }
0N/A }
0N/A }
0N/A return buf.toString();
0N/A }
0N/A
0N/A /**
0N/A * change a string into lower case except permission classes and URLs.
0N/A */
0N/A private static String marshal(String args) {
0N/A if (args != null) {
0N/A StringBuffer target = new StringBuffer();
0N/A StringBuffer source = new StringBuffer(args);
0N/A
0N/A // obtain the "permission=<classname>" options
0N/A // the syntax of classname: IDENTIFIER.IDENTIFIER
0N/A // the regular express to match a class name:
0N/A // "[a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*"
0N/A String keyReg = "[Pp][Ee][Rr][Mm][Ii][Ss][Ss][Ii][Oo][Nn]=";
0N/A String keyStr = "permission=";
0N/A String reg = keyReg +
0N/A "[a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*";
0N/A Pattern pattern = Pattern.compile(reg);
0N/A Matcher matcher = pattern.matcher(source);
0N/A StringBuffer left = new StringBuffer();
0N/A while (matcher.find()) {
0N/A String matched = matcher.group();
0N/A target.append(matched.replaceFirst(keyReg, keyStr));
0N/A target.append(" ");
0N/A
0N/A // delete the matched sequence
0N/A matcher.appendReplacement(left, "");
0N/A }
0N/A matcher.appendTail(left);
0N/A source = left;
0N/A
0N/A // obtain the "codebase=<URL>" options
0N/A // the syntax of URL is too flexible, and here assumes that the
0N/A // URL contains no space, comma(','), and semicolon(';'). That
0N/A // also means those characters also could be used as separator
0N/A // after codebase option.
0N/A // However, the assumption is incorrect in some special situation
0N/A // when the URL contains comma or semicolon
0N/A keyReg = "[Cc][Oo][Dd][Ee][Bb][Aa][Ss][Ee]=";
0N/A keyStr = "codebase=";
0N/A reg = keyReg + "[^, ;]*";
0N/A pattern = Pattern.compile(reg);
0N/A matcher = pattern.matcher(source);
0N/A left = new StringBuffer();
0N/A while (matcher.find()) {
0N/A String matched = matcher.group();
0N/A target.append(matched.replaceFirst(keyReg, keyStr));
0N/A target.append(" ");
0N/A
0N/A // delete the matched sequence
0N/A matcher.appendReplacement(left, "");
0N/A }
0N/A matcher.appendTail(left);
0N/A source = left;
0N/A
0N/A // convert the rest to lower-case characters
2619N/A target.append(source.toString().toLowerCase(Locale.ENGLISH));
0N/A
0N/A return target.toString();
0N/A }
0N/A
0N/A return null;
0N/A }
0N/A
0N/A private final static char[] hexDigits = "0123456789abcdef".toCharArray();
0N/A
0N/A public static String toString(byte[] b) {
0N/A if (b == null) {
0N/A return "(null)";
0N/A }
0N/A StringBuilder sb = new StringBuilder(b.length * 3);
0N/A for (int i = 0; i < b.length; i++) {
0N/A int k = b[i] & 0xff;
0N/A if (i != 0) {
0N/A sb.append(':');
0N/A }
0N/A sb.append(hexDigits[k >>> 4]);
0N/A sb.append(hexDigits[k & 0xf]);
0N/A }
0N/A return sb.toString();
0N/A }
0N/A
0N/A}