1 /* 2 * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.security.jgss.wrapper; 27 28 import java.io.UnsupportedEncodingException; 29 import java.security.Provider; 30 import java.util.Vector; 31 import org.ietf.jgss.*; 32 import sun.security.jgss.GSSUtil; 33 import sun.security.jgss.GSSCaller; 34 import sun.security.jgss.GSSExceptionImpl; 35 import sun.security.jgss.spi.*; 36 37 /** 38 * JGSS plugin for generic mechanisms provided through native GSS framework. 39 * 40 * @author Valerie Peng 41 */ 42 43 public final class NativeGSSFactory implements MechanismFactory { 44 45 GSSLibStub cStub = null; 46 private final GSSCaller caller; 47 getCredFromSubject(GSSNameElement name, boolean initiate)48 private GSSCredElement getCredFromSubject(GSSNameElement name, 49 boolean initiate) 50 throws GSSException { 51 Oid mech = cStub.getMech(); 52 Vector<GSSCredElement> creds = GSSUtil.searchSubject 53 (name, mech, initiate, GSSCredElement.class); 54 55 // If Subject is present but no native creds available 56 if (creds != null && creds.isEmpty()) { 57 if (GSSUtil.useSubjectCredsOnly(caller)) { 58 throw new GSSException(GSSException.NO_CRED); 59 } 60 } 61 62 GSSCredElement result = ((creds == null || creds.isEmpty()) ? 63 null : creds.firstElement()); 64 // Force permission check before returning the cred to caller 65 if (result != null) { 66 result.doServicePermCheck(); 67 } 68 return result; 69 } 70 NativeGSSFactory(GSSCaller caller)71 public NativeGSSFactory(GSSCaller caller) { 72 this.caller = caller; 73 // Have to call setMech(Oid) explicitly before calling other 74 // methods. Otherwise, NPE may be thrown unexpectantly 75 } 76 setMech(Oid mech)77 public void setMech(Oid mech) throws GSSException { 78 cStub = GSSLibStub.getInstance(mech); 79 } 80 getNameElement(String nameStr, Oid nameType)81 public GSSNameSpi getNameElement(String nameStr, Oid nameType) 82 throws GSSException { 83 try { 84 byte[] nameBytes = 85 (nameStr == null ? null : nameStr.getBytes("UTF-8")); 86 return new GSSNameElement(nameBytes, nameType, cStub); 87 } catch (UnsupportedEncodingException uee) { 88 // Shouldn't happen 89 throw new GSSExceptionImpl(GSSException.FAILURE, uee); 90 } 91 } 92 getNameElement(byte[] name, Oid nameType)93 public GSSNameSpi getNameElement(byte[] name, Oid nameType) 94 throws GSSException { 95 return new GSSNameElement(name, nameType, cStub); 96 } 97 getCredentialElement(GSSNameSpi name, int initLifetime, int acceptLifetime, int usage)98 public GSSCredentialSpi getCredentialElement(GSSNameSpi name, 99 int initLifetime, 100 int acceptLifetime, 101 int usage) 102 throws GSSException { 103 GSSNameElement nname = null; 104 if (name != null && !(name instanceof GSSNameElement)) { 105 nname = (GSSNameElement) 106 getNameElement(name.toString(), name.getStringNameType()); 107 } else nname = (GSSNameElement) name; 108 109 if (usage == GSSCredential.INITIATE_AND_ACCEPT) { 110 // Force separate acqusition of cred element since 111 // MIT's impl does not correctly report NO_CRED error. 112 usage = GSSCredential.INITIATE_ONLY; 113 } 114 115 GSSCredElement credElement = 116 getCredFromSubject(nname, (usage == GSSCredential.INITIATE_ONLY)); 117 118 if (credElement == null) { 119 // No cred in the Subject 120 if (usage == GSSCredential.INITIATE_ONLY) { 121 credElement = new GSSCredElement(nname, initLifetime, 122 usage, cStub); 123 } else if (usage == GSSCredential.ACCEPT_ONLY) { 124 if (nname == null) { 125 nname = GSSNameElement.DEF_ACCEPTOR; 126 } 127 credElement = new GSSCredElement(nname, acceptLifetime, 128 usage, cStub); 129 } else { 130 throw new GSSException(GSSException.FAILURE, -1, 131 "Unknown usage mode requested"); 132 } 133 } 134 return credElement; 135 } 136 getMechanismContext(GSSNameSpi peer, GSSCredentialSpi myCred, int lifetime)137 public GSSContextSpi getMechanismContext(GSSNameSpi peer, 138 GSSCredentialSpi myCred, 139 int lifetime) 140 throws GSSException { 141 if (peer == null) { 142 throw new GSSException(GSSException.BAD_NAME); 143 } else if (!(peer instanceof GSSNameElement)) { 144 peer = (GSSNameElement) 145 getNameElement(peer.toString(), peer.getStringNameType()); 146 } 147 if (myCred == null) { 148 myCred = getCredFromSubject(null, true); 149 } else if (!(myCred instanceof GSSCredElement)) { 150 throw new GSSException(GSSException.NO_CRED); 151 } 152 return new NativeGSSContext((GSSNameElement) peer, 153 (GSSCredElement) myCred, 154 lifetime, cStub); 155 } 156 getMechanismContext(GSSCredentialSpi myCred)157 public GSSContextSpi getMechanismContext(GSSCredentialSpi myCred) 158 throws GSSException { 159 if (myCred == null) { 160 myCred = getCredFromSubject(null, false); 161 } else if (!(myCred instanceof GSSCredElement)) { 162 throw new GSSException(GSSException.NO_CRED); 163 } 164 return new NativeGSSContext((GSSCredElement) myCred, cStub); 165 } 166 getMechanismContext(byte[] exportedContext)167 public GSSContextSpi getMechanismContext(byte[] exportedContext) 168 throws GSSException { 169 return cStub.importContext(exportedContext); 170 } 171 getMechanismOid()172 public final Oid getMechanismOid() { 173 return cStub.getMech(); 174 } 175 getProvider()176 public Provider getProvider() { 177 return SunNativeProvider.INSTANCE; 178 } 179 getNameTypes()180 public Oid[] getNameTypes() throws GSSException { 181 return cStub.inquireNamesForMech(); 182 } 183 } 184