diff --git a/README.md b/README.md
index e68fe4c..2d713a3 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ JDK 1.7 +
com.github.core-lib
xjar
- 4.0.1
+ 4.0.2
@@ -188,7 +188,7 @@ xjar java --add-opens java.base/jdk.internal.loader=ALL-UNNAMED -jar /path/to/en
com.github.core-lib
xjar-maven-plugin
- 4.0.1
+ 4.0.2
@@ -262,6 +262,8 @@ mvn clean install -Dxjar.password=io.xjar -Dxjar.targetDir=/directory/to/save/ta
更多文档:[xjar-maven-plugin](https://github.com/core-lib/xjar-maven-plugin)
## 版本记录
+* 4.0.2
+ 1. 安全性升级
* 4.0.1
1. 兼容JDK-9及以上版本
* 4.0.0
diff --git a/pom.xml b/pom.xml
index d2a4c1c..09c6777 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
io.xjar
xjar
- 4.0.1
+ 4.0.2
xjar
diff --git a/src/main/java/io/xjar/XGo.java b/src/main/java/io/xjar/XGo.java
index 94c7b6a..c0ae5cd 100644
--- a/src/main/java/io/xjar/XGo.java
+++ b/src/main/java/io/xjar/XGo.java
@@ -5,7 +5,9 @@
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -34,31 +36,34 @@ public static void make(File xJar, XKey xKey) throws IOException {
variables.put("xKey.ivsize", convert(ivsize));
variables.put("xKey.password", convert(password));
- URL url = XGo.class.getClassLoader().getResource("xjar/xjar.go");
- if (url == null) {
- throw new IOException("could not find xjar.go");
- }
- String dir = xJar.getParent();
- File src = new File(dir, "xjar.go");
- try (
- InputStream in = url.openStream();
- Reader reader = new InputStreamReader(in);
- BufferedReader br = new BufferedReader(reader);
- OutputStream out = new FileOutputStream(src);
- Writer writer = new OutputStreamWriter(out);
- BufferedWriter bw = new BufferedWriter(writer)
- ) {
- String line;
- while ((line = br.readLine()) != null) {
- for (Map.Entry variable : variables.entrySet()) {
- line = line.replace("#{" + variable.getKey() + "}", variable.getValue());
+ List templates = Arrays.asList("xjar.go", "xjar_agentable.go");
+ for (String template : templates) {
+ URL url = XGo.class.getClassLoader().getResource("xjar/" + template);
+ if (url == null) {
+ throw new IOException("could not find xjar/" + template + " in classpath");
+ }
+ String dir = xJar.getParent();
+ File src = new File(dir, template);
+ try (
+ InputStream in = url.openStream();
+ Reader reader = new InputStreamReader(in);
+ BufferedReader br = new BufferedReader(reader);
+ OutputStream out = new FileOutputStream(src);
+ Writer writer = new OutputStreamWriter(out);
+ BufferedWriter bw = new BufferedWriter(writer)
+ ) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ for (Map.Entry variable : variables.entrySet()) {
+ line = line.replace("#{" + variable.getKey() + "}", variable.getValue());
+ }
+ bw.write(line);
+ bw.write(CLRF);
}
- bw.write(line);
- bw.write(CLRF);
+ bw.flush();
+ writer.flush();
+ out.flush();
}
- bw.flush();
- writer.flush();
- out.flush();
}
}
diff --git a/src/main/resources/xjar/xjar.go b/src/main/resources/xjar/xjar.go
index e08c6fc..956c69e 100644
--- a/src/main/resources/xjar/xjar.go
+++ b/src/main/resources/xjar/xjar.go
@@ -10,6 +10,7 @@ import (
"os"
"os/exec"
"path/filepath"
+ "strings"
)
var xJar = XJar{
@@ -55,6 +56,18 @@ func main() {
panic(errors.New("invalid jar with SHA-1"))
}
+ // check agent forbid
+ {
+ args := os.Args
+ l := len(args)
+ for i := 0; i < l; i++ {
+ arg := args[i]
+ if strings.HasPrefix(arg, "-javaagent:") {
+ panic(errors.New("agent forbidden"))
+ }
+ }
+ }
+
// start java application
java := os.Args[1]
args := os.Args[2:]
diff --git a/src/main/resources/xjar/xjar_agentable.go b/src/main/resources/xjar/xjar_agentable.go
new file mode 100644
index 0000000..e08c6fc
--- /dev/null
+++ b/src/main/resources/xjar/xjar_agentable.go
@@ -0,0 +1,134 @@
+package main
+
+import (
+ "bytes"
+ "crypto/md5"
+ "crypto/sha1"
+ "errors"
+ "hash"
+ "io"
+ "os"
+ "os/exec"
+ "path/filepath"
+)
+
+var xJar = XJar{
+ md5: []byte{#{xJar.md5}},
+ sha1: []byte{#{xJar.sha1}},
+}
+
+var xKey = XKey{
+ algorithm: []byte{#{xKey.algorithm}},
+ keysize: []byte{#{xKey.keysize}},
+ ivsize: []byte{#{xKey.ivsize}},
+ password: []byte{#{xKey.password}},
+}
+
+func main() {
+ // search the jar to start
+ jar, err := JAR(os.Args)
+ if err != nil {
+ panic(err)
+ }
+
+ // parse jar name to absolute path
+ path, err := filepath.Abs(jar)
+ if err != nil {
+ panic(err)
+ }
+
+ // verify jar with MD5
+ MD5, err := MD5(path)
+ if err != nil {
+ panic(err)
+ }
+ if bytes.Compare(MD5, xJar.md5) != 0 {
+ panic(errors.New("invalid jar with MD5"))
+ }
+
+ // verify jar with SHA-1
+ SHA1, err := SHA1(path)
+ if err != nil {
+ panic(err)
+ }
+ if bytes.Compare(SHA1, xJar.sha1) != 0 {
+ panic(errors.New("invalid jar with SHA-1"))
+ }
+
+ // start java application
+ java := os.Args[1]
+ args := os.Args[2:]
+ key := bytes.Join([][]byte{
+ xKey.algorithm, {13, 10},
+ xKey.keysize, {13, 10},
+ xKey.ivsize, {13, 10},
+ xKey.password, {13, 10},
+ }, []byte{})
+ cmd := exec.Command(java, args...)
+ cmd.Stdin = bytes.NewReader(key)
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ err = cmd.Run()
+ if err != nil {
+ panic(err)
+ }
+}
+
+// find jar name from args
+func JAR(args []string) (string, error) {
+ var jar string
+
+ l := len(args)
+ for i := 1; i < l-1; i++ {
+ arg := args[i]
+ if arg == "-jar" {
+ jar = args[i+1]
+ }
+ }
+
+ if jar == "" {
+ return "", errors.New("unspecified jar name")
+ }
+
+ return jar, nil
+}
+
+// calculate file's MD5
+func MD5(path string) ([]byte, error) {
+ return HASH(path, md5.New())
+}
+
+// calculate file's SHA-1
+func SHA1(path string) ([]byte, error) {
+ return HASH(path, sha1.New())
+}
+
+// calculate file's HASH value with specified HASH Algorithm
+func HASH(path string, hash hash.Hash) ([]byte, error) {
+ file, err := os.Open(path)
+
+ if err != nil {
+ return nil, err
+ }
+
+ _, _err := io.Copy(hash, file)
+ if _err != nil {
+ return nil, _err
+ }
+
+ sum := hash.Sum(nil)
+
+ return sum, nil
+}
+
+type XJar struct {
+ md5 []byte
+ sha1 []byte
+}
+
+type XKey struct {
+ algorithm []byte
+ keysize []byte
+ ivsize []byte
+ password []byte
+}