diff --git a/test/sun/security/krb5/auto/CrossRealm.java b/test/sun/security/krb5/auto/CrossRealm.java index 9b610279ebca922143e1c63044bba7891b74fc3e..16f738060c869f5b22d291b5d4a5ea4553309f9f 100644 --- a/test/sun/security/krb5/auto/CrossRealm.java +++ b/test/sun/security/krb5/auto/CrossRealm.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008-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 @@ -26,6 +26,7 @@ * @bug 6706974 * @summary Add krb5 test infrastructure */ +import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.security.Security; @@ -50,17 +51,20 @@ public class CrossRealm implements CallbackHandler { KDC kdc1 = KDC.create("RABBIT.HOLE"); kdc1.addPrincipal("dummy", "bogus".toCharArray()); kdc1.addPrincipalRandKey("krbtgt/RABBIT.HOLE"); - kdc1.addPrincipal("krbtgt/SNAKE.HOLE", "sharedsec".toCharArray()); + kdc1.addPrincipal("krbtgt/SNAKE.HOLE@RABBIT.HOLE", + "rabbit->snake".toCharArray()); KDC kdc2 = KDC.create("SNAKE.HOLE"); kdc2.addPrincipalRandKey("krbtgt/SNAKE.HOLE"); - kdc2.addPrincipal("krbtgt/RABBIT.HOLE", "sharedsec".toCharArray()); + kdc2.addPrincipal("krbtgt/SNAKE.HOLE@RABBIT.HOLE", + "rabbit->snake".toCharArray()); kdc2.addPrincipalRandKey("host/www.snake.hole"); KDC.saveConfig("krb5-localkdc.conf", kdc1, kdc2, "forwardable=true", "[domain_realm]", ".snake.hole=SNAKE.HOLE"); + new File("krb5-localkdc.conf").deleteOnExit(); System.setProperty("java.security.krb5.conf", "krb5-localkdc.conf"); } @@ -68,6 +72,7 @@ public class CrossRealm implements CallbackHandler { Security.setProperty("auth.login.defaultCallbackHandler", "CrossRealm"); System.setProperty("java.security.auth.login.config", "jaas-localkdc.conf"); System.setProperty("javax.security.auth.useSubjectCredsOnly", "false"); + new File("jaas-localkdc.conf").deleteOnExit(); FileOutputStream fos = new FileOutputStream("jaas-localkdc.conf"); fos.write(("com.sun.security.jgss.krb5.initiate {\n" + " com.sun.security.auth.module.Krb5LoginModule\n" + diff --git a/test/sun/security/krb5/auto/HttpNegotiateServer.java b/test/sun/security/krb5/auto/HttpNegotiateServer.java index 9505455f9478cbc73e19bda8637b7e8f760b5d88..f50fb55855c7fd4698f55296c43311ad20b161f7 100644 --- a/test/sun/security/krb5/auto/HttpNegotiateServer.java +++ b/test/sun/security/krb5/auto/HttpNegotiateServer.java @@ -25,7 +25,6 @@ * @test * @bug 6578647 * @summary Undefined requesting URL in java.net.Authenticator.getPasswordAuthentication() - * @run main/othervm -Dsun.net.spi.nameservice.provider.1=ns,mock HttpNegotiateServer */ import com.sun.net.httpserver.Headers; @@ -40,12 +39,10 @@ import java.io.IOException; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.InetSocketAddress; -import java.net.InetAddress; import java.net.PasswordAuthentication; import java.net.Proxy; import java.net.URL; import java.security.PrivilegedExceptionAction; -import java.net.UnknownHostException; import java.util.HashMap; import java.util.Map; import javax.security.auth.Subject; @@ -53,8 +50,6 @@ import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSManager; import sun.security.jgss.GSSUtil; -import sun.net.spi.nameservice.NameService; -import sun.net.spi.nameservice.NameServiceDescriptor; import sun.security.krb5.Config; /** @@ -62,7 +57,7 @@ import sun.security.krb5.Config; * party uses JAAS login to get subjects and executes JGSS calls using * Subject.doAs. */ -public class HttpNegotiateServer implements NameServiceDescriptor { +public class HttpNegotiateServer { // Two realm, web server in one, proxy server in another final static String REALM_WEB = "WEB.DOMAIN"; @@ -142,12 +137,12 @@ public class HttpNegotiateServer implements NameServiceDescriptor { public static void main(String[] args) throws Exception { - KDC kdcw = new KDC(REALM_WEB, 0, true); + KDC kdcw = KDC.create(REALM_WEB); kdcw.addPrincipal(WEB_USER, WEB_PASS); kdcw.addPrincipalRandKey("krbtgt/" + REALM_WEB); kdcw.addPrincipalRandKey("HTTP/" + WEB_HOST); - KDC kdcp = new KDC(REALM_PROXY, 0, true); + KDC kdcp = KDC.create(REALM_PROXY); kdcp.addPrincipal(PROXY_USER, PROXY_PASS); kdcp.addPrincipalRandKey("krbtgt/" + REALM_PROXY); kdcp.addPrincipalRandKey("HTTP/" + PROXY_HOST); @@ -306,36 +301,5 @@ public class HttpNegotiateServer implements NameServiceDescriptor { } } } - - @Override - public NameService createNameService() throws Exception { - NameService ns = new NameService() { - @Override - public InetAddress[] lookupAllHostAddr(String host) - throws UnknownHostException { - // Everything is localhost - return new InetAddress[]{ - InetAddress.getByAddress(host, new byte[]{127,0,0,1}) - }; - } - @Override - public String getHostByAddr(byte[] addr) - throws UnknownHostException { - // No reverse lookup - throw new UnknownHostException(); - } - }; - return ns; - } - - @Override - public String getProviderName() { - return "mock"; - } - - @Override - public String getType() { - return "ns"; - } } diff --git a/test/sun/security/krb5/auto/KDC.java b/test/sun/security/krb5/auto/KDC.java index 14767c4085cbe3e41d9148f1f1b1d09e17f1ab2e..601eda50707bb23389fbdcb408672aef03044a4d 100644 --- a/test/sun/security/krb5/auto/KDC.java +++ b/test/sun/security/krb5/auto/KDC.java @@ -30,6 +30,8 @@ import java.lang.reflect.Method; import java.security.SecureRandom; import java.util.*; import java.util.concurrent.*; +import sun.net.spi.nameservice.NameService; +import sun.net.spi.nameservice.NameServiceDescriptor; import sun.security.krb5.*; import sun.security.krb5.internal.*; import sun.security.krb5.internal.ccache.CredentialsCache; @@ -118,14 +120,16 @@ public class KDC { // The random generator to generate random keys (including session keys) private static SecureRandom secureRandom = new SecureRandom(); - // Principal db + // Principal db. principal -> pass private Map passwords = new HashMap(); // Realm name private String realm; - // The request/response job queue - private BlockingQueue q = new ArrayBlockingQueue(100); + // KDC + private String kdc; // Service port number private int port; + // The request/response job queue + private BlockingQueue q = new ArrayBlockingQueue(100); // Options private Map options = new HashMap(); @@ -139,33 +143,21 @@ public class KDC { PREAUTH_REQUIRED, }; + static { + System.setProperty("sun.net.spi.nameservice.provider.1", "ns,mock"); + } + /** * A standalone KDC server. - * @param args - * @throws java.lang.Exception */ public static void main(String[] args) throws Exception { - if (args.length > 0) { - if (args[0].equals("-help") || args[0].equals("--help")) { - System.out.println("Usage:"); - System.out.println(" java " + KDC.class + " " + - "Start KDC on port 8888"); - return; - } - } - String localhost = "localhost"; - try { - localhost = InetAddress.getByName(localhost) - .getCanonicalHostName(); - } catch (UnknownHostException uhe) { - ; // Ignore, localhost is still "localhost" - } - KDC kdc = create("RABBIT.HOLE", 8888, false); + KDC kdc = create("RABBIT.HOLE", "kdc.rabbit,hole", 0, false); kdc.addPrincipal("dummy", "bogus".toCharArray()); kdc.addPrincipal("foo", "bar".toCharArray()); - kdc.addPrincipalRandKey("krbtgt/" + kdc.realm); - kdc.addPrincipalRandKey("server/" + localhost); - kdc.addPrincipalRandKey("backend/" + localhost); + kdc.addPrincipalRandKey("krbtgt/RABBIT.HOLE"); + kdc.addPrincipalRandKey("server/host.rabbit.hole"); + kdc.addPrincipalRandKey("backend/host.rabbit.hole"); + KDC.saveConfig("krb5.conf", kdc, "forwardable = true"); } /** @@ -175,7 +167,7 @@ public class KDC { * @throws java.io.IOException for any socket creation error */ public static KDC create(String realm) throws IOException { - return create(realm, 0, true); + return create(realm, "kdc." + realm.toLowerCase(), 0, true); } /** @@ -187,8 +179,8 @@ public class KDC { * @return the running KDC instance * @throws java.io.IOException for any socket creation error */ - public static KDC create(String realm, int port, boolean asDaemon) throws IOException { - return new KDC(realm, port, asDaemon); + public static KDC create(String realm, String kdc, int port, boolean asDaemon) throws IOException { + return new KDC(realm, kdc, port, asDaemon); } /** @@ -228,10 +220,7 @@ public class KDC { KeyTab ktab = KeyTab.create(tab); for (KDC kdc: kdcs) { for (String name : kdc.passwords.keySet()) { - if (name.equals("krbtgt/" + kdc.realm)) { - continue; - } - ktab.addEntry(new PrincipalName(name + "@" + kdc.realm, + ktab.addEntry(new PrincipalName(name, name.indexOf('/') < 0 ? PrincipalName.KRB_NT_UNKNOWN : PrincipalName.KRB_NT_SRV_HST), @@ -255,6 +244,9 @@ public class KDC { * @param pass the password for the principal */ public void addPrincipal(String user, char[] pass) { + if (user.indexOf('@') < 0) { + user = user + "@" + realm; + } passwords.put(user, pass); } @@ -264,7 +256,7 @@ public class KDC { * form of host/f.q.d.n */ public void addPrincipalRandKey(String user) { - passwords.put(user, randomPassword()); + addPrincipal(user, randomPassword()); } /** @@ -275,6 +267,14 @@ public class KDC { return realm; } + /** + * Returns the name of kdc + * @return the name of kdc + */ + public String getKDC() { + return kdc; + } + /** * Writes a krb5.conf for one or more KDC that includes KDC locations for * each realm and the default realm name. You can also add extra strings @@ -299,7 +299,7 @@ public class KDC { * * [realms] * REALM.NAME = { - * kdc = localhost:port_number + * kdc = host:port_number * } * * @@ -320,10 +320,10 @@ public class KDC { * * [realms] * KDC1.NAME = { - * kdc = localhost:port1 + * kdc = host:port1 * } * KDC2.NAME = { - * kdc = localhost:port2 + * kdc = host:port2 * } * * @param file the name of the file to write into @@ -372,16 +372,17 @@ public class KDC { * Private constructor, cannot be called outside. * @param realm */ - private KDC(String realm) { + private KDC(String realm, String kdc) { this.realm = realm; + this.kdc = kdc; } /** * A constructor that starts the KDC service also. */ - protected KDC(String realm, int port, boolean asDaemon) + protected KDC(String realm, String kdc, int port, boolean asDaemon) throws IOException { - this(realm); + this(realm, kdc); startServer(port, asDaemon); } /** @@ -426,7 +427,11 @@ public class KDC { * the database. */ private char[] getPassword(PrincipalName p) throws KrbException { - char[] pass = passwords.get(p.getNameString()); + String pn = p.toString(); + if (p.getRealmString() == null) { + pn = pn + "@" + getRealm(); + } + char[] pass = passwords.get(pn); if (pass == null) { throw new KrbException(Krb5.KDC_ERR_C_PRINCIPAL_UNKNOWN); } @@ -434,29 +439,18 @@ public class KDC { } /** - * Returns the salt string for the principal. For normal users, the - * concatenation for the realm name and the sections of the principal; - * for krgtgt/A@B and krbtgt/B@A, always return AB (so that inter-realm - * principals have the same key). + * Returns the salt string for the principal. * @param p principal * @return the salt */ private String getSalt(PrincipalName p) { String[] ns = p.getNameStrings(); - if (ns[0].equals("krbtgt") && ns.length > 1) { - // Shared cross-realm keys must be the same - if (ns[1].compareTo(realm) < 0) { - return ns[1] + realm; - } else { - return realm + ns[1]; - } - } else { - String s = getRealm(); - for (String n: p.getNameStrings()) { - s += n; - } - return s; + String s = p.getRealmString(); + if (s == null) s = getRealm(); + for (String n: p.getNameStrings()) { + s += n; } + return s; } /** @@ -525,14 +519,8 @@ public class KDC { EncryptedData ed = apReq.authenticator; tkt = apReq.ticket; etype = tkt.encPart.getEType(); - EncryptionKey kkey = null; - if (!tkt.realm.toString().equals(realm)) { - if (tkt.sname.getNameString().equals("krbtgt/" + realm)) { - kkey = keyForUser(new PrincipalName("krbtgt/" + tkt.realm.toString(), realm), etype); - } - } else { - kkey = keyForUser(tkt.sname, etype); - } + tkt.sname.setRealm(tkt.realm); + EncryptionKey kkey = keyForUser(tkt.sname, etype); byte[] bb = tkt.encPart.decrypt(kkey, KeyUsage.KU_TICKET); DerInputStream derIn = new DerInputStream(bb); DerValue der = derIn.getDerValue(); @@ -857,10 +845,13 @@ public class KDC { /** * Generates a line for a KDC to put inside [realms] of krb5.conf * @param kdc the KDC - * @return REALM.NAME = { kdc = localhost:port } + * @return REALM.NAME = { kdc = host:port } */ private static String realmLineForKDC(KDC kdc) { - return String.format(" %s = {\n kdc = localhost:%d\n }\n", kdc.realm, kdc.port); + return String.format(" %s = {\n kdc = %s:%d\n }\n", + kdc.realm, + kdc.kdc, + kdc.port); } /** @@ -1000,4 +991,37 @@ public class KDC { } } } + + public static class KDCNameService implements NameServiceDescriptor { + @Override + public NameService createNameService() throws Exception { + NameService ns = new NameService() { + @Override + public InetAddress[] lookupAllHostAddr(String host) + throws UnknownHostException { + // Everything is localhost + return new InetAddress[]{ + InetAddress.getByAddress(host, new byte[]{127,0,0,1}) + }; + } + @Override + public String getHostByAddr(byte[] addr) + throws UnknownHostException { + // No reverse lookup, PrincipalName use original string + throw new UnknownHostException(); + } + }; + return ns; + } + + @Override + public String getProviderName() { + return "mock"; + } + + @Override + public String getType() { + return "ns"; + } + } } diff --git a/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor b/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor index 32f3a09bb472ceb7c47f07fbb543806150364fe5..b87d67ad274150b74d2a42b5460767cf192947ff 100644 --- a/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor +++ b/test/sun/security/krb5/auto/META-INF/services/sun.net.spi.nameservice.NameServiceDescriptor @@ -1 +1 @@ -HttpNegotiateServer +KDC$KDCNameService diff --git a/test/sun/security/krb5/auto/OneKDC.java b/test/sun/security/krb5/auto/OneKDC.java index 9505c6a3c8f6378ece79fa61e1e7c391056de96f..213869e8d24037582b996696afa2e0dd7279145f 100644 --- a/test/sun/security/krb5/auto/OneKDC.java +++ b/test/sun/security/krb5/auto/OneKDC.java @@ -1,5 +1,5 @@ /* - * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright 2008-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 @@ -46,35 +46,22 @@ import sun.security.krb5.Config; */ public class OneKDC extends KDC { - // The krb5 codes would try to canonicalize hostnames before creating - // a service principal name, so let's find out the canonicalized form - // of localhost first. The following codes mimic the process inside - // PrincipalName.java. - static String localhost = "localhost"; - static { - try { - localhost = InetAddress.getByName(localhost) - .getCanonicalHostName(); - } catch (UnknownHostException uhe) { - ; // Ignore, localhost is still "localhost" - } - } public static final String USER = "dummy"; public static final char[] PASS = "bogus".toCharArray(); - public static String SERVER = "server/" + localhost; - public static String BACKEND = "backend/" + localhost; public static final String KRB5_CONF = "localkdc-krb5.conf"; public static final String KTAB = "localkdc.ktab"; public static final String JAAS_CONF = "localkdc-jaas.conf"; public static final String REALM = "RABBIT.HOLE"; - + public static String SERVER = "server/host." + REALM.toLowerCase(); + public static String BACKEND = "backend/host." + REALM.toLowerCase(); + public static String KDCHOST = "kdc." + REALM.toLowerCase(); /** * Creates the KDC and starts it. * @param etype Encryption type, null if not specified * @throws java.lang.Exception if there's anything wrong */ public OneKDC(String etype) throws Exception { - super(REALM, 0, true); + super(REALM, KDCHOST, 0, true); addPrincipal(USER, PASS); addPrincipalRandKey("krbtgt/" + REALM); addPrincipalRandKey(SERVER); diff --git a/test/sun/security/krb5/auto/basic.sh b/test/sun/security/krb5/auto/basic.sh index 388e4a1ea55d8d46e7f0119376cdcaeec2e6691c..f2592ee2dc10ae23b165fb4d079aeaac80551856 100644 --- a/test/sun/security/krb5/auto/basic.sh +++ b/test/sun/security/krb5/auto/basic.sh @@ -1,5 +1,5 @@ # -# Copyright 2008 Sun Microsystems, Inc. All Rights Reserved. +# Copyright 2008-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 @@ -41,25 +41,31 @@ OS=`uname -s` case "$OS" in Windows_* ) FS="\\" + SEP=";" ;; * ) FS="/" + SEP=":" ;; esac -${TESTJAVA}${FS}bin${FS}javac -d . \ +${TESTJAVA}${FS}bin${FS}javac -XDignore.symbol.file -d . \ ${TESTSRC}${FS}BasicKrb5Test.java \ ${TESTSRC}${FS}KDC.java \ ${TESTSRC}${FS}OneKDC.java \ ${TESTSRC}${FS}Action.java \ ${TESTSRC}${FS}Context.java \ || exit 10 -${TESTJAVA}${FS}bin${FS}java -Dtest.src=$TESTSRC BasicKrb5Test || exit 100 -${TESTJAVA}${FS}bin${FS}java -Dtest.src=$TESTSRC BasicKrb5Test des-cbc-crc || exit 1 -${TESTJAVA}${FS}bin${FS}java -Dtest.src=$TESTSRC BasicKrb5Test des-cbc-md5 || exit 3 -${TESTJAVA}${FS}bin${FS}java -Dtest.src=$TESTSRC BasicKrb5Test des3-cbc-sha1 || exit 16 -${TESTJAVA}${FS}bin${FS}java -Dtest.src=$TESTSRC BasicKrb5Test aes128-cts || exit 17 -${TESTJAVA}${FS}bin${FS}java -Dtest.src=$TESTSRC BasicKrb5Test aes256-cts || exit 18 -${TESTJAVA}${FS}bin${FS}java -Dtest.src=$TESTSRC BasicKrb5Test rc4-hmac || exit 23 + +# Add $TESTSRC to classpath so that customized nameservice can be used +J="${TESTJAVA}${FS}bin${FS}java -cp $TESTSRC${SEP}. BasicKrb5Test" + +$J || exit 100 +$J des-cbc-crc || exit 1 +$J des-cbc-md5 || exit 3 +$J des3-cbc-sha1 || exit 16 +$J aes128-cts || exit 17 +$J aes256-cts || exit 18 +$J rc4-hmac || exit 23 exit 0