[PATCH] 8005819: Support cross-realm MSSFU
richard at pointon.org.uk
richard at pointon.org.uk
Tue Mar 28 16:59:20 UTC 2017
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
More information about the security-dev
mailing list