From a57b0dd1c8e4b54376e3feba60ed2234cbd3c11f Mon Sep 17 00:00:00 2001 From: Artem Smotrakov Date: Fri, 17 Jul 2015 17:30:55 -0700 Subject: [PATCH 1/6] 8075297: Tests for RFEs 4515853 and 4745056 Reviewed-by: weijun --- jdk/test/sun/security/krb5/auto/BogusKDC.java | 118 ++++++++++++++++++ jdk/test/sun/security/krb5/auto/Helper.java | 57 +++++++++ jdk/test/sun/security/krb5/auto/KDC.java | 19 ++- .../security/krb5/auto/RefreshKrb5Config.java | 100 +++++++++++++++ .../security/krb5/auto/refreshKrb5Config.jaas | 11 ++ 5 files changed, 301 insertions(+), 4 deletions(-) create mode 100644 jdk/test/sun/security/krb5/auto/BogusKDC.java create mode 100644 jdk/test/sun/security/krb5/auto/Helper.java create mode 100644 jdk/test/sun/security/krb5/auto/RefreshKrb5Config.java create mode 100644 jdk/test/sun/security/krb5/auto/refreshKrb5Config.jaas diff --git a/jdk/test/sun/security/krb5/auto/BogusKDC.java b/jdk/test/sun/security/krb5/auto/BogusKDC.java new file mode 100644 index 00000000000..15d9adddd37 --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/BogusKDC.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2015, 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. + */ + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.HashMap; +import java.util.Map; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 4515853 8075297 + * @summary Checks that Kerberos client tries slave KDC + * if master KDC is not responding + * @run main/othervm BogusKDC + */ +public class BogusKDC { + + static final String TEST_SRC = System.getProperty("test.src", "."); + static final String HOST = "localhost"; + static final String NOT_EXISTING_HOST = "not.existing.host"; + static final String REALM = "TEST.REALM"; + static final String USER = "USER"; + static final String USER_PRINCIPAL = USER + "@" + REALM; + static final String USER_PASSWORD = "password"; + static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + static final String KRB5_CONF = "krb5.conf"; + static final int WRONG_KDC_PORT = 21; + + static final String KRB5_CONF_TEMPLATE = "" + + "[libdefaults]\n" + + "default_realm = TEST.REALM\n" + + "max_retries = 1\n" + + "\n" + + "[realms]\n" + + "TEST.REALM = {\n" + + " kdc = %s\n" + + " kdc = localhost:%d\n" + + "}"; + + public static void main(String[] args) throws LoginException, IOException { + Map principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, USER_PASSWORD); + principals.put(KRBTGT_PRINCIPAL, null); + + System.setProperty("java.security.krb5.conf", KRB5_CONF); + + // start a local KDC + KDC kdc = KDC.startKDC(HOST, KRB5_CONF, REALM, principals, null, null); + + System.setProperty("java.security.auth.login.config", + TEST_SRC + File.separator + "refreshKrb5Config.jaas"); + + CallbackHandler handler = new Helper.UserPasswordHandler( + USER, USER_PASSWORD); + + // create a krb5 config with non-existing host for master KDC, + // and wrong port for slave KDC + try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) { + w.write(String.format(KRB5_CONF_TEMPLATE, + KDC.KDCNameService.NOT_EXISTING_HOST, WRONG_KDC_PORT)); + w.flush(); + } + + // login with not-refreshable config + try { + new LoginContext("NotRefreshable", handler).login(); + throw new RuntimeException("Expected exception not thrown"); + } catch (LoginException le) { + System.out.println("Expected login failure: " + le); + } + + // create a krb5 config with non-existing host for master KDC, + // but correct port for slave KDC + try (PrintWriter w = new PrintWriter(new FileWriter(KRB5_CONF))) { + w.write(String.format(KRB5_CONF_TEMPLATE, + KDC.KDCNameService.NOT_EXISTING_HOST, kdc.getPort())); + w.flush(); + } + + // login with not-refreshable config + try { + new LoginContext("NotRefreshable", handler).login(); + throw new RuntimeException("Expected exception not thrown"); + } catch (LoginException le) { + System.out.println("Expected login failure: " + le); + } + + // login with refreshable config + new LoginContext("Refreshable", handler).login(); + + System.out.println("Test passed"); + } +} diff --git a/jdk/test/sun/security/krb5/auto/Helper.java b/jdk/test/sun/security/krb5/auto/Helper.java new file mode 100644 index 00000000000..ff43c0b3a41 --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/Helper.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, 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. + */ + +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; + +public class Helper { + + static class UserPasswordHandler implements CallbackHandler { + + private final String name; + private final String password; + + UserPasswordHandler(String name, String password) { + this.name = name; + this.password = password; + } + + @Override + public void handle(Callback[] callbacks) + throws UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof PasswordCallback) { + ((PasswordCallback) callback).setPassword( + password.toCharArray()); + } else if (callback instanceof NameCallback) { + ((NameCallback)callback).setName(name); + } else { + throw new UnsupportedCallbackException(callback); + } + } + } + } +} diff --git a/jdk/test/sun/security/krb5/auto/KDC.java b/jdk/test/sun/security/krb5/auto/KDC.java index 7488fa53ec4..51b2fcfa8d6 100644 --- a/jdk/test/sun/security/krb5/auto/KDC.java +++ b/jdk/test/sun/security/krb5/auto/KDC.java @@ -1320,14 +1320,17 @@ public class KDC { } } - public static void startKDC(final String host, final String krbConfFileName, + public static KDC startKDC(final String host, final String krbConfFileName, final String realm, final Map principals, final String ktab, final KtabMode mode) { + KDC kdc; try { - KDC kdc = KDC.create(realm, host, 0, true); + kdc = KDC.create(realm, host, 0, true); kdc.setOption(KDC.Option.PREAUTH_REQUIRED, Boolean.FALSE); - KDC.saveConfig(krbConfFileName, kdc); + if (krbConfFileName != null) { + KDC.saveConfig(krbConfFileName, kdc); + } // Add principals if (principals != null) { @@ -1379,6 +1382,7 @@ public class KDC { throw new RuntimeException("KDC: unexpected exception", e); } + return kdc; } /** @@ -1428,13 +1432,20 @@ public class KDC { } public static class KDCNameService implements NameServiceDescriptor { + + public static String NOT_EXISTING_HOST = "not.existing.host"; + @Override public NameService createNameService() throws Exception { NameService ns = new NameService() { @Override public InetAddress[] lookupAllHostAddr(String host) throws UnknownHostException { - // Everything is localhost + // Everything is localhost except NOT_EXISTING_HOST + if (NOT_EXISTING_HOST.equals(host)) { + throw new UnknownHostException("Unknown host name: " + + NOT_EXISTING_HOST); + } return new InetAddress[]{ InetAddress.getByAddress(host, new byte[]{127,0,0,1}) }; diff --git a/jdk/test/sun/security/krb5/auto/RefreshKrb5Config.java b/jdk/test/sun/security/krb5/auto/RefreshKrb5Config.java new file mode 100644 index 00000000000..c32258f268c --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/RefreshKrb5Config.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2015, 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. + */ + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/* + * @test + * @bug 4745056 8075297 + * @summary Checks if refreshKrb5Config is set to true for Krb5LoginModule, + * then configuration will be refreshed before login() method is called + * @run main/othervm RefreshKrb5Config + */ +public class RefreshKrb5Config { + + static final String TEST_SRC = System.getProperty("test.src", "."); + static final String HOST = "localhost"; + static final String NOT_EXISTING_HOST = "not.existing.host"; + static final String REALM = "TEST.REALM"; + static final String USER = "USER"; + static final String USER_PRINCIPAL = USER + "@" + REALM; + static final String USER_PASSWORD = "password"; + static final String KRBTGT_PRINCIPAL = "krbtgt/" + REALM; + static final String KRB5_CONF_FILENAME = "krb5.conf"; + + public static void main(String[] args) throws LoginException, IOException { + Map principals = new HashMap<>(); + principals.put(USER_PRINCIPAL, USER_PASSWORD); + principals.put(KRBTGT_PRINCIPAL, null); + + System.setProperty("java.security.krb5.conf", KRB5_CONF_FILENAME); + + // start a local KDC, and save krb5 config + KDC kdc = KDC.startKDC(HOST, null, REALM, principals, null, null); + KDC.saveConfig(KRB5_CONF_FILENAME, kdc, "max_retries = 1"); + + System.setProperty("java.security.auth.login.config", + TEST_SRC + File.separator + "refreshKrb5Config.jaas"); + + CallbackHandler handler = new Helper.UserPasswordHandler( + USER, USER_PASSWORD); + + // set incorrect KDC + System.out.println("java.security.krb5.kdc = " + NOT_EXISTING_HOST); + System.setProperty("java.security.krb5.kdc", NOT_EXISTING_HOST); + System.out.println("java.security.krb5.realm = " + REALM); + System.setProperty("java.security.krb5.realm", REALM); + try { + new LoginContext("Refreshable", handler).login(); + throw new RuntimeException("Expected exception not thrown"); + } catch (LoginException le) { + System.out.println("Expected login failure: " + le); + } + + // reset properties + System.out.println("Reset java.security.krb5.kdc"); + System.clearProperty("java.security.krb5.kdc"); + System.out.println("Reset java.security.krb5.realm"); + System.clearProperty("java.security.krb5.realm"); + + // login with not-refreshable config + try { + new LoginContext("NotRefreshable", handler).login(); + throw new RuntimeException("Expected exception not thrown"); + } catch (LoginException le) { + System.out.println("Expected login failure: " + le); + } + + // login with refreshable config + new LoginContext("Refreshable", handler).login(); + + System.out.println("Test passed"); + } + +} diff --git a/jdk/test/sun/security/krb5/auto/refreshKrb5Config.jaas b/jdk/test/sun/security/krb5/auto/refreshKrb5Config.jaas new file mode 100644 index 00000000000..fd3b60d86a8 --- /dev/null +++ b/jdk/test/sun/security/krb5/auto/refreshKrb5Config.jaas @@ -0,0 +1,11 @@ +Refreshable { + com.sun.security.auth.module.Krb5LoginModule required + useTicketCache=false + refreshKrb5Config=true; +}; + +NotRefreshable { + com.sun.security.auth.module.Krb5LoginModule required + useTicketCache=false + refreshKrb5Config=false; +}; From d9cbd23d508768f4b48a10eb92f2e405c406522a Mon Sep 17 00:00:00 2001 From: Michael Haupt Date: Fri, 17 Jul 2015 08:10:41 +0200 Subject: [PATCH 2/6] 8062543: Replace uses of MethodHandleImpl.castReference with Class.cast Reviewed-by: psandoz, vlivanov --- .../lang/invoke/InvokerBytecodeGenerator.java | 5 ++- .../java/lang/invoke/MethodHandleImpl.java | 36 +++++-------------- 2 files changed, 11 insertions(+), 30 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 6698d9da36e..2c94e081568 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2015, 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 @@ -61,7 +61,6 @@ class InvokerBytecodeGenerator { private static final String LFN_SIG = "L" + LFN + ";"; private static final String LL_SIG = "(L" + OBJ + ";)L" + OBJ + ";"; private static final String LLV_SIG = "(L" + OBJ + ";L" + OBJ + ";)V"; - private static final String CLL_SIG = "(L" + CLS + ";L" + OBJ + ";)L" + OBJ + ";"; /** Name of its super class*/ private static final String superName = OBJ; @@ -571,7 +570,7 @@ class InvokerBytecodeGenerator { mv.visitLdcInsn(constantPlaceholder(cls)); mv.visitTypeInsn(Opcodes.CHECKCAST, CLS); mv.visitInsn(Opcodes.SWAP); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "castReference", CLL_SIG, false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CLS, "cast", LL_SIG, false); if (Object[].class.isAssignableFrom(cls)) mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY); else if (PROFILE_LEVEL > 0) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index 4de3439d0a4..3fad3315ea1 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, 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 @@ -219,7 +219,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; if (convSpec == null) continue; MethodHandle fn; if (convSpec instanceof Class) { - fn = Lazy.MH_castReference.bindTo(convSpec); + fn = Lazy.MH_cast.bindTo(convSpec); } else { fn = (MethodHandle) convSpec; } @@ -239,7 +239,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; if (convSpec == void.class) fn = null; else - fn = Lazy.MH_castReference.bindTo(convSpec); + fn = Lazy.MH_cast.bindTo(convSpec); } else { fn = (MethodHandle) convSpec; } @@ -302,7 +302,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; Name conv; if (convSpec instanceof Class) { Class convClass = (Class) convSpec; - conv = new Name(Lazy.MH_castReference, convClass, names[INARG_BASE + i]); + conv = new Name(Lazy.MH_cast, convClass, names[INARG_BASE + i]); } else { MethodHandle fn = (MethodHandle) convSpec; conv = new Name(fn, names[INARG_BASE + i]); @@ -326,7 +326,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; conv = new Name(LambdaForm.constantZero(BasicType.basicType(srcType.returnType()))); } else if (convSpec instanceof Class) { Class convClass = (Class) convSpec; - conv = new Name(Lazy.MH_castReference, convClass, names[OUT_CALL]); + conv = new Name(Lazy.MH_cast, convClass, names[OUT_CALL]); } else { MethodHandle fn = (MethodHandle) convSpec; if (fn.type().parameterCount() == 0) @@ -343,25 +343,6 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; return SimpleMethodHandle.make(srcType, form); } - /** - * Identity function, with reference cast. - * @param t an arbitrary reference type - * @param x an arbitrary reference value - * @return the same value x - */ - @ForceInline - @SuppressWarnings("unchecked") - static T castReference(Class t, U x) { - // inlined Class.cast because we can't ForceInline it - if (x != null && !t.isInstance(x)) - throw newClassCastException(t, x); - return (T) x; - } - - private static ClassCastException newClassCastException(Class t, Object obj) { - return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName()); - } - static Object[] computeValueConversions(MethodType srcType, MethodType dstType, boolean strict, boolean monobox) { final int INARG_COUNT = srcType.parameterCount(); @@ -591,6 +572,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; */ static class Lazy { private static final Class MHI = MethodHandleImpl.class; + private static final Class CLS = Class.class; private static final MethodHandle[] ARRAYS; private static final MethodHandle[] FILL_ARRAYS; @@ -600,7 +582,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; static final NamedFunction NF_throwException; static final NamedFunction NF_profileBoolean; - static final MethodHandle MH_castReference; + static final MethodHandle MH_cast; static final MethodHandle MH_selectAlternative; static final MethodHandle MH_copyAsPrimitiveArray; static final MethodHandle MH_fillNewTypedArray; @@ -623,8 +605,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; NF_throwException.resolve(); NF_profileBoolean.resolve(); - MH_castReference = IMPL_LOOKUP.findStatic(MHI, "castReference", - MethodType.methodType(Object.class, Class.class, Object.class)); + MH_cast = IMPL_LOOKUP.findVirtual(CLS, "cast", + MethodType.methodType(Object.class, Object.class)); MH_copyAsPrimitiveArray = IMPL_LOOKUP.findStatic(MHI, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class)); MH_arrayIdentity = IMPL_LOOKUP.findStatic(MHI, "identity", From 9866d4239de109d5f33609e01cda51b096b404e9 Mon Sep 17 00:00:00 2001 From: Weijun Wang Date: Mon, 20 Jul 2015 20:47:54 +0800 Subject: [PATCH 3/6] 8131350: policytool can directly reference permission classes Reviewed-by: xuelei, mullan --- .../security/tools/policytool/PolicyTool.java | 327 ++++++++---------- 1 file changed, 152 insertions(+), 175 deletions(-) diff --git a/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java b/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java index fde04357822..02a82d941f9 100644 --- a/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java +++ b/jdk/src/jdk.policytool/share/classes/sun/security/tools/policytool/PolicyTool.java @@ -633,17 +633,16 @@ public class PolicyTool { type.equals(PolicyParser.PrincipalEntry.REPLACE_NAME)) { return; } - Class PRIN = Class.forName("java.security.Principal"); Class pc = Class.forName(type, true, Thread.currentThread().getContextClassLoader()); - if (!PRIN.isAssignableFrom(pc)) { + if (!Principal.class.isAssignableFrom(pc)) { MessageFormat form = new MessageFormat(getMessage ("Illegal.Principal.Type.type")); Object[] source = {type}; throw new InstantiationException(form.format(source)); } - if (ToolDialog.X500_PRIN_CLASS.equals(pc.getName())) { + if (X500Principal.class.getName().equals(pc.getName())) { // PolicyParser checks validity of X500Principal name // - PolicyTool needs to as well so that it doesn't store // an invalid name that can't be read in later @@ -1563,14 +1562,6 @@ class ToolDialog extends JDialog { public static final int NEW = 2; public static final int OPEN = 3; - public static final String ALL_PERM_CLASS = - "java.security.AllPermission"; - public static final String FILE_PERM_CLASS = - "java.io.FilePermission"; - - public static final String X500_PRIN_CLASS = - "javax.security.auth.x500.X500Principal"; - /* popup menus */ public static final String PERM = PolicyTool.getMessage @@ -1752,11 +1743,11 @@ class ToolDialog extends JDialog { for (int i = 0; i < PERM_ARRAY.size(); i++) { Perm next = PERM_ARRAY.get(i); if (fullClassName) { - if (next.FULL_CLASS.equals(clazz)) { + if (next.getName().equals(clazz)) { return next; } } else { - if (next.CLASS.equals(clazz)) { + if (next.getSimpleName().equals(clazz)) { return next; } } @@ -1772,11 +1763,11 @@ class ToolDialog extends JDialog { for (int i = 0; i < PRIN_ARRAY.size(); i++) { Prin next = PRIN_ARRAY.get(i); if (fullClassName) { - if (next.FULL_CLASS.equals(clazz)) { + if (next.getName().equals(clazz)) { return next; } } else { - if (next.CLASS.equals(clazz)) { + if (next.getSimpleName().equals(clazz)) { return next; } } @@ -2170,7 +2161,7 @@ class ToolDialog extends JDialog { choice.getAccessibleContext().setAccessibleName(PRIN_TYPE); for (int i = 0; i < PRIN_ARRAY.size(); i++) { Prin next = PRIN_ARRAY.get(i); - choice.addItem(next.CLASS); + choice.addItem(next.getSimpleName()); } if (edit) { @@ -2180,7 +2171,7 @@ class ToolDialog extends JDialog { } else { Prin inputPrin = getPrin(editMe.getPrincipalClass(), true); if (inputPrin != null) { - choice.setSelectedItem(inputPrin.CLASS); + choice.setSelectedItem(inputPrin.getSimpleName()); } } } @@ -2286,7 +2277,7 @@ class ToolDialog extends JDialog { choice.getAccessibleContext().setAccessibleName(PERM); for (int i = 0; i < PERM_ARRAY.size(); i++) { Perm next = PERM_ARRAY.get(i); - choice.addItem(next.CLASS); + choice.addItem(next.getSimpleName()); } tw.addNewComponent(newTD, choice, PD_PERM_CHOICE, 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.BOTH, @@ -2300,7 +2291,7 @@ class ToolDialog extends JDialog { if (edit) { Perm inputPerm = getPerm(editMe.permission, true); if (inputPerm != null) { - choice.setSelectedItem(inputPerm.CLASS); + choice.setSelectedItem(inputPerm.getSimpleName()); } } tw.addNewComponent(newTD, tf, PD_PERM_TEXTFIELD, @@ -2417,7 +2408,7 @@ class ToolDialog extends JDialog { "\t'" + pname + "' will be interpreted " + "as a key store alias.\n" + "\tThe final principal class will be " + - ToolDialog.X500_PRIN_CLASS + ".\n" + + X500Principal.class.getName() + ".\n" + "\tThe final principal name will be " + "determined by the following:\n" + "\n" + @@ -2452,7 +2443,7 @@ class ToolDialog extends JDialog { if (tf.getText().trim().equals("") == false) name = new String(tf.getText().trim()); if (permission.equals("") || - (!permission.equals(ALL_PERM_CLASS) && name == null)) { + (!permission.equals(AllPermission.class.getName()) && name == null)) { throw new InvalidParameterException(PolicyTool.getMessage ("Permission.and.Target.Name.must.have.a.value")); } @@ -2467,7 +2458,8 @@ class ToolDialog extends JDialog { // \\server\share 0, legal // \\\\server\share 2, illegal - if (permission.equals(FILE_PERM_CLASS) && name.lastIndexOf("\\\\") > 0) { + if (permission.equals(FilePermission.class.getName()) + && name.lastIndexOf("\\\\") > 0) { char result = tw.displayYesNoDialog(this, PolicyTool.getMessage("Warning"), PolicyTool.getMessage( @@ -3645,7 +3637,7 @@ class PrincipalTypeMenuListener implements ItemListener { if (prinField.getText() != null && prinField.getText().length() > 0) { Prin inputPrin = ToolDialog.getPrin(prinField.getText(), true); - prin.setSelectedItem(inputPrin.CLASS); + prin.setSelectedItem(inputPrin.getSimpleName()); } return; } @@ -3660,7 +3652,7 @@ class PrincipalTypeMenuListener implements ItemListener { // set of names and actions Prin inputPrin = ToolDialog.getPrin((String)e.getItem(), false); if (inputPrin != null) { - prinField.setText(inputPrin.FULL_CLASS); + prinField.setText(inputPrin.getName()); } } } @@ -3711,7 +3703,7 @@ class PermissionMenuListener implements ItemListener { Perm inputPerm = ToolDialog.getPerm(permField.getText(), true); if (inputPerm != null) { - perms.setSelectedItem(inputPerm.CLASS); + perms.setSelectedItem(inputPerm.getSimpleName()); } } return; @@ -3732,7 +3724,7 @@ class PermissionMenuListener implements ItemListener { if (inputPerm == null) { permField.setText(""); } else { - permField.setText(inputPerm.FULL_CLASS); + permField.setText(inputPerm.getName()); } td.setPermissionNames(inputPerm, names, nameField); td.setPermissionActions(inputPerm, actions, actionsField); @@ -4082,26 +4074,30 @@ class TaggedList extends JList { */ class Prin { - public final String CLASS; - public final String FULL_CLASS; + final Class CLASS; - public Prin(String clazz, String fullClass) { + Prin(Class clazz) { this.CLASS = clazz; - this.FULL_CLASS = fullClass; + } + + String getName() { + return CLASS.getName(); + } + + String getSimpleName() { + return CLASS.getSimpleName(); } } class KrbPrin extends Prin { - public KrbPrin() { - super("KerberosPrincipal", - "javax.security.auth.kerberos.KerberosPrincipal"); + KrbPrin() { + super(javax.security.auth.kerberos.KerberosPrincipal.class); } } class X500Prin extends Prin { - public X500Prin() { - super("X500Principal", - "javax.security.auth.x500.X500Principal"); + X500Prin() { + super(javax.security.auth.x500.X500Principal.class); } } @@ -4110,44 +4106,48 @@ class X500Prin extends Prin { */ class Perm { - public final String CLASS; - public final String FULL_CLASS; - public final String[] TARGETS; - public final String[] ACTIONS; + final Class CLASS; + final String[] TARGETS; + final String[] ACTIONS; - public Perm(String clazz, String fullClass, + Perm(Class clazz, String[] targets, String[] actions) { this.CLASS = clazz; - this.FULL_CLASS = fullClass; this.TARGETS = targets; this.ACTIONS = actions; } + + String getName() { + return CLASS.getName(); + } + + String getSimpleName() { + return CLASS.getSimpleName(); + } } class AllPerm extends Perm { - public AllPerm() { - super("AllPermission", "java.security.AllPermission", null, null); + AllPerm() { + super(java.security.AllPermission.class, null, null); } } class AudioPerm extends Perm { - public AudioPerm() { - super("AudioPermission", - "javax.sound.sampled.AudioPermission", - new String[] { + AudioPerm() { + super(javax.sound.sampled.AudioPermission.class, + new String[] { "play", "record" }, - null); + null); } } class AuthPerm extends Perm { - public AuthPerm() { - super("AuthPermission", - "javax.security.auth.AuthPermission", - new String[] { + AuthPerm() { + super(javax.security.auth.AuthPermission.class, + new String[] { "doAs", "doAsPrivileged", "getSubject", @@ -4165,15 +4165,14 @@ class AuthPerm extends Perm { PolicyTool.getMessage("configuration.type") + ">", "refreshLoginConfiguration" }, - null); + null); } } class AWTPerm extends Perm { - public AWTPerm() { - super("AWTPermission", - "java.awt.AWTPermission", - new String[] { + AWTPerm() { + super(java.awt.AWTPermission.class, + new String[] { "accessClipboard", "accessEventQueue", "accessSystemTray", @@ -4187,30 +4186,28 @@ class AWTPerm extends Perm { "showWindowWithoutWarningBanner", "toolkitModality", "watchMousePointer" - }, - null); + }, + null); } } class DelegationPerm extends Perm { - public DelegationPerm() { - super("DelegationPermission", - "javax.security.auth.kerberos.DelegationPermission", - new String[] { + DelegationPerm() { + super(javax.security.auth.kerberos.DelegationPermission.class, + new String[] { // allow user input }, - null); + null); } } class FilePerm extends Perm { - public FilePerm() { - super("FilePermission", - "java.io.FilePermission", - new String[] { + FilePerm() { + super(java.io.FilePermission.class, + new String[] { "<>" }, - new String[] { + new String[] { "read", "write", "delete", @@ -4220,64 +4217,59 @@ class FilePerm extends Perm { } class URLPerm extends Perm { - public URLPerm() { - super("URLPermission", - "java.net.URLPermission", - new String[] { - "<"+ PolicyTool.getMessage("url") + ">", - }, - new String[] { - "<" + PolicyTool.getMessage("method.list") + ">:<" - + PolicyTool.getMessage("request.headers.list") + ">", - }); + URLPerm() { + super(java.net.URLPermission.class, + new String[] { + "<"+ PolicyTool.getMessage("url") + ">", + }, + new String[] { + "<" + PolicyTool.getMessage("method.list") + ">:<" + + PolicyTool.getMessage("request.headers.list") + ">", + }); } } class InqSecContextPerm extends Perm { - public InqSecContextPerm() { - super("InquireSecContextPermission", - "com.sun.security.jgss.InquireSecContextPermission", - new String[] { + InqSecContextPerm() { + super(com.sun.security.jgss.InquireSecContextPermission.class, + new String[] { "KRB5_GET_SESSION_KEY", "KRB5_GET_TKT_FLAGS", "KRB5_GET_AUTHZ_DATA", "KRB5_GET_AUTHTIME" }, - null); + null); } } class LogPerm extends Perm { - public LogPerm() { - super("LoggingPermission", - "java.util.logging.LoggingPermission", - new String[] { + LogPerm() { + super(java.util.logging.LoggingPermission.class, + new String[] { "control" }, - null); + null); } } class MgmtPerm extends Perm { - public MgmtPerm() { - super("ManagementPermission", - "java.lang.management.ManagementPermission", - new String[] { + MgmtPerm() { + super(java.lang.management.ManagementPermission.class, + new String[] { "control", "monitor" }, - null); + null); } } class MBeanPerm extends Perm { - public MBeanPerm() { - super("MBeanPermission", - "javax.management.MBeanPermission", - new String[] { + MBeanPerm() { + super(javax.management.MBeanPermission.class, + new String[] { // allow user input }, - new String[] { + new String[] { "addNotificationListener", "getAttribute", "getClassLoader", @@ -4300,35 +4292,32 @@ class MBeanPerm extends Perm { } class MBeanSvrPerm extends Perm { - public MBeanSvrPerm() { - super("MBeanServerPermission", - "javax.management.MBeanServerPermission", - new String[] { + MBeanSvrPerm() { + super(javax.management.MBeanServerPermission.class, + new String[] { "createMBeanServer", "findMBeanServer", "newMBeanServer", "releaseMBeanServer" }, - null); + null); } } class MBeanTrustPerm extends Perm { - public MBeanTrustPerm() { - super("MBeanTrustPermission", - "javax.management.MBeanTrustPermission", - new String[] { + MBeanTrustPerm() { + super(javax.management.MBeanTrustPermission.class, + new String[] { "register" }, - null); + null); } } class NetPerm extends Perm { - public NetPerm() { - super("NetPermission", - "java.net.NetPermission", - new String[] { + NetPerm() { + super(java.net.NetPermission.class, + new String[] { "allowHttpTrace", "setDefaultAuthenticator", "requestPasswordAuthentication", @@ -4341,43 +4330,40 @@ class NetPerm extends Perm { "setResponseCache", "getResponseCache" }, - null); + null); } } class NetworkPerm extends Perm { - public NetworkPerm() { - super("NetworkPermission", - "jdk.net.NetworkPermission", - new String[] { + NetworkPerm() { + super(jdk.net.NetworkPermission.class, + new String[] { "setOption.SO_FLOW_SLA", "getOption.SO_FLOW_SLA" }, - null); + null); } } class PrivCredPerm extends Perm { - public PrivCredPerm() { - super("PrivateCredentialPermission", - "javax.security.auth.PrivateCredentialPermission", - new String[] { + PrivCredPerm() { + super(javax.security.auth.PrivateCredentialPermission.class, + new String[] { // allow user input }, - new String[] { + new String[] { "read" }); } } class PropPerm extends Perm { - public PropPerm() { - super("PropertyPermission", - "java.util.PropertyPermission", - new String[] { + PropPerm() { + super(java.util.PropertyPermission.class, + new String[] { // allow user input }, - new String[] { + new String[] { "read", "write" }); @@ -4385,21 +4371,19 @@ class PropPerm extends Perm { } class ReflectPerm extends Perm { - public ReflectPerm() { - super("ReflectPermission", - "java.lang.reflect.ReflectPermission", - new String[] { + ReflectPerm() { + super(java.lang.reflect.ReflectPermission.class, + new String[] { "suppressAccessChecks" }, - null); + null); } } class RuntimePerm extends Perm { - public RuntimePerm() { - super("RuntimePermission", - "java.lang.RuntimePermission", - new String[] { + RuntimePerm() { + super(java.lang.RuntimePermission.class, + new String[] { "createClassLoader", "getClassLoader", "setContextClassLoader", @@ -4432,15 +4416,14 @@ class RuntimePerm extends Perm { "usePolicy", // "inheritedChannel" }, - null); + null); } } class SecurityPerm extends Perm { - public SecurityPerm() { - super("SecurityPermission", - "java.security.SecurityPermission", - new String[] { + SecurityPerm() { + super(java.security.SecurityPermission.class, + new String[] { "createAccessControlContext", "getDomainCombiner", "getPolicy", @@ -4470,30 +4453,28 @@ class SecurityPerm extends Perm { //"getSignerPrivateKey", //"setSignerKeyPair" }, - null); + null); } } class SerialPerm extends Perm { - public SerialPerm() { - super("SerializablePermission", - "java.io.SerializablePermission", - new String[] { + SerialPerm() { + super(java.io.SerializablePermission.class, + new String[] { "enableSubclassImplementation", "enableSubstitution" }, - null); + null); } } class ServicePerm extends Perm { - public ServicePerm() { - super("ServicePermission", - "javax.security.auth.kerberos.ServicePermission", - new String[] { + ServicePerm() { + super(javax.security.auth.kerberos.ServicePermission.class, + new String[] { // allow user input }, - new String[] { + new String[] { "initiate", "accept" }); @@ -4501,13 +4482,12 @@ class ServicePerm extends Perm { } class SocketPerm extends Perm { - public SocketPerm() { - super("SocketPermission", - "java.net.SocketPermission", - new String[] { + SocketPerm() { + super(java.net.SocketPermission.class, + new String[] { // allow user input }, - new String[] { + new String[] { "accept", "connect", "listen", @@ -4517,38 +4497,35 @@ class SocketPerm extends Perm { } class SQLPerm extends Perm { - public SQLPerm() { - super("SQLPermission", - "java.sql.SQLPermission", - new String[] { + SQLPerm() { + super(java.sql.SQLPermission.class, + new String[] { "setLog", "callAbort", "setSyncFactory", "setNetworkTimeout", }, - null); + null); } } class SSLPerm extends Perm { - public SSLPerm() { - super("SSLPermission", - "javax.net.ssl.SSLPermission", - new String[] { + SSLPerm() { + super(javax.net.ssl.SSLPermission.class, + new String[] { "setHostnameVerifier", "getSSLSessionContext" }, - null); + null); } } class SubjDelegPerm extends Perm { - public SubjDelegPerm() { - super("SubjectDelegationPermission", - "javax.management.remote.SubjectDelegationPermission", - new String[] { + SubjDelegPerm() { + super(javax.management.remote.SubjectDelegationPermission.class, + new String[] { // allow user input }, - null); + null); } } From 981dbca21aadd67b3504f079770f2647e70fa446 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Mon, 20 Jul 2015 09:03:03 -0400 Subject: [PATCH 4/6] 8131486: SecureClassLoader key for ProtectionDomain cache also needs to take into account certificates Reviewed-by: weijun --- .../classes/java/security/CodeSource.java | 2 +- .../java/security/SecureClassLoader.java | 57 +++-- .../SecureClassLoader/DefineClass.java | 219 ++++++++++++++++-- .../SecureClassLoader/DefineClass.policy | 7 +- 4 files changed, 254 insertions(+), 31 deletions(-) diff --git a/jdk/src/java.base/share/classes/java/security/CodeSource.java b/jdk/src/java.base/share/classes/java/security/CodeSource.java index c08050a9f03..6c922aad441 100644 --- a/jdk/src/java.base/share/classes/java/security/CodeSource.java +++ b/jdk/src/java.base/share/classes/java/security/CodeSource.java @@ -339,7 +339,7 @@ public class CodeSource implements java.io.Serializable { * @param strict If true then a strict equality match is performed. * Otherwise a subset match is performed. */ - private boolean matchCerts(CodeSource that, boolean strict) + boolean matchCerts(CodeSource that, boolean strict) { boolean match; diff --git a/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java index 56d98363dd9..eee1e0bb7fe 100644 --- a/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java +++ b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java @@ -25,9 +25,10 @@ package java.security; -import java.util.Map; -import java.util.ArrayList; import java.net.URL; +import java.util.ArrayList; +import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; @@ -50,15 +51,15 @@ public class SecureClassLoader extends ClassLoader { private final boolean initialized; /* - * Map that maps the CodeSource URL (as a String) to ProtectionDomain. - * We use a String instead of a CodeSource/URL as the key to avoid + * Map that maps the CodeSource to a ProtectionDomain. The key is a + * CodeSourceKey class that uses a String instead of a URL to avoid * potential expensive name service lookups. This does mean that URLs that * are equivalent after nameservice lookup will be placed in separate * ProtectionDomains; however during policy enforcement these URLs will be * canonicalized and resolved resulting in a consistent set of granted * permissions. */ - private final Map pdcache + private final Map pdcache = new ConcurrentHashMap<>(11); private static final Debug debug = Debug.getInstance("scl"); @@ -209,17 +210,14 @@ public class SecureClassLoader extends ClassLoader { return null; } - // Use a String form of the URL as the key. It should behave in the - // same manner as the URL when compared for equality except that no - // nameservice lookup is done on the hostname (String comparison + // Use a CodeSourceKey object key. It should behave in the + // same manner as the CodeSource when compared for equality except + // that no nameservice lookup is done on the hostname (String comparison // only), and the fragment is not considered. - String key = cs.getLocationNoFragString(); - if (key == null) { - key = ""; - } + CodeSourceKey key = new CodeSourceKey(cs); return pdcache.computeIfAbsent(key, new Function<>() { @Override - public ProtectionDomain apply(String key /* not used */) { + public ProtectionDomain apply(CodeSourceKey key /* not used */) { PermissionCollection perms = SecureClassLoader.this.getPermissions(cs); ProtectionDomain pd = new ProtectionDomain( @@ -242,4 +240,37 @@ public class SecureClassLoader extends ClassLoader { } } + private static class CodeSourceKey { + private final CodeSource cs; + + CodeSourceKey(CodeSource cs) { + this.cs = cs; + } + + @Override + public int hashCode() { + String locationNoFrag = cs.getLocationNoFragString(); + return locationNoFrag != null ? locationNoFrag.hashCode() : 0; + } + + @Override + public boolean equals(Object obj) { + if (obj == this) { + return true; + } + + if (!(obj instanceof CodeSourceKey)) { + return false; + } + + CodeSourceKey csk = (CodeSourceKey) obj; + + if (!Objects.equals(cs.getLocationNoFragString(), + csk.cs.getLocationNoFragString())) { + return false; + } + + return cs.matchCerts(csk.cs, true); + } + } } diff --git a/jdk/test/java/security/SecureClassLoader/DefineClass.java b/jdk/test/java/security/SecureClassLoader/DefineClass.java index c54ef2215cd..33efdb0e648 100644 --- a/jdk/test/java/security/SecureClassLoader/DefineClass.java +++ b/jdk/test/java/security/SecureClassLoader/DefineClass.java @@ -21,28 +21,44 @@ * questions. */ +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.InputStream; import java.io.IOException; +import java.io.OutputStream; import java.net.URL; import java.security.CodeSource; +import java.security.Key; +import java.security.KeyStoreException; +import java.security.KeyStoreSpi; +import java.security.NoSuchAlgorithmException; import java.security.Permission; import java.security.Policy; import java.security.ProtectionDomain; +import java.security.Provider; import java.security.SecureClassLoader; +import java.security.Security; +import java.security.UnrecoverableKeyException; +import java.security.URIParameter; import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; import java.util.List; import java.util.PropertyPermission; /* * @test - * @bug 6826789 + * @bug 6826789 8131486 * @summary Make sure equivalent ProtectionDomains are granted the same * permissions when the CodeSource URLs are different but resolve * to the same ip address after name service resolution. - * @run main/othervm/java.security.policy=DefineClass.policy DefineClass + * @run main/othervm DefineClass */ public class DefineClass { @@ -53,42 +69,100 @@ public class DefineClass { new PropertyPermission("user.name", "read") }; - // Base64 encoded bytes of a simple class: "public class Foo {}" + // Base64 encoded bytes of simple class: "package foo; public class Foo {}" private final static String FOO_CLASS = - "yv66vgAAADQADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" + + "yv66vgAAADMADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" + "D0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAhGb28uamF2YQwABAAF" + - "AQADRm9vAQAQamF2YS9sYW5nL09iamVjdAAhAAIAAwAAAAAAAQABAAQABQAB" + - "AAYAAAAdAAEAAQAAAAUqtwABsQAAAAEABwAAAAYAAQAAAAEAAQAIAAAAAgAJ"; + "AQAHZm9vL0ZvbwEAEGphdmEvbGFuZy9PYmplY3QAIQACAAMAAAAAAAEAAQAE" + + "AAUAAQAGAAAAHQABAAEAAAAFKrcAAbEAAAABAAcAAAAGAAEAAAABAAEACAAA" + + "AAIACQ=="; - // Base64 encoded bytes of a simple class: "public class Bar {}" + // Base64 encoded bytes of simple class: "package bar; public class Bar {}" private final static String BAR_CLASS = - "yv66vgAAADQADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" + + "yv66vgAAADMADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" + "D0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAhCYXIuamF2YQwABAAF" + - "AQADQmFyAQAQamF2YS9sYW5nL09iamVjdAAhAAIAAwAAAAAAAQABAAQABQAB" + - "AAYAAAAdAAEAAQAAAAUqtwABsQAAAAEABwAAAAYAAQAAAAEAAQAIAAAAAgAJ"; + "AQAHYmFyL0JhcgEAEGphdmEvbGFuZy9PYmplY3QAIQACAAMAAAAAAAEAAQAE" + + "AAUAAQAGAAAAHQABAAEAAAAFKrcAAbEAAAABAAcAAAAGAAEAAAABAAEACAAA" + + "AAIACQ=="; + + // Base64 encoded bytes of simple class: "package baz; public class Baz {}" + private final static String BAZ_CLASS = + "yv66vgAAADQADQoAAwAKBwALBwAMAQAGPGluaXQ+AQADKClWAQAEQ29kZQEA" + + "D0xpbmVOdW1iZXJUYWJsZQEAClNvdXJjZUZpbGUBAAhCYXouamF2YQwABAAF" + + "AQAHYmF6L0JhegEAEGphdmEvbGFuZy9PYmplY3QAIQACAAMAAAAAAAEAAQAE" + + "AAUAAQAGAAAAHQABAAEAAAAFKrcAAbEAAAABAAcAAAAGAAEAAAABAAEACAAA" + + "AAIACQ=="; + + private final static String BAZ_CERT = + "-----BEGIN CERTIFICATE-----\n" + + "MIIEFzCCA8OgAwIBAgIESpPf8TANBglghkgBZQMEAwIFADAOMQwwCgYDVQQDEwNG\n" + + "b28wHhcNMTUwNzE1MTY1ODM5WhcNMTUxMDEzMTY1ODM5WjAOMQwwCgYDVQQDEwNG\n" + + "b28wggNCMIICNQYHKoZIzjgEATCCAigCggEBAI95Ndm5qum/q+2Ies9JUbbzLsWe\n" + + "O683GOjqxJYfPv02BudDUanEGDM5uAnnwq4cU5unR1uF0BGtuLR5h3VJhGlcrA6P\n" + + "FLM2CCiiL/onEQo9YqmTRTQJoP5pbEZY+EvdIIGcNwmgEFexla3NACM9ulSEtikf\n" + + "nWSO+INEhneXnOwEtDSmrC516Zhd4j2wKS/BEYyf+p2BgeczjbeStzDXueNJWS9o\n" + + "CZhyFTkV6j1ri0ZTxjNFj4A7MqTC4PJykCVuTj+KOwg4ocRQ5OGMGimjfd9eoUPe\n" + + "S2b/BJA+1c8WI+FY1IfGCOl/IRzYHcojy244B2X4IuNCvkhMBXY5OWAc1mcCHQC6\n" + + "9pamhXj3397n+mfJd8eF7zKyM7rlgMC81WldAoIBABamXFggSFBwTnUCo5dXBA00\n" + + "2jo0eMFU1OSlwC0kLuBPluYeS9CQSr2sjzfuseCfMYLSPJBDy2QviABBYO35ygmz\n" + + "IHannDKmJ/JHPpGHm6LE50S9IIFUTLVbgCw2jR+oPtSJ6U4PoGiOMkKKXHjEeMaN\n" + + "BSe3HJo6uwsL4SxEaJY559POdNsQGmWqK4f2TGgm2z7HL0tVmYNLtO2wL3yQ6aSW\n" + + "06VdU1vr/EXU9hn2Pz3tu4c5JcLyJOB3MSltqIfsHkdI+H77X963VIQxayIy3uVT\n" + + "3a8CESsNHwLaMJcyJP4nrtqLnUspItm6i+Oe2eEDpjxSgQvGiLfi7UMW4e8X294D\n" + + "ggEFAAKCAQBsGeU8/STExzQsJ8kFM9xarA/2VAFMzyUpd3IQ2UGHQC5rEnGh/RiU\n" + + "T20y7a2hCpQ1f/qgLnY8hku9GRVY3z8WamBzWLzCAEAx67EsS58mf4o8R3sUbkH5\n" + + "/mRaZoNVSPUy+tXoLmTzIetU4W+JT8Rq4OcXXU9uo9TreeBehhVexS3vpVgQeUIn\n" + + "MmMma8WHpovIJQQlp4cyjalX7Beda/tqX/HPLkAS4TRqQAz7hFr3FqFrVMKFSGo4\n" + + "fTS06GGdQ4tw9c6NQLuQ9WF9BxYSwSk9yENQvKDZaBNarqPMnsh1Gi/QcKMRBVhM\n" + + "RT/9vb4QUi/pOowhhKCDBLgjY60QgX3HoyEwHzAdBgNVHQ4EFgQUa787CE+3ZNAb\n" + + "g1ql9yJVVrRCdx0wDQYJYIZIAWUDBAMCBQADPwAwPAIcCUkZIRrBlKdTzhKYBEOm\n" + + "E1i45MMum1RuHc28agIcfHQkkjBA4FfH5UMRgKpIyRR8V/dVboxDj4hKOA==\n" + + "-----END CERTIFICATE-----"; public static void main(String[] args) throws Exception { + Security.addProvider(new TestProvider()); + MySecureClassLoader scl = new MySecureClassLoader(); - Policy p = Policy.getPolicy(); + + File policyFile = new File(System.getProperty("test.src", "."), + "DefineClass.policy"); + Policy p = Policy.getInstance("JavaPolicy", + new URIParameter(policyFile.toURI())); + Policy.setPolicy(p); + + System.setSecurityManager(new SecurityManager()); ArrayList perms1 = getPermissions(scl, p, "http://localhost/", - "Foo", FOO_CLASS); + "foo.Foo", FOO_CLASS, + null); checkPerms(perms1, GRANTED_PERMS); ArrayList perms2 = getPermissions(scl, p, "http://127.0.0.1/", - "Bar", BAR_CLASS); + "bar.Bar", BAR_CLASS, + null); checkPerms(perms2, GRANTED_PERMS); assert(perms1.equals(perms2)); + + // check that class signed by baz is granted an additional permission + Certificate[] chain = new Certificate[] {getCert(BAZ_CERT)}; + ArrayList perms3 = getPermissions(scl, p, + "http://localhost/", + "baz.Baz", BAZ_CLASS, + chain); + List perms = new ArrayList<>(Arrays.asList(GRANTED_PERMS)); + perms.add(new PropertyPermission("user.dir", "read")); + checkPerms(perms3, perms.toArray(new Permission[0])); } // returns the permissions granted to the codebase URL private static ArrayList getPermissions(MySecureClassLoader scl, Policy p, String url, String className, - String classBytes) + String classBytes, + Certificate[] chain) throws IOException { - CodeSource cs = new CodeSource(new URL(url), (Certificate[])null); + CodeSource cs = new CodeSource(new URL(url), chain); Base64.Decoder bd = Base64.getDecoder(); byte[] bytes = bd.decode(classBytes); Class c = scl.defineMyClass(className, bytes, cs); @@ -105,10 +179,125 @@ public class DefineClass { } } + private static Certificate getCert(String base64Cert) throws Exception { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + InputStream is = new ByteArrayInputStream(base64Cert.getBytes("UTF-8")); + return cf.generateCertificate(is); + } + // A SecureClassLoader that allows the test to define its own classes private static class MySecureClassLoader extends SecureClassLoader { Class defineMyClass(String name, byte[] b, CodeSource cs) { return super.defineClass(name, b, 0, b.length, cs); } } + + private static class TestProvider extends Provider { + TestProvider() { + super("Test8131486", 0.0, "For testing only"); + putService(new Provider.Service(this, "KeyStore", "Test8131486", + "DefineClass$TestKeyStore", null, null)); + } + } + + /** + * A KeyStore containing a single certificate entry named "baz". + */ + public static class TestKeyStore extends KeyStoreSpi { + private final String baz = "baz"; + private final List aliases = Collections.singletonList(baz); + private final Certificate bazCert; + + public TestKeyStore() { + try { + this.bazCert = getCert(BAZ_CERT); + } catch (Exception e) { + throw new Error(); + } + } + + @Override + public Enumeration engineAliases() { + return Collections.enumeration(aliases); + } + + @Override + public boolean engineContainsAlias(String alias) { + return alias.equals(baz); + } + + @Override + public void engineDeleteEntry(String alias) throws KeyStoreException { + throw new KeyStoreException(); + } + + @Override + public Certificate engineGetCertificate(String alias) { + return alias.equals(baz) ? bazCert : null; + } + + @Override + public String engineGetCertificateAlias(Certificate cert) { + return cert.equals(bazCert) ? baz : null; + } + + @Override + public Certificate[] engineGetCertificateChain(String alias) { + return alias.equals(baz) ? new Certificate[] {bazCert} : null; + } + + @Override + public Date engineGetCreationDate(String alias) { + return alias.equals(baz) ? new Date() : null; + } + + @Override + public Key engineGetKey(String alias, char[] password) + throws NoSuchAlgorithmException, UnrecoverableKeyException { + return null; + } + + @Override + public boolean engineIsCertificateEntry(String alias) { + return alias.equals(baz); + } + + @Override + public boolean engineIsKeyEntry(String alias) { + return false; + } + + @Override + public void engineLoad(InputStream stream, char[] password) + throws IOException, NoSuchAlgorithmException, CertificateException { + } + + @Override + public void engineSetCertificateEntry(String alias, Certificate cert) + throws KeyStoreException { + throw new KeyStoreException(); + } + + @Override + public void engineSetKeyEntry(String alias, byte[] key, + Certificate[] chain) + throws KeyStoreException { + throw new KeyStoreException(); + } + + @Override + public void engineSetKeyEntry(String alias, Key key, char[] password, + Certificate[] chain) + throws KeyStoreException { + throw new KeyStoreException(); + } + + @Override + public int engineSize() { return 1; } + + @Override + public void engineStore(OutputStream stream, char[] password) + throws IOException, NoSuchAlgorithmException, CertificateException { + } + } } diff --git a/jdk/test/java/security/SecureClassLoader/DefineClass.policy b/jdk/test/java/security/SecureClassLoader/DefineClass.policy index ea7eae7c003..dd9dbaa1efd 100644 --- a/jdk/test/java/security/SecureClassLoader/DefineClass.policy +++ b/jdk/test/java/security/SecureClassLoader/DefineClass.policy @@ -1,7 +1,7 @@ +keystore "NONE", "Test8131486", "Test8131486"; + grant { - permission java.lang.RuntimePermission "createClassLoader"; permission java.lang.RuntimePermission "getProtectionDomain"; - permission java.security.SecurityPermission "getPolicy"; }; grant codebase "http://localhost/" { permission java.util.PropertyPermission "user.home", "read"; @@ -9,3 +9,6 @@ grant codebase "http://localhost/" { grant codebase "http://127.0.0.1/" { permission java.util.PropertyPermission "user.name", "read"; }; +grant codebase "http://localhost/", signedby "baz" { + permission java.util.PropertyPermission "user.dir", "read"; +}; From 8b236a44de52340b8eb7adeae5111cc414ebcd85 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Mon, 20 Jul 2015 13:11:20 -0700 Subject: [PATCH 5/6] 8129904: Add beans tests to tier 3 Reviewed-by: alanb, serb --- jdk/test/TEST.groups | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/test/TEST.groups b/jdk/test/TEST.groups index f9e6753b340..fa237c9be2b 100644 --- a/jdk/test/TEST.groups +++ b/jdk/test/TEST.groups @@ -42,7 +42,8 @@ tier2 = \ :jdk_svc tier3 = \ - :jdk_rmi + :jdk_rmi \ + :jdk_beans ############################################################################### # From 6e48caf2507d4a45e1861ee699a32a5e459d70c2 Mon Sep 17 00:00:00 2001 From: Joe Darcy Date: Mon, 20 Jul 2015 15:13:50 -0700 Subject: [PATCH 6/6] 8081734: ConcurrentHashMap/ConcurrentAssociateTest.java, times out 90% of time on sparc with 256 cpu Reviewed-by: chegar --- .../concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/jdk/test/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java b/jdk/test/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java index b0a1ecc8be8..9430813d020 100644 --- a/jdk/test/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java +++ b/jdk/test/java/util/concurrent/ConcurrentHashMap/ConcurrentAssociateTest.java @@ -120,7 +120,8 @@ public class ConcurrentAssociateTest { } }; - int ps = Runtime.getRuntime().availableProcessors(); + // Bound concurrency to avoid degenerate performance + int ps = Math.min(Runtime.getRuntime().availableProcessors(), 32); Stream runners = IntStream.range(0, ps) .mapToObj(i -> sr.get()) .map(CompletableFuture::runAsync);