summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/net/geedge/api/controller/APIController.java57
-rw-r--r--src/main/java/net/geedge/api/util/AdbCommandBuilder.java62
-rw-r--r--src/main/java/net/geedge/api/util/AdbUtil.java108
-rw-r--r--src/main/java/net/geedge/common/Constant.java6
4 files changed, 231 insertions, 2 deletions
diff --git a/src/main/java/net/geedge/api/controller/APIController.java b/src/main/java/net/geedge/api/controller/APIController.java
index db2eee3..397b210 100644
--- a/src/main/java/net/geedge/api/controller/APIController.java
+++ b/src/main/java/net/geedge/api/controller/APIController.java
@@ -189,4 +189,61 @@ public class APIController {
Integer timeout = T.MapUtil.getInt(requestBody, "timeout", 10);
return R.ok().putData("result", adbUtil.execShellCommand(cmd, timeout));
}
+
+ @GetMapping("/acl")
+ public R listAcl() {
+ return R.ok().putData("records", adbUtil.listAcl());
+ }
+
+ @PostMapping("/acl")
+ public R addAcl(@RequestBody Map<String, Object> requestBody) {
+ String ip = T.MapUtil.getStr(requestBody, "ip");
+ String port = T.MapUtil.getStr(requestBody, "port");
+ if (T.StrUtil.isAllEmpty(ip, port)) {
+ return R.error(RCode.BAD_REQUEST);
+ }
+
+ String protocol = T.MapUtil.getStr(requestBody, "protocol", "all");
+ if (!T.StrUtil.equalsAny(protocol, "tcp", "udp", "all")) {
+ return R.error(RCode.BAD_REQUEST);
+ }
+
+ if ("all".equals(protocol) && T.StrUtil.isEmpty(ip)) {
+ return R.error(RCode.BAD_REQUEST);
+ }
+
+ adbUtil.addAcl(protocol, ip, port);
+ return R.ok().putData("records", adbUtil.listAcl());
+ }
+
+ @DeleteMapping("/acl")
+ public R deleteAcl(@RequestBody Map<String, Object> requestBody) {
+ String ip = T.MapUtil.getStr(requestBody, "ip");
+ String port = T.MapUtil.getStr(requestBody, "port");
+ if (T.StrUtil.isAllEmpty(ip, port)) {
+ return R.error(RCode.BAD_REQUEST);
+ }
+
+ String protocol = T.MapUtil.getStr(requestBody, "protocol", "all");
+ if (!T.StrUtil.equalsAny(protocol, "tcp", "udp", "all")) {
+ return R.error(RCode.BAD_REQUEST);
+ }
+
+ if ("all".equals(protocol) && T.StrUtil.isEmpty(ip)) {
+ return R.error(RCode.BAD_REQUEST);
+ }
+
+ adbUtil.deleteAcl(protocol, ip, port);
+ return R.ok().putData("records", adbUtil.listAcl());
+ }
+
+ @DeleteMapping("/acl/flush")
+ public R flushAcl() {
+ AdbUtil.CommandResult result = adbUtil.flushAcl();
+ if (0 != result.exitCode()) {
+ return R.error(result.output());
+ }
+ return R.ok();
+ }
+
} \ No newline at end of file
diff --git a/src/main/java/net/geedge/api/util/AdbCommandBuilder.java b/src/main/java/net/geedge/api/util/AdbCommandBuilder.java
index 5335d41..f77d70e 100644
--- a/src/main/java/net/geedge/api/util/AdbCommandBuilder.java
+++ b/src/main/java/net/geedge/api/util/AdbCommandBuilder.java
@@ -136,6 +136,68 @@ public class AdbCommandBuilder {
return this;
}
+ public AdbCommandBuilder buildIptablesLnRulesCommand(String chainName) {
+ this.command.add("shell");
+ this.command.add("iptables");
+ this.command.add("-nL");
+ this.command.add(chainName);
+ this.command.add("--line-numbers");
+ return this;
+ }
+
+ public AdbCommandBuilder buildIptablesAddRuleCommand(String chainName, String protocol, String ip, String port) {
+ this.command.add("shell");
+ this.command.add("iptables");
+ this.command.add("-A");
+ this.command.add(chainName);
+ this.command.add("-p");
+ this.command.add(protocol);
+
+ if (T.StrUtil.isNotEmpty(ip)) {
+ this.command.add("-d");
+ this.command.add(ip);
+ }
+
+ if (T.StrUtil.isNotEmpty(port) && !"all".equals(protocol)) {
+ this.command.add("--dport");
+ this.command.add(port);
+ }
+
+ this.command.add("-j");
+ this.command.add("ACCEPT");
+ return this;
+ }
+
+ public AdbCommandBuilder buildIptablesDelRuleCommand(String chainName, String protocol, String ip, String port) {
+ this.command.add("shell");
+ this.command.add("iptables");
+ this.command.add("-D");
+ this.command.add(chainName);
+ this.command.add("-p");
+ this.command.add(protocol);
+
+ if (T.StrUtil.isNotEmpty(ip)) {
+ this.command.add("-d");
+ this.command.add(ip);
+ }
+
+ if (T.StrUtil.isNotEmpty(port) && !"all".equals(protocol)) {
+ this.command.add("--dport");
+ this.command.add(port);
+ }
+
+ this.command.add("-j");
+ this.command.add("ACCEPT");
+ return this;
+ }
+
+ public AdbCommandBuilder buildIptablesFlushRuleCommand(String chainName) {
+ this.command.add("shell");
+ this.command.add("iptables");
+ this.command.add("-F");
+ this.command.add(chainName);
+ return this;
+ }
public List<String> build() {
return this.command;
diff --git a/src/main/java/net/geedge/api/util/AdbUtil.java b/src/main/java/net/geedge/api/util/AdbUtil.java
index c0df871..a9a609a 100644
--- a/src/main/java/net/geedge/api/util/AdbUtil.java
+++ b/src/main/java/net/geedge/api/util/AdbUtil.java
@@ -120,6 +120,9 @@ public class AdbUtil {
// 后台启动
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_STOP --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0");
this.execShellCommand("shell am start-foreground-service -n net.christianbeier.droidvnc_ng/.MainService -a net.christianbeier.droidvnc_ng.ACTION_START --es net.christianbeier.droidvnc_ng.EXTRA_ACCESS_KEY d042e2b5d5f348588a4e1a243eb7a9a0");
+
+ // 添加自定义链
+ this.addAswOutputChain();
}
/**
@@ -703,6 +706,111 @@ public class AdbUtil {
}
}
+ /**
+ * 1. 添加自定义链
+ * 2. 自定义链添加到 OUTPUT 链中
+ */
+ private void addAswOutputChain() {
+ // name=ASW_OUTPUT
+ this.execShellCommand("shell iptables -N ASW_OUTPUT");
+
+ String outputChainResult = CommandExec.exec(AdbCommandBuilder.builder()
+ .serial(this.getSerial())
+ .buildShellCommand(String.format("shell \"iptables -L OUTPUT --line-numbers | grep ASW_OUTPUT\""))
+ .build());
+ log.info("[addAswOutputChain] [ASW_OUTPUT in OUTPUT Chain] [result: {}]", outputChainResult);
+ if (T.StrUtil.isEmpty(outputChainResult)) {
+ // ASW_OUTPUT 添加到 OUTPUT 链中
+ this.execShellCommand("shell iptables -A OUTPUT -j ASW_OUTPUT");
+ }
+ }
+
+ /**
+ * ASW_OUTPUT chain rules
+ * iptables -nL ASW_OUTPUT --line-numbers
+ */
+ public List<Map> listAcl() {
+ String result = CommandExec.exec(AdbCommandBuilder.builder()
+ .serial(this.getSerial())
+ .buildIptablesLnRulesCommand("ASW_OUTPUT")
+ .build());
+
+ List<Map> chainList = T.ListUtil.list(true);
+
+ String[] lines = result.split("\\n");
+ for (String line : lines) {
+ String[] split = line.split("\\s+");
+
+ String chainIndex = T.StrUtil.trim(split[0]);
+
+ if (T.StrUtil.isNumeric(chainIndex)) {
+ String protocol = T.StrUtil.trim(split[2]);
+ Map<Object, Object> m = T.MapUtil.builder()
+ .put("num", Integer.valueOf(chainIndex))
+ .put("protocol", protocol)
+ .build();
+
+ String destIp = T.StrUtil.trim(split[5]);
+ if (!T.StrUtil.equals("0.0.0.0/0", destIp)) {
+ m.put("ip", destIp);
+ }
+
+ if (split.length == 8) {
+ String dpt = T.StrUtil.trim(split[7]);
+ dpt = dpt.replaceAll("dpt:", "");
+ if (T.StrUtil.isNumeric(chainIndex)) {
+ m.put("port", Integer.valueOf(dpt));
+ }
+ }
+ chainList.add(m);
+ }
+ }
+ return chainList;
+ }
+
+ /**
+ * add chain rule
+ * iptables -A ASW_OUTPUT -p prot -d ip --dport port -j ACCEPT
+ */
+ public void addAcl(String protocol, String ip, String port) {
+ // add chain
+ this.addAswOutputChain();
+
+ // add chain ruls
+ String result = CommandExec.exec(AdbCommandBuilder.builder()
+ .serial(this.getSerial())
+ .buildIptablesAddRuleCommand("ASW_OUTPUT", protocol, ip, port)
+ .build());
+ log.info("[addAcl] [protocol: {}] [ip: {}] [port: {}] [result: {}]", protocol, ip, port, result);
+ }
+
+
+ /**
+ * del chain rule
+ * iptables -D ASW_OUTPUT -p prot -d ip --dport port -j ACCEPT
+ */
+ public void deleteAcl(String protocol, String ip, String port) {
+ // add chain ruls
+ String result = CommandExec.exec(AdbCommandBuilder.builder()
+ .serial(this.getSerial())
+ .buildIptablesDelRuleCommand("ASW_OUTPUT", protocol, ip, port)
+ .build());
+ log.info("[deleteAcl] [protocol: {}] [ip: {}] [port: {}] [result: {}]", protocol, ip, port, result);
+ }
+
+ /**
+ * flushAcl
+ * iptables -F ASW_OUTPUT
+ */
+ public CommandResult flushAcl() {
+ String result = CommandExec.exec(AdbCommandBuilder.builder()
+ .serial(this.getSerial())
+ .buildIptablesFlushRuleCommand("ASW_OUTPUT")
+ .build());
+ log.info("[flushAcl] [result: {}]", result);
+ return new CommandResult(T.StrUtil.isNotEmpty(result) ? 1 : 0, result);
+ }
+
private synchronized ExecutorService getThreadPool() {
if (threadPool == null) {
threadPool = new ThreadPoolExecutor(
diff --git a/src/main/java/net/geedge/common/Constant.java b/src/main/java/net/geedge/common/Constant.java
index b1b4f6b..a79b36b 100644
--- a/src/main/java/net/geedge/common/Constant.java
+++ b/src/main/java/net/geedge/common/Constant.java
@@ -11,7 +11,9 @@ public class Constant {
static {
File tempPath = T.FileUtil.file(TEMP_PATH);
// 程序启动清空临时目录
- T.FileUtil.del(tempPath);
- T.FileUtil.mkdir(tempPath);
+ // T.FileUtil.del(tempPath);
+ if (!T.FileUtil.exist(tempPath)) {
+ T.FileUtil.mkdir(tempPath);
+ }
}
} \ No newline at end of file