11package auth
22
3- import "encoding/csv"
4- import "os"
3+ import (
4+ "encoding/csv"
5+ "os"
6+ "sync"
7+ )
58
69/*
710 SecretProvider is used by authenticators. Takes user name and realm
@@ -20,13 +23,16 @@ type File struct {
2023 Info os.FileInfo
2124 /* must be set in inherited types during initialization */
2225 Reload func ()
26+ mu sync.Mutex
2327}
2428
2529func (f * File ) ReloadIfNeeded () {
2630 info , err := os .Stat (f .Path )
2731 if err != nil {
2832 panic (err )
2933 }
34+ f .mu .Lock ()
35+ defer f .mu .Unlock ()
3036 if f .Info == nil || f .Info .ModTime () != info .ModTime () {
3137 f .Info = info
3238 f .Reload ()
@@ -40,6 +46,7 @@ func (f *File) ReloadIfNeeded() {
4046type HtdigestFile struct {
4147 File
4248 Users map [string ]map [string ]string
49+ mu sync.RWMutex
4350}
4451
4552func reload_htdigest (hf * HtdigestFile ) {
@@ -57,6 +64,8 @@ func reload_htdigest(hf *HtdigestFile) {
5764 panic (err )
5865 }
5966
67+ hf .mu .Lock ()
68+ defer hf .mu .Unlock ()
6069 hf .Users = make (map [string ]map [string ]string )
6170 for _ , record := range records {
6271 _ , exists := hf .Users [record [1 ]]
@@ -77,6 +86,8 @@ func HtdigestFileProvider(filename string) SecretProvider {
7786 hf .Reload = func () { reload_htdigest (hf ) }
7887 return func (user , realm string ) string {
7988 hf .ReloadIfNeeded ()
89+ hf .mu .RLock ()
90+ defer hf .mu .RUnlock ()
8091 _ , exists := hf .Users [realm ]
8192 if ! exists {
8293 return ""
@@ -96,6 +107,7 @@ func HtdigestFileProvider(filename string) SecretProvider {
96107type HtpasswdFile struct {
97108 File
98109 Users map [string ]string
110+ mu sync.RWMutex
99111}
100112
101113func reload_htpasswd (h * HtpasswdFile ) {
@@ -113,6 +125,8 @@ func reload_htpasswd(h *HtpasswdFile) {
113125 panic (err )
114126 }
115127
128+ h .mu .Lock ()
129+ defer h .mu .Unlock ()
116130 h .Users = make (map [string ]string )
117131 for _ , record := range records {
118132 h .Users [record [0 ]] = record [1 ]
@@ -129,7 +143,9 @@ func HtpasswdFileProvider(filename string) SecretProvider {
129143 h .Reload = func () { reload_htpasswd (h ) }
130144 return func (user , realm string ) string {
131145 h .ReloadIfNeeded ()
146+ h .mu .RLock ()
132147 password , exists := h .Users [user ]
148+ h .mu .RUnlock ()
133149 if ! exists {
134150 return ""
135151 }
0 commit comments