Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion age/encrypted_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func unwrapIdentities(key string, reader io.Reader) (ParsedIdentities, error) {
Passphrase: func() (string, error) {
conn, err := gpgagent.NewConn()
if err != nil {
passphrase, err := readPassphrase("Enter passphrase for identity " + key + ":")
passphrase, err := readSecret("Enter passphrase for identity " + key + ":")
if err != nil {
return "", err
}
Expand Down
2 changes: 1 addition & 1 deletion age/ssh_parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func parseSSHIdentityFromPrivateKeyFile(keyPath string) (age.Identity, error) {
}
}
passphrasePrompt := func() ([]byte, error) {
pass, err := readPassphrase(fmt.Sprintf("Enter passphrase for %q:", keyPath))
pass, err := readSecret(fmt.Sprintf("Enter passphrase for %q:", keyPath))
if err != nil {
return nil, fmt.Errorf("could not read passphrase for %q: %v", keyPath, err)
}
Expand Down
45 changes: 7 additions & 38 deletions age/tui.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// These functions have been copied from the age project
// https://github.com/FiloSottile/age/blob/v1.0.0/cmd/age/encrypted_keys.go
// https://github.com/FiloSottile/age/blob/3d91014ea095e8d70f7c6c4833f89b53a96e0832/cmd/age/tui.go
//
// Copyright 2021 The age Authors. All rights reserved.
Expand Down Expand Up @@ -27,43 +26,6 @@ const (
SopsAgePasswordEnv = "SOPS_AGE_PASSWORD"
)

// readPassphrase reads a passphrase from the terminal. It does not read from a
// non-terminal stdin, so it does not check stdinInUse.
func readPassphrase(prompt string) ([]byte, error) {
if testing.Testing() {
password := os.Getenv(SopsAgePasswordEnv)
if password != "" {
return []byte(password), nil
}
}

var (
err error
passphrase []byte
)

err = withTerminal(func(in, out *os.File) error {
_, err := fmt.Fprintf(out, "%s ", prompt)
if err != nil {
return fmt.Errorf("could not write prompt: %v", err)
}

// Use CRLF to work around an apparent bug in WSL2's handling of CONOUT$.
// Only when running a Windows binary from WSL2, the cursor would not go
// back to the start of the line with a simple LF. Honestly, it's impressive
// CONIN$ and CONOUT$ even work at all inside WSL2.
defer fmt.Fprintf(out, "\r\n")

if passphrase, err = term.ReadPassword(int(in.Fd())); err != nil {
return fmt.Errorf("could not read passphrase: %v", err)
}

return nil
})

return passphrase, err
}

func printf(format string, v ...interface{}) {
log.Printf("age: "+format, v...)
}
Expand Down Expand Up @@ -133,6 +95,13 @@ func withTerminal(f func(in, out *os.File) error) error {

// readSecret reads a value from the terminal with no echo. The prompt is ephemeral.
func readSecret(prompt string) (s []byte, err error) {
if testing.Testing() {
password := os.Getenv(SopsAgePasswordEnv)
if password != "" {
return []byte(password), nil
}
}

err = withTerminal(func(in, out *os.File) error {
fmt.Fprintf(out, "%s ", prompt)
defer clearLine(out)
Expand Down
Loading