[PATCH] 8005819: Support cross-realm MSSFU (original) (raw)
richard at pointon.org.uk richard at pointon.org.uk
Tue Mar 28 16:59:20 UTC 2017
- Previous message (by thread): RFR of 8177683: Suppress lint removal warnings in jdk.security and jdk.policytool
- Next message (by thread): [PATCH] 8005819: Support cross-realm MSSFU
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Hi,
I have developed a fix for the lack of cross-realm S4USelf support in OpenJDK 8 which I would like to contribute.
The fix does not address realm referral as discussed in the bug and so requires both realms to be present in the krb5.conf file.
Bug: https://bugs.openjdk.java.net/browse/JDK-8005819
Diff:
../jdk8u/jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java 2016-08-22 15:58:34.720949000 +0100 +++ ../jdkpatch/jdk/src/share/classes/sun/security/krb5/internal/CredentialsUtil.java 2016-09-16 15:11:02.967278000 +0100 @@ -54,19 +54,57 @@ Credentials ccreds) throws KrbException, IOException { String uRealm = client.getRealmString(); String localRealm = ccreds.getClient().getRealmString(); + KrbTgsReq req; if (!uRealm.equals(localRealm)) { - // TODO: we do not support kerberos referral now - throw new KrbException("Cross realm impersonation not supported"); + //get a cross realm TGT + String tname = PrincipalName.TGS_DEFAULT_SRV_NAME + PrincipalName.NAME_COMPONENT_SEPARATOR_STR + + uRealm + PrincipalName.NAME_REALM_SEPARATOR_STR + uRealm; + + Credentials foreignTGT = acquireServiceCreds(tname, ccreds); + + //get a referral TGT from the foreign realm for the user + String [] svcUPN = ccreds.getClient().getNameStrings().clone(); + svcUPN[svcUPN.length-1] += PrincipalName.NAME_REALM_SEPARATOR_STR + localRealm; + + PrincipalName svcPrinc = new PrincipalName(PrincipalName.KRB_NT_ENTERPRISE, svcUPN, new Realm(uRealm)); + + req = new KrbTgsReq( + foreignTGT, + svcPrinc, + new PAData(Krb5.PA_FOR_USER, + new PAForUserEnc(client, + foreignTGT.getSessionKey()).asn1Encode()), + client); + + if (!foreignTGT.isForwardable()) { + throw new KrbException("S4U2self needs a FORWARDABLE ticket"); + } + + Credentials referralTGT = req.sendAndGetCreds(); + + //create request to local realm for user in foreign realm using the referral TGT from the + //foreign realm + req = new KrbTgsReq( + referralTGT, + ccreds.getClient(), + new PAData(Krb5.PA_FOR_USER, + new PAForUserEnc(client, + referralTGT.getSessionKey()).asn1Encode())); } - if (!ccreds.isForwardable()) { - throw new KrbException("S4U2self needs a FORWARDABLE ticket"); + else { + //same realm + req = new KrbTgsReq( + ccreds, + ccreds.getClient(), + new PAData(Krb5.PA_FOR_USER, + new PAForUserEnc(client, + ccreds.getSessionKey()).asn1Encode())); + + if (!ccreds.isForwardable()) { + throw new KrbException("S4U2self needs a FORWARDABLE ticket"); + } } - KrbTgsReq req = new KrbTgsReq( - ccreds, - ccreds.getClient(), - new PAData(Krb5.PA_FOR_USER, - new PAForUserEnc(client, - ccreds.getSessionKey()).asn1Encode())); + Credentials creds = req.sendAndGetCreds(); if (!creds.getClient().equals(client)) { throw new KrbException("S4U2self request not honored by KDC");
../jdk8u/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java 2016-08-22 15:58:34.718972000 +0100 +++ ../jdkpatch/jdk/src/share/classes/sun/security/krb5/KrbTgsReq.java 2016-09-16 15:11:02.979473000 +0100 @@ -45,6 +45,7 @@
private PrincipalName princName;
private PrincipalName servName;
- private PrincipalName targetName; private TGSReq tgsReqMessg; private KerberosTime ctime; private Ticket secondTicket = null; @@ -109,8 +110,31 @@ null, null, null,
extraPA); // the PA-FOR-USER
extraPA,// the PA-FOR-USER
null); }
- public KrbTgsReq(Credentials asCreds,
PrincipalName sname,
PAData extraPA,
PrincipalName tname)
- throws KrbException, IOException {
- this(KDCOptions.with(KDCOptions.FORWARDABLE, KDCOptions.CANONICALIZE),
asCreds,
asCreds.getClient(),
sname,
null,
null,
null,
null,
null,
null,
null,
null,
extraPA,// the PA-FOR-USER
tname);
- }
// Called by Credentials, KrbCred
KrbTgsReq(
@@ -127,7 +151,7 @@ EncryptionKey subKey) throws KrbException, IOException { this(options, asCreds, asCreds.getClient(), sname, from, till, rtime, eTypes, addresses,
authorizationData, additionalTickets, subKey, null);
authorizationData, additionalTickets, subKey, null,
null); }
private KrbTgsReq(
@@ -143,10 +167,12 @@ AuthorizationData authorizationData, Ticket[] additionalTickets, EncryptionKey subKey,
PAData extraPA) throws KrbException, IOException {
PAData extraPA,
PrincipalName tname) throws KrbException, IOException { princName = cname; servName = sname;
targetName = tname; ctime = KerberosTime.now(); // check if they are valid arguments. The optional fields
@@ -240,8 +266,13 @@ */ public void send() throws IOException, KrbException { String realmStr = null; - if (servName != null) + if (targetName != null){ + realmStr = targetName.getRealmString(); + } + else if (servName != null) { realmStr = servName.getRealmString(); + } + KdcComm comm = new KdcComm(realmStr); ibuf = comm.send(obuf); }
../jdk8u/jdk/src/share/classes/sun/security/krb5/KrbKdcRep.java 2016-08-22 15:58:34.801487000 +0100 +++ ../jdkpatch/jdk/src/share/classes/sun/security/krb5/KrbKdcRep.java 2016-09-16 15:11:02.986718000 +0100 @@ -45,7 +45,8 @@ throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); }
if (!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) {
if (!req.reqBody.kdcOptions.get(KDCOptions.CANONICALIZE) &&
!req.reqBody.sname.equals(rep.encKDCRepPart.sname)) { rep.encKDCRepPart.key.destroy(); throw new KrbApErrException(Krb5.KRB_AP_ERR_MODIFIED); }
../jdk8u/jdk/src/share/classes/sun/security/krb5/internal/KDCOptions.java 2016-08-22 15:58:34.758240000 +0100 +++ ../jdkpatch/jdk/src/share/classes/sun/security/krb5/internal/KDCOptions.java 2016-09-16 15:11:02.990754000 +0100 @@ -140,6 +140,7 @@ public static final int UNUSED10 = 10; public static final int UNUSED11 = 11; public static final int CNAME_IN_ADDL_TKT = 14; + public static final int CANONICALIZE = 15; public static final int RENEWABLE_OK = 27; public static final int ENC_TKT_IN_SKEY = 28; public static final int RENEW = 30; @@ -160,7 +161,8 @@ "UNUSED11", //11; null,null, "CNAME_IN_ADDL_TKT",//14; - null,null,null,null,null,null,null,null,null,null,null,null, + "CANONICALIZE", //15; + null,null,null,null,null,null,null,null,null,null,null, "RENEWABLE_OK", //27; "ENC_TKT_IN_SKEY", //28; null,
../jdk8u/jdk/src/share/classes/sun/security/krb5/PrincipalName.java 2016-08-22 15:58:34.708329000 +0100 +++ ../jdkpatch/jdk/src/share/classes/sun/security/krb5/PrincipalName.java 2016-09-16 15:11:02.995791000 +0100 @@ -89,6 +89,11 @@ * Unique ID */ public static final int KRB_NT_UID = 5; +
/**
* Enterprise name; may be mapped to principal name
*/
public static final int KRB_NT_ENTERPRISE = 10;
/**
- TGS Name
- Previous message (by thread): RFR of 8177683: Suppress lint removal warnings in jdk.security and jdk.policytool
- Next message (by thread): [PATCH] 8005819: Support cross-realm MSSFU
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]