Home | History | Annotate | Download | only in util
      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 
     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 
    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      */
    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      */
    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 
    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 
    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      */
    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      */
    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 
    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