mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-15 08:34:30 +02:00
Merge
This commit is contained in:
commit
1c89e3aa56
390 changed files with 7435 additions and 10519 deletions
|
@ -273,7 +273,7 @@ BUNDLE_UP_AND_EXIT = \
|
|||
prep:
|
||||
@$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
|
||||
@$(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)`
|
||||
@if [ ! -d $(TEST_ROOT)/../.hg ] ; then \
|
||||
@if [ ! -d $(TEST_ROOT)/../../.hg ] && [ ! -d $(TEST_ROOT)/../../../.hg ]; then \
|
||||
$(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \) \
|
||||
-exec $(CHMOD) a+rx {} \; ; \
|
||||
fi
|
||||
|
|
68
test/hotspot/jtreg/runtime/execstack/TestCheckJDK.java
Normal file
68
test/hotspot/jtreg/runtime/execstack/TestCheckJDK.java
Normal file
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 Testexecstack.java
|
||||
* @summary Searches for all libraries in test VM and checks that they
|
||||
* have the noexecstack bit set.
|
||||
* @requires (os.family == "linux")
|
||||
* @library /test/lib
|
||||
* @modules java.base/jdk.internal.misc
|
||||
* @build sun.hotspot.WhiteBox
|
||||
* @run driver ClassFileInstaller sun.hotspot.WhiteBox
|
||||
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||
* TestCheckJDK
|
||||
*/
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
import sun.hotspot.WhiteBox;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class TestCheckJDK {
|
||||
static boolean testPassed = true;
|
||||
private static final WhiteBox WB = WhiteBox.getWhiteBox();
|
||||
|
||||
static void checkExecStack(Path file) {
|
||||
String filename = file.toString();
|
||||
if (filename.endsWith(".so")) {
|
||||
if (!WB.checkLibSpecifiesNoexecstack(filename)) {
|
||||
System.out.println("Library does not have the noexecstack bit set: " + filename);
|
||||
testPassed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
String vmInstallDir = System.getProperty("java.home");
|
||||
|
||||
Files.walk(Paths.get(vmInstallDir)).filter(Files::isRegularFile).forEach(TestCheckJDK::checkExecStack);
|
||||
|
||||
Asserts.assertTrue(testPassed,
|
||||
"The tested VM contains libs that don't have the noexecstack " +
|
||||
"bit set. They must be linked with -z,noexecstack.");
|
||||
}
|
||||
}
|
|
@ -468,7 +468,6 @@ needs_jdk = \
|
|||
com/sun/tools \
|
||||
jdk/security/jarsigner \
|
||||
sun/security/tools/jarsigner \
|
||||
sun/security/tools/policytool \
|
||||
sun/rmi/rmic \
|
||||
sun/tools \
|
||||
sun/jvmstat \
|
||||
|
@ -785,8 +784,7 @@ compact1_minimal = \
|
|||
-:needs_jdk
|
||||
|
||||
needs_headful = \
|
||||
java/util/TimeZone/DefaultTimeZoneTest.java \
|
||||
sun/security/tools/policytool
|
||||
java/util/TimeZone/DefaultTimeZoneTest.java
|
||||
|
||||
needs_locales = \
|
||||
-:needs_locales_and_charsets \
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2017, 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
|
||||
|
@ -26,19 +26,56 @@
|
|||
* @bug 4273031
|
||||
* @summary ClassLoader.getResouce() should be able to
|
||||
* find resources with leading "." in their names
|
||||
* @build GetDotResource
|
||||
* @run shell getdotresource.sh
|
||||
* @library /lib/testlibrary
|
||||
* @build jdk.testlibrary.*
|
||||
* @run main GetDotResource
|
||||
*/
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarOutputStream;
|
||||
|
||||
import jdk.testlibrary.ProcessTools;
|
||||
|
||||
public class GetDotResource {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
private static final String JAR_FILENAME = "resource.jar";
|
||||
private static final String DOT_FILENAME = ".resource";
|
||||
private static final String CP = JAR_FILENAME + File.pathSeparator
|
||||
+ System.getProperty("test.class.path");
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
if (args.length == 0) {
|
||||
createJar(JAR_FILENAME, DOT_FILENAME);
|
||||
|
||||
ProcessTools.executeTestJava("-cp", CP,
|
||||
GetDotResource.class.getName(),
|
||||
DOT_FILENAME)
|
||||
.outputTo(System.out)
|
||||
.errorTo(System.out)
|
||||
.shouldHaveExitValue(0);
|
||||
} else {
|
||||
runTest(args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
public static void runTest(String dotFileName) throws Exception {
|
||||
if (GetDotResource.class.getClassLoader().
|
||||
getResourceAsStream(".resource") == null)
|
||||
throw new Exception("Could not find resource with " +
|
||||
"leading . in their names");
|
||||
getResourceAsStream(dotFileName) == null) {
|
||||
throw new Exception("Could not find resource with "
|
||||
+ "leading . in their names");
|
||||
}
|
||||
}
|
||||
|
||||
public static void createJar(String jarFileName, String dotFileName)
|
||||
throws IOException {
|
||||
try (FileOutputStream fos = new FileOutputStream(jarFileName);
|
||||
JarOutputStream out = new JarOutputStream(fos))
|
||||
{
|
||||
out.putNextEntry(new JarEntry(dotFileName));
|
||||
out.closeEntry();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
#! /bin/sh
|
||||
|
||||
#
|
||||
# Copyright (c) 1999, 2012, 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.
|
||||
#
|
||||
|
||||
if [ x"$TESTJAVA" = x ]; then
|
||||
TESTJAVA=$1
|
||||
shift
|
||||
fi
|
||||
if [ x"$TESTCLASSES" = x ]; then TESTCLASSES=.; fi
|
||||
if [ x"$TESTSRC" = x ]; then TESTSRC=.; fi
|
||||
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
Windows* | CYGWIN* )
|
||||
PS=";"
|
||||
FS="\\"
|
||||
;;
|
||||
* )
|
||||
PS=":"
|
||||
FS="/"
|
||||
;;
|
||||
esac
|
||||
|
||||
# now start the test
|
||||
${TESTJAVA}/bin/java ${TESTVMOPTS} -cp ${TESTSRC}${FS}resource.jar${PS}${TESTCLASSES} GetDotResource
|
Binary file not shown.
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2017, 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
|
||||
|
@ -22,13 +22,15 @@
|
|||
*/
|
||||
|
||||
/* @test
|
||||
* @summary High arity invocations, up to the maximum of 255 arguments
|
||||
* @summary High arity invocations
|
||||
* @compile BigArityTest.java
|
||||
* @run junit/othervm/timeout=2500 -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -esa -DBigArityTest.ITERATION_COUNT=1 test.java.lang.invoke.BigArityTest
|
||||
*/
|
||||
|
||||
package test.java.lang.invoke;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
|
@ -37,8 +39,8 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BigArityTest {
|
||||
|
||||
|
@ -63,12 +65,70 @@ public class BigArityTest {
|
|||
static Object hashArguments(Object... args) {
|
||||
return Objects.hash(args);
|
||||
}
|
||||
static Object hashArguments(int... args) {
|
||||
Object[] wrappedArgs = new Object[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
wrappedArgs[i] = args[i];
|
||||
}
|
||||
return hashArguments(wrappedArgs);
|
||||
}
|
||||
static Object hashArguments(long... args) {
|
||||
Object[] wrappedArgs = new Object[args.length];
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
wrappedArgs[i] = (int) args[i];
|
||||
}
|
||||
return hashArguments(wrappedArgs);
|
||||
}
|
||||
|
||||
static Object hashArguments1(Object o, Object... args) {
|
||||
Object[] arr = new Object[args.length + 1];
|
||||
arr[0] = 0;
|
||||
System.arraycopy(args, 0, arr, 1, args.length);
|
||||
return Objects.hash(arr);
|
||||
}
|
||||
static Object hashArguments1(int i0, int... args) {
|
||||
Object[] wrappedArgs = new Object[args.length + 1];
|
||||
wrappedArgs[0] = i0;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
wrappedArgs[i + 1] = args[i];
|
||||
}
|
||||
return hashArguments(wrappedArgs);
|
||||
}
|
||||
static Object hashArguments1(long l0, long... args) {
|
||||
Object[] wrappedArgs = new Object[args.length + 1];
|
||||
wrappedArgs[0] = l0;
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
wrappedArgs[i + 1] = (int) args[i];
|
||||
}
|
||||
return hashArguments(wrappedArgs);
|
||||
}
|
||||
|
||||
static final MethodHandle MH_hashArguments_VA;
|
||||
static final MethodHandle MH_hashArguments_IVA;
|
||||
static final MethodHandle MH_hashArguments_JVA;
|
||||
static final MethodHandle MH_hashArguments1_VA;
|
||||
static final MethodHandle MH_hashArguments1_IVA;
|
||||
static final MethodHandle MH_hashArguments1_JVA;
|
||||
static {
|
||||
try {
|
||||
MH_hashArguments_VA =
|
||||
MethodHandles.lookup().unreflect(
|
||||
BigArityTest.class.getDeclaredMethod("hashArguments", Object[].class));
|
||||
MH_hashArguments_IVA =
|
||||
MethodHandles.lookup().unreflect(
|
||||
BigArityTest.class.getDeclaredMethod("hashArguments", int[].class));
|
||||
MH_hashArguments_JVA =
|
||||
MethodHandles.lookup().unreflect(
|
||||
BigArityTest.class.getDeclaredMethod("hashArguments", long[].class));
|
||||
MH_hashArguments1_VA =
|
||||
MethodHandles.lookup().unreflect(
|
||||
BigArityTest.class.getDeclaredMethod("hashArguments1", Object.class, Object[].class));
|
||||
MH_hashArguments1_IVA =
|
||||
MethodHandles.lookup().unreflect(
|
||||
BigArityTest.class.getDeclaredMethod("hashArguments1", int.class, int[].class));
|
||||
MH_hashArguments1_JVA =
|
||||
MethodHandles.lookup().unreflect(
|
||||
BigArityTest.class.getDeclaredMethod("hashArguments1", long.class, long[].class));
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new Error(ex);
|
||||
}
|
||||
|
@ -345,6 +405,28 @@ public class BigArityTest {
|
|||
assertEquals("arity=MAX_ARITY", r0, r);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeWithArgumentsJumbo() throws Throwable {
|
||||
System.out.println("testing invokeWithArguments on jumbo arities");
|
||||
ArrayList<Integer> arities = new ArrayList<>();
|
||||
for (int arity = 125; arity < 1000; arity += (arity < MAX_ARITY+10 ? 1 : arity/7)) {
|
||||
arities.add(arity);
|
||||
Object[] args = testArgs(arity);
|
||||
Object r0 = Objects.hash(args);
|
||||
|
||||
assertEquals("jumbo arity="+arity, r0, MH_hashArguments_VA.invokeWithArguments(args));
|
||||
assertEquals("jumbo arity="+arity, r0, MH_hashArguments1_VA.invokeWithArguments(args));
|
||||
|
||||
// use primitive typed argument lists also:
|
||||
assertEquals("jumbo int arity="+arity, r0, MH_hashArguments_IVA.invokeWithArguments(args));
|
||||
assertEquals("jumbo int arity="+arity, r0, MH_hashArguments1_IVA.invokeWithArguments(args));
|
||||
|
||||
assertEquals("jumbo long arity="+arity, r0, MH_hashArguments_JVA.invokeWithArguments(args));
|
||||
assertEquals("jumbo long arity="+arity, r0, MH_hashArguments1_JVA.invokeWithArguments(args));
|
||||
}
|
||||
System.out.println(" jumbo arities = "+arities);
|
||||
}
|
||||
|
||||
static Object[] cat(Object a, Object[] b) {
|
||||
int alen = 1, blen = b.length;
|
||||
Object[] c = new Object[alen + blen];
|
||||
|
|
135
test/jdk/java/lang/invoke/InvokeWithArgumentsTest.java
Normal file
135
test/jdk/java/lang/invoke/InvokeWithArgumentsTest.java
Normal file
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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
|
||||
* @summary basic tests for MethodHandle.invokeWithArguments
|
||||
* @run testng test.java.lang.invoke.InvokeWithArgumentsTest
|
||||
*/
|
||||
|
||||
package test.java.lang.invoke;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.WrongMethodTypeException;
|
||||
|
||||
import static java.lang.invoke.MethodType.methodType;
|
||||
|
||||
public class InvokeWithArgumentsTest {
|
||||
static final MethodHandles.Lookup L = MethodHandles.lookup();
|
||||
|
||||
static Object[] arity(Object o1, Object o2, Object... a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArity() throws Throwable {
|
||||
MethodHandle mh = L.findStatic(L.lookupClass(), "arity",
|
||||
methodType(Object[].class, Object.class, Object.class, Object[].class));
|
||||
|
||||
try {
|
||||
mh.invokeWithArguments("");
|
||||
Assert.fail("WrongMethodTypeException expected");
|
||||
} catch (WrongMethodTypeException e) {}
|
||||
}
|
||||
|
||||
static Object[] passThrough(String... a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
static Object[] pack(Object o, Object... a) {
|
||||
return a;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayNoPassThrough() throws Throwable {
|
||||
String[] actual = {"A", "B"};
|
||||
|
||||
MethodHandle mh = L.findStatic(L.lookupClass(), "passThrough",
|
||||
methodType(Object[].class, String[].class));
|
||||
|
||||
// Note: the actual array is not preserved, the elements will be
|
||||
// unpacked and then packed into a new array before invoking the method
|
||||
String[] expected = (String[]) mh.invokeWithArguments(actual);
|
||||
|
||||
Assert.assertTrue(actual != expected, "Array should not pass through");
|
||||
Assert.assertEquals(actual, expected, "Array contents should be equal");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayPack() throws Throwable {
|
||||
String[] actual = new String[]{"A", "B"};
|
||||
|
||||
MethodHandle mh = L.findStatic(L.lookupClass(), "pack",
|
||||
methodType(Object[].class, Object.class, Object[].class));
|
||||
|
||||
// Note: since String[] can be cast to Object, the actual String[] array
|
||||
// will cast to Object become the single element of a new Object[] array
|
||||
Object[] expected = (Object[]) mh.invokeWithArguments("", actual);
|
||||
|
||||
Assert.assertEquals(1, expected.length, "Array should contain just one element");
|
||||
Assert.assertTrue(actual == expected[0], "Array should pass through");
|
||||
}
|
||||
|
||||
static void intArray(int... a) {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrimitiveArrayWithNull() throws Throwable {
|
||||
MethodHandle mh = L.findStatic(L.lookupClass(), "intArray",
|
||||
methodType(void.class, int[].class));
|
||||
try {
|
||||
mh.invokeWithArguments(null, null);
|
||||
Assert.fail("NullPointerException expected");
|
||||
} catch (NullPointerException e) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrimitiveArrayWithRef() throws Throwable {
|
||||
MethodHandle mh = L.findStatic(L.lookupClass(), "intArray",
|
||||
methodType(void.class, int[].class));
|
||||
try {
|
||||
mh.invokeWithArguments("A", "B");
|
||||
Assert.fail("ClassCastException expected");
|
||||
} catch (ClassCastException e) {}
|
||||
}
|
||||
|
||||
|
||||
static void numberArray(Number... a) {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRefArrayWithCast() throws Throwable {
|
||||
MethodHandle mh = L.findStatic(L.lookupClass(), "numberArray",
|
||||
methodType(void.class, Number[].class));
|
||||
// All numbers, should not throw
|
||||
mh.invokeWithArguments(1, 1.0, 1.0F, 1L);
|
||||
|
||||
try {
|
||||
mh.invokeWithArguments("A");
|
||||
Assert.fail("ClassCastException expected");
|
||||
} catch (ClassCastException e) {}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2015, 2017, 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
|
||||
|
@ -203,10 +203,8 @@ abstract class VarHandleBaseTest {
|
|||
|
||||
static List<TestAccessMode> testAccessModesOfType(TestAccessType... ats) {
|
||||
Stream<TestAccessMode> s = Stream.of(TestAccessMode.values());
|
||||
for (TestAccessType at : ats) {
|
||||
s = s.filter(e -> e.isOfType(at));
|
||||
}
|
||||
return s.collect(toList());
|
||||
return s.filter(e -> Stream.of(ats).anyMatch(e::isOfType))
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
static List<VarHandle.AccessMode> accessModes() {
|
||||
|
@ -215,10 +213,9 @@ abstract class VarHandleBaseTest {
|
|||
|
||||
static List<VarHandle.AccessMode> accessModesOfType(TestAccessType... ats) {
|
||||
Stream<TestAccessMode> s = Stream.of(TestAccessMode.values());
|
||||
for (TestAccessType at : ats) {
|
||||
s = s.filter(e -> e.isOfType(at));
|
||||
}
|
||||
return s.map(TestAccessMode::toAccessMode).collect(toList());
|
||||
return s.filter(e -> Stream.of(ats).anyMatch(e::isOfType))
|
||||
.map(TestAccessMode::toAccessMode)
|
||||
.collect(toList());
|
||||
}
|
||||
|
||||
static MethodHandle toMethodHandle(VarHandle vh, TestAccessMode tam, MethodType mt) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2000, 2017, 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
|
||||
|
@ -24,11 +24,11 @@
|
|||
/**
|
||||
* @test
|
||||
* @bug 4361783
|
||||
* @key intermittent
|
||||
* @summary Test to see if ICMP Port Unreachable on non-connected
|
||||
* DatagramSocket causes a SocketException "socket closed"
|
||||
* exception on Windows 2000.
|
||||
*/
|
||||
import java.net.BindException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.DatagramPacket;
|
||||
|
@ -50,7 +50,7 @@ public class PortUnreachable {
|
|||
serverPort);
|
||||
clientSock.send(packet);
|
||||
|
||||
DatagramSocket sock = new DatagramSocket(serverPort);
|
||||
DatagramSocket sock = recreateServerSocket(serverPort);
|
||||
b = "Greetings from the server".getBytes();
|
||||
packet = new DatagramPacket(b, b.length, addr, clientPort);
|
||||
sock.send(packet);
|
||||
|
@ -60,6 +60,29 @@ public class PortUnreachable {
|
|||
}
|
||||
}
|
||||
|
||||
DatagramSocket recreateServerSocket (int serverPort) throws Exception {
|
||||
DatagramSocket serverSocket = null;
|
||||
int retryCount = 0;
|
||||
System.out.println("Attempting to recreate server socket with port: " +
|
||||
serverPort);
|
||||
while (serverSocket == null) {
|
||||
try {
|
||||
serverSocket = new DatagramSocket(serverPort);
|
||||
} catch (BindException bEx) {
|
||||
if (retryCount++ < 5) {
|
||||
Thread.sleep(500);
|
||||
} else {
|
||||
System.out.println("Give up after 5 retries");
|
||||
throw bEx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("PortUnreachableTest.recreateServerSocket: returning socket == "
|
||||
+ serverSocket.getLocalAddress() + ":" + serverSocket.getLocalPort());
|
||||
return serverSocket;
|
||||
}
|
||||
|
||||
PortUnreachable() throws Exception {
|
||||
|
||||
clientSock = new DatagramSocket();
|
||||
|
@ -103,3 +126,4 @@ public class PortUnreachable {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
881
test/jdk/java/net/HugeDataTransferTest.java
Normal file
881
test/jdk/java/net/HugeDataTransferTest.java
Normal file
|
@ -0,0 +1,881 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 8185072
|
||||
* @summary network006 times out in many configs in JDK10-hs nightly
|
||||
* @run main/othervm/manual HugeDataTransferTest 1
|
||||
*/
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* This test makes huge number of data transfers between 2 Java virtual machines
|
||||
* using the TCP/IP protocol, and checks if those data are transfered correctly.
|
||||
* Both client and server VMs run on the same local computer and attach TCP/IP
|
||||
* sockets to the local host, or to the loopback domain
|
||||
* ``<code>localhost</code>'' (having IP address <code>127.0.0.1</code>).
|
||||
*
|
||||
* <p>
|
||||
* In this test, 128 client/server connections are established. Once a
|
||||
* connection is established, client passes a data parcel to server, and server
|
||||
* reads that parcel and checks if it is same as expected (byte-to-byte equality
|
||||
* is desired). Then server passes (some other) parcel to the client, and client
|
||||
* reads and verifies those bytes. This ping-pong game is repeated 128 times;
|
||||
* and after that each pair of sockets checks if there are no extra bytes
|
||||
* accedentally passed through their connection.
|
||||
*
|
||||
* <p>
|
||||
* Parcels lengths and contents are chosen randomly, and average parcel length
|
||||
* is 128 bytes. So totally, each pair of sockets passes ~16Kb of data to each
|
||||
* other, and thus ~32Kb of data are transfered by each sockets pair. Totally,
|
||||
* ~4Mb of data are transfered by all client/server pairs.
|
||||
*
|
||||
* @author vtewari
|
||||
*/
|
||||
public class HugeDataTransferTest {
|
||||
|
||||
/**
|
||||
* Timeout for TCP/IP sockets (currently set to 1 min).
|
||||
*/
|
||||
private static int SO_TIMEOUT;// = 2*60*1000;
|
||||
|
||||
/**
|
||||
* Maximal number of connections this test should open simultaneously.
|
||||
*/
|
||||
private final static int MAX_CONNECTIONS = 128;
|
||||
|
||||
/**
|
||||
* Check few more connections to make sure that MAX_CONNECTIONS are safe.
|
||||
*/
|
||||
private final static int CONNECTIONS_RESERVE = 10;
|
||||
|
||||
/**
|
||||
* The test used to fail with connection reset by peer set to 50. (and once
|
||||
* in a three if it was set to 10). So now we set it to MAX_CONNECTIONS
|
||||
* (128).
|
||||
*/
|
||||
private final static int BACKLOG_QUEUE_LENGTH = MAX_CONNECTIONS;
|
||||
|
||||
/**
|
||||
* Number of parcels to be sent/recieved.
|
||||
*/
|
||||
private final static int DATA_PARCELS = 128;
|
||||
|
||||
/**
|
||||
* Maximal length of data parcel to be sent/recieved (it equals to 256 bytes
|
||||
* now).
|
||||
*/
|
||||
private final static int MAX_PARCEL = 1 << 8;
|
||||
|
||||
/**
|
||||
* Either actually display optional reports or not.
|
||||
*/
|
||||
static private final boolean DEBUG_MODE = false;
|
||||
|
||||
/**
|
||||
* How many IP sockets can we open simultaneously? Check if
|
||||
* <code>MAX_CONNECTIONS</code> connections can be open simultaneously.
|
||||
*/
|
||||
private static int detectOSLimitation() {
|
||||
final int CONNECTIONS_TO_TRY = MAX_CONNECTIONS + CONNECTIONS_RESERVE;
|
||||
display("--- Trying to open " + CONNECTIONS_TO_TRY + " connections:");
|
||||
|
||||
InetAddress address;
|
||||
ServerSocket serverSocket;
|
||||
try {
|
||||
address = InetAddress.getLocalHost();
|
||||
int anyPort = 0;
|
||||
int defaultBacklog = BACKLOG_QUEUE_LENGTH;
|
||||
serverSocket = new ServerSocket(anyPort, defaultBacklog, address);
|
||||
} catch (IOException ioe) {
|
||||
throw new Error("FATAL error while loading the test: " + ioe);
|
||||
}
|
||||
display(serverSocket.toString());
|
||||
|
||||
Socket server[] = new Socket[CONNECTIONS_TO_TRY];
|
||||
Socket client[] = new Socket[CONNECTIONS_TO_TRY];
|
||||
|
||||
int i, port = serverSocket.getLocalPort();
|
||||
for (i = 0; i < CONNECTIONS_TO_TRY; i++) {
|
||||
try {
|
||||
client[i] = new Socket(address, port);
|
||||
display(">Open: client[" + i + "] = " + client[i]);
|
||||
server[i] = serverSocket.accept();
|
||||
display(">Open: server[" + i + "] = " + server[i]);
|
||||
} catch (IOException ioe) {
|
||||
display(">OOPS! -- failed to open connection #" + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
display("> Could open "
|
||||
+ (i < CONNECTIONS_TO_TRY ? "only " : "") + i + " connections.");
|
||||
display(">Closing them:");
|
||||
for (int j = 0; j < i; j++) {
|
||||
try {
|
||||
server[j].close();
|
||||
client[j].close();
|
||||
} catch (IOException ioe) {
|
||||
throw new Error("FATAL error while loading the test: " + ioe);
|
||||
}
|
||||
}
|
||||
display(">OK.");
|
||||
int safeConnections = i - CONNECTIONS_RESERVE;
|
||||
if (safeConnections < 1) {
|
||||
safeConnections = 1;
|
||||
}
|
||||
if (safeConnections < MAX_CONNECTIONS) {
|
||||
complain("------------------------- CAUTION: -------------------");
|
||||
complain("While checking the OS limitations, the test found that");
|
||||
complain("only " + i + " TCP/IP socket connections could be safely open");
|
||||
complain("simultaneously. However, possibility to open at least");
|
||||
complain("" + MAX_CONNECTIONS + "+" + CONNECTIONS_RESERVE
|
||||
+ " connections were expected.");
|
||||
complain("");
|
||||
complain("So, the test will check only " + safeConnections + " connection"
|
||||
+ (safeConnections == 1 ? "" : "s") + " which seem");
|
||||
complain("safe to be open simultaneously.");
|
||||
complain("------------------------------------------------------");
|
||||
}
|
||||
return safeConnections;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------//
|
||||
/**
|
||||
* Re-calls to the method <code>run(args[],out)</code> actually performing
|
||||
* the test. After <code>run(args[],out)</code> stops, follow JDK-like
|
||||
* convention for exit codes. I.e.: stop with exit status 95 if the test has
|
||||
* passed, or with status 97 if the test has failed.
|
||||
*
|
||||
* @see #run(String[],PrintStream)
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
int exitCode = run(args, System.out);
|
||||
System.exit(exitCode + 95);
|
||||
// JCK-like exit status.
|
||||
}
|
||||
|
||||
public static int run(String args[], PrintStream out) {
|
||||
HugeDataTransferTest.out = out;
|
||||
|
||||
//
|
||||
// Get the Internet address of the local machine.
|
||||
//
|
||||
InetAddress address = null;
|
||||
try {
|
||||
address = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException exception) {
|
||||
complain(exception.toString());
|
||||
return 2; // FAILED
|
||||
}
|
||||
display("Host: " + address);
|
||||
|
||||
//
|
||||
// Detect if it is safe to open MAX_CONNETIONS simultaneously:
|
||||
//
|
||||
final int CONNECTIONS = detectOSLimitation();
|
||||
|
||||
//
|
||||
// Assign ServerSocket, and start client VM which should open
|
||||
// the prescribed number of CONNECTIONS to that ServerSocket.
|
||||
//
|
||||
ServerSocket serverSocket;
|
||||
try {
|
||||
final int anyPort = 0;
|
||||
final int defaultBacklog = BACKLOG_QUEUE_LENGTH;
|
||||
serverSocket = new ServerSocket(anyPort, defaultBacklog, address);
|
||||
} catch (IOException exception) {
|
||||
complain("Cannot assign a ServerSocket on: " + address);
|
||||
return 2;
|
||||
}
|
||||
|
||||
//
|
||||
// Start the client process on different VM.
|
||||
//
|
||||
String jdkPath = System.getProperty("test.jdk");
|
||||
Path toolName = Paths.get("bin", "java" + (isWindows() ? ".exe" : ""));
|
||||
Path jdkTool = Paths.get(jdkPath, toolName.toString());
|
||||
|
||||
String IPAddress = address.getHostAddress();
|
||||
int localPort = serverSocket.getLocalPort();
|
||||
String arguments = " " + CONNECTIONS + " " + IPAddress + " " + localPort;
|
||||
//String command = args[0] + " " + network006.class.getName() + "$Client " + arguments;
|
||||
String command = jdkTool.toAbsolutePath().toString() + " " + Client.class.getName() + " " + arguments;
|
||||
try {
|
||||
SO_TIMEOUT = Integer.parseInt(args[0]) * 60 * 1000;
|
||||
} catch (NumberFormatException e) {
|
||||
complain("Wrong timeout argument: " + e);
|
||||
return 2;
|
||||
}
|
||||
|
||||
Runtime runtime = Runtime.getRuntime();
|
||||
|
||||
Process client = null;
|
||||
IORedirector redirectOut = null;
|
||||
IORedirector redirectErr = null;
|
||||
|
||||
try {
|
||||
// Start clients on different JVM:
|
||||
client = runtime.exec(command);
|
||||
|
||||
// Provide clients with access to stderr and stdout:
|
||||
InputStream clientOut = client.getInputStream();
|
||||
InputStream clientErr = client.getErrorStream();
|
||||
redirectOut = new IORedirector(clientOut, DEBUG_MODE ? out : null);
|
||||
redirectErr = new IORedirector(clientErr, out);
|
||||
redirectOut.start();
|
||||
redirectErr.start();
|
||||
|
||||
} catch (IOException exception) {
|
||||
complain("Failed to start client: " + exception);
|
||||
return 2;
|
||||
}
|
||||
//
|
||||
// Start the server threads (and let them establish connections):
|
||||
//
|
||||
|
||||
Server server[] = new Server[CONNECTIONS];
|
||||
for (int i = 0; i < CONNECTIONS; i++) {
|
||||
server[i] = new Server(serverSocket);
|
||||
display("Server #" + i + ": " + server[i]);
|
||||
server[i].start();
|
||||
}
|
||||
|
||||
//
|
||||
// Wait for the servers and the clients:
|
||||
//
|
||||
boolean testFailed = false;
|
||||
|
||||
try {
|
||||
client.waitFor();
|
||||
int clientStatus = client.exitValue();
|
||||
display("Client VM exitCode=" + clientStatus);
|
||||
|
||||
// Let I/O redirectors to flush:
|
||||
if (redirectOut.isAlive()) {
|
||||
redirectOut.join();
|
||||
}
|
||||
if (redirectErr.isAlive()) {
|
||||
redirectErr.join();
|
||||
}
|
||||
|
||||
// If client has crashed, also terminate the server (to avoid hangup).
|
||||
if (clientStatus != 95) {
|
||||
complain("Client VM has crashed: exit status=" + clientStatus);
|
||||
testFailed = true;
|
||||
}
|
||||
|
||||
// Client has finished OK; wait for the server.
|
||||
for (int i = 0; i < CONNECTIONS; i++) {
|
||||
display("Server: waiting for #" + i);
|
||||
if (server[i].isAlive()) {
|
||||
display("Server #" + i + ": (joining...)" + server[i]);
|
||||
server[i].join();
|
||||
}
|
||||
if (server[i].exception != null) {
|
||||
if (server[i].message != null) {
|
||||
complain("Server #" + i + "(finished): with message:" + server[i].message);
|
||||
}
|
||||
|
||||
complain("Server #" + i + "(finished): " + server[i].exception);
|
||||
server[i].exception.printStackTrace(out);
|
||||
out.flush();
|
||||
// complain("Server #"+i+": "+server[i].exception.getStackTrace());
|
||||
testFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (InterruptedException exception) {
|
||||
complain("Test interrupted: " + exception);
|
||||
testFailed = true;
|
||||
}
|
||||
|
||||
if (testFailed) {
|
||||
complain("Test failed.");
|
||||
} else {
|
||||
display("Test passed.");
|
||||
}
|
||||
return testFailed ? 2 : 0;
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
return System.getProperty("os.name").toLowerCase().startsWith("win");
|
||||
}
|
||||
//----------------------------------------------------------------//
|
||||
/**
|
||||
* Log stream for error messages and/or (optional) execution trace.
|
||||
*/
|
||||
private static PrintStream out;
|
||||
|
||||
/**
|
||||
* Print error message.
|
||||
*/
|
||||
private static synchronized void complain(Object message) {
|
||||
out.println("# " + message);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* Display optional report: comment ca va?
|
||||
*/
|
||||
private static synchronized void display(Object report) {
|
||||
if (DEBUG_MODE) {
|
||||
out.println(report.toString());
|
||||
}
|
||||
out.flush(); //todo shouldn't this be inside if??
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
//----------------------------------------------------------------//
|
||||
|
||||
/**
|
||||
* Server thread should reply to data parcels sent by Client VM.
|
||||
*/
|
||||
private static class Server extends Thread {
|
||||
|
||||
/**
|
||||
* The socket is assigned at the Server instantiation.
|
||||
*/
|
||||
private ServerSocket serverSocket;
|
||||
|
||||
/**
|
||||
* The socket is assigned at the Server runtime.
|
||||
*/
|
||||
private Socket socket;
|
||||
|
||||
/**
|
||||
* Display the server socket.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "ServerSocket: " + serverSocket.toString();
|
||||
// + " socket: " + socket.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Which port is this socket listening?
|
||||
*/
|
||||
int getPort() {
|
||||
return serverSocket.getLocalPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find some free port at the given <code>address</code> and attach new
|
||||
* server to hear that port. // lidsten to??
|
||||
*/
|
||||
public Server(ServerSocket serverSocket) {
|
||||
this.serverSocket = serverSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* Exception just arisen while the server was working, or
|
||||
* <code>null</code> if it was OK with the server.
|
||||
*/
|
||||
Exception exception = null;
|
||||
String message = null;
|
||||
|
||||
/**
|
||||
* Accept connection, then reply to client's parcels.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
socket = serverSocket.accept();
|
||||
socket.setSoTimeout(SO_TIMEOUT);
|
||||
|
||||
InputStream istream = socket.getInputStream();
|
||||
OutputStream ostream = socket.getOutputStream();
|
||||
|
||||
Random random = new Random(getPort());
|
||||
|
||||
for (int i = 0; i < DATA_PARCELS; i++) {
|
||||
Parcel etalon = new Parcel(random);
|
||||
message = "reading parcel number " + i;
|
||||
Parcel sample = new Parcel(istream); // read
|
||||
if (!sample.equals(etalon)) {
|
||||
complain("Server thread for port #"
|
||||
+ getPort() + " got unexpected parcel:\n"
|
||||
+ "sample=" + sample + "\n"
|
||||
+ "etalon=" + etalon);
|
||||
throw new TestFailure( //received??
|
||||
"server has read unexpected parcel");
|
||||
}
|
||||
message = "sending parcel number " + i;
|
||||
etalon.send(ostream);
|
||||
ostream.flush();
|
||||
}
|
||||
|
||||
int datum = istream.read(); // wait for client close()
|
||||
if (datum >= 0) {
|
||||
throw new TestFailure(
|
||||
"server has read ambigous byte: " + datum);
|
||||
}
|
||||
|
||||
ostream.close(); // implies: socket.close();
|
||||
|
||||
} catch (Exception oops) {
|
||||
exception = oops;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------//
|
||||
/**
|
||||
* Client VM should send data parcels to Server VM and recieve and verify
|
||||
* the server's replies.
|
||||
*/
|
||||
private static class Client extends Thread {
|
||||
|
||||
/**
|
||||
* This thread uses the single client socket.
|
||||
*/
|
||||
private Socket socket;
|
||||
|
||||
/**
|
||||
* Address and port of this socket.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return socket.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Did the thread failed? If yes, what is the failure's reason.
|
||||
*/
|
||||
Exception exception = null;
|
||||
String message = null;
|
||||
|
||||
public static java.io.PrintStream complainStream = System.out;
|
||||
public static java.io.PrintStream displayStream = System.err;
|
||||
|
||||
/**
|
||||
* Connect client socket on the given <code>address</code> and
|
||||
* <code>port</code>.
|
||||
*/
|
||||
Client(InetAddress address, int port) throws IOException {
|
||||
socket = new Socket(address, port);
|
||||
socket.setSoTimeout(SO_TIMEOUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* What is the port number this socket is listening for?
|
||||
*/
|
||||
int getPort() {
|
||||
return socket.getPort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish connection, then read/respond <code>DATA_PARCELS</code>
|
||||
* parcels of random data. Set initial seed for pseudo-random numbers
|
||||
* generator to the value of the local port number.
|
||||
*
|
||||
* @see #DATA_PARCELS
|
||||
* @see #getPort()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
InputStream istream = socket.getInputStream();
|
||||
OutputStream ostream = socket.getOutputStream();
|
||||
|
||||
Random random = new Random(getPort());
|
||||
// suggested by Oleg -- to avoid race conditions
|
||||
/* try{
|
||||
Thread.sleep(500);
|
||||
}
|
||||
catch (java.lang.InterruptedException e)
|
||||
{
|
||||
}*/
|
||||
|
||||
for (int i = 0; i < DATA_PARCELS; i++) {
|
||||
Parcel etalon = new Parcel(random);
|
||||
message = "sending parcel number: " + i;
|
||||
etalon.send(ostream);
|
||||
ostream.flush();
|
||||
|
||||
message = "reading parcel number: " + i;
|
||||
Parcel sample = new Parcel(istream); // read
|
||||
if (!sample.equals(etalon)) {
|
||||
complain("Client thread for port #"
|
||||
+ getPort() + " got unexpected parcel:\n"
|
||||
+ "sample=" + sample + "\n"
|
||||
+ "etalon=" + etalon);
|
||||
throw new TestFailure(
|
||||
"parcel context is unexpected to client");
|
||||
}
|
||||
}
|
||||
|
||||
if (istream.available() > 0) {
|
||||
int datum = istream.read();
|
||||
throw new TestFailure(
|
||||
"client has read ambigous byte: " + datum);
|
||||
}
|
||||
ostream.close(); // implies: socket.close()
|
||||
|
||||
} catch (Exception oops) {
|
||||
exception = oops;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish lots of connections to server socket, attack servers with
|
||||
* huge data parcels, and check if they reply correctly. The number of
|
||||
* connections to try, the address and port number for the server socket
|
||||
* are passed through <code>args[]</code>, like:
|
||||
* <pre>
|
||||
* java network006$Client connections_to_try address port
|
||||
* </pre>
|
||||
*/
|
||||
public static void main(String args[]) {
|
||||
if (DEBUG_MODE) {
|
||||
try {
|
||||
String filename = "Client" + ((args.length == 3) ? args[2] : "new");
|
||||
displayStream = new PrintStream(filename + ".out");
|
||||
complainStream = new PrintStream(filename + ".err");
|
||||
} catch (FileNotFoundException exception) {
|
||||
complain(exception);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (args.length != 3) {
|
||||
complain("Client expects 3 paramenets:");
|
||||
complain(" java " + Client.class.getName() + " connections_to_try address port");
|
||||
exit(1); // FAILED
|
||||
}
|
||||
|
||||
int CONNECTIONS = Integer.parseInt(args[0]);
|
||||
display("Client VM: will try " + CONNECTIONS + " connections.");
|
||||
InetAddress address;
|
||||
try {
|
||||
address = InetAddress.getByName(args[1]);
|
||||
} catch (UnknownHostException exception) {
|
||||
address = null;
|
||||
complain("Client: cannot find host: \"" + args[1] + "\"");
|
||||
exit(4);
|
||||
}
|
||||
display("Client: host to contact: " + address);
|
||||
int port = Integer.parseInt(args[2]);
|
||||
display("Client: port to contact: " + port);
|
||||
|
||||
//
|
||||
// Establish connections, and start client processes:
|
||||
//
|
||||
Client client[] = new Client[CONNECTIONS];
|
||||
for (int i = 0; i < CONNECTIONS; i++) {
|
||||
try {
|
||||
client[i] = new Client(address, port);
|
||||
display("Client #" + i + ": " + client[i]);
|
||||
|
||||
} catch (IOException ioe) {
|
||||
complain("Client #" + i + "(creation): " + ioe);
|
||||
ioe.printStackTrace(complainStream);
|
||||
complainStream.flush();
|
||||
// complain("Client #" + i + "(creation): " + ioe.getStackTrace());
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < CONNECTIONS; i++) {
|
||||
client[i].start();
|
||||
}
|
||||
|
||||
//
|
||||
// Wait until testing is not finished:
|
||||
//
|
||||
int status = 0;
|
||||
for (int i = 0; i < CONNECTIONS; i++) {
|
||||
display("Client: waiting for #" + i);
|
||||
if (client[i].isAlive()) {
|
||||
display("Client #" + i + ": (joining...)" + client[i]);
|
||||
|
||||
try {
|
||||
client[i].join();
|
||||
} catch (InterruptedException ie) {
|
||||
complain("Client #" + i + ": " + ie);
|
||||
status = 3;
|
||||
}
|
||||
}
|
||||
if (client[i].exception != null) {
|
||||
if (client[i].message != null) {
|
||||
complain("Client #" + i + "(finished) with message: " + client[i].message);
|
||||
}
|
||||
complain("Client #" + i + "(finished): " + client[i].exception);
|
||||
client[i].exception.printStackTrace(complainStream);
|
||||
complainStream.flush();
|
||||
if (status == 0) {
|
||||
status = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print error message.
|
||||
*/
|
||||
private static synchronized void complain(Object message) {
|
||||
complainStream.println("# " + message);
|
||||
complainStream.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Display execution trace.
|
||||
*/
|
||||
private static synchronized void display(Object message) {
|
||||
if (!DEBUG_MODE) {
|
||||
return;
|
||||
}
|
||||
displayStream.println(message.toString());
|
||||
displayStream.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Exit with JCK-like status.
|
||||
*/
|
||||
private static void exit(int exitCode) {
|
||||
int status = exitCode + 95;
|
||||
// display("Client: exiting with code=" + status);
|
||||
System.exit(status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Two of such threads should redirect <code>out</code> and <code>err</code>
|
||||
* streams of client VM.
|
||||
*/
|
||||
private static class IORedirector extends Thread {
|
||||
|
||||
/**
|
||||
* Source stream.
|
||||
*/
|
||||
InputStream in;
|
||||
/**
|
||||
* Destination stream.
|
||||
*/
|
||||
OutputStream out;
|
||||
|
||||
/**
|
||||
* Redirect <code>in</code> to <code>out</code>.
|
||||
*/
|
||||
public IORedirector(InputStream in, OutputStream out) {
|
||||
this.in = in;
|
||||
this.out = out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read input stream until the EOF, and write everithing to output
|
||||
* stream. If output stream is assigned to <code>null</code>, do not
|
||||
* print anything, but read the input stream anywhere.
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
for (;;) {
|
||||
int symbol = in.read();
|
||||
if (symbol < 0) {
|
||||
break; // EOF
|
||||
}
|
||||
if (out != null) {
|
||||
out.write(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
if (out != null) {
|
||||
out.flush();
|
||||
}
|
||||
|
||||
} catch (IOException exception) {
|
||||
throw new TestFailure("IORedirector exception: " + exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------//
|
||||
/**
|
||||
* A data parcel to be sent/recieved between Client VM and Server thread.
|
||||
* When data parcel is sent, first 4 bytes are transfered which encode the
|
||||
* <code>int</code> number equal to size of the parcel minus 1. I.e.: if
|
||||
* number of data bytes in the parcel's contents is <code>N</code>, then the
|
||||
* first 4 bytes encode the number <code>N-1</code>. After that, the
|
||||
* parcel's contents bytes are transered.
|
||||
*/
|
||||
static class Parcel {
|
||||
|
||||
private final byte[] parcel;
|
||||
|
||||
/**
|
||||
* Display all bytes as integer values from 0 to 255; or return
|
||||
* ``<tt>null</tt>'' if this Parcel is not yet initialized.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
if (parcel == null) {
|
||||
return "null";
|
||||
}
|
||||
String s = "{";
|
||||
for (int i = 0; i < parcel.length; i++) {
|
||||
s += (i > 0 ? ", " : "") + ((int) parcel[i] & 0xFF);
|
||||
}
|
||||
return s + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate new <code>parcel[]</code> array using the given
|
||||
* <code>random</code> numbers generator. Client and Server threads
|
||||
* should use identical <code>random</code> generators, so that those
|
||||
* threads could generate equal data parcels and check the parcel just
|
||||
* transfered.
|
||||
*/
|
||||
public Parcel(Random random) {
|
||||
int size = random.nextInt(MAX_PARCEL) + 1;
|
||||
parcel = new byte[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
parcel[i] = (byte) random.nextInt(256);
|
||||
}
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* Read exactly <code>size</code> bytes from the <code>istream</code>
|
||||
* if possible, or throw <code>TestFailure</code> if unexpected end of
|
||||
* <code>istream</code> occurs.
|
||||
*/
|
||||
private static byte[] readBytes(int size, InputStream istream)
|
||||
throws IOException {
|
||||
|
||||
byte data[] = new byte[size];
|
||||
for (int i = 0; i < size; i++) {
|
||||
int datum = istream.read();
|
||||
if (datum < 0) {
|
||||
throw new TestFailure(
|
||||
"unexpected EOF: have read: " + i + " bytes of " + size);
|
||||
}
|
||||
data[i] = (byte) datum;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read 4 bytes from <code>istream</code> and threat them to encode size
|
||||
* of data parcel following these 4 bytes.
|
||||
*/
|
||||
private static int getSize(InputStream istream) throws IOException {
|
||||
byte data[] = readBytes(4, istream);
|
||||
int data0 = (int) data[0] & 0xFF;
|
||||
int data1 = (int) data[1] & 0xFF;
|
||||
int data2 = (int) data[2] & 0xFF;
|
||||
int data3 = (int) data[3] & 0xFF;
|
||||
int sizeWord = data0 + (data1 << 8) + (data2 << 16) + (data3 << 24);
|
||||
int size = sizeWord + 1;
|
||||
if (size <= 0) {
|
||||
throw new TestFailure("illegal size: " + size);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send 4 bytes encoding actual size of the parcel just to be
|
||||
* transfered.
|
||||
*/
|
||||
private static void putSize(OutputStream ostream, int size)
|
||||
throws IOException {
|
||||
|
||||
if (size <= 0) {
|
||||
throw new TestFailure("illegal size: " + size);
|
||||
}
|
||||
|
||||
int sizeWord = size - 1;
|
||||
byte data[] = new byte[4];
|
||||
data[0] = (byte) sizeWord;
|
||||
data[1] = (byte) (sizeWord >> 8);
|
||||
data[2] = (byte) (sizeWord >> 16);
|
||||
data[3] = (byte) (sizeWord >> 24);
|
||||
ostream.write(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Recieve data parcel.
|
||||
*/
|
||||
public Parcel(InputStream istream) throws IOException {
|
||||
int size = getSize(istream);
|
||||
parcel = readBytes(size, istream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send <code>this</code> data parcel.
|
||||
*/
|
||||
public void send(OutputStream ostream) throws IOException {
|
||||
int size = parcel.length;
|
||||
putSize(ostream, size);
|
||||
ostream.write(parcel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check byte-to-byte equality between <code>this</code> and the
|
||||
* <code>other</code> parcels.
|
||||
*/
|
||||
public boolean equals(Parcel other) {
|
||||
if (this.parcel.length != other.parcel.length) {
|
||||
return false;
|
||||
}
|
||||
int size = parcel.length;
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (this.parcel[i] != other.parcel[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Server or Client may throw this exception to report the test failure.
|
||||
*/
|
||||
static class TestFailure extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Report particular <code>purpose</code> of the test failure.
|
||||
*/
|
||||
public TestFailure(String purpose) {
|
||||
super(purpose);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,7 +24,6 @@
|
|||
/*
|
||||
* @test
|
||||
* @bug 8087112
|
||||
* @key intermittent
|
||||
* @library /lib/testlibrary server
|
||||
* @build jdk.testlibrary.SimpleSSLContext
|
||||
* @modules jdk.incubator.httpclient/jdk.incubator.http.internal.common
|
||||
|
|
|
@ -105,7 +105,7 @@ public final class DummyWebSocketServer implements Closeable {
|
|||
channel.configureBlocking(true);
|
||||
StringBuilder request = new StringBuilder();
|
||||
if (!readRequest(channel, request)) {
|
||||
throw new IOException("Bad request");
|
||||
throw new IOException("Bad request:" + request);
|
||||
}
|
||||
List<String> strings = asList(request.toString().split("\r\n"));
|
||||
List<String> response = mapping.apply(strings);
|
||||
|
@ -156,6 +156,7 @@ public final class DummyWebSocketServer implements Closeable {
|
|||
public void close() {
|
||||
log.log(INFO, "Stopping: " + getURI());
|
||||
thread.interrupt();
|
||||
close(ssc);
|
||||
}
|
||||
|
||||
URI getURI() {
|
||||
|
@ -169,19 +170,21 @@ public final class DummyWebSocketServer implements Closeable {
|
|||
throws IOException
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocate(512);
|
||||
int num = channel.read(buffer);
|
||||
if (num == -1) {
|
||||
return false;
|
||||
while (channel.read(buffer) != -1) {
|
||||
// read the complete HTTP request headers, there should be no body
|
||||
CharBuffer decoded;
|
||||
buffer.flip();
|
||||
try {
|
||||
decoded = ISO_8859_1.newDecoder().decode(buffer);
|
||||
} catch (CharacterCodingException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
request.append(decoded);
|
||||
if (Pattern.compile("\r\n\r\n").matcher(request).find())
|
||||
return true;
|
||||
buffer.clear();
|
||||
}
|
||||
CharBuffer decoded;
|
||||
buffer.flip();
|
||||
try {
|
||||
decoded = ISO_8859_1.newDecoder().decode(buffer);
|
||||
} catch (CharacterCodingException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
request.append(decoded);
|
||||
return Pattern.compile("\r\n\r\n").matcher(request).find();
|
||||
return false;
|
||||
}
|
||||
|
||||
private void writeResponse(SocketChannel channel, List<String> response)
|
||||
|
|
|
@ -32,7 +32,7 @@ public final class LoggingHelper {
|
|||
* @run main/othervm/jul=logging.properties ClassUnderTest
|
||||
*/
|
||||
public static void setupLogging() {
|
||||
String path = System.getProperty("test.src") + File.separator + "logging.properties";
|
||||
String path = System.getProperty("test.src", ".") + File.separator + "logging.properties";
|
||||
System.setProperty("java.util.logging.config.file", path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -323,9 +323,12 @@ public class Proc {
|
|||
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
||||
return this;
|
||||
}
|
||||
String getId(String prefix) {
|
||||
if (debug != null) return prefix + "." + debug;
|
||||
else return prefix + "." + System.identityHashCode(this);
|
||||
String getId(String suffix) {
|
||||
if (debug != null) {
|
||||
return debug + "." + suffix;
|
||||
} else {
|
||||
return System.identityHashCode(this) + "." + suffix;
|
||||
}
|
||||
}
|
||||
// Reads a line from stdout of proc
|
||||
public String readLine() throws IOException {
|
||||
|
@ -395,9 +398,13 @@ public class Proc {
|
|||
boolean isEmpty = true;
|
||||
while (true) {
|
||||
int i = System.in.read();
|
||||
if (i == -1) break;
|
||||
if (i == -1) {
|
||||
break;
|
||||
}
|
||||
isEmpty = false;
|
||||
if (i == '\n') break;
|
||||
if (i == '\n') {
|
||||
break;
|
||||
}
|
||||
if (i != 13) {
|
||||
// Force it to a char, so only simple ASCII works.
|
||||
sb.append((char)i);
|
||||
|
|
|
@ -22,19 +22,27 @@
|
|||
*/
|
||||
|
||||
/* @test
|
||||
@bug 4241361 4842702 4985614 6646605 5032358 6923692 6233323 8144977
|
||||
@bug 4241361 4842702 4985614 6646605 5032358 6923692 6233323 8144977 8186464
|
||||
@summary Make sure we can read a zip file.
|
||||
@key randomness
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.NoSuchFileException;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.zip.*;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.US_ASCII;
|
||||
|
||||
public class ReadZip {
|
||||
private static void unreached (Object o)
|
||||
throws Exception
|
||||
|
@ -137,8 +145,6 @@ public class ReadZip {
|
|||
newZip.delete();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Throw a FNF exception when read a non-existing zip file
|
||||
try { unreached (new ZipFile(
|
||||
new File(System.getProperty("test.src", "."),
|
||||
|
@ -146,5 +152,54 @@ public class ReadZip {
|
|||
+ String.valueOf(new java.util.Random().nextInt())
|
||||
+ ".zip")));
|
||||
} catch (NoSuchFileException nsfe) {}
|
||||
|
||||
// read a zip file with ZIP64 end
|
||||
Path path = Paths.get(System.getProperty("test.dir", ""), "end64.zip");
|
||||
try {
|
||||
URI uri = URI.create("jar:" + path.toUri());
|
||||
Map<String, Object> env = Map.of("create", "true", "forceZIP64End", "true");
|
||||
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
|
||||
Files.write(fs.getPath("hello"), "hello".getBytes());
|
||||
}
|
||||
try (ZipFile zf = new ZipFile(path.toFile())) {
|
||||
if (!"hello".equals(new String(zf.getInputStream(new ZipEntry("hello"))
|
||||
.readAllBytes(),
|
||||
US_ASCII)))
|
||||
throw new RuntimeException("zipfile: read entry failed");
|
||||
} catch (IOException x) {
|
||||
throw new RuntimeException("zipfile: zip64 end failed");
|
||||
}
|
||||
try (FileSystem fs = FileSystems.newFileSystem(uri, Map.of())) {
|
||||
if (!"hello".equals(new String(Files.readAllBytes(fs.getPath("hello")))))
|
||||
throw new RuntimeException("zipfs: read entry failed");
|
||||
} catch (IOException x) {
|
||||
throw new RuntimeException("zipfile: zip64 end failed");
|
||||
}
|
||||
} finally {
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
|
||||
// read a zip file created via "echo hello | zip dst.zip -", which uses
|
||||
// ZIP64 end record
|
||||
if (Files.notExists(Paths.get("/usr/bin/zip")))
|
||||
return;
|
||||
try {
|
||||
Process zip = new ProcessBuilder("zip", path.toString().toString(), "-").start();
|
||||
OutputStream os = zip.getOutputStream();
|
||||
os.write("hello".getBytes(US_ASCII));
|
||||
os.close();
|
||||
zip.waitFor();
|
||||
if (zip.exitValue() == 0 && Files.exists(path)) {
|
||||
try (ZipFile zf = new ZipFile(path.toFile())) {
|
||||
if (!"hello".equals(new String(zf.getInputStream(new ZipEntry("-"))
|
||||
.readAllBytes())))
|
||||
throw new RuntimeException("zipfile: read entry failed");
|
||||
} catch (IOException x) {
|
||||
throw new RuntimeException("zipfile: zip64 end failed");
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
Files.deleteIfExists(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.base/sun.security.util
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
* @summary Testing DTLS engines do not enable RC4 ciphers by default.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @key randomness
|
||||
* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* causes IllegalArgumentException.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
modules = \
|
||||
java.security.jgss/sun.security.jgss.krb5 \
|
||||
java.security.jgss/sun.security.krb5:+open \
|
||||
java.security.jgss/sun.security.krb5.internal.crypto \
|
||||
java.security.jgss/sun.security.krb5.internal.ccache \
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon /javax/net/ssl/DTLS
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon /javax/net/ssl/DTLS
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
* @summary Testing DTLS engines do not enable RC4 ciphers by default.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @key randomness
|
||||
* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /lib/testlibrary /javax/net/ssl/TLSCommon /javax/net/ssl/DTLS
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* causes IllegalArgumentException.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
modules = \
|
||||
java.security.jgss/sun.security.jgss.krb5 \
|
||||
java.security.jgss/sun.security.krb5:+open \
|
||||
java.security.jgss/sun.security.krb5.internal.crypto \
|
||||
java.security.jgss/sun.security.krb5.internal.ccache \
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
modules = \
|
||||
java.security.jgss/sun.security.jgss.krb5 \
|
||||
java.security.jgss/sun.security.krb5:+open \
|
||||
java.security.jgss/sun.security.krb5.internal.crypto \
|
||||
java.security.jgss/sun.security.krb5.internal.ktab \
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* @summary javax/net/ssl/TLS/TLSClientPropertyTest.java needs to be
|
||||
* updated for JDK-8061210
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
* @summary Testing TLS engines do not enable RC4 ciphers by default.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @key randomness
|
||||
* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* causes IllegalArgumentException.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
modules = \
|
||||
java.security.jgss/sun.security.jgss.krb5 \
|
||||
java.security.jgss/sun.security.krb5:+open \
|
||||
java.security.jgss/sun.security.krb5.internal.crypto \
|
||||
java.security.jgss/sun.security.krb5.internal.ccache \
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
* @summary Testing TLS engines do not enable RC4 ciphers by default.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @key randomness
|
||||
* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* causes IllegalArgumentException.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
* @summary Support TLS 1.1
|
||||
* @run main/othervm EmptyCertificateAuthorities
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
* @summary Support TLS 1.1
|
||||
* @run main/othervm ExportableBlockCipher
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
* @bug 4873188
|
||||
* @summary Support TLS 1.1
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* @bug 4873188
|
||||
* @summary Support TLS 1.1
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* @bug 4873188
|
||||
* @summary Support TLS 1.1
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
modules = \
|
||||
java.security.jgss/sun.security.jgss.krb5 \
|
||||
java.security.jgss/sun.security.krb5:+open \
|
||||
java.security.jgss/sun.security.krb5.internal.crypto \
|
||||
java.security.jgss/sun.security.krb5.internal.ccache \
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
* @summary Testing TLS engines do not enable RC4 ciphers by default.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
* @key randomness
|
||||
* @library /sun/security/krb5/auto /test/lib /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* jdk.security.auth
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
* causes IllegalArgumentException.
|
||||
* @library /sun/security/krb5/auto /javax/net/ssl/TLSCommon
|
||||
* @modules java.security.jgss
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2013, 2017, 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
|
||||
|
@ -23,170 +23,312 @@
|
|||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8009977
|
||||
* @summary A test library to launch multiple Java processes
|
||||
* @bug 8009977 8186884
|
||||
* @summary A test to launch multiple Java processes using either Java GSS
|
||||
* or native GSS
|
||||
* @library ../../../../java/security/testlibrary/
|
||||
* @compile -XDignore.symbol.file BasicProc.java
|
||||
* @run main/othervm BasicProc
|
||||
* @run main/othervm BasicProc launcher
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.nio.file.attribute.PosixFilePermission;
|
||||
import java.util.Arrays;
|
||||
import java.util.PropertyPermission;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import org.ietf.jgss.Oid;
|
||||
import sun.security.krb5.Config;
|
||||
|
||||
import javax.security.auth.PrivateCredentialPermission;
|
||||
|
||||
/**
|
||||
* Run this test automatically and test Java GSS with embedded KDC.
|
||||
*
|
||||
* Run with customized native.krb5.libs to test interop between Java GSS
|
||||
* and native GSS, and native.kdc.path with a native KDC. For example,
|
||||
* run the following command to test interop among Java, default native,
|
||||
* MIT, and Heimdal krb5 libraries with the Heimdal KDC:
|
||||
*
|
||||
* jtreg -Dnative.krb5.libs=j=,
|
||||
* n=,
|
||||
* k=/usr/local/krb5/lib/libgssapi_krb5.so,
|
||||
* h=/space/install/heimdal/lib/libgssapi.so \
|
||||
* -Dnative.kdc.path=/usr/local/heimdal \
|
||||
* BasicProc.java
|
||||
*
|
||||
* Note: The first 4 lines should be concatenated to make a long system
|
||||
* property value with no blank around ",". This comma-separated value
|
||||
* has each element being name=libpath. The special name "j" means the
|
||||
* Java library and libpath is ignored. Otherwise it means a native library,
|
||||
* and libpath (can be empty) will be the value for the sun.security.jgss.lib
|
||||
* system property. If this system property is not set, only the Java
|
||||
* library will be tested.
|
||||
*/
|
||||
|
||||
public class BasicProc {
|
||||
|
||||
static String CONF = "krb5.conf";
|
||||
static String KTAB = "ktab";
|
||||
private static final String CONF = "krb5.conf";
|
||||
private static final String KTAB_S = "server.ktab";
|
||||
private static final String KTAB_B = "backend.ktab";
|
||||
|
||||
private static final String HOST = "localhost";
|
||||
private static final String SERVER = "server/" + HOST;
|
||||
private static final String BACKEND = "backend/" + HOST;
|
||||
private static final String USER = "user";
|
||||
private static final char[] PASS = "password".toCharArray();
|
||||
private static final String REALM = "REALM";
|
||||
|
||||
private static final int MSGSIZE = 1024;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String HOST = "localhost";
|
||||
String SERVER = "server/" + HOST;
|
||||
String BACKEND = "backend/" + HOST;
|
||||
String USER = "user";
|
||||
char[] PASS = "password".toCharArray();
|
||||
String REALM = "REALM";
|
||||
|
||||
Oid oid = new Oid("1.2.840.113554.1.2.2");
|
||||
byte[] token, msg;
|
||||
|
||||
if (args.length == 0) {
|
||||
System.setProperty("java.security.krb5.conf", CONF);
|
||||
KDC kdc = KDC.create(REALM, HOST, 0, true);
|
||||
kdc.addPrincipal(USER, PASS);
|
||||
kdc.addPrincipalRandKey("krbtgt/" + REALM);
|
||||
kdc.addPrincipalRandKey(SERVER);
|
||||
kdc.addPrincipalRandKey(BACKEND);
|
||||
switch (args[0]) {
|
||||
case "launcher":
|
||||
KDC kdc = KDC.create(REALM, HOST, 0, true);
|
||||
try {
|
||||
kdc.addPrincipal(USER, PASS);
|
||||
kdc.addPrincipalRandKey("krbtgt/" + REALM);
|
||||
kdc.addPrincipalRandKey(SERVER);
|
||||
kdc.addPrincipalRandKey(BACKEND);
|
||||
|
||||
String cwd = System.getProperty("user.dir");
|
||||
kdc.writeKtab(KTAB);
|
||||
KDC.saveConfig(CONF, kdc, "forwardable = true");
|
||||
// Native lib might do some name lookup
|
||||
KDC.saveConfig(CONF, kdc,
|
||||
"dns_lookup_kdc = no",
|
||||
"ticket_lifetime = 1h",
|
||||
"dns_lookup_realm = no",
|
||||
"dns_canonicalize_hostname = false",
|
||||
"forwardable = true");
|
||||
System.setProperty("java.security.krb5.conf", CONF);
|
||||
Config.refresh();
|
||||
kdc.writeKtab(KTAB_S, false, SERVER);
|
||||
kdc.writeKtab(KTAB_B, false, BACKEND);
|
||||
|
||||
Proc pc = Proc.create("BasicProc")
|
||||
.args("client")
|
||||
.prop("java.security.krb5.conf", CONF)
|
||||
.prop("java.security.manager", "")
|
||||
.perm(new java.util.PropertyPermission(
|
||||
"sun.security.krb5.principal", "read"))
|
||||
.perm(new javax.security.auth.AuthPermission(
|
||||
"modifyPrincipals"))
|
||||
.perm(new javax.security.auth.AuthPermission(
|
||||
"modifyPrivateCredentials"))
|
||||
.perm(new javax.security.auth.AuthPermission("doAs"))
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
"krbtgt/" + REALM + "@" + REALM, "initiate"))
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
"server/localhost@" + REALM, "initiate"))
|
||||
.perm(new javax.security.auth.kerberos.DelegationPermission(
|
||||
"\"server/localhost@" + REALM + "\" " +
|
||||
"\"krbtgt/" + REALM + "@" + REALM + "\""))
|
||||
.debug("C")
|
||||
.start();
|
||||
Proc ps = Proc.create("BasicProc")
|
||||
.args("server")
|
||||
.prop("java.security.krb5.conf", CONF)
|
||||
.prop("java.security.manager", "")
|
||||
.perm(new java.util.PropertyPermission(
|
||||
"sun.security.krb5.principal", "read"))
|
||||
.perm(new javax.security.auth.AuthPermission(
|
||||
"modifyPrincipals"))
|
||||
.perm(new javax.security.auth.AuthPermission(
|
||||
"modifyPrivateCredentials"))
|
||||
.perm(new javax.security.auth.AuthPermission("doAs"))
|
||||
.perm(new PrivateCredentialPermission(
|
||||
"javax.security.auth.kerberos.KeyTab * \"*\"",
|
||||
"read"))
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
"server/localhost@" + REALM, "accept"))
|
||||
.perm(new java.io.FilePermission(
|
||||
cwd + File.separator + KTAB, "read"))
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
"backend/localhost@" + REALM, "initiate"))
|
||||
.debug("S")
|
||||
.start();
|
||||
Proc pb = Proc.create("BasicProc")
|
||||
.args("backend")
|
||||
.prop("java.security.krb5.conf", CONF)
|
||||
.prop("java.security.manager", "")
|
||||
.perm(new java.util.PropertyPermission(
|
||||
"sun.security.krb5.principal", "read"))
|
||||
.perm(new javax.security.auth.AuthPermission(
|
||||
"modifyPrincipals"))
|
||||
.perm(new javax.security.auth.AuthPermission(
|
||||
"modifyPrivateCredentials"))
|
||||
.perm(new javax.security.auth.AuthPermission("doAs"))
|
||||
.perm(new PrivateCredentialPermission(
|
||||
"javax.security.auth.kerberos.KeyTab * \"*\"",
|
||||
"read"))
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
"backend/localhost@" + REALM, "accept"))
|
||||
.perm(new java.io.FilePermission(
|
||||
cwd + File.separator + KTAB, "read"))
|
||||
.debug("B")
|
||||
.start();
|
||||
String[] tmp = System.getProperty("native.krb5.libs", "j=")
|
||||
.split(",");
|
||||
|
||||
// Client and server handshake
|
||||
String token = pc.readData();
|
||||
ps.println(token);
|
||||
token = ps.readData();
|
||||
pc.println(token);
|
||||
// Server and backend handshake
|
||||
token = ps.readData();
|
||||
pb.println(token);
|
||||
token = pb.readData();
|
||||
ps.println(token);
|
||||
// wrap/unwrap/getMic/verifyMic and plain text
|
||||
token = ps.readData();
|
||||
pb.println(token);
|
||||
token = pb.readData();
|
||||
ps.println(token);
|
||||
token = pb.readData();
|
||||
ps.println(token);
|
||||
// Library paths. The 1st one is always null which means
|
||||
// Java, "" means the default native lib.
|
||||
String[] libs = new String[tmp.length];
|
||||
|
||||
if ((pc.waitFor() | ps.waitFor() | pb.waitFor()) != 0) {
|
||||
throw new Exception();
|
||||
}
|
||||
} else if (args[0].equals("client")) {
|
||||
Context c = Context.fromUserPass(USER, PASS, false);
|
||||
c.startAsClient(SERVER, oid);
|
||||
c.x().requestCredDeleg(true);
|
||||
Proc.binOut(c.take(new byte[0]));
|
||||
byte[] token = Proc.binIn();
|
||||
c.take(token);
|
||||
} else if (args[0].equals("server")) {
|
||||
Context s = Context.fromUserKtab(SERVER, KTAB, true);
|
||||
s.startAsServer(oid);
|
||||
byte[] token = Proc.binIn();
|
||||
token = s.take(token);
|
||||
Proc.binOut(token);
|
||||
Context s2 = s.delegated();
|
||||
s2.startAsClient(BACKEND, oid);
|
||||
Proc.binOut(s2.take(new byte[0]));
|
||||
token = Proc.binIn();
|
||||
s2.take(token);
|
||||
byte[] msg = "Hello".getBytes();
|
||||
Proc.binOut(s2.wrap(msg, true));
|
||||
s2.verifyMic(Proc.binIn(), msg);
|
||||
String in = Proc.textIn();
|
||||
if (!in.equals("Hello")) {
|
||||
throw new Exception();
|
||||
}
|
||||
} else if (args[0].equals("backend")) {
|
||||
Context b = Context.fromUserKtab(BACKEND, KTAB, true);
|
||||
b.startAsServer(oid);
|
||||
byte[] token = Proc.binIn();
|
||||
Proc.binOut(b.take(token));
|
||||
byte[] msg = b.unwrap(Proc.binIn(), true);
|
||||
Proc.binOut(b.getMic(msg));
|
||||
Proc.textOut(new String(msg));
|
||||
// Names for each lib above. Use in file names.
|
||||
String[] names = new String[tmp.length];
|
||||
|
||||
boolean hasNative = false;
|
||||
|
||||
for (int i = 0; i < tmp.length; i++) {
|
||||
if (tmp[i].isEmpty()) {
|
||||
throw new Exception("Invalid native.krb5.libs");
|
||||
}
|
||||
String[] pair = tmp[i].split("=", 2);
|
||||
names[i] = pair[0];
|
||||
if (!pair[0].equals("j")) {
|
||||
libs[i] = pair.length > 1 ? pair[1] : "";
|
||||
hasNative = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasNative) {
|
||||
kdc.kinit(USER, "base.ccache");
|
||||
}
|
||||
|
||||
// Try the same lib first
|
||||
for (int i = 0; i < libs.length; i++) {
|
||||
once(names[i] + names[i] + names[i],
|
||||
libs[i], libs[i], libs[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < libs.length; i++) {
|
||||
for (int j = 0; j < libs.length; j++) {
|
||||
for (int k = 0; k < libs.length; k++) {
|
||||
if (i != j || i != k) {
|
||||
once(names[i] + names[j] + names[k],
|
||||
libs[i], libs[j], libs[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
kdc.terminate();
|
||||
}
|
||||
break;
|
||||
case "client":
|
||||
Context c = args[1].equals("n") ?
|
||||
Context.fromThinAir() :
|
||||
Context.fromUserPass(USER, PASS, false);
|
||||
c.startAsClient(SERVER, oid);
|
||||
c.x().requestCredDeleg(true);
|
||||
Proc.binOut(c.take(new byte[0])); // AP-REQ
|
||||
token = Proc.binIn(); // AP-REP
|
||||
c.take(token);
|
||||
break;
|
||||
case "server":
|
||||
Context s = args[1].equals("n") ?
|
||||
Context.fromThinAir() :
|
||||
Context.fromUserKtab(SERVER, KTAB_S, true);
|
||||
s.startAsServer(oid);
|
||||
token = Proc.binIn(); // AP-REQ
|
||||
token = s.take(token);
|
||||
Proc.binOut(token); // AP-REP
|
||||
Context s2 = s.delegated();
|
||||
s2.startAsClient(BACKEND, oid);
|
||||
Proc.binOut(s2.take(new byte[0])); // AP-REQ
|
||||
token = Proc.binIn();
|
||||
s2.take(token); // AP-REP
|
||||
Random r = new Random();
|
||||
msg = new byte[MSGSIZE];
|
||||
r.nextBytes(msg);
|
||||
Proc.binOut(s2.wrap(msg, true)); // enc1
|
||||
Proc.binOut(s2.wrap(msg, true)); // enc2
|
||||
Proc.binOut(s2.wrap(msg, true)); // enc3
|
||||
s2.verifyMic(Proc.binIn(), msg); // mic
|
||||
byte[] msg2 = Proc.binIn(); // msg
|
||||
if (!Arrays.equals(msg, msg2)) {
|
||||
throw new Exception("diff msg");
|
||||
}
|
||||
break;
|
||||
case "backend":
|
||||
Context b = args[1].equals("n") ?
|
||||
Context.fromThinAir() :
|
||||
Context.fromUserKtab(BACKEND, KTAB_B, true);
|
||||
b.startAsServer(oid);
|
||||
token = Proc.binIn(); // AP-REQ
|
||||
Proc.binOut(b.take(token)); // AP-REP
|
||||
msg = b.unwrap(Proc.binIn(), true); // enc1
|
||||
if (!Arrays.equals(msg, b.unwrap(Proc.binIn(), true))) { // enc2
|
||||
throw new Exception("diff msg");
|
||||
}
|
||||
if (!Arrays.equals(msg, b.unwrap(Proc.binIn(), true))) { // enc3
|
||||
throw new Exception("diff msg");
|
||||
}
|
||||
Proc.binOut(b.getMic(msg)); // mic
|
||||
Proc.binOut(msg); // msg
|
||||
break;
|
||||
}
|
||||
}
|
||||
// create a native server
|
||||
private static Proc ns(Proc p) throws Exception {
|
||||
return p
|
||||
.env("KRB5_CONFIG", CONF)
|
||||
.env("KRB5_KTNAME", KTAB)
|
||||
.prop("sun.security.jgss.native", "true")
|
||||
.prop("javax.security.auth.useSubjectCredsOnly", "false")
|
||||
.prop("sun.security.nativegss.debug", "true");
|
||||
|
||||
/**
|
||||
* One test run.
|
||||
*
|
||||
* @param label test label
|
||||
* @param lc lib of client
|
||||
* @param ls lib of server
|
||||
* @param lb lib of backend
|
||||
*/
|
||||
private static void once(String label, String lc, String ls, String lb)
|
||||
throws Exception {
|
||||
|
||||
Proc pc = proc(lc)
|
||||
.args("client", lc == null ? "j" : "n")
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
"krbtgt/" + REALM + "@" + REALM, "initiate"))
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
SERVER + "@" + REALM, "initiate"))
|
||||
.perm(new javax.security.auth.kerberos.DelegationPermission(
|
||||
"\"" + SERVER + "@" + REALM + "\" " +
|
||||
"\"krbtgt/" + REALM + "@" + REALM + "\""))
|
||||
.debug(label + "-C");
|
||||
if (lc == null) {
|
||||
// for Krb5LoginModule::promptForName
|
||||
pc.perm(new PropertyPermission("user.name", "read"));
|
||||
} else {
|
||||
Files.copy(Paths.get("base.ccache"), Paths.get(label + ".ccache"));
|
||||
Files.setPosixFilePermissions(Paths.get(label + ".ccache"),
|
||||
Set.of(PosixFilePermission.OWNER_READ,
|
||||
PosixFilePermission.OWNER_WRITE));
|
||||
pc.env("KRB5CCNAME", label + ".ccache");
|
||||
// Do not try system ktab if ccache fails
|
||||
pc.env("KRB5_KTNAME", "none");
|
||||
}
|
||||
pc.start();
|
||||
|
||||
Proc ps = proc(ls)
|
||||
.args("server", ls == null ? "j" : "n")
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
SERVER + "@" + REALM, "accept"))
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
BACKEND + "@" + REALM, "initiate"))
|
||||
.debug(label + "-S");
|
||||
if (ls == null) {
|
||||
ps.perm(new PrivateCredentialPermission(
|
||||
"javax.security.auth.kerberos.KeyTab * \"*\"", "read"))
|
||||
.perm(new java.io.FilePermission(KTAB_S, "read"));
|
||||
} else {
|
||||
ps.env("KRB5_KTNAME", KTAB_S);
|
||||
}
|
||||
ps.start();
|
||||
|
||||
Proc pb = proc(lb)
|
||||
.args("backend", lb == null ? "j" : "n")
|
||||
.perm(new javax.security.auth.kerberos.ServicePermission(
|
||||
BACKEND + "@" + REALM, "accept"))
|
||||
.debug(label + "-B");
|
||||
if (lb == null) {
|
||||
pb.perm(new PrivateCredentialPermission(
|
||||
"javax.security.auth.kerberos.KeyTab * \"*\"", "read"))
|
||||
.perm(new java.io.FilePermission(KTAB_B, "read"));
|
||||
} else {
|
||||
pb.env("KRB5_KTNAME", KTAB_B);
|
||||
}
|
||||
pb.start();
|
||||
|
||||
// Client and server handshake
|
||||
ps.println(pc.readData());
|
||||
pc.println(ps.readData());
|
||||
|
||||
// Server and backend handshake
|
||||
pb.println(ps.readData());
|
||||
ps.println(pb.readData());
|
||||
|
||||
// wrap/unwrap/getMic/verifyMic and plain text
|
||||
pb.println(ps.readData());
|
||||
pb.println(ps.readData());
|
||||
pb.println(ps.readData());
|
||||
ps.println(pb.readData());
|
||||
ps.println(pb.readData());
|
||||
|
||||
if ((pc.waitFor() | ps.waitFor() | pb.waitFor()) != 0) {
|
||||
throw new Exception("Process failed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Proc for a child process.
|
||||
*
|
||||
* @param lib the library. Null is Java. "" is default native lib.
|
||||
*/
|
||||
private static Proc proc(String lib) throws Exception {
|
||||
Proc p = Proc.create("BasicProc")
|
||||
.prop("java.security.manager", "")
|
||||
.perm(new javax.security.auth.AuthPermission("doAs"));
|
||||
if (lib != null) {
|
||||
p.env("KRB5_CONFIG", CONF)
|
||||
.env("KRB5_TRACE", "/dev/stderr")
|
||||
.prop("sun.security.jgss.native", "true")
|
||||
.prop("sun.security.jgss.lib", lib)
|
||||
.prop("javax.security.auth.useSubjectCredsOnly", "false")
|
||||
.prop("sun.security.nativegss.debug", "true");
|
||||
int pos = lib.lastIndexOf('/');
|
||||
if (pos > 0) {
|
||||
p.env("LD_LIBRARY_PATH", lib.substring(0, pos));
|
||||
p.env("DYLD_LIBRARY_PATH", lib.substring(0, pos));
|
||||
}
|
||||
} else {
|
||||
p.perm(new java.util.PropertyPermission(
|
||||
"sun.security.krb5.principal", "read"))
|
||||
// For Krb5LoginModule::login.
|
||||
.perm(new javax.security.auth.AuthPermission(
|
||||
"modifyPrincipals"))
|
||||
.perm(new javax.security.auth.AuthPermission(
|
||||
"modifyPrivateCredentials"))
|
||||
.prop("sun.security.krb5.debug", "true")
|
||||
.prop("java.security.krb5.conf", CONF);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2008, 2017, 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
|
||||
|
@ -23,6 +23,7 @@
|
|||
|
||||
import com.sun.security.auth.module.Krb5LoginModule;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.PrivilegedActionException;
|
||||
|
@ -31,6 +32,11 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.security.auth.Subject;
|
||||
import javax.security.auth.callback.Callback;
|
||||
import javax.security.auth.callback.CallbackHandler;
|
||||
import javax.security.auth.callback.NameCallback;
|
||||
import javax.security.auth.callback.PasswordCallback;
|
||||
import javax.security.auth.callback.UnsupportedCallbackException;
|
||||
import javax.security.auth.kerberos.KerberosKey;
|
||||
import javax.security.auth.kerberos.KerberosTicket;
|
||||
import javax.security.auth.login.LoginContext;
|
||||
|
@ -41,9 +47,14 @@ import org.ietf.jgss.GSSManager;
|
|||
import org.ietf.jgss.GSSName;
|
||||
import org.ietf.jgss.MessageProp;
|
||||
import org.ietf.jgss.Oid;
|
||||
import sun.security.jgss.krb5.Krb5Util;
|
||||
import sun.security.krb5.Credentials;
|
||||
import sun.security.krb5.internal.ccache.CredentialsCache;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.Principal;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Context of a JGSS subject, encapsulating Subject and GSSContext.
|
||||
|
@ -149,24 +160,36 @@ public class Context {
|
|||
Map<String, String> map = new HashMap<>();
|
||||
Map<String, Object> shared = new HashMap<>();
|
||||
|
||||
if (storeKey) {
|
||||
map.put("storeKey", "true");
|
||||
}
|
||||
|
||||
if (pass != null) {
|
||||
map.put("useFirstPass", "true");
|
||||
shared.put("javax.security.auth.login.name", user);
|
||||
shared.put("javax.security.auth.login.password", pass);
|
||||
krb5.initialize(out.s, new CallbackHandler() {
|
||||
@Override
|
||||
public void handle(Callback[] callbacks)
|
||||
throws IOException, UnsupportedCallbackException {
|
||||
for (Callback cb: callbacks) {
|
||||
if (cb instanceof NameCallback) {
|
||||
((NameCallback)cb).setName(user);
|
||||
} else if (cb instanceof PasswordCallback) {
|
||||
((PasswordCallback)cb).setPassword(pass);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, shared, map);
|
||||
} else {
|
||||
map.put("doNotPrompt", "true");
|
||||
map.put("useTicketCache", "true");
|
||||
if (user != null) {
|
||||
map.put("principal", user);
|
||||
}
|
||||
}
|
||||
if (storeKey) {
|
||||
map.put("storeKey", "true");
|
||||
krb5.initialize(out.s, null, shared, map);
|
||||
}
|
||||
|
||||
krb5.initialize(out.s, null, shared, map);
|
||||
krb5.login();
|
||||
krb5.commit();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -529,9 +552,23 @@ public class Context {
|
|||
* @param s2 the receiver
|
||||
* @throws java.lang.Exception If anything goes wrong
|
||||
*/
|
||||
static public void transmit(final String message, final Context s1,
|
||||
static public void transmit(String message, final Context s1,
|
||||
final Context s2) throws Exception {
|
||||
transmit(message.getBytes(), s1, s2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmits a message from one Context to another. The sender wraps the
|
||||
* message and sends it to the receiver. The receiver unwraps it, creates
|
||||
* a MIC of the clear text and sends it back to the sender. The sender
|
||||
* verifies the MIC against the message sent earlier.
|
||||
* @param messageBytes the message
|
||||
* @param s1 the sender
|
||||
* @param s2 the receiver
|
||||
* @throws java.lang.Exception If anything goes wrong
|
||||
*/
|
||||
static public void transmit(byte[] messageBytes, final Context s1,
|
||||
final Context s2) throws Exception {
|
||||
final byte[] messageBytes = message.getBytes();
|
||||
System.out.printf("-------------------- TRANSMIT from %s to %s------------------------\n",
|
||||
s1.name, s2.name);
|
||||
byte[] wrapped = s1.wrap(messageBytes, true);
|
||||
|
@ -618,6 +655,32 @@ public class Context {
|
|||
}, in);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the tickets to a ccache file.
|
||||
*
|
||||
* @param file pathname of the ccache file
|
||||
* @return true if created, false otherwise.
|
||||
*/
|
||||
public boolean ccache(String file) throws Exception {
|
||||
Set<KerberosTicket> tickets
|
||||
= s.getPrivateCredentials(KerberosTicket.class);
|
||||
if (tickets != null && !tickets.isEmpty()) {
|
||||
CredentialsCache cc = null;
|
||||
for (KerberosTicket t : tickets) {
|
||||
Credentials cred = Krb5Util.ticketToCreds(t);
|
||||
if (cc == null) {
|
||||
cc = CredentialsCache.create(cred.getClient(), file);
|
||||
}
|
||||
cc.update(cred.toCCacheCreds());
|
||||
}
|
||||
if (cc != null) {
|
||||
cc.save();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handshake (security context establishment process) between two Contexts
|
||||
* @param c the initiator
|
||||
|
|
50
test/jdk/sun/security/krb5/auto/DiffSaltParams.java
Normal file
50
test/jdk/sun/security/krb5/auto/DiffSaltParams.java
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 8186831
|
||||
* @summary Kerberos ignores PA-DATA with a non-null s2kparams
|
||||
* @compile -XDignore.symbol.file DiffSaltParams.java
|
||||
* @run main/othervm -Dsun.security.krb5.debug=true DiffSaltParams
|
||||
*/
|
||||
|
||||
public class DiffSaltParams {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
OneKDC kdc = new OneKDC(null).writeJAASConf();
|
||||
kdc.addPrincipal("user1", "user1pass".toCharArray(),
|
||||
"hello", new byte[]{0, 0, 1, 0});
|
||||
kdc.addPrincipal("user2", "user2pass".toCharArray(),
|
||||
"hello", null);
|
||||
kdc.addPrincipal("user3", "user3pass".toCharArray(),
|
||||
null, new byte[]{0, 0, 1, 0});
|
||||
kdc.addPrincipal("user4", "user4pass".toCharArray());
|
||||
|
||||
Context.fromUserPass("user1", "user1pass".toCharArray(), true);
|
||||
Context.fromUserPass("user2", "user2pass".toCharArray(), true);
|
||||
Context.fromUserPass("user3", "user3pass".toCharArray(), true);
|
||||
Context.fromUserPass("user4", "user4pass".toCharArray(), true);
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@
|
|||
* java.security.jgss/sun.security.krb5.internal:+open
|
||||
* java.security.jgss/sun.security.jgss
|
||||
* java.security.jgss/sun.security.krb5:+open
|
||||
* java.security.jgss/sun.security.jgss.krb5
|
||||
* java.security.jgss/sun.security.krb5.internal.ccache
|
||||
* java.security.jgss/sun.security.krb5.internal.crypto
|
||||
* java.security.jgss/sun.security.krb5.internal.ktab
|
||||
|
|
|
@ -27,11 +27,12 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import sun.security.krb5.*;
|
||||
import sun.security.krb5.internal.*;
|
||||
|
@ -45,6 +46,11 @@ import sun.security.util.DerValue;
|
|||
|
||||
/**
|
||||
* A KDC server.
|
||||
*
|
||||
* Note: By setting the system property native.kdc.path to a native
|
||||
* krb5 installation, this class starts a native KDC with the
|
||||
* given realm and host. It can also add new principals and save keytabs.
|
||||
* Other features might not be available.
|
||||
* <p>
|
||||
* Features:
|
||||
* <ol>
|
||||
|
@ -125,19 +131,38 @@ public class KDC {
|
|||
public static final int DEFAULT_LIFETIME = 39600;
|
||||
public static final int DEFAULT_RENEWTIME = 86400;
|
||||
|
||||
public static String NOT_EXISTING_HOST = "not.existing.host";
|
||||
public static final String NOT_EXISTING_HOST = "not.existing.host";
|
||||
|
||||
// What etypes the KDC supports. Comma-separated strings. Null for all.
|
||||
// Please note native KDCs might use different names.
|
||||
private static final String SUPPORTED_ETYPES
|
||||
= System.getProperty("kdc.supported.enctypes");
|
||||
|
||||
// The native KDC
|
||||
private final NativeKdc nativeKdc;
|
||||
|
||||
// The native KDC process
|
||||
private Process kdcProc = null;
|
||||
|
||||
// Under the hood.
|
||||
|
||||
// The random generator to generate random keys (including session keys)
|
||||
private static SecureRandom secureRandom = new SecureRandom();
|
||||
|
||||
// Principal db. principal -> pass. A case-insensitive TreeMap is used
|
||||
// so that even if the client provides a name with different case, the KDC
|
||||
// can still locate the principal and give back correct salt.
|
||||
private TreeMap<String,char[]> passwords = new TreeMap<>
|
||||
(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
// Non default salts. Precisely, there should be different salts for
|
||||
// different etypes, pretend they are the same at the moment.
|
||||
private TreeMap<String,String> salts = new TreeMap<>
|
||||
(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
// Non default s2kparams for newer etypes. Precisely, there should be
|
||||
// different s2kparams for different etypes, pretend they are the same
|
||||
// at the moment.
|
||||
private TreeMap<String,byte[]> s2kparamses = new TreeMap<>
|
||||
(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
// Realm name
|
||||
private String realm;
|
||||
// KDC
|
||||
|
@ -218,7 +243,8 @@ public class KDC {
|
|||
|
||||
static {
|
||||
if (System.getProperty("jdk.net.hosts.file") == null) {
|
||||
String hostsFileName = System.getProperty("test.src", ".") + "/TestHosts";
|
||||
String hostsFileName
|
||||
= System.getProperty("test.src", ".") + "/TestHosts";
|
||||
System.setProperty("jdk.net.hosts.file", hostsFileName);
|
||||
}
|
||||
}
|
||||
|
@ -262,7 +288,8 @@ public class KDC {
|
|||
* @return the running KDC instance
|
||||
* @throws java.io.IOException for any socket creation error
|
||||
*/
|
||||
public static KDC create(String realm, String kdc, int port, boolean asDaemon) throws IOException {
|
||||
public static KDC create(String realm, String kdc, int port,
|
||||
boolean asDaemon) throws IOException {
|
||||
return new KDC(realm, kdc, port, asDaemon);
|
||||
}
|
||||
|
||||
|
@ -302,26 +329,38 @@ public class KDC {
|
|||
*/
|
||||
public void writeKtab(String tab, boolean append, String... names)
|
||||
throws IOException, KrbException {
|
||||
KeyTab ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab);
|
||||
KeyTab ktab = null;
|
||||
if (nativeKdc == null) {
|
||||
ktab = append ? KeyTab.getInstance(tab) : KeyTab.create(tab);
|
||||
}
|
||||
Iterable<String> entries =
|
||||
(names.length != 0) ? Arrays.asList(names): passwords.keySet();
|
||||
for (String name : entries) {
|
||||
char[] pass = passwords.get(name);
|
||||
int kvno = 0;
|
||||
if (Character.isDigit(pass[pass.length-1])) {
|
||||
kvno = pass[pass.length-1] - '0';
|
||||
if (name.indexOf('@') < 0) {
|
||||
name = name + "@" + realm;
|
||||
}
|
||||
PrincipalName pn = new PrincipalName(name,
|
||||
if (nativeKdc == null) {
|
||||
char[] pass = passwords.get(name);
|
||||
int kvno = 0;
|
||||
if (Character.isDigit(pass[pass.length - 1])) {
|
||||
kvno = pass[pass.length - 1] - '0';
|
||||
}
|
||||
PrincipalName pn = new PrincipalName(name,
|
||||
name.indexOf('/') < 0 ?
|
||||
PrincipalName.KRB_NT_UNKNOWN :
|
||||
PrincipalName.KRB_NT_SRV_HST);
|
||||
ktab.addEntry(pn,
|
||||
PrincipalName.KRB_NT_UNKNOWN :
|
||||
PrincipalName.KRB_NT_SRV_HST);
|
||||
ktab.addEntry(pn,
|
||||
getSalt(pn),
|
||||
pass,
|
||||
kvno,
|
||||
true);
|
||||
} else {
|
||||
nativeKdc.ktadd(name, tab);
|
||||
}
|
||||
}
|
||||
if (nativeKdc == null) {
|
||||
ktab.save();
|
||||
}
|
||||
ktab.save();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -367,10 +406,36 @@ public class KDC {
|
|||
* @param pass the password for the principal
|
||||
*/
|
||||
public void addPrincipal(String user, char[] pass) {
|
||||
addPrincipal(user, pass, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new principal to this realm with a given password.
|
||||
* @param user the principal's name. For a service principal, use the
|
||||
* form of host/f.q.d.n
|
||||
* @param pass the password for the principal
|
||||
* @param salt the salt, or null if a default value will be used
|
||||
* @param s2kparams the s2kparams, or null if a default value will be used
|
||||
*/
|
||||
public void addPrincipal(
|
||||
String user, char[] pass, String salt, byte[] s2kparams) {
|
||||
if (user.indexOf('@') < 0) {
|
||||
user = user + "@" + realm;
|
||||
}
|
||||
passwords.put(user, pass);
|
||||
if (nativeKdc != null) {
|
||||
if (!user.equals("krbtgt/" + realm)) {
|
||||
nativeKdc.addPrincipal(user, new String(pass));
|
||||
}
|
||||
passwords.put(user, new char[0]);
|
||||
} else {
|
||||
passwords.put(user, pass);
|
||||
if (salt != null) {
|
||||
salts.put(user, salt);
|
||||
}
|
||||
if (s2kparams != null) {
|
||||
s2kparamses.put(user, s2kparams);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -466,12 +531,11 @@ public class KDC {
|
|||
*/
|
||||
public static void saveConfig(String file, KDC kdc, Object... more)
|
||||
throws IOException {
|
||||
File f = new File(file);
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("[libdefaults]\ndefault_realm = ");
|
||||
sb.append(kdc.realm);
|
||||
sb.append("\n");
|
||||
for (Object o: more) {
|
||||
for (Object o : more) {
|
||||
if (o instanceof String) {
|
||||
sb.append(o);
|
||||
sb.append("\n");
|
||||
|
@ -479,14 +543,12 @@ public class KDC {
|
|||
}
|
||||
sb.append("\n[realms]\n");
|
||||
sb.append(kdc.realmLine());
|
||||
for (Object o: more) {
|
||||
for (Object o : more) {
|
||||
if (o instanceof KDC) {
|
||||
sb.append(((KDC)o).realmLine());
|
||||
sb.append(((KDC) o).realmLine());
|
||||
}
|
||||
}
|
||||
FileOutputStream fos = new FileOutputStream(f);
|
||||
fos.write(sb.toString().getBytes());
|
||||
fos.close();
|
||||
Files.write(Paths.get(file), sb.toString().getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -506,6 +568,7 @@ public class KDC {
|
|||
private KDC(String realm, String kdc) {
|
||||
this.realm = realm;
|
||||
this.kdc = kdc;
|
||||
this.nativeKdc = null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -513,7 +576,9 @@ public class KDC {
|
|||
*/
|
||||
protected KDC(String realm, String kdc, int port, boolean asDaemon)
|
||||
throws IOException {
|
||||
this(realm, kdc);
|
||||
this.realm = realm;
|
||||
this.kdc = kdc;
|
||||
this.nativeKdc = NativeKdc.get(this);
|
||||
startServer(port, asDaemon);
|
||||
}
|
||||
/**
|
||||
|
@ -522,8 +587,9 @@ public class KDC {
|
|||
*/
|
||||
private static char[] randomPassword() {
|
||||
char[] pass = new char[32];
|
||||
Random r = new Random();
|
||||
for (int i=0; i<31; i++)
|
||||
pass[i] = (char)secureRandom.nextInt();
|
||||
pass[i] = (char)('a' + r.nextInt(26));
|
||||
// The last char cannot be a number, otherwise, keyForUser()
|
||||
// believes it's a sign of kvno
|
||||
pass[31] = 'Z';
|
||||
|
@ -585,6 +651,9 @@ public class KDC {
|
|||
if (p.getRealmString() == null) {
|
||||
pn = pn + "@" + getRealm();
|
||||
}
|
||||
if (salts.containsKey(pn)) {
|
||||
return salts.get(pn);
|
||||
}
|
||||
if (passwords.containsKey(pn)) {
|
||||
try {
|
||||
// Find the principal name with correct case.
|
||||
|
@ -601,6 +670,29 @@ public class KDC {
|
|||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the s2kparams for the principal given the etype.
|
||||
* @param p principal
|
||||
* @param etype encryption type
|
||||
* @return the s2kparams, might be null
|
||||
*/
|
||||
protected byte[] getParams(PrincipalName p, int etype) {
|
||||
switch (etype) {
|
||||
case EncryptedData.ETYPE_AES128_CTS_HMAC_SHA1_96:
|
||||
case EncryptedData.ETYPE_AES256_CTS_HMAC_SHA1_96:
|
||||
String pn = p.toString();
|
||||
if (p.getRealmString() == null) {
|
||||
pn = pn + "@" + getRealm();
|
||||
}
|
||||
if (s2kparamses.containsKey(pn)) {
|
||||
return s2kparamses.get(pn);
|
||||
}
|
||||
return new byte[] {0, 0, 0x10, 0};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key for a given principal of the given encryption type
|
||||
* @param p the principal
|
||||
|
@ -624,7 +716,7 @@ public class KDC {
|
|||
}
|
||||
}
|
||||
return new EncryptionKey(EncryptionKeyDotStringToKey(
|
||||
getPassword(p, server), getSalt(p), null, etype),
|
||||
getPassword(p, server), getSalt(p), getParams(p, etype), etype),
|
||||
etype, kvno);
|
||||
} catch (KrbException ke) {
|
||||
throw ke;
|
||||
|
@ -633,6 +725,15 @@ public class KDC {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a KerberosTime.
|
||||
*
|
||||
* @param offset offset from NOW in milliseconds
|
||||
*/
|
||||
private static KerberosTime timeFor(long offset) {
|
||||
return new KerberosTime(new Date().getTime() + offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes an incoming request and generates a response.
|
||||
* @param in the request
|
||||
|
@ -664,7 +765,10 @@ public class KDC {
|
|||
" sends TGS-REQ for " +
|
||||
service + ", " + tgsReq.reqBody.kdcOptions);
|
||||
KDCReqBody body = tgsReq.reqBody;
|
||||
int[] eTypes = KDCReqBodyDotEType(body);
|
||||
int[] eTypes = filterSupported(KDCReqBodyDotEType(body));
|
||||
if (eTypes.length == 0) {
|
||||
throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
|
||||
}
|
||||
int e2 = eTypes[0]; // etype for outgoing session key
|
||||
int e3 = eTypes[0]; // etype for outgoing ticket
|
||||
|
||||
|
@ -701,13 +805,14 @@ public class KDC {
|
|||
PAForUserEnc p4u = new PAForUserEnc(
|
||||
new DerValue(pa.getValue()), null);
|
||||
forUserCName = p4u.name;
|
||||
System.out.println(realm + "> presenting a PA_FOR_USER "
|
||||
System.out.println(realm + "> See PA_FOR_USER "
|
||||
+ " in the name of " + p4u.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (forUserCName != null) {
|
||||
List<String> names = (List<String>)options.get(Option.ALLOW_S4U2SELF);
|
||||
List<String> names = (List<String>)
|
||||
options.get(Option.ALLOW_S4U2SELF);
|
||||
if (!names.contains(cname.toString())) {
|
||||
// Mimic the normal KDC behavior. When a server is not
|
||||
// allowed to send S4U2self, do not send an error.
|
||||
|
@ -728,11 +833,15 @@ public class KDC {
|
|||
EncryptionKey key = generateRandomKey(e2);
|
||||
|
||||
// Check time, TODO
|
||||
KerberosTime from = body.from;
|
||||
KerberosTime till = body.till;
|
||||
if (from == null || from.isZero()) {
|
||||
from = timeFor(0);
|
||||
}
|
||||
if (till == null) {
|
||||
throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO
|
||||
} else if (till.isZero()) {
|
||||
till = new KerberosTime(new Date().getTime() + 1000 * DEFAULT_LIFETIME);
|
||||
till = timeFor(1000 * DEFAULT_LIFETIME);
|
||||
}
|
||||
|
||||
boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1];
|
||||
|
@ -758,7 +867,7 @@ public class KDC {
|
|||
}
|
||||
if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
|
||||
bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
|
||||
//renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7);
|
||||
//renew = timeFor(1000 * 3600 * 24 * 7);
|
||||
}
|
||||
if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
|
||||
bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
|
||||
|
@ -777,7 +886,8 @@ public class KDC {
|
|||
Map<String,List<String>> map = (Map<String,List<String>>)
|
||||
options.get(Option.ALLOW_S4U2PROXY);
|
||||
Ticket second = KDCReqBodyDotFirstAdditionalTicket(body);
|
||||
EncryptionKey key2 = keyForUser(second.sname, second.encPart.getEType(), true);
|
||||
EncryptionKey key2 = keyForUser(
|
||||
second.sname, second.encPart.getEType(), true);
|
||||
byte[] bb = second.encPart.decrypt(key2, KeyUsage.KU_TICKET);
|
||||
DerInputStream derIn = new DerInputStream(bb);
|
||||
DerValue der = derIn.getDerValue();
|
||||
|
@ -827,8 +937,8 @@ public class KDC {
|
|||
key,
|
||||
cname,
|
||||
new TransitedEncoding(1, new byte[0]), // TODO
|
||||
new KerberosTime(new Date()),
|
||||
body.from,
|
||||
timeFor(0),
|
||||
from,
|
||||
till, renewTill,
|
||||
body.addresses != null ? body.addresses
|
||||
: etp.caddr,
|
||||
|
@ -845,20 +955,21 @@ public class KDC {
|
|||
);
|
||||
EncTGSRepPart enc_part = new EncTGSRepPart(
|
||||
key,
|
||||
new LastReq(new LastReqEntry[]{
|
||||
new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000))
|
||||
new LastReq(new LastReqEntry[] {
|
||||
new LastReqEntry(0, timeFor(-10000))
|
||||
}),
|
||||
body.getNonce(), // TODO: detect replay
|
||||
new KerberosTime(new Date().getTime() + 1000 * 3600 * 24),
|
||||
timeFor(1000 * 3600 * 24),
|
||||
// Next 5 and last MUST be same with ticket
|
||||
tFlags,
|
||||
new KerberosTime(new Date()),
|
||||
body.from,
|
||||
timeFor(0),
|
||||
from,
|
||||
till, renewTill,
|
||||
service,
|
||||
body.addresses
|
||||
);
|
||||
EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
|
||||
EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(),
|
||||
KeyUsage.KU_ENC_TGS_REP_PART_SESSKEY);
|
||||
TGSRep tgsRep = new TGSRep(null,
|
||||
cname,
|
||||
t,
|
||||
|
@ -879,7 +990,7 @@ public class KDC {
|
|||
+ " " +ke.returnCodeMessage());
|
||||
if (kerr == null) {
|
||||
kerr = new KRBError(null, null, null,
|
||||
new KerberosTime(new Date()),
|
||||
timeFor(0),
|
||||
0,
|
||||
ke.returnCode(),
|
||||
body.cname,
|
||||
|
@ -915,16 +1026,11 @@ public class KDC {
|
|||
|
||||
KDCReqBody body = asReq.reqBody;
|
||||
|
||||
eTypes = KDCReqBodyDotEType(body);
|
||||
int eType = eTypes[0];
|
||||
|
||||
// Maybe server does not support aes256, but a kinit does
|
||||
if (!EType.isSupported(eType)) {
|
||||
if (eTypes.length < 2) {
|
||||
throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
|
||||
}
|
||||
eType = eTypes[1];
|
||||
eTypes = filterSupported(KDCReqBodyDotEType(body));
|
||||
if (eTypes.length == 0) {
|
||||
throw new KrbException(Krb5.KDC_ERR_ETYPE_NOSUPP);
|
||||
}
|
||||
int eType = eTypes[0];
|
||||
|
||||
EncryptionKey ckey = keyForUser(body.cname, eType, false);
|
||||
EncryptionKey skey = keyForUser(service, eType, true);
|
||||
|
@ -953,31 +1059,32 @@ public class KDC {
|
|||
// Session key
|
||||
EncryptionKey key = generateRandomKey(eType);
|
||||
// Check time, TODO
|
||||
KerberosTime from = body.from;
|
||||
KerberosTime till = body.till;
|
||||
KerberosTime rtime = body.rtime;
|
||||
if (from == null || from.isZero()) {
|
||||
from = timeFor(0);
|
||||
}
|
||||
if (till == null) {
|
||||
throw new KrbException(Krb5.KDC_ERR_NEVER_VALID); // TODO
|
||||
} else if (till.isZero()) {
|
||||
till = new KerberosTime(
|
||||
new Date().getTime() + 1000 * DEFAULT_LIFETIME);
|
||||
} else if (till.greaterThan(new KerberosTime(Instant.now()
|
||||
.plus(1, ChronoUnit.DAYS)))) {
|
||||
till = timeFor(1000 * DEFAULT_LIFETIME);
|
||||
} else if (till.greaterThan(timeFor(24 * 3600 * 1000))) {
|
||||
// If till is more than 1 day later, make it renewable
|
||||
till = new KerberosTime(
|
||||
new Date().getTime() + 1000 * DEFAULT_LIFETIME);
|
||||
till = timeFor(1000 * DEFAULT_LIFETIME);
|
||||
body.kdcOptions.set(KDCOptions.RENEWABLE, true);
|
||||
if (rtime == null) rtime = till;
|
||||
}
|
||||
if (rtime == null && body.kdcOptions.get(KDCOptions.RENEWABLE)) {
|
||||
rtime = new KerberosTime(
|
||||
new Date().getTime() + 1000 * DEFAULT_RENEWTIME);
|
||||
rtime = timeFor(1000 * DEFAULT_RENEWTIME);
|
||||
}
|
||||
//body.from
|
||||
boolean[] bFlags = new boolean[Krb5.TKT_OPTS_MAX+1];
|
||||
if (body.kdcOptions.get(KDCOptions.FORWARDABLE)) {
|
||||
List<String> sensitives = (List<String>)
|
||||
options.get(Option.SENSITIVE_ACCOUNTS);
|
||||
if (sensitives != null && sensitives.contains(body.cname.toString())) {
|
||||
if (sensitives != null
|
||||
&& sensitives.contains(body.cname.toString())) {
|
||||
// Cannot make FORWARDABLE
|
||||
} else {
|
||||
bFlags[Krb5.TKT_OPTS_FORWARDABLE] = true;
|
||||
|
@ -985,7 +1092,7 @@ public class KDC {
|
|||
}
|
||||
if (body.kdcOptions.get(KDCOptions.RENEWABLE)) {
|
||||
bFlags[Krb5.TKT_OPTS_RENEWABLE] = true;
|
||||
//renew = new KerberosTime(new Date().getTime() + 1000 * 3600 * 24 * 7);
|
||||
//renew = timeFor(1000 * 3600 * 24 * 7);
|
||||
}
|
||||
if (body.kdcOptions.get(KDCOptions.PROXIABLE)) {
|
||||
bFlags[Krb5.TKT_OPTS_PROXIABLE] = true;
|
||||
|
@ -1007,7 +1114,8 @@ public class KDC {
|
|||
pas2 = new DerValue[] {
|
||||
new DerValue(new ETypeInfo2(1, null, null).asn1Encode()),
|
||||
new DerValue(new ETypeInfo2(1, "", null).asn1Encode()),
|
||||
new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()),
|
||||
new DerValue(new ETypeInfo2(
|
||||
1, realm, new byte[]{1}).asn1Encode()),
|
||||
};
|
||||
pas = new DerValue[] {
|
||||
new DerValue(new ETypeInfo(1, null).asn1Encode()),
|
||||
|
@ -1017,7 +1125,8 @@ public class KDC {
|
|||
break;
|
||||
case 2: // we still reject non-null s2kparams and prefer E2 over E
|
||||
pas2 = new DerValue[] {
|
||||
new DerValue(new ETypeInfo2(1, realm, new byte[]{1}).asn1Encode()),
|
||||
new DerValue(new ETypeInfo2(
|
||||
1, realm, new byte[]{1}).asn1Encode()),
|
||||
new DerValue(new ETypeInfo2(1, null, null).asn1Encode()),
|
||||
new DerValue(new ETypeInfo2(1, "", null).asn1Encode()),
|
||||
};
|
||||
|
@ -1068,7 +1177,7 @@ public class KDC {
|
|||
epas[i],
|
||||
epas[i] == EncryptedData.ETYPE_ARCFOUR_HMAC ?
|
||||
null : getSalt(body.cname),
|
||||
null).asn1Encode());
|
||||
getParams(body.cname, epas[i])).asn1Encode());
|
||||
}
|
||||
boolean allOld = true;
|
||||
for (int i: eTypes) {
|
||||
|
@ -1110,11 +1219,15 @@ public class KDC {
|
|||
}
|
||||
} else {
|
||||
try {
|
||||
EncryptedData data = newEncryptedData(new DerValue(inPAs[0].getValue()));
|
||||
EncryptionKey pakey = keyForUser(body.cname, data.getEType(), false);
|
||||
EncryptedData data = newEncryptedData(
|
||||
new DerValue(inPAs[0].getValue()));
|
||||
EncryptionKey pakey
|
||||
= keyForUser(body.cname, data.getEType(), false);
|
||||
data.decrypt(pakey, KeyUsage.KU_PA_ENC_TS);
|
||||
} catch (Exception e) {
|
||||
throw new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED);
|
||||
KrbException ke = new KrbException(Krb5.KDC_ERR_PREAUTH_FAILED);
|
||||
ke.initCause(e);
|
||||
throw ke;
|
||||
}
|
||||
bFlags[Krb5.TKT_OPTS_PRE_AUTHENT] = true;
|
||||
}
|
||||
|
@ -1125,8 +1238,8 @@ public class KDC {
|
|||
key,
|
||||
body.cname,
|
||||
new TransitedEncoding(1, new byte[0]),
|
||||
new KerberosTime(new Date()),
|
||||
body.from,
|
||||
timeFor(0),
|
||||
from,
|
||||
till, rtime,
|
||||
body.addresses,
|
||||
null);
|
||||
|
@ -1137,19 +1250,20 @@ public class KDC {
|
|||
EncASRepPart enc_part = new EncASRepPart(
|
||||
key,
|
||||
new LastReq(new LastReqEntry[]{
|
||||
new LastReqEntry(0, new KerberosTime(new Date().getTime() - 10000))
|
||||
new LastReqEntry(0, timeFor(-10000))
|
||||
}),
|
||||
body.getNonce(), // TODO: detect replay?
|
||||
new KerberosTime(new Date().getTime() + 1000 * 3600 * 24),
|
||||
timeFor(1000 * 3600 * 24),
|
||||
// Next 5 and last MUST be same with ticket
|
||||
tFlags,
|
||||
new KerberosTime(new Date()),
|
||||
body.from,
|
||||
timeFor(0),
|
||||
from,
|
||||
till, rtime,
|
||||
service,
|
||||
body.addresses
|
||||
);
|
||||
EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(), KeyUsage.KU_ENC_AS_REP_PART);
|
||||
EncryptedData edata = new EncryptedData(ckey, enc_part.asn1Encode(),
|
||||
KeyUsage.KU_ENC_AS_REP_PART);
|
||||
ASRep asRep = new ASRep(
|
||||
outPAs.toArray(new PAData[outPAs.size()]),
|
||||
body.cname,
|
||||
|
@ -1204,7 +1318,7 @@ public class KDC {
|
|||
eData = temp.toByteArray();
|
||||
}
|
||||
kerr = new KRBError(null, null, null,
|
||||
new KerberosTime(new Date()),
|
||||
timeFor(0),
|
||||
0,
|
||||
ke.returnCode(),
|
||||
body.cname,
|
||||
|
@ -1216,6 +1330,35 @@ public class KDC {
|
|||
}
|
||||
}
|
||||
|
||||
private int[] filterSupported(int[] input) {
|
||||
int count = 0;
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
if (!EType.isSupported(input[i])) {
|
||||
continue;
|
||||
}
|
||||
if (SUPPORTED_ETYPES != null) {
|
||||
boolean supported = false;
|
||||
for (String se : SUPPORTED_ETYPES.split(",")) {
|
||||
if (Config.getType(se) == input[i]) {
|
||||
supported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!supported) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (count != i) {
|
||||
input[count] = input[i];
|
||||
}
|
||||
count++;
|
||||
}
|
||||
if (count != input.length) {
|
||||
input = Arrays.copyOf(input, count);
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a line for a KDC to put inside [realms] of krb5.conf
|
||||
* @return REALM.NAME = { kdc = host:port etc }
|
||||
|
@ -1240,6 +1383,20 @@ public class KDC {
|
|||
* @throws java.io.IOException for any communication error
|
||||
*/
|
||||
protected void startServer(int port, boolean asDaemon) throws IOException {
|
||||
if (nativeKdc != null) {
|
||||
startNativeServer(port, asDaemon);
|
||||
} else {
|
||||
startJavaServer(port, asDaemon);
|
||||
}
|
||||
}
|
||||
|
||||
private void startNativeServer(int port, boolean asDaemon) throws IOException {
|
||||
nativeKdc.prepare();
|
||||
nativeKdc.init();
|
||||
kdcProc = nativeKdc.kdc();
|
||||
}
|
||||
|
||||
private void startJavaServer(int port, boolean asDaemon) throws IOException {
|
||||
if (port > 0) {
|
||||
u1 = new DatagramSocket(port, InetAddress.getByName("127.0.0.1"));
|
||||
t1 = new ServerSocket(port);
|
||||
|
@ -1336,19 +1493,37 @@ public class KDC {
|
|||
}
|
||||
}
|
||||
|
||||
public void kinit(String user, String ccache) throws Exception {
|
||||
if (user.indexOf('@') < 0) {
|
||||
user = user + "@" + realm;
|
||||
}
|
||||
if (nativeKdc != null) {
|
||||
nativeKdc.kinit(user, ccache);
|
||||
} else {
|
||||
Context.fromUserPass(user, passwords.get(user), false)
|
||||
.ccache(ccache);
|
||||
}
|
||||
}
|
||||
|
||||
boolean isReady() {
|
||||
return udpConsumerReady && tcpConsumerReady && dispatcherReady;
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
try {
|
||||
thread1.stop();
|
||||
thread2.stop();
|
||||
thread3.stop();
|
||||
u1.close();
|
||||
t1.close();
|
||||
} catch (Exception e) {
|
||||
// OK
|
||||
if (nativeKdc != null) {
|
||||
System.out.println("Killing kdc...");
|
||||
kdcProc.destroyForcibly();
|
||||
System.out.println("Done");
|
||||
} else {
|
||||
try {
|
||||
thread1.stop();
|
||||
thread2.stop();
|
||||
thread3.stop();
|
||||
u1.close();
|
||||
t1.close();
|
||||
} catch (Exception e) {
|
||||
// OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1463,6 +1638,266 @@ public class KDC {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A native KDC using the binaries in nativePath. Attention:
|
||||
* this is using binaries, not an existing KDC instance.
|
||||
* An implementation of this takes care of configuration,
|
||||
* principal db managing and KDC startup.
|
||||
*/
|
||||
static abstract class NativeKdc {
|
||||
|
||||
protected Map<String,String> env;
|
||||
protected String nativePath;
|
||||
protected String base;
|
||||
protected String realm;
|
||||
protected int port;
|
||||
|
||||
NativeKdc(String nativePath, KDC kdc) {
|
||||
if (kdc.port == 0) {
|
||||
kdc.port = 8000 + new java.util.Random().nextInt(10000);
|
||||
}
|
||||
this.nativePath = nativePath;
|
||||
this.realm = kdc.realm;
|
||||
this.port = kdc.port;
|
||||
this.base = Paths.get("" + port).toAbsolutePath().toString();
|
||||
}
|
||||
|
||||
// Add a new principal
|
||||
abstract void addPrincipal(String user, String pass);
|
||||
// Add a keytab entry
|
||||
abstract void ktadd(String user, String ktab);
|
||||
// Initialize KDC
|
||||
abstract void init();
|
||||
// Start kdc
|
||||
abstract Process kdc();
|
||||
// Configuration
|
||||
abstract void prepare();
|
||||
// Fill ccache
|
||||
abstract void kinit(String user, String ccache);
|
||||
|
||||
static NativeKdc get(KDC kdc) {
|
||||
String prop = System.getProperty("native.kdc.path");
|
||||
if (prop == null) {
|
||||
return null;
|
||||
} else if (Files.exists(Paths.get(prop, "sbin/krb5kdc"))) {
|
||||
return new MIT(true, prop, kdc);
|
||||
} else if (Files.exists(Paths.get(prop, "kdc/krb5kdc"))) {
|
||||
return new MIT(false, prop, kdc);
|
||||
} else if (Files.exists(Paths.get(prop, "libexec/kdc"))) {
|
||||
return new Heimdal(prop, kdc);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Strange " + prop);
|
||||
}
|
||||
}
|
||||
|
||||
Process run(boolean wait, String... cmd) {
|
||||
try {
|
||||
System.out.println("Running " + cmd2str(env, cmd));
|
||||
ProcessBuilder pb = new ProcessBuilder();
|
||||
pb.inheritIO();
|
||||
pb.environment().putAll(env);
|
||||
Process p = pb.command(cmd).start();
|
||||
if (wait) {
|
||||
if (p.waitFor() < 0) {
|
||||
throw new RuntimeException("exit code is not null");
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return p;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private String cmd2str(Map<String,String> env, String... cmd) {
|
||||
return env.entrySet().stream().map(e -> e.getKey()+"="+e.getValue())
|
||||
.collect(Collectors.joining(" ")) + " " +
|
||||
Stream.of(cmd).collect(Collectors.joining(" "));
|
||||
}
|
||||
}
|
||||
|
||||
// Heimdal KDC. Build your own and run "make install" to nativePath.
|
||||
static class Heimdal extends NativeKdc {
|
||||
|
||||
Heimdal(String nativePath, KDC kdc) {
|
||||
super(nativePath, kdc);
|
||||
this.env = Map.of(
|
||||
"KRB5_CONFIG", base + "/krb5.conf",
|
||||
"KRB5_TRACE", "/dev/stderr",
|
||||
"DYLD_LIBRARY_PATH", nativePath + "/lib",
|
||||
"LD_LIBRARY_PATH", nativePath + "/lib");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPrincipal(String user, String pass) {
|
||||
run(true, nativePath + "/bin/kadmin", "-l", "-r", realm,
|
||||
"add", "-p", pass, "--use-defaults", user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ktadd(String user, String ktab) {
|
||||
run(true, nativePath + "/bin/kadmin", "-l", "-r", realm,
|
||||
"ext_keytab", "-k", ktab, user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
run(true, nativePath + "/bin/kadmin", "-l", "-r", realm,
|
||||
"init", "--realm-max-ticket-life=1day",
|
||||
"--realm-max-renewable-life=1month", realm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process kdc() {
|
||||
return run(false, nativePath + "/libexec/kdc",
|
||||
"--addresses=127.0.0.1", "-P", "" + port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
try {
|
||||
Files.createDirectory(Paths.get(base));
|
||||
Files.write(Paths.get(base + "/krb5.conf"), Arrays.asList(
|
||||
"[libdefaults]",
|
||||
"default_realm = " + realm,
|
||||
"default_keytab_name = FILE:" + base + "/krb5.keytab",
|
||||
"forwardable = true",
|
||||
"dns_lookup_kdc = no",
|
||||
"dns_lookup_realm = no",
|
||||
"dns_canonicalize_hostname = false",
|
||||
"\n[realms]",
|
||||
realm + " = {",
|
||||
" kdc = localhost:" + port,
|
||||
"}",
|
||||
"\n[kdc]",
|
||||
"db-dir = " + base,
|
||||
"database = {",
|
||||
" label = {",
|
||||
" dbname = " + base + "/current-db",
|
||||
" realm = " + realm,
|
||||
" mkey_file = " + base + "/mkey.file",
|
||||
" acl_file = " + base + "/heimdal.acl",
|
||||
" log_file = " + base + "/current.log",
|
||||
" }",
|
||||
"}",
|
||||
SUPPORTED_ETYPES == null ? ""
|
||||
: ("\n[kadmin]\ndefault_keys = "
|
||||
+ (SUPPORTED_ETYPES + ",")
|
||||
.replaceAll(",", ":pw-salt ")),
|
||||
"\n[logging]",
|
||||
"kdc = 0-/FILE:" + base + "/messages.log",
|
||||
"krb5 = 0-/FILE:" + base + "/messages.log",
|
||||
"default = 0-/FILE:" + base + "/messages.log"
|
||||
));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void kinit(String user, String ccache) {
|
||||
String tmpName = base + "/" + user + "." +
|
||||
System.identityHashCode(this) + ".keytab";
|
||||
ktadd(user, tmpName);
|
||||
run(true, nativePath + "/bin/kinit",
|
||||
"-f", "-t", tmpName, "-c", ccache, user);
|
||||
}
|
||||
}
|
||||
|
||||
// MIT krb5 KDC. Make your own exploded (install == false), or
|
||||
// "make install" into nativePath (install == true).
|
||||
static class MIT extends NativeKdc {
|
||||
|
||||
private boolean install; // "make install" or "make"
|
||||
|
||||
MIT(boolean install, String nativePath, KDC kdc) {
|
||||
super(nativePath, kdc);
|
||||
this.install = install;
|
||||
this.env = Map.of(
|
||||
"KRB5_KDC_PROFILE", base + "/kdc.conf",
|
||||
"KRB5_CONFIG", base + "/krb5.conf",
|
||||
"KRB5_TRACE", "/dev/stderr",
|
||||
"DYLD_LIBRARY_PATH", nativePath + "/lib",
|
||||
"LD_LIBRARY_PATH", nativePath + "/lib");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPrincipal(String user, String pass) {
|
||||
run(true, nativePath +
|
||||
(install ? "/sbin/" : "/kadmin/cli/") + "kadmin.local",
|
||||
"-q", "addprinc -pw " + pass + " " + user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ktadd(String user, String ktab) {
|
||||
run(true, nativePath +
|
||||
(install ? "/sbin/" : "/kadmin/cli/") + "kadmin.local",
|
||||
"-q", "ktadd -k " + ktab + " -norandkey " + user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
run(true, nativePath +
|
||||
(install ? "/sbin/" : "/kadmin/dbutil/") + "kdb5_util",
|
||||
"create", "-s", "-W", "-P", "olala");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Process kdc() {
|
||||
return run(false, nativePath +
|
||||
(install ? "/sbin/" : "/kdc/") + "krb5kdc",
|
||||
"-n");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepare() {
|
||||
try {
|
||||
Files.createDirectory(Paths.get(base));
|
||||
Files.write(Paths.get(base + "/kdc.conf"), Arrays.asList(
|
||||
"[kdcdefaults]",
|
||||
"\n[realms]",
|
||||
realm + "= {",
|
||||
" kdc_listen = " + this.port,
|
||||
" kdc_tcp_listen = " + this.port,
|
||||
" database_name = " + base + "/principal",
|
||||
" key_stash_file = " + base + "/.k5.ATHENA.MIT.EDU",
|
||||
SUPPORTED_ETYPES == null ? ""
|
||||
: (" supported_enctypes = "
|
||||
+ (SUPPORTED_ETYPES + ",")
|
||||
.replaceAll(",", ":normal ")),
|
||||
"}"
|
||||
));
|
||||
Files.write(Paths.get(base + "/krb5.conf"), Arrays.asList(
|
||||
"[libdefaults]",
|
||||
"default_realm = " + realm,
|
||||
"default_keytab_name = FILE:" + base + "/krb5.keytab",
|
||||
"forwardable = true",
|
||||
"dns_lookup_kdc = no",
|
||||
"dns_lookup_realm = no",
|
||||
"dns_canonicalize_hostname = false",
|
||||
"\n[realms]",
|
||||
realm + " = {",
|
||||
" kdc = localhost:" + port,
|
||||
"}",
|
||||
"\n[logging]",
|
||||
"kdc = FILE:" + base + "/krb5kdc.log"
|
||||
));
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void kinit(String user, String ccache) {
|
||||
String tmpName = base + "/" + user + "." +
|
||||
System.identityHashCode(this) + ".keytab";
|
||||
ktadd(user, tmpName);
|
||||
run(true, nativePath +
|
||||
(install ? "/bin/" : "/clients/kinit/") + "kinit",
|
||||
"-f", "-t", tmpName, "-c", ccache, user);
|
||||
}
|
||||
}
|
||||
|
||||
// Calling private methods thru reflections
|
||||
private static final Field getPADataField;
|
||||
|
|
|
@ -95,6 +95,7 @@ public class SSLwithPerms {
|
|||
.prop("javax.net.ssl", "handshake")
|
||||
.prop("sun.security.krb5.debug", "true")
|
||||
.perm(new SecurityPermission("setProperty.jdk.tls.disabledAlgorithms"))
|
||||
.perm(new java.util.PropertyPermission("user.name", "read"))
|
||||
.perm(new PropertyPermission("sun.security.krb5.principal", "read"))
|
||||
.perm(new FilePermission("port", "read"))
|
||||
.perm(new FilePermission(hostsFileName, "read"))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
modules java.base/jdk.internal.misc \
|
||||
java.base/sun.security.util \
|
||||
java.security.jgss/sun.security.jgss \
|
||||
java.security.jgss/sun.security.jgss.krb5 \
|
||||
java.security.jgss/sun.security.krb5:+open \
|
||||
java.security.jgss/sun.security.krb5.internal:+open \
|
||||
java.security.jgss/sun.security.krb5.internal.ccache \
|
||||
|
|
271
test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
Normal file
271
test/jdk/sun/security/ssl/SSLSocketImpl/SSLSocketCloseHang.java
Normal file
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 8184328
|
||||
* @summary JDK8u131-b34-socketRead0 hang at SSL read
|
||||
* @run main/othervm SSLSocketCloseHang
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.security.*;
|
||||
import javax.net.ssl.*;
|
||||
|
||||
public class SSLSocketCloseHang {
|
||||
|
||||
/*
|
||||
* =============================================================
|
||||
* Set the various variables needed for the tests, then
|
||||
* specify what tests to run on each side.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Should we run the client or server in a separate thread?
|
||||
* Both sides can throw exceptions, but do you have a preference
|
||||
* as to which side should be the main thread.
|
||||
*/
|
||||
static boolean separateServerThread = true;
|
||||
|
||||
/*
|
||||
* Where do we find the keystores?
|
||||
*/
|
||||
static String pathToStores = "../../../../javax/net/ssl/etc";
|
||||
static String keyStoreFile = "keystore";
|
||||
static String trustStoreFile = "truststore";
|
||||
static String passwd = "passphrase";
|
||||
|
||||
/*
|
||||
* Is the server ready to serve?
|
||||
*/
|
||||
volatile static boolean serverReady = false;
|
||||
|
||||
/*
|
||||
* Was the client responsible for closing the socket
|
||||
*/
|
||||
volatile static boolean clientClosed = false;
|
||||
|
||||
/*
|
||||
* Turn on SSL debugging?
|
||||
*/
|
||||
static boolean debug = false;
|
||||
|
||||
/*
|
||||
* If the client or server is doing some kind of object creation
|
||||
* that the other side depends on, and that thread prematurely
|
||||
* exits, you may experience a hang. The test harness will
|
||||
* terminate all hung threads after its timeout has expired,
|
||||
* currently 3 minutes by default, but you might try to be
|
||||
* smart about it....
|
||||
*/
|
||||
|
||||
/*
|
||||
* Define the server side of the test.
|
||||
*
|
||||
* If the server prematurely exits, serverReady will be set to true
|
||||
* to avoid infinite hangs.
|
||||
*/
|
||||
void doServerSide() throws Exception {
|
||||
SSLServerSocketFactory sslssf =
|
||||
(SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
|
||||
SSLServerSocket sslServerSocket =
|
||||
(SSLServerSocket) sslssf.createServerSocket(serverPort);
|
||||
|
||||
serverPort = sslServerSocket.getLocalPort();
|
||||
|
||||
/*
|
||||
* Signal Client, we're ready for his connect.
|
||||
*/
|
||||
serverReady = true;
|
||||
|
||||
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
|
||||
sslSocket.startHandshake();
|
||||
while (!clientClosed) {
|
||||
Thread.sleep(500);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Define the client side of the test.
|
||||
*
|
||||
* If the server prematurely exits, serverReady will be set to true
|
||||
* to avoid infinite hangs.
|
||||
*/
|
||||
void doClientSide() throws Exception {
|
||||
boolean caught = false;
|
||||
|
||||
/*
|
||||
* Wait for server to get started.
|
||||
*/
|
||||
System.out.println("waiting on server");
|
||||
while (!serverReady) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
System.out.println("server ready");
|
||||
|
||||
Socket baseSocket = new Socket("localhost", serverPort);
|
||||
baseSocket.setSoTimeout(100);
|
||||
|
||||
SSLSocketFactory sslsf =
|
||||
(SSLSocketFactory) SSLSocketFactory.getDefault();
|
||||
SSLSocket sslSocket = (SSLSocket)
|
||||
sslsf.createSocket(baseSocket, "localhost", serverPort, false);
|
||||
|
||||
// handshaking
|
||||
sslSocket.startHandshake();
|
||||
System.out.println("handshake done");
|
||||
|
||||
Thread.sleep(500);
|
||||
System.out.println("client closing");
|
||||
|
||||
sslSocket.close();
|
||||
clientClosed = true;
|
||||
System.out.println("client closed");
|
||||
}
|
||||
|
||||
/*
|
||||
* =============================================================
|
||||
* The remainder is just support stuff
|
||||
*/
|
||||
|
||||
// use any free port by default
|
||||
volatile int serverPort = 0;
|
||||
|
||||
volatile Exception serverException = null;
|
||||
volatile Exception clientException = null;
|
||||
|
||||
volatile byte[] serverDigest = null;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String keyFilename =
|
||||
System.getProperty("test.src", "./") + "/" + pathToStores +
|
||||
"/" + keyStoreFile;
|
||||
String trustFilename =
|
||||
System.getProperty("test.src", "./") + "/" + pathToStores +
|
||||
"/" + trustStoreFile;
|
||||
|
||||
System.setProperty("javax.net.ssl.keyStore", keyFilename);
|
||||
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
|
||||
System.setProperty("javax.net.ssl.trustStore", trustFilename);
|
||||
System.setProperty("javax.net.ssl.trustStorePassword", passwd);
|
||||
|
||||
if (debug)
|
||||
System.setProperty("javax.net.debug", "all");
|
||||
|
||||
/*
|
||||
* Start the tests.
|
||||
*/
|
||||
new SSLSocketCloseHang();
|
||||
}
|
||||
|
||||
Thread clientThread = null;
|
||||
Thread serverThread = null;
|
||||
|
||||
/*
|
||||
* Primary constructor, used to drive remainder of the test.
|
||||
*
|
||||
* Fork off the other side, then do your work.
|
||||
*/
|
||||
SSLSocketCloseHang() throws Exception {
|
||||
if (separateServerThread) {
|
||||
startServer(true);
|
||||
startClient(false);
|
||||
} else {
|
||||
startClient(true);
|
||||
startServer(false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for other side to close down.
|
||||
*/
|
||||
if (separateServerThread) {
|
||||
serverThread.join();
|
||||
} else {
|
||||
clientThread.join();
|
||||
}
|
||||
|
||||
/*
|
||||
* When we get here, the test is pretty much over.
|
||||
*
|
||||
* If the main thread excepted, that propagates back
|
||||
* immediately. If the other thread threw an exception, we
|
||||
* should report back.
|
||||
*/
|
||||
if (serverException != null) {
|
||||
System.out.print("Server Exception:");
|
||||
throw serverException;
|
||||
}
|
||||
if (clientException != null) {
|
||||
System.out.print("Client Exception:");
|
||||
throw clientException;
|
||||
}
|
||||
}
|
||||
|
||||
void startServer(boolean newThread) throws Exception {
|
||||
if (newThread) {
|
||||
serverThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
doServerSide();
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* Our server thread just died.
|
||||
*
|
||||
* Release the client, if not active already...
|
||||
*/
|
||||
System.err.println("Server died...");
|
||||
System.err.println(e);
|
||||
serverReady = true;
|
||||
serverException = e;
|
||||
}
|
||||
}
|
||||
};
|
||||
serverThread.start();
|
||||
} else {
|
||||
doServerSide();
|
||||
}
|
||||
}
|
||||
|
||||
void startClient(boolean newThread) throws Exception {
|
||||
if (newThread) {
|
||||
clientThread = new Thread() {
|
||||
public void run() {
|
||||
try {
|
||||
doClientSide();
|
||||
} catch (Exception e) {
|
||||
/*
|
||||
* Our client thread just died.
|
||||
*/
|
||||
System.err.println("Client died...");
|
||||
clientException = e;
|
||||
}
|
||||
}
|
||||
};
|
||||
clientThread.start();
|
||||
} else {
|
||||
doClientSide();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
* Copyright (c) 2017, 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 6695402
|
||||
* @summary verify signatures of jars containing classes with names
|
||||
* with multi-byte unicode characters broken across lines
|
||||
* @library /test/lib
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Attributes.Name;
|
||||
import java.util.jar.JarEntry;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
import jdk.test.lib.SecurityTools;
|
||||
import jdk.test.lib.util.JarUtils;
|
||||
|
||||
public class LineBrokenMultiByteCharacter {
|
||||
|
||||
/**
|
||||
* this name will break across lines in MANIFEST.MF at the
|
||||
* middle of a two-byte utf-8 encoded character due to its e acute letter
|
||||
* at its exact position.
|
||||
*
|
||||
* because no file with such a name exists {@link JarUtils} will add the
|
||||
* name itself as contents to the jar entry which would have contained a
|
||||
* compiled class in the original bug. For this test, the contents of the
|
||||
* files contained in the jar file is not important as long as they get
|
||||
* signed.
|
||||
*
|
||||
* @see #verifyClassNameLineBroken(JarFile, String)
|
||||
*/
|
||||
static final String testClassName =
|
||||
"LineBrokenMultiByteCharacterA1234567890B1234567890C123456789D12\u00E9xyz.class";
|
||||
|
||||
static final String anotherName =
|
||||
"LineBrokenMultiByteCharacterA1234567890B1234567890C123456789D1234567890.class";
|
||||
|
||||
static final String alias = "a";
|
||||
static final String keystoreFileName = "test.jks";
|
||||
static final String manifestFileName = "MANIFEST.MF";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
prepare();
|
||||
|
||||
testSignJar("test.jar");
|
||||
testSignJarNoManifest("test-no-manifest.jar");
|
||||
testSignJarUpdate("test-update.jar", "test-updated.jar");
|
||||
}
|
||||
|
||||
static void prepare() throws Exception {
|
||||
SecurityTools.keytool("-keystore", keystoreFileName, "-genkeypair",
|
||||
"-storepass", "changeit", "-keypass", "changeit", "-storetype",
|
||||
"JKS", "-alias", alias, "-dname", "CN=X", "-validity", "366")
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
Files.write(Paths.get(manifestFileName), (Name.
|
||||
MANIFEST_VERSION.toString() + ": 1.0\r\n").getBytes(UTF_8));
|
||||
}
|
||||
|
||||
static void testSignJar(String jarFileName) throws Exception {
|
||||
JarUtils.createJar(jarFileName, manifestFileName, testClassName);
|
||||
verifyJarSignature(jarFileName);
|
||||
}
|
||||
|
||||
static void testSignJarNoManifest(String jarFileName) throws Exception {
|
||||
JarUtils.createJar(jarFileName, testClassName);
|
||||
verifyJarSignature(jarFileName);
|
||||
}
|
||||
|
||||
static void testSignJarUpdate(
|
||||
String initialFileName, String updatedFileName) throws Exception {
|
||||
JarUtils.createJar(initialFileName, manifestFileName, anotherName);
|
||||
SecurityTools.jarsigner("-keystore", keystoreFileName, "-storetype",
|
||||
"JKS", "-storepass", "changeit", "-debug", initialFileName,
|
||||
alias).shouldHaveExitValue(0);
|
||||
JarUtils.updateJar(initialFileName, updatedFileName, testClassName);
|
||||
verifyJarSignature(updatedFileName);
|
||||
}
|
||||
|
||||
static void verifyJarSignature(String jarFileName) throws Exception {
|
||||
// actually sign the jar
|
||||
SecurityTools.jarsigner("-keystore", keystoreFileName, "-storetype",
|
||||
"JKS", "-storepass", "changeit", "-debug", jarFileName, alias)
|
||||
.shouldHaveExitValue(0);
|
||||
|
||||
try (
|
||||
JarFile jar = new JarFile(jarFileName);
|
||||
) {
|
||||
verifyClassNameLineBroken(jar, testClassName);
|
||||
verifyCodeSigners(jar, jar.getJarEntry(testClassName));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* it would be too easy to miss the actual test case by just renaming an
|
||||
* identifier so that the multi-byte encoded character would not any longer
|
||||
* be broken across a line break.
|
||||
*
|
||||
* this check here verifies that the actual test case is tested based on
|
||||
* the manifest and not based on the signature file because at the moment,
|
||||
* the signature file does not even contain the desired entry at all.
|
||||
*
|
||||
* this relies on {@link java.util.jar.Manifest} breaking lines unaware
|
||||
* of bytes that belong to the same multi-byte utf characters.
|
||||
*/
|
||||
static void verifyClassNameLineBroken(JarFile jar, String className)
|
||||
throws IOException {
|
||||
byte[] eAcute = "\u00E9".getBytes(UTF_8);
|
||||
byte[] eAcuteBroken =
|
||||
new byte[] {eAcute[0], '\r', '\n', ' ', eAcute[1]};
|
||||
|
||||
if (jar.getManifest().getAttributes(className) == null) {
|
||||
throw new AssertionError(className + " not found in manifest");
|
||||
}
|
||||
|
||||
JarEntry manifestEntry = jar.getJarEntry(JarFile.MANIFEST_NAME);
|
||||
try (
|
||||
InputStream manifestIs = jar.getInputStream(manifestEntry);
|
||||
) {
|
||||
int bytesMatched = 0;
|
||||
for (int b = manifestIs.read(); b > -1; b = manifestIs.read()) {
|
||||
if ((byte) b == eAcuteBroken[bytesMatched]) {
|
||||
bytesMatched++;
|
||||
if (bytesMatched == eAcuteBroken.length) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
bytesMatched = 0;
|
||||
}
|
||||
}
|
||||
if (bytesMatched < eAcuteBroken.length) {
|
||||
throw new AssertionError("self-test failed: multi-byte "
|
||||
+ "utf-8 character not broken across lines");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void verifyCodeSigners(JarFile jar, JarEntry jarEntry)
|
||||
throws IOException {
|
||||
// codeSigners is initialized only after the entry has been read
|
||||
try (
|
||||
InputStream inputStream = jar.getInputStream(jarEntry);
|
||||
) {
|
||||
inputStream.readAllBytes();
|
||||
}
|
||||
|
||||
// a check for the presence of code signers is sufficient to check
|
||||
// bug JDK-6695402. no need to also verify the actual code signers
|
||||
// attributes here.
|
||||
if (jarEntry.getCodeSigners() == null
|
||||
|| jarEntry.getCodeSigners().length == 0) {
|
||||
throw new AssertionError(
|
||||
"no signing certificate found for " + jarEntry.getName());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,34 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
<applet width=100 height=100 code=Alias.class>
|
||||
</applet>
|
||||
|
||||
This is a multi-stage test. Click on "done" when you have completed
|
||||
reading these instructions.<br><br>
|
||||
|
||||
<ol>
|
||||
<li> PolicyTool will be invoked
|
||||
<li> Click on "Add Policy Entry"
|
||||
<li> Click on "Add Principal"
|
||||
<li> Type "myalias" in the "Principal Name" field
|
||||
(leave "Principal Type" empty)
|
||||
<li> Click on "OK"
|
||||
<li> Confirm there is a message:
|
||||
'myalias' will be interpreted as a key store alias. ...
|
||||
Click on "OK"
|
||||
<li> Click on "Done"
|
||||
<li> Open the "File" menu, and "View Warning Log"
|
||||
<li> Confirm there is a warning:
|
||||
Warning: Principal name 'myalias' specified without a Principal class.
|
||||
<li> Click on "OK"
|
||||
<li> Open the "File" menu, and "Save As"
|
||||
<li> Save using the file name "p1"
|
||||
<li> Click on "OK" in the status message window
|
||||
<li> Open the "File" menu and "Open Policy"
|
||||
<li> Open the file named "p1"
|
||||
<li> If the file opens successfully, the test passed.
|
||||
Otherwise, the test failed.
|
||||
</ol>
|
||||
</body>
|
||||
</html>
|
|
@ -1,78 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2001, 2013, 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 4449491
|
||||
# @summary policytool should allow principal type to be empty
|
||||
# (keystore alias substitution)
|
||||
#
|
||||
# @run applet/manual=done Alias.html
|
||||
# @run shell Alias.sh
|
||||
# @run applet/manual=yesno Alias.html
|
||||
|
||||
# set a few environment variables so that the shell-script can run stand-alone
|
||||
# in the source directory
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC="."
|
||||
fi
|
||||
if [ "${TESTCLASSES}" = "" ] ; then
|
||||
TESTCLASSES="."
|
||||
fi
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
echo "TESTJAVA not set. Test cannot execute."
|
||||
echo "FAILED!!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux | Darwin | AIX )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
;;
|
||||
CYGWIN* )
|
||||
NULL=/dev/null
|
||||
PS=";"
|
||||
FS="/"
|
||||
;;
|
||||
Windows* )
|
||||
NULL=NUL
|
||||
PS=";"
|
||||
FS="\\"
|
||||
;;
|
||||
* )
|
||||
echo "Unrecognized system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
# the test code
|
||||
|
||||
echo "HELLO!"
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}policytool
|
||||
|
||||
exit $?
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
<applet width=100 height=100 code=ChangeUI.class>
|
||||
</applet>
|
||||
|
||||
<b>ATTENTION:</b> policytool now contains no platform-specific codes anymore and
|
||||
should behaves exactly the same across all platforms. This also means:
|
||||
<ol>
|
||||
<li>You may only need to test it on one platform</li>
|
||||
<li>You can create policy files for a platform which is different than
|
||||
the platform you are running policytool on</li>
|
||||
</ol>
|
||||
|
||||
This is a multi-stage test. Click on "done" when you have completed
|
||||
reading these instructions.<br><br>
|
||||
|
||||
First, policytool will be invoked.<br><br>
|
||||
<ol start="0">
|
||||
<li>Find (or create) a temporary directory that you have write access to.
|
||||
(Example: 'C:\foo\tmp' on Windows or '/tmp' on other systems)
|
||||
<li>Add new policy entry
|
||||
<li>Add permission:
|
||||
<pre>
|
||||
Type Target name Actions
|
||||
FilePermission c:\\foo\\bar read
|
||||
</pre>
|
||||
<ol>
|
||||
<li>Press OK</li>
|
||||
<li>Confirm the file name warning dialog appears</li>
|
||||
<li>Choose Retain, confirm the permission edit dialog is closed</li>
|
||||
<li>Double click the newly created FilePermission entry to edit it</li>
|
||||
<li>Press OK</li>
|
||||
<li>Confirm the file name warning dialog appears</li>
|
||||
<li>Choose Edit, confirm the permission edit dialog is still opened</li>
|
||||
<li>change Target name to c:\foo\bar</li>
|
||||
<li>Press OK, no warning dialog is shown</li>
|
||||
</ol>
|
||||
<li>Add permission:
|
||||
<pre>
|
||||
Type Target name
|
||||
DelegationPermission "me@SOMEWHERE" "you@SOMEWHERE"
|
||||
</pre>
|
||||
<ol>
|
||||
<li>Press OK</li>
|
||||
<li>Double click the newly craeted DelegationPermission entry to edit it</li>
|
||||
<li>Confirm the target name is still "me@SOMEWHERE" "you@SOMEWHERE"</li>
|
||||
<li>Press OK</li>
|
||||
</ol>
|
||||
<li>Confirm there are 2 entries in the permission list
|
||||
<li>Press Done
|
||||
<li>Double click the new policy entry to edit it
|
||||
<li>Add permission:
|
||||
<pre>
|
||||
Type
|
||||
AllPermission
|
||||
</pre>
|
||||
<li>Add a new Principal, say, KerberosPrincipal with Principal Name as aaa
|
||||
<li>Confirm there is 1 entry in the Principals list
|
||||
<li>Confirm there are 3 entries in the permission list
|
||||
<li>Press cancel
|
||||
<li>Double click the policy entry to edit it
|
||||
<li>Confirm there are ZERO entries in the Principals list
|
||||
<li>Confirm there are 2 entries in the permission list
|
||||
<li>Press cancel
|
||||
<li>Save as "/tmp/p"<br>
|
||||
(Or use the temporary directory mentioned in Step 0 if it's not '/tmp'.
|
||||
For example, "C:\foo\tmp\p" on Windows)
|
||||
<li>Confirm that the file created in the previous step looks like
|
||||
<pre>
|
||||
/* AUTOMATICALLY GENERATED ON Tue Jul 19 16:27:30 CST 2005*/
|
||||
/* DO NOT EDIT */
|
||||
|
||||
grant {
|
||||
permission java.io.FilePermission "c:\\foo\\bar", "read";
|
||||
permission javax.security.auth.kerberos.DelegationPermission "\"me@SOMEWHERE\" \"you@SOMEWHERE\"";
|
||||
};
|
||||
</pre>
|
||||
</ol>
|
||||
<br><br>
|
||||
|
||||
Press "Pass" if ... press "Fail" otherwise.<br><br>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,77 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 2005, 2013, 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 6296772 6293981 6290216 8015276
|
||||
# @summary FilePermission and DelegationPermission, and cancel button
|
||||
#
|
||||
# @run applet/manual=done ChangeUI.html
|
||||
# @run shell ChangeUI.sh
|
||||
# @run applet/manual=yesno ChangeUI.html
|
||||
|
||||
# set a few environment variables so that the shell-script can run stand-alone
|
||||
# in the source directory
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC="."
|
||||
fi
|
||||
if [ "${TESTCLASSES}" = "" ] ; then
|
||||
TESTCLASSES="."
|
||||
fi
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
echo "TESTJAVA not set. Test cannot execute."
|
||||
echo "FAILED!!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux | Darwin | AIX )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
;;
|
||||
CYGWIN* )
|
||||
NULL=/dev/null
|
||||
PS=";"
|
||||
FS="/"
|
||||
;;
|
||||
Windows* )
|
||||
NULL=NUL
|
||||
PS=";"
|
||||
FS="\\"
|
||||
;;
|
||||
* )
|
||||
echo "Unrecognized system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
# the test code
|
||||
|
||||
echo "HELLO!"
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}policytool
|
||||
|
||||
exit $?
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
<applet width=100 height=100 code=OpenPolicy.class>
|
||||
</applet>
|
||||
|
||||
This is a multi-stage test. Click on "done" when you have completed
|
||||
reading these instructions.<br><br>
|
||||
|
||||
First, policytool will be invoked.<br><br>
|
||||
|
||||
Pull down 'File' menu and select 'View Warning Log', which shows that
|
||||
the default Policy File is not found. On Windows, if the file name
|
||||
has the File separator character pointing the wrong way, like:<br><br>
|
||||
|
||||
C:\windows/java.policy<br><br>
|
||||
|
||||
Then the bug fix failed.
|
||||
Otherwise, the bug fix succeeded.
|
||||
|
||||
Exit policytool.<br><br>
|
||||
|
||||
Press "Pass" if ... press "Fail" otherwise.<br><br>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,77 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 1999, 2013, 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 4224186
|
||||
# @summary missing File.separatorChar when initially opening policy file
|
||||
#
|
||||
# @run applet/manual=done OpenPolicy.html
|
||||
# @run shell OpenPolicy.sh
|
||||
# @run applet/manual=yesno OpenPolicy.html
|
||||
|
||||
# set a few environment variables so that the shell-script can run stand-alone
|
||||
# in the source directory
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC="."
|
||||
fi
|
||||
if [ "${TESTCLASSES}" = "" ] ; then
|
||||
TESTCLASSES="."
|
||||
fi
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
echo "TESTJAVA not set. Test cannot execute."
|
||||
echo "FAILED!!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux | Darwin | AIX )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
;;
|
||||
CYGWIN* )
|
||||
NULL=/dev/null
|
||||
PS=";"
|
||||
FS="/"
|
||||
;;
|
||||
Windows* )
|
||||
NULL=NUL
|
||||
PS=";"
|
||||
FS="\\"
|
||||
;;
|
||||
* )
|
||||
echo "Unrecognized system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
# the test code
|
||||
|
||||
echo "HELLO!"
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}policytool
|
||||
|
||||
exit $?
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
<applet width=100 height=100 code=SaveAs.class>
|
||||
</applet>
|
||||
|
||||
This is a multi-stage test. Click on "done" when you have completed
|
||||
reading these instructions.<br><br>
|
||||
|
||||
First, policytool will be invoked.<br><br>
|
||||
|
||||
Then, go to the "File" menu, and select, "New".<br>
|
||||
Next, go back to the "File" menu, and select, "Save".<br>
|
||||
If you get the "Save As" File window, where you can enter<br>
|
||||
a new filename, then the bug fix succeeded.<br>
|
||||
If you get a FileNotFoundException, then the bug fix failed.<br><br>
|
||||
|
||||
If you are at the "Save As" File window, click on "Cancel"
|
||||
and exit policytool.<br>
|
||||
Otherwise, if you see an Exception window, click on "OK"
|
||||
and exit policytool.<br><br>
|
||||
|
||||
Press "Pass" if ... press "Fail" otherwise.<br><br>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,78 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 1999, 2013, 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 4252583
|
||||
# @summary policytool throws FileNotFoundException when user tries to
|
||||
# save new policy file
|
||||
#
|
||||
# @run applet/manual=done SaveAs.html
|
||||
# @run shell SaveAs.sh
|
||||
# @run applet/manual=yesno SaveAs.html
|
||||
|
||||
# set a few environment variables so that the shell-script can run stand-alone
|
||||
# in the source directory
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC="."
|
||||
fi
|
||||
if [ "${TESTCLASSES}" = "" ] ; then
|
||||
TESTCLASSES="."
|
||||
fi
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
echo "TESTJAVA not set. Test cannot execute."
|
||||
echo "FAILED!!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux | Darwin | AIX )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
;;
|
||||
CYGWIN* )
|
||||
NULL=/dev/null
|
||||
PS=";"
|
||||
FS="/"
|
||||
;;
|
||||
Windows* )
|
||||
NULL=NUL
|
||||
PS=";"
|
||||
FS="\\"
|
||||
;;
|
||||
* )
|
||||
echo "Unrecognized system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
# the test code
|
||||
|
||||
echo "HELLO!"
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}policytool
|
||||
|
||||
exit $?
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
<html>
|
||||
<body>
|
||||
|
||||
<applet width=100 height=100 code=UpdatePermissions.class>
|
||||
</applet>
|
||||
|
||||
This is a multi-stage test. Click on "done" when you have completed
|
||||
reading these instructions.<br><br>
|
||||
|
||||
First, policytool will be invoked.<br><br>
|
||||
|
||||
Then, follow these steps:<br>
|
||||
0) Find (or create) a temporary directory that you have write access to.
|
||||
(Example: 'C:\foo\tmp' on Windows or '/tmp' on other systems)<br><br>
|
||||
|
||||
1) Click on the "Add Policy Entry" button in the
|
||||
main policytool window.<br><br>
|
||||
|
||||
2) Click on the "Add Permission" button in the Policy Entry window.<br><br>
|
||||
|
||||
3) In the Permission window, pull down the "Permission" menu and
|
||||
select "AWTPermission".<br><br>
|
||||
|
||||
4) In the Permission window, pull down the "Target Name" menu and
|
||||
select "listenToAllAWTEvents".<br><br>
|
||||
|
||||
5) Click on the "OK" button in the Permission window.<br><br>
|
||||
|
||||
6) Click on the "Done" button in the Policy Entry window.<br><br>
|
||||
|
||||
7) In the main policytool window, pull down the "File" menu and
|
||||
select "Save As".<br><br>
|
||||
|
||||
8) In the SaveAs window, enter "/tmp/ptool.test" as the file name
|
||||
and save it. If the file already exists, just replace it.<br>
|
||||
(Or use the temporary directory mentioned in Step 0 if it's not '/tmp'.
|
||||
For example, "C:\foo\tmp\ptool.test" on Windows)<br><br>
|
||||
|
||||
9) Check the content of the file created in the previous step<br><br>
|
||||
|
||||
10) check to make sure that the new entry is in the policy file.<br><br>
|
||||
|
||||
11) repeat steps 1-10 for:<br>
|
||||
AWTPermission: readDisplayPixels<br>
|
||||
NetPermission: specifyStreamHandler<br>
|
||||
RuntimePermission: setContextClassLoader,
|
||||
setSecurityManager,
|
||||
shutdownHooks,
|
||||
stopThread<br>
|
||||
SecurityPermission: createAccessControlContext<br><br>
|
||||
|
||||
In the confirmation dialog pop-up, click "OK".<br><br>
|
||||
|
||||
Exit policytool. Delete the files created during this test. If the
|
||||
temporary directory is also newly created, empty and delete it.<br><br>
|
||||
|
||||
Press "Pass" if ... press "Fail" otherwise.<br><br>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
// This trivial file is only necessary to display instructions and "pass/fail"
|
||||
// buttons for a manual test.
|
||||
public class UpdatePermissions extends java.applet.Applet
|
||||
{
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
#
|
||||
# Copyright (c) 1999, 2013, 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 4218206
|
||||
# @bug 8015276
|
||||
# @summary missing or invalid permission target names in policy tool
|
||||
#
|
||||
# @run applet/manual=done UpdatePermissions.html
|
||||
# @run shell UpdatePermissions.sh
|
||||
# @run applet/manual=yesno UpdatePermissions.html
|
||||
|
||||
# set a few environment variables so that the shell-script can run stand-alone
|
||||
# in the source directory
|
||||
if [ "${TESTSRC}" = "" ] ; then
|
||||
TESTSRC="."
|
||||
fi
|
||||
if [ "${TESTCLASSES}" = "" ] ; then
|
||||
TESTCLASSES="."
|
||||
fi
|
||||
if [ "${TESTJAVA}" = "" ] ; then
|
||||
echo "TESTJAVA not set. Test cannot execute."
|
||||
echo "FAILED!!!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# set platform-dependent variables
|
||||
OS=`uname -s`
|
||||
case "$OS" in
|
||||
SunOS | Linux | Darwin | AIX )
|
||||
NULL=/dev/null
|
||||
PS=":"
|
||||
FS="/"
|
||||
;;
|
||||
CYGWIN* )
|
||||
NULL=/dev/null
|
||||
PS=";"
|
||||
FS="/"
|
||||
;;
|
||||
Windows* )
|
||||
NULL=NUL
|
||||
PS=";"
|
||||
FS="\\"
|
||||
;;
|
||||
* )
|
||||
echo "Unrecognized system!"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
|
||||
# the test code
|
||||
|
||||
echo "HELLO!"
|
||||
|
||||
${TESTJAVA}${FS}bin${FS}policytool
|
||||
|
||||
exit $?
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue