Fix multiauth
This commit is contained in:
parent
a7059fa9b0
commit
44bd8c758f
3 changed files with 32 additions and 34 deletions
14
caddyfile.go
14
caddyfile.go
|
|
@ -1,6 +1,7 @@
|
|||
package forwardproxy
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
|
@ -45,13 +46,14 @@ func (h *Handler) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
|
|||
if strings.Contains(args[0], ":") {
|
||||
return d.Err("character ':' in usernames is not allowed")
|
||||
}
|
||||
// TODO: Support multiple basicauths.
|
||||
// TODO: Actually, just try to use Caddy 2's existing basicauth module.
|
||||
if h.BasicauthUser != "" || h.BasicauthPass != "" {
|
||||
return d.Err("Multi-user basicauth is not supported")
|
||||
if h.AuthCredentials == nil {
|
||||
h.AuthCredentials = [][]byte{}
|
||||
}
|
||||
h.BasicauthUser = args[0]
|
||||
h.BasicauthPass = args[1]
|
||||
// base64-encode credentials
|
||||
buf := make([]byte, base64.StdEncoding.EncodedLen(len(args[0])+1+len(args[1])))
|
||||
base64.StdEncoding.Encode(buf, []byte(args[0]+":"+args[1]))
|
||||
h.AuthCredentials = append(h.AuthCredentials, buf)
|
||||
h.AuthRequired = true
|
||||
case "hosts":
|
||||
if len(args) == 0 {
|
||||
return d.ArgErr()
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package forwardproxy
|
|||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
|
@ -190,15 +191,18 @@ func TestMain(m *testing.M) {
|
|||
},
|
||||
}
|
||||
|
||||
buf := make([]byte, base64.StdEncoding.EncodedLen(9))
|
||||
base64.StdEncoding.Encode(buf, []byte("test:pass"))
|
||||
|
||||
caddyForwardProxyAuth = caddyTestServer{
|
||||
addr: "127.0.0.1:4891",
|
||||
root: "./test/forwardproxy",
|
||||
tls: true,
|
||||
proxyHandler: &Handler{
|
||||
PACPath: defaultPACPath,
|
||||
ACL: []ACLRule{{Subjects: []string{"all"}, Allow: true}},
|
||||
BasicauthUser: "test",
|
||||
BasicauthPass: "pass",
|
||||
PACPath: defaultPACPath,
|
||||
ACL: []ACLRule{{Subjects: []string{"all"}, Allow: true}},
|
||||
AuthCredentials: [][]byte{buf},
|
||||
AuthRequired: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -206,10 +210,10 @@ func TestMain(m *testing.M) {
|
|||
addr: "127.0.69.73:6973",
|
||||
root: "./test/forwardproxy",
|
||||
proxyHandler: &Handler{
|
||||
PACPath: defaultPACPath,
|
||||
ACL: []ACLRule{{Subjects: []string{"all"}, Allow: true}},
|
||||
BasicauthUser: "test",
|
||||
BasicauthPass: "pass",
|
||||
PACPath: defaultPACPath,
|
||||
ACL: []ACLRule{{Subjects: []string{"all"}, Allow: true}},
|
||||
AuthCredentials: [][]byte{buf},
|
||||
AuthRequired: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -221,8 +225,8 @@ func TestMain(m *testing.M) {
|
|||
PACPath: "/superhiddenfile.pac",
|
||||
ACL: []ACLRule{{Subjects: []string{"all"}, Allow: true}},
|
||||
ProbeResistance: &ProbeResistance{Domain: "test.localhost"},
|
||||
BasicauthUser: "test",
|
||||
BasicauthPass: "pass",
|
||||
AuthCredentials: [][]byte{buf},
|
||||
AuthRequired: true,
|
||||
},
|
||||
httpRedirPort: "8880",
|
||||
}
|
||||
|
|
@ -249,9 +253,9 @@ func TestMain(m *testing.M) {
|
|||
root: "./test/upstreamingproxy",
|
||||
tls: true,
|
||||
proxyHandler: &Handler{
|
||||
Upstream: "https://test:pass@127.0.0.1:4891",
|
||||
BasicauthUser: "upstreamtest",
|
||||
BasicauthPass: "upstreampass",
|
||||
Upstream: "https://test:pass@127.0.0.1:4891",
|
||||
AuthCredentials: [][]byte{buf},
|
||||
AuthRequired: true,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,10 +91,10 @@ type Handler struct {
|
|||
aclRules []aclRule
|
||||
|
||||
// TODO: temporary/deprecated - we should try to reuse existing authentication modules instead!
|
||||
BasicauthUser string `json:"auth_user_deprecated,omitempty"`
|
||||
BasicauthPass string `json:"auth_pass_deprecated,omitempty"`
|
||||
authRequired bool
|
||||
authCredentials [][]byte // slice with base64-encoded credentials
|
||||
BasicauthUser string `json:"auth_user_deprecated,omitempty"`
|
||||
BasicauthPass string `json:"auth_pass_deprecated,omitempty"`
|
||||
AuthRequired bool `json:"auth_required,omitempty"`
|
||||
AuthCredentials [][]byte `json:"auth_credentials,omitempty"` // slice with base64-encoded credentials
|
||||
}
|
||||
|
||||
// CaddyModule returns the Caddy module information.
|
||||
|
|
@ -120,14 +120,6 @@ func (h *Handler) Provision(ctx caddy.Context) error {
|
|||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
// TODO: temporary, in an effort to get the tests to pass
|
||||
if h.BasicauthUser != "" && h.BasicauthPass != "" {
|
||||
basicAuthBuf := make([]byte, base64.StdEncoding.EncodedLen(len(h.BasicauthUser)+1+len(h.BasicauthPass)))
|
||||
base64.StdEncoding.Encode(basicAuthBuf, []byte(h.BasicauthUser+":"+h.BasicauthPass))
|
||||
h.authRequired = true
|
||||
h.authCredentials = [][]byte{basicAuthBuf}
|
||||
}
|
||||
|
||||
// access control lists
|
||||
for _, rule := range h.ACL {
|
||||
for _, subj := range rule.Subjects {
|
||||
|
|
@ -155,7 +147,7 @@ func (h *Handler) Provision(ctx caddy.Context) error {
|
|||
h.aclRules = append(h.aclRules, &aclAllRule{allow: true})
|
||||
|
||||
if h.ProbeResistance != nil {
|
||||
if !h.authRequired {
|
||||
if !h.AuthRequired {
|
||||
return fmt.Errorf("probe resistance requires authentication")
|
||||
}
|
||||
if len(h.ProbeResistance.Domain) > 0 {
|
||||
|
|
@ -237,7 +229,7 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyht
|
|||
}
|
||||
|
||||
var authErr error
|
||||
if h.authRequired {
|
||||
if h.AuthRequired {
|
||||
authErr = h.checkCredentials(r)
|
||||
}
|
||||
if h.ProbeResistance != nil && len(h.ProbeResistance.Domain) > 0 && reqHost == h.ProbeResistance.Domain {
|
||||
|
|
@ -418,7 +410,7 @@ func (h Handler) checkCredentials(r *http.Request) error {
|
|||
if strings.ToLower(pa[0]) != "basic" {
|
||||
return errors.New("Auth type is not supported")
|
||||
}
|
||||
for _, creds := range h.authCredentials {
|
||||
for _, creds := range h.AuthCredentials {
|
||||
if subtle.ConstantTimeCompare(creds, []byte(pa[1])) == 1 {
|
||||
// Please do not consider this to be timing-attack-safe code. Simple equality is almost
|
||||
// mindlessly substituted with constant time algo and there ARE known issues with this code,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue