improve (build): make build reproducible and easy to inspect/verify

This commit is contained in:
Mickael Kerjean 2019-08-20 00:34:24 +10:00
parent aff3dc704a
commit 4a0b952ba8
7 changed files with 52 additions and 31 deletions

View file

@ -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

View file

@ -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

View file

@ -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<len(d); i++ {
if n > 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<len(d); i++ {
for i:=0; i<len(b); i++ {
if n > 0 && len(h) >= n {
break
}
h += ReversedBaseChange(Letters, int(d[i]))
h += ReversedBaseChange(Letters, int(b[i]))
}
if len(h) > n {

View file

@ -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,

View file

@ -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; }
</style>
</head>
<body>

View file

@ -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(`
<h1> {{index .App 0}} <br>
<span>({{index .App 1}} - {{index .App 2}})</span>
</h1>
<h1> {{index .App 0}} </h1>
<table>
<tr> <td> Commit hash </td> <td> {{ index .App 1}} </td> </tr>
<tr> <td> Binary hash </td> <td> {{ index .App 2}} </td> </tr>
<tr> <td> Config hash </td> <td> {{ index .App 3}} </td> </tr>
</table>
<style>
table { margin: 0 auto; font-family: monospace; opacity: 0.8; }
td { text-align: right; padding-left: 10px; }
</style>
`))
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)
}

View file

@ -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 <https://filestash.app>", APP_VERSION + "." + BUILD_NUMBER))
header.Set("X-Powered-By", fmt.Sprintf("Filestash/%s.%s <https://filestash.app>", 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)
}