mirror of
https://e.coding.net/circlecloud/Yum.git
synced 2024-11-22 14:28:46 +00:00
feat: 添加安全管理工具
This commit is contained in:
parent
776820e4b7
commit
d298c2c6a6
@ -11,8 +11,10 @@ import cn.citycraft.PluginHelper.config.FileConfig;
|
|||||||
import cn.citycraft.PluginHelper.utils.VersionChecker;
|
import cn.citycraft.PluginHelper.utils.VersionChecker;
|
||||||
import pw.yumc.Yum.api.YumAPI;
|
import pw.yumc.Yum.api.YumAPI;
|
||||||
import pw.yumc.Yum.commands.FileCommand;
|
import pw.yumc.Yum.commands.FileCommand;
|
||||||
|
import pw.yumc.Yum.commands.NetCommand;
|
||||||
import pw.yumc.Yum.commands.YumCommand;
|
import pw.yumc.Yum.commands.YumCommand;
|
||||||
import pw.yumc.Yum.manager.NetworkManager;
|
import pw.yumc.Yum.manager.NetworkManager;
|
||||||
|
import pw.yumc.Yum.manager.SecurityManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MC插件仓库
|
* MC插件仓库
|
||||||
@ -21,7 +23,7 @@ import pw.yumc.Yum.manager.NetworkManager;
|
|||||||
* @since 2015年8月21日下午5:14:39
|
* @since 2015年8月21日下午5:14:39
|
||||||
*/
|
*/
|
||||||
public class Yum extends JavaPlugin {
|
public class Yum extends JavaPlugin {
|
||||||
public FileConfig config;
|
FileConfig config;
|
||||||
NetworkManager netmgr;
|
NetworkManager netmgr;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -38,7 +40,9 @@ public class Yum extends JavaPlugin {
|
|||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
new YumAPI(this);
|
new YumAPI(this);
|
||||||
new YumCommand(this);
|
new YumCommand(this);
|
||||||
|
new NetCommand(this);
|
||||||
new FileCommand(this);
|
new FileCommand(this);
|
||||||
|
new SecurityManager(this);
|
||||||
new VersionChecker(this);
|
new VersionChecker(this);
|
||||||
YumAPI.updaterepo(Bukkit.getConsoleSender());
|
YumAPI.updaterepo(Bukkit.getConsoleSender());
|
||||||
YumAPI.updatecheck(Bukkit.getConsoleSender());
|
YumAPI.updatecheck(Bukkit.getConsoleSender());
|
||||||
|
@ -28,7 +28,7 @@ public class FileCommand implements HandlerCommands {
|
|||||||
plugin = yum;
|
plugin = yum;
|
||||||
dl = YumAPI.getDownload();
|
dl = YumAPI.getDownload();
|
||||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file");
|
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "file");
|
||||||
cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyFileCommandConsole", true));
|
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyFileCommandConsole", true));
|
||||||
cmdhandler.registerCommands(this);
|
cmdhandler.registerCommands(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ public class FileCommand implements HandlerCommands {
|
|||||||
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c是一个文件 请使用file delete!");
|
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c是一个文件 请使用file delete!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (final String name : plugin.config.getStringList("blacklist")) {
|
for (final String name : plugin.getConfig().getStringList("blacklist")) {
|
||||||
if (file.getAbsolutePath().toLowerCase().endsWith(name)) {
|
if (file.getAbsolutePath().toLowerCase().endsWith(name)) {
|
||||||
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c不允许被删除!");
|
sender.sendMessage("§d路径 §e" + file.getAbsolutePath() + " §c不允许被删除!");
|
||||||
return;
|
return;
|
||||||
|
@ -7,9 +7,10 @@ import cn.citycraft.PluginHelper.commands.InvokeSubCommand;
|
|||||||
import pw.yumc.Yum.Yum;
|
import pw.yumc.Yum.Yum;
|
||||||
|
|
||||||
public class NetCommand implements HandlerCommands {
|
public class NetCommand implements HandlerCommands {
|
||||||
|
|
||||||
public NetCommand(final Yum yum) {
|
public NetCommand(final Yum yum) {
|
||||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "net");
|
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "net");
|
||||||
cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyNetCommandConsole", false));
|
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyNetCommandConsole", false));
|
||||||
cmdhandler.registerCommands(this);
|
cmdhandler.registerCommands(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ public class YumCommand implements HandlerCommands, Listener {
|
|||||||
plugman = YumAPI.getPlugman();
|
plugman = YumAPI.getPlugman();
|
||||||
Bukkit.getPluginManager().registerEvents(this, yum);
|
Bukkit.getPluginManager().registerEvents(this, yum);
|
||||||
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "yum");
|
final InvokeSubCommand cmdhandler = new InvokeSubCommand(yum, "yum");
|
||||||
cmdhandler.setAllCommandOnlyConsole(yum.config.getBoolean("onlyCommandConsole", false));
|
cmdhandler.setAllCommandOnlyConsole(yum.getConfig().getBoolean("onlyCommandConsole", false));
|
||||||
cmdhandler.registerCommands(this);
|
cmdhandler.registerCommands(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import java.net.Proxy;
|
|||||||
import java.net.ProxySelector;
|
import java.net.ProxySelector;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -13,6 +12,7 @@ import org.bukkit.plugin.Plugin;
|
|||||||
|
|
||||||
import cn.citycraft.PluginHelper.config.FileConfig;
|
import cn.citycraft.PluginHelper.config.FileConfig;
|
||||||
import cn.citycraft.PluginHelper.kit.ExceptionKit;
|
import cn.citycraft.PluginHelper.kit.ExceptionKit;
|
||||||
|
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||||
import pw.yumc.Yum.Yum;
|
import pw.yumc.Yum.Yum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,7 +24,7 @@ import pw.yumc.Yum.Yum;
|
|||||||
public class NetworkManager {
|
public class NetworkManager {
|
||||||
|
|
||||||
public NetworkManager register(final Yum plugin) {
|
public NetworkManager register(final Yum plugin) {
|
||||||
Bukkit.getConsoleSender().sendMessage("§6[§bYum-网络管理§6] §a注入网络管理系统 将托管服务器网络!");
|
Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §a注入网络管理系统 将托管服务器网络!");
|
||||||
ProxySelector.setDefault(new YumProxySelector(ProxySelector.getDefault(), plugin));
|
ProxySelector.setDefault(new YumProxySelector(ProxySelector.getDefault(), plugin));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -41,7 +41,6 @@ public class NetworkManager {
|
|||||||
private final boolean allowPrimaryThread;
|
private final boolean allowPrimaryThread;
|
||||||
private final FileConfig config;
|
private final FileConfig config;
|
||||||
private final ProxySelector defaultSelector;
|
private final ProxySelector defaultSelector;
|
||||||
private final HashMap<ClassLoader, Plugin> pluginMap = new HashMap<>();
|
|
||||||
|
|
||||||
public YumProxySelector(final ProxySelector defaultSelector, final Yum plugin) {
|
public YumProxySelector(final ProxySelector defaultSelector, final Yum plugin) {
|
||||||
this.config = plugin.getConfig();
|
this.config = plugin.getConfig();
|
||||||
@ -61,19 +60,17 @@ public class NetworkManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Proxy> select(final URI uri) {
|
public List<Proxy> select(final URI uri) {
|
||||||
if (debug || Bukkit.isPrimaryThread()) {
|
final boolean isPrimaryThread = Bukkit.isPrimaryThread();
|
||||||
final Plugin plugin = this.getRequestingPlugin();
|
if (debug || isPrimaryThread) {
|
||||||
|
final Plugin plugin = PluginKit.getOperatePlugin();
|
||||||
final String urlinfo = uri.toString();
|
final String urlinfo = uri.toString();
|
||||||
if (!urlinfo.startsWith("socket") && !urlinfo.toLowerCase().contains("yumc") && !urlinfo.toLowerCase().contains("pom.xml")) {
|
if (!urlinfo.startsWith("socket") && !urlinfo.toLowerCase().contains("yumc") && !urlinfo.toLowerCase().contains("pom.xml") && !urlinfo.toLowerCase().contains("502647092")) {
|
||||||
final String str = debug ? "§6[§bYum-网络监控§6] §c插件 §6%s §c尝试访问 §e%s §c请注意服务器网络安全!" : "§6[§bYum-网络管理§6] §c插件 §6%s §c尝试在主线程访问 §e%s §4可能会导致服务器卡顿或无响应!";
|
final String str = isPrimaryThread ? "§6[§bYum §a网络管理§6] §c插件 §6%s §c尝试在主线程访问 §e%s §4可能会导致服务器卡顿或无响应!" : "§6[§bYum §a网络监控§6] §c插件 §6%s §c尝试访问 §e%s §c请注意服务器网络安全!";
|
||||||
if (plugin == null) {
|
if (plugin != null) {
|
||||||
Bukkit.getConsoleSender().sendMessage(String.format(str, "未知(请查看堆栈)", urlinfo));
|
|
||||||
Thread.dumpStack();
|
|
||||||
} else if (!plugin.getName().equalsIgnoreCase("Yum")) {
|
|
||||||
Bukkit.getConsoleSender().sendMessage(String.format(str, plugin.getName(), urlinfo));
|
Bukkit.getConsoleSender().sendMessage(String.format(str, plugin.getName(), urlinfo));
|
||||||
if (!allowPrimaryThread) {
|
if (!allowPrimaryThread && isPrimaryThread) {
|
||||||
Bukkit.getConsoleSender().sendMessage("§6[§bYum-网络管理§6] §4已阻止插件 §b" + plugin.getName() + " §4在主线程访问网络!");
|
Bukkit.getConsoleSender().sendMessage("§6[§bYum §a网络管理§6] §4已阻止插件 §b" + plugin.getName() + " §4在主线程访问网络!");
|
||||||
ExceptionKit.throwException(new IOException("[Yum-网络管理] 已开启网络防护 不允许在主线程访问网络!"));
|
ExceptionKit.throwException(new IOException("[Yum 网络防护] 已开启网络防护 不允许在主线程访问网络!"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,32 +78,6 @@ public class NetworkManager {
|
|||||||
return defaultSelector.select(uri);
|
return defaultSelector.select(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectPlugin() {
|
|
||||||
if (Bukkit.getPluginManager().getPlugins().length != pluginMap.keySet().size() - 1) {
|
|
||||||
pluginMap.clear();
|
|
||||||
for (final Plugin plugin : Bukkit.getPluginManager().getPlugins()) {
|
|
||||||
pluginMap.put(plugin.getClass().getClassLoader(), plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Plugin getRequestingPlugin() {
|
|
||||||
collectPlugin();
|
|
||||||
final StackTraceElement[] stacktrace = new Exception().getStackTrace();
|
|
||||||
for (final StackTraceElement element : stacktrace) {
|
|
||||||
try {
|
|
||||||
final ClassLoader loader = Class.forName(element.getClassName(), false, getClass().getClassLoader()).getClassLoader();
|
|
||||||
if (pluginMap.containsKey(loader)) {
|
|
||||||
final Plugin p = pluginMap.get(loader);
|
|
||||||
if (element.getClassName().contains("pw.yumc.Yum.utils.") || !p.getName().equalsIgnoreCase("Yum")) {
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (final ClassNotFoundException ex) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -30,6 +31,7 @@ import org.bukkit.plugin.PluginDescriptionFile;
|
|||||||
import org.bukkit.plugin.PluginLoader;
|
import org.bukkit.plugin.PluginLoader;
|
||||||
import org.bukkit.plugin.PluginManager;
|
import org.bukkit.plugin.PluginManager;
|
||||||
import org.bukkit.plugin.UnknownDependencyException;
|
import org.bukkit.plugin.UnknownDependencyException;
|
||||||
|
import org.bukkit.plugin.java.JavaPluginLoader;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
|
|
||||||
@ -536,8 +538,7 @@ public class PluginsManager {
|
|||||||
List<Plugin> plugins = null;
|
List<Plugin> plugins = null;
|
||||||
Map<String, Plugin> lookupNames = null;
|
Map<String, Plugin> lookupNames = null;
|
||||||
Map<String, Command> knownCommands = null;
|
Map<String, Command> knownCommands = null;
|
||||||
// ###移除类加载器后会导致插件无法载入###
|
final Map<Pattern, JavaPluginLoader> fileAssociations = null;
|
||||||
// Map<Pattern, PluginLoader> fileAssociations = null;
|
|
||||||
if (pluginManager == null) {
|
if (pluginManager == null) {
|
||||||
sender.sendMessage("§4异常: §c插件管理类反射获取失败!");
|
sender.sendMessage("§4异常: §c插件管理类反射获取失败!");
|
||||||
return false;
|
return false;
|
||||||
@ -558,11 +559,11 @@ public class PluginsManager {
|
|||||||
final Field knownCommandsField = commandMap.getClass().getDeclaredField("knownCommands");
|
final Field knownCommandsField = commandMap.getClass().getDeclaredField("knownCommands");
|
||||||
knownCommandsField.setAccessible(true);
|
knownCommandsField.setAccessible(true);
|
||||||
knownCommands = (Map<String, Command>) knownCommandsField.get(commandMap);
|
knownCommands = (Map<String, Command>) knownCommandsField.get(commandMap);
|
||||||
|
// XXX 暂时用不到
|
||||||
// ###移除类加载器后会导致插件无法载入###
|
|
||||||
// final Field fileAssociationsField = pluginManager.getClass().getDeclaredField("fileAssociations");
|
// final Field fileAssociationsField = pluginManager.getClass().getDeclaredField("fileAssociations");
|
||||||
// fileAssociationsField.setAccessible(true);
|
// fileAssociationsField.setAccessible(true);
|
||||||
// fileAssociations = (Map<Pattern, PluginLoader>) fileAssociationsField.get(pluginManager);
|
// fileAssociations = (Map<Pattern, JavaPluginLoader>) fileAssociationsField.get(pluginManager);
|
||||||
|
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
sender.sendMessage("§4异常: §c" + e.getMessage() + " 插件 §b" + name + " §c卸载失败!");
|
sender.sendMessage("§4异常: §c" + e.getMessage() + " 插件 §b" + name + " §c卸载失败!");
|
||||||
return false;
|
return false;
|
||||||
@ -592,16 +593,39 @@ public class PluginsManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// try {
|
||||||
|
// if (fileAssociations != null) {
|
||||||
|
// // XXX 不能移除 会导致无法加载
|
||||||
|
// for (final Iterator<Entry<Pattern, JavaPluginLoader>> filter = fileAssociations.entrySet().iterator(); filter.hasNext();) {
|
||||||
|
// final Entry<Pattern, JavaPluginLoader> entry = filter.next();
|
||||||
|
// final Matcher match = entry.getKey().matcher(getPluginFile(next).getName());
|
||||||
|
// if (match.find()) {
|
||||||
|
// final JavaPluginLoader pluginLoader = entry.getValue();
|
||||||
|
// final Field loadersField = pluginLoader.getClass().getDeclaredField("loaders");
|
||||||
|
// loadersField.setAccessible(true);
|
||||||
|
// final Map<String, URLClassLoader> loaders = (Map<String, URLClassLoader>) loadersField.get(pluginLoader);
|
||||||
|
// // XXX 不能移除 会导致无法调用其他插件
|
||||||
|
// loaders.clear();
|
||||||
|
// sender.sendMessage("§6卸载: §a移除插件 §b" + name + " §a的类实例缓存!");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (final Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
sender.sendMessage("§6卸载: §a注销插件 §b" + name + " §a的所有命令!");
|
sender.sendMessage("§6卸载: §a注销插件 §b" + name + " §a的所有命令!");
|
||||||
final ClassLoader cl = next.getClass().getClassLoader();
|
final ClassLoader cl = next.getClass().getClassLoader();
|
||||||
try {
|
try {
|
||||||
((URLClassLoader) cl).close();
|
((URLClassLoader) cl).close();
|
||||||
} catch (final IOException ex) {
|
} catch (final IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
System.gc();
|
System.gc();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pluginVersion.isEmpty()) {
|
if (!pluginVersion.isEmpty())
|
||||||
|
|
||||||
|
{
|
||||||
sender.sendMessage("§6卸载: §a插件 §b" + name + " §a版本 §d" + pluginVersion + " §a已成功卸载!");
|
sender.sendMessage("§6卸载: §a插件 §b" + name + " §a版本 §d" + pluginVersion + " §a已成功卸载!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
36
src/main/java/pw/yumc/Yum/manager/SecurityManager.java
Normal file
36
src/main/java/pw/yumc/Yum/manager/SecurityManager.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package pw.yumc.Yum.manager;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
|
|
||||||
|
import cn.citycraft.PluginHelper.kit.PluginKit;
|
||||||
|
import pw.yumc.Yum.Yum;
|
||||||
|
import pw.yumc.injected.event.SetOpEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @since 2016年3月31日 下午3:01:22
|
||||||
|
* @author 喵♂呜
|
||||||
|
*/
|
||||||
|
public class SecurityManager implements Listener {
|
||||||
|
public String warn = "§6[§bYum §a安全系统§6] §c插件 §e%s §c已设置玩家 §a%s §c为OP §4请注意服务器安全!";
|
||||||
|
public String prevent = "§6[§bYum §a安全系统§6] §c黑名单插件 §e%s §c尝试设置玩家 §a%s §c为OP §a安全系统已成功拦截!";
|
||||||
|
|
||||||
|
public SecurityManager(final Yum yum) {
|
||||||
|
Bukkit.getPluginManager().registerEvents(this, yum);
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void setop(final SetOpEvent event) {
|
||||||
|
final Plugin plugin = PluginKit.getOperatePlugin();
|
||||||
|
if (plugin != null) {
|
||||||
|
if (plugin.getName().equalsIgnoreCase("BukkitInjectedTools")) {
|
||||||
|
Bukkit.getConsoleSender().sendMessage(String.format(prevent, plugin, event.getOfflinePlayer().getName()));
|
||||||
|
} else {
|
||||||
|
Bukkit.getConsoleSender().sendMessage(String.format(warn, plugin, event.getOfflinePlayer().getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ name: ${project.artifactId}
|
|||||||
description: ${project.description}
|
description: ${project.description}
|
||||||
main: ${project.groupId}.${project.artifactId}.${project.artifactId}
|
main: ${project.groupId}.${project.artifactId}.${project.artifactId}
|
||||||
version: ${project.version}-git-${env.GIT_COMMIT}
|
version: ${project.version}-git-${env.GIT_COMMIT}
|
||||||
|
load: STARTUP
|
||||||
author: 喵♂呜
|
author: 喵♂呜
|
||||||
website: ${ciManagement.url}
|
website: ${ciManagement.url}
|
||||||
commands:
|
commands:
|
||||||
@ -23,6 +24,12 @@ commands:
|
|||||||
usage: §6使用§a/file help§6查看帮助!
|
usage: §6使用§a/file help§6查看帮助!
|
||||||
permission: file.use
|
permission: file.use
|
||||||
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||||
|
security:
|
||||||
|
description: MC安全管理命令
|
||||||
|
aliases: [f]
|
||||||
|
usage: §6使用§a/security help§6查看帮助!
|
||||||
|
permission: file.use
|
||||||
|
permission-message: §c你没有 <permission> 的权限来执行此命令!
|
||||||
permissions:
|
permissions:
|
||||||
yum.use:
|
yum.use:
|
||||||
description: 插件管理系统使用权限!
|
description: 插件管理系统使用权限!
|
||||||
|
Loading…
Reference in New Issue
Block a user