< 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 /*
   2  * Copyright (c) 2011, 2019, 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 
  26 #import <Cocoa/Cocoa.h>
  27 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  28 #import <SystemConfiguration/SystemConfiguration.h>
  29 
  30 
  31 @interface JNFVectorCoercion : NSObject <JNFTypeCoercion> { }
  32 @end
  33 
  34 @implementation JNFVectorCoercion
  35 
  36 - (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
  37     static JNF_CLASS_CACHE(jc_Vector, "java/util/Vector");
  38     static JNF_CTOR_CACHE(jm_Vector_ctor, jc_Vector, "(I)V");
  39     static JNF_MEMBER_CACHE(jm_Vector_add, jc_Vector, "add", "(Ljava/lang/Object;)Z");
  40 
  41     NSArray *nsArray = (NSArray *)obj;
  42     jobject javaArray = JNFNewObject(env, jm_Vector_ctor, (jint)[nsArray count]);
  43 
  44     for (id obj in nsArray) {
  45         jobject jobj = [coercer coerceNSObject:obj withEnv:env usingCoercer:coercer];
  46         JNFCallBooleanMethod(env, javaArray, jm_Vector_add, jobj);
  47         if (jobj != NULL) (*env)->DeleteLocalRef(env, jobj);
  48     }
  49 
  50     return javaArray;
  51 }
  52 
  53 - (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
  54     return nil;
  55 }
  56 
  57 @end
  58 
  59 
  60 @interface JNFHashtableCoercion : NSObject <JNFTypeCoercion> { }
  61 @end
  62 
  63 @implementation JNFHashtableCoercion
  64 
  65 - (jobject) coerceNSObject:(id)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
  66     static JNF_CLASS_CACHE(jc_Hashtable, "java/util/Hashtable");
  67     static JNF_CTOR_CACHE(jm_Hashtable_ctor, jc_Hashtable, "()V");
  68     static JNF_MEMBER_CACHE(jm_Hashtable_put, jc_Hashtable, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
  69 
  70     NSDictionary *nsDict = (NSDictionary *)obj;
  71     NSEnumerator *keyEnum = [nsDict keyEnumerator];
  72 
  73     jobject jHashTable = JNFNewObject(env, jm_Hashtable_ctor);
  74 
  75     id key = nil;
  76     while ((key = [keyEnum nextObject]) != nil) {
  77         jobject jkey = [coercer coerceNSObject:key withEnv:env usingCoercer:coercer];
  78 
  79         id value = [nsDict objectForKey:key];
  80         jobject jvalue = [coercer coerceNSObject:value withEnv:env usingCoercer:coercer];
  81 
  82         JNFCallObjectMethod(env, jHashTable, jm_Hashtable_put, jkey, jvalue);
  83 
  84         if (jkey != NULL) (*env)->DeleteLocalRef(env, jkey);
  85         if (jvalue != NULL) (*env)->DeleteLocalRef(env, jvalue);
  86     }
  87 
  88     return jHashTable;
  89 }
  90 
  91 - (id) coerceJavaObject:(jobject)obj withEnv:(JNIEnv *)env usingCoercer:(JNFTypeCoercion *)coercer {
  92     return nil;
  93 }
  94 
  95 @end
  96 
  97 
  98 
  99 NSDictionary *realmConfigsForRealms(SCDynamicStoreRef store, NSArray *realms) {
 100     NSMutableDictionary *dict = [NSMutableDictionary dictionary];
 101 
 102     for (NSString *realm in realms) {
 103         CFTypeRef realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:@"Kerberos:%@", realm]);
 104 
 105         if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
 106             if (realmInfo) CFRelease(realmInfo);
 107             return nil;
 108         }
 109 
 110         [dict setObject:(NSArray *)realmInfo forKey:realm];
 111         CFRelease(realmInfo);
 112     }
 113 
 114     return dict;
 115 }
 116 
 117 
 118 #define KERBEROS_DEFAULT_REALMS @"Kerberos-Default-Realms"
 119 #define KERBEROS_DEFAULT_REALM_MAPPINGS @"Kerberos-Domain-Realm-Mappings"



 120 
 121 void _SCDynamicStoreCallBack(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) {
 122    NSArray *keys = (NSArray *)changedKeys;
 123     if ([keys count] == 0) return;
 124     if (![keys containsObject:KERBEROS_DEFAULT_REALMS] && ![keys containsObject:KERBEROS_DEFAULT_REALM_MAPPINGS]) return;
 125 
 126     JNFPerformEnvBlock(JNFThreadDetachOnThreadDeath | JNFThreadSetSystemClassLoaderOnAttach | JNFThreadAttachAsDaemon, ^(JNIEnv *env) {
 127         static JNF_CLASS_CACHE(jc_Config, "sun/security/krb5/Config");
 128         static JNF_STATIC_MEMBER_CACHE(jm_Config_refresh, jc_Config, "refresh", "()V");
 129         JNFCallStaticVoidMethod(env, jm_Config_refresh);
 130     });















 131 }
 132 
 133 /*
 134  * Class:     sun_security_krb5_SCDynamicStoreConfig
 135  * Method:    installNotificationCallback
 136  */
 137 JNIEXPORT void JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_installNotificationCallback(JNIEnv *env, jclass klass) {
 138 
 139 JNF_COCOA_ENTER(env);
 140 
 141     SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java"), _SCDynamicStoreCallBack, NULL);
 142     if (store == NULL) {
 143         return;
 144     }
 145 
 146     NSArray *keys = [NSArray arrayWithObjects:KERBEROS_DEFAULT_REALMS, KERBEROS_DEFAULT_REALM_MAPPINGS, nil];
 147     SCDynamicStoreSetNotificationKeys(store, (CFArrayRef) keys, NULL);
 148 
 149     CFRunLoopSourceRef rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
 150     if (rls != NULL) {
 151         CFRunLoopAddSource(CFRunLoopGetMain(), rls, kCFRunLoopDefaultMode);
 152         CFRelease(rls);
 153     }
 154 
 155     CFRelease(store);






 156 
 157 JNF_COCOA_EXIT(env);
 158 


 159 }
 160 


 161 /*
 162  * Class:     sun_security_krb5_SCDynamicStoreConfig
 163  * Method:    getKerberosConfig
 164  * Signature: ()Ljava/util/Hashtable;
 165  */
 166 JNIEXPORT jobject JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_getKerberosConfig(JNIEnv *env, jclass klass) {
 167     jobject jHashTable = NULL;
 168 
 169 JNF_COCOA_ENTER(env);
 170 







 171     SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java-kerberos"), NULL, NULL);
 172     if (store == NULL) {
 173         return NULL;
 174     }
 175 
 176     CFTypeRef realms = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALMS);
 177     if (realms == NULL || CFGetTypeID(realms) != CFArrayGetTypeID()) {
 178         if (realms) CFRelease(realms);
 179         CFRelease(store);
 180         return NULL;
 181     }
 182 
 183     CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS);
 184 
 185     if (realmMappings == NULL || CFGetTypeID(realmMappings) != CFArrayGetTypeID()) {
 186         if (realmMappings) CFRelease(realmMappings);
 187         CFRelease(realms);
 188         CFRelease(store);
 189         return NULL;









 190     }
 191 
 192     NSMutableDictionary *dict = [NSMutableDictionary dictionary];
 193 
 194     if (CFArrayGetCount(realms) > 0) {
 195         NSDictionary *defaultRealmsDict = [NSDictionary dictionaryWithObject:[(NSArray *)realms objectAtIndex:0] forKey:@"default_realm"];
 196         [dict setObject:defaultRealmsDict forKey:@"libdefaults"];
 197 
 198         NSDictionary *realmConfigs = realmConfigsForRealms(store, (NSArray *)realms);
 199         [dict setObject:realmConfigs forKey:@"realms"];
 200     }
 201     CFRelease(realms);
 202     CFRelease(store);
 203 
 204     if (CFArrayGetCount(realmMappings) > 0) {
 205         [dict setObject:[(NSArray *)realmMappings objectAtIndex:0] forKey:@"domain_realm"];
 206     }
 207     CFRelease(realmMappings);
 208 
 209 
 210     // create and load a coercer with all of the different coercions to convert each type of object
 211     JNFTypeCoercer *coercer = [[[JNFTypeCoercer alloc] init] autorelease];
 212     [JNFDefaultCoercions addStringCoercionTo:coercer];
 213     [JNFDefaultCoercions addNumberCoercionTo:coercer];
 214     [coercer addCoercion:[[[JNFHashtableCoercion alloc] init] autorelease] forNSClass:[NSDictionary class] javaClass:@"java/util/Map"];
 215     [coercer addCoercion:[[[JNFVectorCoercion alloc] init] autorelease] forNSClass:[NSArray class] javaClass:@"java/util/List"];
 216 
 217     // convert Cocoa graph to Java graph
 218     jHashTable = [coercer coerceNSObject:dict withEnv:env];
 219 
 220 JNF_COCOA_EXIT(env);
 221 
 222     return jHashTable;
















 223 }
   1 /*
   2  * Copyright (c) 2011, 2021, 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 
  26 #import <Cocoa/Cocoa.h>

  27 #import <SystemConfiguration/SystemConfiguration.h>
  28 #import "jni_util.h"























































































  29 
  30 #define KERBEROS_DEFAULT_REALMS @"Kerberos-Default-Realms"
  31 #define KERBEROS_DEFAULT_REALM_MAPPINGS @"Kerberos-Domain-Realm-Mappings"
  32 #define KERBEROS_REALM_INFO @"Kerberos:%@"
  33 
  34 JavaVM *localVM;
  35 
  36 void _SCDynamicStoreCallBack(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) {
  37     NSArray *keys = (NSArray *)changedKeys;
  38     if ([keys count] == 0) return;
  39     if (![keys containsObject:KERBEROS_DEFAULT_REALMS] && ![keys containsObject:KERBEROS_DEFAULT_REALM_MAPPINGS]) return;
  40 
  41     JNIEnv *env;
  42     bool createdFromAttach = FALSE;
  43     jint status = (*localVM)->GetEnv(localVM, (void**)&env, JNI_VERSION_1_2);
  44     if (status == JNI_EDETACHED) {
  45         status = (*localVM)->AttachCurrentThreadAsDaemon(localVM, (void**)&env, NULL);
  46         createdFromAttach = TRUE;
  47     }
  48     if (status == 0) {
  49         jclass jc_Config = (*env)->FindClass(env, "sun/security/krb5/Config");
  50         CHECK_NULL(jc_Config);
  51         jmethodID jm_Config_refresh = (*env)->GetStaticMethodID(env, jc_Config, "refresh", "()V");
  52         CHECK_NULL(jm_Config_refresh);
  53         (*env)->CallStaticVoidMethod(env, jc_Config, jm_Config_refresh);
  54         if ((*env)->ExceptionOccurred(env) != NULL) {
  55             (*env)->ExceptionClear(env);
  56         }
  57         if (createdFromAttach) {
  58             (*localVM)->DetachCurrentThread(localVM);
  59         }
  60     }
  61 }
  62 
  63 /*
  64  * Class:     sun_security_krb5_SCDynamicStoreConfig
  65  * Method:    installNotificationCallback
  66  */
  67 JNIEXPORT void JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_installNotificationCallback(JNIEnv *env, jclass klass) {
  68     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \
  69     @try {
  70         (*env)->GetJavaVM(env, &localVM);
  71         SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java"), _SCDynamicStoreCallBack, NULL);
  72         if (store == NULL) {
  73             return;
  74         }
  75 
  76         NSArray *keys = [NSArray arrayWithObjects:KERBEROS_DEFAULT_REALMS, KERBEROS_DEFAULT_REALM_MAPPINGS, nil];
  77         SCDynamicStoreSetNotificationKeys(store, (CFArrayRef) keys, NULL);
  78 
  79         CFRunLoopSourceRef rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);
  80         if (rls != NULL) {
  81             CFRunLoopAddSource(CFRunLoopGetMain(), rls, kCFRunLoopDefaultMode);
  82             CFRelease(rls);
  83         }
  84 
  85         CFRelease(store);
  86     } @catch (NSException *e) {
  87         NSLog(@"%@", [e callStackSymbols]);
  88     } @finally {
  89         [pool drain];
  90     }
  91 }
  92 
  93 #define ADD(list, str) { \
  94     jobject localeObj = (*env)->NewStringUTF(env, [str UTF8String]); \
  95     (*env)->CallBooleanMethod(env, list, jm_listAdd, localeObj); \
  96     (*env)->DeleteLocalRef(env, localeObj); \
  97 }
  98 
  99 #define ADDNULL(list) (*env)->CallBooleanMethod(env, list, jm_listAdd, NULL)
 100 
 101 /*
 102  * Class:     sun_security_krb5_SCDynamicStoreConfig
 103  * Method:    getKerberosConfig
 104  * Signature: ()Ljava/util/List;
 105  */
 106 JNIEXPORT jobject JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_getKerberosConfig(JNIEnv *env, jclass klass) {

 107 
 108     jobject newList = 0;
 109 
 110     SCDynamicStoreRef store = NULL;
 111     CFTypeRef realms = NULL;
 112     CFTypeRef realmMappings = NULL;
 113     CFTypeRef realmInfo = NULL;
 114 
 115     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \
 116     @try {
 117         SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java-kerberos"), NULL, NULL);
 118         if (store == NULL) {
 119             return NULL;
 120         }
 121 
 122         CFTypeRef realms = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALMS);
 123         if (realms == NULL || CFGetTypeID(realms) != CFArrayGetTypeID()) {


 124             return NULL;
 125         }
 126 
 127         // This methods returns a ArrayList<String>:
 128         // (realm kdc* null) null (mapping-domain mapping-realm)*
 129         jclass jc_arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");
 130         CHECK_NULL_RETURN(jc_arrayListClass, NULL);
 131         jmethodID jm_arrayListCons = (*env)->GetMethodID(env, jc_arrayListClass, "<init>", "()V");
 132         CHECK_NULL_RETURN(jm_arrayListCons, NULL);
 133         jmethodID jm_listAdd = (*env)->GetMethodID(env, jc_arrayListClass, "add", "(Ljava/lang/Object;)Z");
 134         CHECK_NULL_RETURN(jm_listAdd, NULL);
 135         newList = (*env)->NewObject(env, jc_arrayListClass, jm_arrayListCons);
 136         CHECK_NULL_RETURN(newList, NULL);
 137 
 138         for (NSString *realm in (NSArray*)realms) {
 139             if (realmInfo) CFRelease(realmInfo); // for the previous realm
 140             realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:KERBEROS_REALM_INFO, realm]);
 141             if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {
 142                 continue;
 143             }
 144 
 145             ADD(newList, realm);
 146             NSDictionary* ri = (NSDictionary*)realmInfo;
 147             for (NSDictionary* k in (NSArray*)ri[@"kdc"]) {
 148                 ADD(newList, k[@"host"]);




 149             }
 150             ADDNULL(newList);




 151         }
 152         ADDNULL(newList);











 153 
 154         CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS);
 155         if (realmMappings != NULL && CFGetTypeID(realmMappings) == CFArrayGetTypeID()) {
 156             for (NSDictionary* d in (NSArray *)realmMappings) {
 157                 for (NSString* s in d) {
 158                     ADD(newList, s);
 159                     ADD(newList, d[s]);
 160                 }
 161             }
 162         }
 163     } @catch (NSException *e) {
 164         NSLog(@"%@", [e callStackSymbols]);
 165     } @finally {
 166         [pool drain];
 167         if (realmInfo) CFRelease(realmInfo);
 168         if (realmMappings) CFRelease(realmMappings);
 169         if (realms) CFRelease(realms);
 170         if (store) CFRelease(store);
 171     }
 172     return newList;
 173 }
< prev index next >