Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
basicauth: Accept placeholders; move base64 decoding to provision
See https://caddy.community/t/v2-basicauth-bug/6738?u=matt
Matthew Holt committed
Jan 7, 2020 at 08:50 UTC
78e98c40d35c0b3bc933886ce11cbf2d0cf44c99
2 files changed
+32
-21
modules/caddyhttp/caddyauth/basicauth.go
+30
-5
@@ -15,6 +15,7 @@
15
package caddyauth
16
17
import (
18
+ "encoding/base64"
19
"encoding/json"
20
"fmt"
21
"net/http"
@@ -66,12 +67,34 @@ func (hba *HTTPBasicAuth) Provision(ctx caddy.Context) error {
67
return fmt.Errorf("hash is required")
68
}
69
70
+ repl := caddy.NewReplacer()
71
+
72
// load account list
73
hba.Accounts = make(map[string]Account)
71
- for _, acct := range hba.AccountList {
74
+ for i, acct := range hba.AccountList {
75
if _, ok := hba.Accounts[acct.Username]; ok {
73
- return fmt.Errorf("username is not unique: %s", acct.Username)
76
+ return fmt.Errorf("account %d: username is not unique: %s", i, acct.Username)
77
}
78
+
79
+ acct.Username = repl.ReplaceAll(acct.Username, "")
80
+ acct.Password = repl.ReplaceAll(string(acct.Password), "")
81
+ acct.Salt = repl.ReplaceAll(string(acct.Salt), "")
82
+
83
+ if acct.Username == "" || acct.Password == "" {
84
+ return fmt.Errorf("account %d: username and password are required", i)
85
+ }
86
+
87
+ acct.password, err = base64.StdEncoding.DecodeString(acct.Password)
88
+ if err != nil {
89
+ return fmt.Errorf("base64-decoding password: %v", err)
90
+ }
91
+ if acct.Salt != "" {
92
+ acct.salt, err = base64.StdEncoding.DecodeString(acct.Salt)
93
+ if err != nil {
94
+ return fmt.Errorf("base64-decoding salt: %v", err)
95
+ }
96
+ }
97
+
98
hba.Accounts[acct.Username] = acct
99
}
100
hba.AccountList = nil // allow GC to deallocate
@@ -104,7 +127,7 @@ func (hba HTTPBasicAuth) Authenticate(w http.ResponseWriter, req *http.Request)
127
// don't return early if account does not exist; we want
128
// to try to avoid side-channels that leak existence
129
107
- same, err := hba.Hash.Compare(account.Password, plaintextPassword, account.Salt)
130
+ same, err := hba.Hash.Compare(account.password, plaintextPassword, account.salt)
131
if err != nil {
132
return User{}, false, err
133
}
@@ -134,11 +157,13 @@ type Account struct {
157
Username string `json:"username"`
158
159
// The user's hashed password, base64-encoded.
137
- Password []byte `json:"password"`
160
+ Password string `json:"password"`
161
162
// The user's password salt, base64-encoded; for
163
// algorithms where external salt is needed.
141
- Salt []byte `json:"salt,omitempty"`
164
+ Salt string `json:"salt,omitempty"`
165
+
166
+ password, salt []byte
167
}
168
169
// Interface guards
modules/caddyhttp/caddyauth/caddyfile.go
+2
-16
@@ -15,8 +15,6 @@
15
package caddyauth
16
17
import (
18
- "encoding/base64"
19
-
18
"github.com/caddyserver/caddy/v2"
19
"github.com/caddyserver/caddy/v2/caddyconfig"
20
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
@@ -76,22 +74,10 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
74
return nil, h.Err("username and password cannot be empty or missing")
75
}
76
79
- pwd, err := base64.StdEncoding.DecodeString(b64Pwd)
80
- if err != nil {
81
- return nil, h.Errf("decoding password: %v", err)
82
- }
83
- var salt []byte
84
- if b64Salt != "" {
85
- salt, err = base64.StdEncoding.DecodeString(b64Salt)
86
- if err != nil {
87
- return nil, h.Errf("decoding salt: %v", err)
88
- }
89
- }
90
-
77
ba.AccountList = append(ba.AccountList, Account{
78
Username: username,
93
- Password: pwd,
94
- Salt: salt,
79
+ Password: b64Pwd,
80
+ Salt: b64Salt,
81
})
82
}
83
}