# HG changeset patch # User weijun # Date 1235354665 -28800 # Node ID d690c8a2acea0e1a0120b7a922898f8ed5cb3eec # Parent 8ad79de28190ca2a846e490090e0540397c79d89 6789935: cross-realm capath search error Reviewed-by: xuelei diff -r 8ad79de28190 -r d690c8a2acea jdk/src/share/classes/sun/security/krb5/Realm.java --- a/jdk/src/share/classes/sun/security/krb5/Realm.java Mon Feb 23 10:03:36 2009 +0800 +++ b/jdk/src/share/classes/sun/security/krb5/Realm.java Mon Feb 23 10:04:25 2009 +0800 @@ -39,7 +39,6 @@ import sun.security.krb5.internal.Krb5; import sun.security.util.*; import java.io.IOException; -import java.io.OutputStream; import java.util.StringTokenizer; import java.util.Vector; import java.util.Stack; @@ -364,7 +363,6 @@ } String tempTarget = null, tempRealm = null; - StringTokenizer strTok = null; Stack iStack = new Stack (); /* @@ -382,7 +380,7 @@ tempTarget = sRealm; } - do { + out: do { if (DEBUG) { count++; System.out.println(">>> Realm parseCapaths: loop " + @@ -400,15 +398,21 @@ /* * We have one or more space-separated intermediary realms. - * Stack them. + * 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. */ - strTok = new StringTokenizer(intermediaries, " "); - while (strTok.hasMoreTokens()) + iStack.push(null); + String[] ints = intermediaries.split("\\s+"); + for (int i = ints.length-1; i>=0; i--) { - tempRealm = strTok.nextToken(); - if (!tempRealm.equals(PrincipalName. - REALM_COMPONENT_SEPARATOR_STR) && - !iStack.contains(tempRealm)) { + 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 " + @@ -418,16 +422,18 @@ } } 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"); + } else { + if (DEBUG) { + System.out.println(">>> Realm parseCapaths: loop " + + count + + ": no intermediaries"); + } + break; } /* @@ -435,7 +441,12 @@ */ try { - tempTarget = iStack.pop(); + while ((tempTarget = iStack.pop()) == null) { + tempList.removeElementAt(tempList.size()-1); + if (DEBUG) { + System.out.println(">>> Realm parseCapaths: backtrack, remove tail"); + } + } } catch (EmptyStackException exc) { tempTarget = null; } diff -r 8ad79de28190 -r d690c8a2acea jdk/test/sun/security/krb5/ParseCAPaths.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/sun/security/krb5/ParseCAPaths.java Mon Feb 23 10:04:25 2009 +0800 @@ -0,0 +1,98 @@ +/* + * Copyright 2009 Sun Microsystems, Inc. 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. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +/* + * @test + * @bug 6789935 + * @summary cross-realm capath search error + */ + +import java.util.Arrays; +import sun.security.krb5.Realm; + +public class ParseCAPaths { + static boolean failed = false; + 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 + 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"); + // 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 + "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("B1.COM", "B3.COM", "B1.COM", "B2.COM"); + // Missing is "." + 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"); + check("I1.COM", "I4.COM", "I1.COM", "I5.COM"); + + if (failed) { + throw new Exception("Failed somewhere."); + } + } + + static void check(String from, String to, String... paths) { + try { + check2(from, to, paths); + } catch (Exception e) { + failed = true; + e.printStackTrace(); + } + } + static void check2(String from, String to, String... paths) + throws Exception { + 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."); + } + } else if(result.length != paths.length) { + throw new Exception("Length of path not correct"); + } else { + for (int i=0; i