mirror of
https://github.com/gocsaf/csaf.git
synced 2025-12-22 11:55:40 +01:00
Pwacc (#218)
* Adds option to require Client Certificate and a Password to aquire write access in provider * Removed unnecessary flavourtext from provider markdown file * Fixed and simplified the auth middleware Co-authored-by: Jan Höfelmeyer <Jan Höfelmeyer jhoefelmeyer@intevation.de> Co-authored-by: Sascha L. Teichmann <sascha.teichmann@intevation.de>
This commit is contained in:
parent
50024915f4
commit
2ac7940206
3 changed files with 47 additions and 24 deletions
|
|
@ -48,6 +48,7 @@ type config struct {
|
||||||
TLPs []tlp `toml:"tlps"`
|
TLPs []tlp `toml:"tlps"`
|
||||||
UploadSignature bool `toml:"upload_signature"`
|
UploadSignature bool `toml:"upload_signature"`
|
||||||
CanonicalURLPrefix string `toml:"canonical_url_prefix"`
|
CanonicalURLPrefix string `toml:"canonical_url_prefix"`
|
||||||
|
CertificateAndPassword bool `toml:"certificate_and_password"`
|
||||||
NoPassphrase bool `toml:"no_passphrase"`
|
NoPassphrase bool `toml:"no_passphrase"`
|
||||||
NoValidation bool `toml:"no_validation"`
|
NoValidation bool `toml:"no_validation"`
|
||||||
NoWebUI bool `toml:"no_web_ui"`
|
NoWebUI bool `toml:"no_web_ui"`
|
||||||
|
|
|
||||||
|
|
@ -72,13 +72,9 @@ func (c *controller) bind(pim *pathInfoMux) {
|
||||||
pim.handleFunc("/api/create", c.auth(api(c.create)))
|
pim.handleFunc("/api/create", c.auth(api(c.create)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// auth wraps the given http.HandlerFunc and returns an new one after authenticating the
|
// authenticate checks if the incoming request confirms with the
|
||||||
// password contained in the header "X-CSAF-PROVIDER-AUTH" with the "password" config value
|
// configured authentication mechanism.
|
||||||
// if set, otherwise returns the given http.HandlerFunc.
|
func (c *controller) authenticate(r *http.Request) bool {
|
||||||
func (c *controller) auth(
|
|
||||||
fn func(http.ResponseWriter, *http.Request),
|
|
||||||
) func(http.ResponseWriter, *http.Request) {
|
|
||||||
return func(rw http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
verify := os.Getenv("SSL_CLIENT_VERIFY")
|
verify := os.Getenv("SSL_CLIENT_VERIFY")
|
||||||
log.Printf("SSL_CLIENT_VERIFY: %s\n", verify)
|
log.Printf("SSL_CLIENT_VERIFY: %s\n", verify)
|
||||||
|
|
@ -90,19 +86,44 @@ func (c *controller) auth(
|
||||||
log.Printf("SSL_CLIENT_I_DN: %s\n", os.Getenv("SSL_CLIENT_I_DN"))
|
log.Printf("SSL_CLIENT_I_DN: %s\n", os.Getenv("SSL_CLIENT_I_DN"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkCert := func() bool {
|
||||||
|
return verify == "SUCCESS" && (c.cfg.Issuer == nil || *c.cfg.Issuer == os.Getenv("SSL_CLIENT_I_DN"))
|
||||||
|
}
|
||||||
|
|
||||||
|
checkPassword := func() bool {
|
||||||
|
return c.cfg.checkPassword(r.Header.Get("X-CSAF-PROVIDER-AUTH"))
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.cfg.CertificateAndPassword {
|
||||||
|
if c.cfg.Password == nil {
|
||||||
|
log.Println("No password set, declining access.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
log.Printf("user: %s\n", os.Getenv("SSL_CLIENT_S_DN"))
|
||||||
|
return checkPassword() && checkCert()
|
||||||
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case verify == "SUCCESS" && (c.cfg.Issuer == nil || *c.cfg.Issuer == os.Getenv("SSL_CLIENT_I_DN")):
|
case checkCert():
|
||||||
log.Printf("user: %s\n", os.Getenv("SSL_CLIENT_S_DN"))
|
log.Printf("user: %s\n", os.Getenv("SSL_CLIENT_S_DN"))
|
||||||
case c.cfg.Password == nil:
|
case c.cfg.Password == nil:
|
||||||
log.Println("No password set, declining access.")
|
log.Println("No password set, declining access.")
|
||||||
http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden)
|
return false
|
||||||
return
|
|
||||||
default:
|
default:
|
||||||
if pa := r.Header.Get("X-CSAF-PROVIDER-AUTH"); !c.cfg.checkPassword(pa) {
|
return checkPassword()
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// auth is a middleware to decorate endpoints with authentication.
|
||||||
|
func (c *controller) auth(
|
||||||
|
fn func(http.ResponseWriter, *http.Request),
|
||||||
|
) func(http.ResponseWriter, *http.Request) {
|
||||||
|
return func(rw http.ResponseWriter, r *http.Request) {
|
||||||
|
if !c.authenticate(r) {
|
||||||
http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden)
|
http.Error(rw, http.StatusText(http.StatusForbidden), http.StatusForbidden)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
fn(rw, r)
|
fn(rw, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ Following options are supported in the config file:
|
||||||
- web: Specify the web folder. Default: `/var/www/html`.
|
- web: Specify the web folder. Default: `/var/www/html`.
|
||||||
- upload_signature: Send signature with the request, an additional input-field in the web interface will be shown to let user enter an ascii armored signature. Default: `false`.
|
- upload_signature: Send signature with the request, an additional input-field in the web interface will be shown to let user enter an ascii armored signature. Default: `false`.
|
||||||
- canonical_url_prefix: start of the URL where contents shall be accessible from the internet. Default: `https://$SERVER_NAME`.
|
- canonical_url_prefix: start of the URL where contents shall be accessible from the internet. Default: `https://$SERVER_NAME`.
|
||||||
|
- certificate_and_password: Require password and a valid Client Certificate for write access. Default: false
|
||||||
- no_passphrase: Let the user send the request without having to send a password. If set to true, the input-field in the web interface will be omitted. Default: `false`.
|
- no_passphrase: Let the user send the request without having to send a password. If set to true, the input-field in the web interface will be omitted. Default: `false`.
|
||||||
- no_validation: Skip validation of the uploaded CSAF document against the JSON schema. Default: `false`.
|
- no_validation: Skip validation of the uploaded CSAF document against the JSON schema. Default: `false`.
|
||||||
- no_web_ui: Disable the web interface. Default: `false`.
|
- no_web_ui: Disable the web interface. Default: `false`.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue