diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dee41439e..33c36e2ec 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -170,6 +170,12 @@ jobs: with: path: build_artifacts + - name: Create extra package + run: | + pushd ./release/extra/ + zip -9vr ../../build_artifacts/v2ray-extra.zip . + popd + - name: Generate shasum run: | go get -v github.com/v2fly/V2BuildAssist/v2buildutil @@ -205,6 +211,11 @@ jobs: name: Release.unsigned.dgst path: build_artifacts/Release.unsigned.dgst + - uses: actions/upload-artifact@v2 + with: + name: v2ray-extra.zip + path: build_artifacts/v2ray-extra.zip + - name: Upload Release.unsigned related files uses: svenstaro/upload-release-action@v2 if: github.event_name == 'release' @@ -213,3 +224,12 @@ jobs: file_glob: true file: build_artifacts/Release.unsigned* tag: ${{ github.ref }} + + - name: Upload extra package + uses: svenstaro/upload-release-action@v2 + if: github.event_name == 'release' + with: + repo_token: ${{ secrets.GITHUB_TOKEN }} + file_glob: true + file: build_artifacts/v2ray-extra.zip + tag: ${{ github.ref }} diff --git a/common/platform/securedload/embedded.go b/common/platform/securedload/embedded.go new file mode 100644 index 000000000..bb29d8d85 --- /dev/null +++ b/common/platform/securedload/embedded.go @@ -0,0 +1,6 @@ +package securedload + +const allowedHashes = `SHA256 (!#project==v2fly) = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +SHA256 (!#version==embedded) = ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +SHA256 (subscriptions/subscriptionsDefinition.v2flyTemplate) = 3f165dba7de0d7c506fbdff3275ea64b76f307df435316a3ea0914ee957793ab +` diff --git a/common/platform/securedload/embeddedhash.go b/common/platform/securedload/embeddedhash.go new file mode 100644 index 000000000..620bb4aa6 --- /dev/null +++ b/common/platform/securedload/embeddedhash.go @@ -0,0 +1,47 @@ +package securedload + +import ( + "bytes" + "crypto/sha256" + "encoding/hex" + "github.com/v2fly/VSign/insmgr" + "github.com/v2fly/VSign/signerVerify" + "github.com/v2fly/v2ray-core/v4/common/platform" + "github.com/v2fly/v2ray-core/v4/common/platform/filesystem" + "strings" +) + +type EmbeddedHashProtectedLoader struct { + checkedFile map[string]string +} + +func (e EmbeddedHashProtectedLoader) VerifyAndLoad(filename string) ([]byte, error) { + filecontent, err := filesystem.ReadFile(platform.GetAssetLocation(filename)) + if err != nil { + return nil, newError("Cannot find file", filename).Base(err) + } + fileHash := sha256.Sum256(filecontent) + fileHashAsString := hex.EncodeToString(fileHash[:]) + if filenameverified, ok := e.checkedFile[fileHashAsString]; ok { + for _, filenameVerifiedIndividual := range strings.Split(filenameverified, ";") { + if strings.HasSuffix(filenameVerifiedIndividual, filename) { + return filecontent, nil + } + } + + } + return nil, newError("Unrecognized file at ", filename, " can not be loaded for execution") +} + +func NewEmbeddedHashProtectedLoader() *EmbeddedHashProtectedLoader { + instructions := insmgr.ReadAllIns(bytes.NewReader([]byte(allowedHashes))) + checkedFile, _, ok := signerVerify.CheckAsClient(instructions, "v2fly", true) + if !ok { + panic("Embedded Hash data is invalid") + } + return &EmbeddedHashProtectedLoader{checkedFile: checkedFile} +} + +func init() { + RegisterProtectedLoader("embedded", NewEmbeddedHashProtectedLoader()) +} diff --git a/common/platform/securedload/errors.generated.go b/common/platform/securedload/errors.generated.go new file mode 100644 index 000000000..83d7c7cbb --- /dev/null +++ b/common/platform/securedload/errors.generated.go @@ -0,0 +1,9 @@ +package securedload + +import "github.com/v2fly/v2ray-core/v4/common/errors" + +type errPathObjHolder struct{} + +func newError(values ...interface{}) *errors.Error { + return errors.New(values...).WithPathObj(errPathObjHolder{}) +} diff --git a/common/platform/securedload/file.go b/common/platform/securedload/file.go new file mode 100644 index 000000000..8b87ec517 --- /dev/null +++ b/common/platform/securedload/file.go @@ -0,0 +1,13 @@ +package securedload + +func GetAssetSecured(name string) ([]byte, error) { + var err error + for k, v := range knownProtectedLoader { + if loadedData, errLoad := v.VerifyAndLoad(name); errLoad == nil { + return loadedData, nil + } else { + err = newError(k, " is not loading executable file").Base(errLoad) + } + } + return nil, err +} diff --git a/common/platform/securedload/securedload.go b/common/platform/securedload/securedload.go new file mode 100644 index 000000000..af4e95758 --- /dev/null +++ b/common/platform/securedload/securedload.go @@ -0,0 +1,3 @@ +package securedload + +//go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen diff --git a/common/platform/securedload/verify.go b/common/platform/securedload/verify.go new file mode 100644 index 000000000..0220d07c1 --- /dev/null +++ b/common/platform/securedload/verify.go @@ -0,0 +1,14 @@ +package securedload + +type ProtectedLoader interface { + VerifyAndLoad(filename string) ([]byte, error) +} + +var knownProtectedLoader map[string]ProtectedLoader + +func RegisterProtectedLoader(name string, sv ProtectedLoader) { + if knownProtectedLoader == nil { + knownProtectedLoader = map[string]ProtectedLoader{} + } + knownProtectedLoader[name] = sv +}