< prev index next >

src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m

Print this page
rev 54093 : 8257858: [macOS]: Remove JNF dependency from libosxsecurity/KeystoreImpl.m
8257860: [macOS]: Remove JNF dependency from libosxkrb5/SCDynamicStoreConfig.m

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2021, 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

@@ -22,124 +22,54 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
 
 #import <Cocoa/Cocoa.h>
-#import <JavaNativeFoundation/JavaNativeFoundation.h>
 #import <SystemConfiguration/SystemConfiguration.h>
-
-
-@interface JNFVectorCoercion : NSObject <JNFTypeCoercion> { }
-@end
-
-@implementation JNFVectorCoercion
-
-- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    static JNF_CLASS_CACHE(jc_Vector, "java/util/Vector");
-    static JNF_CTOR_CACHE(jm_Vector_ctor, jc_Vector, "(I)V");
-    static JNF_MEMBER_CACHE(jm_Vector_add, jc_Vector, "add", "(Ljava/lang/Object;)Z");
-
-    NSArray *nsArray = (NSArray *)obj;
-    jobject javaArray = JNFNewObject(env, jm_Vector_ctor, (jint)[nsArray count]);
-
-    for (id obj in nsArray) {
-        jobject jobj = [coercer coerceNSObject:obj withEnv:env usingCoercer:coercer];
-        JNFCallBooleanMethod(env, javaArray, jm_Vector_add, jobj);
-        if (jobj != NULL) (*env)->DeleteLocalRef(env, jobj);
-    }
-
-    return javaArray;
-}
-
-- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return nil;
-}
-
-@end
-
-
-@interface JNFHashtableCoercion : NSObject <JNFTypeCoercion> { }
-@end
-
-@implementation JNFHashtableCoercion
-
-- (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    static JNF_CLASS_CACHE(jc_Hashtable, "java/util/Hashtable");
-    static JNF_CTOR_CACHE(jm_Hashtable_ctor, jc_Hashtable, "()V");
-    static JNF_MEMBER_CACHE(jm_Hashtable_put, jc_Hashtable, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
-
-    NSDictionary *nsDict = (NSDictionary *)obj;
-    NSEnumerator *keyEnum = [nsDict keyEnumerator];
-
-    jobject jHashTable = JNFNewObject(env, jm_Hashtable_ctor);
-
-    id key = nil;
-    while ((key = [keyEnum nextObject]) != nil) {
-        jobject jkey = [coercer coerceNSObject:key withEnv:env usingCoercer:coercer];
-
-        id value = [nsDict objectForKey:key];
-        jobject jvalue = [coercer coerceNSObject:value withEnv:env usingCoercer:coercer];
-
-        JNFCallObjectMethod(env, jHashTable, jm_Hashtable_put, jkey, jvalue);
-
-        if (jkey != NULL) (*env)->DeleteLocalRef(env, jkey);
-        if (jvalue != NULL) (*env)->DeleteLocalRef(env, jvalue);
-    }
-
-    return jHashTable;
-}
-
-- (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
-    return nil;
-}
-
-@end
-
-
-
-NSDictionary *realmConfigsForRealms(SCDynamicStoreRef store, NSArray *realms) {
-    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
-
-    for (NSString *realm in realms) {
-        CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]);
-
-        if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
-            if (realmInfo) CFRelease(realmInfo);
-            return nil;
-        }
-
-        [dict setObject:(NSArray *)realmInfo forKey:realm];
-        CFRelease(realmInfo);
-    }
-
-    return dict;
-}
-
+#import "jni_util.h"
 
 #define KERBEROS_DEFAULT_REALMS @"Kerberos-Default-Realms"
 #define KERBEROS_DEFAULT_REALM_MAPPINGS @"Kerberos-Domain-Realm-Mappings"
