From 874c52b13c2c16b516908ad9d6254fccda3f3d11 Mon Sep 17 00:00:00 2001 From: "U-D16\\weijwan" Date: Thu, 17 Oct 2024 19:55:09 -0400 Subject: [PATCH] in subject --- .../jgss/wrapper/NativeGSSContext.java | 69 ++++++++++++++++--- .../jgss/wrapper/NativeGSSFactory.java | 2 +- .../native/libw2k_lsa_auth/NativeCreds.c | 23 ++----- test/jdk/sun/security/krb5/GetSessionKey.java | 21 ++++-- 4 files changed, 83 insertions(+), 32 deletions(-) diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java index 23773fcad0c56..ee82f8c9bd24b 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java @@ -31,13 +31,14 @@ import java.lang.ref.Cleaner; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.security.Provider; -import sun.security.jgss.GSSHeader; -import sun.security.jgss.GSSUtil; -import sun.security.jgss.GSSExceptionImpl; -import sun.security.jgss.KerberosSessionKey; + +import sun.security.jgss.*; import sun.security.jgss.spi.*; import sun.security.krb5.Credentials; +import sun.security.krb5.KrbCred; import sun.security.krb5.KrbException; import sun.security.krb5.PrincipalName; import sun.security.krb5.internal.KerberosTime; @@ -46,8 +47,11 @@ import sun.security.util.ObjectIdentifier; import sun.security.jgss.spnego.NegTokenInit; import sun.security.jgss.spnego.NegTokenTarg; + +import javax.security.auth.Subject; import javax.security.auth.kerberos.DelegationPermission; import javax.security.auth.kerberos.EncryptionKey; +import javax.security.auth.kerberos.KerberosTicket; import java.io.*; /** @@ -309,6 +313,47 @@ public byte[] initSecContext(InputStream is, int mechTokenLen) (outToken == null ? 0 : outToken.length)); } + if ((inToken == null || inToken.length == 0) && GSSUtil.useSubjectCredsOnly(GSSCaller.CALLER_UNKNOWN)) { + // first time + if (OperatingSystem.isWindows()) { + Object[] nativeCreds = Credentials.queryNativeCreds(); + for (int i = 0; i < nativeCreds.length; i++) { + try { + KrbCred cred = new KrbCred((byte[])nativeCreds[i], null); + System.out.println(cred.getDelegatedCreds()[0].getServer()); + System.out.println(this.targetName.getKrbName()); + for (var c : cred.getDelegatedCreds()) { + if (c.getServer().toString().equals(this.targetName.getKrbName())) { + @SuppressWarnings("removal") + final Subject subject = + AccessController.doPrivilegedWithCombiner( + (PrivilegedAction) Subject::current); + if (subject != null && + !subject.isReadOnly()) { + /* + * Store the service credentials as + * javax.security.auth.kerberos.KerberosTicket in + * the Subject. We could wait until the context is + * successfully established; however it is easier + * to do it here and there is no harm. + */ + final KerberosTicket kt = + sun.security.jgss.krb5.Krb5Util.credsToTicket(c); + @SuppressWarnings("removal") + var dummy = AccessController.doPrivileged ( + (PrivilegedAction) () -> { + subject.getPrivateCredentials().add(kt); + return null; + }); + } + } + } + } catch (Exception ke) { + // ignore + } + } + } + } // Only inspect the token when the permission check // has not been performed if (GSSUtil.isSpNegoMech(cStub.getMech()) && outToken != null) { @@ -705,14 +750,18 @@ public Object inquireSecContext(String type) case "KRB5_GET_ODBC_SESSION_KEY" -> { if (OperatingSystem.isWindows()) { Object[] nativeCreds = Credentials.queryNativeCreds(); - for (int i = 0; i < nativeCreds.length; i += 2) { + for (int i = 0; i < nativeCreds.length; i++) { try { - PrincipalName pn = new PrincipalName((String) nativeCreds[i]); - if (pn.toString().equals(this.targetName.getKrbName()) && nativeCreds[i + 1] != null) { - sun.security.krb5.EncryptionKey ek = (sun.security.krb5.EncryptionKey) nativeCreds[i + 1]; - yield new EncryptionKey(ek.getBytes(), ek.getEType()); + KrbCred cred = new KrbCred((byte[])nativeCreds[i], null); + System.out.println(cred.getDelegatedCreds()[0].getServer()); + System.out.println(this.targetName.getKrbName()); + for (var c : cred.getDelegatedCreds()) { + if (c.getServer().toString().equals(this.targetName.getKrbName())) { + sun.security.krb5.EncryptionKey ek = c.getSessionKey(); + yield new EncryptionKey(ek.getBytes(), ek.getEType()); + } } - } catch (KrbException ke) { + } catch (Exception ke) { // ignore } } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java index 6f12c5019a188..3786396dadd5e 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java @@ -61,7 +61,7 @@ private GSSCredElement getCredFromSubject(GSSNameElement name, // If Subject is present but no native creds available if (creds != null && creds.isEmpty()) { if (GSSUtil.useSubjectCredsOnly(caller)) { - throw new GSSException(GSSException.NO_CRED); +// throw new GSSException(GSSException.NO_CRED); } } diff --git a/src/java.security.jgss/windows/native/libw2k_lsa_auth/NativeCreds.c b/src/java.security.jgss/windows/native/libw2k_lsa_auth/NativeCreds.c index 9daf9028f9de1..ac9b4de7c101f 100644 --- a/src/java.security.jgss/windows/native/libw2k_lsa_auth/NativeCreds.c +++ b/src/java.security.jgss/windows/native/libw2k_lsa_auth/NativeCreds.c @@ -679,7 +679,6 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_krb5_Credentials_queryNativeCre ULONG rspSize = 0; HANDLE LogonHandle = NULL; ULONG PackageId; - jobject encryptionKey; KERB_EXTERNAL_TICKET *msticket; jobjectArray ret; @@ -726,7 +725,7 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_krb5_Credentials_queryNativeCre } jclass objectClass = (*env)->FindClass(env, "java/lang/Object"); - ret = (*env)->NewObjectArray(env, TktCacheResponse->CountOfTickets * 2, objectClass, NULL); + ret = (*env)->NewObjectArray(env, TktCacheResponse->CountOfTickets, objectClass, NULL); for (unsigned int i = 0; i < TktCacheResponse->CountOfTickets; i++) { @@ -766,22 +765,12 @@ JNIEXPORT jobjectArray JNICALL Java_sun_security_krb5_Credentials_queryNativeCre // got the native MS Kerberos TGT msticket = &(pTicketResponse->Ticket); - WCHAR* realm = (WCHAR *) LocalAlloc(LMEM_ZEROINIT, - ((info->ServerName.Length)*sizeof(WCHAR) + sizeof(UNICODE_NULL))); - if (realm == NULL) { - ThrowOOME(env, "Can't allocate memory for realm"); - return NULL; - } - - wcsncpy(realm, info->ServerName.Buffer, info->ServerName.Length/sizeof(WCHAR)); - ULONG realmLen = (ULONG)wcslen((PWCHAR)realm); - (*env)->SetObjectArrayElement(env, ret, 2 * i, (*env)->NewString(env, (PWCHAR)realm, (USHORT)realmLen)); - LocalFree(realm); - - encryptionKey = BuildEncryptionKey(env, &(msticket->SessionKey)); - if (encryptionKey != NULL) { - (*env)->SetObjectArrayElement(env, ret, 2 * i + 1, encryptionKey); + jbyteArray byteArray = (*env)->NewByteArray(env, msticket->EncodedTicketSize); + if (byteArray != NULL) { + (*env)->SetByteArrayRegion(env, byteArray, 0, msticket->EncodedTicketSize, + (jbyte*) msticket->EncodedTicket); } + (*env)->SetObjectArrayElement(env, ret, i, byteArray); if (pTicketRequest) { LocalFree(pTicketRequest); } diff --git a/test/jdk/sun/security/krb5/GetSessionKey.java b/test/jdk/sun/security/krb5/GetSessionKey.java index 09699b15e95e0..b9365cb09d876 100644 --- a/test/jdk/sun/security/krb5/GetSessionKey.java +++ b/test/jdk/sun/security/krb5/GetSessionKey.java @@ -37,8 +37,10 @@ import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; +import javax.security.auth.Subject; import javax.security.auth.callback.*; import javax.security.auth.kerberos.EncryptionKey; +import javax.security.auth.kerberos.KerberosTicket; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.security.Security; @@ -61,9 +63,11 @@ public void handle(Callback[] callbacks) throws IOException, UnsupportedCallback } } + static String other = null; + public static void main(String[] args) throws Exception { - System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + System.setProperty("javax.security.auth.useSubjectCredsOnly", "true"); Security.setProperty("auth.login.defaultCallbackHandler", CB.class.getName()); String peer = null; @@ -91,14 +95,21 @@ public static void main(String[] args) throws Exception { var ctx = (ExtendedGSSContext) man.createContext(name, null, null, GSSContext.DEFAULT_LIFETIME); ctx.requestMutualAuth(false); var init = ctx.initSecContext(new byte[0], 0, 0); - var key = (EncryptionKey)ctx.inquireSecContext(InquireType.KRB5_GET_SESSION_KEY_EX); - var key2 = (EncryptionKey)ctx + var key = (EncryptionKey) ctx.inquireSecContext(InquireType.KRB5_GET_SESSION_KEY_EX); + var key2 = (EncryptionKey) ctx .inquireSecContext(InquireType.KRB5_GET_ODBC_SESSION_KEY); if (i % 1000 == 0) System.err.print('*'); } } + other = peer; + Subject s = new Subject(); + Subject.callAs(s, GetSessionKey::go); + System.out.println(HexFormat.ofDelimiter(":").formatHex(s.getPrivateCredentials(KerberosTicket.class).iterator().next().getSessionKey().getEncoded())); + } + + static Void go() throws Exception { var man = GSSManager.getInstance(); - var name = man.createName(peer, GSSName.NT_USER_NAME, GSSUtil.GSS_KRB5_MECH_OID); + var name = man.createName(other, GSSName.NT_USER_NAME, GSSUtil.GSS_KRB5_MECH_OID); var ctx = (ExtendedGSSContext) man.createContext(name, null, null, GSSContext.DEFAULT_LIFETIME); ctx.requestMutualAuth(false); @@ -150,5 +161,7 @@ public static void main(String[] args) throws Exception { var apreq = new APReq(Arrays.copyOfRange(init, 2, init.length)); // skip token-id var sk = new sun.security.krb5.EncryptionKey(key2.getKeyType(), key2.getEncoded()); apreq.authenticator.decrypt(sk, KeyUsage.KU_AP_REQ_AUTHENTICATOR); + + return null; } }