Skip to content

Commit

Permalink
Accpet HMAC key from file
Browse files Browse the repository at this point in the history
  • Loading branch information
aaronborden-rivian committed Jul 23, 2022
1 parent 6772f8d commit db5bb20
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,13 @@ git config lfs.url http://localhost:9876/
# you can confirm the Endpoint that will be used by running
git lfs env | grep Endpoint
```

When running multiple instances of lfscache, you must use a shared hmac key so
signatures from one instance can be verified by the others with a shared key.
This key is not used for storage, so it's safe to rotate the key and restart all
instances.

```
dd if=/dev/urandom bs=1 count=64 > hmac-key
$ ./lfscache --hmac-key-file hmac-key ...
```
15 changes: 14 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"errors"
"flag"
"fmt"
"io/ioutil"
"net"
"net/http"
"net/url"
Expand All @@ -30,6 +31,7 @@ func main() {
tlsCert = flag.String("tls-cert", "", "HTTPS TLS certificate filepath")
lfsServerURL = flag.String("url", "", "LFS server URL")
directory = flag.String("directory", "./objects", "cache directory")
hmacKeyFile = flag.String("hmac-key-file", "", "file containing 64 byte HMAC key for request signing")
printVersion = flag.Bool("v", false, "print version")
)

Expand All @@ -56,7 +58,18 @@ func main() {
os.Exit(1)
}

s, err := server.New(logger, addr.String(), *directory)
var hmacKey []byte = nil
if *hmacKeyFile != "" {
hmac, err := ioutil.ReadFile(*hmacKeyFile)
if err != nil {
level.Error(logger).Log("err", err)
os.Exit(1)
}
hmacKey = hmac
}


s, err := server.New(logger, addr.String(), *directory, hmacKey)
if err != nil {
panic(err)
}
Expand Down
20 changes: 12 additions & 8 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,16 @@ type Server struct {
}

// New returns a new LFS proxy caching server.
func New(logger log.Logger, upstream, directory string) (*Server, error) {
return newServer(logger, upstream, directory, true)
func New(logger log.Logger, upstream, directory string, hmacKey []byte) (*Server, error) {
return newServer(logger, upstream, directory, true, hmacKey)
}

// NewNoCache returns a new LFS proxy server, with no caching.
func NewNoCache(logger log.Logger, upstream string) (*Server, error) {
return newServer(logger, upstream, "", false)
return newServer(logger, upstream, "", false, nil)
}

func newServer(logger log.Logger, upstream, directory string, cacheEnabled bool) (*Server, error) {
func newServer(logger log.Logger, upstream, directory string, cacheEnabled bool, hmacKey []byte) (*Server, error) {
var fs *cache.FilesystemCache
var err error
if cacheEnabled {
Expand Down Expand Up @@ -135,10 +135,14 @@ func newServer(logger log.Logger, upstream, directory string, cacheEnabled bool)
ObjectBatchActionURLRewriter: DefaultObjectBatchActionURLRewriter,
}

_, err = rand.Read(s.hmacKey[:])
if err != nil {
return nil, err
}
if hmacKey != nil {
copy(s.hmacKey[:], hmacKey)
} else {
_, err = rand.Read(s.hmacKey[:])
if err != nil {
return nil, err
}
}

if s.upstream, err = url.Parse(upstream); err != nil {
return nil, err
Expand Down
19 changes: 18 additions & 1 deletion server/server_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package server

import (
"crypto/rand"
"encoding/json"
"fmt"
"io/ioutil"
Expand Down Expand Up @@ -47,11 +48,27 @@ func server() (*httptest.Server, *Server, string, error) {
return ts, nil, dir, err
}

s, err := New(log.NewNopLogger(), ts.URL, dir)
s, err := New(log.NewNopLogger(), ts.URL, dir, nil)

return ts, s, dir, err
}

func TestHmac(t *testing.T) {
var hmac [64]byte
_, err := rand.Read(hmac[:])
require.NoError(t, err)

s, err := New(log.NewNopLogger(), "http://example.com", "", hmac[:])
require.NoError(t, err)
assert.Equal(t, s.hmacKey, hmac)
}

func TestNoHmac(t *testing.T) {
s, err := New(log.NewNopLogger(), "http://example.com", "", nil)
require.NoError(t, err)
assert.NotEmpty(t, s.hmacKey)
}

func TestProxy(t *testing.T) {
ts, s, dir, err := server()
defer os.RemoveAll(dir)
Expand Down

0 comments on commit db5bb20

Please sign in to comment.