7676import  javax .net .ssl .KeyManagerFactory ;
7777import  javax .net .ssl .SSLContext ;
7878import  javax .net .ssl .TrustManagerFactory ;
79+ import  javax .security .auth .callback .CallbackHandler ;
7980import  javax .security .auth .login .Configuration ;
81+ import  javax .security .sasl .Sasl ;
82+ import  javax .security .sasl .SaslClient ;
8083import  javax .security .sasl .SaslClientFactory ;
84+ import  javax .security .sasl .SaslServer ;
8185import  javax .security .sasl .SaslServerFactory ;
8286import  javax .smartcardio .TerminalFactory ;
8387import  javax .xml .crypto .dsig .TransformService ;
109113import  com .oracle .svm .hosted .FeatureImpl .DuringAnalysisAccessImpl ;
110114import  com .oracle .svm .hosted .FeatureImpl .DuringSetupAccessImpl ;
111115import  com .oracle .svm .hosted .c .NativeLibraries ;
116+ import  com .oracle .svm .util .ClassUtil ;
112117import  com .oracle .svm .util .ModuleSupport ;
113118import  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