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 );
}
}
}