001: /*
002: * Copyright 2005-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.security.jgss.wrapper;
027:
028: import java.io.UnsupportedEncodingException;
029: import java.security.AccessController;
030: import java.security.AccessControlContext;
031: import java.security.PrivilegedAction;
032: import java.security.Provider;
033: import java.util.Set;
034: import java.util.Vector;
035: import java.util.Iterator;
036: import javax.security.auth.Subject;
037: import javax.security.auth.kerberos.*;
038: import org.ietf.jgss.*;
039: import sun.security.jgss.GSSUtil;
040: import sun.security.jgss.GSSExceptionImpl;
041: import sun.security.jgss.spi.*;
042:
043: /**
044: * JGSS plugin for generic mechanisms provided through native GSS framework.
045: *
046: * @author Valerie Peng
047: * @version 1.16, 05/05/07
048: */
049:
050: public final class NativeGSSFactory implements MechanismFactory {
051:
052: GSSLibStub cStub = null;
053:
054: private GSSCredElement getCredFromSubject(GSSNameElement name,
055: boolean initiate) throws GSSException {
056: Oid mech = cStub.getMech();
057: Vector<GSSCredElement> creds = GSSUtil.searchSubject(name,
058: mech, initiate, GSSCredElement.class);
059:
060: // If Subject is present but no native creds available
061: if (creds != null && creds.isEmpty()) {
062: if (GSSUtil.useSubjectCredsOnly()) {
063: throw new GSSException(GSSException.NO_CRED);
064: }
065: }
066:
067: GSSCredElement result = ((creds == null || creds.isEmpty()) ? null
068: : creds.firstElement());
069: // Force permission check before returning the cred to caller
070: if (result != null) {
071: result.doServicePermCheck();
072: }
073: return result;
074: }
075:
076: public NativeGSSFactory(int caller) {
077: // Ignore caller at the moment
078: // Have to call setMech(Oid) explicitly before calling other
079: // methods. Otherwise, NPE may be thrown unexpectantly
080: }
081:
082: public void setMech(Oid mech) throws GSSException {
083: cStub = GSSLibStub.getInstance(mech);
084: }
085:
086: public GSSNameSpi getNameElement(String nameStr, Oid nameType)
087: throws GSSException {
088: try {
089: byte[] nameBytes = (nameStr == null ? null : nameStr
090: .getBytes("UTF-8"));
091: return new GSSNameElement(nameBytes, nameType, cStub);
092: } catch (UnsupportedEncodingException uee) {
093: // Shouldn't happen
094: throw new GSSExceptionImpl(GSSException.FAILURE, uee);
095: }
096: }
097:
098: public GSSNameSpi getNameElement(byte[] name, Oid nameType)
099: throws GSSException {
100: return new GSSNameElement(name, nameType, cStub);
101: }
102:
103: public GSSCredentialSpi getCredentialElement(GSSNameSpi name,
104: int initLifetime, int acceptLifetime, int usage)
105: throws GSSException {
106: GSSNameElement nname = null;
107: if (name != null && !(name instanceof GSSNameElement)) {
108: nname = (GSSNameElement) getNameElement(name.toString(),
109: name.getStringNameType());
110: } else
111: nname = (GSSNameElement) name;
112:
113: if (usage == GSSCredential.INITIATE_AND_ACCEPT) {
114: // Force separate acqusition of cred element since
115: // MIT's impl does not correctly report NO_CRED error.
116: usage = GSSCredential.INITIATE_ONLY;
117: }
118:
119: GSSCredElement credElement = getCredFromSubject(
120: (GSSNameElement) nname,
121: (usage == GSSCredential.INITIATE_ONLY));
122:
123: if (credElement == null) {
124: // No cred in the Subject
125: if (usage == GSSCredential.INITIATE_ONLY) {
126: credElement = new GSSCredElement(nname, initLifetime,
127: usage, cStub);
128: } else if (usage == GSSCredential.ACCEPT_ONLY) {
129: if (nname == null) {
130: nname = GSSNameElement.DEF_ACCEPTOR;
131: }
132: credElement = new GSSCredElement(nname, acceptLifetime,
133: usage, cStub);
134: } else {
135: throw new GSSException(GSSException.FAILURE, -1,
136: "Unknown usage mode requested");
137: }
138: }
139: return credElement;
140: }
141:
142: public GSSContextSpi getMechanismContext(GSSNameSpi peer,
143: GSSCredentialSpi myCred, int lifetime) throws GSSException {
144: if (peer == null) {
145: throw new GSSException(GSSException.BAD_NAME);
146: } else if (!(peer instanceof GSSNameElement)) {
147: peer = (GSSNameElement) getNameElement(peer.toString(),
148: peer.getStringNameType());
149: }
150: if (myCred == null) {
151: myCred = getCredFromSubject(null, true);
152: } else if (!(myCred instanceof GSSCredElement)) {
153: throw new GSSException(GSSException.NO_CRED);
154: }
155: return new NativeGSSContext((GSSNameElement) peer,
156: (GSSCredElement) myCred, lifetime, cStub);
157: }
158:
159: public GSSContextSpi getMechanismContext(GSSCredentialSpi myCred)
160: throws GSSException {
161: if (myCred == null) {
162: myCred = getCredFromSubject(null, false);
163: } else if (!(myCred instanceof GSSCredElement)) {
164: throw new GSSException(GSSException.NO_CRED);
165: }
166: return new NativeGSSContext((GSSCredElement) myCred, cStub);
167: }
168:
169: public GSSContextSpi getMechanismContext(byte[] exportedContext)
170: throws GSSException {
171: return cStub.importContext(exportedContext);
172: }
173:
174: public final Oid getMechanismOid() {
175: return cStub.getMech();
176: }
177:
178: public Provider getProvider() {
179: return SunNativeProvider.INSTANCE;
180: }
181:
182: public Oid[] getNameTypes() throws GSSException {
183: return cStub.inquireNamesForMech();
184: }
185: }
|