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