package net.md_5.bungee; import java.io.PrintWriter; import java.io.StringWriter; import java.security.AccessControlException; import java.security.Permission; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; import net.md_5.bungee.api.ProxyServer; import net.md_5.bungee.api.scheduler.GroupedThreadFactory; public class BungeeSecurityManager extends SecurityManager { private static final boolean ENFORCE = false; private final Set<String> seen = new HashSet<>(); private void checkRestricted(String text) { Class[] context = getClassContext(); for ( int i = 2; i < context.length; i++ ) { ClassLoader loader = context[i].getClassLoader(); // Bungee / system can do everything if ( loader == ClassLoader.getSystemClassLoader() || loader == null ) { break; } AccessControlException ex = new AccessControlException( "Plugin violation: " + text ); if ( ENFORCE ) { throw ex; } StringWriter stack = new StringWriter(); ex.printStackTrace( new PrintWriter( stack ) ); if ( seen.add( stack.toString() ) ) { ProxyServer.getInstance().getLogger().log( Level.WARNING, "Plugin performed restricted action, please inform them to use proper API methods: " + text, ex ); } break; } } @Override public void checkExit(int status) { checkRestricted( "Exit: Cannot close VM" ); } @Override public void checkAccess(ThreadGroup g) { if ( !( g instanceof GroupedThreadFactory.BungeeGroup ) ) { checkRestricted( "Illegal thread group access" ); } } @Override public void checkPermission(Permission perm, Object context) { checkPermission( perm ); } @Override public void checkPermission(Permission perm) { switch ( perm.getName() ) { case "setSecurityManager": throw new AccessControlException( "Restricted Action", perm ); } } }