| /* |
| * Copyright (c) 2005, 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.spnego; |
| |
| import org.ietf.jgss.*; |
| import sun.security.jgss.*; |
| import sun.security.jgss.spi.*; |
| import sun.security.jgss.krb5.Krb5MechFactory; |
| import sun.security.jgss.krb5.Krb5InitCredential; |
| import sun.security.jgss.krb5.Krb5AcceptCredential; |
| import sun.security.jgss.krb5.Krb5NameElement; |
| import java.security.Provider; |
| import java.util.Vector; |
| |
| /** |
| * SpNego Mechanism plug in for JGSS |
| * This is the properties object required by the JGSS framework. |
| * All mechanism specific information is defined here. |
| * |
| * @author Seema Malkani |
| * @since 1.6 |
| */ |
| |
| public final class SpNegoMechFactory implements MechanismFactory { |
| |
| static final Provider PROVIDER = |
| new sun.security.jgss.SunProvider(); |
| |
| static final Oid GSS_SPNEGO_MECH_OID = |
| GSSUtil.createOid("1.3.6.1.5.5.2"); |
| |
| private static Oid[] nameTypes = |
| new Oid[] { GSSName.NT_USER_NAME, |
| GSSName.NT_HOSTBASED_SERVICE, |
| GSSName.NT_EXPORT_NAME}; |
| |
| // The default underlying mech of SPNEGO, must not be SPNEGO itself. |
| private static final Oid DEFAULT_SPNEGO_MECH_OID = |
| ProviderList.DEFAULT_MECH_OID.equals(GSS_SPNEGO_MECH_OID)? |
| GSSUtil.GSS_KRB5_MECH_OID: |
| ProviderList.DEFAULT_MECH_OID; |
| |
| // Use an instance of a GSSManager whose provider list |
| // does not include native provider |
| final GSSManagerImpl manager; |
| final Oid[] availableMechs; |
| |
| private static SpNegoCredElement getCredFromSubject(GSSNameSpi name, |
| boolean initiate) |
| throws GSSException { |
| Vector<SpNegoCredElement> creds = |
| GSSUtil.searchSubject(name, GSS_SPNEGO_MECH_OID, |
| initiate, SpNegoCredElement.class); |
| |
| SpNegoCredElement result = ((creds == null || creds.isEmpty()) ? |
| null : creds.firstElement()); |
| |
| // Force permission check before returning the cred to caller |
| if (result != null) { |
| GSSCredentialSpi cred = result.getInternalCred(); |
| if (GSSUtil.isKerberosMech(cred.getMechanism())) { |
| if (initiate) { |
| Krb5InitCredential krbCred = (Krb5InitCredential) cred; |
| Krb5MechFactory.checkInitCredPermission |
| ((Krb5NameElement) krbCred.getName()); |
| } else { |
| Krb5AcceptCredential krbCred = (Krb5AcceptCredential) cred; |
| Krb5MechFactory.checkAcceptCredPermission |
| ((Krb5NameElement) krbCred.getName(), name); |
| } |
| } |
| } |
| return result; |
| } |
| |
| public SpNegoMechFactory(GSSCaller caller) { |
| manager = new GSSManagerImpl(caller, false); |
| Oid[] mechs = manager.getMechs(); |
| availableMechs = new Oid[mechs.length-1]; |
| for (int i = 0, j = 0; i < mechs.length; i++) { |
| // Skip SpNego mechanism |
| if (!mechs[i].equals(GSS_SPNEGO_MECH_OID)) { |
| availableMechs[j++] = mechs[i]; |
| } |
| } |
| // Move the preferred mech to first place |
| for (int i=0; i<availableMechs.length; i++) { |
| if (availableMechs[i].equals(DEFAULT_SPNEGO_MECH_OID)) { |
| if (i != 0) { |
| availableMechs[i] = availableMechs[0]; |
| availableMechs[0] = DEFAULT_SPNEGO_MECH_OID; |
| } |
| break; |
| } |
| } |
| } |
| |
| public GSSNameSpi getNameElement(String nameStr, Oid nameType) |
| throws GSSException { |
| return manager.getNameElement( |
| nameStr, nameType, DEFAULT_SPNEGO_MECH_OID); |
| } |
| |
| public GSSNameSpi getNameElement(byte[] name, Oid nameType) |
| throws GSSException { |
| return manager.getNameElement(name, nameType, DEFAULT_SPNEGO_MECH_OID); |
| } |
| |
| public GSSCredentialSpi getCredentialElement(GSSNameSpi name, |
| int initLifetime, int acceptLifetime, |
| int usage) throws GSSException { |
| |
| SpNegoCredElement credElement = getCredFromSubject |
| (name, (usage != GSSCredential.ACCEPT_ONLY)); |
| |
| if (credElement == null) { |
| // get CredElement for the default Mechanism |
| credElement = new SpNegoCredElement |
| (manager.getCredentialElement(name, initLifetime, |
| acceptLifetime, null, usage)); |
| } |
| return credElement; |
| } |
| |
| public GSSContextSpi getMechanismContext(GSSNameSpi peer, |
| GSSCredentialSpi myInitiatorCred, int lifetime) |
| throws GSSException { |
| // get SpNego mechanism context |
| if (myInitiatorCred == null) { |
| myInitiatorCred = getCredFromSubject(null, true); |
| } else if (!(myInitiatorCred instanceof SpNegoCredElement)) { |
| // convert to SpNegoCredElement |
| SpNegoCredElement cred = new SpNegoCredElement(myInitiatorCred); |
| return new SpNegoContext(this, peer, cred, lifetime); |
| } |
| return new SpNegoContext(this, peer, myInitiatorCred, lifetime); |
| } |
| |
| public GSSContextSpi getMechanismContext(GSSCredentialSpi myAcceptorCred) |
| throws GSSException { |
| // get SpNego mechanism context |
| if (myAcceptorCred == null) { |
| myAcceptorCred = getCredFromSubject(null, false); |
| } else if (!(myAcceptorCred instanceof SpNegoCredElement)) { |
| // convert to SpNegoCredElement |
| SpNegoCredElement cred = new SpNegoCredElement(myAcceptorCred); |
| return new SpNegoContext(this, cred); |
| } |
| return new SpNegoContext(this, myAcceptorCred); |
| } |
| |
| public GSSContextSpi getMechanismContext(byte[] exportedContext) |
| throws GSSException { |
| // get SpNego mechanism context |
| return new SpNegoContext(this, exportedContext); |
| } |
| |
| public final Oid getMechanismOid() { |
| return GSS_SPNEGO_MECH_OID; |
| } |
| |
| public Provider getProvider() { |
| return PROVIDER; |
| } |
| |
| public Oid[] getNameTypes() { |
| // nameTypes is cloned in GSSManager.getNamesForMech |
| return nameTypes; |
| } |
| } |