1314 lines · 47.9 KB · Java
RawDownload
     *          default_realm = EXAMPLE.COM     *          default_tgs_enctypes = des-cbc-md5     *          default_tkt_enctypes = des-cbc-md5     * [realms]     *          EXAMPLE.COM = {     *                  kdc = kerberos.example.com     *                  kdc = kerberos-1.example.com     *                  admin_server = kerberos.example.com     *                  }     *          SAMPLE_COM = {     *                  kdc = orange.sample.com     *                  admin_server = orange.sample.com     *                  }     * [domain_realm]     *          blue.sample.com = TEST.SAMPLE.COM     *          .backup.com     = EXAMPLE.COM     */    private Vector<String> loadConfigFile() throws IOException {        try {            final String fileName = getFileName();            if (!fileName.equals("")) {                BufferedReader br = new BufferedReader(new InputStreamReader(                java.security.AccessController.doPrivileged(                new java.security.PrivilegedExceptionAction<FileInputStream> () {                public FileInputStream run() throws IOException {                    return new FileInputStream(fileName);                }                })));                String Line;                Vector<String> v = new Vector<>();                String previous = null;                while ((Line = br.readLine()) != null) {                    // ignore comments and blank line in the configuration file.                    // Comments start with #.                    if (!(Line.startsWith("#") || Line.trim().isEmpty())) {                        String current = Line.trim();                        // In practice, a subsection might look like:                        //      EXAMPLE.COM =                        //      {                        //              kdc = kerberos.example.com                        //              ...                        //      }                        // Before parsed into stanza table, it needs to be                        // converted into formal style:                        //      EXAMPLE.COM = {                        //              kdc = kerberos.example.com                        //              ...                        //      }                        //                        // So, if a line is "{", adhere to the previous line.                        if (current.equals("{")) {                            if (previous == null) {                                throw new IOException(                                    "Config file should not start with \"{\"");                            }                            previous += " " + current;                        } else {                            if (previous != null) {                                v.addElement(previous);                            }                            previous = current;                        }                    }                }                if (previous != null) {                    v.addElement(previous);                }                 br.close();                return v;            }            return null;        } catch (java.security.PrivilegedActionException pe) {            throw (IOException)pe.getException();        }    }      /**     * Parses stanza names and values from configuration file to     * stanzaTable (Hashtable). Hashtable key would be stanza names,     * (libdefaults, realms, domain_realms, etc), and the hashtable value     * would be another hashtable which contains the key-value pairs under     * a stanza name.     */    private Hashtable<String,Object> parseStanzaTable(Vector<String> v) throws KrbException {        if (v == null) {            throw new KrbException("I/O error while reading" +                        " configuration file.");        }        Hashtable<String,Object> table = new Hashtable<>();        for (int i = 0; i < v.size(); i++) {            String line = v.elementAt(i).trim();            if (line.equalsIgnoreCase("[realms]")) {                for (int count = i + 1; count < v.size() + 1; count++) {                    // find the next stanza name                    if ((count == v.size()) ||                        (v.elementAt(count).startsWith("["))) {                        Hashtable<String,Hashtable<String,Vector<String>>> temp =                            new Hashtable<>();                        temp = parseRealmField(v, i + 1, count);                        table.put("realms", temp);                        i = count - 1;                        break;                    }                }            } else if (line.equalsIgnoreCase("[capaths]")) {                for (int count = i + 1; count < v.size() + 1; count++) {                    // find the next stanza name                    if ((count == v.size()) ||                        (v.elementAt(count).startsWith("["))) {                        Hashtable<String,Hashtable<String,Vector<String>>> temp =                            new Hashtable<>();                        temp = parseRealmField(v, i + 1, count);                        table.put("capaths", temp);                        i = count - 1;                        break;                    }                }            } else if (line.startsWith("[") && line.endsWith("]")) {                String key = line.substring(1, line.length() - 1);                for (int count = i + 1; count < v.size() + 1; count++) {                    // find the next stanza name                    if ((count == v.size()) ||                        (v.elementAt(count).startsWith("["))) {                        Hashtable<String,String> temp =                            parseField(v, i + 1, count);                        table.put(key, temp);                        i = count - 1;                        break;                    }                }            }        }        return table;    }     /**     * Gets the default configuration file name. This method will never     * return null.     *     * If the system property "java.security.krb5.conf" is defined, we'll     * use its value, no matter if the file exists or not. Otherwise,     * the file will be searched in a list of possible loations in the     * following order:     *     * 1. at Java home lib\security directory with "krb5.conf" name,     * 2. at windows directory with the name of "krb5.ini" for Windows,     * /etc/krb5/krb5.conf for Solaris, /etc/krb5.conf otherwise.     *     * Note: When the Terminal Service is started in Windows (from 2003),     * there are two kinds of Windows directories: A system one (say,     * C:\Windows), and a user-private one (say, C:\Users\Me\Windows).     * We will first look for krb5.ini in the user-private one. If not     * found, try the system one instead.     */    private String getFileName() {        String name =            java.security.AccessController.doPrivileged(                                new sun.security.action.                                GetPropertyAction("java.security.krb5.conf"));        if (name == null) {            name = java.security.AccessController.doPrivileged(                        new sun.security.action.                        GetPropertyAction("java.home")) + File.separator +                                "lib" + File.separator + "security" +                                File.separator + "krb5.conf";            if (!fileExists(name)) {                name = null;                String osname =                        java.security.AccessController.doPrivileged(                        new sun.security.action.GetPropertyAction("os.name"));                if (osname.startsWith("Windows")) {                    try {                        Credentials.ensureLoaded();                    } catch (Exception e) {                        // ignore exceptions                    }                    if (Credentials.alreadyLoaded) {                        String path = getWindowsDirectory(false);                        if (path != null) {                            if (path.endsWith("\\")) {                                path = path + "krb5.ini";                            } else {                                path = path + "\\krb5.ini";                            }                            if (fileExists(path)) {                                name = path;                            }                        }                        if (name == null) {                            path = getWindowsDirectory(true);                            if (path != null) {                                if (path.endsWith("\\")) {                                    path = path + "krb5.ini";                                } else {                                    path = path + "\\krb5.ini";                                }                                name = path;                            }                        }                    }                    if (name == null) {                        name = "c:\\winnt\\krb5.ini";                    }                } else if (osname.startsWith("SunOS")) {                    name =  "/etc/krb5/krb5.conf";                } else {                    name =  "/etc/krb5.conf";                }            }        }        if (DEBUG) {            System.out.println("Config name: " + name);        }        return name;    }     private static String trimmed(String s) {        s = s.trim();        if (s.charAt(0) == '"' && s.charAt(s.length()-1) == '"' ||                s.charAt(0) == '\'' && s.charAt(s.length()-1) == '\'') {            s = s.substring(1, s.length()-1).trim();        }        return s;    }    /**     * Parses key-value pairs under a stanza name.     */    private Hashtable<String,String>  parseField(Vector<String> v, int start, int end) {        Hashtable<String,String> table = new Hashtable<>();        String line;        for (int i = start; i < end; i++) {            line = v.elementAt(i);            for (int j = 0; j < line.length(); j++) {                if (line.charAt(j) == '=') {                    String key = (line.substring(0, j)).trim();                    String value = trimmed(line.substring(j + 1));                    table.put(key, value);                    break;                }            }        }        return table;    }     /**     * Parses key-value pairs under [realms].  The key would be the realm     * name, the value would be another hashtable which contains     * information for the realm given within a pair of braces.     */    private Hashtable<String,Hashtable<String,Vector<String>>> parseRealmField(Vector<String> v, int start, int end) {        Hashtable<String,Hashtable<String,Vector<String>>> table = new Hashtable<>();        String line;        for (int i = start; i < end; i++) {            line = v.elementAt(i).trim();            if (line.endsWith("{")) {                String key = "";                for (int j = 0; j < line.length(); j++) {                    if (line.charAt(j) == '=') {                        key = line.substring(0, j).trim();                        // get the key                        break;                    }                }                for (int k = i + 1; k < end; k++) {                    boolean found = false;                    line = v.elementAt(k).trim();                    for (int l = 0; l < line.length(); l++) {                        if (line.charAt(l) == '}') {                            found = true;                            break;                        }                    }                    if (found == true) {                        Hashtable<String,Vector<String>> temp = parseRealmFieldEx(v, i + 1, k);                        table.put(key, temp);                        i = k;                        found = false;                        break;                    }                 }            }        }        return table;    }     /**     * Parses key-value pairs within each braces under [realms].     */    private Hashtable<String,Vector<String>> parseRealmFieldEx(Vector<String> v, int start, int end) {        Hashtable<String,Vector<String>> table = new Hashtable<>();        Vector<String> keyVector = new Vector<>();        Vector<String> nameVector = new Vector<>();        String line = "";        String key;        for (int i = start; i < end; i++) {            line = v.elementAt(i);            for (int j = 0; j < line.length(); j++) {                if (line.charAt(j) == '=') {                    int index;                    key = line.substring(0, j).trim();                    if (! exists(key, keyVector)) {                        keyVector.addElement(key);                        nameVector = new Vector<String> ();                    } else {                        nameVector = table.get(key);                    }                    nameVector.addElement(trimmed(line.substring(j + 1)));                    table.put(key, nameVector);                    break;                }            }        }        return table;    }     /**     * Compares the key with the known keys to see if it exists.     */    private boolean exists(String key, Vector v) {        boolean exists = false;        for (int i = 0; i < v.size(); i++) {            if (((String)(v.elementAt(i))).equals(key)) {                exists = true;            }        }        return exists;    }     /**     * For testing purpose. This method lists all information being parsed from     * the configuration file to the hashtable.     */    public void listTable() {        listTable(stanzaTable);    }     private void listTable(Hashtable table) {        Vector v = new Vector();        String key;        if (stanzaTable != null) {            for (Enumeration e = table.keys(); e.hasMoreElements(); ) {                key = (String)e.nextElement();                Object object = table.get(key);                if (table == stanzaTable) {                    System.out.println("[" + key + "]");                }                if (object instanceof Hashtable) {                    if (table != stanzaTable)                        System.out.println("\t" + key + " = {");                    listTable((Hashtable)object);                    if (table != stanzaTable)                        System.out.println("\t}");                 } else if (object instanceof String) {                    System.out.println("\t" + key + " = " +                                (String)table.get(key));                } else if (object instanceof Vector) {                    v = (Vector)object;                    for (int i = 0; i < v.size(); i++) {                        System.out.println("\t" + key + " = " +                                (String)v.elementAt(i));                    }                }            }        } else {            System.out.println("Configuration file not found.");        }    }     /**     * Returns the default encryption types.     *     */    public int[] defaultEtype(String enctypes) {        String default_enctypes;        default_enctypes = getDefault(enctypes, "libdefaults");        String delim = " ";        StringTokenizer st;        int[] etype;        if (default_enctypes == null) {            if (DEBUG) {                System.out.println("Using builtin default etypes for " +                    enctypes);            }            etype = EType.getBuiltInDefaults();        } else {            for (int j = 0; j < default_enctypes.length(); j++) {                if (default_enctypes.substring(j, j + 1).equals(",")) {                    // only two delimiters are allowed to use                    // according to Kerberos DCE doc.                    delim = ",";                    break;                }            }            st = new StringTokenizer(default_enctypes, delim);            int len = st.countTokens();            ArrayList<Integer> ls = new ArrayList<>(len);            int type;            for (int i = 0; i < len; i++) {                type = getType(st.nextToken());                if ((type != -1) &&                    (EType.isSupported(type))) {                    ls.add(type);                }            }            if (ls.size() == 0) {                if (DEBUG) {                    System.out.println(                        "no supported default etypes for " + enctypes);                }                return null;            } else {                etype = new int[ls.size()];                for (int i = 0; i < etype.length; i++) {                    etype[i] = ls.get(i);                }            }        }         if (DEBUG) {            System.out.print("default etypes for " + enctypes + ":");            for (int i = 0; i < etype.length; i++) {                System.out.print(" " + etype[i]);            }            System.out.println(".");        }        return etype;    }      /**     * Get the etype and checksum value for the specified encryption and     * checksum type.     *     */    /*     * This method converts the string representation of encryption type and     * checksum type to int value that can be later used by EType and     * Checksum classes.     */    public int getType(String input) {        int result = -1;        if (input == null) {            return result;        }        if (input.startsWith("d") || (input.startsWith("D"))) {            if (input.equalsIgnoreCase("des-cbc-crc")) {                result = EncryptedData.ETYPE_DES_CBC_CRC;            } else if (input.equalsIgnoreCase("des-cbc-md5")) {                result = EncryptedData.ETYPE_DES_CBC_MD5;            } else if (input.equalsIgnoreCase("des-mac")) {                result = Checksum.CKSUMTYPE_DES_MAC;            } else if (input.equalsIgnoreCase("des-mac-k")) {                result = Checksum.CKSUMTYPE_DES_MAC_K;            } else if (input.equalsIgnoreCase("des-cbc-md4")) {                result = EncryptedData.ETYPE_DES_CBC_MD4;            } else if (input.equalsIgnoreCase("des3-cbc-sha1") ||                input.equalsIgnoreCase("des3-hmac-sha1") ||                input.equalsIgnoreCase("des3-cbc-sha1-kd") ||                input.equalsIgnoreCase("des3-cbc-hmac-sha1-kd")) {                result = EncryptedData.ETYPE_DES3_CBC_HMAC_SHA1_KD;            }        } else if (input.startsWith("a") || (input.startsWith("A"))) {            // AES            if (input.equalsIgnoreCase("aes128-cts") ||                input.equalsIgnoreCase("aes128-cts-hmac-sha1-96")) {                result = EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96;            } else if (input.equalsIgnoreCase("aes256-cts") ||                input.equalsIgnoreCase("aes256-cts-hmac-sha1-96")) {                result = EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96;            // ARCFOUR-HMAC            } else if (input.equalsIgnoreCase("arcfour-hmac") ||                   input.equalsIgnoreCase("arcfour-hmac-md5")) {                result = EncryptedData.ETYPE_ARCFOUR_HMAC;            }        // RC4-HMAC        } else if (input.equalsIgnoreCase("rc4-hmac")) {            result = EncryptedData.ETYPE_ARCFOUR_HMAC;        } else if (input.equalsIgnoreCase("CRC32")) {            result = Checksum.CKSUMTYPE_CRC32;        } else if (input.startsWith("r") || (input.startsWith("R"))) {            if (input.equalsIgnoreCase("rsa-md5")) {                result = Checksum.CKSUMTYPE_RSA_MD5;            } else if (input.equalsIgnoreCase("rsa-md5-des")) {                result = Checksum.CKSUMTYPE_RSA_MD5_DES;            }        } else if (input.equalsIgnoreCase("hmac-sha1-des3-kd")) {            result = Checksum.CKSUMTYPE_HMAC_SHA1_DES3_KD;        } else if (input.equalsIgnoreCase("hmac-sha1-96-aes128")) {            result = Checksum.CKSUMTYPE_HMAC_SHA1_96_AES128;        } else if (input.equalsIgnoreCase("hmac-sha1-96-aes256")) {            result = Checksum.CKSUMTYPE_HMAC_SHA1_96_AES256;        } else if (input.equalsIgnoreCase("hmac-md5-rc4") ||                input.equalsIgnoreCase("hmac-md5-arcfour") ||                input.equalsIgnoreCase("hmac-md5-enc")) {            result = Checksum.CKSUMTYPE_HMAC_MD5_ARCFOUR;        } else if (input.equalsIgnoreCase("NULL")) {

Lines 501–1000 of 1314. Previous lines