+#define KERBEROS_REALM_INFO @"Kerberos:%@"
+
+JavaVM *localVM;
 
 void _SCDynamicStoreCallBack(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) {
    NSArray *keys = (NSArray *)changedKeys;
     if ([keys count] == 0) return;
     if (![keys containsObject:KERBEROS_DEFAULT_REALMS] && ![keys containsObject:KERBEROS_DEFAULT_REALM_MAPPINGS]) return;
 
-    JNFPerformEnvBlock(JNFThreadDetachOnThreadDeath | JNFThreadSetSystemClassLoaderOnAttach | JNFThreadAttachAsDaemon, ^(JNIEnv *env) {
-        static JNF_CLASS_CACHE(jc_Config, "sun/security/krb5/Config");
-        static JNF_STATIC_MEMBER_CACHE(jm_Config_refresh, jc_Config, "refresh", "()V");
-        JNFCallStaticVoidMethod(env, jm_Config_refresh);
-    });
+    JNIEnv *env;
+    bool createdFromAttach = FALSE;
+    jint status = (*localVM)->GetEnv(localVM, (void**)&env, JNI_VERSION_1_2);
+    if (status == JNI_EDETACHED) {
+        status = (*localVM)->AttachCurrentThreadAsDaemon(localVM, (void**)&env, NULL);
+        createdFromAttach = TRUE;
+    }
+    if (status == 0) {
+        jclass jc_Config = (*env)->FindClass(env, "sun/security/krb5/Config");
+        CHECK_NULL(jc_Config);
+        jmethodID jm_Config_refresh = (*env)->GetStaticMethodID(env, jc_Config, "refresh", "()V");
+        CHECK_NULL(jm_Config_refresh);
+        (*env)->CallStaticVoidMethod(env, jc_Config, jm_Config_refresh);
+        if ((*env)->ExceptionOccurred(env) != NULL) {
+            (*env)->ExceptionClear(env);
+        }
+        if (createdFromAttach) {
+            (*localVM)->DetachCurrentThread(localVM);
+        }
+    }
 }
 
 /*
  * Class:     sun_security_krb5_SCDynamicStoreConfig
  * Method:    installNotificationCallback
  */
 JNIEXPORT void JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_installNotificationCallback(JNIEnv *env, jclass klass) {
-
-JNF_COCOA_ENTER(env);
-
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \
+    @try {
+        (*env)->GetJavaVM(env, &localVM);
     SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java"), _SCDynamicStoreCallBack, NULL);
     if (store == NULL) {
         return;
     }
 

@@ -151,73 +81,93 @@
         CFRunLoopAddSource(CFRunLoopGetMain(), rls, kCFRunLoopDefaultMode);
         CFRelease(rls);
     }
 
     CFRelease(store);
+    } @catch (NSException *e) {
+        NSLog(@"%@", [e callStackSymbols]);
+    } @finally {
+        [pool drain];
+    }
+}
 
-JNF_COCOA_EXIT(env);
-
+#define ADD(list, str) { \
+    jobject localeObj = (*env)->NewStringUTF(env, [str UTF8String]); \
+    (*env)->CallBooleanMethod(env, list, jm_listAdd, localeObj); \
+    (*env)->DeleteLocalRef(env, localeObj); \
 }
 
