/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.system.security; import java.io.FileNotFoundException; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.security.AccessControlException; import java.security.AccessController; import java.security.Permission; import java.security.PrivilegedAction; /** * A Security Manager that is useful for debugging access exceptions * because the default security manager in the JDK can be very verbose * and difficult to debug * * <b> NOTE:</b> Do not use this security manager in production. * * <b> USAGE:</b> -Djava.security.manager -Djava.security.manager=org.jboss.system.security.DebuggingJavaSecurityManager * * @author Anil.Saldhana@redhat.com * @since Mar 26, 2010 */ @SuppressWarnings("unchecked") public class DebuggingJavaSecurityManager extends SecurityManager { FilteringPrintStream fps = null; /** * JBoss Logging Subsystem tries to install its own stdout/stderr which can * mess around with this debugging security manager which installs a filtering * print stream (as the JDK Java Security Manager runs in a full debug mode) */ private boolean settingStream = false; /** * We are filtering the log entries. We do not want to see the verbose * "access allowed" console entries from the Java Security Manager */ private static boolean turnOnLogging = false; public DebuggingJavaSecurityManager() { AccessController.doPrivileged( new PrivilegedAction() { @Override public Object run() { try { fps = new FilteringPrintStream(); setStreams(); } catch(Exception e) { e.printStackTrace(); }return null; }}); } public void checkRead(final String file) { //We blank this method to avoid a stack over flow error } @Override public void checkPermission(final Permission perm) { turnOnLogging = false; try { if(System.err != fps ) setStreams(); super.checkPermission(perm); } catch( AccessControlException ace ) { turnOnLogging = true; throw ace; } } private static class FilteringPrintStream extends PrintStream { private PrintStream ps; public FilteringPrintStream( ) throws FileNotFoundException { super( new DummyOutputStream() ); this.ps = System.err; } @Override public void println(String x) { if( DebuggingJavaSecurityManager.turnOnLogging == false ) { if( x.contains( "allowed") ) return; if( x.contains( "domain that failed ProtectionDomain") || x.contains( "Confirming") || x.contains("denied") || x.contains( "Exception" ) ) { ps.println(x); } } } public void print(String s) { ps.print(s); } } private static class DummyOutputStream extends OutputStream { @Override public void write(int b) throws IOException { } } /** * Since the JBoss Logging Subsystem can install its own std err/output stream, it is very * important for debugging purposes to set the security manager output to our custom * PrintStream. */ private void setStreams() { AccessController.doPrivileged( new PrivilegedAction() { @Override public Object run() { try { //recursive check may be happening if (settingStream == true ) return null; settingStream = true; System.err.println( " "); System.err.println( " "); System.err.println( "*** Java Security Manager is the one for debugging. DO NOT USE THIS IN PRODUCTION ****"); System.err.println( " "); System.err.println( " "); System.err.println( " "); System.err.println( " "); System.err.println( "WE ARE SETTING THE error and output streams to FILTERINGPRINTSTREAM (Not for ***Production*** Use)"); if( fps == null) fps = new FilteringPrintStream(); System.setErr( fps); System.setOut(fps); System.err.println( "Confirming that the error stream is set to FILTERINGPRINTSTREAM : " + (fps == System.err)); settingStream = false; } catch(Exception e) { e.printStackTrace(); }return null; }}); } }