From d335ad1b84efe486cb4bb3b176fb3781d84d0cd1 Mon Sep 17 00:00:00 2001 From: "Sascha L. Teichmann" Date: Mon, 6 Dec 2021 17:24:45 +0100 Subject: [PATCH] Added server config and middleware to use password to protect endpoints. --- cmd/csaf_provider/config.go | 7 +++++++ cmd/csaf_provider/controller.go | 27 ++++++++++++++++++++++----- go.mod | 6 +++--- go.sum | 11 ++++++++--- 4 files changed, 40 insertions(+), 11 deletions(-) diff --git a/cmd/csaf_provider/config.go b/cmd/csaf_provider/config.go index 38be445..e81104f 100644 --- a/cmd/csaf_provider/config.go +++ b/cmd/csaf_provider/config.go @@ -8,6 +8,7 @@ import ( "github.com/BurntSushi/toml" "github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/csaf-poc/csaf_distribution/csaf" + "golang.org/x/crypto/bcrypt" ) const ( @@ -19,6 +20,7 @@ const ( ) type config struct { + Password *string `toml:"password"` Key string `toml:"key"` Folder string `toml:"folder"` Web string `toml:"web"` @@ -83,6 +85,11 @@ func (cfg *config) loadCryptoKey() (*crypto.Key, error) { return crypto.NewKeyFromArmoredReader(f) } +func (cfg *config) checkPassword(hash string) bool { + return cfg.Password == nil || + bcrypt.CompareHashAndPassword([]byte(hash), []byte(*cfg.Password)) == nil +} + func loadConfig() (*config, error) { path := os.Getenv(configEnv) if path == "" { diff --git a/cmd/csaf_provider/controller.go b/cmd/csaf_provider/controller.go index 31e29b9..24188b1 100644 --- a/cmd/csaf_provider/controller.go +++ b/cmd/csaf_provider/controller.go @@ -50,12 +50,29 @@ func newController(cfg *config) (*controller, error) { func (c *controller) bind(pim *pathInfoMux) { if !c.cfg.NoWebUI { - pim.handleFunc("/", c.index) - pim.handleFunc("/upload", c.web(c.upload, "upload.html")) - pim.handleFunc("/create", c.web(c.create, "create.html")) + pim.handleFunc("/", c.auth(c.index)) + pim.handleFunc("/upload", c.auth(c.web(c.upload, "upload.html"))) + pim.handleFunc("/create", c.auth(c.web(c.create, "create.html"))) + } + pim.handleFunc("/api/upload", c.auth(api(c.upload))) + pim.handleFunc("/api/create", c.auth(api(c.create))) +} + +func (c *controller) auth( + fn func(http.ResponseWriter, *http.Request), +) func(http.ResponseWriter, *http.Request) { + + if c.cfg.Password == nil { + return fn + } + return func(rw http.ResponseWriter, r *http.Request) { + hash := r.Header.Get("X-CSAF-PROVIDER-AUTH") + if !c.cfg.checkPassword(hash) { + http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden) + return + } + fn(rw, r) } - pim.handleFunc("/api/upload", api(c.upload)) - pim.handleFunc("/api/create", api(c.create)) } func (c *controller) render(rw http.ResponseWriter, tmpl string, arg interface{}) { diff --git a/go.mod b/go.mod index fd964b4..8814c8e 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/PaesslerAG/jsonpath v0.1.1 github.com/ProtonMail/gopenpgp/v2 v2.3.0 github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 + golang.org/x/crypto v0.0.0-20211202192323-5770296d904e ) require ( @@ -16,7 +17,6 @@ require ( github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/sirupsen/logrus v1.4.2 // indirect - golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect - golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect - golang.org/x/text v0.3.3 // indirect + golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect + golang.org/x/text v0.3.6 // indirect ) diff --git a/go.sum b/go.sum index 5cd8cb7..83173d4 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,9 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8= +golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -48,17 +49,21 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=