1/* 2 * Copyright (c) 2000, 2013, 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 26package sun.security.jgss; 27 28import org.ietf.jgss.*; 29import sun.security.jgss.spi.*; 30import java.security.Provider; 31import java.security.AccessController; 32import java.security.PrivilegedAction; 33 34/** 35 * This class provides the default implementation of the GSSManager 36 * interface. 37 */ 38public class GSSManagerImpl extends GSSManager { 39 40 // Undocumented property 41 private static final String USE_NATIVE_PROP = 42 "sun.security.jgss.native"; 43 private static final Boolean USE_NATIVE; 44 45 static { 46 USE_NATIVE = 47 AccessController.doPrivileged(new PrivilegedAction<Boolean>() { 48 public Boolean run() { 49 String osname = System.getProperty("os.name"); 50 if (osname.startsWith("SunOS") || 51 osname.contains("OS X") || 52 osname.startsWith("Linux")) { 53 return Boolean.valueOf(System.getProperty 54 (USE_NATIVE_PROP)); 55 } 56 return Boolean.FALSE; 57 } 58 }); 59 60 } 61 62 private ProviderList list; 63 64 // Used by java SPNEGO impl to make sure native is disabled 65 public GSSManagerImpl(GSSCaller caller, boolean useNative) { 66 list = new ProviderList(caller, useNative); 67 } 68 69 // Used by HTTP/SPNEGO NegotiatorImpl 70 public GSSManagerImpl(GSSCaller caller) { 71 list = new ProviderList(caller, USE_NATIVE); 72 } 73 74 public GSSManagerImpl() { 75 list = new ProviderList(GSSCaller.CALLER_UNKNOWN, USE_NATIVE); 76 } 77 78 public Oid[] getMechs(){ 79 return list.getMechs(); 80 } 81 82 public Oid[] getNamesForMech(Oid mech) 83 throws GSSException { 84 MechanismFactory factory = list.getMechFactory(mech); 85 return factory.getNameTypes().clone(); 86 } 87 88 public Oid[] getMechsForName(Oid nameType){ 89 Oid[] mechs = list.getMechs(); 90 Oid[] retVal = new Oid[mechs.length]; 91 int pos = 0; 92 93 // Compatibility with RFC 2853 old NT_HOSTBASED_SERVICE value. 94 if (nameType.equals(GSSNameImpl.oldHostbasedServiceName)) { 95 nameType = GSSName.NT_HOSTBASED_SERVICE; 96 } 97 98 // Iterate thru all mechs in GSS 99 for (int i = 0; i < mechs.length; i++) { 100 // what nametypes does this mech support? 101 Oid mech = mechs[i]; 102 try { 103 Oid[] namesForMech = getNamesForMech(mech); 104 // Is the desired Oid present in that list? 105 if (nameType.containedIn(namesForMech)) { 106 retVal[pos++] = mech; 107 } 108 } catch (GSSException e) { 109 // Squelch it and just skip over this mechanism 110 GSSUtil.debug("Skip " + mech + 111 ": error retrieving supported name types"); 112 } 113 } 114 115 // Trim the list if needed 116 if (pos < retVal.length) { 117 Oid[] temp = new Oid[pos]; 118 for (int i = 0; i < pos; i++) 119 temp[i] = retVal[i]; 120 retVal = temp; 121 } 122 123 return retVal; 124 } 125 126 public GSSName createName(String nameStr, Oid nameType) 127 throws GSSException { 128 return new GSSNameImpl(this, nameStr, nameType); 129 } 130 131 public GSSName createName(byte[] name, Oid nameType) 132 throws GSSException { 133 return new GSSNameImpl(this, name, nameType); 134 } 135 136 public GSSName createName(String nameStr, Oid nameType, 137 Oid mech) throws GSSException { 138 return new GSSNameImpl(this, nameStr, nameType, mech); 139 } 140 141 public GSSName createName(byte[] name, Oid nameType, Oid mech) 142 throws GSSException { 143 return new GSSNameImpl(this, name, nameType, mech); 144 } 145 146 public GSSCredential createCredential(int usage) 147 throws GSSException { 148 return wrap(new GSSCredentialImpl(this, usage)); 149 } 150 151 public GSSCredential createCredential(GSSName aName, 152 int lifetime, Oid mech, int usage) 153 throws GSSException { 154 return wrap(new GSSCredentialImpl(this, aName, lifetime, mech, usage)); 155 } 156 157 public GSSCredential createCredential(GSSName aName, 158 int lifetime, Oid[] mechs, int usage) 159 throws GSSException { 160 return wrap(new GSSCredentialImpl(this, aName, lifetime, mechs, usage)); 161 } 162 163 public GSSContext createContext(GSSName peer, Oid mech, 164 GSSCredential myCred, int lifetime) 165 throws GSSException { 166 return wrap(new GSSContextImpl(this, peer, mech, myCred, lifetime)); 167 } 168 169 public GSSContext createContext(GSSCredential myCred) 170 throws GSSException { 171 return wrap(new GSSContextImpl(this, myCred)); 172 } 173 174 public GSSContext createContext(byte[] interProcessToken) 175 throws GSSException { 176 return wrap(new GSSContextImpl(this, interProcessToken)); 177 } 178 179 public void addProviderAtFront(Provider p, Oid mech) 180 throws GSSException { 181 list.addProviderAtFront(p, mech); 182 } 183 184 public void addProviderAtEnd(Provider p, Oid mech) 185 throws GSSException { 186 list.addProviderAtEnd(p, mech); 187 } 188 189 public GSSCredentialSpi getCredentialElement(GSSNameSpi name, int initLifetime, 190 int acceptLifetime, Oid mech, int usage) 191 throws GSSException { 192 MechanismFactory factory = list.getMechFactory(mech); 193 return factory.getCredentialElement(name, initLifetime, 194 acceptLifetime, usage); 195 } 196 197 // Used by java SPNEGO impl 198 public GSSNameSpi getNameElement(String name, Oid nameType, Oid mech) 199 throws GSSException { 200 // Just use the most preferred MF impl assuming GSSNameSpi 201 // objects are interoperable among providers 202 MechanismFactory factory = list.getMechFactory(mech); 203 return factory.getNameElement(name, nameType); 204 } 205 206 // Used by java SPNEGO impl 207 public GSSNameSpi getNameElement(byte[] name, Oid nameType, Oid mech) 208 throws GSSException { 209 // Just use the most preferred MF impl assuming GSSNameSpi 210 // objects are interoperable among providers 211 MechanismFactory factory = list.getMechFactory(mech); 212 return factory.getNameElement(name, nameType); 213 } 214 215 GSSContextSpi getMechanismContext(GSSNameSpi peer, 216 GSSCredentialSpi myInitiatorCred, 217 int lifetime, Oid mech) 218 throws GSSException { 219 Provider p = null; 220 if (myInitiatorCred != null) { 221 p = myInitiatorCred.getProvider(); 222 } 223 MechanismFactory factory = list.getMechFactory(mech, p); 224 return factory.getMechanismContext(peer, myInitiatorCred, lifetime); 225 } 226 227 GSSContextSpi getMechanismContext(GSSCredentialSpi myAcceptorCred, 228 Oid mech) 229 throws GSSException { 230 Provider p = null; 231 if (myAcceptorCred != null) { 232 p = myAcceptorCred.getProvider(); 233 } 234 MechanismFactory factory = list.getMechFactory(mech, p); 235 return factory.getMechanismContext(myAcceptorCred); 236 } 237 238 GSSContextSpi getMechanismContext(byte[] exportedContext) 239 throws GSSException { 240 if ((exportedContext == null) || (exportedContext.length == 0)) { 241 throw new GSSException(GSSException.NO_CONTEXT); 242 } 243 GSSContextSpi result = null; 244 245 // Only allow context import with native provider since JGSS 246 // still has not defined its own interprocess token format 247 Oid[] mechs = list.getMechs(); 248 for (int i = 0; i < mechs.length; i++) { 249 MechanismFactory factory = list.getMechFactory(mechs[i]); 250 if (factory.getProvider().getName().equals("SunNativeGSS")) { 251 result = factory.getMechanismContext(exportedContext); 252 if (result != null) break; 253 } 254 } 255 if (result == null) { 256 throw new GSSException(GSSException.UNAVAILABLE); 257 } 258 return result; 259 } 260 261 static { 262 // Load the extended JGSS interfaces if exist 263 try { 264 Class.forName("com.sun.security.jgss.Extender"); 265 } catch (Exception e) { 266 } 267 } 268 269 static GSSCredential wrap(GSSCredentialImpl cred) { 270 return sun.security.jgss.JgssExtender.getExtender().wrap(cred); 271 } 272 273 static GSSContext wrap(GSSContextImpl ctxt) { 274 return sun.security.jgss.JgssExtender.getExtender().wrap(ctxt); 275 } 276} 277