From c0204db9bd7164b591492ea33fe402677f648cfd Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Mon, 27 Oct 2025 13:02:28 -0400 Subject: [PATCH 01/17] Add support for native Kerberos credential acquisition on Linux --- make/autoconf/lib-krb5.m4 | 113 ++++++++ make/autoconf/libraries.m4 | 9 + make/autoconf/spec.gmk.template | 3 + make/modules/java.security.jgss/Lib.gmk | 18 ++ .../sun/security/krb5/Credentials.java | 12 +- .../native/libkrb5shared}/nativeccache.c | 37 ++- .../security/krb5/native/NativeCacheTest.java | 212 ++++++++++++++ .../krb5/native/NativeCredentialCacheHelper.c | 270 ++++++++++++++++++ .../native/NativeCredentialCacheHelper.java | 65 +++++ test/jdk/sun/security/krb5/native/TestHosts | 3 + test/jdk/sun/security/krb5/native/build.sh | 90 ++++++ 11 files changed, 819 insertions(+), 13 deletions(-) create mode 100644 make/autoconf/lib-krb5.m4 rename src/java.security.jgss/{macosx/native/libosxkrb5 => share/native/libkrb5shared}/nativeccache.c (96%) create mode 100644 test/jdk/sun/security/krb5/native/NativeCacheTest.java create mode 100644 test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c create mode 100644 test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java create mode 100644 test/jdk/sun/security/krb5/native/TestHosts create mode 100755 test/jdk/sun/security/krb5/native/build.sh diff --git a/make/autoconf/lib-krb5.m4 b/make/autoconf/lib-krb5.m4 new file mode 100644 index 0000000000000..5dfd28695234c --- /dev/null +++ b/make/autoconf/lib-krb5.m4 @@ -0,0 +1,113 @@ +# +# Copyright (c) 2025, 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 +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +################################################################################ +# Setup krb5 (Kerberos 5) +################################################################################ +AC_DEFUN_ONCE([LIB_SETUP_KRB5], +[ + AC_ARG_WITH(krb5, [AS_HELP_STRING([--with-krb5], + [enable krb5 support (default=yes), or "no" to disable])]) + + # Determine if krb5 should be disabled + KRB5_DISABLED=no + if test "x${with_krb5}" = xno; then + AC_MSG_NOTICE([krb5 explicitly disabled]) + KRB5_DISABLED=yes + elif test "x$NEEDS_LIB_KRB5" = xfalse; then + if test "x${with_krb5}" != x && test "x${with_krb5}" != xno; then + AC_MSG_WARN([[krb5 not used, so --with-krb5 is ignored]]) + fi + KRB5_DISABLED=yes + fi + + if test "x$KRB5_DISABLED" = xyes; then + KRB5_CFLAGS= + KRB5_LIBS= + ENABLE_LIBLINUXKRB5=false + else + # First try pkg-config (most modern approach) + AC_PATH_TOOL([PKG_CONFIG], [pkg-config], [no]) + use_pkgconfig_for_krb5=no + + if test "x$PKG_CONFIG" != "xno"; then + AC_MSG_CHECKING([if pkg-config knows about krb5]) + if $PKG_CONFIG --exists krb5; then + AC_MSG_RESULT([yes]) + use_pkgconfig_for_krb5=yes + else + AC_MSG_RESULT([no]) + fi + fi + + if test "x$use_pkgconfig_for_krb5" = "xyes"; then + # Use pkg-config to get compiler and linker flags + AC_MSG_CHECKING([for krb5 cflags via pkg-config]) + KRB5_CFLAGS="`$PKG_CONFIG --cflags krb5`" + AC_MSG_RESULT([$KRB5_CFLAGS]) + + AC_MSG_CHECKING([for krb5 libs via pkg-config]) + KRB5_LIBS="`$PKG_CONFIG --libs krb5`" + AC_MSG_RESULT([$KRB5_LIBS]) + + ENABLE_LIBLINUXKRB5=true + else + # Fallback: try krb5-config + AC_PATH_TOOL([KRB5CONF], [krb5-config], [no]) + + if test "x$KRB5CONF" != "xno"; then + # Use krb5-config to get compiler and linker flags + AC_MSG_CHECKING([for krb5 cflags via krb5-config]) + KRB5_CFLAGS="`$KRB5CONF --cflags`" + AC_MSG_RESULT([$KRB5_CFLAGS]) + + AC_MSG_CHECKING([for krb5 libs via krb5-config]) + KRB5_LIBS="`$KRB5CONF --libs`" + AC_MSG_RESULT([$KRB5_LIBS]) + + ENABLE_LIBLINUXKRB5=true + else + # Final fallback: try manual detection in system locations + AC_CHECK_HEADERS([krb5.h], [ + AC_CHECK_LIB([krb5], [krb5_init_context], [ + KRB5_CFLAGS="" + KRB5_LIBS="-lkrb5" + # Check for com_err header and library which are often required + AC_CHECK_HEADERS([com_err.h], [ + AC_CHECK_LIB([com_err], [com_err], [ + KRB5_LIBS="$KRB5_LIBS -lcom_err" + ]) + ]) + ENABLE_LIBLINUXKRB5=true + ], [ENABLE_LIBLINUXKRB5=false]) + ], [ENABLE_LIBLINUXKRB5=false]) + fi + fi + fi + + AC_SUBST(KRB5_CFLAGS) + AC_SUBST(KRB5_LIBS) + AC_SUBST(ENABLE_LIBLINUXKRB5) +]) diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 index 8dc3d55ed0c83..926ea5994629d 100644 --- a/make/autoconf/libraries.m4 +++ b/make/autoconf/libraries.m4 @@ -31,6 +31,7 @@ m4_include([lib-ffi.m4]) m4_include([lib-fontconfig.m4]) m4_include([lib-freetype.m4]) m4_include([lib-hsdis.m4]) +m4_include([lib-krb5.m4]) m4_include([lib-std.m4]) m4_include([lib-x11.m4]) @@ -81,6 +82,13 @@ AC_DEFUN_ONCE([LIB_DETERMINE_DEPENDENCIES], NEEDS_LIB_ALSA=false fi + # Check if krb5 is needed + if test "x$OPENJDK_TARGET_OS" = xlinux -o "x$OPENJDK_TARGET_OS" = xmacosx; then + NEEDS_LIB_KRB5=true + else + NEEDS_LIB_KRB5=false + fi + # Check if ffi is needed if HOTSPOT_CHECK_JVM_VARIANT(zero) || test "x$ENABLE_FALLBACK_LINKER" = "xtrue"; then NEEDS_LIB_FFI=true @@ -117,6 +125,7 @@ AC_DEFUN_ONCE([LIB_SETUP_LIBRARIES], LIB_SETUP_FONTCONFIG LIB_SETUP_FREETYPE LIB_SETUP_HSDIS + LIB_SETUP_KRB5 LIB_SETUP_LIBFFI LIB_SETUP_MISC_LIBS LIB_SETUP_X11 diff --git a/make/autoconf/spec.gmk.template b/make/autoconf/spec.gmk.template index 0b336721d654d..41ad307f9cabd 100644 --- a/make/autoconf/spec.gmk.template +++ b/make/autoconf/spec.gmk.template @@ -435,6 +435,9 @@ FONTCONFIG_CFLAGS := @FONTCONFIG_CFLAGS@ CUPS_CFLAGS := @CUPS_CFLAGS@ ALSA_LIBS := @ALSA_LIBS@ ALSA_CFLAGS := @ALSA_CFLAGS@ +KRB5_LIBS := @KRB5_LIBS@ +KRB5_CFLAGS := @KRB5_CFLAGS@ +ENABLE_LIBLINUXKRB5 := @ENABLE_LIBLINUXKRB5@ LIBFFI_LIBS := @LIBFFI_LIBS@ LIBFFI_CFLAGS := @LIBFFI_CFLAGS@ ENABLE_LIBFFI_BUNDLING := @ENABLE_LIBFFI_BUNDLING@ diff --git a/make/modules/java.security.jgss/Lib.gmk b/make/modules/java.security.jgss/Lib.gmk index 4b05100e6a603..57dc5d4af539c 100644 --- a/make/modules/java.security.jgss/Lib.gmk +++ b/make/modules/java.security.jgss/Lib.gmk @@ -86,6 +86,7 @@ ifneq ($(BUILD_CRYPTO), false) NAME := osxkrb5, \ OPTIMIZATION := LOW, \ EXTRA_HEADER_DIRS := java.base:libjava, \ + EXTRA_SRC := $(TOPDIR)/src/java.security.jgss/share/native/libkrb5shared, \ DISABLED_WARNINGS_clang_nativeccache.c := deprecated-declarations, \ LIBS_macosx := \ -framework Cocoa \ @@ -95,6 +96,23 @@ ifneq ($(BUILD_CRYPTO), false) TARGETS += $(BUILD_LIBOSXKRB5) endif + + ifeq ($(call isTargetOs, linux), true) + ifeq ($(ENABLE_LIBLINUXKRB5), true) + $(eval $(call SetupJdkLibrary, BUILD_LIBLINUXKRB5, \ + NAME := linuxkrb5, \ + OPTIMIZATION := LOW, \ + DISABLED_WARNINGS_clang_nativeccache.c := deprecated-declarations, \ + EXTRA_HEADER_DIRS := java.base:libjava, \ + EXTRA_SRC := $(TOPDIR)/src/java.security.jgss/share/native/libkrb5shared, \ + CFLAGS_linux := $(KRB5_CFLAGS) $(COM_ERR_CFLAGS), \ + LIBS_linux := $(KRB5_LIBS) $(COM_ERR_LIBS), \ + )) + + TARGETS += $(BUILD_LIBLINUXKRB5) + endif + endif + endif ################################################################################ diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java index f9076a9b0dd6c..1348f970a8d2b 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java @@ -326,9 +326,13 @@ public static Credentials acquireTGTFromCache(PrincipalName princ, throws KrbException, IOException { if (ticketCache == null) { - // The default ticket cache on Windows and Mac is not a file. + // On Windows/MacOSX/Linux, use native system library calls to acquire + // credentials from any supported credential cache types on those + // platforms (in particular, the default ticket cache on Windows and + // Mac is not a file, so cannot use the pure Java code) if (OperatingSystem.isWindows() || - OperatingSystem.isMacOS()) { + OperatingSystem.isMacOS() || + OperatingSystem.isLinux()) { Credentials creds = acquireDefaultCreds(); if (creds == null) { if (DEBUG != null) { @@ -411,7 +415,7 @@ public static Credentials acquireTGTFromCache(PrincipalName princ, // It assumes that the GSS call has // the privilege to access the default cache file. - // This method is only called on Windows and Mac OS X, the native + // This method is only called on Windows, Mac OS X and Linux, the native // acquireDefaultNativeCreds is also available on these platforms. public static synchronized Credentials acquireDefaultCreds() { Credentials result = null; @@ -528,6 +532,8 @@ public static void printDebug(Credentials c) { static void ensureLoaded() { if (OperatingSystem.isMacOS()) { System.loadLibrary("osxkrb5"); + } else if (OperatingSystem.isLinux()) { + System.loadLibrary("linuxkrb5"); } else { System.loadLibrary("w2k_lsa_auth"); } diff --git a/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c b/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c similarity index 96% rename from src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c rename to src/java.security.jgss/share/native/libkrb5shared/nativeccache.c index 36e7a942ded61..d6c7cf4f8d22d 100644 --- a/src/java.security.jgss/macosx/native/libosxkrb5/nativeccache.c +++ b/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c @@ -23,10 +23,28 @@ * questions. */ -#import "sun_security_krb5_Credentials.h" -#import -#import -#import +/* + * Unified Kerberos native credential cache implementation for Mac OS X and Linux. + * This implementation consolidates the previously separate platform-specific + * implementations while maintaining platform-specific library names. + * + * Platform-specific differences are handled via conditional compilation. + */ + +#include "sun_security_krb5_Credentials.h" +#include +#include +#include + +#ifdef MACOSX + // Mac OS X specific includes + #import +#elif defined(LINUX) + // Linux specific includes + #include + #include + #include +#endif #include "jni_util.h" @@ -72,7 +90,7 @@ static jobject BuildClientPrincipal(JNIEnv *env, krb5_context kcontext, krb5_pri static jobject BuildEncryptionKey(JNIEnv *env, krb5_keyblock *cryptoKey); static jobject BuildTicketFlags(JNIEnv *env, krb5_flags flags); static jobject BuildKerberosTime(JNIEnv *env, krb5_timestamp kerbtime); -static jobject BuildAddressList(JNIEnv *env, krb5_address **kerbtime); +static jobject BuildAddressList(JNIEnv *env, krb5_address **addresses); static void printiferr (errcode_t err, const char *format, ...); @@ -446,9 +464,6 @@ JNIEXPORT jobject JNICALL Java_sun_security_krb5_Credentials_acquireDefaultNativ return krbCreds; } - -#pragma mark - - jobject BuildTicket(JNIEnv *env, krb5_data *encodedTicket) { // To build a Ticket, we need to make a byte array out of the EncodedTicket. @@ -567,6 +582,10 @@ jobject BuildAddressList(JNIEnv *env, krb5_address **addresses) { p++; } + if (addressCount == 0) { + return NULL; + } + jobject address_list = (*env)->NewObjectArray(env, addressCount, hostAddressClass, NULL); if (address_list == NULL) { @@ -607,8 +626,6 @@ jobject BuildAddressList(JNIEnv *env, krb5_address **addresses) { return address_list; } -#pragma mark - Utility methods - - static void printiferr (errcode_t err, const char *format, ...) { if (err) { diff --git a/test/jdk/sun/security/krb5/native/NativeCacheTest.java b/test/jdk/sun/security/krb5/native/NativeCacheTest.java new file mode 100644 index 0000000000000..f3df9a5aeea72 --- /dev/null +++ b/test/jdk/sun/security/krb5/native/NativeCacheTest.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2025, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8123456 + * @summary Test JAAS access to in-memory credential caches + * @library /test/lib ../auto + * @requires os.family != "windows" + * @compile -XDignore.symbol.file + * --add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.krb5.internal.ccache=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.krb5.internal.crypto=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.jgss.krb5=ALL-UNNAMED + * --add-exports java.base/sun.security.util=ALL-UNNAMED + * --add-exports java.base/jdk.internal.misc=ALL-UNNAMED + * NativeCacheTest.java + * @run shell build.sh + * @run main jdk.test.lib.FileInstaller TestHosts TestHosts + * @run main/othervm + * --add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.krb5.internal.ccache=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.krb5.internal.crypto=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED + * --add-exports java.security.jgss/sun.security.jgss.krb5=ALL-UNNAMED + * --add-exports java.base/sun.security.util=ALL-UNNAMED + * --add-exports java.base/jdk.internal.misc=ALL-UNNAMED + * --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED + * --add-opens java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED + * --add-opens java.base/sun.security.util=ALL-UNNAMED + * --enable-native-access=ALL-UNNAMED + * -Djava.library.path=${test.src}:.:${test.jdk}/lib + * -Djdk.net.hosts.file=TestHosts + * NativeCacheTest + */ + +import sun.security.krb5.Credentials; +import javax.security.auth.login.LoginContext; +import javax.security.auth.Subject; +import javax.security.auth.kerberos.KerberosTicket; +import java.io.File; + +/** + * Test JAAS access to in-memory credential caches. + * + * This test validates that JAAS can access MEMORY: credential caches + * on Linux through the native enhancement, using real TGTs from OneKDC. + */ +public class NativeCacheTest { + + public static void main(String[] args) throws Exception { + try { + // Create real TGT using OneKDC (in isolated cache) + createRealTGTWithOneKDC(); + + // Copy real TGT to in-memory cache using JNI + String inMemoryCacheName = copyTGTToInMemoryCache(); + + // Test JAAS access to in-memory cache + testJAASAccessToInMemoryCache(inMemoryCacheName); + + } catch (Exception e) { + System.err.println("Test failed: " + e.getMessage()); + throw e; + } + } + + /** + * Use OneKDC to create a real TGT via JAAS LoginModule + */ + private static void createRealTGTWithOneKDC() throws Exception { + System.out.println("Creating TGT via OneKDC"); + + OneKDC kdc = new OneKDC(null); + kdc.writeJAASConf(); + + // Force JAAS to save credentials to file cache for copying + System.setProperty("test.kdc.save.ccache", "onekdc_cache.ccache"); + + try { + // Authenticate using JAAS LoginModule + LoginContext lc = new LoginContext("com.sun.security.jgss.krb5.initiate", + new OneKDC.CallbackForClient()); + lc.login(); + + // Verify authentication + Subject subject = lc.getSubject(); + KerberosTicket ticket = subject.getPrivateCredentials(KerberosTicket.class).iterator().next(); + + System.out.println("JAAS authentication successful"); + System.out.println("TGT: " + ticket.getClient() + " -> " + ticket.getServer()); + + } catch (Exception e) { + System.out.println("JAAS authentication failed: " + e.getMessage()); + } + } + + /** + * Copy the real TGT to memory cache using JNI + */ + private static String copyTGTToInMemoryCache() throws Exception { + System.out.println("Copying credentials to memory cache"); + + String memoryCacheName = "MEMORY:test_" + System.currentTimeMillis(); + + // Create the memory cache + if (!NativeCredentialCacheHelper.createInMemoryCache(memoryCacheName)) { + throw new RuntimeException("Failed to create memory cache"); + } + System.out.println("Created memory cache: " + memoryCacheName); + + // Try to copy credentials from saved cache file + boolean copied = false; + File savedCache = new File("onekdc_cache.ccache"); + if (savedCache.exists()) { + System.out.println("Copying from: " + savedCache.getAbsolutePath()); + copied = NativeCredentialCacheHelper.copyCredentialsToInMemoryCache( + memoryCacheName, + "FILE:" + savedCache.getAbsolutePath() + ); + } + + // Fallback to default cache if file cache doesn't exist + if (!copied) { + copied = NativeCredentialCacheHelper.copyCredentialsToInMemoryCache(memoryCacheName, null); + } + + if (copied) { + System.out.println("Credentials copied to memory cache"); + } else { + System.out.println("No credentials found to copy"); + } + + // Set as default cache for JAAS testing + NativeCredentialCacheHelper.setDefaultCache(memoryCacheName); + System.setProperty("KRB5CCNAME", memoryCacheName); + + return memoryCacheName; + } + + /** + * Test JAAS access to the memory cache (the main test) + */ + private static void testJAASAccessToInMemoryCache(String inMemoryCacheName) throws Exception { + System.out.println("Testing JAAS access to an in-memory cache"); + + // Verify KRB5CCNAME points to our memory cache + String krb5ccname = System.getProperty("KRB5CCNAME"); + System.out.println("KRB5CCNAME is set to: " + krb5ccname); + System.out.println("Expected in-memory cache: " + inMemoryCacheName); + + if (!inMemoryCacheName.equals(krb5ccname)) { + System.out.println("ERROR: KRB5CCNAME does not point to our in-memory cache"); + throw new RuntimeException("test setup error - KRB5CCNAME not pointing to in-memory cache"); + } + + try { + Credentials creds = Credentials.acquireDefaultCreds(); + + if (creds != null) { + String client = creds.getClient().toString(); + String server = creds.getServer().toString(); + + System.out.println("SUCCESS: JAAS retrieved credentials from in-memory cache"); + System.out.println("Client: " + client); + System.out.println("Server: " + server); + + // Verify these are the OneKDC test credentials we copied + if (client.contains("dummy") && server.contains("RABBIT.HOLE")) { + System.out.println("SUCCESS: Retrieved correct OneKDC test credentials from in-memory cache"); + if (server.contains("krbtgt")) { + System.out.println("Retrieved TGT as expected"); + } + } else { + System.out.println("ERROR: JAAS retrieved wrong credentials from in-memory cache"); + System.out.println("Expected: dummy@RABBIT.HOLE -> krbtgt/RABBIT.HOLE@RABBIT.HOLE"); + System.out.println("Found: " + client + " -> " + server); + throw new RuntimeException("in-memory cache test failed - wrong credentials retrieved"); + } + + } else { + System.out.println("JAAS accessed in-memory cache but found no credentials"); + } + + } catch (Exception e) { + System.out.println("JAAS error: " + e.getMessage()); + } + } +} diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c new file mode 100644 index 0000000000000..35e17cebd98f1 --- /dev/null +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2025, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include +#include +#include +#include +#include // for access() +#include // for realpath() + +#include "NativeCredentialCacheHelper.h" + +// Global krb5 context - initialized once +static krb5_context g_context = NULL; + +// Initialize krb5 context with OneKDC config if available +static krb5_error_code ensure_context() { + // Always check for OneKDC config file and set environment + if (access("localkdc-krb5.conf", F_OK) != -1) { + char *current_path = realpath("localkdc-krb5.conf", NULL); + if (current_path != NULL) { + setenv("KRB5_CONFIG", current_path, 1); + free(current_path); + + // If context already exists, reinitialize it to pick up new config + if (g_context != NULL) { + krb5_free_context(g_context); + g_context = NULL; + } + } + } + + if (g_context == NULL) { + return krb5_init_context(&g_context); + } + return 0; +} + +// Utility function to convert Java string to C string +static char* jstring_to_cstring(JNIEnv *env, jstring jstr) { + if (jstr == NULL) return NULL; + + const char *utf_chars = (*env)->GetStringUTFChars(env, jstr, NULL); + if (utf_chars == NULL) return NULL; + + char *result = strdup(utf_chars); + (*env)->ReleaseStringUTFChars(env, jstr, utf_chars); + return result; +} + +// Print error message for krb5 errors +static void print_krb5_error(const char *operation, krb5_error_code code) { + if (code != 0) { + printf("krb5 error in %s: %s\n", operation, error_message(code)); + } +} + +/** + * Create an in-memory credential cache using native krb5 API. + * Creates a MEMORY: type cache that can be used for testing JAAS access + * to in-memory credential stores. + */ +JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCache + (JNIEnv *env, jclass cls, jstring cacheName) +{ + krb5_error_code ret; + krb5_ccache ccache; + char *cache_name = NULL; + + ret = ensure_context(); + if (ret) { + print_krb5_error("ensure_context", ret); + return JNI_FALSE; + } + + cache_name = jstring_to_cstring(env, cacheName); + if (cache_name == NULL) { + return JNI_FALSE; + } + + // Resolve the memory cache + ret = krb5_cc_resolve(g_context, cache_name, &ccache); + if (ret) { + print_krb5_error("krb5_cc_resolve", ret); + free(cache_name); + return JNI_FALSE; + } + + printf("Created memory cache: %s\n", cache_name); + + krb5_cc_close(g_context, ccache); + free(cache_name); + return JNI_TRUE; +} + + +/** + * Set the default credential cache to the specified credential cache. + * This makes the credential cache the target for credential lookups. + */ +JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_setDefaultCache + (JNIEnv *env, jclass cls, jstring cacheName) +{ + char *cache_name = jstring_to_cstring(env, cacheName); + if (cache_name == NULL) { + return JNI_FALSE; + } + + // Set KRB5CCNAME environment variable + if (setenv("KRB5CCNAME", cache_name, 1) != 0) { + free(cache_name); + return JNI_FALSE; + } + + printf("Set default cache to: %s\n", cache_name); + free(cache_name); + return JNI_TRUE; +} + + +/** + * Copy real Kerberos credentials from a source cache to a memory cache. + * This preserves the proper credential format so JAAS can access them. + * Used to move OneKDC-generated TGTs to in-memory caches for testing. + */ +JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInMemoryCache + (JNIEnv *env, jclass cls, jstring inMemoryCacheName, jstring sourceCacheName) +{ + krb5_error_code ret; + krb5_ccache source_ccache = NULL; + krb5_ccache in_memory_ccache = NULL; + krb5_cc_cursor cursor; + krb5_creds creds; + char *in_memory_cache_name = NULL; + char *source_cache_name = NULL; + int copied_count = 0; + + ret = ensure_context(); + if (ret) { + print_krb5_error("ensure_context", ret); + return JNI_FALSE; + } + + // Convert Java strings + in_memory_cache_name = jstring_to_cstring(env, inMemoryCacheName); + if (sourceCacheName != NULL) { + source_cache_name = jstring_to_cstring(env, sourceCacheName); + } + + if (!in_memory_cache_name) { + printf("Failed to get in-memory cache name\n"); + goto cleanup; + } + + printf("Copying credentials to in-memory cache: %s from source: %s\n", + in_memory_cache_name, + source_cache_name ? source_cache_name : "default cache" + ); + + // Open source cache (default if sourceCacheName is null) + if (source_cache_name) { + ret = krb5_cc_resolve(g_context, source_cache_name, &source_ccache); + if (ret) { + print_krb5_error("krb5_cc_resolve (source)", ret); + goto cleanup; + } + } else { + ret = krb5_cc_default(g_context, &source_ccache); + if (ret) { + print_krb5_error("krb5_cc_default", ret); + goto cleanup; + } + } + + // Open/resolve memory cache + ret = krb5_cc_resolve(g_context, in_memory_cache_name, &in_memory_ccache); + if (ret) { + print_krb5_error("krb5_cc_resolve (in-memory)", ret); + goto cleanup; + } + + // Get principal from source cache for initialization + krb5_principal principal = NULL; + ret = krb5_cc_get_principal(g_context, source_ccache, &principal); + if (ret) { + print_krb5_error("krb5_cc_get_principal", ret); + goto cleanup; + } + + // Initialize in-memory cache with the principal + ret = krb5_cc_initialize(g_context, in_memory_ccache, principal); + if (ret) { + print_krb5_error("krb5_cc_initialize", ret); + krb5_free_principal(g_context, principal); + goto cleanup; + } + + // Start credential cursor on source cache + ret = krb5_cc_start_seq_get(g_context, source_ccache, &cursor); + if (ret) { + print_krb5_error("krb5_cc_start_seq_get", ret); + krb5_free_principal(g_context, principal); + goto cleanup; + } + + // Copy each credential from source to memory cache + while ((ret = krb5_cc_next_cred(g_context, source_ccache, &cursor, &creds)) == 0) { + ret = krb5_cc_store_cred(g_context, in_memory_ccache, &creds); + if (ret) { + print_krb5_error("krb5_cc_store_cred", ret); + krb5_free_cred_contents(g_context, &creds); + break; + } + + printf("Copied in-memory credential: %s -> %s\n", + creds.client ? "client" : "unknown", + creds.server ? "server" : "unknown"); + + copied_count++; + krb5_free_cred_contents(g_context, &creds); + } + + // End the cursor (expected to return KRB5_CC_END) + krb5_cc_end_seq_get(g_context, source_ccache, &cursor); + + // Success if we copied at least one credential + if (copied_count > 0) { + printf("Successfully copied %d credentials to in-memory cache: %s\n", + copied_count, in_memory_cache_name); + ret = 0; + } else { + printf("No credentials found in source cache to copy to in-memory cache\n"); + ret = KRB5_CC_NOTFOUND; + } + + krb5_free_principal(g_context, principal); + +cleanup: + if (source_ccache) krb5_cc_close(g_context, source_ccache); + if (in_memory_ccache) krb5_cc_close(g_context, in_memory_ccache); + if (in_memory_cache_name) free(in_memory_cache_name); + if (source_cache_name) free(source_cache_name); + + return (ret == 0) ? JNI_TRUE : JNI_FALSE; +} + + + + diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java new file mode 100644 index 0000000000000..1dfaf4be24be2 --- /dev/null +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025, 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JNI wrapper for native Kerberos credential cache operations. + * Provides native methods to create MEMORY: credential caches and copy + * real Kerberos credentials to them for testing JAAS access. + */ +public class NativeCredentialCacheHelper { + + static { + try { + System.loadLibrary("nativecredentialcachehelper"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Failed to load nativecredentialcachehelper library: " + e.getMessage()); + throw e; + } + } + + /** + * Create an in-memory credential cache using native krb5 calls. + * @param cacheName The name for the in-memory cache (e.g., "MEMORY:test123") + * @return true if cache was created successfully, false otherwise + */ + public static native boolean createInMemoryCache(String cacheName); + + /** + * Copy real credentials from a source cache to the in-memory cache. + * This preserves the proper Kerberos credential format for JAAS access. + * @param inMemoryCacheName The target in-memory cache name (e.g., "MEMORY:test123") + * @param sourceCacheName The source cache name (null for default cache) + * @return true if credentials were copied successfully, false otherwise + */ + public static native boolean copyCredentialsToInMemoryCache(String inMemoryCacheName, String sourceCacheName); + + /** + * Set the default credential cache to the specified credential cache. + * @param cacheName The credential cache name to set as default + * @return true if set successfully, false otherwise + */ + public static native boolean setDefaultCache(String cacheName); +} + + + diff --git a/test/jdk/sun/security/krb5/native/TestHosts b/test/jdk/sun/security/krb5/native/TestHosts new file mode 100644 index 0000000000000..21fc88eacc56d --- /dev/null +++ b/test/jdk/sun/security/krb5/native/TestHosts @@ -0,0 +1,3 @@ +127.0.0.1 localhost +127.0.0.1 host.rabbit.hole +127.0.0.1 kdc.rabbit.hole diff --git a/test/jdk/sun/security/krb5/native/build.sh b/test/jdk/sun/security/krb5/native/build.sh new file mode 100755 index 0000000000000..d6ac9936874d7 --- /dev/null +++ b/test/jdk/sun/security/krb5/native/build.sh @@ -0,0 +1,90 @@ +#!/bin/bash +# Build script for NativeCacheTest - compiles Java classes and native library + +set -e + +# Use jtreg environment variables when available, fallback to manual calculation +if [ -n "$TESTJAVA" ]; then + # Running under jtreg + BUILT_JDK="$TESTJAVA" + JDK_ROOT="$(dirname $(dirname $TESTROOT))" + LIB_DIR="$JDK_ROOT/test/lib" + TEST_DIR="$TESTSRC" +else + # Running manually + TEST_DIR=$(pwd) + JDK_ROOT="$(cd ../../../../../../ && pwd)" + LIB_DIR="$JDK_ROOT/test/lib" + BUILT_JDK="$JDK_ROOT/build/linux-x86_64-server-release/jdk" +fi + +export JAVA_HOME="$BUILT_JDK" +export PATH="$BUILT_JDK/bin:$PATH" + +# Module exports required for Kerberos internal APIs +if [ -n "$TESTCLASSPATH" ]; then + # Use jtreg's prepared classpath + JAVA_CP="$TESTCLASSPATH" +else + # Manual execution classpath + JAVA_CP="$LIB_DIR:../auto:." +fi +MODULE_EXPORTS="--add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED \ +--add-exports java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED \ +--add-exports java.security.jgss/sun.security.krb5.internal.ccache=ALL-UNNAMED \ +--add-exports java.security.jgss/sun.security.krb5.internal.crypto=ALL-UNNAMED \ +--add-exports java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED \ +--add-exports java.security.jgss/sun.security.jgss.krb5=ALL-UNNAMED \ +--add-exports java.base/sun.security.util=ALL-UNNAMED \ +--add-exports java.base/jdk.internal.misc=ALL-UNNAMED" + +cd "$TEST_DIR" + +# For jtreg, classes are already compiled by the harness +# For manual execution, compile what's needed +if [ -z "$TESTJAVA" ]; then + # Manual execution - compile everything + + # Compile test library classes + cd "$LIB_DIR" + javac -cp . --add-exports java.base/jdk.internal.misc=ALL-UNNAMED jdk/test/lib/Platform.java + + # Compile OneKDC and test infrastructure + cd "$TEST_DIR/../auto" + javac -cp "$LIB_DIR:." $MODULE_EXPORTS -XDignore.symbol.file \ + KDC.java OneKDC.java Context.java + + cd "$TEST_DIR" + + # Compile test classes + javac -cp "$JAVA_CP" $MODULE_EXPORTS -XDignore.symbol.file \ + NativeCredentialCacheHelper.java NativeCacheTest.java +fi + +# Generate JNI header (always needed for native compilation) +cd "$TEST_DIR" +if [ -n "$TESTCLASSPATH" ]; then + javac -cp "$TESTCLASSPATH" -h . NativeCredentialCacheHelper.java +else + javac -cp . -h . NativeCredentialCacheHelper.java +fi + +# get the OS +OS=$(uname -s | tr 'A-Z' 'a-z') +if [ "$OS" == "linux" ]; then + COMPILER=gcc + LIBEXT=so +elif [ "$OS" == "darwin" ]; then + COMPILER=clang + LIBEXT=dylib +else + echo "Unsupported os: ${OS}" + exit 1 +fi + +# Compile native library (work from test source directory) +cd "$TEST_DIR" +${COMPILER} -shared -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/${OS}" -lkrb5 \ + -o libnativecredentialcachehelper.${LIBEXT} NativeCredentialCacheHelper.c + +echo "Build completed successfully" From 2e6cd029686576220b38d777b192b523b9682764 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 30 Oct 2025 18:31:45 -0400 Subject: [PATCH 02/17] Fix permissions on build.sh --- test/jdk/sun/security/krb5/native/build.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 test/jdk/sun/security/krb5/native/build.sh diff --git a/test/jdk/sun/security/krb5/native/build.sh b/test/jdk/sun/security/krb5/native/build.sh old mode 100755 new mode 100644 From 307c3f285fd84436d93b35663051c8f37e3e1b2d Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 30 Oct 2025 18:58:25 -0400 Subject: [PATCH 03/17] Tidy up comments/docs --- .../security/krb5/native/NativeCacheTest.java | 20 +++++----- .../krb5/native/NativeCredentialCacheHelper.c | 38 +++++++++---------- test/jdk/sun/security/krb5/native/build.sh | 15 ++++---- 3 files changed, 35 insertions(+), 38 deletions(-) diff --git a/test/jdk/sun/security/krb5/native/NativeCacheTest.java b/test/jdk/sun/security/krb5/native/NativeCacheTest.java index f3df9a5aeea72..df7bd2ded8e2b 100644 --- a/test/jdk/sun/security/krb5/native/NativeCacheTest.java +++ b/test/jdk/sun/security/krb5/native/NativeCacheTest.java @@ -89,7 +89,7 @@ public static void main(String[] args) throws Exception { } /** - * Use OneKDC to create a real TGT via JAAS LoginModule + * Use OneKDC to create a real TGT via the JAAS LoginModule */ private static void createRealTGTWithOneKDC() throws Exception { System.out.println("Creating TGT via OneKDC"); @@ -101,7 +101,7 @@ private static void createRealTGTWithOneKDC() throws Exception { System.setProperty("test.kdc.save.ccache", "onekdc_cache.ccache"); try { - // Authenticate using JAAS LoginModule + // Authenticate using the JAAS LoginModule LoginContext lc = new LoginContext("com.sun.security.jgss.krb5.initiate", new OneKDC.CallbackForClient()); lc.login(); @@ -119,20 +119,20 @@ private static void createRealTGTWithOneKDC() throws Exception { } /** - * Copy the real TGT to memory cache using JNI + * Copy the real TGT to an in-memory cache using JNI */ private static String copyTGTToInMemoryCache() throws Exception { System.out.println("Copying credentials to memory cache"); String memoryCacheName = "MEMORY:test_" + System.currentTimeMillis(); - // Create the memory cache + // Create the in-memory cache if (!NativeCredentialCacheHelper.createInMemoryCache(memoryCacheName)) { throw new RuntimeException("Failed to create memory cache"); } System.out.println("Created memory cache: " + memoryCacheName); - // Try to copy credentials from saved cache file + // Try to copy credentials from the saved cache file boolean copied = false; File savedCache = new File("onekdc_cache.ccache"); if (savedCache.exists()) { @@ -143,7 +143,7 @@ private static String copyTGTToInMemoryCache() throws Exception { ); } - // Fallback to default cache if file cache doesn't exist + // Fallback to the default cache if the file cache doesn't exist if (!copied) { copied = NativeCredentialCacheHelper.copyCredentialsToInMemoryCache(memoryCacheName, null); } @@ -154,7 +154,7 @@ private static String copyTGTToInMemoryCache() throws Exception { System.out.println("No credentials found to copy"); } - // Set as default cache for JAAS testing + // Set as the default cache for JAAS testing NativeCredentialCacheHelper.setDefaultCache(memoryCacheName); System.setProperty("KRB5CCNAME", memoryCacheName); @@ -162,12 +162,12 @@ private static String copyTGTToInMemoryCache() throws Exception { } /** - * Test JAAS access to the memory cache (the main test) + * Test JAAS access to an in-memory cache */ private static void testJAASAccessToInMemoryCache(String inMemoryCacheName) throws Exception { System.out.println("Testing JAAS access to an in-memory cache"); - // Verify KRB5CCNAME points to our memory cache + // Verify KRB5CCNAME points to our in-memory cache String krb5ccname = System.getProperty("KRB5CCNAME"); System.out.println("KRB5CCNAME is set to: " + krb5ccname); System.out.println("Expected in-memory cache: " + inMemoryCacheName); @@ -188,7 +188,7 @@ private static void testJAASAccessToInMemoryCache(String inMemoryCacheName) thro System.out.println("Client: " + client); System.out.println("Server: " + server); - // Verify these are the OneKDC test credentials we copied + // Verify these are the OneKDC test credentials if (client.contains("dummy") && server.contains("RABBIT.HOLE")) { System.out.println("SUCCESS: Retrieved correct OneKDC test credentials from in-memory cache"); if (server.contains("krbtgt")) { diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c index 35e17cebd98f1..68df803aa2ddc 100644 --- a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c @@ -26,24 +26,26 @@ #include #include #include -#include // for access() -#include // for realpath() +#include +#include #include "NativeCredentialCacheHelper.h" -// Global krb5 context - initialized once +// Global krb5 context static krb5_context g_context = NULL; -// Initialize krb5 context with OneKDC config if available +/** + * Initialize krb5 context with OneKDC config + */ static krb5_error_code ensure_context() { - // Always check for OneKDC config file and set environment + // Check if OneKDC config file exists or needs to be created if (access("localkdc-krb5.conf", F_OK) != -1) { char *current_path = realpath("localkdc-krb5.conf", NULL); if (current_path != NULL) { setenv("KRB5_CONFIG", current_path, 1); free(current_path); - // If context already exists, reinitialize it to pick up new config + // If context already exists, reinitialize it if (g_context != NULL) { krb5_free_context(g_context); g_context = NULL; @@ -57,7 +59,9 @@ static krb5_error_code ensure_context() { return 0; } -// Utility function to convert Java string to C string +/** + * Convert Java string to C string + */ static char* jstring_to_cstring(JNIEnv *env, jstring jstr) { if (jstr == NULL) return NULL; @@ -69,7 +73,9 @@ static char* jstring_to_cstring(JNIEnv *env, jstring jstr) { return result; } -// Print error message for krb5 errors +/** + * Print error messages for krb5 errors + */ static void print_krb5_error(const char *operation, krb5_error_code code) { if (code != 0) { printf("krb5 error in %s: %s\n", operation, error_message(code)); @@ -78,8 +84,6 @@ static void print_krb5_error(const char *operation, krb5_error_code code) { /** * Create an in-memory credential cache using native krb5 API. - * Creates a MEMORY: type cache that can be used for testing JAAS access - * to in-memory credential stores. */ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCache (JNIEnv *env, jclass cls, jstring cacheName) @@ -114,10 +118,8 @@ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCache return JNI_TRUE; } - /** - * Set the default credential cache to the specified credential cache. - * This makes the credential cache the target for credential lookups. + * Set KRB5CCNAME so that the test will pick up the in-memory credential cache. */ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_setDefaultCache (JNIEnv *env, jclass cls, jstring cacheName) @@ -140,9 +142,9 @@ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_setDefaultCache /** - * Copy real Kerberos credentials from a source cache to a memory cache. - * This preserves the proper credential format so JAAS can access them. - * Used to move OneKDC-generated TGTs to in-memory caches for testing. + * Copy real Kerberos credentials from a source cache to an in-memory cache. + * in-memory cache. Used to move OneKDC-generated TGTs to an in-memory cache + * for testing. */ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInMemoryCache (JNIEnv *env, jclass cls, jstring inMemoryCacheName, jstring sourceCacheName) @@ -264,7 +266,3 @@ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInM return (ret == 0) ? JNI_TRUE : JNI_FALSE; } - - - - diff --git a/test/jdk/sun/security/krb5/native/build.sh b/test/jdk/sun/security/krb5/native/build.sh index d6ac9936874d7..0c9433e60b146 100644 --- a/test/jdk/sun/security/krb5/native/build.sh +++ b/test/jdk/sun/security/krb5/native/build.sh @@ -1,9 +1,9 @@ #!/bin/bash -# Build script for NativeCacheTest - compiles Java classes and native library +# Build script for NativeCacheTest set -e -# Use jtreg environment variables when available, fallback to manual calculation +# Use jtreg environment variables when available if [ -n "$TESTJAVA" ]; then # Running under jtreg BUILT_JDK="$TESTJAVA" @@ -23,7 +23,7 @@ export PATH="$BUILT_JDK/bin:$PATH" # Module exports required for Kerberos internal APIs if [ -n "$TESTCLASSPATH" ]; then - # Use jtreg's prepared classpath + # Use the jtreg classpath JAVA_CP="$TESTCLASSPATH" else # Manual execution classpath @@ -41,9 +41,8 @@ MODULE_EXPORTS="--add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED \ cd "$TEST_DIR" # For jtreg, classes are already compiled by the harness -# For manual execution, compile what's needed if [ -z "$TESTJAVA" ]; then - # Manual execution - compile everything + # Manual execution # Compile test library classes cd "$LIB_DIR" @@ -61,7 +60,7 @@ if [ -z "$TESTJAVA" ]; then NativeCredentialCacheHelper.java NativeCacheTest.java fi -# Generate JNI header (always needed for native compilation) +# Generate JNI header cd "$TEST_DIR" if [ -n "$TESTCLASSPATH" ]; then javac -cp "$TESTCLASSPATH" -h . NativeCredentialCacheHelper.java @@ -69,7 +68,7 @@ else javac -cp . -h . NativeCredentialCacheHelper.java fi -# get the OS +# Get the OS to determine the compiler and library extension OS=$(uname -s | tr 'A-Z' 'a-z') if [ "$OS" == "linux" ]; then COMPILER=gcc @@ -82,7 +81,7 @@ else exit 1 fi -# Compile native library (work from test source directory) +# Compile native library cd "$TEST_DIR" ${COMPILER} -shared -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/${OS}" -lkrb5 \ -o libnativecredentialcachehelper.${LIBEXT} NativeCredentialCacheHelper.c From 5106d31a272b95dfa76b1f3591e82249a1a91eb3 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 30 Oct 2025 19:19:00 -0400 Subject: [PATCH 04/17] eliminate build.sh in favour of jtreg primitives --- make/test/JtregNativeJdk.gmk | 3 + .../security/krb5/native/NativeCacheTest.java | 4 +- .../native/NativeCredentialCacheHelper.java | 4 +- test/jdk/sun/security/krb5/native/build.sh | 89 ------------------- ...per.c => libNativeCredentialCacheHelper.c} | 0 5 files changed, 6 insertions(+), 94 deletions(-) delete mode 100644 test/jdk/sun/security/krb5/native/build.sh rename test/jdk/sun/security/krb5/native/{NativeCredentialCacheHelper.c => libNativeCredentialCacheHelper.c} (100%) diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index a204467a77b47..5b4b2a7360d09 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -110,6 +110,9 @@ ifeq ($(call isTargetOs, linux), true) BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libCreationTimeHelper := -ldl endif +# Kerberos native test library needs krb5 and com_err libraries +BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := -lkrb5 -lcom_err + ifeq ($(ASAN_ENABLED), true) # Any executable which launches the JVM and uses a custom launcher needs to explicitly link in the # default ASan options. diff --git a/test/jdk/sun/security/krb5/native/NativeCacheTest.java b/test/jdk/sun/security/krb5/native/NativeCacheTest.java index df7bd2ded8e2b..5476042769482 100644 --- a/test/jdk/sun/security/krb5/native/NativeCacheTest.java +++ b/test/jdk/sun/security/krb5/native/NativeCacheTest.java @@ -37,9 +37,8 @@ * --add-exports java.base/sun.security.util=ALL-UNNAMED * --add-exports java.base/jdk.internal.misc=ALL-UNNAMED * NativeCacheTest.java - * @run shell build.sh * @run main jdk.test.lib.FileInstaller TestHosts TestHosts - * @run main/othervm + * @run main/othervm/native * --add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED * --add-exports java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED * --add-exports java.security.jgss/sun.security.krb5.internal.ccache=ALL-UNNAMED @@ -52,7 +51,6 @@ * --add-opens java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED * --add-opens java.base/sun.security.util=ALL-UNNAMED * --enable-native-access=ALL-UNNAMED - * -Djava.library.path=${test.src}:.:${test.jdk}/lib * -Djdk.net.hosts.file=TestHosts * NativeCacheTest */ diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java index 1dfaf4be24be2..511d35ce88ba5 100644 --- a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java @@ -30,9 +30,9 @@ public class NativeCredentialCacheHelper { static { try { - System.loadLibrary("nativecredentialcachehelper"); + System.loadLibrary("NativeCredentialCacheHelper"); } catch (UnsatisfiedLinkError e) { - System.err.println("Failed to load nativecredentialcachehelper library: " + e.getMessage()); + System.err.println("Failed to load NativeCredentialCacheHelper library: " + e.getMessage()); throw e; } } diff --git a/test/jdk/sun/security/krb5/native/build.sh b/test/jdk/sun/security/krb5/native/build.sh deleted file mode 100644 index 0c9433e60b146..0000000000000 --- a/test/jdk/sun/security/krb5/native/build.sh +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/bash -# Build script for NativeCacheTest - -set -e - -# Use jtreg environment variables when available -if [ -n "$TESTJAVA" ]; then - # Running under jtreg - BUILT_JDK="$TESTJAVA" - JDK_ROOT="$(dirname $(dirname $TESTROOT))" - LIB_DIR="$JDK_ROOT/test/lib" - TEST_DIR="$TESTSRC" -else - # Running manually - TEST_DIR=$(pwd) - JDK_ROOT="$(cd ../../../../../../ && pwd)" - LIB_DIR="$JDK_ROOT/test/lib" - BUILT_JDK="$JDK_ROOT/build/linux-x86_64-server-release/jdk" -fi - -export JAVA_HOME="$BUILT_JDK" -export PATH="$BUILT_JDK/bin:$PATH" - -# Module exports required for Kerberos internal APIs -if [ -n "$TESTCLASSPATH" ]; then - # Use the jtreg classpath - JAVA_CP="$TESTCLASSPATH" -else - # Manual execution classpath - JAVA_CP="$LIB_DIR:../auto:." -fi -MODULE_EXPORTS="--add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED \ ---add-exports java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED \ ---add-exports java.security.jgss/sun.security.krb5.internal.ccache=ALL-UNNAMED \ ---add-exports java.security.jgss/sun.security.krb5.internal.crypto=ALL-UNNAMED \ ---add-exports java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED \ ---add-exports java.security.jgss/sun.security.jgss.krb5=ALL-UNNAMED \ ---add-exports java.base/sun.security.util=ALL-UNNAMED \ ---add-exports java.base/jdk.internal.misc=ALL-UNNAMED" - -cd "$TEST_DIR" - -# For jtreg, classes are already compiled by the harness -if [ -z "$TESTJAVA" ]; then - # Manual execution - - # Compile test library classes - cd "$LIB_DIR" - javac -cp . --add-exports java.base/jdk.internal.misc=ALL-UNNAMED jdk/test/lib/Platform.java - - # Compile OneKDC and test infrastructure - cd "$TEST_DIR/../auto" - javac -cp "$LIB_DIR:." $MODULE_EXPORTS -XDignore.symbol.file \ - KDC.java OneKDC.java Context.java - - cd "$TEST_DIR" - - # Compile test classes - javac -cp "$JAVA_CP" $MODULE_EXPORTS -XDignore.symbol.file \ - NativeCredentialCacheHelper.java NativeCacheTest.java -fi - -# Generate JNI header -cd "$TEST_DIR" -if [ -n "$TESTCLASSPATH" ]; then - javac -cp "$TESTCLASSPATH" -h . NativeCredentialCacheHelper.java -else - javac -cp . -h . NativeCredentialCacheHelper.java -fi - -# Get the OS to determine the compiler and library extension -OS=$(uname -s | tr 'A-Z' 'a-z') -if [ "$OS" == "linux" ]; then - COMPILER=gcc - LIBEXT=so -elif [ "$OS" == "darwin" ]; then - COMPILER=clang - LIBEXT=dylib -else - echo "Unsupported os: ${OS}" - exit 1 -fi - -# Compile native library -cd "$TEST_DIR" -${COMPILER} -shared -fPIC -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/${OS}" -lkrb5 \ - -o libnativecredentialcachehelper.${LIBEXT} NativeCredentialCacheHelper.c - -echo "Build completed successfully" diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c similarity index 100% rename from test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.c rename to test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c From 33407d4aaeccd5da6ec5b5e628ce8fb67209c32b Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 30 Oct 2025 19:30:11 -0400 Subject: [PATCH 05/17] more comment fixes --- .../security/krb5/native/NativeCredentialCacheHelper.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java index 511d35ce88ba5..4e3b3767a93d9 100644 --- a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java @@ -38,15 +38,15 @@ public class NativeCredentialCacheHelper { } /** - * Create an in-memory credential cache using native krb5 calls. + * Create an in-memory credential cache using native krb5 API. * @param cacheName The name for the in-memory cache (e.g., "MEMORY:test123") * @return true if cache was created successfully, false otherwise */ public static native boolean createInMemoryCache(String cacheName); /** - * Copy real credentials from a source cache to the in-memory cache. - * This preserves the proper Kerberos credential format for JAAS access. + * Copy real Kerberos credentials from a source cache to an in-memory cache. + * Used to move OneKDC-generated TGTs to an in-memory cache for testing. * @param inMemoryCacheName The target in-memory cache name (e.g., "MEMORY:test123") * @param sourceCacheName The source cache name (null for default cache) * @return true if credentials were copied successfully, false otherwise @@ -54,7 +54,7 @@ public class NativeCredentialCacheHelper { public static native boolean copyCredentialsToInMemoryCache(String inMemoryCacheName, String sourceCacheName); /** - * Set the default credential cache to the specified credential cache. + * Set KRB5CCNAME so that the test will pick up the in-memory credential cache. * @param cacheName The credential cache name to set as default * @return true if set successfully, false otherwise */ From 1a28cee2e351b21dab0b3c505605c72183ee4f83 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 30 Oct 2025 20:00:54 -0400 Subject: [PATCH 06/17] Add specific MacOS jtreg compiler flags to fix deprecation warnings --- make/test/JtregNativeJdk.gmk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index 5b4b2a7360d09..b810b073e8ffe 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -113,6 +113,11 @@ endif # Kerberos native test library needs krb5 and com_err libraries BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := -lkrb5 -lcom_err +ifeq ($(call isTargetOs, macosx), true) + # On macOS, disable deprecation warnings for krb5 API + BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper := -Wno-deprecated-declarations +endif + ifeq ($(ASAN_ENABLED), true) # Any executable which launches the JVM and uses a custom launcher needs to explicitly link in the # default ASan options. From 5cad1e417f0666255fc0edf1a542ee6126da8af2 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 30 Oct 2025 20:48:16 -0400 Subject: [PATCH 07/17] Add missing .h file to PR --- .../krb5/native/NativeCredentialCacheHelper.h | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.h diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.h b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.h new file mode 100644 index 0000000000000..43760ff18480b --- /dev/null +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.h @@ -0,0 +1,37 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class NativeCredentialCacheHelper */ + +#ifndef _Included_NativeCredentialCacheHelper +#define _Included_NativeCredentialCacheHelper +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: NativeCredentialCacheHelper + * Method: createInMemoryCache + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCache + (JNIEnv *, jclass, jstring); + +/* + * Class: NativeCredentialCacheHelper + * Method: copyCredentialsToInMemoryCache + * Signature: (Ljava/lang/String;Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInMemoryCache + (JNIEnv *, jclass, jstring, jstring); + +/* + * Class: NativeCredentialCacheHelper + * Method: setDefaultCache + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_setDefaultCache + (JNIEnv *, jclass, jstring); + +#ifdef __cplusplus +} +#endif +#endif From bc904b0ef170db1a0dcfd65c0fce525370203cfb Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 30 Oct 2025 21:03:37 -0400 Subject: [PATCH 08/17] Fixes to ensure that the jtreg test is not built or executed if krb5 is not installed --- make/test/JtregNativeJdk.gmk | 18 ++++++++++++------ .../security/krb5/native/NativeCacheTest.java | 3 +++ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index b810b073e8ffe..e2e26c56190d5 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -110,12 +110,18 @@ ifeq ($(call isTargetOs, linux), true) BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libCreationTimeHelper := -ldl endif -# Kerberos native test library needs krb5 and com_err libraries -BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := -lkrb5 -lcom_err - -ifeq ($(call isTargetOs, macosx), true) - # On macOS, disable deprecation warnings for krb5 API - BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper := -Wno-deprecated-declarations +# Kerberos native test library - only build if krb5 is available +ifeq ($(ENABLE_LIBLINUXKRB5), true) + BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := $(KRB5_LIBS) + BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper := $(KRB5_CFLAGS) + + ifeq ($(call isTargetOs, macosx), true) + # On macOS, disable deprecation warnings for krb5 API + BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper += -Wno-deprecated-declarations + endif +else + # Exclude the Kerberos test library if krb5 is not available + BUILD_JDK_JTREG_EXCLUDE += libNativeCredentialCacheHelper.c endif ifeq ($(ASAN_ENABLED), true) diff --git a/test/jdk/sun/security/krb5/native/NativeCacheTest.java b/test/jdk/sun/security/krb5/native/NativeCacheTest.java index 5476042769482..741d19d081c3f 100644 --- a/test/jdk/sun/security/krb5/native/NativeCacheTest.java +++ b/test/jdk/sun/security/krb5/native/NativeCacheTest.java @@ -80,6 +80,9 @@ public static void main(String[] args) throws Exception { // Test JAAS access to in-memory cache testJAASAccessToInMemoryCache(inMemoryCacheName); + } catch (UnsatisfiedLinkError e) { + System.out.println("Kerberos native library not available - test skipped"); + return; } catch (Exception e) { System.err.println("Test failed: " + e.getMessage()); throw e; From 3ea9793866ac44fed2e1b18f6da162bb4b530dbe Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Fri, 31 Oct 2025 18:15:49 -0400 Subject: [PATCH 09/17] Attend to @erikj79's code review comments --- make/autoconf/lib-krb5.m4 | 186 +++++++++++++++++++++----------- make/autoconf/libraries.m4 | 7 -- make/autoconf/spec.gmk.template | 2 +- make/test/JtregNativeJdk.gmk | 23 ++-- 4 files changed, 140 insertions(+), 78 deletions(-) diff --git a/make/autoconf/lib-krb5.m4 b/make/autoconf/lib-krb5.m4 index 5dfd28695234c..754fc3816c929 100644 --- a/make/autoconf/lib-krb5.m4 +++ b/make/autoconf/lib-krb5.m4 @@ -29,85 +29,149 @@ AC_DEFUN_ONCE([LIB_SETUP_KRB5], [ AC_ARG_WITH(krb5, [AS_HELP_STRING([--with-krb5], - [enable krb5 support (default=yes), or "no" to disable])]) - - # Determine if krb5 should be disabled - KRB5_DISABLED=no - if test "x${with_krb5}" = xno; then - AC_MSG_NOTICE([krb5 explicitly disabled]) - KRB5_DISABLED=yes - elif test "x$NEEDS_LIB_KRB5" = xfalse; then - if test "x${with_krb5}" != x && test "x${with_krb5}" != xno; then - AC_MSG_WARN([[krb5 not used, so --with-krb5 is ignored]]) - fi - KRB5_DISABLED=yes - fi + [specify prefix directory for the krb5 package on Linux, or use "yes/no/auto" (default=auto)])]) + AC_ARG_WITH(krb5-include, [AS_HELP_STRING([--with-krb5-include], + [specify directory for the krb5 include files on Linux])]) + AC_ARG_WITH(krb5-lib, [AS_HELP_STRING([--with-krb5-lib], + [specify directory for the krb5 library on Linux])]) + + KRB5_CFLAGS= + KRB5_LIBS= + ENABLE_LIBKRB5_LINUX=false - if test "x$KRB5_DISABLED" = xyes; then - KRB5_CFLAGS= - KRB5_LIBS= - ENABLE_LIBLINUXKRB5=false + if test "x$OPENJDK_TARGET_OS" != "xlinux" && test "x${with_krb5}" = "xyes"; then + AC_MSG_ERROR([krb5 support is only available on Linux]) else - # First try pkg-config (most modern approach) - AC_PATH_TOOL([PKG_CONFIG], [pkg-config], [no]) - use_pkgconfig_for_krb5=no - - if test "x$PKG_CONFIG" != "xno"; then - AC_MSG_CHECKING([if pkg-config knows about krb5]) - if $PKG_CONFIG --exists krb5; then - AC_MSG_RESULT([yes]) - use_pkgconfig_for_krb5=yes - else - AC_MSG_RESULT([no]) + KRB5_FOUND=no + + if test "x${with_krb5}" != "x" && test "x${with_krb5}" != "xyes" && test "x${with_krb5}" != "xauto"; then + # if a path was provided, use it + if test "x${with_krb5}" != "x"; then + AC_MSG_CHECKING([for krb5]) + KRB5_LIBS="-L${with_krb5}/lib -lkrb5 -lcom_err" + KRB5_CFLAGS="-I${with_krb5}/include" + KRB5_FOUND=yes + AC_MSG_RESULT([${with_krb5}]) fi fi - if test "x$use_pkgconfig_for_krb5" = "xyes"; then - # Use pkg-config to get compiler and linker flags - AC_MSG_CHECKING([for krb5 cflags via pkg-config]) - KRB5_CFLAGS="`$PKG_CONFIG --cflags krb5`" - AC_MSG_RESULT([$KRB5_CFLAGS]) + if test "x${with_krb5_include}" != "x"; then + AC_MSG_CHECKING([for krb5 includes]) + KRB5_CFLAGS="-I${with_krb5_include}" + KRB5_FOUND=yes + AC_MSG_RESULT([${with_krb5_include}]) + fi - AC_MSG_CHECKING([for krb5 libs via pkg-config]) - KRB5_LIBS="`$PKG_CONFIG --libs krb5`" - AC_MSG_RESULT([$KRB5_LIBS]) + if test "x${with_krb5_lib}" != "x"; then + AC_MSG_CHECKING([for krb5 libs]) + KRB5_LIBS="-L${with_krb5_lib} -lkrb5 -lcom_err" + KRB5_FOUND=yes + AC_MSG_RESULT([${with_krb5_lib}]) + fi - ENABLE_LIBLINUXKRB5=true - else - # Fallback: try krb5-config - AC_PATH_TOOL([KRB5CONF], [krb5-config], [no]) + if test "x$KRB5_FOUND" = "xno"; then + if test "x$SYSROOT" != "x"; then + AC_MSG_CHECKING([for krb5 ($SYSROOT)]) + # Cross-compilation with SYSROOT - look at known locations in SYSROOT. + KRB5_LIB_PATH="" + COM_ERR_LIB_PATH="" + + # Look for libkrb5/libcom_err + if test -f "$SYSROOT/usr/lib64/libkrb5.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + KRB5_LIB_PATH="$SYSROOT/usr/lib64" + elif test -f "$SYSROOT/usr/lib/libkrb5.so"; then + KRB5_LIB_PATH="$SYSROOT/usr/lib" + elif test -f "$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libkrb5.so"; then + KRB5_LIB_PATH="$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI" + elif test -f "$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libkrb5.so"; then + KRB5_LIB_PATH="$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI" + fi + + if test -f "$KRB5_LIB_PATH/libcom_err.so"; then + COM_ERR_LIB_PATH="$KRB5_LIB_PATH" + elif test -f "$SYSROOT/usr/lib64/libcom_err.so" && test "x$OPENJDK_TARGET_CPU_BITS" = x64; then + COM_ERR_LIB_PATH="$SYSROOT/usr/lib64" + elif test -f "$SYSROOT/usr/lib/libcom_err.so"; then + COM_ERR_LIB_PATH="$SYSROOT/usr/lib" + elif test -f "$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libcom_err.so"; then + COM_ERR_LIB_PATH="$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI" + elif test -f "$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI/libcom_err.so"; then + COM_ERR_LIB_PATH="$SYSROOT/usr/lib/$OPENJDK_TARGET_CPU_AUTOCONF-$OPENJDK_TARGET_OS-$OPENJDK_TARGET_ABI" + fi - if test "x$KRB5CONF" != "xno"; then - # Use krb5-config to get compiler and linker flags - AC_MSG_CHECKING([for krb5 cflags via krb5-config]) - KRB5_CFLAGS="`$KRB5CONF --cflags`" - AC_MSG_RESULT([$KRB5_CFLAGS]) + # Check for matching include files + KRB5_INCLUDE_PATH="" + COM_ERR_INCLUDE_PATH="" - AC_MSG_CHECKING([for krb5 libs via krb5-config]) - KRB5_LIBS="`$KRB5CONF --libs`" - AC_MSG_RESULT([$KRB5_LIBS]) + if test -f "$SYSROOT/usr/include/krb5/krb5.h"; then + KRB5_INCLUDE_PATH="$SYSROOT/usr/include" + fi - ENABLE_LIBLINUXKRB5=true + if test -f "$SYSROOT/usr/include/com_err.h"; then + COM_ERR_INCLUDE_PATH="$SYSROOT/usr/include" + fi + + # Check everything was found and merge paths + if test "x$KRB5_LIB_PATH" != "x" && test "x$COM_ERR_LIB_PATH" != "x" && \ + test "x$KRB5_INCLUDE_PATH" != "x" && test "x$COM_ERR_INCLUDE_PATH" != "x"; then + KRB5_LIBS="-L$KRB5_LIB_PATH -lkrb5" + if test "x$COM_ERR_LIB_PATH" != "x" && test "x$COM_ERR_LIB_PATH" != "x$KRB5_LIB_PATH"; then + KRB5_LIBS="$KRB5_LIBS -L$COM_ERR_LIB_PATH" + fi + KRB5_LIBS="$KRB5_LIBS -lcom_err" + + KRB5_CFLAGS="-I$KRB5_INCLUDE_PATH" + if test "x$COM_ERR_INCLUDE_PATH" != "x" && test "x$COM_ERR_INCLUDE_PATH" != "x$KRB5_INCLUDE_PATH"; then + KRB5_CFLAGS="$KRB5_CFLAGS -I$COM_ERR_INCLUDE_PATH" + fi + + KRB5_FOUND=yes + fi + AC_MSG_RESULT([$KRB5_FOUND]) else - # Final fallback: try manual detection in system locations - AC_CHECK_HEADERS([krb5.h], [ + PKG_CHECK_MODULES(KRB5, krb5, [KRB5_FOUND=yes], [KRB5_FOUND=no]) + if test "x$KRB5_FOUND" = "xno"; then + UTIL_LOOKUP_PROGS(KRB5CONF, krb5-config) + if test "x$KRB5CONF" != "x"; then + AC_MSG_CHECKING([for krb5 using krb5-config]) + KRB5_CFLAGS="`$KRB5CONF --cflags`" + KRB5_LIBS="`$KRB5CONF --libs`" + KRB5_FOUND=yes + AC_MSG_RESULT([$KRB5_FOUND]) + fi + fi + fi + fi + + # No sysconfig/pkg-config/krb5-config, so auto-detect + if test "x$KRB5_FOUND" = "xno"; then + AC_CHECK_HEADERS([krb5.h], [ + AC_CHECK_HEADERS([com_err.h], [ AC_CHECK_LIB([krb5], [krb5_init_context], [ KRB5_CFLAGS="" KRB5_LIBS="-lkrb5" - # Check for com_err header and library which are often required - AC_CHECK_HEADERS([com_err.h], [ - AC_CHECK_LIB([com_err], [com_err], [ - KRB5_LIBS="$KRB5_LIBS -lcom_err" - ]) + AC_CHECK_LIB([com_err], [com_err], [ + KRB5_LIBS="$KRB5_LIBS -lcom_err" ]) - ENABLE_LIBLINUXKRB5=true - ], [ENABLE_LIBLINUXKRB5=false]) - ], [ENABLE_LIBLINUXKRB5=false]) + KRB5_FOUND=yes + ]) + ]) + ]) + fi + + if test "x$KRB5_FOUND" = "xno"; then + if test "x${with_krb5}" = "xyes"; then + AC_MSG_ERROR([krb5 was required but could not be found]) fi + KRB5_CFLAGS= + KRB5_LIBS= + ENABLE_LIBKRB5_LINUX=false + else + ENABLE_LIBKRB5_LINUX=true fi fi AC_SUBST(KRB5_CFLAGS) AC_SUBST(KRB5_LIBS) - AC_SUBST(ENABLE_LIBLINUXKRB5) -]) + AC_SUBST(ENABLE_LIBKRB5_LINUX) +]) \ No newline at end of file diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4 index 926ea5994629d..063a7c95b8f13 100644 --- a/make/autoconf/libraries.m4 +++ b/make/autoconf/libraries.m4 @@ -82,13 +82,6 @@ AC_DEFUN_ONCE([LIB_DETERMINE_DEPENDENCIES], NEEDS_LIB_ALSA=false fi - # Check if krb5 is needed - if test "x$OPENJDK_TARGET_OS" = xlinux -o "x$OPENJDK_TARGET_OS" = xmacosx; then - NEEDS_LIB_KRB5=true - else - NEEDS_LIB_KRB5=false - fi - # Check if ffi is needed if HOTSPOT_CHECK_JVM_VARIANT(zero) || test "x$ENABLE_FALLBACK_LINKER" = "xtrue"; then NEEDS_LIB_FFI=true diff --git a/make/autoconf/spec.gmk.template b/make/autoconf/spec.gmk.template index 41ad307f9cabd..9e3f7dc7e1f0d 100644 --- a/make/autoconf/spec.gmk.template +++ b/make/autoconf/spec.gmk.template @@ -437,7 +437,7 @@ ALSA_LIBS := @ALSA_LIBS@ ALSA_CFLAGS := @ALSA_CFLAGS@ KRB5_LIBS := @KRB5_LIBS@ KRB5_CFLAGS := @KRB5_CFLAGS@ -ENABLE_LIBLINUXKRB5 := @ENABLE_LIBLINUXKRB5@ +ENABLE_LIBKRB5_LINUX := @ENABLE_LIBKRB5_LINUX@ LIBFFI_LIBS := @LIBFFI_LIBS@ LIBFFI_CFLAGS := @LIBFFI_CFLAGS@ ENABLE_LIBFFI_BUNDLING := @ENABLE_LIBFFI_BUNDLING@ diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index e2e26c56190d5..74b26a4ba61cb 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -110,17 +110,22 @@ ifeq ($(call isTargetOs, linux), true) BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libCreationTimeHelper := -ldl endif -# Kerberos native test library - only build if krb5 is available -ifeq ($(ENABLE_LIBLINUXKRB5), true) - BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := $(KRB5_LIBS) - BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper := $(KRB5_CFLAGS) - - ifeq ($(call isTargetOs, macosx), true) - # On macOS, disable deprecation warnings for krb5 API - BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper += -Wno-deprecated-declarations +# Kerberos native test library configuration +ifeq ($(call isTargetOs, linux), true) + # Linux: only build if krb5 is enabled and working + ifeq ($(ENABLE_LIBKRB5_LINUX), true) + BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := $(KRB5_LIBS) + BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper := $(KRB5_CFLAGS) + else + # Exclude the Kerberos test library if krb5 is not available on Linux + BUILD_JDK_JTREG_EXCLUDE += libNativeCredentialCacheHelper.c endif +else ifeq ($(call isTargetOs, macosx), true) + # macOS: build with system krb5 and disable deprecation warnings + BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := -lkrb5 -lcom_err + BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper := -Wno-deprecated-declarations else - # Exclude the Kerberos test library if krb5 is not available + # Other platforms: exclude the library BUILD_JDK_JTREG_EXCLUDE += libNativeCredentialCacheHelper.c endif From d58d41723efaaf152d12c0abe1956ca8a844d5f8 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Fri, 31 Oct 2025 18:39:38 -0400 Subject: [PATCH 10/17] Minor variable/function name and comment clean-ups --- .../security/krb5/native/NativeCacheTest.java | 28 +++++++++---------- .../native/libNativeCredentialCacheHelper.c | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/test/jdk/sun/security/krb5/native/NativeCacheTest.java b/test/jdk/sun/security/krb5/native/NativeCacheTest.java index 741d19d081c3f..7becb4218c871 100644 --- a/test/jdk/sun/security/krb5/native/NativeCacheTest.java +++ b/test/jdk/sun/security/krb5/native/NativeCacheTest.java @@ -64,17 +64,17 @@ /** * Test JAAS access to in-memory credential caches. * - * This test validates that JAAS can access MEMORY: credential caches - * on Linux through the native enhancement, using real TGTs from OneKDC. + * This test validates that JAAS can access in-memory credential caches + * on Linux through the native enhancement, using TGTs from OneKDC. */ public class NativeCacheTest { public static void main(String[] args) throws Exception { try { - // Create real TGT using OneKDC (in isolated cache) - createRealTGTWithOneKDC(); + // Create TGT using OneKDC (in file cache) + createTGTWithOneKDC(); - // Copy real TGT to in-memory cache using JNI + // Copy TGT to in-memory cache using JNI String inMemoryCacheName = copyTGTToInMemoryCache(); // Test JAAS access to in-memory cache @@ -90,9 +90,9 @@ public static void main(String[] args) throws Exception { } /** - * Use OneKDC to create a real TGT via the JAAS LoginModule + * Use OneKDC to create a TGT via the JAAS LoginModule */ - private static void createRealTGTWithOneKDC() throws Exception { + private static void createTGTWithOneKDC() throws Exception { System.out.println("Creating TGT via OneKDC"); OneKDC kdc = new OneKDC(null); @@ -120,7 +120,7 @@ private static void createRealTGTWithOneKDC() throws Exception { } /** - * Copy the real TGT to an in-memory cache using JNI + * Copy the TGT to an in-memory cache using JNI */ private static String copyTGTToInMemoryCache() throws Exception { System.out.println("Copying credentials to memory cache"); @@ -133,18 +133,18 @@ private static String copyTGTToInMemoryCache() throws Exception { } System.out.println("Created memory cache: " + memoryCacheName); - // Try to copy credentials from the saved cache file + // Try to copy credentials from the file cache boolean copied = false; - File savedCache = new File("onekdc_cache.ccache"); - if (savedCache.exists()) { - System.out.println("Copying from: " + savedCache.getAbsolutePath()); + File fileCache = new File("onekdc_cache.ccache"); + if (fileCache.exists()) { + System.out.println("Copying from: " + fileCache.getAbsolutePath()); copied = NativeCredentialCacheHelper.copyCredentialsToInMemoryCache( memoryCacheName, - "FILE:" + savedCache.getAbsolutePath() + "FILE:" + fileCache.getAbsolutePath() ); } - // Fallback to the default cache if the file cache doesn't exist + // Fallback to the default cache if copying from file cache fails if (!copied) { copied = NativeCredentialCacheHelper.copyCredentialsToInMemoryCache(memoryCacheName, null); } diff --git a/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c index 68df803aa2ddc..344f03a270697 100644 --- a/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c +++ b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c @@ -180,7 +180,7 @@ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInM source_cache_name ? source_cache_name : "default cache" ); - // Open source cache (default if sourceCacheName is null) + // Open source cache (or default cache if sourceCacheName is null) if (source_cache_name) { ret = krb5_cc_resolve(g_context, source_cache_name, &source_ccache); if (ret) { From 47968fe78eae78968a811f3e03b3101769fb2725 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Fri, 31 Oct 2025 18:44:44 -0400 Subject: [PATCH 11/17] Minor doc/comment clean-ups --- .../share/classes/sun/security/krb5/Credentials.java | 4 ++-- .../share/native/libkrb5shared/nativeccache.c | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java index 1348f970a8d2b..e9fb0875436de 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java @@ -329,7 +329,7 @@ public static Credentials acquireTGTFromCache(PrincipalName princ, // On Windows/MacOSX/Linux, use native system library calls to acquire // credentials from any supported credential cache types on those // platforms (in particular, the default ticket cache on Windows and - // Mac is not a file, so cannot use the pure Java code) + // MacOSX is not a file, so cannot use the pure Java code) if (OperatingSystem.isWindows() || OperatingSystem.isMacOS() || OperatingSystem.isLinux()) { @@ -415,7 +415,7 @@ public static Credentials acquireTGTFromCache(PrincipalName princ, // It assumes that the GSS call has // the privilege to access the default cache file. - // This method is only called on Windows, Mac OS X and Linux, the native + // This method is only called on Windows, MacOSX and Linux, the native // acquireDefaultNativeCreds is also available on these platforms. public static synchronized Credentials acquireDefaultCreds() { Credentials result = null; diff --git a/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c b/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c index d6c7cf4f8d22d..4a98ec544e208 100644 --- a/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c +++ b/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c @@ -24,11 +24,7 @@ */ /* - * Unified Kerberos native credential cache implementation for Mac OS X and Linux. - * This implementation consolidates the previously separate platform-specific - * implementations while maintaining platform-specific library names. - * - * Platform-specific differences are handled via conditional compilation. + * Unified Kerberos native credential cache implementation for MacOSX/Linux. */ #include "sun_security_krb5_Credentials.h" From 8c8288a31ce7df55444212039d05464df45d25c9 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Mon, 3 Nov 2025 13:44:01 -0500 Subject: [PATCH 12/17] Address second set of @erikj79's build comments --- make/autoconf/lib-krb5.m4 | 14 ++++++++++++-- make/modules/java.security.jgss/Lib.gmk | 6 +++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/make/autoconf/lib-krb5.m4 b/make/autoconf/lib-krb5.m4 index 754fc3816c929..93c6bc35108e5 100644 --- a/make/autoconf/lib-krb5.m4 +++ b/make/autoconf/lib-krb5.m4 @@ -41,6 +41,9 @@ AC_DEFUN_ONCE([LIB_SETUP_KRB5], if test "x$OPENJDK_TARGET_OS" != "xlinux" && test "x${with_krb5}" = "xyes"; then AC_MSG_ERROR([krb5 support is only available on Linux]) + elif test "x${with_krb5}" = "xno"; then + AC_MSG_CHECKING([for krb5]) + AC_MSG_RESULT([disabled]) else KRB5_FOUND=no @@ -129,7 +132,14 @@ AC_DEFUN_ONCE([LIB_SETUP_KRB5], fi AC_MSG_RESULT([$KRB5_FOUND]) else - PKG_CHECK_MODULES(KRB5, krb5, [KRB5_FOUND=yes], [KRB5_FOUND=no]) + if test "x$PKG_CONFIG" != "x" ; then + PKG_CHECK_MODULES(KRB5, krb5, [KRB5_FOUND=yes], [KRB5_FOUND=no]) + if test "x$KRB5_FOUND" = "xyes" ; then + AC_MSG_CHECKING([for krb5]) + AC_MSG_RESULT([yes (using pkg-config)]) + fi + fi + if test "x$KRB5_FOUND" = "xno"; then UTIL_LOOKUP_PROGS(KRB5CONF, krb5-config) if test "x$KRB5CONF" != "x"; then @@ -174,4 +184,4 @@ AC_DEFUN_ONCE([LIB_SETUP_KRB5], AC_SUBST(KRB5_CFLAGS) AC_SUBST(KRB5_LIBS) AC_SUBST(ENABLE_LIBKRB5_LINUX) -]) \ No newline at end of file +]) diff --git a/make/modules/java.security.jgss/Lib.gmk b/make/modules/java.security.jgss/Lib.gmk index 57dc5d4af539c..8024f1641d118 100644 --- a/make/modules/java.security.jgss/Lib.gmk +++ b/make/modules/java.security.jgss/Lib.gmk @@ -98,8 +98,8 @@ ifneq ($(BUILD_CRYPTO), false) endif ifeq ($(call isTargetOs, linux), true) - ifeq ($(ENABLE_LIBLINUXKRB5), true) - $(eval $(call SetupJdkLibrary, BUILD_LIBLINUXKRB5, \ + ifeq ($(ENABLE_LIBKRB5_LINUX), true) + $(eval $(call SetupJdkLibrary, BUILD_LIBKRB5_LINUX, \ NAME := linuxkrb5, \ OPTIMIZATION := LOW, \ DISABLED_WARNINGS_clang_nativeccache.c := deprecated-declarations, \ @@ -109,7 +109,7 @@ ifneq ($(BUILD_CRYPTO), false) LIBS_linux := $(KRB5_LIBS) $(COM_ERR_LIBS), \ )) - TARGETS += $(BUILD_LIBLINUXKRB5) + TARGETS += $(BUILD_LIBKRB5_LINUX) endif endif From f4a8543fc3e9ccd489f22d30cac949bc249c8ea0 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Wed, 12 Nov 2025 06:48:02 -0500 Subject: [PATCH 13/17] Attend to @smemery's code review comments --- make/test/JtregNativeJdk.gmk | 4 ++-- .../share/classes/sun/security/krb5/Credentials.java | 2 +- .../share/native/libkrb5shared/nativeccache.c | 2 +- test/jdk/sun/security/krb5/native/NativeCacheTest.java | 1 - .../sun/security/krb5/native/libNativeCredentialCacheHelper.c | 3 ++- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/make/test/JtregNativeJdk.gmk b/make/test/JtregNativeJdk.gmk index 74b26a4ba61cb..dece0fb4954f2 100644 --- a/make/test/JtregNativeJdk.gmk +++ b/make/test/JtregNativeJdk.gmk @@ -122,8 +122,8 @@ ifeq ($(call isTargetOs, linux), true) endif else ifeq ($(call isTargetOs, macosx), true) # macOS: build with system krb5 and disable deprecation warnings - BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := -lkrb5 -lcom_err - BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper := -Wno-deprecated-declarations + BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libNativeCredentialCacheHelper := $(KRB5_LIBS) + BUILD_JDK_JTREG_LIBRARIES_CFLAGS_libNativeCredentialCacheHelper := $(KRB5_CFLAGS) -Wno-deprecated-declarations else # Other platforms: exclude the library BUILD_JDK_JTREG_EXCLUDE += libNativeCredentialCacheHelper.c diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java index e9fb0875436de..9577e02b008a4 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2025, 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 diff --git a/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c b/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c index 4a98ec544e208..819d3ddeb93f2 100644 --- a/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c +++ b/src/java.security.jgss/share/native/libkrb5shared/nativeccache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2025, 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 diff --git a/test/jdk/sun/security/krb5/native/NativeCacheTest.java b/test/jdk/sun/security/krb5/native/NativeCacheTest.java index 7becb4218c871..5572e8e91c3ce 100644 --- a/test/jdk/sun/security/krb5/native/NativeCacheTest.java +++ b/test/jdk/sun/security/krb5/native/NativeCacheTest.java @@ -23,7 +23,6 @@ /* * @test - * @bug 8123456 * @summary Test JAAS access to in-memory credential caches * @library /test/lib ../auto * @requires os.family != "windows" diff --git a/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c index 344f03a270697..94e19f4ec7a9e 100644 --- a/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c +++ b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c @@ -69,6 +69,8 @@ static char* jstring_to_cstring(JNIEnv *env, jstring jstr) { if (utf_chars == NULL) return NULL; char *result = strdup(utf_chars); + if (result == NULL) return NULL; + (*env)->ReleaseStringUTFChars(env, jstr, utf_chars); return result; } @@ -140,7 +142,6 @@ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_setDefaultCache return JNI_TRUE; } - /** * Copy real Kerberos credentials from a source cache to an in-memory cache. * in-memory cache. Used to move OneKDC-generated TGTs to an in-memory cache From 98417c379059dbd612008b3dd43e5803af8b5946 Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 13 Nov 2025 05:03:02 -0500 Subject: [PATCH 14/17] Attend to remaining comments from @smemery --- .../share/classes/sun/security/krb5/Credentials.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java index 9577e02b008a4..a73a52642ae18 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java @@ -330,9 +330,8 @@ public static Credentials acquireTGTFromCache(PrincipalName princ, // credentials from any supported credential cache types on those // platforms (in particular, the default ticket cache on Windows and // MacOSX is not a file, so cannot use the pure Java code) - if (OperatingSystem.isWindows() || - OperatingSystem.isMacOS() || - OperatingSystem.isLinux()) { + if (OperatingSystem.isWindows() || OperatingSystem.isMacOS() + || OperatingSystem.isLinux()) { Credentials creds = acquireDefaultCreds(); if (creds == null) { if (DEBUG != null) { From 369070219187d406fa05c1faabf4952ee23e306b Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 13 Nov 2025 05:50:14 -0500 Subject: [PATCH 15/17] Attend to @wangweij's code review comments - in particular a large clean-up of the test helper and the output it creates --- .../security/krb5/native/NativeCacheTest.java | 77 +++----- .../krb5/native/NativeCredentialCacheHelper.h | 47 +++-- .../native/NativeCredentialCacheHelper.java | 32 ++-- .../native/libNativeCredentialCacheHelper.c | 174 +++++++----------- 4 files changed, 129 insertions(+), 201 deletions(-) diff --git a/test/jdk/sun/security/krb5/native/NativeCacheTest.java b/test/jdk/sun/security/krb5/native/NativeCacheTest.java index 5572e8e91c3ce..0b49659f32ca5 100644 --- a/test/jdk/sun/security/krb5/native/NativeCacheTest.java +++ b/test/jdk/sun/security/krb5/native/NativeCacheTest.java @@ -122,42 +122,25 @@ private static void createTGTWithOneKDC() throws Exception { * Copy the TGT to an in-memory cache using JNI */ private static String copyTGTToInMemoryCache() throws Exception { - System.out.println("Copying credentials to memory cache"); + System.out.println("Creating in-memory cache and copying TGT from file cache"); - String memoryCacheName = "MEMORY:test_" + System.currentTimeMillis(); - - // Create the in-memory cache - if (!NativeCredentialCacheHelper.createInMemoryCache(memoryCacheName)) { - throw new RuntimeException("Failed to create memory cache"); - } - System.out.println("Created memory cache: " + memoryCacheName); - - // Try to copy credentials from the file cache - boolean copied = false; + // Check that the FILE: ccache exists File fileCache = new File("onekdc_cache.ccache"); - if (fileCache.exists()) { - System.out.println("Copying from: " + fileCache.getAbsolutePath()); - copied = NativeCredentialCacheHelper.copyCredentialsToInMemoryCache( - memoryCacheName, - "FILE:" + fileCache.getAbsolutePath() - ); + if (!fileCache.exists()) { + throw new RuntimeException("File cache does not exist: " + fileCache.getAbsolutePath()); } - // Fallback to the default cache if copying from file cache fails - if (!copied) { - copied = NativeCredentialCacheHelper.copyCredentialsToInMemoryCache(memoryCacheName, null); - } - - if (copied) { - System.out.println("Credentials copied to memory cache"); - } else { - System.out.println("No credentials found to copy"); + // Create MEMORY: ccache from the FILE: ccache + String memoryCacheName = "MEMORY:test_" + System.currentTimeMillis(); + if (!NativeCredentialCacheHelper.createInMemoryCacheFromFileCache( + memoryCacheName, "FILE:" + fileCache.getAbsolutePath())) { + throw new RuntimeException("Failed to create in-memory cache from file cache"); } - // Set as the default cache for JAAS testing - NativeCredentialCacheHelper.setDefaultCache(memoryCacheName); System.setProperty("KRB5CCNAME", memoryCacheName); + System.out.println("Successfully created in-memory cache with credentials: " + memoryCacheName); + return memoryCacheName; } @@ -177,36 +160,26 @@ private static void testJAASAccessToInMemoryCache(String inMemoryCacheName) thro throw new RuntimeException("test setup error - KRB5CCNAME not pointing to in-memory cache"); } - try { - Credentials creds = Credentials.acquireDefaultCreds(); + Credentials creds = Credentials.acquireDefaultCreds(); - if (creds != null) { - String client = creds.getClient().toString(); - String server = creds.getServer().toString(); + if (creds != null) { + String client = creds.getClient().toString(); + String server = creds.getServer().toString(); - System.out.println("SUCCESS: JAAS retrieved credentials from in-memory cache"); + // Verify these are the OneKDC test credentials + if (client.contains("dummy") && server.contains("RABBIT.HOLE") && server.contains("krbtgt")) { + System.out.println("SUCCESS: Retrieved correct OneKDC test credentials from in-memory cache"); System.out.println("Client: " + client); System.out.println("Server: " + server); - - // Verify these are the OneKDC test credentials - if (client.contains("dummy") && server.contains("RABBIT.HOLE")) { - System.out.println("SUCCESS: Retrieved correct OneKDC test credentials from in-memory cache"); - if (server.contains("krbtgt")) { - System.out.println("Retrieved TGT as expected"); - } - } else { - System.out.println("ERROR: JAAS retrieved wrong credentials from in-memory cache"); - System.out.println("Expected: dummy@RABBIT.HOLE -> krbtgt/RABBIT.HOLE@RABBIT.HOLE"); - System.out.println("Found: " + client + " -> " + server); - throw new RuntimeException("in-memory cache test failed - wrong credentials retrieved"); - } - } else { - System.out.println("JAAS accessed in-memory cache but found no credentials"); + System.out.println("ERROR: JAAS retrieved wrong credentials from in-memory cache"); + System.out.println("Expected: dummy@RABBIT.HOLE -> krbtgt/RABBIT.HOLE@RABBIT.HOLE"); + System.out.println("Found: " + client + " -> " + server); + throw new RuntimeException("in-memory cache test failed - wrong credentials retrieved"); } - - } catch (Exception e) { - System.out.println("JAAS error: " + e.getMessage()); + } else { + System.out.println("ERROR: JAAS accessed in-memory cache but found no credentials"); + throw new RuntimeException("in-memory cache test failed - no credentials retrieved"); } } } diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.h b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.h index 43760ff18480b..23ad7fa78d3a9 100644 --- a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.h +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.h @@ -1,4 +1,29 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ +/* + * Copyright (c) 2025, 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 + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class NativeCredentialCacheHelper */ @@ -9,28 +34,12 @@ extern "C" { #endif /* * Class: NativeCredentialCacheHelper - * Method: createInMemoryCache - * Signature: (Ljava/lang/String;)Z - */ -JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCache - (JNIEnv *, jclass, jstring); - -/* - * Class: NativeCredentialCacheHelper - * Method: copyCredentialsToInMemoryCache + * Method: createInMemoryCacheFromFileCache * Signature: (Ljava/lang/String;Ljava/lang/String;)Z */ -JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInMemoryCache +JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCacheFromFileCache (JNIEnv *, jclass, jstring, jstring); -/* - * Class: NativeCredentialCacheHelper - * Method: setDefaultCache - * Signature: (Ljava/lang/String;)Z - */ -JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_setDefaultCache - (JNIEnv *, jclass, jstring); - #ifdef __cplusplus } #endif diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java index 4e3b3767a93d9..6cee067db7d66 100644 --- a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java @@ -38,27 +38,19 @@ public class NativeCredentialCacheHelper { } /** - * Create an in-memory credential cache using native krb5 API. - * @param cacheName The name for the in-memory cache (e.g., "MEMORY:test123") - * @return true if cache was created successfully, false otherwise + * Creates an in-memory credential cache, copies credentials from a file cache, + * and sets it as the default cache in one atomic operation. + * + * This method performs all three operations required to set up an in-memory cache: + * 1. Creates the in-memory cache using native krb5 API + * 2. Copies real Kerberos credentials from the file cache to the in-memory cache + * 3. Sets KRB5CCNAME so that JAAS will use the in-memory cache + * + * @param inMemoryCacheName The name for the in-memory cache (e.g., "MEMORY:test123") + * @param fileCacheName The file cache name to copy from (e.g., "FILE:/path/to/cache") + * @return true if all operations succeeded, false if any operation failed */ - public static native boolean createInMemoryCache(String cacheName); - - /** - * Copy real Kerberos credentials from a source cache to an in-memory cache. - * Used to move OneKDC-generated TGTs to an in-memory cache for testing. - * @param inMemoryCacheName The target in-memory cache name (e.g., "MEMORY:test123") - * @param sourceCacheName The source cache name (null for default cache) - * @return true if credentials were copied successfully, false otherwise - */ - public static native boolean copyCredentialsToInMemoryCache(String inMemoryCacheName, String sourceCacheName); - - /** - * Set KRB5CCNAME so that the test will pick up the in-memory credential cache. - * @param cacheName The credential cache name to set as default - * @return true if set successfully, false otherwise - */ - public static native boolean setDefaultCache(String cacheName); + public static native boolean createInMemoryCacheFromFileCache(String inMemoryCacheName, String fileCacheName); } diff --git a/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c index 94e19f4ec7a9e..8ee8794dd8e1f 100644 --- a/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c +++ b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c @@ -85,78 +85,19 @@ static void print_krb5_error(const char *operation, krb5_error_code code) { } /** - * Create an in-memory credential cache using native krb5 API. + * Creates an in-memory credential cache, copies credentials from a file cache, + * and sets it as the default cache in one atomic operation. */ -JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCache - (JNIEnv *env, jclass cls, jstring cacheName) +JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCacheFromFileCache + (JNIEnv *env, jclass cls, jstring inMemoryCacheName, jstring fileCacheName) { krb5_error_code ret; - krb5_ccache ccache; - char *cache_name = NULL; - - ret = ensure_context(); - if (ret) { - print_krb5_error("ensure_context", ret); - return JNI_FALSE; - } - - cache_name = jstring_to_cstring(env, cacheName); - if (cache_name == NULL) { - return JNI_FALSE; - } - - // Resolve the memory cache - ret = krb5_cc_resolve(g_context, cache_name, &ccache); - if (ret) { - print_krb5_error("krb5_cc_resolve", ret); - free(cache_name); - return JNI_FALSE; - } - - printf("Created memory cache: %s\n", cache_name); - - krb5_cc_close(g_context, ccache); - free(cache_name); - return JNI_TRUE; -} - -/** - * Set KRB5CCNAME so that the test will pick up the in-memory credential cache. - */ -JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_setDefaultCache - (JNIEnv *env, jclass cls, jstring cacheName) -{ - char *cache_name = jstring_to_cstring(env, cacheName); - if (cache_name == NULL) { - return JNI_FALSE; - } - - // Set KRB5CCNAME environment variable - if (setenv("KRB5CCNAME", cache_name, 1) != 0) { - free(cache_name); - return JNI_FALSE; - } - - printf("Set default cache to: %s\n", cache_name); - free(cache_name); - return JNI_TRUE; -} - -/** - * Copy real Kerberos credentials from a source cache to an in-memory cache. - * in-memory cache. Used to move OneKDC-generated TGTs to an in-memory cache - * for testing. - */ -JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInMemoryCache - (JNIEnv *env, jclass cls, jstring inMemoryCacheName, jstring sourceCacheName) -{ - krb5_error_code ret; - krb5_ccache source_ccache = NULL; + krb5_ccache file_ccache = NULL; krb5_ccache in_memory_ccache = NULL; krb5_cc_cursor cursor; krb5_creds creds; char *in_memory_cache_name = NULL; - char *source_cache_name = NULL; + char *file_cache_name = NULL; int copied_count = 0; ret = ensure_context(); @@ -165,49 +106,39 @@ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInM return JNI_FALSE; } - // Convert Java strings in_memory_cache_name = jstring_to_cstring(env, inMemoryCacheName); - if (sourceCacheName != NULL) { - source_cache_name = jstring_to_cstring(env, sourceCacheName); - } - - if (!in_memory_cache_name) { - printf("Failed to get in-memory cache name\n"); + file_cache_name = jstring_to_cstring(env, fileCacheName); + if (!in_memory_cache_name || !file_cache_name) { + printf("Failed to get file or in-memory cache names\n"); goto cleanup; } - printf("Copying credentials to in-memory cache: %s from source: %s\n", - in_memory_cache_name, - source_cache_name ? source_cache_name : "default cache" - ); + printf("Creating in-memory cache: %s from file cache: %s\n", + in_memory_cache_name, file_cache_name); - // Open source cache (or default cache if sourceCacheName is null) - if (source_cache_name) { - ret = krb5_cc_resolve(g_context, source_cache_name, &source_ccache); - if (ret) { - print_krb5_error("krb5_cc_resolve (source)", ret); - goto cleanup; - } - } else { - ret = krb5_cc_default(g_context, &source_ccache); - if (ret) { - print_krb5_error("krb5_cc_default", ret); - goto cleanup; - } + // Resolve FILE: ccache + ret = krb5_cc_resolve(g_context, file_cache_name, &file_ccache); + if (ret) { + print_krb5_error("krb5_cc_resolve (file cache)", ret); + printf("ERROR: File cache does not exist or cannot be accessed: %s\n", file_cache_name); + goto cleanup; } - // Open/resolve memory cache + // Resolve in-memory cache ret = krb5_cc_resolve(g_context, in_memory_cache_name, &in_memory_ccache); if (ret) { print_krb5_error("krb5_cc_resolve (in-memory)", ret); goto cleanup; } - // Get principal from source cache for initialization + printf("Created in-memory cache: %s\n", in_memory_cache_name); + + // Get principal from file cache for initialization krb5_principal principal = NULL; - ret = krb5_cc_get_principal(g_context, source_ccache, &principal); + ret = krb5_cc_get_principal(g_context, file_ccache, &principal); if (ret) { print_krb5_error("krb5_cc_get_principal", ret); + printf("ERROR: Cannot get principal from file cache: %s\n", file_cache_name); goto cleanup; } @@ -219,16 +150,15 @@ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInM goto cleanup; } - // Start credential cursor on source cache - ret = krb5_cc_start_seq_get(g_context, source_ccache, &cursor); + // Copy credentials from file cache to in-memory cache + ret = krb5_cc_start_seq_get(g_context, file_ccache, &cursor); if (ret) { print_krb5_error("krb5_cc_start_seq_get", ret); krb5_free_principal(g_context, principal); goto cleanup; } - // Copy each credential from source to memory cache - while ((ret = krb5_cc_next_cred(g_context, source_ccache, &cursor, &creds)) == 0) { + while ((ret = krb5_cc_next_cred(g_context, file_ccache, &cursor, &creds)) == 0) { ret = krb5_cc_store_cred(g_context, in_memory_ccache, &creds); if (ret) { print_krb5_error("krb5_cc_store_cred", ret); @@ -236,34 +166,58 @@ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_copyCredentialsToInM break; } - printf("Copied in-memory credential: %s -> %s\n", - creds.client ? "client" : "unknown", - creds.server ? "server" : "unknown"); + // Print the actual credential names + char *client_name = NULL; + char *server_name = NULL; + if (creds.client) { + krb5_unparse_name(g_context, creds.client, &client_name); + } + if (creds.server) { + krb5_unparse_name(g_context, creds.server, &server_name); + } + + printf("Copied credential: %s -> %s\n", + client_name ? client_name : "unknown", + server_name ? server_name : "unknown"); + + if (client_name) krb5_free_unparsed_name(g_context, client_name); + if (server_name) krb5_free_unparsed_name(g_context, server_name); copied_count++; krb5_free_cred_contents(g_context, &creds); } // End the cursor (expected to return KRB5_CC_END) - krb5_cc_end_seq_get(g_context, source_ccache, &cursor); - - // Success if we copied at least one credential - if (copied_count > 0) { - printf("Successfully copied %d credentials to in-memory cache: %s\n", - copied_count, in_memory_cache_name); - ret = 0; - } else { - printf("No credentials found in source cache to copy to in-memory cache\n"); + krb5_cc_end_seq_get(g_context, file_ccache, &cursor); + + if (copied_count == 0) { + printf("ERROR: No credentials found in file cache to copy: %s\n", file_cache_name); ret = KRB5_CC_NOTFOUND; + krb5_free_principal(g_context, principal); + goto cleanup; } + printf("Successfully copied %d credentials to in-memory cache: %s\n", + copied_count, in_memory_cache_name); + + // Set KRB5CCNAME environment variable to point to in-memory cache + if (setenv("KRB5CCNAME", in_memory_cache_name, 1) != 0) { + printf("ERROR: Failed to set KRB5CCNAME environment variable\n"); + ret = -1; + krb5_free_principal(g_context, principal); + goto cleanup; + } + + printf("Set KRB5CCNAME to: %s\n", in_memory_cache_name); + ret = 0; krb5_free_principal(g_context, principal); cleanup: - if (source_ccache) krb5_cc_close(g_context, source_ccache); + if (file_ccache) krb5_cc_close(g_context, file_ccache); + if (file_cache_name) free(file_cache_name); + if (in_memory_ccache) krb5_cc_close(g_context, in_memory_ccache); if (in_memory_cache_name) free(in_memory_cache_name); - if (source_cache_name) free(source_cache_name); return (ret == 0) ? JNI_TRUE : JNI_FALSE; } From d7ea6c9e6a6f838627efa8983d8d2ec9a1c46b9f Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Thu, 13 Nov 2025 05:54:51 -0500 Subject: [PATCH 16/17] Small doc fix --- .../native/NativeCredentialCacheHelper.java | 17 ++++++----------- .../native/libNativeCredentialCacheHelper.c | 4 ++-- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java index 6cee067db7d66..3c2e980357cde 100644 --- a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java @@ -23,8 +23,8 @@ /** * JNI wrapper for native Kerberos credential cache operations. - * Provides native methods to create MEMORY: credential caches and copy - * real Kerberos credentials to them for testing JAAS access. + * Provides native methods to create in-memory credential caches and copy + * Kerberos credentials from file credential caches for testing JAAS access. */ public class NativeCredentialCacheHelper { @@ -38,16 +38,11 @@ public class NativeCredentialCacheHelper { } /** - * Creates an in-memory credential cache, copies credentials from a file cache, - * and sets it as the default cache in one atomic operation. + * Creates an in-memory credential ccache, copies credentials from a file ccache, + * and sets KRB5CCNAME to the in-memory ccache. * - * This method performs all three operations required to set up an in-memory cache: - * 1. Creates the in-memory cache using native krb5 API - * 2. Copies real Kerberos credentials from the file cache to the in-memory cache - * 3. Sets KRB5CCNAME so that JAAS will use the in-memory cache - * - * @param inMemoryCacheName The name for the in-memory cache (e.g., "MEMORY:test123") - * @param fileCacheName The file cache name to copy from (e.g., "FILE:/path/to/cache") + * @param inMemoryCacheName The name for the MEMORY: ccache (e.g., "MEMORY:test123") + * @param fileCacheName The FILE: ccache name to copy from (e.g., "FILE:/path/to/cache") * @return true if all operations succeeded, false if any operation failed */ public static native boolean createInMemoryCacheFromFileCache(String inMemoryCacheName, String fileCacheName); diff --git a/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c index 8ee8794dd8e1f..a9604c2b70499 100644 --- a/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c +++ b/test/jdk/sun/security/krb5/native/libNativeCredentialCacheHelper.c @@ -85,8 +85,8 @@ static void print_krb5_error(const char *operation, krb5_error_code code) { } /** - * Creates an in-memory credential cache, copies credentials from a file cache, - * and sets it as the default cache in one atomic operation. + * Creates an in-memory credential ccache, copies credentials from a file ccache, + * and sets KRB5CCNAME to the in-memory ccache. */ JNIEXPORT jboolean JNICALL Java_NativeCredentialCacheHelper_createInMemoryCacheFromFileCache (JNIEnv *env, jclass cls, jstring inMemoryCacheName, jstring fileCacheName) From ed56092b0e324bf34dfad788cdf267f9505f987f Mon Sep 17 00:00:00 2001 From: Nick Hall Date: Tue, 18 Nov 2025 07:13:48 -0500 Subject: [PATCH 17/17] Clean up jtreg run/compile directives, attend to other review comments --- .../security/krb5/native/NativeCacheTest.java | 37 ++++++------------- .../native/NativeCredentialCacheHelper.java | 3 -- 2 files changed, 11 insertions(+), 29 deletions(-) diff --git a/test/jdk/sun/security/krb5/native/NativeCacheTest.java b/test/jdk/sun/security/krb5/native/NativeCacheTest.java index 0b49659f32ca5..f4b9c9e31c74d 100644 --- a/test/jdk/sun/security/krb5/native/NativeCacheTest.java +++ b/test/jdk/sun/security/krb5/native/NativeCacheTest.java @@ -24,34 +24,19 @@ /* * @test * @summary Test JAAS access to in-memory credential caches - * @library /test/lib ../auto + * @library /test/lib * @requires os.family != "windows" - * @compile -XDignore.symbol.file - * --add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.krb5.internal.ccache=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.krb5.internal.crypto=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.jgss.krb5=ALL-UNNAMED - * --add-exports java.base/sun.security.util=ALL-UNNAMED - * --add-exports java.base/jdk.internal.misc=ALL-UNNAMED - * NativeCacheTest.java + * @modules java.security.jgss/sun.security.krb5:+open + * java.security.jgss/sun.security.krb5.internal:+open + * java.security.jgss/sun.security.krb5.internal.ccache + * java.security.jgss/sun.security.krb5.internal.crypto + * java.security.jgss/sun.security.krb5.internal.ktab + * java.security.jgss/sun.security.jgss.krb5 + * java.base/sun.security.util:+open + * java.base/jdk.internal.misc + * @compile NativeCacheTest.java * @run main jdk.test.lib.FileInstaller TestHosts TestHosts - * @run main/othervm/native - * --add-exports java.security.jgss/sun.security.krb5=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.krb5.internal.ccache=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.krb5.internal.crypto=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.krb5.internal.ktab=ALL-UNNAMED - * --add-exports java.security.jgss/sun.security.jgss.krb5=ALL-UNNAMED - * --add-exports java.base/sun.security.util=ALL-UNNAMED - * --add-exports java.base/jdk.internal.misc=ALL-UNNAMED - * --add-opens java.security.jgss/sun.security.krb5=ALL-UNNAMED - * --add-opens java.security.jgss/sun.security.krb5.internal=ALL-UNNAMED - * --add-opens java.base/sun.security.util=ALL-UNNAMED - * --enable-native-access=ALL-UNNAMED - * -Djdk.net.hosts.file=TestHosts - * NativeCacheTest + * @run main/othervm/native --enable-native-access=ALL-UNNAMED -Djdk.net.hosts.file=TestHosts NativeCacheTest */ import sun.security.krb5.Credentials; diff --git a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java index 3c2e980357cde..27cd3b8ddefd8 100644 --- a/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java +++ b/test/jdk/sun/security/krb5/native/NativeCredentialCacheHelper.java @@ -47,6 +47,3 @@ public class NativeCredentialCacheHelper { */ public static native boolean createInMemoryCacheFromFileCache(String inMemoryCacheName, String fileCacheName); } - - -