Add the ability to manage .htpasswd from widdler.
This commit is contained in:
parent
2cfd965467
commit
0c90ee2be7
10
README.md
10
README.md
@ -26,11 +26,11 @@ go get -u suah.dev/widdler
|
|||||||
```
|
```
|
||||||
mkdir wiki
|
mkdir wiki
|
||||||
cd wiki
|
cd wiki
|
||||||
# OpenBSD:
|
# Generate a .htpasswd file:
|
||||||
htpasswd .htpasswd youruser
|
widdler -gen
|
||||||
# or on Linux/macOS
|
Username: qbit
|
||||||
# htpasswd -c -B youruser
|
Passwd: ******
|
||||||
widdler
|
./widdler
|
||||||
```
|
```
|
||||||
|
|
||||||
Now open your browser to [http://localhost:8080](http://localhost:8080).
|
Now open your browser to [http://localhost:8080](http://localhost:8080).
|
||||||
|
2
go.sum
2
go.sum
@ -7,9 +7,9 @@ golang.org/x/sys v0.0.0-20200501145240-bc7a7d42d5c3/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da h1:b3NXsE2LusjYGGjL5bxEVZZORm/YEFFrWFjR8eFrw/c=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
suah.dev/protect v1.0.0 h1:X8pzDvDIZIiugmkmr6DES6JFO1XUdJWi34Ffmk6CMZY=
|
suah.dev/protect v1.0.0 h1:X8pzDvDIZIiugmkmr6DES6JFO1XUdJWi34Ffmk6CMZY=
|
||||||
|
106
main.go
106
main.go
@ -19,6 +19,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
"golang.org/x/net/webdav"
|
"golang.org/x/net/webdav"
|
||||||
"suah.dev/protect"
|
"suah.dev/protect"
|
||||||
)
|
)
|
||||||
@ -60,6 +61,7 @@ var (
|
|||||||
auth bool
|
auth bool
|
||||||
davDir string
|
davDir string
|
||||||
fullListen string
|
fullListen string
|
||||||
|
genHtpass bool
|
||||||
handlers map[string]userHandlers
|
handlers map[string]userHandlers
|
||||||
listen string
|
listen string
|
||||||
passPath string
|
passPath string
|
||||||
@ -82,6 +84,7 @@ func init() {
|
|||||||
flag.StringVar(&tlsKey, "tlskey", "", "TLS key.")
|
flag.StringVar(&tlsKey, "tlskey", "", "TLS key.")
|
||||||
flag.StringVar(&passPath, "htpass", fmt.Sprintf("%s/.htpasswd", dir), "Path to .htpasswd file..")
|
flag.StringVar(&passPath, "htpass", fmt.Sprintf("%s/.htpasswd", dir), "Path to .htpasswd file..")
|
||||||
flag.BoolVar(&auth, "auth", true, "Enable HTTP Basic Authentication.")
|
flag.BoolVar(&auth, "auth", true, "Enable HTTP Basic Authentication.")
|
||||||
|
flag.BoolVar(&genHtpass, "gen", false, "Generate a .htpasswd file or add a new entry to an existing file.")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// These are OpenBSD specific protections used to prevent unnecessary file access.
|
// These are OpenBSD specific protections used to prevent unnecessary file access.
|
||||||
@ -96,33 +99,6 @@ func init() {
|
|||||||
log.Fatalln(err)
|
log.Fatalln(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, fErr := os.Stat(passPath)
|
|
||||||
if os.IsNotExist(fErr) {
|
|
||||||
if auth {
|
|
||||||
fmt.Println("No .htpasswd file found!")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
p, err := os.Open(passPath)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
defer p.Close()
|
|
||||||
|
|
||||||
ht := csv.NewReader(p)
|
|
||||||
ht.Comma = ':'
|
|
||||||
ht.Comment = '#'
|
|
||||||
ht.TrimLeadingSpace = true
|
|
||||||
|
|
||||||
entries, err := ht.ReadAll()
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, parts := range entries {
|
|
||||||
users[parts[0]] = parts[1]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func authenticate(user string, pass string) bool {
|
func authenticate(user string, pass string) bool {
|
||||||
@ -164,7 +140,83 @@ func createEmpty(path string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func prompt(prompt string, secure bool) (string, error) {
|
||||||
|
var input string
|
||||||
|
fmt.Print(prompt)
|
||||||
|
|
||||||
|
if secure {
|
||||||
|
b, err := terminal.ReadPassword(int(os.Stdin.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
input = string(b)
|
||||||
|
} else {
|
||||||
|
fmt.Scanln(&input)
|
||||||
|
}
|
||||||
|
return input, nil
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
if genHtpass {
|
||||||
|
user, err := prompt("Username: ", false)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
pass, err := prompt("Password: ", true)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hash, err := bcrypt.GenerateFromPassword([]byte(pass), 11)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
f, err := os.OpenFile(passPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
if _, err := f.WriteString(fmt.Sprintf("%s:%s\n", user, hash)); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Added %q to %q\n", user, passPath)
|
||||||
|
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, fErr := os.Stat(passPath)
|
||||||
|
if os.IsNotExist(fErr) {
|
||||||
|
if auth {
|
||||||
|
fmt.Println("No .htpasswd file found!")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p, err := os.Open(passPath)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer p.Close()
|
||||||
|
|
||||||
|
ht := csv.NewReader(p)
|
||||||
|
ht.Comma = ':'
|
||||||
|
ht.Comment = '#'
|
||||||
|
ht.TrimLeadingSpace = true
|
||||||
|
|
||||||
|
entries, err := ht.ReadAll()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, parts := range entries {
|
||||||
|
users[parts[0]] = parts[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if auth {
|
if auth {
|
||||||
for u := range users {
|
for u := range users {
|
||||||
uPath := path.Join(davDir, u)
|
uPath := path.Join(davDir, u)
|
||||||
|
Loading…
Reference in New Issue
Block a user