summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorAndrew Zhou <andrewfzhou@gmail.com>2020-05-11 15:10:47 -0500
committerGitHub <noreply@github.com>2020-05-11 14:10:47 -0600
commit5bde8d705b9c9cae6751ccf95b7b8acfc1bbb7f5 (patch)
tree84f1eda422c410c26a384ee2471b0e114d1b33a3 /modules
parent7960b4259d976810691f1085332d4761abab9928 (diff)
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>
Diffstat (limited to 'modules')
-rw-r--r--modules/caddyhttp/caddyauth/command.go45
1 files changed, 42 insertions, 3 deletions
diff --git a/modules/caddyhttp/caddyauth/command.go b/modules/caddyhttp/caddyauth/command.go
index 24f6c5a..2c08815 100644
--- a/modules/caddyhttp/caddyauth/command.go
+++ b/modules/caddyhttp/caddyauth/command.go
@@ -15,26 +15,34 @@
package caddyauth
import (
+ "bufio"
+ "bytes"
"encoding/base64"
"flag"
"fmt"
+ "os"
"github.com/caddyserver/caddy/v2"
caddycmd "github.com/caddyserver/caddy/v2/cmd"
"golang.org/x/crypto/bcrypt"
"golang.org/x/crypto/scrypt"
+ "golang.org/x/crypto/ssh/terminal"
)
func init() {
caddycmd.RegisterCommand(caddycmd.Command{
Name: "hash-password",
Func: cmdHashPassword,
- Usage: "--plaintext <password> [--salt <string>] [--algorithm <name>]",
+ Usage: "[--algorithm <name>] [--salt <string>] [--plaintext <password>]",
Short: "Hashes a password and writes base64",
Long: `
Convenient way to hash a plaintext password. The resulting
hash is written to stdout as a base64 string.
+--plaintext, when omitted, will be read from stdin. If
+Caddy is attached to a controlling tty, the plaintext will
+not be echoed.
+
--algorithm may be bcrypt or scrypt. If script, the default
parameters are used.
@@ -52,16 +60,47 @@ be provided (scrypt).
}
func cmdHashPassword(fs caddycmd.Flags) (int, error) {
+ var err error
+
algorithm := fs.String("algorithm")
plaintext := []byte(fs.String("plaintext"))
salt := []byte(fs.String("salt"))
if len(plaintext) == 0 {
- return caddy.ExitCodeFailedStartup, fmt.Errorf("password is required")
+ if terminal.IsTerminal(int(os.Stdin.Fd())) {
+ fmt.Print("Enter password: ")
+ plaintext, err = terminal.ReadPassword(int(os.Stdin.Fd()))
+ fmt.Println()
+ if err != nil {
+ return caddy.ExitCodeFailedStartup, err
+ }
+
+ fmt.Print("Confirm password: ")
+ confirmation, err := terminal.ReadPassword(int(os.Stdin.Fd()))
+ fmt.Println()
+ if err != nil {
+ return caddy.ExitCodeFailedStartup, err
+ }
+
+ if !bytes.Equal(plaintext, confirmation) {
+ return caddy.ExitCodeFailedStartup, fmt.Errorf("password does not match")
+ }
+ } else {
+ rd := bufio.NewReader(os.Stdin)
+ plaintext, err = rd.ReadBytes('\n')
+ if err != nil {
+ return caddy.ExitCodeFailedStartup, err
+ }
+
+ plaintext = plaintext[:len(plaintext)-1] // Trailing newline
+ }
+
+ if len(plaintext) == 0 {
+ return caddy.ExitCodeFailedStartup, fmt.Errorf("plaintext is required")
+ }
}
var hash []byte
- var err error
switch algorithm {
case "bcrypt":
hash, err = bcrypt.GenerateFromPassword(plaintext, bcrypt.DefaultCost)