Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
cmd: hash-password: Support reading from stdin (#3373)
Closes #3365 * http: Add support in hash-password for reading from terminals/stdin * FIXUP: Run gofmt -s * FIXUP * FIXUP: Apply suggestions from code review Co-authored-by: Matt Holt <mholt@users.noreply.github.com> * FIXUP Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
Andrew Zhou committed
May 11, 2020 at 15:10 UTC
5bde8d705b9c9cae6751ccf95b7b8acfc1bbb7f5
1 file changed
+42
-3
modules/caddyhttp/caddyauth/command.go
+42
-3
@@ -15,26 +15,34 @@
15
package caddyauth
16
17
import (
18
+ "bufio"
19
+ "bytes"
20
"encoding/base64"
21
"flag"
22
"fmt"
23
+ "os"
24
25
"github.com/caddyserver/caddy/v2"
26
caddycmd "github.com/caddyserver/caddy/v2/cmd"
27
"golang.org/x/crypto/bcrypt"
28
"golang.org/x/crypto/scrypt"
29
+ "golang.org/x/crypto/ssh/terminal"
30
)
31
32
func init() {
33
caddycmd.RegisterCommand(caddycmd.Command{
34
Name: "hash-password",
35
Func: cmdHashPassword,
32
- Usage: "--plaintext <password> [--salt <string>] [--algorithm <name>]",
36
+ Usage: "[--algorithm <name>] [--salt <string>] [--plaintext <password>]",
37
Short: "Hashes a password and writes base64",
38
Long: `
39
Convenient way to hash a plaintext password. The resulting
40
hash is written to stdout as a base64 string.
41
42
+--plaintext, when omitted, will be read from stdin. If
43
+Caddy is attached to a controlling tty, the plaintext will
44
+not be echoed.
45
+
46
--algorithm may be bcrypt or scrypt. If script, the default
47
parameters are used.
48
@@ -52,16 +60,47 @@ be provided (scrypt).
60
}
61
62
func cmdHashPassword(fs caddycmd.Flags) (int, error) {
63
+ var err error
64
+
65
algorithm := fs.String("algorithm")
66
plaintext := []byte(fs.String("plaintext"))
67
salt := []byte(fs.String("salt"))
68
69
if len(plaintext) == 0 {
60
- return caddy.ExitCodeFailedStartup, fmt.Errorf("password is required")
70
+ if terminal.IsTerminal(int(os.Stdin.Fd())) {
71
+ fmt.Print("Enter password: ")
72
+ plaintext, err = terminal.ReadPassword(int(os.Stdin.Fd()))
73
+ fmt.Println()
74
+ if err != nil {
75
+ return caddy.ExitCodeFailedStartup, err
76
+ }
77
+
78
+ fmt.Print("Confirm password: ")
79
+ confirmation, err := terminal.ReadPassword(int(os.Stdin.Fd()))
80
+ fmt.Println()
81
+ if err != nil {
82
+ return caddy.ExitCodeFailedStartup, err
83
+ }
84
+
85
+ if !bytes.Equal(plaintext, confirmation) {
86
+ return caddy.ExitCodeFailedStartup, fmt.Errorf("password does not match")
87
+ }
88
+ } else {
89
+ rd := bufio.NewReader(os.Stdin)
90
+ plaintext, err = rd.ReadBytes('\n')
91
+ if err != nil {
92
+ return caddy.ExitCodeFailedStartup, err
93
+ }
94
+
95
+ plaintext = plaintext[:len(plaintext)-1] // Trailing newline
96
+ }
97
+
98
+ if len(plaintext) == 0 {
99
+ return caddy.ExitCodeFailedStartup, fmt.Errorf("plaintext is required")
100
+ }
101
}
102
103
var hash []byte
64
- var err error
104
switch algorithm {
105
case "bcrypt":
106
hash, err = bcrypt.GenerateFromPassword(plaintext, bcrypt.DefaultCost)