232 lines · 8.5 KB · Java
RawDownload
/* * Copyright (c) 2000, 2009, 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. */ package sun.security.jgss.krb5; import org.ietf.jgss.*;import sun.security.jgss.GSSUtil;import sun.security.jgss.GSSCaller;import sun.security.jgss.spi.*;import javax.security.auth.kerberos.ServicePermission;import java.security.Provider;import java.util.Vector; /** * Krb5 Mechanism plug in for JGSS * This is the properties object required by the JGSS framework. * All mechanism specific information is defined here. * * @author Mayank Upadhyay */ public final class Krb5MechFactory implements MechanismFactory {     private static final boolean DEBUG = Krb5Util.DEBUG;     static final Provider PROVIDER =        new sun.security.jgss.SunProvider();     static final Oid GSS_KRB5_MECH_OID =        createOid("1.2.840.113554.1.2.2");     static final Oid NT_GSS_KRB5_PRINCIPAL =        createOid("1.2.840.113554.1.2.2.1");     private static Oid[] nameTypes =        new Oid[] { GSSName.NT_USER_NAME,                        GSSName.NT_HOSTBASED_SERVICE,                        GSSName.NT_EXPORT_NAME,                        NT_GSS_KRB5_PRINCIPAL};     final private GSSCaller caller;     private static Krb5CredElement getCredFromSubject(GSSNameSpi name,                                                      boolean initiate)        throws GSSException {        Vector<Krb5CredElement> creds =            GSSUtil.searchSubject(name, GSS_KRB5_MECH_OID, initiate,                                  (initiate ?                                   Krb5InitCredential.class :                                   Krb5AcceptCredential.class));         Krb5CredElement result = ((creds == null || creds.isEmpty()) ?                                  null : creds.firstElement());         // Force permission check before returning the cred to caller        if (result != null) {            if (initiate) {                checkInitCredPermission((Krb5NameElement) result.getName());            } else {                checkAcceptCredPermission                    ((Krb5NameElement) result.getName(), name);            }        }        return result;    }     public Krb5MechFactory(GSSCaller caller) {        this.caller = caller;    }     public GSSNameSpi getNameElement(String nameStr, Oid nameType)        throws GSSException {        return Krb5NameElement.getInstance(nameStr, nameType);    }     public GSSNameSpi getNameElement(byte[] name, Oid nameType)        throws GSSException {        // At this point, even an exported name is stripped down to safe        // bytes only        // XXX Use encoding here        return Krb5NameElement.getInstance(new String(name), nameType);    }     public GSSCredentialSpi getCredentialElement(GSSNameSpi name,           int initLifetime, int acceptLifetime,           int usage) throws GSSException {         if (name != null && !(name instanceof Krb5NameElement)) {            name = Krb5NameElement.getInstance(name.toString(),                                       name.getStringNameType());        }         Krb5CredElement credElement = getCredFromSubject            (name, (usage != GSSCredential.ACCEPT_ONLY));         if (credElement == null) {            if (usage == GSSCredential.INITIATE_ONLY ||                usage == GSSCredential.INITIATE_AND_ACCEPT) {                credElement = Krb5InitCredential.getInstance                    (caller, (Krb5NameElement) name, initLifetime);                checkInitCredPermission                    ((Krb5NameElement) credElement.getName());            } else if (usage == GSSCredential.ACCEPT_ONLY) {                credElement =                    Krb5AcceptCredential.getInstance(caller,                                                     (Krb5NameElement) name);                checkAcceptCredPermission                    ((Krb5NameElement) credElement.getName(), name);            } else                throw new GSSException(GSSException.FAILURE, -1,                                       "Unknown usage mode requested");        }        return credElement;    }     public static void checkInitCredPermission(Krb5NameElement name) {        SecurityManager sm = System.getSecurityManager();        if (sm != null) {            String realm = (name.getKrb5PrincipalName()).getRealmAsString();            String tgsPrincipal =                new String("krbtgt/" + realm + '@' + realm);            ServicePermission perm =                new ServicePermission(tgsPrincipal, "initiate");            try {                sm.checkPermission(perm);            } catch (SecurityException e) {                if (DEBUG) {                    System.out.println("Permission to initiate" +                        "kerberos init credential" + e.getMessage());                }                throw e;            }        }    }     public static void checkAcceptCredPermission(Krb5NameElement name,                                           GSSNameSpi originalName) {        SecurityManager sm = System.getSecurityManager();        if (sm != null) {            ServicePermission perm = new ServicePermission                (name.getKrb5PrincipalName().getName(), "accept");            try {                sm.checkPermission(perm);            } catch (SecurityException e) {                if (originalName == null) {                    // Don't disclose the name of the principal                    e = new SecurityException("No permission to acquire "                                      + "Kerberos accept credential");                    // Don't call e.initCause() with caught exception                }                throw e;            }        }    }     public GSSContextSpi getMechanismContext(GSSNameSpi peer,                             GSSCredentialSpi myInitiatorCred, int lifetime)        throws GSSException {        if (peer != null && !(peer instanceof Krb5NameElement)) {            peer = Krb5NameElement.getInstance(peer.toString(),                                       peer.getStringNameType());        }        // XXX Convert myInitiatorCred to Krb5CredElement        if (myInitiatorCred == null) {            myInitiatorCred = getCredentialElement(null, lifetime, 0,                GSSCredential.INITIATE_ONLY);        }        return new Krb5Context(caller, (Krb5NameElement)peer,                               (Krb5CredElement)myInitiatorCred, lifetime);    }     public GSSContextSpi getMechanismContext(GSSCredentialSpi myAcceptorCred)        throws GSSException {        // XXX Convert myAcceptorCred to Krb5CredElement        if (myAcceptorCred == null) {            myAcceptorCred = getCredentialElement(null, 0,                GSSCredential.INDEFINITE_LIFETIME, GSSCredential.ACCEPT_ONLY);        }        return new Krb5Context(caller, (Krb5CredElement)myAcceptorCred);    }     public GSSContextSpi getMechanismContext(byte[] exportedContext)        throws GSSException {        return new Krb5Context(caller, exportedContext);    }      public final Oid getMechanismOid() {        return GSS_KRB5_MECH_OID;    }     public Provider getProvider() {        return PROVIDER;    }     public Oid[] getNameTypes() {        // nameTypes is cloned in GSSManager.getNamesForMech        return nameTypes;    }     private static Oid createOid(String oidStr) {        Oid retVal = null;        try {            retVal = new Oid(oidStr);        } catch (GSSException e) {            // Should not happen!        }        return retVal;    }}