Skip to content

Commit 4e55e6e

Browse files
author
Aleksandar Gradinac
committed
Automatically register the Sasl provider
1 parent b8b94ef commit 4e55e6e

File tree

1 file changed

+38
-1
lines changed

1 file changed

+38
-1
lines changed

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/SecurityServicesFeature.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,12 @@
7676
import javax.net.ssl.KeyManagerFactory;
7777
import javax.net.ssl.SSLContext;
7878
import javax.net.ssl.TrustManagerFactory;
79+
import javax.security.auth.callback.CallbackHandler;
7980
import javax.security.auth.login.Configuration;
81+
import javax.security.sasl.Sasl;
82+
import javax.security.sasl.SaslClient;
8083
import javax.security.sasl.SaslClientFactory;
84+
import javax.security.sasl.SaslServer;
8185
import javax.security.sasl.SaslServerFactory;
8286
import javax.smartcardio.TerminalFactory;
8387
import javax.xml.crypto.dsig.TransformService;
@@ -109,6 +113,7 @@
109113
import com.oracle.svm.hosted.FeatureImpl.DuringAnalysisAccessImpl;
110114
import com.oracle.svm.hosted.FeatureImpl.DuringSetupAccessImpl;
111115
import com.oracle.svm.hosted.c.NativeLibraries;
116+
import com.oracle.svm.util.ClassUtil;
112117
import com.oracle.svm.util.ModuleSupport;
113118
import com.oracle.svm.util.ReflectionUtil;
114119

@@ -518,6 +523,29 @@ private static Set<Class<?>> computeKnownServices(BeforeAnalysisAccess access) {
518523
return allKnownServices;
519524
}
520525

526+
private void registerSpecialReachabilityHandlers(BeforeAnalysisAccess access) {
527+
/*
528+
* Sasl does not conform to the JCA - the service has no getInstance method. We instead use
529+
* the Sasl facade class for our reachability handlers.
530+
*/
531+
String saslRegistrationFailureMessage = "Failed to enable automatic SASL provider registration: %s";
532+
String saslClassName = "javax.security.sasl.Sasl";
533+
try {
534+
TypeResult<Class<?>> saslClassLookup = loader.findClass(saslClassName);
535+
if (saslClassLookup.isPresent()) {
536+
trace(saslRegistrationFailureMessage, saslClassName);
537+
}
538+
539+
Class<?> saslClass = saslClassLookup.getOrFail();
540+
Method createSaslClient = ReflectionUtil.lookupMethod(saslClass, "createSaslClient", String[].class, String.class, String.class, String.class, Map.class, CallbackHandler.class);
541+
access.registerReachabilityHandler(a -> registerServices(a, createSaslClient, SaslClient.class), createSaslClient);
542+
Method createSaslServer = ReflectionUtil.lookupMethod(saslClass, "createSaslServer", String.class, String.class, String.class, Map.class, CallbackHandler.class);
543+
access.registerReachabilityHandler(a -> registerServices(a, createSaslServer, SaslServer.class), createSaslServer);
544+
} catch (ReflectionUtil.ReflectionUtilError e) {
545+
trace(saslRegistrationFailureMessage, e);
546+
}
547+
}
548+
521549
private void registerServiceReachabilityHandlers(BeforeAnalysisAccess access) {
522550
ctrParamClassAccessor = getConstructorParameterClassAccessor(loader);
523551
getSpiClassMethod = getSpiClassMethod();
@@ -550,6 +578,8 @@ private void registerServiceReachabilityHandlers(BeforeAnalysisAccess access) {
550578
}
551579
}
552580

581+
registerSpecialReachabilityHandlers(access);
582+
553583
/*
554584
* On Oracle JDK the SecureRandom service implementations are not automatically discovered
555585
* by the mechanism above because SecureRandom.getInstance() is not invoked. For example
@@ -569,14 +599,21 @@ private void registerServices(DuringAnalysisAccess access, Object trigger, Class
569599
* but not any of its sub-packages. See java.security.Security.getSpiClass().
570600
*/
571601
// Checkstyle: allow Class.getSimpleName
572-
String serviceType = serviceClass.getSimpleName();
602+
String serviceType = getServiceType(serviceClass);
573603
// Checkstyle: disallow Class.getSimpleName
574604
if (serviceClass.getPackage().getName().equals("java.security")) {
575605
registerSpiClass(getSpiClassMethod, serviceType);
576606
}
577607
registerServices(access, trigger, serviceType);
578608
}
579609

610+
private String getServiceType(Class<?> serviceClass) {
611+
if (serviceClass == SaslClient.class || serviceClass == SaslServer.class) {
612+
return ClassUtil.getUnqualifiedName(serviceClass) + "Factory";
613+
}
614+
return ClassUtil.getUnqualifiedName(serviceClass);
615+
}
616+
580617
ConcurrentHashMap<String, Boolean> processedServiceClasses = new ConcurrentHashMap<>();
581618

582619
private void registerServices(DuringAnalysisAccess access, Object trigger, String serviceType) {

0 commit comments

Comments
 (0)