提交 3781604c 编写于 作者: W weijun

8012615: Realm.getRealmsList returns realms list in wrong

Reviewed-by: valeriep, xuelei
上级 433e57be
......@@ -225,19 +225,19 @@ public class Config {
* and has no sub-key at all (given "forwardable" is defined, otherwise,
* this method has no knowledge if it's a value name or a section name),
*/
@SuppressWarnings("unchecked")
public String get(String... keys) {
Vector<String> v = get0(keys);
Vector<String> v = getString0(keys);
if (v == null) return null;
return v.lastElement();
}
/**
* Gets all values for the specified keys.
* @see #get(java.lang.String[])
* @throws IllegalArgumentException if any of the keys is illegal
* (See {@link #get})
*/
public String getAll(String... keys) {
Vector<String> v = get0(keys);
Vector<String> v = getString0(keys);
if (v == null) return null;
StringBuilder sb = new StringBuilder();
boolean first = true;
......@@ -252,17 +252,37 @@ public class Config {
return sb.toString();
}
// Internal method. Returns the vector of strings for keys.
/**
* Returns true if keys exists, can be either final string(s) or sub-stanza
* @throws IllegalArgumentException if any of the keys is illegal
* (See {@link #get})
*/
public boolean exists(String... keys) {
return get0(keys) != null;
}
// Returns final string value(s) for given keys.
@SuppressWarnings("unchecked")
private Vector<String> getString0(String... keys) {
try {
return (Vector<String>)get0(keys);
} catch (ClassCastException cce) {
throw new IllegalArgumentException(cce);
}
}
// Internal method. Returns the value for keys, which can be a sub-stanza
// or final string value(s).
// The only method (except for toString) that reads stanzaTable directly.
@SuppressWarnings("unchecked")
private Vector<String> get0(String... keys) {
private Object get0(String... keys) {
Object current = stanzaTable;
try {
for (String key: keys) {
current = ((Hashtable<String,Object>)current).get(key);
if (current == null) return null;
}
return (Vector<String>)current;
return current;
} catch (ClassCastException cce) {
throw new IllegalArgumentException(cce);
}
......
......@@ -34,10 +34,8 @@ package sun.security.krb5;
import sun.security.krb5.internal.Krb5;
import sun.security.util.*;
import java.io.IOException;
import java.util.StringTokenizer;
import java.util.Vector;
import java.util.Stack;
import java.util.EmptyStackException;
import java.util.*;
import sun.security.krb5.internal.util.KerberosString;
/**
......@@ -50,7 +48,6 @@ import sun.security.krb5.internal.util.KerberosString;
*/
public class Realm implements Cloneable {
private final String realm; // not null nor empty
private static boolean DEBUG = Krb5.DEBUG;
public Realm(String name) throws RealmException {
realm = parseRealm(name);
......@@ -233,90 +230,53 @@ public class Realm implements Cloneable {
}
}
/*
* First leg of realms parsing. Used by getRealmsList.
*/
private static String[] doInitialParse(String cRealm, String sRealm)
throws KrbException {
if (cRealm == null || sRealm == null){
throw new KrbException(Krb5.API_INVALID_ARG);
}
if (DEBUG) {
System.out.println(">>> Realm doInitialParse: cRealm=["
+ cRealm + "], sRealm=[" +sRealm + "]");
}
if (cRealm.equals(sRealm)) {
String[] retList = null;
retList = new String[1];
retList[0] = new String(cRealm);
if (DEBUG) {
System.out.println(">>> Realm doInitialParse: "
+ retList[0]);
}
return retList;
}
return null;
}
/**
* Returns an array of realms that may be traversed to obtain
* a TGT from the initiating realm cRealm to the target realm
* sRealm.
* <br>
* There may be an arbitrary number of intermediate realms
* between cRealm and sRealm. The realms may be organized
* organized hierarchically, or the paths between them may be
* specified in the [capaths] stanza of the caller's
* Kerberos configuration file. The configuration file is consulted
* first. Then a hirarchical organization is assumed if no realms
* are found in the configuration file.
* This method would read [capaths] to create a path, or generate a
* hierarchical path if [capaths] does not contain a sub-stanza for cRealm
* or the sub-stanza does not contain a tag for sRealm.
* <br>
* The returned list, if not null, contains cRealm as the first
* entry. sRealm is not included unless it is mistakenly listed
* in the configuration file as an intermediary realm.
* The returned list would never be null, and it always contains
* cRealm as the head entry. sRealm is not included as the tail.
*
* @param cRealm the initiating realm
* @param sRealm the target realm
* @returns array of realms
* @thows KrbException
* @param cRealm the initiating realm, not null
* @param sRealm the target realm, not null, not equals to cRealm
* @returns array of realms including at least cRealm as the first
* element
*/
public static String[] getRealmsList(String cRealm, String sRealm)
throws KrbException {
String[] retList = doInitialParse(cRealm, sRealm);
if (retList != null && retList.length != 0) {
return retList;
}
/*
* Try [capaths].
*/
retList = parseCapaths(cRealm, sRealm);
if (retList != null && retList.length != 0) {
return retList;
}
/*
* Now assume the realms are organized hierarchically.
*/
retList = parseHierarchy(cRealm, sRealm);
return retList;
public static String[] getRealmsList(String cRealm, String sRealm) {
try {
// Try [capaths]
return parseCapaths(cRealm, sRealm);
} catch (KrbException ke) {
// Now assume the realms are organized hierarchically.
return parseHierarchy(cRealm, sRealm);
}
}
/**
* Parses the [capaths] stanza of the configuration file
* for a list of realms to traverse
* to obtain credentials from the initiating realm cRealm to
* the target realm sRealm.
* @param cRealm the initiating realm
* @param sRealm the target realm
* @returns array of realms
* @ throws KrbException
*/
/*
* parseCapaths works for a capaths organized such that
* for a given client realm C there is a tag C that
* contains subtags Ci ... Cn that completely define intermediate
* realms from C to target T. For example:
* Parses the [capaths] stanza of the configuration file for a
* list of realms to traverse to obtain credentials from the
* initiating realm cRealm to the target realm sRealm.
*
* For a given client realm C there is a tag C in [capaths] whose
* subtag S has a value which is a (possibly partial) path from C
* to S. When the path is partial, it contains only the tail of the
* full path. Values of other subtags will be used to build the full
* path. The value "." means a direct path from C to S. If realm S
* does not appear as a subtag, there is no path defined here.
*
* The implementation ignores all values which equals to C or S, or
* a "." in multiple values, or any duplicated realm names.
*
* When a path value has more than two realms, they can be specified
* with multiple key-value pairs each having a single value, but the
* order must not change.
*
* For example:
*
* [capaths]
* TIVOLI.COM = {
......@@ -325,357 +285,130 @@ public class Realm implements Cloneable {
* LDAPCENTRAL.NET = .
* }
*
* The tag TIVOLI.COM contains subtags IBM.COM, IBM_LDAPCENTRAL.COM
* and LDAPCENTRAL.NET that completely define the path from TIVOLI.COM
* to IBM.COM (TIVOLI.COM->LADAPCENTRAL.NET->IBM_LDAPCENTRAL.COM->IBM
* or TIVOLI.COM->MOONLITE.ORG->IBM.COM).
* TIVOLI.COM has a direct path to LDAPCENTRAL.NET, which has a direct
* path to IBM_LDAPCENTRAL.COM. It also has a partial path to IBM.COM
* being "IBM_LDAPCENTRAL.COM MOONLITE.ORG". Merging these info together,
* a full path from TIVOLI.COM to IBM.COM will be
*
* TIVOLI.COM -> LDAPCENTRAL.NET -> IBM_LDAPCENTRAL.COM
* -> IBM_LDAPCENTRAL.COM -> MOONLITE.ORG
*
* Please note the sRealm IBM.COM does not appear in the path.
*
* A direct path is assumed for an intermediary whose entry is not
* "closed" by a "." In the above example, TIVOLI.COM is assumed
* to have a direct path to MOONLITE.ORG and MOONLITE.COM
* in turn to IBM.COM.
* @param cRealm the initiating realm
* @param sRealm the target realm, not the same as cRealm
* @returns array of realms including at least cRealm as the first
* element
* @throws KrbException if the config does not contain a sub-stanza
* for cRealm in [capaths] or the sub-stanza does not contain
* sRealm as a tag
*/
private static String[] parseCapaths(String cRealm, String sRealm)
throws KrbException {
private static String[] parseCapaths(String cRealm, String sRealm) throws KrbException {
String[] retList = null;
Config cfg = null;
try {
cfg = Config.getInstance();
} catch (Exception exc) {
if (DEBUG) {
System.out.println ("Configuration information can not be " +
"obtained " + exc.getMessage());
}
return null;
}
String intermediaries = cfg.getAll("capaths", cRealm, sRealm);
// This line could throw a KrbException
Config cfg = Config.getInstance();
if (intermediaries == null) {
if (DEBUG) {
System.out.println(">>> Realm parseCapaths: no cfg entry");
}
return null;
if (!cfg.exists("capaths", cRealm, sRealm)) {
throw new KrbException("No conf");
}
String tempTarget = null, tempRealm = null;
Stack<String> iStack = new Stack<>();
/*
* The half-established reversed-path, starting from the final target
* (sRealm), each item can be connected to by the next one.
* Might contains wrong item, if found, a bad track is performed
*/
Vector<String> tempList = new Vector<>(8, 8);
tempList.add(sRealm);
int count = 0; // For debug only
tempTarget = sRealm;
out: do {
if (DEBUG) {
count++;
System.out.println(">>> Realm parseCapaths: loop " +
count + ": target=" + tempTarget);
}
if (intermediaries != null &&
!intermediaries.equals(".") &&
!intermediaries.equals(cRealm)) {
if (DEBUG) {
System.out.println(">>> Realm parseCapaths: loop " +
count + ": intermediaries=[" +
intermediaries + "]");
}
LinkedList<String> path = new LinkedList<>();
/*
* We have one or more space-separated intermediary realms.
* Stack them. A null is always added between intermedies of
* different targets. When this null is popped, it means none
* of the intermedies for this target is useful (because of
* infinite loop), the target is then removed from the partial
* tempList, and the next possible intermediary is tried.
*/
iStack.push(null);
String[] ints = intermediaries.split("\\s+");
for (int i = ints.length-1; i>=0; i--)
{
tempRealm = ints[i];
if (tempRealm.equals(PrincipalName.REALM_COMPONENT_SEPARATOR_STR)) {
break out;
}
if (!tempList.contains(tempRealm)) {
iStack.push(tempRealm);
if (DEBUG) {
System.out.println(">>> Realm parseCapaths: loop " +
count +
": pushed realm on to stack: " +
tempRealm);
}
} else if (DEBUG) {
System.out.println(">>> Realm parseCapaths: loop " +
count +
": ignoring realm: [" +
tempRealm + "]");
}
}
} else {
if (DEBUG) {
System.out.println(">>> Realm parseCapaths: loop " +
count +
": no intermediaries");
}
String head = sRealm;
while (true) {
String value = cfg.getAll("capaths", cRealm, head);
if (value == null) {
break;
}
/*
* Get next intermediary realm from the stack
*/
try {
while ((tempTarget = iStack.pop()) == null) {
tempList.removeElementAt(tempList.size()-1);
if (DEBUG) {
System.out.println(">>> Realm parseCapaths: backtrack, remove tail");
}
String[] more = value.split("\\s+");
boolean changed = false;
for (int i=more.length-1; i>=0; i--) {
if (path.contains(more[i])
|| more[i].equals(".")
|| more[i].equals(cRealm)
|| more[i].equals(sRealm)
|| more[i].equals(head)) {
// Ignore invalid values
continue;
}
} catch (EmptyStackException exc) {
tempTarget = null;
}
if (tempTarget == null) {
/*
* No more intermediaries. We're done.
*/
break;
}
tempList.add(tempTarget);
if (DEBUG) {
System.out.println(">>> Realm parseCapaths: loop " + count +
": added intermediary to list: " +
tempTarget);
}
intermediaries = cfg.getAll("capaths", cRealm, tempTarget);
} while (true);
if (tempList.isEmpty()) {
return null;
}
// From (SREALM, T1, T2) to (CREALM, T2, T1)
retList = new String[tempList.size()];
retList[0] = cRealm;
for (int i=1; i<tempList.size(); i++) {
retList[i] = tempList.elementAt(tempList.size()-i);
}
if (DEBUG && retList != null) {
for (int i = 0; i < retList.length; i++) {
System.out.println(">>> Realm parseCapaths [" + i +
"]=" + retList[i]);
changed = true;
path.addFirst(more[i]);
}
if (!changed) break;
head = path.getFirst();
}
return retList;
}
path.addFirst(cRealm);
return path.toArray(new String[path.size()]);
}
/**
* Build a list of realm that can be traversed
* to obtain credentials from the initiating realm cRealm
* for a service in the target realm sRealm.
* @param cRealm the initiating realm
* @param sRealm the target realm
* @returns array of realms
* @throws KrbException
* @param sRealm the target realm, not the same as cRealm
* @returns array of realms including cRealm as the first element
*/
private static String[] parseHierarchy(String cRealm, String sRealm)
throws KrbException
{
String[] retList = null;
// Parse the components and determine common part, if any.
String[] cComponents = null;
String[] sComponents = null;
StringTokenizer strTok =
new StringTokenizer(cRealm,
PrincipalName.REALM_COMPONENT_SEPARATOR_STR);
// Parse cRealm
int cCount = strTok.countTokens();
cComponents = new String[cCount];
for (cCount = 0; strTok.hasMoreTokens(); cCount++) {
cComponents[cCount] = strTok.nextToken();
}
if (DEBUG) {
System.out.println(">>> Realm parseHierarchy: cRealm has " +
cCount + " components:");
int j = 0;
while (j < cCount) {
System.out.println(">>> Realm parseHierarchy: " +
"cComponents["+j+"]=" + cComponents[j++]);
}
}
// Parse sRealm
strTok = new StringTokenizer(sRealm,
PrincipalName.REALM_COMPONENT_SEPARATOR_STR);
int sCount = strTok.countTokens();
sComponents = new String[sCount];
for (sCount = 0; strTok.hasMoreTokens(); sCount++) {
sComponents[sCount] = strTok.nextToken();
}
if (DEBUG) {
System.out.println(">>> Realm parseHierarchy: sRealm has " +
sCount + " components:");
int j = 0;
while (j < sCount) {
System.out.println(">>> Realm parseHierarchy: sComponents["+j+
"]=" + sComponents[j++]);
}
}
// Determine common components, if any.
int commonComponents = 0;
//while (sCount > 0 && cCount > 0 &&
// sComponents[--sCount].equals(cComponents[--cCount]))
private static String[] parseHierarchy(String cRealm, String sRealm) {
for (sCount--, cCount--; sCount >=0 && cCount >= 0 &&
sComponents[sCount].equals(cComponents[cCount]);
sCount--, cCount--) {
commonComponents++;
}
int cCommonStart = -1;
int sCommonStart = -1;
String[] cComponents = cRealm.split("\\.");
String[] sComponents = sRealm.split("\\.");
int links = 0;
int cPos = cComponents.length;
int sPos = sComponents.length;
if (commonComponents > 0) {
sCommonStart = sCount+1;
cCommonStart = cCount+1;
// components from common to ancestors
links += sCommonStart;
links += cCommonStart;
} else {
links++;
boolean hasCommon = false;
for (sPos--, cPos--; sPos >=0 && cPos >= 0 &&
sComponents[sPos].equals(cComponents[cPos]);
sPos--, cPos--) {
hasCommon = true;
}
if (DEBUG) {
if (commonComponents > 0) {
System.out.println(">>> Realm parseHierarchy: " +
commonComponents + " common component" +
(commonComponents > 1 ? "s" : " "));
System.out.println(">>> Realm parseHierarchy: common part "
+
"in cRealm (starts at index " +
cCommonStart + ")");
System.out.println(">>> Realm parseHierarchy: common part in sRealm (starts at index " +
sCommonStart + ")");
String commonPart = substring(cRealm, cCommonStart);
System.out.println(">>> Realm parseHierarchy: common part in cRealm=" +
commonPart);
// For those with common components:
// length pos
// SITES1.SALES.EXAMPLE.COM 4 1
// EVERYWHERE.EXAMPLE.COM 3 0
commonPart = substring(sRealm, sCommonStart);
System.out.println(">>> Realm parseHierarchy: common part in sRealm=" +
commonPart);
// For those without common components:
// length pos
// DEVEL.EXAMPLE.COM 3 2
// PROD.EXAMPLE.ORG 3 2
} else
System.out.println(">>> Realm parseHierarchy: no common part");
}
LinkedList<String> path = new LinkedList<>();
if (DEBUG) {
System.out.println(">>> Realm parseHierarchy: total links=" + links);
// Un-common ones for client side
for (int i=0; i<=cPos; i++) {
path.addLast(subStringFrom(cComponents, i));
}
retList = new String[links];
retList[0] = new String(cRealm);
if (DEBUG) {
System.out.println(">>> Realm parseHierarchy A: retList[0]=" +
retList[0]);
// Common one
if (hasCommon) {
path.addLast(subStringFrom(cComponents, cPos+1));
}
// For an initiator realm A.B.C.D.COM,
// build a list krbtgt/B.C.D.COM@A.B.C.D.COM up to the common part,
// ie the issuer realm is the immediate descendant
// of the target realm.
String cTemp = null, sTemp = null;
int i;
for (i = 1, cCount = 0; i < links && cCount < cCommonStart; cCount++) {
sTemp = substring(cRealm, cCount+1);
//cTemp = substring(cRealm, cCount);
retList[i++] = new String(sTemp);
if (DEBUG) {
System.out.println(">>> Realm parseHierarchy B: retList[" +
(i-1) +"]="+retList[i-1]);
}
// Un-common ones for server side
for (int i=sPos; i>=0; i--) {
path.addLast(subStringFrom(sComponents, i));
}
// Remove sRealm from path. Note that it might be added at last loop
// or as a common component, if sRealm is a parent of cRealm
path.removeLast();
for (sCount = sCommonStart; i < links && sCount - 1 > 0; sCount--) {
sTemp = substring(sRealm, sCount-1);
//cTemp = substring(sRealm, sCount);
retList[i++] = new String(sTemp);
if (DEBUG) {
System.out.println(">>> Realm parseHierarchy D: retList[" +
(i-1) +"]="+retList[i-1]);
}
}
return retList;
return path.toArray(new String[path.size()]);
}
private static String substring(String realm, int componentIndex)
{
int i = 0 , j = 0, len = realm.length();
while(i < len && j != componentIndex) {
if (realm.charAt(i++) != PrincipalName.REALM_COMPONENT_SEPARATOR)
continue;
j++;
}
return realm.substring(i);
}
static int getRandIndex(int arraySize) {
return (int)(Math.random() * 16384.0) % arraySize;
}
static void printNames(String[] names) {
if (names == null || names.length == 0)
return;
int len = names.length;
int i = 0;
System.out.println("List length = " + len);
while (i < names.length) {
System.out.println("["+ i +"]=" + names[i]);
i++;
/**
* Creates a realm name using components from the given postion.
* For example, subStringFrom({"A", "B", "C"}, 1) is "B.C".
*/
private static String subStringFrom(String[] components, int from) {
StringBuilder sb = new StringBuilder();
for (int i=from; i<components.length; i++) {
if (sb.length() != 0) sb.append('.');
sb.append(components[i]);
}
return sb.toString();
}
}
......@@ -160,7 +160,7 @@ public class CredentialsUtil {
/**
* Gets a TGT to another realm
* @param localRealm this realm
* @param serviceRealm the other realm
* @param serviceRealm the other realm, cannot equals to localRealm
* @param ccreds TGT in this realm
* @param okAsDelegate an [out] argument to receive the okAsDelegate
* property. True only if all realms allow delegation.
......@@ -174,14 +174,6 @@ public class CredentialsUtil {
// Get a list of realms to traverse
String[] realms = Realm.getRealmsList(localRealm, serviceRealm);
if (realms == null || realms.length == 0) {
if (DEBUG) {
System.out.println(
">>> Credentials acquireServiceCreds: no realms list");
}
return null;
}
int i = 0, k = 0;
Credentials cTgt = null, newTgt = null, theTgt = null;
PrincipalName tempService = null;
......@@ -206,16 +198,14 @@ public class CredentialsUtil {
if (newTgt == null) {
if (DEBUG) {
System.out.println(">>> Credentials acquireServiceCreds: "
+ "no tgt; searching backwards");
+ "no tgt; searching thru capath");
}
/*
* No tgt found. Try to get one for a
* realm as close to the target as possible.
* That means traversing the realms list backwards.
* No tgt found. Let's go thru the realms list one by one.
*/
for (newTgt = null, k = realms.length - 1;
newTgt == null && k > i; k--) {
for (newTgt = null, k = i+1;
newTgt == null && k < realms.length; k++) {
tempService = PrincipalName.tgsService(realms[k], realms[i]);
if (DEBUG) {
System.out.println(
......
......@@ -22,7 +22,7 @@
*/
/*
* @test
* @bug 6789935
* @bug 6789935 8012615
* @run main/othervm ParseCAPaths
* @summary cross-realm capath search error
*/
......@@ -35,37 +35,75 @@ public class ParseCAPaths {
public static void main(String[] args) throws Exception {
System.setProperty("java.security.krb5.conf",
System.getProperty("test.src", ".") +"/krb5-capaths.conf");
//System.setProperty("sun.security.krb5.debug", "true");
// Standard example
// MIT
check("ANL.GOV", "TEST.ANL.GOV", "ANL.GOV");
check("ANL.GOV", "ES.NET", "ANL.GOV");
check("ANL.GOV", "PNL.GOV", "ANL.GOV", "ES.NET");
check("ANL.GOV", "NERSC.GOV", "ANL.GOV", "ES.NET");
check("NERSC.GOV", "TEST.ANL.GOV", "NERSC.GOV", "ES.NET", "ANL.GOV");
// RedHat
// 3.6.2.1. Configuring a Shared Hierarchy of Names
check("AA.EXAMPLE.COM", "BB.EXAMPLE.COM",
"AA.EXAMPLE.COM", "EXAMPLE.COM");
check("SITE1.SALES.EXAMPLE.COM", "EVERYWHERE.EXAMPLE.COM",
"SITE1.SALES.EXAMPLE.COM", "SALES.EXAMPLE.COM",
"EXAMPLE.COM");
check("DEVEL.EXAMPLE.COM", "PROD.EXAMPLE.ORG",
"DEVEL.EXAMPLE.COM", "EXAMPLE.COM", "COM",
"ORG", "EXAMPLE.ORG");
// 3.6.2.2. Configuring Paths in krb5.conf
check("A.EXAMPLE.COM", "B.EXAMPLE.COM", "A.EXAMPLE.COM");
check("A.EXAMPLE.COM", "C.EXAMPLE.COM",
"A.EXAMPLE.COM", "B.EXAMPLE.COM");
check("A.EXAMPLE.COM", "D.EXAMPLE.COM",
"A.EXAMPLE.COM", "B.EXAMPLE.COM", "C.EXAMPLE.COM");
// The original JDK example
check("TIVOLI.COM", "IBM.COM", "TIVOLI.COM", "LDAPCENTRAL.NET",
"IBM_LDAPCENTRAL.COM", "MOONLITE.ORG");
// Hierachical
check("N1.N.COM", "N2.N.COM", "N1.N.COM", "N.COM"); // 2 common
check("N1.N.COM", "N2.N3.COM", "N1.N.COM", "N.COM", // 1 common
check("N1.N.COM", "N2.N.COM", "N1.N.COM", "N.COM");
check("N1.N.COM", "N2.N3.COM", "N1.N.COM", "N.COM",
"COM", "N3.COM");
check("N1.COM", "N2.COM", "N1.COM", "COM"); // 1 common
check("N1", "N2", "N1"); // 0 common
// Extra garbages
check("A1.COM", "A4.COM", "A1.COM", "A2.COM");
check("N1.COM", "N2.COM", "N1.COM", "COM");
check("N1", "N2", "N1");
check("N1.COM", "N2.ORG", "N1.COM", "COM", "ORG");
check("N1.N.COM", "N.COM", "N1.N.COM");
check("X.N1.N.COM", "N.COM", "X.N1.N.COM", "N1.N.COM");
check("N.COM", "N1.N.COM", "N.COM");
check("N.COM", "X.N1.N.COM", "N.COM", "N1.N.COM");
check("A.B.C", "D.E.F", "A.B.C", "B.C", "C", "F", "E.F");
// Full path
check("A1.COM", "A2.COM", "A1.COM");
check("A1.COM", "A3.COM", "A1.COM", "A2.COM");
check("A1.COM", "A4.COM", "A1.COM", "A2.COM", "A3.COM");
// Shortest path
check("B1.COM", "B2.COM", "B1.COM");
check("B1.COM", "B3.COM", "B1.COM", "B2.COM");
check("B1.COM", "B4.COM", "B1.COM", "B2.COM", "B3.COM");
// Missing is "."
check("C1.COM", "C2.COM", "C1.COM", "COM");
check("C1.COM", "C3.COM", "C1.COM", "C2.COM");
// Multiple path
check("D1.COM", "D4.COM", "D1.COM", "D2.COM");
check("E1.COM", "E4.COM", "E1.COM", "E2.COM");
check("F1.COM", "F4.COM", "F1.COM", "F9.COM");
// Infinite loop
check("G1.COM", "G3.COM", "G1.COM", "COM");
check("H1.COM", "H3.COM", "H1.COM");
// cRealm = .
check("D1.COM", "D2.COM", "D1.COM");
// Bad cases
check("E1.COM", "E2.COM", "E1.COM");
check("E1.COM", "E3.COM", "E1.COM", "E4.COM");
check("G1.COM", "G3.COM", "G1.COM", "G2.COM");
check("I1.COM", "I4.COM", "I1.COM", "I5.COM");
// J2=J1 is the same as J2=.
check("J1.COM", "J2.COM", "J1.COM");
// 7019384
check("A9.PRAGUE.XXX.CZ", "SERVIS.XXX.CZ",
"A9.PRAGUE.XXX.CZ", "PRAGUE.XXX.CZ", "ROOT.XXX.CZ");
if (failed != null) {
throw failed;
}
......@@ -75,6 +113,7 @@ public class ParseCAPaths {
try {
check2(from, to, paths);
} catch (Exception e) {
System.out.println(" " + e.getMessage());
failed = e;
}
}
......@@ -84,18 +123,14 @@ public class ParseCAPaths {
System.out.println(from + " -> " + to);
System.out.println(" expected: " + Arrays.toString(paths));
String[] result = Realm.getRealmsList(from, to);
System.out.println(" result: " + Arrays.toString(result));
if (result == null) {
if (paths.length == 0) {
// OK
} else {
throw new Exception("Shouldn't have a valid path.");
}
if (result == null || result.length == 0) {
throw new Exception("There is always a valid path.");
} else if(result.length != paths.length) {
throw new Exception("Length of path not correct");
} else {
for (int i=0; i<result.length; i++) {
if (!result[i].equals(paths[i])) {
System.out.println(" result: " + Arrays.toString(result));
throw new Exception("Path not same");
}
}
......
[capaths]
# Standard
# http://web.mit.edu/kerberos/krb5-1.5/krb5-1.5.4/doc/krb5-admin/capaths.html
ANL.GOV = {
TEST.ANL.GOV = .
......@@ -14,81 +14,86 @@ TEST.ANL.GOV = {
PNL.GOV = {
ANL.GOV = ES.NET
}
#NERSC.GOV = {
# ANL.GOV = ES.NET
#}
ES.NET = {
ANL.GOV = .
}
NERSC.GOV = {
ANL.GOV = ES.NET
TEST.ANL.GOV = ES.NET
TEST.ANL.GOV = ANL.GOV
PNL.GOV = ES.NET
ES.NET = .
}
ES.NET = {
ANL.GOV = .
# The original JDK example
TIVOLI.COM = {
IBM.COM = IBM_LDAPCENTRAL.COM MOONLITE.ORG
IBM_LDAPCENTRAL.COM = LDAPCENTRAL.NET
LDAPCENTRAL.NET = .
}
# https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Managing_Smart_Cards/Setting_Up_Cross_Realm_Authentication.html
A.EXAMPLE.COM = {
B.EXAMPLE.COM = .
C.EXAMPLE.COM = B.EXAMPLE.COM
D.EXAMPLE.COM = B.EXAMPLE.COM
D.EXAMPLE.COM = C.EXAMPLE.COM
}
# Extra garbages
# Full path
A1.COM = {
A2.COM = .
A4.COM = A2.COM
A3.COM = A4.COM
A3.COM = A2.COM
A4.COM = A2.COM
A4.COM = A3.COM
}
# Shortest path
B1.COM = {
B2.COM = .
B3.COM = B2.COM
B3.COM = B4.COM
B4.COM = B3.COM
}
# Missing is "."
# If no sRealm key, fallback to hierarchy
C1.COM = {
C3.COM = C2.COM
}
# Multiple paths
# cRealm is "."
D1.COM = {
D2.COM = .
D3.COM = .
D4.COM = D2.COM
D4.COM = D3.COM
D2.COM=D1.COM
}
# Bad cases
E1.COM = {
E2.COM = .
E2.COM = E2.COM
E3.COM = E4.COM
E3.COM = .
E4.COM = E2.COM E3.COM E2.COM
}
# Shortest or First?
F1.COM = {
F2.COM = .
F3.COM = F2.COM
F4.COM = F9.COM
F4.COM = F3.COM
F4.COM = F2.COM
}
# Infinite loop
G1.COM = {
G2.COM = G3.COM
G3.COM = G2.COM
}
H1.COM = {
H2.COM = H3.COM
H3.COM = H2.COM
H3.COM = .
}
I1.COM = {
I2.COM = I3.COM
I3.COM = I2.COM
I4.COM = I2.COM I5.COM
I4.COM = I5.COM
}
J1.COM = {
J2.COM=J1.COM
}
# 7019384
A9.PRAGUE.XXX.CZ = {
PRAGUE.XXX.CZ = .
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册