Fix concurrent map writes on digest auth
This commit is contained in:
parent
b5ee5c34f2
commit
5316b412d2
5 changed files with 18 additions and 9 deletions
7
Gopkg.lock
generated
7
Gopkg.lock
generated
|
@ -120,10 +120,11 @@
|
||||||
version = "v1.0.0"
|
version = "v1.0.0"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
|
branch = "containous-fork"
|
||||||
name = "github.com/abbot/go-http-auth"
|
name = "github.com/abbot/go-http-auth"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "0ddd408d5d60ea76e320503cc7dd091992dee608"
|
revision = "65b0cdae8d7fe5c05c7430e055938ef6d24a66c9"
|
||||||
version = "v0.4.0"
|
source = "github.com/containous/go-http-auth"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
name = "github.com/aokoli/goutils"
|
name = "github.com/aokoli/goutils"
|
||||||
|
@ -1385,6 +1386,6 @@
|
||||||
[solve-meta]
|
[solve-meta]
|
||||||
analyzer-name = "dep"
|
analyzer-name = "dep"
|
||||||
analyzer-version = 1
|
analyzer-version = 1
|
||||||
inputs-digest = "8cd40e70454298aa3ef967edf2c501aef87f1964b9e5cef3318f2c99fc5e620e"
|
inputs-digest = "bd1e7a1b07d95ff85c675468bbfc4bc7a91c39cf1feceeb58dfcdba9592180a5"
|
||||||
solver-name = "gps-cdcl"
|
solver-name = "gps-cdcl"
|
||||||
solver-version = 1
|
solver-version = 1
|
||||||
|
|
|
@ -38,8 +38,9 @@ ignored = ["github.com/sirupsen/logrus"]
|
||||||
name = "github.com/NYTimes/gziphandler"
|
name = "github.com/NYTimes/gziphandler"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
|
branch = "containous-fork"
|
||||||
name = "github.com/abbot/go-http-auth"
|
name = "github.com/abbot/go-http-auth"
|
||||||
version = "0.4.0"
|
source = "github.com/containous/go-http-auth"
|
||||||
|
|
||||||
[[constraint]]
|
[[constraint]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
|
13
vendor/github.com/abbot/go-http-auth/digest.go
generated
vendored
13
vendor/github.com/abbot/go-http-auth/digest.go
generated
vendored
|
@ -39,7 +39,7 @@ type DigestAuth struct {
|
||||||
ClientCacheTolerance int
|
ClientCacheTolerance int
|
||||||
|
|
||||||
clients map[string]*digest_client
|
clients map[string]*digest_client
|
||||||
mutex sync.Mutex
|
mutex sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that DigestAuth implements AuthenticatorInterface
|
// check that DigestAuth implements AuthenticatorInterface
|
||||||
|
@ -84,11 +84,16 @@ func (a *DigestAuth) Purge(count int) {
|
||||||
(or requires reauthentication).
|
(or requires reauthentication).
|
||||||
*/
|
*/
|
||||||
func (a *DigestAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
|
func (a *DigestAuth) RequireAuth(w http.ResponseWriter, r *http.Request) {
|
||||||
|
a.mutex.Lock()
|
||||||
|
defer a.mutex.Unlock()
|
||||||
if len(a.clients) > a.ClientCacheSize+a.ClientCacheTolerance {
|
if len(a.clients) > a.ClientCacheSize+a.ClientCacheTolerance {
|
||||||
a.Purge(a.ClientCacheTolerance * 2)
|
a.Purge(a.ClientCacheTolerance * 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce := RandomKey()
|
nonce := RandomKey()
|
||||||
|
|
||||||
a.clients[nonce] = &digest_client{nc: 0, last_seen: time.Now().UnixNano()}
|
a.clients[nonce] = &digest_client{nc: 0, last_seen: time.Now().UnixNano()}
|
||||||
|
|
||||||
w.Header().Set(contentType, a.Headers.V().UnauthContentType)
|
w.Header().Set(contentType, a.Headers.V().UnauthContentType)
|
||||||
w.Header().Set(a.Headers.V().Authenticate,
|
w.Header().Set(a.Headers.V().Authenticate,
|
||||||
fmt.Sprintf(`Digest realm="%s", nonce="%s", opaque="%s", algorithm="MD5", qop="auth"`,
|
fmt.Sprintf(`Digest realm="%s", nonce="%s", opaque="%s", algorithm="MD5", qop="auth"`,
|
||||||
|
@ -118,8 +123,8 @@ func DigestAuthParams(authorization string) map[string]string {
|
||||||
Authentication-Info response header.
|
Authentication-Info response header.
|
||||||
*/
|
*/
|
||||||
func (da *DigestAuth) CheckAuth(r *http.Request) (username string, authinfo *string) {
|
func (da *DigestAuth) CheckAuth(r *http.Request) (username string, authinfo *string) {
|
||||||
da.mutex.Lock()
|
da.mutex.RLock()
|
||||||
defer da.mutex.Unlock()
|
defer da.mutex.RUnlock()
|
||||||
username = ""
|
username = ""
|
||||||
authinfo = nil
|
authinfo = nil
|
||||||
auth := DigestAuthParams(r.Header.Get(da.Headers.V().Authorization))
|
auth := DigestAuthParams(r.Header.Get(da.Headers.V().Authorization))
|
||||||
|
@ -242,6 +247,8 @@ func (a *DigestAuth) JustCheck(wrapped http.HandlerFunc) http.HandlerFunc {
|
||||||
|
|
||||||
// NewContext returns a context carrying authentication information for the request.
|
// NewContext returns a context carrying authentication information for the request.
|
||||||
func (a *DigestAuth) NewContext(ctx context.Context, r *http.Request) context.Context {
|
func (a *DigestAuth) NewContext(ctx context.Context, r *http.Request) context.Context {
|
||||||
|
a.mutex.Lock()
|
||||||
|
defer a.mutex.Unlock()
|
||||||
username, authinfo := a.CheckAuth(r)
|
username, authinfo := a.CheckAuth(r)
|
||||||
info := &Info{Username: username, ResponseHeaders: make(http.Header)}
|
info := &Info{Username: username, ResponseHeaders: make(http.Header)}
|
||||||
if username != "" {
|
if username != "" {
|
||||||
|
|
Loading…
Reference in a new issue