6682516: SPNEGO_HTTP_AUTH/WWW_KRB and SPNEGO_HTTP_AUTH/WWW_SPNEGO failed on all non-windows platforms
Reviewed-by: xuelei
diff --git a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
index 0e6b328..3761ffb 100644
--- a/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
+++ b/jdk/src/share/classes/sun/security/krb5/PrincipalName.java
@@ -1,5 +1,5 @@
/*
- * Portions Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Portions Copyright 2000-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
@@ -36,8 +36,6 @@
import java.net.*;
import java.util.Vector;
import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import sun.security.krb5.internal.ccache.CCacheOutputStream;
@@ -383,19 +381,26 @@
switch (type) {
case KRB_NT_SRV_HST:
if (nameParts.length >= 2) {
+ String hostName = nameParts[1];
try {
- // Canonicalize the hostname as per the
- // RFC4120 Section 6.2.1 and
- // RFC1964 Section 2.1.2
- // we assume internet domain names
- String hostName =
- (InetAddress.getByName(nameParts[1])).
- getCanonicalHostName();
- nameParts[1] = hostName.toLowerCase();
+ // RFC4120 does not recommend canonicalizing a hostname.
+ // However, for compatibility reason, we will try
+ // canonicalize it and see if the output looks better.
+
+ String canonicalized = (InetAddress.getByName(hostName)).
+ getCanonicalHostName();
+
+ // Looks if canonicalized is a longer format of hostName,
+ // we accept cases like
+ // bunny -> bunny.rabbit.hole
+ if (canonicalized.toLowerCase()
+ .startsWith(hostName.toLowerCase()+".")) {
+ hostName = canonicalized;
+ }
} catch (UnknownHostException e) {
- // no canonicalization, just convert to lowercase
- nameParts[1] = nameParts[1].toLowerCase();
+ // no canonicalization, use old
}
+ nameParts[1] = hostName.toLowerCase();
}
nameStrings = nameParts;
nameType = type;
diff --git a/jdk/test/sun/security/krb5/canonicalize/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/jdk/test/sun/security/krb5/canonicalize/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
new file mode 100644
index 0000000..345e6ae
--- /dev/null
+++ b/jdk/test/sun/security/krb5/canonicalize/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor
@@ -0,0 +1 @@
+Test
diff --git a/jdk/test/sun/security/krb5/canonicalize/Test.java b/jdk/test/sun/security/krb5/canonicalize/Test.java
new file mode 100644
index 0000000..e4fb4f6
--- /dev/null
+++ b/jdk/test/sun/security/krb5/canonicalize/Test.java
@@ -0,0 +1,103 @@
+/*
+ * 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 6682516
+ * @summary SPNEGO_HTTP_AUTH/WWW_KRB and SPNEGO_HTTP_AUTH/WWW_SPNEGO failed on all non-windows platforms
+ * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock -Djava.security.krb5.conf=krb5.conf Test
+ */
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import sun.net.spi.nameservice.NameService;
+import sun.net.spi.nameservice.NameServiceDescriptor;
+import sun.security.krb5.PrincipalName;
+
+public class Test implements NameServiceDescriptor {
+ public static void main(String[] args) throws Exception {
+ // This config file is generated using Kerberos.app on a Mac
+ System.setProperty("java.security.krb5.realm", "THIS.REALM");
+ System.setProperty("java.security.krb5.kdc", "localhost");
+
+ // add using canonicalized name
+ check("c1", "c1.this.domain");
+ check("c1.this", "c1.this.domain");
+ check("c1.this.domain", "c1.this.domain");
+
+ // canonicalized name goes IP, reject
+ check("c2", "c2");
+
+ // canonicalized name goes strange, reject
+ check("c3", "c3");
+
+ // unsupported
+ check("c4", "c4");
+ }
+
+ static void check(String input, String output) throws Exception {
+ System.out.println(input + " -> " + output);
+ PrincipalName pn = new PrincipalName("host/"+input,
+ PrincipalName.KRB_NT_SRV_HST);
+ if (!pn.getNameStrings()[1].equals(output)) {
+ throw new Exception("Output is " + pn);
+ }
+ }
+
+ @Override
+ public NameService createNameService() throws Exception {
+ NameService ns = new NameService() {
+ @Override
+ public InetAddress[] lookupAllHostAddr(String host)
+ throws UnknownHostException {
+ // All c<n>.* goes to 127.0.0.n
+ int i = Integer.valueOf(host.split("\\.")[0].substring(1));
+ return new InetAddress[]{
+ InetAddress.getByAddress(host, new byte[]{127,0,0,(byte)i})
+ };
+ }
+ @Override
+ public String getHostByAddr(byte[] addr)
+ throws UnknownHostException {
+ int i = addr[3];
+ switch (i) {
+ case 1: return "c1.this.domain"; // Good
+ case 2: return "127.0.0.2"; // Only IP
+ case 3: return "d3.this.domain"; // name change
+ default:
+ throw new UnknownHostException();
+ }
+ }
+ };
+ return ns;
+ }
+
+ @Override
+ public String getProviderName() {
+ return "mock";
+ }
+
+ @Override
+ public String getType() {
+ return "ns";
+ }
+}