1 /* 2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.util; 27 28 import java.math.BigInteger; 29 import java.util.Locale; 30 import java.util.regex.Matcher; 31 import java.util.regex.Pattern; 32 33 /** 34 * A utility class for debuging. 35 * 36 * @author Roland Schemers 37 */ 38 public class Debug { 39 40 private static final String args = null; 41 42 private final String prefix; 43 Debug(String prefix)44 private Debug(String prefix) { 45 this.prefix = prefix; 46 } 47 48 /* 49 From public static void Help() : Serves as a documentation of the 50 values that "args" accepts. 51 52 System.err.println(); 53 System.err.println("all turn on all debugging"); 54 System.err.println("access print all checkPermission results"); 55 System.err.println("certpath PKIX CertPathBuilder and"); 56 System.err.println(" CertPathValidator debugging"); 57 System.err.println("combiner SubjectDomainCombiner debugging"); 58 System.err.println("gssloginconfig"); 59 System.err.println(" GSS LoginConfigImpl debugging"); 60 System.err.println("configfile JAAS ConfigFile loading"); 61 System.err.println("configparser JAAS ConfigFile parsing"); 62 System.err.println("jar jar verification"); 63 System.err.println("logincontext login context results"); 64 System.err.println("jca JCA engine class debugging"); 65 System.err.println("policy loading and granting"); 66 System.err.println("provider security provider debugging"); 67 System.err.println("pkcs11 PKCS11 session manager debugging"); 68 System.err.println("pkcs11keystore"); 69 System.err.println(" PKCS11 KeyStore debugging"); 70 System.err.println("sunpkcs11 SunPKCS11 provider debugging"); 71 System.err.println("scl permissions SecureClassLoader assigns"); 72 System.err.println("ts timestamping"); 73 System.err.println(); 74 System.err.println("The following can be used with access:"); 75 System.err.println(); 76 System.err.println("stack include stack trace"); 77 System.err.println("domain dump all domains in context"); 78 System.err.println("failure before throwing exception, dump stack"); 79 System.err.println(" and domain that didn't have permission"); 80 System.err.println(); 81 System.err.println("The following can be used with stack and domain:"); 82 System.err.println(); 83 System.err.println("permission=<classname>"); 84 System.err.println(" only dump output if specified permission"); 85 System.err.println(" is being checked"); 86 System.err.println("codebase=<URL>"); 87 System.err.println(" only dump output if specified codebase"); 88 System.err.println(" is being checked"); 89 System.err.println(); 90 System.err.println("The following can be used with provider:"); 91 System.err.println(); 92 System.err.println("engine=<engines>"); 93 System.err.println(" only dump output for the specified list"); 94 System.err.println(" of JCA engines. Supported values:"); 95 System.err.println(" Cipher, KeyAgreement, KeyGenerator,"); 96 System.err.println(" KeyPairGenerator, KeyStore, Mac,"); 97 System.err.println(" MessageDigest, SecureRandom, Signature."); 98 System.err.println(); 99 System.err.println("Note: Separate multiple options with a comma"); 100 System.exit(0); 101 */ 102 103 /** 104 * Get a Debug object corresponding to whether or not the given 105 * option is set. Set the prefix to be the same as option. 106 */ 107 getInstance(String option)108 public static Debug getInstance(String option) 109 { 110 return getInstance(option, option); 111 } 112 113 /** 114 * Get a Debug object corresponding to whether or not the given 115 * option is set. Set the prefix to be prefix. 116 */ getInstance(String option, String prefix)117 public static Debug getInstance(String option, String prefix) 118 { 119 if (isOn(option)) { 120 Debug d = new Debug(prefix); 121 return d; 122 } else { 123 return null; 124 } 125 } 126 127 /** 128 * True if the system property "security.debug" contains the 129 * string "option". 130 */ isOn(String option)131 public static boolean isOn(String option) 132 { 133 if (args == null) 134 return false; 135 else { 136 if (args.indexOf("all") != -1) 137 return true; 138 else 139 return (args.indexOf(option) != -1); 140 } 141 } 142 143 /** 144 * print a message to stderr that is prefixed with the prefix 145 * created from the call to getInstance. 146 */ 147 println(String message)148 public void println(String message) 149 { 150 System.err.println(prefix + ": "+message); 151 } 152 153 /** 154 * print a blank line to stderr that is prefixed with the prefix. 155 */ 156 println()157 public void println() 158 { 159 System.err.println(prefix + ":"); 160 } 161 162 163 /** 164 * return a hexadecimal printed representation of the specified 165 * BigInteger object. the value is formatted to fit on lines of 166 * at least 75 characters, with embedded newlines. Words are 167 * separated for readability, with eight words (32 bytes) per line. 168 */ toHexString(BigInteger b)169 public static String toHexString(BigInteger b) { 170 String hexValue = b.toString(16); 171 StringBuffer buf = new StringBuffer(hexValue.length()*2); 172 173 if (hexValue.startsWith("-")) { 174 buf.append(" -"); 175 hexValue = hexValue.substring(1); 176 } else { 177 buf.append(" "); // four spaces 178 } 179 if ((hexValue.length()%2) != 0) { 180 // add back the leading 0 181 hexValue = "0" + hexValue; 182 } 183 int i=0; 184 while (i < hexValue.length()) { 185 // one byte at a time 186 buf.append(hexValue.substring(i, i+2)); 187 i+=2; 188 if (i!= hexValue.length()) { 189 if ((i%64) == 0) { 190 buf.append("\n "); // line after eight words 191 } else if (i%8 == 0) { 192 buf.append(" "); // space between words 193 } 194 } 195 } 196 return buf.toString(); 197 } 198 199 /** 200 * change a string into lower case except permission classes and URLs. 201 */ marshal(String args)202 private static String marshal(String args) { 203 if (args != null) { 204 StringBuffer target = new StringBuffer(); 205 StringBuffer source = new StringBuffer(args); 206 207 // obtain the "permission=<classname>" options 208 // the syntax of classname: IDENTIFIER.IDENTIFIER 209 // the regular express to match a class name: 210 // "[a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*" 211 String keyReg = "[Pp][Ee][Rr][Mm][Ii][Ss][Ss][Ii][Oo][Nn]="; 212 String keyStr = "permission="; 213 String reg = keyReg + 214 "[a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*"; 215 Pattern pattern = Pattern.compile(reg); 216 Matcher matcher = pattern.matcher(source); 217 StringBuffer left = new StringBuffer(); 218 while (matcher.find()) { 219 String matched = matcher.group(); 220 target.append(matched.replaceFirst(keyReg, keyStr)); 221 target.append(" "); 222 223 // delete the matched sequence 224 matcher.appendReplacement(left, ""); 225 } 226 matcher.appendTail(left); 227 source = left; 228 229 // obtain the "codebase=<URL>" options 230 // the syntax of URL is too flexible, and here assumes that the 231 // URL contains no space, comma(','), and semicolon(';'). That 232 // also means those characters also could be used as separator 233 // after codebase option. 234 // However, the assumption is incorrect in some special situation 235 // when the URL contains comma or semicolon 236 keyReg = "[Cc][Oo][Dd][Ee][Bb][Aa][Ss][Ee]="; 237 keyStr = "codebase="; 238 reg = keyReg + "[^, ;]*"; 239 pattern = Pattern.compile(reg); 240 matcher = pattern.matcher(source); 241 left = new StringBuffer(); 242 while (matcher.find()) { 243 String matched = matcher.group(); 244 target.append(matched.replaceFirst(keyReg, keyStr)); 245 target.append(" "); 246 247 // delete the matched sequence 248 matcher.appendReplacement(left, ""); 249 } 250 matcher.appendTail(left); 251 source = left; 252 253 // convert the rest to lower-case characters 254 target.append(source.toString().toLowerCase(Locale.ENGLISH)); 255 256 return target.toString(); 257 } 258 259 return null; 260 } 261 262 private final static char[] hexDigits = "0123456789abcdef".toCharArray(); 263 toString(byte[] b)264 public static String toString(byte[] b) { 265 if (b == null) { 266 return "(null)"; 267 } 268 StringBuilder sb = new StringBuilder(b.length * 3); 269 for (int i = 0; i < b.length; i++) { 270 int k = b[i] & 0xff; 271 if (i != 0) { 272 sb.append(':'); 273 } 274 sb.append(hexDigits[k >>> 4]); 275 sb.append(hexDigits[k & 0xf]); 276 } 277 return sb.toString(); 278 } 279 280 } 281