diff --git a/demos/logging/src/main/java/example/app/FileErrorManager.java b/demos/logging/src/main/java/example/app/FileErrorManager.java index f695fe6f..d280c698 100644 --- a/demos/logging/src/main/java/example/app/FileErrorManager.java +++ b/demos/logging/src/main/java/example/app/FileErrorManager.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2009, 2023 Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2009, 2023 Jason Mehrens. All Rights Reserved. + * Copyright (c) 2009, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024 Jason Mehrens. All Rights Reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0, which is available at @@ -18,8 +18,6 @@ import java.io.OutputStream; import java.io.PrintStream; import java.lang.reflect.Constructor; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.logging.ErrorManager; import java.util.logging.Level; import java.util.logging.LogManager; @@ -269,13 +267,7 @@ private File getEmailStore() { String dir = manager.getProperty( getClass().getName().concat(".pattern")); if (dir == null) { - dir = AccessController.doPrivileged(new PrivilegedAction() { - - @Override - public String run() { - return System.getProperty("java.io.tmpdir", "."); - } - }); + dir = System.getProperty("java.io.tmpdir", "."); } return new File(dir); } @@ -291,7 +283,7 @@ private OutputStream wrap(OutputStream out) { assert out != null; Class k; try { - k = Class.forName("example.app.NewlineOutputStream"); + k = Class.forName("example.app.internal.NewlineOutputStream"); if (OutputStream.class.isAssignableFrom(k)) { Constructor c = k.getConstructor(OutputStream.class); return (OutputStream) c.newInstance(out); diff --git a/demos/logging/src/main/java/example/app/MailHandlerDemo.java b/demos/logging/src/main/java/example/app/MailHandlerDemo.java index fab1b48f..3b5b994b 100644 --- a/demos/logging/src/main/java/example/app/MailHandlerDemo.java +++ b/demos/logging/src/main/java/example/app/MailHandlerDemo.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2009, 2023 Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2009, 2023 Jason Mehrens. All Rights Reserved. + * Copyright (c) 2009, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024 Jason Mehrens. All Rights Reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Distribution License v. 1.0, which is available at @@ -151,21 +151,6 @@ private static void checkConfig(String prefix, PrintStream err) { err.println(prefix + ": LOGGER=" + LOGGER.getLevel()); err.println(prefix + ": JVM id " + ManagementFactory.getRuntimeMXBean().getName()); - err.println(prefix + ": java.security.debug=" - + System.getProperty("java.security.debug")); - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - err.println(prefix + ": SecurityManager.class=" - + sm.getClass().getName()); - err.println(prefix + ": SecurityManager classLoader=" - + toString(sm.getClass().getClassLoader())); - err.println(prefix + ": SecurityManager.toString=" + sm); - } else { - err.println(prefix + ": SecurityManager.class=null"); - err.println(prefix + ": SecurityManager.toString=null"); - err.println(prefix + ": SecurityManager classLoader=null"); - } - String policy = System.getProperty("java.security.policy"); if (policy != null) { File f = new File(policy); diff --git a/doc/src/main/resources/docs/CHANGES.txt b/doc/src/main/resources/docs/CHANGES.txt index 6caee3c4..23a784e7 100644 --- a/doc/src/main/resources/docs/CHANGES.txt +++ b/doc/src/main/resources/docs/CHANGES.txt @@ -11,6 +11,7 @@ for the Eclipse EE4J Angus Mail project: ---------------------------- The following bugs have been fixed in the 2.0.3 release. +16: Remove SecurityManager references from logging package 52: CompactFormatter support for LogRecord::getLongThreadID 107: java.io.UnsupportedEncodingException: en_US.iso885915 if charset is "en_US.iso885915" 110: WildFly support for MailHandler diff --git a/mailhandler/src/main/java/org/eclipse/angus/mail/util/logging/LogManagerProperties.java b/mailhandler/src/main/java/org/eclipse/angus/mail/util/logging/LogManagerProperties.java index 9c41f07f..501b77f5 100644 --- a/mailhandler/src/main/java/org/eclipse/angus/mail/util/logging/LogManagerProperties.java +++ b/mailhandler/src/main/java/org/eclipse/angus/mail/util/logging/LogManagerProperties.java @@ -25,13 +25,13 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.UndeclaredThrowableException; -import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashSet; import java.util.Locale; +import java.util.Objects; import java.util.Properties; import java.util.logging.ErrorManager; import java.util.logging.Filter; @@ -40,7 +40,6 @@ import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; -import java.util.logging.LoggingPermission; /** * An adapter class to allow the Mail API to access the LogManager properties. @@ -171,7 +170,7 @@ private static Object loadLogManager() { try { m = LogManager.getLogManager(); } catch (final LinkageError | RuntimeException restricted) { - m = readConfiguration(); + m = readConfiguration(); //GAE will forbid access to LogManager } return m; } @@ -197,11 +196,8 @@ private static Properties readConfiguration() { String n = System.getProperty("java.util.logging.config.file"); if (n != null) { final File f = new File(n).getCanonicalFile(); - final InputStream in = new FileInputStream(f); - try { + try (InputStream in = new FileInputStream(f)) { props.load(in); - } finally { - in.close(); } } } catch (final LinkageError | Exception permissionsOrMalformed) { @@ -219,10 +215,7 @@ private static Properties readConfiguration() { * @since JavaMail 1.5.3 */ static String fromLogManager(final String name) { - if (name == null) { - throw new NullPointerException(); - } - + Objects.requireNonNull(name); final Object m = LOG_MANAGER; try { if (m instanceof Properties) { @@ -237,7 +230,7 @@ static String fromLogManager(final String name) { return ((LogManager) m).getProperty(name); } } catch (final LinkageError | RuntimeException restricted) { - } + } //GAE will forbid access to LogManager } return null; } @@ -256,55 +249,46 @@ static void checkLogManagerAccess() { if (m != null) { try { if (m instanceof LogManager) { - checked = true; - ((LogManager) m).checkAccess(); + try { + LogManager.class.getMethod("checkAccess").invoke(m); + checked = true; + } catch (InvocationTargetException ite) { + Throwable cause = ite.getCause(); + if (cause instanceof SecurityException) { + checked = true; + throw (SecurityException) cause; + } + + if (cause instanceof UnsupportedOperationException) { + checked = true; + } + } catch (NoSuchMethodException removed) { + checked = true; + } catch (ReflectiveOperationException fallthrough) { + } } } catch (final SecurityException notAllowed) { if (checked) { throw notAllowed; } } catch (final LinkageError | RuntimeException restricted) { - } - } - - if (!checked) { - checkLoggingAccess(); + } //GAE will forbid access to LogManager } - } - /** - * Check that the current context is trusted to modify the logging - * configuration when the LogManager is not present. This requires - * LoggingPermission("control"). - * - * @throws SecurityException if a security manager exists and the caller - * does not have {@code LoggingPermission("control")}. - * @since JavaMail 1.5.3 - */ - private static void checkLoggingAccess() { /** * Some environments selectively enforce logging permissions by allowing * access to loggers but not allowing access to handlers. This is an * indirect way of checking for LoggingPermission when the LogManager is * not present. The root logger will lazy create handlers so the global * logger is used instead as it is a known named logger with well - * defined behavior. If the global logger is a subclass then fallback to - * using the SecurityManager. + * defined behavior. Contractually, Logger::remove will check + * permission before checking if the argument is null. + * See JDK-8023168 */ - boolean checked = false; - final Logger global = Logger.getLogger("global"); - try { - if (Logger.class == global.getClass()) { - global.removeHandler((Handler) null); - checked = true; - } - } catch (final NullPointerException unexpected) { - } - if (!checked) { - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new LoggingPermission("control", null)); + try { + Logger.getGlobal().removeHandler((Handler) null); + } catch (final NullPointerException unexpected) { } } } @@ -332,9 +316,7 @@ static boolean hasLogManager() { */ @SuppressWarnings("UseSpecificCatch") static Comparable getZonedDateTime(LogRecord record) { - if (record == null) { - throw new NullPointerException(); - } + Objects.requireNonNull(record); final Method m = ZDT_OF_INSTANT; if (m != null) { try { @@ -368,10 +350,7 @@ static Comparable getZonedDateTime(LogRecord record) { * @since Angus Mail 2.0.3 */ static Long getLongThreadID(final LogRecord record) { - if (record == null) { - throw new NullPointerException(); - } - + Objects.requireNonNull(record); final Method m = LR_GET_LONG_TID; if (m != null) { try { @@ -409,6 +388,7 @@ static Long getLongThreadID(final LogRecord record) { * @since JavaMail 1.5.3 */ static String getLocalHost(final Object s) throws Exception { + Objects.requireNonNull(s); try { final Method m = s.getClass().getMethod("getLocalHost"); if (!Modifier.isStatic(m.getModifiers()) @@ -443,10 +423,7 @@ static String getLocalHost(final Object s) throws Exception { * @since JavaMail 1.5.5 */ static long parseDurationToMillis(final CharSequence value) throws Exception { - if (value == null) { - throw new NullPointerException(); - } - + Objects.requireNonNull(value); try { final Class k = findClass("java.time.Duration"); final Method parse = k.getMethod("parse", CharSequence.class); @@ -586,10 +563,7 @@ static Comparator newComparator(String name) throws Exception */ @SuppressWarnings({"unchecked", "ThrowableResultIgnored"}) static Comparator reverseOrder(final Comparator c) { - if (c == null) { - throw new NullPointerException(); - } - + Objects.requireNonNull(c); Comparator reverse = null; //Comparator in JDK8 has 'reversed' as a default method. //This code calls that method first to allow custom @@ -794,18 +768,12 @@ static T newObjectFrom(String name, Class type) throws Exception { * @param ite any invocation target. * @return the exception. * @throws VirtualMachineError if present as cause. - * @throws ThreadDeath if present as cause. * @since JavaMail 1.4.5 */ private static Exception paramOrError(InvocationTargetException ite) { final Throwable cause = ite.getCause(); - if (cause != null) { - //Bitwise inclusive OR produces tighter bytecode for instanceof - //and matches with multicatch syntax. - if (cause instanceof VirtualMachineError - | cause instanceof ThreadDeath) { - throw (Error) cause; - } + if (cause instanceof VirtualMachineError) { + throw (Error) cause; } return ite; } @@ -881,7 +849,7 @@ private static Class tryLoad(String name, ClassLoader l) throws ClassNotFound * @return any array of class loaders. Indexes may be null. */ private static ClassLoader[] getClassLoaders() { - return AccessController.doPrivileged(new PrivilegedAction() { + return runOrDoPrivileged(new PrivilegedAction() { @SuppressWarnings("override") //JDK-6954234 public ClassLoader[] run() { @@ -902,6 +870,58 @@ public ClassLoader[] run() { }); } + /** + * Executes a PrivilegedAction without permissions then falling back to + * running with elevated permissions. + * + * Any unchecked exceptions from the action are passed through this API. + * + * @param the action return type. + * @param a the PrivilegedAction object. + * @return the result. + * @throws NullPointerException if the given action is null. + * @throws UndeclaredThrowableException if a checked exception is thrown. + * @since Angus Mail 2.0.3 + */ + static T runOrDoPrivileged(final PrivilegedAction a) { + Objects.requireNonNull(a); + try { + return a.run(); + } catch (SecurityException sandbox) { + return invokeAccessController(a); + } + } + + /** + * Reflective call to access controller for sandbox environments. + * Any unchecked exceptions from the action are passed through this API. + * + * @param the return type of the action. + * @param a a non-null action. + * @return the result. + * @throws UnsupportedOperationException if not allowed. + * @throws UndeclaredThrowableException if a checked exception is thrown. + * @since Angus Mail 2.0.3 + */ + @SuppressWarnings("unchecked") + private static T invokeAccessController(final PrivilegedAction a) { + assert a != null; + try { + Class c = Class.forName("java.security.AccessController"); + return (T) c.getMethod("doPrivileged", PrivilegedAction.class) + .invoke((Object) null, a); + } catch (ReflectiveOperationException roe) { + Throwable cause = roe.getCause(); + if (cause instanceof RuntimeException) { + throw (RuntimeException) cause; + } else if (cause instanceof Error) { + throw (Error) cause; + } else { + throw new UndeclaredThrowableException(roe); + } + } + } + /** * The namespace prefix to search LogManager and defaults. */ diff --git a/mailhandler/src/main/java/org/eclipse/angus/mail/util/logging/MailHandler.java b/mailhandler/src/main/java/org/eclipse/angus/mail/util/logging/MailHandler.java index d4c0fbeb..aeced388 100644 --- a/mailhandler/src/main/java/org/eclipse/angus/mail/util/logging/MailHandler.java +++ b/mailhandler/src/main/java/org/eclipse/angus/mail/util/logging/MailHandler.java @@ -59,7 +59,6 @@ import java.net.URLConnection; import java.net.UnknownHostException; import java.nio.charset.Charset; -import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Comparator; @@ -1017,9 +1016,7 @@ private synchronized void setEnabled0(final boolean enabled) { */ @Override public void setLevel(final Level newLevel) { - if (newLevel == null) { - throw new NullPointerException(); - } + Objects.requireNonNull(newLevel); checkAccess(); //Don't allow a closed handler to be opened (half way). @@ -1087,9 +1084,7 @@ public void setErrorManager(final ErrorManager em) { * @since JavaMail 1.5.6 */ private void setErrorManager0(final ErrorManager em) { - if (em == null) { - throw new NullPointerException(); - } + Objects.requireNonNull(em); try { synchronized (this) { //Wait for writeLogRecords. this.errorManager = em; @@ -1209,10 +1204,7 @@ public synchronized Formatter getFormatter() { @Override public synchronized void setFormatter(Formatter newFormatter) throws SecurityException { checkAccess(); - if (newFormatter == null) { - throw new NullPointerException(); - } - this.formatter = newFormatter; + this.formatter = Objects.requireNonNull(newFormatter); } /** @@ -4687,7 +4679,7 @@ private Object getAndSetContextClassLoader(final Object ccl) { } else { pa = new GetAndSetContext(ccl); } - return AccessController.doPrivileged(pa); + return LogManagerProperties.runOrDoPrivileged(pa); } catch (final SecurityException ignore) { } } @@ -4756,9 +4748,7 @@ private String getLocalHost(final Service s) { * @since JavaMail 1.5.3 */ private Session getSession(final Message msg) { - if (msg == null) { - throw new NullPointerException(); - } + Objects.requireNonNull(msg); return new MessageContext(msg).getSession(); } diff --git a/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/AbstractLogging.java b/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/AbstractLogging.java index 7938fd10..14600343 100644 --- a/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/AbstractLogging.java +++ b/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/AbstractLogging.java @@ -308,7 +308,7 @@ final void testLogManagerModifiers(final Class c) throws Exception { /** * Checks that the given class is not dependent on the * {@code javax.annotation} classes as they are not present in all - * environments. + * environments and were present in JDK. * * @param k the class to inspect. * @throws Exception if there is a problem. diff --git a/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/LogManagerPropertiesTest.java b/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/LogManagerPropertiesTest.java index 47eeeac7..b21d54ad 100644 --- a/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/LogManagerPropertiesTest.java +++ b/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/LogManagerPropertiesTest.java @@ -27,7 +27,6 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; import java.io.Serializable; @@ -35,6 +34,8 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.UndeclaredThrowableException; +import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Comparator; import java.util.Locale; @@ -47,7 +48,6 @@ import java.util.logging.Level; import java.util.logging.LogManager; import java.util.logging.LogRecord; -import java.util.logging.LoggingPermission; import java.util.logging.SimpleFormatter; import static org.junit.Assert.assertEquals; @@ -55,6 +55,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -70,11 +71,6 @@ public class LogManagerPropertiesTest extends AbstractLogging { */ private final static ThreadLocal PENDING = new ThreadLocal<>(); - @BeforeClass - public static void setUpClass() throws Exception { - Assert.assertNull(System.getSecurityManager()); - } - private static void fullFence() { LogManager.getLogManager().getProperty(""); } @@ -96,33 +92,114 @@ public void testDeclaredClasses() throws Exception { } @Test - public void testCheckAccessPresent() { - LogManager m = LogManager.getLogManager(); - m.checkAccess(); - LogManagerProperties.checkLogManagerAccess(); - - LogPermSecurityManager sm = new LogPermSecurityManager(); - sm.secure = false; - System.setSecurityManager(sm); + public void testCheckLogManagerAccess() { try { - sm.secure = true; - try { - m.checkAccess(); - fail(m.toString()); - } catch (SecurityException expect) { + LogManagerProperties.checkLogManagerAccess(); + //okay if we return normally, this is a weak test. + } catch (SecurityException allowed) { + } + } + + private static boolean isInvokeAccessController() { + for (StackTraceElement frame : new Throwable().getStackTrace()) { + if ("invokeAccessController".equals(frame.getMethodName()) + && LogManagerProperties.class.getName().equals(frame.getClassName())) { + return true; } + } + return false; + } - try { - LogManagerProperties.checkLogManagerAccess(); - fail(LogManagerProperties.class.getName()); - } catch (SecurityException expect) { + private static boolean isAccessController() { + for (StackTraceElement frame : new Throwable().getStackTrace()) { + if ("doPrivileged".equals(frame.getMethodName()) + && "java.security.AccessController".equals( + frame.getClassName())) { + return true; } - } finally { - sm.secure = false; - System.setSecurityManager((SecurityManager) null); } + return false; + } + + @Test + public void testRun() { + PrivilegedAction p = () -> { + assertFalse(isInvokeAccessController()); + assertFalse(isAccessController()); + return true; + }; + assertTrue(LogManagerProperties.runOrDoPrivileged(p)); + } + + @Test + public void testDoPrivileged() { + PrivilegedAction p = () -> { + if (isInvokeAccessController()) { + return isAccessController(); + } + throw new SecurityException(); + }; + + try { + assertTrue(LogManagerProperties.runOrDoPrivileged(p)); + } catch (UndeclaredThrowableException removed) { + assertTrue(removed.getCause() instanceof ClassNotFoundException); + } catch (UnsupportedOperationException terminal) { + } + } + + @Test + public void testDoPrivilegedRuntimeException() { + RuntimeException cause = new RuntimeException(); + PrivilegedAction p = () -> { + if (isInvokeAccessController()) { + throw cause; + } + throw new SecurityException(); + }; + + boolean ran = false; + try { + LogManagerProperties.runOrDoPrivileged(p); + ran = true; + } catch (UndeclaredThrowableException removed) { + assertTrue(removed.getCause() instanceof ClassNotFoundException); + } catch (UnsupportedOperationException terminal) { + } catch (RuntimeException re) { + assertSame(re, cause); + } + assertFalse(ran); + } + + @Test + public void testDoPrivilegedError() { + Error cause = new Error(); + PrivilegedAction p = () -> { + if (isInvokeAccessController()) { + throw cause; + } + throw new SecurityException(); + }; + + boolean ran = false; + try { + LogManagerProperties.runOrDoPrivileged(p); + ran = true; + } catch (UndeclaredThrowableException removed) { + assertTrue(removed.getCause() instanceof ClassNotFoundException); + } catch (UnsupportedOperationException terminal) { + } catch (Error e) { + assertSame(e, cause); + } + assertFalse(ran); } + @Test(expected=NullPointerException.class) + public void testRunOrDoPrivilegedNull() { + LogManagerProperties.runOrDoPrivileged((PrivilegedAction) null); + } + + @Test public void testFromLogManagerPresent() throws Exception { String prefix = LogManagerPropertiesTest.class.getName(); @@ -968,11 +1045,11 @@ public void testEscapingAuthenticator() throws Exception { a = LogManagerProperties.newObjectFrom(k.getName(), Authenticator.class); assertEquals(k, a.getClass()); - setPending(new ThreadDeath()); + setPending(new StackOverflowError()); try { a = LogManagerProperties.newObjectFrom(k.getName(), Authenticator.class); fail(String.valueOf(a)); - } catch (ThreadDeath expect) { + } catch (StackOverflowError expect) { } setPending(new OutOfMemoryError()); @@ -995,11 +1072,11 @@ public void testEscapingComparator() throws Exception { c = LogManagerProperties.newComparator(k.getName()); assertEquals(k, c.getClass()); - setPending(new ThreadDeath()); + setPending(new StackOverflowError()); try { c = LogManagerProperties.newComparator(k.getName()); fail(String.valueOf(c)); - } catch (ThreadDeath expect) { + } catch (StackOverflowError expect) { } setPending(new OutOfMemoryError()); @@ -1022,11 +1099,11 @@ public void testEscapingErrorErrorManager() throws Exception { f = LogManagerProperties.newErrorManager(k.getName()); assertEquals(k, f.getClass()); - setPending(new ThreadDeath()); + setPending(new StackOverflowError()); try { f = LogManagerProperties.newErrorManager(k.getName()); fail(String.valueOf(f)); - } catch (ThreadDeath expect) { + } catch (StackOverflowError expect) { } setPending(new OutOfMemoryError()); @@ -1049,11 +1126,11 @@ public void testEscapingFilter() throws Exception { f = LogManagerProperties.newFilter(k.getName()); assertEquals(k, f.getClass()); - setPending(new ThreadDeath()); + setPending(new StackOverflowError()); try { f = LogManagerProperties.newFilter(k.getName()); fail(String.valueOf(f)); - } catch (ThreadDeath expect) { + } catch (StackOverflowError expect) { } setPending(new OutOfMemoryError()); @@ -1076,11 +1153,11 @@ public void testEscapingFormatter() throws Exception { f = LogManagerProperties.newFormatter(k.getName()); assertEquals(k, f.getClass()); - setPending(new ThreadDeath()); + setPending(new StackOverflowError()); try { f = LogManagerProperties.newFormatter(k.getName()); fail(String.valueOf(f)); - } catch (ThreadDeath expect) { + } catch (StackOverflowError expect) { } setPending(new OutOfMemoryError()); @@ -1319,38 +1396,4 @@ public String getLocalHost() { throw new SecurityException(); } } - - private static final class LogPermSecurityManager extends SecurityManager { - - volatile boolean secure = false; - - LogPermSecurityManager() { - } - - @Override - public void checkPermission(java.security.Permission perm) { - try { //Call super class always for java.security.debug tracing. - super.checkPermission(perm); - checkPermission(perm, new SecurityException(perm.toString())); - } catch (SecurityException se) { - checkPermission(perm, se); - } - } - - @Override - public void checkPermission(java.security.Permission perm, Object context) { - try { //Call super class always for java.security.debug tracing. - super.checkPermission(perm, context); - checkPermission(perm, new SecurityException(perm.toString())); - } catch (SecurityException se) { - checkPermission(perm, se); - } - } - - private void checkPermission(java.security.Permission perm, SecurityException se) { - if (secure && perm instanceof LoggingPermission) { - throw se; - } - } - } } diff --git a/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/MailHandlerTest.java b/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/MailHandlerTest.java index 3b58b137..cbd2005f 100644 --- a/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/MailHandlerTest.java +++ b/providers/angus-mail/src/test/java/org/eclipse/angus/mail/util/logging/MailHandlerTest.java @@ -1,6 +1,6 @@ /* - * Copyright (c) 2009, 2023 Oracle and/or its affiliates. All rights reserved. - * Copyright (c) 2009, 2023 Jason Mehrens. All rights reserved. + * Copyright (c) 2009, 2024 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024 Jason Mehrens. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -79,6 +79,8 @@ import java.util.Random; import java.util.ResourceBundle; import java.util.UUID; +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; import java.util.logging.ConsoleHandler; import java.util.logging.ErrorManager; import java.util.logging.Filter; @@ -88,7 +90,6 @@ import java.util.logging.LogManager; import java.util.logging.LogRecord; import java.util.logging.Logger; -import java.util.logging.LoggingPermission; import java.util.logging.MemoryHandler; import java.util.logging.SimpleFormatter; import java.util.logging.XMLFormatter; @@ -260,41 +261,47 @@ static void checkContextClassLoader(ClassLoader expect) { Object ccl = Thread.currentThread().getContextClassLoader(); if (expect != ccl) { AssertionError ae = new AssertionError(expect + " != " + ccl - + ", sm=" + System.getSecurityManager()); + + ", thread=" + Thread.currentThread()); dump(ae); throw ae; } } @Test - public void testChildClassLoader() { - assertNull(System.getSecurityManager()); - final Thread thread = Thread.currentThread(); - final ClassLoader ccl = thread.getContextClassLoader(); - try { - URLClassLoader child = new URLClassLoader(new URL[0], ccl); + public void testChildClassLoader() throws Exception { + Callable c = () -> { + final Thread thread = Thread.currentThread(); + final ClassLoader ccl = thread.getContextClassLoader(); + try { + URLClassLoader child = new URLClassLoader(new URL[0], ccl); - thread.setContextClassLoader(child); - testCallingClassLoader((ClassLoaderSecurityManager) null, child); + thread.setContextClassLoader(child); + testCallingClassLoader(false, child); - thread.setContextClassLoader(child); - testCallingClassLoader(new ClassLoaderSecurityManager(), child); - } finally { - thread.setContextClassLoader(ccl); - } - assertNull(System.getSecurityManager()); + thread.setContextClassLoader(child); + testCallingClassLoader(true, child); + } finally { + thread.setContextClassLoader(ccl); + } + return null; + }; + + FutureTask f = new FutureTask<>(c); + Thread t = new ClassLoaderThread(f); + t.start(); + assertNull(f.get()); } - private void testCallingClassLoader( - ClassLoaderSecurityManager sm, ClassLoader expect) { + private void testCallingClassLoader(boolean secure, ClassLoader expect) { + Thread clt = Thread.currentThread(); + assertEquals(ClassLoaderThread.class, clt.getClass()); + assert clt instanceof ClassLoaderThread : clt; + InternalErrorManager em = new ClassLoaderErrorManager(expect); try { MailHandler instance = new MailHandler(createInitProperties("")); try { - if (sm != null) { - System.setSecurityManager(sm); - sm.secure = true; - } + ((ClassLoaderThread) clt).secure = secure; instance.setErrorManager(em); instance.setLevel(Level.ALL); instance.setPushLevel(Level.SEVERE); @@ -313,10 +320,7 @@ private void testCallingClassLoader( instance.close(); } } finally { - if (sm != null) { - sm.secure = false; - System.setSecurityManager((SecurityManager) null); - } + ((ClassLoaderThread) clt).secure = false; } assert em != null; @@ -332,21 +336,27 @@ private void testCallingClassLoader( @Test public void testVerifyClassLoader() throws Exception { - assertNull(System.getSecurityManager()); - final Thread thread = Thread.currentThread(); - final ClassLoader ccl = thread.getContextClassLoader(); - try { - URLClassLoader child = new URLClassLoader(new URL[0], ccl); + Callable c = () -> { + final Thread thread = Thread.currentThread(); + final ClassLoader ccl = thread.getContextClassLoader(); + try { + URLClassLoader child = new URLClassLoader(new URL[0], ccl); - thread.setContextClassLoader(child); - testVerify((ClassLoaderSecurityManager) null, child); + thread.setContextClassLoader(child); + testVerify(false, child); - thread.setContextClassLoader(child); - testVerify(new ClassLoaderSecurityManager(), child); - } finally { - thread.setContextClassLoader(ccl); - } - assertNull(System.getSecurityManager()); + thread.setContextClassLoader(child); + testVerify(true, child); + } finally { + thread.setContextClassLoader(ccl); + } + return null; + }; + + FutureTask f = new FutureTask<>(c); + Thread t = new ClassLoaderThread(f); + t.start(); + assertNull(f.get()); } @Test @@ -369,7 +379,11 @@ public void testWebappClassLoaderFieldNames() throws Exception { testWebappClassLoaderFieldNames(MailHandler.class); } - private void testVerify(ClassLoaderSecurityManager sm, ClassLoader expect) throws Exception { + private void testVerify(boolean secure, ClassLoader expect) throws Exception { + Thread clt = Thread.currentThread(); + assertEquals(ClassLoaderThread.class, clt.getClass()); + assert clt instanceof ClassLoaderThread : clt; + final LogManager manager = LogManager.getLogManager(); InternalErrorManager em = null; set(expect); @@ -384,11 +398,8 @@ private void testVerify(ClassLoaderSecurityManager sm, ClassLoader expect) throw read(manager, props); - if (sm != null) { - System.setSecurityManager(sm); - sm.secure = true; - } + ((ClassLoaderThread) clt).secure = secure; MailHandler instance = new MailHandler(); try { em = internalErrorManagerFrom(instance); @@ -396,10 +407,7 @@ private void testVerify(ClassLoaderSecurityManager sm, ClassLoader expect) throw instance.close(); } } finally { - if (sm != null) { - sm.secure = false; - System.setSecurityManager((SecurityManager) null); - } + ((ClassLoaderThread) clt).secure = false; set((ClassLoader) null); manager.reset(); } @@ -416,33 +424,40 @@ private void testVerify(ClassLoaderSecurityManager sm, ClassLoader expect) throw @Test public void testSetMailPropertiesClassLoader() throws Exception { - assertNull(System.getSecurityManager()); - final Thread thread = Thread.currentThread(); - final ClassLoader ccl = thread.getContextClassLoader(); - try { - URLClassLoader child = new URLClassLoader(new URL[0], ccl); + Callable c = () -> { + final Thread thread = Thread.currentThread(); + final ClassLoader ccl = thread.getContextClassLoader(); + try { + URLClassLoader child = new URLClassLoader(new URL[0], ccl); - thread.setContextClassLoader(child); - testSetMailProperties((ClassLoaderSecurityManager) null, child); + thread.setContextClassLoader(child); + testSetMailProperties(false, child); - thread.setContextClassLoader(child); - testSetMailProperties(new ClassLoaderSecurityManager(), child); - } finally { - thread.setContextClassLoader(ccl); - } - assertNull(System.getSecurityManager()); + thread.setContextClassLoader(child); + testSetMailProperties(true, child); + } finally { + thread.setContextClassLoader(ccl); + } + return null; + }; + + FutureTask f = new FutureTask<>(c); + Thread t = new ClassLoaderThread(f); + t.start(); + assertNull(f.get()); } - private void testSetMailProperties(ClassLoaderSecurityManager sm, ClassLoader expect) throws Exception { + private void testSetMailProperties(boolean secure, ClassLoader expect) throws Exception { + Thread clt = Thread.currentThread(); + assertEquals(ClassLoaderThread.class, clt.getClass()); + assert clt instanceof ClassLoaderThread : clt; + InternalErrorManager em = new ClassLoaderErrorManager(expect); try { Properties props = createInitProperties(""); props.put("verify", "local"); - if (sm != null) { - System.setSecurityManager(sm); - sm.secure = true; - } + ((ClassLoaderThread) clt).secure = secure; MailHandler instance = new MailHandler(); try { @@ -458,10 +473,7 @@ private void testSetMailProperties(ClassLoaderSecurityManager sm, ClassLoader ex instance.close(); } } finally { - if (sm != null) { - sm.secure = false; - System.setSecurityManager((SecurityManager) null); - } + ((ClassLoaderThread) clt).secure = false; } assert em != null; @@ -2327,7 +2339,6 @@ private void testLinkageErrorEmptyStack(String method) throws IOException { @Test public void testCloseContextClassLoader() { - assertNull(System.getSecurityManager()); final Thread thread = Thread.currentThread(); final ClassLoader ccl = thread.getContextClassLoader(); try { @@ -2335,7 +2346,6 @@ public void testCloseContextClassLoader() { } finally { thread.setContextClassLoader(ccl); } - assertNull(System.getSecurityManager()); } private void testCloseContextClassLoader0() { @@ -3045,12 +3055,6 @@ public void testContentTypeOverride() throws Exception { assertEquals(expected, type); } - private ErrorManager getSuperErrorManager(MailHandler h) throws Exception { - Method hem = MailHandler.class.getDeclaredMethod("defaultErrorManager"); - hem.setAccessible(true); - return (ErrorManager) hem.invoke(h); - } - private String getInlineContentType(Formatter f) throws Exception { final String[] value = new String[1]; MailHandler instance = new MailHandler(createInitProperties("")); @@ -5201,85 +5205,6 @@ private String toString(Address o) { instance.close(); } - @Test - public void testReportErrorSuper() throws Exception { - assertNull(System.getSecurityManager()); - Field mhem = MailHandler.class.getDeclaredField("errorManager"); - mhem.setAccessible(true); - - InternalErrorManager superEm = new InternalErrorManager(); - InternalErrorManager em = new InternalErrorManager(); - MailHandler h = new MailHandler(); - try { - Exception tester = new Exception(); - synchronized (h) { - assertSame(h.getErrorManager(), getSuperErrorManager(h)); - - h.setErrorManager(superEm); - assertSame(superEm, getSuperErrorManager(h)); - assertSame(superEm, mhem.get(h)); - - mhem.set(h, em); - assertSame(em, h.getErrorManager()); - assertSame(superEm, getSuperErrorManager(h)); - assertNotSame(h.getErrorManager(), getSuperErrorManager(h)); - h.reportError("", tester, ErrorManager.GENERIC_FAILURE); - } - - assertEquals(1, em.exceptions.size()); - assertSame(tester, em.exceptions.get(0)); - assertTrue(superEm.exceptions.toString(), - superEm.exceptions.isEmpty()); - } finally { - h.close(); - } - } - - @Test - public void testGaeReportErrorSuper() throws Exception { - Field mhem = MailHandler.class.getDeclaredField("errorManager"); - mhem.setAccessible(true); - - InternalErrorManager em = new InternalErrorManager(); - GaeSecurityManager sm = new GaeSecurityManager(); - System.setSecurityManager(sm); - sm.secure = true; - try { - MailHandler h = new MailHandler(); - try { - Exception tester = new Exception(); - synchronized (h) { - sm.secure = false; - final Object def = getSuperErrorManager(h); - assertSame(def, getSuperErrorManager(h)); - sm.secure = true; - - assertEquals(h.getErrorManager().getClass(), def.getClass()); - assertNotSame(h.getErrorManager(), def); - - h.setErrorManager(em); - sm.secure = false; - final Object sem = getSuperErrorManager(h); - sm.secure = true; - assertSame(def, sem); - assertNotSame(h.getErrorManager(), def); - assertNotSame(h.getErrorManager(), sem); - assertSame(h.getErrorManager(), em); - - h.reportError("", tester, ErrorManager.GENERIC_FAILURE); - } - - assertEquals(1, em.exceptions.size()); - assertSame(tester, em.exceptions.get(0)); - } finally { - h.close(); - } - } finally { - sm.secure = false; - System.setSecurityManager((SecurityManager) null); - } - } - @Test public void testReportErrorLinkageWithStack() throws Exception { testReportErrorLinkageWithStack(new LinkageErrorStream()); @@ -5376,470 +5301,6 @@ private void testReportErrorLinkageEmptyStack(PrintStream ps) throws Throwable { } } - /** - * Test logging permissions of the MailHandler. Must run by itself or run in - * isolated VM. Use system property java.security.debug=all to troubleshoot - * failures. - */ - @Test - public void testSecurityManager() { - InternalErrorManager em; - MailHandler h = null; - final ThrowSecurityManager manager = new ThrowSecurityManager(); - System.setSecurityManager(manager); - try { - manager.secure = false; - h = new MailHandler(createInitProperties("")); - em = new InternalErrorManager(); - h.setErrorManager(em); - manager.secure = true; - assertEquals(manager, System.getSecurityManager()); - - try { - assertEquals(0, h.getAttachmentFormatters().length); - h.setAttachmentNames("error.txt"); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertEquals(0, h.getAttachmentFormatters().length); - h.setAttachmentNames(new ThrowFormatter()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertEquals(0, h.getAttachmentFormatters().length); - h.setAttachmentFilters(new ThrowFilter()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setAttachmentFormatters(new ThrowFormatter()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - manager.secure = false; - try { - h.setAttachmentFormatters(new ThrowFormatter()); - } catch (SecurityException fail) { - fail("Unexpected secure check."); - } catch (Exception fail) { - fail(fail.toString()); - } finally { - manager.secure = true; - } - - try { - assertEquals(1, h.getAttachmentFormatters().length); - h.setAttachmentFilters(new ThrowFilter()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertEquals(1, h.getAttachmentFormatters().length); - h.setAttachmentFilters((Filter[]) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertEquals(1, h.getAttachmentFormatters().length); - h.setAttachmentNames("error.txt"); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertEquals(1, h.getAttachmentFormatters().length); - h.setAttachmentNames((String[]) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertEquals(1, h.getAttachmentFormatters().length); - h.setAttachmentNames((Formatter[]) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertEquals(1, h.getAttachmentFormatters().length); - h.setAttachmentNames(new ThrowFormatter()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - manager.secure = false; - try { - assertEquals(1, h.getAttachmentFormatters().length); - h.setAttachmentFormatters(); - } catch (Exception fail) { - fail(fail.toString()); - } finally { - manager.secure = true; - } - - try { - assertEquals(0, h.getAttachmentFormatters().length); - assertEquals(0, h.getAttachmentFilters().length); - assertEquals(0, h.getAttachmentNames().length); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setAuthenticator((Authenticator) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setComparator((Comparator) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getComparator(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setLevel(Level.ALL); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setLevel((Level) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getLevel(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setFilter(BooleanFilter.FALSE); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setFilter((Filter) null); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getFilter(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setFormatter(new EmptyFormatter()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setFormatter((Formatter) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getFormatter(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertNotNull(h.getErrorManager()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setErrorManager(new ErrorManager()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setErrorManager((ErrorManager) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setEncoding((String) null); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getEncoding(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.flush(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.push(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setMailProperties(new Properties()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setMailProperties((Properties) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setPushFilter((Filter) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getPushFilter(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setPushLevel(Level.OFF); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setPushLevel((Level) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getPushLevel(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setSubject((Formatter) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setSubject((String) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setSubject(new ThrowFormatter()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.setSubject("test"); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getSubject(); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - assertTrue(h.getCapacity() > 0); - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getAuthenticator(); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.getMailProperties(); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.close(); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - h.publish(new LogRecord(Level.SEVERE, "")); - h.flush(); - } catch (Exception fail) { - fail(fail.toString()); - } - - //check for internal exceptions caused by security manager. - next: - for (Exception e : em.exceptions) { - for (Throwable t = e; t != null; t = t.getCause()) { - if (t instanceof SecurityException) { - continue next; //expected - } else if (t instanceof RuntimeException) { - throw (RuntimeException) t; //fail - } - } - } - em.exceptions.clear(); - - try { - hardRef = new MailHandler(); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - hardRef = new MailHandler(100); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - hardRef = new MailHandler(new Properties()); - fail("Missing secure check."); - } catch (SecurityException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - hardRef = new MailHandler(-100); - fail("Missing secure check."); - } catch (SecurityException | IllegalArgumentException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - - try { - hardRef = new MailHandler((Properties) null); - fail("Missing secure check."); - } catch (SecurityException | NullPointerException pass) { - } catch (Exception fail) { - fail(fail.toString()); - } - } finally { - hardRef = null; - manager.secure = false; - System.setSecurityManager((SecurityManager) null); - if (h != null) { - h.close(); - } - } - } - @Test public void testVerifyErrorManager() throws Exception { LogManager manager = LogManager.getLogManager(); @@ -5934,7 +5395,6 @@ public void testIsMissingContent() throws Exception { @Test public void testIntern() throws Exception { - assertNull(System.getSecurityManager()); final String p = MailHandler.class.getName(); Properties props = createInitProperties(p); props.put(p.concat(".errorManager"), @@ -6033,7 +5493,6 @@ private MailHandler testIntern(String p, Properties props) throws Exception { @Test public void testInternNonDiscriminating() throws Exception { - assertNull(System.getSecurityManager()); final String p = MailHandler.class.getName(); Properties props = createInitProperties(p); props.put(p.concat(".attachment.formatters"), @@ -8143,46 +7602,6 @@ public String format(LogRecord r) { } } - public static final class ThrowSecurityManager extends SecurityManager { - - boolean secure = false; - private final boolean debug; - - public ThrowSecurityManager() { - debug = isSecurityDebug(); - } - - @Override - public void checkPermission(java.security.Permission perm) { - try { //Call super class always for java.security.debug tracing. - super.checkPermission(perm); - checkPermission(perm, new SecurityException(perm.toString())); - } catch (SecurityException se) { - checkPermission(perm, se); - } - } - - @Override - public void checkPermission(java.security.Permission perm, Object context) { - try { //Call super class always for java.security.debug tracing. - super.checkPermission(perm, context); - checkPermission(perm, new SecurityException(perm.toString())); - } catch (SecurityException se) { - checkPermission(perm, se); - } - } - - private void checkPermission(java.security.Permission perm, SecurityException se) { - if (secure && perm instanceof LoggingPermission) { - throw se; - } else { - if (debug) { - securityDebugPrint(se); - } - } - } - } - public static final class GaeErrorManager extends MessageErrorManager { public GaeErrorManager(MailHandler h) { @@ -8203,53 +7622,6 @@ protected void error(MimeMessage message, Throwable t, int code) { } } - public static final class GaeSecurityManager extends SecurityManager { - - boolean secure = false; - private final boolean debug; - - public GaeSecurityManager() { - debug = isSecurityDebug(); - } - - @Override - public void checkPermission(java.security.Permission perm) { - try { //Call super class always for java.security.debug tracing. - super.checkPermission(perm); - checkPermission(perm, new SecurityException(perm.toString())); - } catch (SecurityException se) { - checkPermission(perm, se); - } - } - - @Override - public void checkPermission(java.security.Permission perm, Object context) { - try { //Call super class always for java.security.debug tracing. - super.checkPermission(perm, context); - checkPermission(perm, new SecurityException(perm.toString())); - } catch (SecurityException se) { - checkPermission(perm, se); - } - } - - private void checkPermission(java.security.Permission perm, SecurityException se) { - if (secure && perm instanceof LoggingPermission) { - final StackTraceElement[] stack = se.getStackTrace(); - if (stack.length == 0) { - Assume.assumeNoException(se); - } - for (StackTraceElement e : stack) { - if (Handler.class.getName().equals(e.getClassName())) { - throw se; - } - } - } - if (debug) { - securityDebugPrint(se); - } - } - } - public static class ErrorFormatter extends Formatter { @Override @@ -8963,53 +8335,34 @@ public boolean isLoggable(LogRecord record) { } } - private final static class ClassLoaderSecurityManager extends SecurityManager { - - volatile boolean secure = false; + private final static class ClassLoaderThread extends Thread { + volatile boolean secure; private final boolean debug; - public ClassLoaderSecurityManager() { + public ClassLoaderThread(Runnable r) { + super(r); debug = isSecurityDebug(); } @Override - public void checkPermission(java.security.Permission perm) { - try { //Call super class always for java.security.debug tracing. - super.checkPermission(perm); - checkPermission(perm, new SecurityException(perm.toString())); - } catch (SecurityException se) { - checkPermission(perm, se); + public void setContextClassLoader(ClassLoader cl) { + if (secure) { + throw new SecurityException(); } - } - @Override - public void checkPermission(java.security.Permission perm, Object context) { - try { //Call super class always for java.security.debug tracing. - super.checkPermission(perm, context); - checkPermission(perm, new SecurityException(perm.toString())); - } catch (SecurityException se) { - checkPermission(perm, se); + if (debug) { + securityDebugPrint(new SecurityException()); } + super.setContextClassLoader(cl); } @Override - public void checkRead(String file, Object context) { - } - - @Override - public void checkRead(String file) { - } - - private void checkPermission(java.security.Permission perm, SecurityException se) { - //Check for set and get context class loader. - String name = perm.getName(); - if (secure && name.contains("ContextClassLoader")) { - throw se; - } else { - if (debug) { - securityDebugPrint(se); - } + public ClassLoader getContextClassLoader() { + //It is too strict to enforce security here + if (debug) { + securityDebugPrint(new SecurityException()); } + return super.getContextClassLoader(); } }