< prev index next >
src/java.security.jgss/share/classes/sun/security/krb5/internal/CredentialsUtil.java
Print this page
rev 54745 : 8215032: Support Kerberos cross-realm referrals (RFC 6806)
Reviewed-by: weijun
*** 1,7 ****
/*
! * Copyright (c) 2001, 2013, 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
--- 1,7 ----
/*
! * Copyright (c) 2001, 2019, 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
*** 31,40 ****
--- 31,43 ----
package sun.security.krb5.internal;
import sun.security.krb5.*;
import java.io.IOException;
+ import java.util.Arrays;
+ import java.util.LinkedList;
+ import java.util.List;
/**
* This class is a utility that contains much of the TGS-Exchange
* protocol. It is used by ../Credentials.java for service ticket
* acquisition in both the normal and the x-realm case.
*** 59,75 ****
throw new KrbException("Cross realm impersonation not supported");
}
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");
}
if (!creds.isForwardable()) {
throw new KrbException("S4U2self ticket must be FORWARDABLE");
--- 62,76 ----
throw new KrbException("Cross realm impersonation not supported");
}
if (!ccreds.isForwardable()) {
throw new KrbException("S4U2self needs a FORWARDABLE ticket");
}
! Credentials creds = serviceCreds(KDCOptions.with(KDCOptions.FORWARDABLE),
! ccreds, ccreds.getClient(), ccreds.getClient(), null,
! new PAData[] {new PAData(Krb5.PA_FOR_USER,
new PAForUserEnc(client,
! ccreds.getSessionKey()).asn1Encode())});
if (!creds.getClient().equals(client)) {
throw new KrbException("S4U2self request not honored by KDC");
}
if (!creds.isForwardable()) {
throw new KrbException("S4U2self ticket must be FORWARDABLE");
*** 87,101 ****
*/
public static Credentials acquireS4U2proxyCreds(
String backend, Ticket second,
PrincipalName client, Credentials ccreds)
throws KrbException, IOException {
! KrbTgsReq req = new KrbTgsReq(
! ccreds,
! second,
! new PrincipalName(backend));
! Credentials creds = req.sendAndGetCreds();
if (!creds.getClient().equals(client)) {
throw new KrbException("S4U2proxy request not honored by KDC");
}
return creds;
}
--- 88,101 ----
*/
public static Credentials acquireS4U2proxyCreds(
String backend, Ticket second,
PrincipalName client, Credentials ccreds)
throws KrbException, IOException {
! Credentials creds = serviceCreds(KDCOptions.with(
! KDCOptions.CNAME_IN_ADDL_TKT, KDCOptions.FORWARDABLE),
! ccreds, ccreds.getClient(), new PrincipalName(backend),
! new Ticket[] {second}, null);
if (!creds.getClient().equals(client)) {
throw new KrbException("S4U2proxy request not honored by KDC");
}
return creds;
}
*** 112,169 ****
* @param ccreds client's initial credential
*/
public static Credentials acquireServiceCreds(
String service, Credentials ccreds)
throws KrbException, IOException {
! PrincipalName sname = new PrincipalName(service);
! String serviceRealm = sname.getRealmString();
! String localRealm = ccreds.getClient().getRealmString();
!
! if (localRealm.equals(serviceRealm)) {
! if (DEBUG) {
! System.out.println(
! ">>> Credentials acquireServiceCreds: same realm");
! }
return serviceCreds(sname, ccreds);
}
- Credentials theCreds = null;
-
- boolean[] okAsDelegate = new boolean[1];
- Credentials theTgt = getTGTforRealm(localRealm, serviceRealm,
- ccreds, okAsDelegate);
- if (theTgt != null) {
- if (DEBUG) {
- System.out.println(">>> Credentials acquireServiceCreds: "
- + "got right tgt");
- System.out.println(">>> Credentials acquireServiceCreds: "
- + "obtaining service creds for " + sname);
- }
-
- try {
- theCreds = serviceCreds(sname, theTgt);
- } catch (Exception exc) {
- if (DEBUG) {
- System.out.println(exc);
- }
- theCreds = null;
- }
- }
-
- if (theCreds != null) {
- if (DEBUG) {
- System.out.println(">>> Credentials acquireServiceCreds: "
- + "returning creds:");
- Credentials.printDebug(theCreds);
- }
- if (!okAsDelegate[0]) {
- theCreds.resetDelegate();
- }
- return theCreds;
- }
- throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
- "No service creds");
- }
/**
* Gets a TGT to another realm
* @param localRealm this realm
* @param serviceRealm the other realm, cannot equals to localRealm
--- 112,125 ----
* @param ccreds client's initial credential
*/
public static Credentials acquireServiceCreds(
String service, Credentials ccreds)
throws KrbException, IOException {
! PrincipalName sname = new PrincipalName(service,
! PrincipalName.KRB_NT_SRV_HST);
return serviceCreds(sname, ccreds);
}
/**
* Gets a TGT to another realm
* @param localRealm this realm
* @param serviceRealm the other realm, cannot equals to localRealm
*** 303,310 ****
* This method does the real job to request the service credential.
*/
private static Credentials serviceCreds(
PrincipalName service, Credentials ccreds)
throws KrbException, IOException {
! return new KrbTgsReq(ccreds, service).sendAndGetCreds();
}
}
--- 259,395 ----
* This method does the real job to request the service credential.
*/
private static Credentials serviceCreds(
PrincipalName service, Credentials ccreds)
throws KrbException, IOException {
! return serviceCreds(new KDCOptions(), ccreds,
! ccreds.getClient(), service, null, null);
! }
!
! private static Credentials serviceCreds(
! KDCOptions options, Credentials asCreds,
! PrincipalName cname, PrincipalName sname,
! Ticket[] additionalTickets, PAData[] extraPAs)
! throws KrbException, IOException {
! if (!Config.DISABLE_REFERRALS) {
! try {
! return serviceCredsReferrals(options, asCreds,
! cname, sname, additionalTickets, extraPAs);
! } catch (KrbException e) {
! // Server may raise an error if CANONICALIZE is true.
! // Try CANONICALIZE false.
! }
! }
! return serviceCredsSingle(options, asCreds,
! cname, sname, additionalTickets, extraPAs);
! }
!
! private static Credentials serviceCredsReferrals(
! KDCOptions options, Credentials asCreds,
! PrincipalName cname, PrincipalName sname,
! Ticket[] additionalTickets, PAData[] extraPAs)
! throws KrbException, IOException {
! options = new KDCOptions(options.toBooleanArray());
! options.set(KDCOptions.CANONICALIZE, true);
! PrincipalName cSname = (PrincipalName) sname.clone();
! Credentials creds = null;
! boolean isReferral = false;
! List<String> referrals = new LinkedList<>();
! while (referrals.size() <= Config.MAX_REFERRALS) {
! ReferralsCache.ReferralCacheEntry ref =
! ReferralsCache.get(sname, cSname.getRealmString());
! String toRealm = null;
! if (ref == null) {
! creds = serviceCredsSingle(options, asCreds,
! cname, cSname, additionalTickets, extraPAs);
! PrincipalName server = creds.getServer();
! if (!cSname.equals(server)) {
! String[] serverNameStrings = server.getNameStrings();
! if (serverNameStrings.length == 2 &&
! serverNameStrings[0].equals(
! PrincipalName.TGS_DEFAULT_SRV_NAME) &&
! !cSname.getRealmAsString().equals(serverNameStrings[1])) {
! // Server Name (sname) has the following format:
! // krbtgt/TO-REALM.COM@FROM-REALM.COM
! ReferralsCache.put(sname, server.getRealmString(),
! serverNameStrings[1], creds);
! toRealm = serverNameStrings[1];
! isReferral = true;
! asCreds = creds;
! }
! }
! } else {
! toRealm = ref.getToRealm();
! asCreds = ref.getCreds();
! isReferral = true;
! }
! if (isReferral) {
! if (referrals.contains(toRealm)) {
! // Referrals loop detected
! return null;
! }
! cSname = new PrincipalName(cSname.getNameString(),
! cSname.getNameType(), toRealm);
! referrals.add(toRealm);
! isReferral = false;
! continue;
! }
! break;
! }
! return creds;
! }
!
! private static Credentials serviceCredsSingle(
! KDCOptions options, Credentials asCreds,
! PrincipalName cname, PrincipalName sname,
! Ticket[] additionalTickets, PAData[] extraPAs)
! throws KrbException, IOException {
! Credentials theCreds = null;
! boolean[] okAsDelegate = new boolean[]{true};
! String[] serverAsCredsNames = asCreds.getServer().getNameStrings();
! if (serverAsCredsNames.length == 2 &&
! serverAsCredsNames[0].equals(
! PrincipalName.TGS_DEFAULT_SRV_NAME)) {
! String tgtRealm = serverAsCredsNames[1];
! String serviceRealm = sname.getRealmString();
! if (!serviceRealm.equals(tgtRealm)) {
! // This is a cross-realm service request
! if (DEBUG) {
! System.out.println(">>> serviceCredsSingle:" +
! " cross-realm authentication");
! System.out.println(">>> serviceCredsSingle:" +
! " obtaining credentials from " + tgtRealm +
! " to " + serviceRealm);
! }
! Credentials newTgt = getTGTforRealm(tgtRealm, serviceRealm,
! asCreds, okAsDelegate);
! if (newTgt == null) {
! throw new KrbApErrException(Krb5.KRB_AP_ERR_GEN_CRED,
! "No service creds");
! }
! if (DEBUG) {
! System.out.println(">>> Cross-realm TGT Credentials" +
! " serviceCredsSingle: ");
! Credentials.printDebug(newTgt);
! }
! asCreds = newTgt;
! cname = asCreds.getClient();
! } else if (DEBUG) {
! System.out.println(">>> Credentials serviceCredsSingle:" +
! " same realm");
! }
! }
! KrbTgsReq req = new KrbTgsReq(options, asCreds,
! cname, sname, additionalTickets, extraPAs);
! theCreds = req.sendAndGetCreds();
! if (theCreds != null) {
! if (DEBUG) {
! System.out.println(">>> TGS credentials serviceCredsSingle:");
! Credentials.printDebug(theCreds);
! }
! if (!okAsDelegate[0]) {
! theCreds.resetDelegate();
! }
! }
! return theCreds;
}
}
< prev index next >