Path: blob/master/src/java.security.jgss/macosx/native/libosxkrb5/SCDynamicStoreConfig.m
41149 views
/*1* Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425#import <Cocoa/Cocoa.h>26#import <SystemConfiguration/SystemConfiguration.h>27#import "jni_util.h"2829#define KERBEROS_DEFAULT_REALMS @"Kerberos-Default-Realms"30#define KERBEROS_DEFAULT_REALM_MAPPINGS @"Kerberos-Domain-Realm-Mappings"31#define KERBEROS_REALM_INFO @"Kerberos:%@"3233JavaVM *localVM;3435void _SCDynamicStoreCallBack(SCDynamicStoreRef store, CFArrayRef changedKeys, void *info) {36NSArray *keys = (NSArray *)changedKeys;37if ([keys count] == 0) return;38if (![keys containsObject:KERBEROS_DEFAULT_REALMS] && ![keys containsObject:KERBEROS_DEFAULT_REALM_MAPPINGS]) return;3940JNIEnv *env;41bool createdFromAttach = FALSE;42jint status = (*localVM)->GetEnv(localVM, (void**)&env, JNI_VERSION_1_2);43if (status == JNI_EDETACHED) {44status = (*localVM)->AttachCurrentThreadAsDaemon(localVM, (void**)&env, NULL);45createdFromAttach = TRUE;46}47if (status == 0) {48jclass jc_Config = (*env)->FindClass(env, "sun/security/krb5/Config");49CHECK_NULL(jc_Config);50jmethodID jm_Config_refresh = (*env)->GetStaticMethodID(env, jc_Config, "refresh", "()V");51CHECK_NULL(jm_Config_refresh);52(*env)->CallStaticVoidMethod(env, jc_Config, jm_Config_refresh);53if ((*env)->ExceptionOccurred(env) != NULL) {54(*env)->ExceptionClear(env);55}56if (createdFromAttach) {57(*localVM)->DetachCurrentThread(localVM);58}59}60}6162/*63* Class: sun_security_krb5_SCDynamicStoreConfig64* Method: installNotificationCallback65*/66JNIEXPORT void JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_installNotificationCallback(JNIEnv *env, jclass klass) {67NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \68@try {69(*env)->GetJavaVM(env, &localVM);70SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java"), _SCDynamicStoreCallBack, NULL);71if (store == NULL) {72return;73}7475NSArray *keys = [NSArray arrayWithObjects:KERBEROS_DEFAULT_REALMS, KERBEROS_DEFAULT_REALM_MAPPINGS, nil];76SCDynamicStoreSetNotificationKeys(store, (CFArrayRef) keys, NULL);7778CFRunLoopSourceRef rls = SCDynamicStoreCreateRunLoopSource(NULL, store, 0);79if (rls != NULL) {80CFRunLoopAddSource(CFRunLoopGetMain(), rls, kCFRunLoopDefaultMode);81CFRelease(rls);82}8384CFRelease(store);85} @catch (NSException *e) {86NSLog(@"%@", [e callStackSymbols]);87} @finally {88[pool drain];89}90}9192#define ADD(list, str) { \93jobject localeObj = (*env)->NewStringUTF(env, [str UTF8String]); \94(*env)->CallBooleanMethod(env, list, jm_listAdd, localeObj); \95(*env)->DeleteLocalRef(env, localeObj); \96}9798#define ADDNULL(list) (*env)->CallBooleanMethod(env, list, jm_listAdd, NULL)99100/*101* Class: sun_security_krb5_SCDynamicStoreConfig102* Method: getKerberosConfig103* Signature: ()Ljava/util/List;104*/105JNIEXPORT jobject JNICALL Java_sun_security_krb5_SCDynamicStoreConfig_getKerberosConfig(JNIEnv *env, jclass klass) {106107jobject newList = 0;108109SCDynamicStoreRef store = NULL;110CFTypeRef realms = NULL;111CFTypeRef realmMappings = NULL;112CFTypeRef realmInfo = NULL;113114NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; \115@try {116SCDynamicStoreRef store = SCDynamicStoreCreate(NULL, CFSTR("java-kerberos"), NULL, NULL);117if (store == NULL) {118return NULL;119}120121CFTypeRef realms = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALMS);122if (realms == NULL || CFGetTypeID(realms) != CFArrayGetTypeID()) {123return NULL;124}125126// This methods returns a ArrayList<String>:127// (realm kdc* null) null (mapping-domain mapping-realm)*128jclass jc_arrayListClass = (*env)->FindClass(env, "java/util/ArrayList");129CHECK_NULL_RETURN(jc_arrayListClass, NULL);130jmethodID jm_arrayListCons = (*env)->GetMethodID(env, jc_arrayListClass, "<init>", "()V");131CHECK_NULL_RETURN(jm_arrayListCons, NULL);132jmethodID jm_listAdd = (*env)->GetMethodID(env, jc_arrayListClass, "add", "(Ljava/lang/Object;)Z");133CHECK_NULL_RETURN(jm_listAdd, NULL);134newList = (*env)->NewObject(env, jc_arrayListClass, jm_arrayListCons);135CHECK_NULL_RETURN(newList, NULL);136137for (NSString *realm in (NSArray*)realms) {138if (realmInfo) CFRelease(realmInfo); // for the previous realm139realmInfo = SCDynamicStoreCopyValue(store, (CFStringRef) [NSString stringWithFormat:KERBEROS_REALM_INFO, realm]);140if (realmInfo == NULL || CFGetTypeID(realmInfo) != CFDictionaryGetTypeID()) {141continue;142}143144ADD(newList, realm);145NSDictionary* ri = (NSDictionary*)realmInfo;146for (NSDictionary* k in (NSArray*)ri[@"kdc"]) {147ADD(newList, k[@"host"]);148}149ADDNULL(newList);150}151ADDNULL(newList);152153CFTypeRef realmMappings = SCDynamicStoreCopyValue(store, (CFStringRef) KERBEROS_DEFAULT_REALM_MAPPINGS);154if (realmMappings != NULL && CFGetTypeID(realmMappings) == CFArrayGetTypeID()) {155for (NSDictionary* d in (NSArray *)realmMappings) {156for (NSString* s in d) {157ADD(newList, s);158ADD(newList, d[s]);159}160}161}162} @catch (NSException *e) {163NSLog(@"%@", [e callStackSymbols]);164} @finally {165[pool drain];166if (realmInfo) CFRelease(realmInfo);167if (realmMappings) CFRelease(realmMappings);168if (realms) CFRelease(realms);169if (store) CFRelease(store);170}171return newList;172}173174175