You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
1.4 KiB
Go
91 lines
1.4 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type digestPwFile struct {
|
|
path string
|
|
entry []pwEntry
|
|
mtime time.Time
|
|
mu *sync.Mutex
|
|
}
|
|
|
|
type pwEntry struct {
|
|
user string
|
|
realm string
|
|
hashPw string
|
|
}
|
|
|
|
func newDigestSecret(f string) (*digestPwFile, error) {
|
|
a := &digestPwFile{path: f, mu: new(sync.Mutex)}
|
|
if err := a.loadFile(); err != nil {
|
|
return nil, err
|
|
}
|
|
go a.tryReload()
|
|
return a, nil
|
|
}
|
|
|
|
func (df *digestPwFile) tryReload() {
|
|
for {
|
|
time.Sleep(10 * time.Second)
|
|
fi, _ := os.Stat(df.path)
|
|
t1 := fi.ModTime()
|
|
if t1 != df.mtime {
|
|
df.loadFile()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (df *digestPwFile) loadFile() error {
|
|
df.mu.Lock()
|
|
defer df.mu.Unlock()
|
|
|
|
fp, err := os.Open(df.path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer fp.Close()
|
|
|
|
entry := []pwEntry{}
|
|
|
|
r := bufio.NewReader(fp)
|
|
for {
|
|
line, err := r.ReadString('\n')
|
|
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
line1 := strings.Trim(line, " \r\n")
|
|
if line1 == "" || line1[0] == '#' {
|
|
continue
|
|
}
|
|
fields := strings.SplitN(line1, ":", 3)
|
|
entry = append(entry, pwEntry{fields[0], fields[1], fields[2]})
|
|
}
|
|
|
|
df.entry = entry
|
|
fi, _ := os.Stat(df.path)
|
|
df.mtime = fi.ModTime()
|
|
|
|
return nil
|
|
}
|
|
|
|
func (df *digestPwFile) getPw(user, realm string) string {
|
|
df.mu.Lock()
|
|
defer df.mu.Unlock()
|
|
|
|
for i := range df.entry {
|
|
if df.entry[i].user == user && df.entry[i].realm == realm {
|
|
return df.entry[i].hashPw
|
|
}
|
|
}
|
|
return ""
|
|
}
|