mirror of
https://github.com/caddyserver/caddy.git
synced 2025-01-23 00:56:45 +01: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
|
package caddyauth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -66,12 +67,34 @@ func (hba *HTTPBasicAuth) Provision(ctx caddy.Context) error {
|
||||||
return fmt.Errorf("hash is required")
|
return fmt.Errorf("hash is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repl := caddy.NewReplacer()
|
||||||
|
|
||||||
// load account list
|
// load account list
|
||||||
hba.Accounts = make(map[string]Account)
|
hba.Accounts = make(map[string]Account)
|
||||||
for _, acct := range hba.AccountList {
|
for i, acct := range hba.AccountList {
|
||||||
if _, ok := hba.Accounts[acct.Username]; ok {
|
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.Accounts[acct.Username] = acct
|
||||||
}
|
}
|
||||||
hba.AccountList = nil // allow GC to deallocate
|
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
|
// don't return early if account does not exist; we want
|
||||||
// to try to avoid side-channels that leak existence
|
// 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 {
|
if err != nil {
|
||||||
return User{}, false, err
|
return User{}, false, err
|
||||||
}
|
}
|
||||||
|
@ -134,11 +157,13 @@ type Account struct {
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
|
||||||
// The user's hashed password, base64-encoded.
|
// The user's hashed password, base64-encoded.
|
||||||
Password []byte `json:"password"`
|
Password string `json:"password"`
|
||||||
|
|
||||||
// The user's password salt, base64-encoded; for
|
// The user's password salt, base64-encoded; for
|
||||||
// algorithms where external salt is needed.
|
// algorithms where external salt is needed.
|
||||||
Salt []byte `json:"salt,omitempty"`
|
Salt string `json:"salt,omitempty"`
|
||||||
|
|
||||||
|
password, salt []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface guards
|
// Interface guards
|
||||||
|
|
|
@ -15,8 +15,6 @@
|
||||||
package caddyauth
|
package caddyauth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
|
||||||
|
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
"github.com/caddyserver/caddy/v2/caddyconfig"
|
"github.com/caddyserver/caddy/v2/caddyconfig"
|
||||||
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
|
"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")
|
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{
|
ba.AccountList = append(ba.AccountList, Account{
|
||||||
Username: username,
|
Username: username,
|
||||||
Password: pwd,
|
Password: b64Pwd,
|
||||||
Salt: salt,
|
Salt: b64Salt,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue