diff --git a/pom.xml b/pom.xml index 1d0736cf95..3a54508162 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.ghostchu.peerbanhelper peerbanhelper - 7.1.0-beta1 + 7.1.0 jar PeerBanHelper diff --git a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnConfig.java b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnConfig.java index f3a9af208f..1f8bc7fd3b 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnConfig.java +++ b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnConfig.java @@ -34,7 +34,8 @@ public BtnNetwork btnNetwork() { var submit = server.getMainConfig().getBoolean("btn.submit"); var appId = server.getMainConfig().getString("btn.app-id"); var appSecret = server.getMainConfig().getString("btn.app-secret"); - BtnNetwork btnNetwork = new BtnNetwork(server, scriptEngine, userAgent, configUrl, submit, appId, appSecret, matchCache); + var scriptExecute = server.getMainConfig().getBoolean("btn.allow-script-execute"); + BtnNetwork btnNetwork = new BtnNetwork(server, scriptEngine, userAgent, configUrl, submit, appId, appSecret, matchCache, scriptExecute); log.info(tlUI(Lang.BTN_NETWORK_ENABLED)); return btnNetwork; } else { diff --git a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnNetwork.java b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnNetwork.java index 0d1ade59c3..4d6794d7a1 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnNetwork.java +++ b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnNetwork.java @@ -37,6 +37,7 @@ public class BtnNetwork { @Getter private final Map, BtnAbility> abilities = new HashMap<>(); private final ScriptEngine scriptEngine; + private final boolean scriptExecute; @Getter private ScheduledExecutorService executeService = null; private String configUrl; @@ -54,7 +55,7 @@ public class BtnNetwork { private PeerRecordDao peerRecordDao; private ModuleMatchCache moduleMatchCache; - public BtnNetwork(PeerBanHelperServer server, ScriptEngine scriptEngine, String userAgent, String configUrl, boolean submit, String appId, String appSecret, ModuleMatchCache moduleMatchCache) { + public BtnNetwork(PeerBanHelperServer server, ScriptEngine scriptEngine, String userAgent, String configUrl, boolean submit, String appId, String appSecret, ModuleMatchCache moduleMatchCache, boolean scriptExecute) { this.server = server; this.scriptEngine = scriptEngine; this.userAgent = userAgent; @@ -63,6 +64,7 @@ public BtnNetwork(PeerBanHelperServer server, ScriptEngine scriptEngine, String this.appId = appId.trim(); this.appSecret = appSecret.trim(); this.moduleMatchCache = moduleMatchCache; + this.scriptExecute = scriptExecute; setupHttpClient(); resetScheduler(); checkIfNeedRetryConfig(); @@ -112,7 +114,7 @@ public void configBtnNetwork() { // abilities.put(BtnAbilitySubmitRulesHitRate.class, new BtnAbilitySubmitRulesHitRate(this, ability.get("submit_hitrate").getAsJsonObject())); // } if (ability.has("rules")) { - abilities.put(BtnAbilityRules.class, new BtnAbilityRules(this, scriptEngine, ability.get("rules").getAsJsonObject())); + abilities.put(BtnAbilityRules.class, new BtnAbilityRules(this, scriptEngine, ability.get("rules").getAsJsonObject(), scriptExecute)); } if (ability.has("reconfigure")) { abilities.put(BtnAbilityReconfigure.class, new BtnAbilityReconfigure(this, ability.get("reconfigure").getAsJsonObject())); diff --git a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnRuleParsed.java b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnRuleParsed.java index 0c9cefc20c..9d5e158596 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/btn/BtnRuleParsed.java +++ b/src/main/java/com/ghostchu/peerbanhelper/btn/BtnRuleParsed.java @@ -33,14 +33,14 @@ public class BtnRuleParsed { private Map> portRules; private Map scriptRules; - public BtnRuleParsed(ScriptEngine scriptEngine, BtnRule btnRule) { + public BtnRuleParsed(ScriptEngine scriptEngine, BtnRule btnRule, boolean scriptExecute) { this.scriptEngine = scriptEngine; this.version = btnRule.getVersion(); this.ipRules = parseIPRule(btnRule.getIpRules()); this.portRules = parsePortRule(btnRule.getPortRules()); this.peerIdRules = parseRule(btnRule.getPeerIdRules()); this.clientNameRules = parseRule(btnRule.getClientNameRules()); - this.scriptRules = compileScripts(btnRule.getScriptRules()); + this.scriptRules = scriptExecute ? compileScripts(btnRule.getScriptRules()) : new HashMap<>(); } private Map compileScripts(Map scriptRules) { diff --git a/src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilityRules.java b/src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilityRules.java index b297c39f94..43ce0321e1 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilityRules.java +++ b/src/main/java/com/ghostchu/peerbanhelper/btn/ability/BtnAbilityRules.java @@ -38,16 +38,18 @@ public class BtnAbilityRules extends AbstractBtnAbility { private final long randomInitialDelay; private final File btnCacheFile = new File(Main.getDataDirectory(), "btn.cache"); private final ScriptEngine scriptEngine; + private final boolean scriptExecute; @Getter private BtnRuleParsed btnRule; - public BtnAbilityRules(BtnNetwork btnNetwork, ScriptEngine scriptEngine, JsonObject ability) { + public BtnAbilityRules(BtnNetwork btnNetwork, ScriptEngine scriptEngine, JsonObject ability, boolean scriptExecute) { this.btnNetwork = btnNetwork; this.scriptEngine = scriptEngine; this.interval = ability.get("interval").getAsLong(); this.endpoint = ability.get("endpoint").getAsString(); this.randomInitialDelay = ability.get("random_initial_delay").getAsLong(); + this.scriptExecute = scriptExecute; setLastStatus(true, new TranslationComponent(Lang.BTN_STAND_BY)); } @@ -60,7 +62,7 @@ private void loadCacheFile() throws IOException { } else { try { BtnRule btnRule = JsonUtil.getGson().fromJson(Files.readString(btnCacheFile.toPath()), BtnRule.class); - this.btnRule = new BtnRuleParsed(scriptEngine, btnRule); + this.btnRule = new BtnRuleParsed(scriptEngine, btnRule, scriptExecute); } catch (Throwable ignored) { } } @@ -122,7 +124,7 @@ private void updateRule() { } else { try { BtnRule btr = JsonUtil.getGson().fromJson(r.body(), BtnRule.class); - this.btnRule = new BtnRuleParsed(scriptEngine, btr); + this.btnRule = new BtnRuleParsed(scriptEngine, btr, scriptExecute); Main.getEventBus().post(new BtnRuleUpdateEvent()); try { Files.writeString(btnCacheFile.toPath(), r.body(), StandardCharsets.UTF_8); diff --git a/src/main/java/com/ghostchu/peerbanhelper/config/MainConfigUpdateScript.java b/src/main/java/com/ghostchu/peerbanhelper/config/MainConfigUpdateScript.java index 1e63f29a61..348853e2fa 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/config/MainConfigUpdateScript.java +++ b/src/main/java/com/ghostchu/peerbanhelper/config/MainConfigUpdateScript.java @@ -29,6 +29,12 @@ private void validate() { // } } + @UpdateScript(version = 23) + public void btnScriptExecuteSwitch() { + conf.set("btn.allow-script-execute", false); + } + + @UpdateScript(version = 22) public void miscChanges() { conf.set("privacy", null); diff --git a/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java b/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java index 597aab070c..dcb476f2d7 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java +++ b/src/main/java/com/ghostchu/peerbanhelper/config/ProfileUpdateScript.java @@ -25,6 +25,8 @@ public ProfileUpdateScript(YamlConfiguration conf) { this.conf = conf; } + + @UpdateScript(version = 22) public void workaroundForBadWebUI() { if(conf.getInt("module.auto-range-ban.ipv6") == 32) { // WebUI bug diff --git a/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/BtnNetworkOnline.java b/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/BtnNetworkOnline.java index 7caca10c0f..1eb5a9f238 100644 --- a/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/BtnNetworkOnline.java +++ b/src/main/java/com/ghostchu/peerbanhelper/module/impl/rule/BtnNetworkOnline.java @@ -66,6 +66,7 @@ public class BtnNetworkOnline extends AbstractRuleFeatureModule implements Reloa private ScriptEngine scriptEngine; @Autowired private ScriptStorageDao scriptStorageDao; + private boolean allowScript; @Override @@ -156,6 +157,7 @@ public ReloadResult reloadModule() throws Exception { public void reloadConfig() { this.banDuration = getConfig().getLong("ban-duration", 0); + this.allowScript = getConfig().getBoolean("allow-script-execute"); getCache().invalidateAll(); } @@ -174,9 +176,11 @@ public boolean isThreadSafe() { if (checkExceptionResult.action() == PeerAction.SKIP) { return checkExceptionResult; } - var scriptResult = checkScript(torrent, peer, downloader, ruleExecuteExecutor); - if (scriptResult.action() != PeerAction.NO_ACTION) { - return scriptResult; + if(allowScript) { + var scriptResult = checkScript(torrent, peer, downloader, ruleExecuteExecutor); + if (scriptResult.action() != PeerAction.NO_ACTION) { + return scriptResult; + } } return checkShouldBan(torrent, peer, downloader, ruleExecuteExecutor); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index a5df61ac9e..a86f3ea351 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,4 +1,4 @@ -config-version: 22 +config-version: 23 # 设置程序语言 # Set the program language # default 跟随操作系统 (Follow the operating system) @@ -77,6 +77,11 @@ btn: # The BTN instance URL, you need find a BTN instance # By default, PBH-BTN official BTN instance will be used config-url: "https://sparkle.ghostchu.com/ping/config" + # 是否允许 PeerBanHelper 接收来自 BTN 服务器的 Aviator 脚本 + # 请仅在受信任的 BTN 服务器上启用此功能,运行来自未知来源的脚本可能会导致设备遭到攻击 + # Allow PeerBanHelper to receive Aviator script from BTN server + # Enable this option only on trusted BTN server, running script from unknown source may cause your device under attack + allow-script-execute: false # 封禁列表处理 # PBH 能够除了调用 BT 客户端的封禁 API 外,还能够进行如下操作,以便适配更多其它客户端 # Banlist invoker diff --git a/webui/src/api/model/config.ts b/webui/src/api/model/config.ts index 06d94f0313..87ea662797 100644 --- a/webui/src/api/model/config.ts +++ b/webui/src/api/model/config.ts @@ -41,6 +41,7 @@ export interface Btn { app_id: string app_secret: string config_url: string + allow_script_execute: boolean } export interface BanlistInvoker { diff --git a/webui/src/views/settings/components/config/components/btn.vue b/webui/src/views/settings/components/config/components/btn.vue index bf374b30e1..31f6790923 100644 --- a/webui/src/views/settings/components/config/components/btn.vue +++ b/webui/src/views/settings/components/config/components/btn.vue @@ -28,6 +28,18 @@ + + + + diff --git a/webui/src/views/settings/components/config/locale/en-US.ts b/webui/src/views/settings/components/config/locale/en-US.ts index 9850abee81..002a05e536 100644 --- a/webui/src/views/settings/components/config/locale/en-US.ts +++ b/webui/src/views/settings/components/config/locale/en-US.ts @@ -49,6 +49,11 @@ export default { 'All peers connected to torrents (Including: IP, Port, PeerID, UserAgent, Peer Protocol, Flags, Uploaded, Downloaded, UploadRate, DownloadRate, PeerProgress, YourProgress and Downloader Name)', 'page.settings.tab.config.btn.enableSubmit.modal.content3': 'Are you sure you want to enable submit?', + 'page.settings.tab.config.btn.allowScript': 'Allow BTN server push scripts', + 'page.settings.tab.config.btn.allowScript.warning': + 'Warning, this means that the remote server can execute any code on your device, please enable with caution!', + 'page.settings.tab.config.btn.allowScript.tips': + 'This option will allow BTN server push scripts to your device, this may increase the accuracy of the ban', 'page.settings.tab.config.ipDatabase.title': 'IP Database', 'page.settings.tab.config.ipDatabase.autoUpdate': 'Enable auto update', diff --git a/webui/src/views/settings/components/config/locale/zh-CN.ts b/webui/src/views/settings/components/config/locale/zh-CN.ts index 22d6fd4b1a..e2847b050c 100644 --- a/webui/src/views/settings/components/config/locale/zh-CN.ts +++ b/webui/src/views/settings/components/config/locale/zh-CN.ts @@ -48,6 +48,11 @@ export default { 'page.settings.tab.config.btn.enableSubmit.modal.content2': '您的 Torrent 列表(包括:Torrent 种子摘要的二次不可逆哈希和 Torrent 大小),连接到您的 Torrent 的所有 Peers (包括:IP地址、端口号、PeerID、UserAgent(ClientName),Peer协议,Peer总下载量,Peer总上传量,Peer瞬时上传速度,Peer瞬时下载速度,Peer下载进度,以及您的下载器名称)', 'page.settings.tab.config.btn.enableSubmit.modal.content3': '确定要开启提交吗?', + 'page.settings.tab.config.btn.allowScript': '允许 BTN 服务器下发脚本', + 'page.settings.tab.config.btn.allowScript.warning': + '警告,这意味着远程服务器可以在你的设备上执行任意代码,请谨慎开启', + 'page.settings.tab.config.btn.allowScript.tips': + '打开此选项后将允许 PeerBanHelper 接收并执行来自 BTN 服务器的动态脚本,这有助于提高反吸血精确度和反吸血效果。', 'page.settings.tab.config.ipDatabase.title': 'IP 数据库', 'page.settings.tab.config.ipDatabase.autoUpdate': '启用自动更新',