diff --git a/pkg/passphrase/passphrase.go b/pkg/passphrase/passphrase.go index e9232f4ede..aae28170b4 100644 --- a/pkg/passphrase/passphrase.go +++ b/pkg/passphrase/passphrase.go @@ -6,11 +6,13 @@ import ( "bufio" "errors" "fmt" + "io" "os" "strings" - "github.com/docker/docker/pkg/term" "path/filepath" + + "github.com/docker/docker/pkg/term" ) // 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 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. -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 -// to retrieve a passphrase. The passphrase will be cached such that subsequent -// prompts will produce the same passphrase. +// PromptRetriever returns a new Retriever which will provide a prompt on stdin +// and stdout to retrieve a passphrase. The passphrase will be cached such that +// subsequent prompts will produce the same passphrase. 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 targetsSnapshotsPass := "" userEnteredRootsPass := false @@ -42,14 +51,14 @@ func PromptRetriever() Retriever { return func(keyName string, alias string, createNew bool, numAttempts int) (string, bool, error) { if alias == tufRootAlias && createNew && numAttempts == 0 { - fmt.Println(tufRootKeyGenerationWarning) + fmt.Fprintln(out, tufRootKeyGenerationWarning) } if numAttempts > 0 { if createNew { - fmt.Println("Passphrases do not match. Please retry.") + fmt.Fprintln(out, "Passphrases do not match. Please retry.") } 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) defer term.RestoreTerminal(0, state) - stdin := bufio.NewReader(os.Stdin) + stdin := bufio.NewReader(in) indexOfLastSeparator := strings.LastIndex(keyName, string(filepath.Separator)) @@ -83,13 +92,13 @@ func PromptRetriever() Retriever { } 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 { - 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') - fmt.Println() + fmt.Fprintln(out) if err != nil { return "", false, err } @@ -109,13 +118,13 @@ func PromptRetriever() Retriever { } 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") } - 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') - fmt.Println() + fmt.Fprintln(out) if err != nil { return "", false, err }