add digest auth support for proxy
parent
3cb3cdb8dd
commit
41ea1f20ca
@ -0,0 +1,90 @@
|
|||||||
|
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 ""
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
# format
|
||||||
|
# user:realm:hashed_passwd
|
||||||
|
#
|
||||||
|
# hashed_passwd = MD5(user:realm:plain_passwd)
|
||||||
|
|
||||||
|
#
|
||||||
|
# user "test", realm "example.com", password "test"
|
||||||
|
# MD5("test:example:test") = 3441b753b98a6dc702183c989e35970f
|
||||||
|
# the entry is
|
||||||
|
test:example.com:3441b753b98a6dc702183c989e35970f
|
Loading…
Reference in New Issue