mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-06 22:40:31 -05:00
basicauth: Accept placeholders; move base64 decoding to provision
See https://caddy.community/t/v2-basicauth-bug/6738?u=matt
This commit is contained in:
parent
5c99267dd8
commit
78e98c40d3
2 changed files with 32 additions and 21 deletions
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue