From 4a0b952ba829f03440cb31b955e28f87231b9f75 Mon Sep 17 00:00:00 2001 From: Mickael Kerjean Date: Tue, 20 Aug 2019 00:34:24 +1000 Subject: [PATCH] improve (build): make build reproducible and easy to inspect/verify --- Makefile | 2 +- server/common/constants.go | 3 ++- server/common/crypto.go | 40 +++++++++++++++++++++----------------- server/common/default.go | 2 +- server/common/response.go | 3 +-- server/ctrl/static.go | 31 ++++++++++++++++++++++------- server/middleware/http.go | 2 +- 7 files changed, 52 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index 4abf7d37..b607fa93 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,4 @@ build_frontend: NODE_ENV=production npm run build build_backend: - PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ CGO_CFLAGS_ALLOW='-fopenmp' go build --tags "fts5" -ldflags "-X github.com/mickael-kerjean/filestash/server/common.BUILD_NUMBER=`date -u +%Y%m%d`" -o dist/filestash server/main.go + PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ CGO_CFLAGS_ALLOW='-fopenmp' go build --tags "fts5" -ldflags "-X github.com/mickael-kerjean/filestash/server/common.BUILD_DATE=`date -u +%Y%m%d` -X github.com/mickael-kerjean/filestash/server/common.BUILD_REF=`git rev-parse HEAD`" -o dist/filestash server/main.go diff --git a/server/common/constants.go b/server/common/constants.go index 03e1cc43..60ffb84b 100644 --- a/server/common/constants.go +++ b/server/common/constants.go @@ -34,7 +34,8 @@ func init(){ var ( - BUILD_NUMBER string + BUILD_REF string + BUILD_DATE string SECRET_KEY string SECRET_KEY_DERIVATE_FOR_PROOF string SECRET_KEY_DERIVATE_FOR_ADMIN string diff --git a/server/common/crypto.go b/server/common/crypto.go index 19b5dfdc..8f95cbb7 100644 --- a/server/common/crypto.go +++ b/server/common/crypto.go @@ -8,6 +8,7 @@ import ( "crypto/rand" "crypto/sha256" "encoding/base64" + "encoding/hex" "hash/fnv" "io" "io/ioutil" @@ -50,31 +51,34 @@ func DecryptString(secret string, data string) (string, error){ func Hash(str string, n int) string { hasher := sha256.New() hasher.Write([]byte(str)) - d := hasher.Sum(nil) - h := "" - for i:=0; i 0 && len(h) >= n { - break - } - h += ReversedBaseChange(Letters, int(d[i])) - } - - if len(h) > n { - return h[0:len(h) - 1] - } - return h + return hashSize(hasher.Sum(nil), n) } func QuickHash(str string, n int) string { - hash := fnv.New64() - hash.Write([]byte(str)) - d := string(hash.Sum(nil)) + hasher := fnv.New64() + hasher.Write([]byte(str)) + return hashSize(hasher.Sum(nil), n) +} + +func HashStream(r io.Reader, n int) string { + hasher := sha256.New() + io.Copy(hasher, r) + h := hex.EncodeToString(hasher.Sum(nil)) + if n == 0 { + return h + } else if n >= len(h) { + return h + } + return h[0:n] +} + +func hashSize(b []byte, n int) string { h := "" - for i:=0; i 0 && len(h) >= n { break } - h += ReversedBaseChange(Letters, int(d[i])) + h += ReversedBaseChange(Letters, int(b[i])) } if len(h) > n { diff --git a/server/common/default.go b/server/common/default.go index 758fb53b..3733ebb5 100644 --- a/server/common/default.go +++ b/server/common/default.go @@ -8,7 +8,7 @@ import ( "time" ) -var USER_AGENT = fmt.Sprintf("Filestash/%s.%s (http://filestash.app)", APP_VERSION, BUILD_NUMBER) +var USER_AGENT = fmt.Sprintf("Filestash/%s.%s (http://filestash.app)", APP_VERSION, BUILD_DATE) var HTTPClient = http.Client{ Timeout: 5 * time.Hour, diff --git a/server/common/response.go b/server/common/response.go index 336ef81b..5d7d7c36 100644 --- a/server/common/response.go +++ b/server/common/response.go @@ -102,8 +102,7 @@ func Page(stuff string) string { html { background: #f4f4f4; color: #455164; font-size: 16px; font-family: -apple-system,system-ui,BlinkMacSystemFont,Roboto,"Helvetica Neue",Arial,sans-serif; } body { text-align: center; padding-top: 50px; text-align: center; } h1 { font-weight: 200; line-height: 1em; font-size: 40px; } - p { opacity: 0.7; } - span { font-size: 0.7em; opacity: 0.7; } + p { opacity: 0.8; font-size: 1.05em; } diff --git a/server/ctrl/static.go b/server/ctrl/static.go index f043acf9..2f431992 100644 --- a/server/ctrl/static.go +++ b/server/ctrl/static.go @@ -67,16 +67,24 @@ func IndexHandler(_path string) func(App, http.ResponseWriter, *http.Request) { func AboutHandler(ctx App, res http.ResponseWriter, req *http.Request) { t, _ := template.New("about").Parse(Page(` -

{{index .App 0}}
- ({{index .App 1}} - {{index .App 2}}) -

+

{{index .App 0}}

+ + + + +
Commit hash {{ index .App 1}}
Binary hash {{ index .App 2}}
Config hash {{ index .App 3}}
+ `)) t.Execute(res, struct { App []string }{ []string{ - "Filestash " + APP_VERSION + "." + BUILD_NUMBER, - hashFile(filepath.Join(GetCurrentDir(), "/filestash"), 6), - hashFile(filepath.Join(GetCurrentDir(), CONFIG_PATH, "config.json"), 6), + "Filestash " + APP_VERSION + "." + BUILD_DATE, + BUILD_REF, + hashFileContent(filepath.Join(GetCurrentDir(), "/filestash"), 0), + hashFileContent(filepath.Join(GetCurrentDir(), CONFIG_PATH, "config.json"), 0), }}) } @@ -131,7 +139,7 @@ func ServeFile(res http.ResponseWriter, req *http.Request, filePath string) { file.Close() } -func hashFile (path string, n int) string { +func hashFile(path string, n int) string { f, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm) if err != nil { return "" @@ -144,3 +152,12 @@ func hashFile (path string, n int) string { } return QuickHash(fmt.Sprintf("%s %d %d %s", path, stat.Size(), stat.Mode(), stat.ModTime()), n) } + +func hashFileContent(path string, n int) string { + f, err := os.OpenFile(path, os.O_RDONLY, os.ModePerm) + if err != nil { + return "" + } + defer f.Close() + return HashStream(f, n) +} diff --git a/server/middleware/http.go b/server/middleware/http.go index 3991743a..ef6ac789 100644 --- a/server/middleware/http.go +++ b/server/middleware/http.go @@ -45,7 +45,7 @@ func IndexHeaders(fn func(App, http.ResponseWriter, *http.Request)) func(ctx App header.Set("X-Content-Type-Options", "nosniff") header.Set("X-XSS-Protection", "1; mode=block") header.Set("X-Frame-Options", "DENY") - header.Set("X-Powered-By", fmt.Sprintf("Filestash/%s ", APP_VERSION + "." + BUILD_NUMBER)) + header.Set("X-Powered-By", fmt.Sprintf("Filestash/%s.%s ", APP_VERSION, BUILD_DATE)) header.Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; font-src 'self' data:; manifest-src 'self'; script-src 'self' 'sha256-JNAde5CZQqXtYRLUk8CGgyJXo6C7Zs1lXPPClLM1YM4=' 'sha256-9/gQeQaAmVkFStl6tfCbHXn8mr6PgtxlH+hEp685lzY='; img-src 'self' data:; connect-src 'self'; object-src 'self'; media-src 'self'; worker-src 'self'; form-action 'self'; frame-ancestors 'none'; base-uri 'self'") fn(ctx, res, req) }