• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.regex.Pattern;
30 import java.util.regex.Matcher;
31 import java.util.Locale;
32 
33 /**
34  * A utility class for debuging.
35  *
36  * @author Roland Schemers
37  */
38 public class Debug {
39 
40     private String prefix;
41 
42     private static String args;
43 
44     // BEGIN Android-changed: Debug is stubbed and disabled on Android.
45     // Removing the static initializer removes the only pathway to set args, which
46     // in turn means that isOn() always returns false and so no code in this
47     // class does anything.
48     /*
49     static {
50         args = java.security.AccessController.doPrivileged
51                 (new sun.security.action.GetPropertyAction
52                 ("java.security.debug"));
53 
54         String args2 = java.security.AccessController.doPrivileged
55                 (new sun.security.action.GetPropertyAction
56                 ("java.security.auth.debug"));
57 
58         if (args == null) {
59             args = args2;
60         } else {
61             if (args2 != null)
62                args = args + "," + args2;
63         }
64 
65         if (args != null) {
66             args = marshal(args);
67             if (args.equals("help")) {
68                 Help();
69             }
70         }
71     }
72 
73         From public static void Help() : Serves as a documentation of the
74         values that "args" accepts.
75 
76         System.err.println();
77         System.err.println("all           turn on all debugging");
78         System.err.println("access        print all checkPermission results");
79         System.err.println("certpath      PKIX CertPathBuilder and");
80         System.err.println("              CertPathValidator debugging");
81         System.err.println("combiner      SubjectDomainCombiner debugging");
82         System.err.println("gssloginconfig");
83         System.err.println("              GSS LoginConfigImpl debugging");
84         System.err.println("configfile    JAAS ConfigFile loading");
85         System.err.println("configparser  JAAS ConfigFile parsing");
86         System.err.println("jar           jar verification");
87         System.err.println("logincontext  login context results");
88         System.err.println("jca           JCA engine class debugging");
89         System.err.println("policy        loading and granting");
90         System.err.println("provider      security provider debugging");
91         System.err.println("pkcs11        PKCS11 session manager debugging");
92         System.err.println("pkcs11keystore");
93         System.err.println("              PKCS11 KeyStore debugging");
94         System.err.println("sunpkcs11     SunPKCS11 provider debugging");
95         System.err.println("scl           permissions SecureClassLoader assigns");
96         System.err.println("ts            timestamping");
97         System.err.println();
98         System.err.println("The following can be used with access:");
99         System.err.println();
100         System.err.println("stack         include stack trace");
101         System.err.println("domain        dump all domains in context");
102         System.err.println("failure       before throwing exception, dump stack");
103         System.err.println("              and domain that didn't have permission");
104         System.err.println();
105         System.err.println("The following can be used with stack and domain:");
106         System.err.println();
107         System.err.println("permission=<classname>");
108         System.err.println("              only dump output if specified permission");
109         System.err.println("              is being checked");
110         System.err.println("codebase=<URL>");
111         System.err.println("              only dump output if specified codebase");
112         System.err.println("              is being checked");
113         System.err.println();
114         System.err.println("The following can be used with provider:");
115         System.err.println();
116         System.err.println("engine=<engines>");
117         System.err.println("              only dump output for the specified list");
118         System.err.println("              of JCA engines. Supported values:");
119         System.err.println("              Cipher, KeyAgreement, KeyGenerator,");
120         System.err.println("              KeyPairGenerator, KeyStore, Mac,");
121         System.err.println("              MessageDigest, SecureRandom, Signature.");
122         System.err.println();
123         System.err.println("Note: Separate multiple options with a comma");
124         System.exit(0);
125     */
126     // END Android-changed: Debug is stubbed and disabled on Android.
127 
128     /**
129      * Get a Debug object corresponding to whether or not the given
130      * option is set. Set the prefix to be the same as option.
131      */
132 
getInstance(String option)133     public static Debug getInstance(String option)
134     {
135         return getInstance(option, option);
136     }
137 
138     /**
139      * Get a Debug object corresponding to whether or not the given
140      * option is set. Set the prefix to be prefix.
141      */
getInstance(String option, String prefix)142     public static Debug getInstance(String option, String prefix)
143     {
144         if (isOn(option)) {
145             Debug d = new Debug();
146             d.prefix = prefix;
147             return d;
148         } else {
149             return null;
150         }
151     }
152 
153     /**
154      * True if the system property "security.debug" contains the
155      * string "option".
156      */
isOn(String option)157     public static boolean isOn(String option)
158     {
159         if (args == null)
160             return false;
161         else {
162             if (args.indexOf("all") != -1)
163                 return true;
164             else
165                 return (args.indexOf(option) != -1);
166         }
167     }
168 
169     /**
170      * print a message to stderr that is prefixed with the prefix
171      * created from the call to getInstance.
172      */
173 
println(String message)174     public void println(String message)
175     {
176         System.err.println(prefix + ": "+message);
177     }
178 
179     /**
180      * print a blank line to stderr that is prefixed with the prefix.
181      */
182 
println()183     public void println()
184     {
185         System.err.println(prefix + ":");
186     }
187 
188     // Android-removed: Nothing uses this code and it serves no purpose.
189     /**
190      * print a message to stderr that is prefixed with the prefix.
191      *
192 
193     public static void println(String prefix, String message)
194     {
195         System.err.println(prefix + ": "+message);
196     }
197      */
198 
199     /**
200      * return a hexadecimal printed representation of the specified
201      * BigInteger object. the value is formatted to fit on lines of
202      * at least 75 characters, with embedded newlines. Words are
203      * separated for readability, with eight words (32 bytes) per line.
204      */
toHexString(BigInteger b)205     public static String toHexString(BigInteger b) {
206         String hexValue = b.toString(16);
207         StringBuffer buf = new StringBuffer(hexValue.length()*2);
208 
209         if (hexValue.startsWith("-")) {
210             buf.append("   -");
211             hexValue = hexValue.substring(1);
212         } else {
213             buf.append("    ");     // four spaces
214         }
215         if ((hexValue.length()%2) != 0) {
216             // add back the leading 0
217             hexValue = "0" + hexValue;
218         }
219         int i=0;
220         while (i < hexValue.length()) {
221             // one byte at a time
222             buf.append(hexValue.substring(i, i+2));
223             i+=2;
224             if (i!= hexValue.length()) {
225                 if ((i%64) == 0) {
226                     buf.append("\n    ");     // line after eight words
227                 } else if (i%8 == 0) {
228                     buf.append(" ");     // space between words
229                 }
230             }
231         }
232         return buf.toString();
233     }
234 
235     /**
236      * change a string into lower case except permission classes and URLs.
237      */
marshal(String args)238     private static String marshal(String args) {
239         if (args != null) {
240             StringBuffer target = new StringBuffer();
241             StringBuffer source = new StringBuffer(args);
242 
243             // obtain the "permission=<classname>" options
244             // the syntax of classname: IDENTIFIER.IDENTIFIER
245             // the regular express to match a class name:
246             // "[a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*"
247             String keyReg = "[Pp][Ee][Rr][Mm][Ii][Ss][Ss][Ii][Oo][Nn]=";
248             String keyStr = "permission=";
249             String reg = keyReg +
250                 "[a-zA-Z_$][a-zA-Z0-9_$]*([.][a-zA-Z_$][a-zA-Z0-9_$]*)*";
251             Pattern pattern = Pattern.compile(reg);
252             Matcher matcher = pattern.matcher(source);
253             StringBuffer left = new StringBuffer();
254             while (matcher.find()) {
255                 String matched = matcher.group();
256                 target.append(matched.replaceFirst(keyReg, keyStr));
257                 target.append("  ");
258 
259                 // delete the matched sequence
260                 matcher.appendReplacement(left, "");
261             }
262             matcher.appendTail(left);
263             source = left;
264 
265             // obtain the "codebase=<URL>" options
266             // the syntax of URL is too flexible, and here assumes that the
267             // URL contains no space, comma(','), and semicolon(';'). That
268             // also means those characters also could be used as separator
269             // after codebase option.
270             // However, the assumption is incorrect in some special situation
271             // when the URL contains comma or semicolon
272             keyReg = "[Cc][Oo][Dd][Ee][Bb][Aa][Ss][Ee]=";
273             keyStr = "codebase=";
274             reg = keyReg + "[^, ;]*";
275             pattern = Pattern.compile(reg);
276             matcher = pattern.matcher(source);
277             left = new StringBuffer();
278             while (matcher.find()) {
279                 String matched = matcher.group();
280                 target.append(matched.replaceFirst(keyReg, keyStr));
281                 target.append("  ");
282 
283                 // delete the matched sequence
284                 matcher.appendReplacement(left, "");
285             }
286             matcher.appendTail(left);
287             source = left;
288 
289             // convert the rest to lower-case characters
290             target.append(source.toString().toLowerCase(Locale.ENGLISH));
291 
292             return target.toString();
293         }
294 
295         return null;
296     }
297 
298     private final static char[] hexDigits = "0123456789abcdef".toCharArray();
299 
toString(byte[] b)300     public static String toString(byte[] b) {
301         if (b == null) {
302             return "(null)";
303         }
304         StringBuilder sb = new StringBuilder(b.length * 3);
305         for (int i = 0; i < b.length; i++) {
306             int k = b[i] & 0xff;
307             if (i != 0) {
308                 sb.append(':');
309             }
310             sb.append(hexDigits[k >>> 4]);
311             sb.append(hexDigits[k & 0xf]);
312         }
313         return sb.toString();
314     }
315 
316 }
317