diff --git a/api/src/main/java/net/md_5/bungee/api/scheduler/TaskScheduler.java b/api/src/main/java/net/md_5/bungee/api/scheduler/TaskScheduler.java index d4cfe8a7..359c3632 100644 --- a/api/src/main/java/net/md_5/bungee/api/scheduler/TaskScheduler.java +++ b/api/src/main/java/net/md_5/bungee/api/scheduler/TaskScheduler.java @@ -1,5 +1,6 @@ package net.md_5.bungee.api.scheduler; +import java.util.concurrent.ExecutorService; import java.util.concurrent.TimeUnit; import net.md_5.bungee.api.plugin.Plugin; @@ -71,4 +72,22 @@ public interface TaskScheduler * @return the scheduled task */ ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit); + + /** + * Get the unsafe methods of this class. + * + * @return the unsafe method interface + */ + Unsafe unsafe(); + + interface Unsafe + { + + /** + * An executor service which underlies this scheduler. + * + * @return the underlying executor service or compatible wrapper + */ + ExecutorService getExecutorService(); + } } diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index e523590e..638d9111 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -159,6 +159,8 @@ public class BungeeCord extends ProxyServer public BungeeCord() throws IOException { + System.setSecurityManager( new BungeeSecurityManager() ); + try { bundle = ResourceBundle.getBundle( "messages" ); diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeSecurityManager.java b/proxy/src/main/java/net/md_5/bungee/BungeeSecurityManager.java new file mode 100644 index 00000000..f169eabb --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/BungeeSecurityManager.java @@ -0,0 +1,58 @@ +package net.md_5.bungee; + +import java.security.AccessControlException; +import java.security.Permission; +import java.util.logging.Level; +import net.md_5.bungee.api.ProxyServer; + +public class BungeeSecurityManager extends SecurityManager +{ + + private static final boolean ENFORCE = false; + + private void checkRestricted(String text) + { + Class[] context = getClassContext(); + for ( int i = 2; i < context.length; i++ ) + { + ClassLoader loader = context[i].getClassLoader(); + + // Bungee can do everything + if ( loader == ClassLoader.getSystemClassLoader() ) + { + break; + } + + // Everyone but system can't do anything + if ( loader != null ) + { + AccessControlException ex = new AccessControlException( "Plugin violation: " + text ); + if ( ENFORCE ) + { + throw ex; + } + + 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 ThreadGroup getThreadGroup() + { + checkRestricted( "Thread Creation: Use scheduler" ); + return super.getThreadGroup(); + } + + @Override + public void checkPermission(Permission perm) + { + } +} diff --git a/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeScheduler.java b/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeScheduler.java index 53048d2d..06568a90 100644 --- a/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeScheduler.java +++ b/proxy/src/main/java/net/md_5/bungee/scheduler/BungeeScheduler.java @@ -25,6 +25,16 @@ public class BungeeScheduler implements TaskScheduler private final AtomicInteger taskCounter = new AtomicInteger(); private final TIntObjectMap tasks = TCollections.synchronizedMap( new TIntObjectHashMap() ); private final Multimap tasksByPlugin = Multimaps.synchronizedMultimap( HashMultimap.create() ); + // + private final Unsafe unsafe = new Unsafe() + { + + @Override + public ExecutorService getExecutorService() + { + return s; + } + }; public void shutdown() { @@ -82,4 +92,10 @@ public class BungeeScheduler implements TaskScheduler s.execute( prepared ); return prepared; } + + @Override + public Unsafe unsafe() + { + return unsafe; + } }