+#define ADDNULL(list) (*env)->CallBooleanMethod(env, list, jm_listAdd, NULL)
+
 /*
  * Class:     sun_security_krb5_SCDynamicStoreConfig
  * Method:    getKerberosConfig
- * Signature: ()Ljava/util/Hashtable;
+ * Signature: ()Ljava/util/List;
  */
 JNIEXPORT jobject JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_getKerberosConfig(JNIEnv *env, jclass klass) {
-    jobject jHashTable = NULL;
 
-JNF_COCOA_ENTER(env);
+    jobject newList = 0;
 
+    SCDynamicStoreRef store = NULL;
+    CFTypeRef realms = NULL;
+    CFTypeRef realmMappings = NULL;
+    CFTypeRef realmInfo = NULL;
+
+    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \
+    @try {
     SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java-kerberos"), NULL, NULL);
     if (store == NULL) {
         return NULL;
     }
 
     CFTypeRef realms = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALMS);
     if (realms == NULL || CFGetTypeID(realms) != CFArrayGetTypeID()) {
-        if (realms) CFRelease(realms);
-        CFRelease(store);
         return NULL;
     }
 
-    CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS);
-
-    if (realmMappings == NULL || CFGetTypeID(realmMappings) != CFArrayGetTypeID()) {
-        if (realmMappings) CFRelease(realmMappings);
-        CFRelease(realms);
-        CFRelease(store);
-        return NULL;
+        // This methods returns a ArrayList<String>:
+        // (realm kdc* null) null (mapping-domain mapping-realm)*
+        jclass jc_arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
+        CHECK_NULL_RETURN(jc_arrayListClass, NULL);
+        jmethodID jm_arrayListCons = (*env)->GetMethodID(env, jc_arrayListClass, "<init>", "()V");
+        CHECK_NULL_RETURN(jm_arrayListCons, NULL);
+        jmethodID jm_listAdd = (*env)->GetMethodID(env, jc_arrayListClass, "add", "(Ljava/lang/Object;)Z");
+        CHECK_NULL_RETURN(jm_listAdd, NULL);
+        newList = (*env)->NewObject(env, jc_arrayListClass, jm_arrayListCons);
+        CHECK_NULL_RETURN(newList, NULL);
+
+        for (NSString *realm in (NSArray*)realms) {
+            if (realmInfo) CFRelease(realmInfo); // for the previous realm
+            realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:KERBEROS_REALM_INFO, realm]);
+            if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
+                continue;
     }
 
-    NSMutableDictionary *dict = [NSMutableDictionary dictionary];
-
-    if (CFArrayGetCount(realms) > 0) {
-        NSDictionary *defaultRealmsDict = [NSDictionary dictionaryWithObject:[(NSArray *)realms objectAtIndex:0] forKey:@"default_realm"];
-        [dict setObject:defaultRealmsDict forKey:@"libdefaults"];
-
-        NSDictionary *realmConfigs = realmConfigsForRealms(store, (NSArray *)realms);
-        [dict setObject:realmConfigs forKey:@"realms"];
+            ADD(newList, realm);
+            NSDictionary* ri = (NSDictionary*)realmInfo;
+            for (NSDictionary* k in (NSArray*)ri[@"kdc"]) {
+                ADD(newList, k[@"host"]);
     }
-    CFRelease(realms);
-    CFRelease(store);
-
-    if (CFArrayGetCount(realmMappings) > 0) {
-        [dict setObject:[(NSArray *)realmMappings objectAtIndex:0] forKey:@"domain_realm"];
+            ADDNULL(newList);
     }
-    CFRelease(realmMappings);
-
-
-    // create and load a coercer with all of the different coercions to convert each type of object
-    JNFTypeCoercer *coercer = [[[JNFTypeCoercer alloc] init] autorelease];
-    [JNFDefaultCoercions addStringCoercionTo:coercer];
-    [JNFDefaultCoercions addNumberCoercionTo:coercer];
-    [coercer addCoercion:[[[JNFHashtableCoercion alloc] init] autorelease] forNSClass:[NSDictionary class] javaClass:@"java/util/Map"];
-    [coercer addCoercion:[[[JNFVectorCoercion alloc] init] autorelease] forNSClass:[NSArray class] javaClass:@"java/util/List"];
-
-    // convert Cocoa graph to Java graph
-    jHashTable = [coercer coerceNSObject:dict withEnv:env];
+        ADDNULL(newList);
 
-JNF_COCOA_EXIT(env);
-
-    return jHashTable;
+        CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS);
+        if (realmMappings != NULL && CFGetTypeID(realmMappings) == CFArrayGetTypeID()) {
+            for (NSDictionary* d in (NSArray *)realmMappings) {
+                for (NSString* s in d) {
+                    ADD(newList, s);
+                    ADD(newList, d[s]);
+                }
+            }
+        }
+    } @catch (NSException *e) {
+        NSLog(@"%@", [e callStackSymbols]);
+    } @finally {
+        [pool drain];
+        if (realmInfo) CFRelease(realmInfo);
+        if (realmMappings) CFRelease(realmMappings);
+        if (realms) CFRelease(realms);
+        if (store) CFRelease(store);
+    }
+    return newList;
 }
< prev index next >