--- /dev/null 2014-06-24 15:54:54.000000000 +0800 +++ new/test/sun/security/krb5/auto/NioTests.java 2014-06-24 15:54:54.000000000 +0800 @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2014, 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. + * + * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8014870 + * @run main/othervm NioTests true true true 7 true + * @run main/othervm NioTests true true false 11 true + * @run main/othervm NioTests true false true 11 false + * @run main/othervm NioTests true false false 22 false + * @run main/othervm NioTests false true true 12 true + * @run main/othervm NioTests false true false 14 true + * @run main/othervm NioTests false false true 17 false + * @run main/othervm NioTests false false false 22 false + */ + +import java.io.*; +import java.net.BindException; +import java.net.DatagramSocket; +import java.net.ServerSocket; +import javax.security.auth.login.LoginException; +import sun.security.krb5.Asn1Exception; +import sun.security.krb5.Config; + +public class NioTests { + + public static void main(String... args) throws Exception { + try { + go0(Boolean.parseBoolean(args[0]), // UDP or TCP + Boolean.parseBoolean(args[1]), // real KDC available + Boolean.parseBoolean(args[2]), // fake KDCs available + Integer.parseInt(args[3]), // Expected number of logs + Boolean.parseBoolean(args[4])); // Expected result of req + } catch (BindException be) { + System.out.println("The random port is used by another process"); + } catch (LoginException le) { + Throwable cause = le.getCause(); + if (cause instanceof Asn1Exception) { + System.out.println("Bad packet possibly from another process"); + return; + } + throw le; + } + } + + public static void go0(boolean udp, boolean oneServer, boolean fakeServer, + int number, boolean result) + throws Exception { + System.setProperty("sun.security.krb5.debug", "true"); + + // Idle sockets to confuse the clients + DatagramSocket d1 = null, d2 = null, d3 = null; + ServerSocket s1 = null, s2 = null, s3 = null; + + // Make sure KDCs' ports starts with 1 and 2 and 3, + // useful for checking debug output. + int p1 = 10000 + new java.util.Random().nextInt(10000); + int p2 = 20000 + new java.util.Random().nextInt(10000); + int p3 = 30000 + new java.util.Random().nextInt(10000); + + KDC k = null; + + FileWriter fw = new FileWriter("alternative-krb5.conf"); + + fw.write("[libdefaults]\n" + + (udp?"":"udp_preference_limit = 1\n") + + "max_retries = 2\n" + + "default_realm = " + OneKDC.REALM + "\n"); + fw.write("[realms]\n" + OneKDC.REALM + " = {\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p1 + "\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p2 + "\n" + + "kdc = " + OneKDC.KDCHOST + ":" + p3 + "\n" + + "}\n"); + + fw.close(); + System.setProperty("java.security.krb5.conf", "alternative-krb5.conf"); + Config.refresh(); + + if (fakeServer) { + if (udp) { + d1 = new DatagramSocket(p1); + d2 = new DatagramSocket(p2); + if (!oneServer) { + d3 = new DatagramSocket(p3); + } + } else { + s1 = new ServerSocket(p1); + s2 = new ServerSocket(p2); + if (!oneServer) { + s3 = new ServerSocket(p3); + } + } + } + + if (oneServer) { + k = on(p3); + } + + ByteArrayOutputStream bo = new ByteArrayOutputStream(); + ByteArrayOutputStream be = new ByteArrayOutputStream(); + + PrintStream oldOut = System.out; + PrintStream oldErr = System.err; + System.setErr(new PrintStream(be)); + System.setOut(new PrintStream(bo)); + boolean succeed = true; + long start = System.nanoTime(); + long end = 0; + try { + Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false); + } catch (Exception e) { + e.printStackTrace(); + succeed = false; + } finally { + System.setOut(oldOut); + System.setErr(oldErr); + end = System.nanoTime(); + System.out.println(new String(bo.toByteArray())); + System.out.println(new String(be.toByteArray())); + } + + String[] lines = new String(bo.toByteArray()).split("\n"); + int cc = 0; + for (String line: lines) { + if (line.indexOf("KdcComm: ") == 0) { + cc++; + } + } + System.out.println("KdcComm Test: " + (udp?"UDP":"TCP") + + (oneServer?" kdc3":"") + (fakeServer?" fake":"") + + ". Result: " + cc + " " + succeed + ". Elapsed: " + + (end-start)/1000000000.0); + + if (fakeServer) { + if (udp) { + d1.close(); + d2.close(); + if (!oneServer) { + d3.close(); + } + } else { + s1.close(); + s2.close(); + if (!oneServer) { + s3.close(); + } + } + } + + if (oneServer) { + k.terminate(); + } + + if (result != succeed || number != cc) { + throw new Exception("Test failure"); + } + } + + private static KDC on(int p) throws Exception { + KDC k = new KDC(OneKDC.REALM, OneKDC.KDCHOST, p, true); + k.addPrincipal(OneKDC.USER, OneKDC.PASS); + k.addPrincipalRandKey("krbtgt/" + OneKDC.REALM); + k.setOption(KDC.Option.PREAUTH_REQUIRED, false); + return k; + } +}