Skip to content

Commit

Permalink
in subject
Browse files Browse the repository at this point in the history
  • Loading branch information
wangweij committed Oct 17, 2024
1 parent 57d1ca2 commit 874c52b
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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.*;

/**
Expand Down Expand Up @@ -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>) 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<Void>) () -> {
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) {
Expand Down Expand Up @@ -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
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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++) {
Expand Down Expand Up @@ -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);
}
Expand Down
21 changes: 17 additions & 4 deletions test/jdk/sun/security/krb5/GetSessionKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}
}

0 comments on commit 874c52b

Please sign in to comment.