src/java.security.sasl/share/classes/javax/security/sasl/Sasl.java
Print this page
7191662: JCE providers should be located via ServiceLoader
*** 1,7 ****
/*
! * Copyright (c) 1999, 2013, 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
--- 1,7 ----
/*
! * Copyright (c) 1999, 2015, 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
*** 31,41 ****
--- 31,44 ----
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.HashSet;
import java.util.Collections;
+ import java.security.InvalidParameterException;
+ import java.security.NoSuchAlgorithmException;
import java.security.Provider;
+ import java.security.Provider.Service;
import java.security.Security;
/**
* A static class for creating SASL clients and servers.
*<p>
*** 358,387 ****
Map<String,?> props,
CallbackHandler cbh) throws SaslException {
SaslClient mech = null;
SaslClientFactory fac;
! String className;
String mechName;
for (int i = 0; i < mechanisms.length; i++) {
if ((mechName=mechanisms[i]) == null) {
throw new NullPointerException(
"Mechanism name cannot be null");
} else if (mechName.length() == 0) {
continue;
}
! String mechFilter = "SaslClientFactory." + mechName;
! Provider[] provs = Security.getProviders(mechFilter);
! for (int j = 0; provs != null && j < provs.length; j++) {
! className = provs[j].getProperty(mechFilter);
! if (className == null) {
! // Case is ignored
continue;
}
! fac = (SaslClientFactory) loadFactory(provs[j], className);
if (fac != null) {
mech = fac.createSaslClient(
new String[]{mechanisms[i]}, authorizationId,
protocol, serverName, props, cbh);
if (mech != null) {
--- 361,391 ----
Map<String,?> props,
CallbackHandler cbh) throws SaslException {
SaslClient mech = null;
SaslClientFactory fac;
! Service service;
String mechName;
for (int i = 0; i < mechanisms.length; i++) {
if ((mechName=mechanisms[i]) == null) {
throw new NullPointerException(
"Mechanism name cannot be null");
} else if (mechName.length() == 0) {
continue;
}
! String type = "SaslClientFactory";
! Provider[] provs = Security.getProviders(type + "." + mechName);
! if (provs != null) {
! for (Provider p : provs) {
! service = p.getService(type, mechName);
! if (service == null) {
! // no such service exists
continue;
}
! fac = (SaslClientFactory) loadFactory(service);
if (fac != null) {
mech = fac.createSaslClient(
new String[]{mechanisms[i]}, authorizationId,
protocol, serverName, props, cbh);
if (mech != null) {
*** 388,402 ****
return mech;
}
}
}
}
!
return null;
}
! private static Object loadFactory(Provider p, String className)
throws SaslException {
try {
/*
* Load the implementation class with the same class loader
* that was used to load the provider.
--- 392,406 ----
return mech;
}
}
}
}
! }
return null;
}
! private static Object loadFactory(Service service)
throws SaslException {
try {
/*
* Load the implementation class with the same class loader
* that was used to load the provider.
*** 404,425 ****
* caller's class loader must be the same as or an ancestor of
* the class loader being returned. Otherwise, the caller must
* have "getClassLoader" permission, or a SecurityException
* will be thrown.
*/
! ClassLoader cl = p.getClass().getClassLoader();
! Class<?> implClass;
! implClass = Class.forName(className, true, cl);
! return implClass.newInstance();
! } catch (ClassNotFoundException e) {
! throw new SaslException("Cannot load class " + className, e);
! } catch (InstantiationException e) {
! throw new SaslException("Cannot instantiate class " + className, e);
! } catch (IllegalAccessException e) {
! throw new SaslException("Cannot access class " + className, e);
! } catch (SecurityException e) {
! throw new SaslException("Cannot access class " + className, e);
}
}
/**
--- 408,420 ----
* caller's class loader must be the same as or an ancestor of
* the class loader being returned. Otherwise, the caller must
* have "getClassLoader" permission, or a SecurityException
* will be thrown.
*/
! return service.newInstance(null);
! } catch (InvalidParameterException | NoSuchAlgorithmException e) {
! throw new SaslException("Cannot instantiate service " + service, e);
}
}
/**
*** 501,536 ****
javax.security.auth.callback.CallbackHandler cbh)
throws SaslException {
SaslServer mech = null;
SaslServerFactory fac;
! String className;
if (mechanism == null) {
throw new NullPointerException("Mechanism name cannot be null");
} else if (mechanism.length() == 0) {
return null;
}
! String mechFilter = "SaslServerFactory." + mechanism;
! Provider[] provs = Security.getProviders(mechFilter);
! for (int j = 0; provs != null && j < provs.length; j++) {
! className = provs[j].getProperty(mechFilter);
! if (className == null) {
throw new SaslException("Provider does not support " +
! mechFilter);
}
! fac = (SaslServerFactory) loadFactory(provs[j], className);
if (fac != null) {
mech = fac.createSaslServer(
mechanism, protocol, serverName, props, cbh);
if (mech != null) {
return mech;
}
}
}
!
return null;
}
/**
* Gets an enumeration of known factories for producing {@code SaslClient}.
--- 496,532 ----
javax.security.auth.callback.CallbackHandler cbh)
throws SaslException {
SaslServer mech = null;
SaslServerFactory fac;
! Service service;
if (mechanism == null) {
throw new NullPointerException("Mechanism name cannot be null");
} else if (mechanism.length() == 0) {
return null;
}
! String type = "SaslServerFactory";
! Provider[] provs = Security.getProviders(type + "." + mechanism);
! if (provs != null) {
! for (Provider p : provs) {
! service = p.getService(type, mechanism);
! if (service == null) {
throw new SaslException("Provider does not support " +
! mechanism + " " + type);
}
! fac = (SaslServerFactory) loadFactory(service);
if (fac != null) {
mech = fac.createSaslServer(
mechanism, protocol, serverName, props, cbh);
if (mech != null) {
return mech;
}
}
}
! }
return null;
}
/**
* Gets an enumeration of known factories for producing {@code SaslClient}.
*** 580,621 ****
if ((serviceName == null) || (serviceName.length() == 0) ||
(serviceName.endsWith("."))) {
return result;
}
!
! Provider[] providers = Security.getProviders();
! HashSet<String> classes = new HashSet<String>();
Object fac;
! for (int i = 0; i < providers.length; i++) {
! classes.clear();
! // Check the keys for each provider.
! for (Enumeration<Object> e = providers[i].keys(); e.hasMoreElements(); ) {
! String currentKey = (String)e.nextElement();
! if (currentKey.startsWith(serviceName)) {
! // We should skip the currentKey if it contains a
! // whitespace. The reason is: such an entry in the
! // provider property contains attributes for the
! // implementation of an algorithm. We are only interested
! // in entries which lead to the implementation
! // classes.
! if (currentKey.indexOf(' ') < 0) {
! String className = providers[i].getProperty(currentKey);
! if (!classes.contains(className)) {
! classes.add(className);
try {
! fac = loadFactory(providers[i], className);
if (fac != null) {
result.add(fac);
}
! }catch (Exception ignore) {
}
}
- }
- }
}
}
return Collections.unmodifiableSet(result);
}
}
--- 576,602 ----
if ((serviceName == null) || (serviceName.length() == 0) ||
(serviceName.endsWith("."))) {
return result;
}
! Provider[] provs = Security.getProviders();
Object fac;
! for (Provider p : provs) {
! Iterator<Service> iter = p.getServices().iterator();
! while (iter.hasNext()) {
! Service s = iter.next();
! if (s.getType().equals(serviceName)) {
try {
! fac = loadFactory(s);
if (fac != null) {
result.add(fac);
}
! } catch (Exception ignore) {
}
}
}
}
return Collections.unmodifiableSet(result);
}
}