Add passphrase function with file input

Updates the prompt receiver to take in the in and out files from arguments.
The default function uses stdin and stdout.
Fixed a typo in comment from "directiory" to "directory".

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
This commit is contained in:
Derek McGowan 2015-07-23 13:43:02 -07:00
parent 6c92ca7f86
commit 71aaf5c84d
1 changed files with 24 additions and 15 deletions

View File

@ -6,11 +6,13 @@ import (
"bufio" "bufio"
"errors" "errors"
"fmt" "fmt"
"io"
"os" "os"
"strings" "strings"
"github.com/docker/docker/pkg/term"
"path/filepath" "path/filepath"
"github.com/docker/docker/pkg/term"
) )
// Retriever is a callback function that should retrieve a passphrase // Retriever is a callback function that should retrieve a passphrase
@ -28,13 +30,20 @@ const (
the most sensitive key in your signing system. Please choose a long, complex passphrase and be careful the most sensitive key in your signing system. Please choose a long, complex passphrase and be careful
to keep the password and the key file itself secure and backed up. It is highly recommended that you use to keep the password and the key file itself secure and backed up. It is highly recommended that you use
a password manager to generate the passphrase and keep it safe. There will be no way to recover this key. a password manager to generate the passphrase and keep it safe. There will be no way to recover this key.
You can find the key in your config directiory.` You can find the key in your config directory.`
) )
// PromptRetriever returns a new Retriever which will provide a terminal prompt // PromptRetriever returns a new Retriever which will provide a prompt on stdin
// to retrieve a passphrase. The passphrase will be cached such that subsequent // and stdout to retrieve a passphrase. The passphrase will be cached such that
// prompts will produce the same passphrase. // subsequent prompts will produce the same passphrase.
func PromptRetriever() Retriever { func PromptRetriever() Retriever {
return PromptRetrieverWithInOut(os.Stdin, os.Stdout)
}
// PromptRetrieverWithInOut returns a new Retriever which will provide a
// prompt using the given in and out readers. The passphrase will be cached
// such that subsequent prompts will produce the same passphrase.
func PromptRetrieverWithInOut(in io.Reader, out io.Writer) Retriever {
userEnteredTargetsSnapshotsPass := false userEnteredTargetsSnapshotsPass := false
targetsSnapshotsPass := "" targetsSnapshotsPass := ""
userEnteredRootsPass := false userEnteredRootsPass := false
@ -42,14 +51,14 @@ func PromptRetriever() Retriever {
return func(keyName string, alias string, createNew bool, numAttempts int) (string, bool, error) { return func(keyName string, alias string, createNew bool, numAttempts int) (string, bool, error) {
if alias == tufRootAlias && createNew && numAttempts == 0 { if alias == tufRootAlias && createNew && numAttempts == 0 {
fmt.Println(tufRootKeyGenerationWarning) fmt.Fprintln(out, tufRootKeyGenerationWarning)
} }
if numAttempts > 0 { if numAttempts > 0 {
if createNew { if createNew {
fmt.Println("Passphrases do not match. Please retry.") fmt.Fprintln(out, "Passphrases do not match. Please retry.")
} else { } else {
fmt.Println("Passphrase incorrect. Please retry.") fmt.Fprintln(out, "Passphrase incorrect. Please retry.")
} }
} }
@ -74,7 +83,7 @@ func PromptRetriever() Retriever {
term.DisableEcho(0, state) term.DisableEcho(0, state)
defer term.RestoreTerminal(0, state) defer term.RestoreTerminal(0, state)
stdin := bufio.NewReader(os.Stdin) stdin := bufio.NewReader(in)
indexOfLastSeparator := strings.LastIndex(keyName, string(filepath.Separator)) indexOfLastSeparator := strings.LastIndex(keyName, string(filepath.Separator))
@ -83,13 +92,13 @@ func PromptRetriever() Retriever {
} }
if createNew { if createNew {
fmt.Printf("Enter passphrase for new %s key with id %s: ", alias, keyName) fmt.Fprintf(out, "Enter passphrase for new %s key with id %s: ", alias, keyName)
} else { } else {
fmt.Printf("Enter key passphrase for %s key with id %s: ", alias, keyName) fmt.Fprintf(out, "Enter key passphrase for %s key with id %s: ", alias, keyName)
} }
passphrase, err := stdin.ReadBytes('\n') passphrase, err := stdin.ReadBytes('\n')
fmt.Println() fmt.Fprintln(out)
if err != nil { if err != nil {
return "", false, err return "", false, err
} }
@ -109,13 +118,13 @@ func PromptRetriever() Retriever {
} }
if len(retPass) < 8 { if len(retPass) < 8 {
fmt.Println("Please use a password manager to generate and store a good random passphrase.") fmt.Fprintln(out, "Please use a password manager to generate and store a good random passphrase.")
return "", false, errors.New("Passphrase too short") return "", false, errors.New("Passphrase too short")
} }
fmt.Printf("Repeat passphrase for new %s key with id %s: ", alias, keyName) fmt.Fprintf(out, "Repeat passphrase for new %s key with id %s: ", alias, keyName)
confirmation, err := stdin.ReadBytes('\n') confirmation, err := stdin.ReadBytes('\n')
fmt.Println() fmt.Fprintln(out)
if err != nil { if err != nil {
return "", false, err return "", false, err
} }