545 lines · 18.2 KB · Java
RawDownload
/* * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * =========================================================================== *  (C) Copyright IBM Corp. 1999 All Rights Reserved. * *  Copyright 1997 The Open Group Research Institute.  All rights reserved. * =========================================================================== * */package sun.security.krb5.internal.ccache; import sun.security.krb5.*;import sun.security.krb5.internal.*;import java.util.StringTokenizer;import java.util.Vector;import java.io.IOException;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.BufferedReader;import java.io.InputStreamReader;import java.lang.reflect.*; /** * CredentialsCache stores credentials(tickets, session keys, etc) in a * semi-permanent store * for later use by different program. * * @author Yanni Zhang * @author Ram Marti */ public class FileCredentialsCache extends CredentialsCache    implements FileCCacheConstants {    public int version;    public Tag tag; // optional    public PrincipalName primaryPrincipal;    public Realm primaryRealm;    private Vector<Credentials> credentialsList;    private static String dir;    private static boolean DEBUG = Krb5.DEBUG;     public static synchronized FileCredentialsCache acquireInstance(                PrincipalName principal, String cache) {        try {            FileCredentialsCache fcc = new FileCredentialsCache();            if (cache == null) {                cacheName = fcc.getDefaultCacheName();            } else {                cacheName = fcc.checkValidation(cache);            }            if ((cacheName == null) || !(new File(cacheName)).exists()) {                // invalid cache name or the file doesn't exist                return null;            }            if (principal != null) {                fcc.primaryPrincipal = principal;                fcc.primaryRealm = principal.getRealm();            }            fcc.load(cacheName);            return fcc;        } catch (IOException e) {            // we don't handle it now, instead we return a null at the end.            if (DEBUG) {                e.printStackTrace();            }        } catch (KrbException e) {            // we don't handle it now, instead we return a null at the end.            if (DEBUG) {                e.printStackTrace();            }        }        return null;    }     public static FileCredentialsCache acquireInstance() {        return acquireInstance(null, null);    }     static synchronized FileCredentialsCache New(PrincipalName principal,                                                String name) {        try {            FileCredentialsCache fcc = new FileCredentialsCache();            cacheName = fcc.checkValidation(name);            if (cacheName == null) {                // invalid cache name or the file doesn't exist                return null;            }            fcc.init(principal, cacheName);            return fcc;        }        catch (IOException e) {        }        catch (KrbException e) {        }        return null;    }     static synchronized FileCredentialsCache New(PrincipalName principal) {        try {            FileCredentialsCache fcc = new FileCredentialsCache();            cacheName = fcc.getDefaultCacheName();            fcc.init(principal, cacheName);            return fcc;        }        catch (IOException e) {            if (DEBUG) {                e.printStackTrace();            }        } catch (KrbException e) {            if (DEBUG) {                e.printStackTrace();            }         }        return null;    }     private FileCredentialsCache() {    }     boolean exists(String cache) {        File file = new File(cache);        if (file.exists()) {            return true;        } else return false;    }     synchronized void init(PrincipalName principal, String name)        throws IOException, KrbException {        primaryPrincipal = principal;        primaryRealm = principal.getRealm();        CCacheOutputStream cos =            new CCacheOutputStream(new FileOutputStream(name));        version = KRB5_FCC_FVNO_3;        cos.writeHeader(primaryPrincipal, version);        cos.close();        load(name);    }     synchronized void load(String name) throws IOException, KrbException {        PrincipalName p;        CCacheInputStream cis =            new CCacheInputStream(new FileInputStream(name));        version = cis.readVersion();        if (version == KRB5_FCC_FVNO_4) {            tag = cis.readTag();        } else {            tag = null;            if (version == KRB5_FCC_FVNO_1 || version == KRB5_FCC_FVNO_2) {                cis.setNativeByteOrder();            }        }        p = cis.readPrincipal(version);         if (primaryPrincipal != null) {            if (!(primaryPrincipal.match(p))) {                throw new IOException("Primary principals don't match.");            }        } else            primaryPrincipal = p;        primaryRealm = primaryPrincipal.getRealm();        credentialsList = new Vector<Credentials> ();        while (cis.available() > 0) {            Credentials cred = cis.readCred(version);            if (cred != null) {                credentialsList.addElement(cred);            }        }        cis.close();    }      /**     * Updates the credentials list. If the specified credentials for the     * service is new, add it to the list. If there is an entry in the list,     * replace the old credentials with the new one.     * @param c the credentials.     */     public synchronized void update(Credentials c) {        if (credentialsList != null) {            if (credentialsList.isEmpty()) {                credentialsList.addElement(c);            } else {                Credentials tmp = null;                boolean matched = false;                 for (int i = 0; i < credentialsList.size(); i++) {                    tmp = credentialsList.elementAt(i);                    if (match(c.sname.getNameStrings(),                              tmp.sname.getNameStrings()) &&                        ((c.sname.getRealmString()).equalsIgnoreCase(                                     tmp.sname.getRealmString()))) {                        matched = true;                        if (c.endtime.getTime() >= tmp.endtime.getTime()) {                            if (DEBUG) {                                System.out.println(" >>> FileCredentialsCache "                                         +  "Ticket matched, overwrite "                                         +  "the old one.");                            }                            credentialsList.removeElementAt(i);                            credentialsList.addElement(c);                        }                    }                }                if (matched == false) {                    if (DEBUG) {                        System.out.println(" >>> FileCredentialsCache Ticket "                                        +   "not exactly matched, "                                        +   "add new one into cache.");                    }                     credentialsList.addElement(c);                }            }        }    }     public synchronized PrincipalName getPrimaryPrincipal() {        return primaryPrincipal;    }      /**     * Saves the credentials cache file to the disk.     */    public synchronized void save() throws IOException, Asn1Exception {        CCacheOutputStream cos            = new CCacheOutputStream(new FileOutputStream(cacheName));        cos.writeHeader(primaryPrincipal, version);        Credentials[] tmp = null;        if ((tmp = getCredsList()) != null) {            for (int i = 0; i < tmp.length; i++) {                cos.addCreds(tmp[i]);            }        }        cos.close();    }     boolean match(String[] s1, String[] s2) {        if (s1.length != s2.length) {            return false;        } else {            for (int i = 0; i < s1.length; i++) {                if (!(s1[i].equalsIgnoreCase(s2[i]))) {                    return false;                }            }        }        return true;    }     /**     * Returns the list of credentials entries in the cache file.     */    public synchronized Credentials[] getCredsList() {        if ((credentialsList == null) || (credentialsList.isEmpty())) {            return null;        } else {            Credentials[] tmp = new Credentials[credentialsList.size()];            for (int i = 0; i < credentialsList.size(); i++) {                tmp[i] = credentialsList.elementAt(i);            }            return tmp;        }     }     public Credentials getCreds(LoginOptions options,                                PrincipalName sname, Realm srealm) {        if (options == null) {            return getCreds(sname, srealm);        } else {            Credentials[] list = getCredsList();            if (list == null) {                return null;            } else {                for (int i = 0; i < list.length; i++) {                    if (sname.match(list[i].sname) &&                        (srealm.toString().equals(list[i].srealm.toString()))) {                        if (list[i].flags.match(options)) {                            return list[i];                        }                    }                }            }            return null;        }    }      /**     * Gets a credentials for a specified service.     * @param sname service principal name.     * @param srealm the realm that the service belongs to.     */    public Credentials getCreds(PrincipalName sname, Realm srealm) {        Credentials[] list = getCredsList();        if (list == null) {            return null;        } else {            for (int i = 0; i < list.length; i++) {                if (sname.match(list[i].sname) &&                    (srealm.toString().equals(list[i].srealm.toString()))) {                    return list[i];                }            }        }        return null;    }     public Credentials getDefaultCreds() {        Credentials[] list = getCredsList();        if (list == null) {            return null;        } else {            for (int i = list.length-1; i >= 0; i--) {                if (list[i].sname.toString().startsWith("krbtgt")) {                    String[] nameStrings = list[i].sname.getNameStrings();                    // find the TGT for the current realm krbtgt/realm@realm                    if (nameStrings[1].equals(list[i].srealm.toString())) {                       return list[i];                    }                }            }        }        return null;    }     /*     * Returns path name of the credentials cache file.     * The path name is searched in the following order:     *     * 1. KRB5CCNAME     * 2. /tmp/krb5cc_<uid> on unix systems     * 3. <user.home>/krb5cc_<user.name>     * 4. <user.home>/krb5cc (if can't get <user.name>)     */     public static String getDefaultCacheName() {         String stdCacheNameComponent = "krb5cc";        String name;         name = java.security.AccessController.doPrivileged(                new java.security.PrivilegedAction<String>() {            @Override            public String run() {                return System.getenv("KRB5CCNAME");            }        });        if (name != null) {            if (DEBUG) {                System.out.println(">>>KinitOptions cache name is " + name);            }            return name;        }         // get cache name from system.property        String osname =            java.security.AccessController.doPrivileged(                        new sun.security.action.GetPropertyAction("os.name"));         /*         * For Unix platforms we use the default cache name to be         * /tmp/krbcc_uid ; for all other platforms  we use         * {user_home}/krb5_cc{user_name}         * Please note that for Windows 2K we will use LSA to get         * the TGT from the the default cache even before we come here;         * however when we create cache we will create a cache under         * {user_home}/krb5_cc{user_name} for non-Unix platforms including         * Windows 2K.         */         if (osname != null) {            String cmd = null;            String uidStr = null;            long uid = 0;             if (osname.startsWith("SunOS") ||                (osname.startsWith("Linux"))) {                try {                    Class<?> c = Class.forName                        ("com.sun.security.auth.module.UnixSystem");                    Constructor<?> constructor = c.getConstructor();                    Object obj = constructor.newInstance();                    Method method = c.getMethod("getUid");                    uid =  ((Long)method.invoke(obj)).longValue();                    name = File.separator + "tmp" +                        File.separator + stdCacheNameComponent + "_" + uid;                    if (DEBUG) {                        System.out.println(">>>KinitOptions cache name is " +                                           name);                    }                    return name;                } catch (Exception e) {                    if (DEBUG) {                        System.out.println("Exception in obtaining uid " +                                            "for Unix platforms " +                                            "Using user's home directory");                          e.printStackTrace();                    }                }            }        }         // we did not get the uid;          String user_name =            java.security.AccessController.doPrivileged(                        new sun.security.action.GetPropertyAction("user.name"));         String user_home =            java.security.AccessController.doPrivileged(                        new sun.security.action.GetPropertyAction("user.home"));         if (user_home == null) {            user_home =                java.security.AccessController.doPrivileged(                        new sun.security.action.GetPropertyAction("user.dir"));        }         if (user_name != null) {            name = user_home + File.separator  +                stdCacheNameComponent + "_" + user_name;        } else {            name = user_home + File.separator + stdCacheNameComponent;        }         if (DEBUG) {            System.out.println(">>>KinitOptions cache name is " + name);        }         return name;    }     public static String checkValidation(String name) {        String fullname = null;        if (name == null) {            return null;        }        try {            // get full path name            fullname = (new File(name)).getCanonicalPath();            File fCheck = new File(fullname);            if (!(fCheck.exists())) {                // get absolute directory                File temp = new File(fCheck.getParent());                // test if the directory exists                if (!(temp.isDirectory()))                    fullname = null;                temp = null;            }            fCheck = null;         } catch (IOException e) {            fullname = null; // invalid name        }        return fullname;    }      private static String exec(String c) {        StringTokenizer st = new StringTokenizer(c);        Vector<String> v = new Vector<>();        while (st.hasMoreTokens()) {            v.addElement(st.nextToken());        }        final String[] command = new String[v.size()];        v.copyInto(command);        try { 

Lines 1–500 of 545.