summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modules/caddyhttp/caddyauth/basicauth.go35
-rw-r--r--modules/caddyhttp/caddyauth/caddyfile.go18
2 files changed, 32 insertions, 21 deletions
diff --git a/modules/caddyhttp/caddyauth/basicauth.go b/modules/caddyhttp/caddyauth/basicauth.go
index 74aa407..e0868c2 100644
--- a/modules/caddyhttp/caddyauth/basicauth.go
+++ b/modules/caddyhttp/caddyauth/basicauth.go
@@ -15,6 +15,7 @@
package caddyauth
import (
+ "encoding/base64"
"encoding/json"
"fmt"
"net/http"
@@ -66,12 +67,34 @@ func (hba *HTTPBasicAuth) Provision(ctx caddy.Context) error {
return fmt.Errorf("hash is required")
}
+ repl := caddy.NewReplacer()
+
// load account list
hba.Accounts = make(map[string]Account)
- for _, acct := range hba.AccountList {
+ for i, acct := range hba.AccountList {
if _, ok := hba.Accounts[acct.Username]; ok {
- return fmt.Errorf("username is not unique: %s", acct.Username)
+ return fmt.Errorf("account %d: username is not unique: %s", i, acct.Username)
}
+
+ acct.Username = repl.ReplaceAll(acct.Username, "")
+ acct.Password = repl.ReplaceAll(string(acct.Password), "")
+ acct.Salt = repl.ReplaceAll(string(acct.Salt), "")
+
+ if acct.Username == "" || acct.Password == "" {
+ return fmt.Errorf("account %d: username and password are required", i)
+ }
+
+ acct.password, err = base64.StdEncoding.DecodeString(acct.Password)
+ if err != nil {
+ return fmt.Errorf("base64-decoding password: %v", err)
+ }
+ if acct.Salt != "" {
+ acct.salt, err = base64.StdEncoding.DecodeString(acct.Salt)
+ if err != nil {
+ return fmt.Errorf("base64-decoding salt: %v", err)
+ }
+ }
+
hba.Accounts[acct.Username] = acct
}
hba.AccountList = nil // allow GC to deallocate
@@ -104,7 +127,7 @@ func (hba HTTPBasicAuth) Authenticate(w http.ResponseWriter, req *http.Request)
// don't return early if account does not exist; we want
// to try to avoid side-channels that leak existence
- same, err := hba.Hash.Compare(account.Password, plaintextPassword, account.Salt)
+ same, err := hba.Hash.Compare(account.password, plaintextPassword, account.salt)
if err != nil {
return User{}, false, err
}
@@ -134,11 +157,13 @@ type Account struct {
Username string `json:"username"`
// The user's hashed password, base64-encoded.
- Password []byte `json:"password"`
+ Password string `json:"password"`
// The user's password salt, base64-encoded; for
// algorithms where external salt is needed.
- Salt []byte `json:"salt,omitempty"`
+ Salt string `json:"salt,omitempty"`
+
+ password, salt []byte
}
// Interface guards
diff --git a/modules/caddyhttp/caddyauth/caddyfile.go b/modules/caddyhttp/caddyauth/caddyfile.go
index 8a33e6f..31acd61 100644
--- a/modules/caddyhttp/caddyauth/caddyfile.go
+++ b/modules/caddyhttp/caddyauth/caddyfile.go
@@ -15,8 +15,6 @@
package caddyauth
import (
- "encoding/base64"
-
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
@@ -76,22 +74,10 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
return nil, h.Err("username and password cannot be empty or missing")
}
- pwd, err := base64.StdEncoding.DecodeString(b64Pwd)
- if err != nil {
- return nil, h.Errf("decoding password: %v", err)
- }
- var salt []byte
- if b64Salt != "" {
- salt, err = base64.StdEncoding.DecodeString(b64Salt)
- if err != nil {
- return nil, h.Errf("decoding salt: %v", err)
- }
- }
-
ba.AccountList = append(ba.AccountList, Account{
Username: username,
- Password: pwd,
- Salt: salt,
+ Password: b64Pwd,
+ Salt: b64Salt,
})
}
}