mirror of
https://github.com/getsops/sops.git
synced 2026-02-05 12:45:21 +01:00
use common function to read password
Signed-off-by: Tomasz Duda <tomaszduda23@gmail.com>
This commit is contained in:
@@ -15,7 +15,6 @@ import (
|
||||
"filippo.io/age/agessh"
|
||||
"filippo.io/age/armor"
|
||||
"github.com/sirupsen/logrus"
|
||||
"golang.org/x/term"
|
||||
|
||||
gpgagent "github.com/getsops/gopgagent"
|
||||
"github.com/getsops/sops/v3/logging"
|
||||
@@ -370,28 +369,11 @@ func (key *MasterKey) loadIdentities() (ParsedIdentities, error) {
|
||||
Passphrase: func() (string, error) {
|
||||
conn, err := gpgagent.NewConn()
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "Enter passphrase for identity '%s':", n)
|
||||
|
||||
var pass string
|
||||
if term.IsTerminal(int(os.Stdout.Fd())) {
|
||||
p, err = term.ReadPassword(int(os.Stdout.Fd()))
|
||||
if err == nil {
|
||||
pass = string(p)
|
||||
}
|
||||
} else {
|
||||
reader := bufio.NewReader(os.Stdin)
|
||||
pass, err = reader.ReadString('\n')
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
passphrase, err := readPassphrase("Enter passphrase for identity " + n + ":")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("could not read passphrase: %v", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stderr)
|
||||
|
||||
return pass, nil
|
||||
return string(passphrase), nil
|
||||
}
|
||||
defer func(conn *gpgagent.Conn) {
|
||||
if err := conn.Close(); err != nil {
|
||||
|
||||
@@ -2,7 +2,6 @@ package age
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
@@ -520,10 +519,7 @@ func TestMasterKey_Identities_Passphrase(t *testing.T) {
|
||||
t.Setenv(SopsAgeKeyEnv, mockEncryptedIdentity)
|
||||
//blocks calling gpg-agent
|
||||
os.Unsetenv("XDG_RUNTIME_DIR")
|
||||
|
||||
funcDefer, _ := mockStdin(t, mockIdentityPassphrase)
|
||||
defer funcDefer()
|
||||
|
||||
t.Setenv(SopsAgePasswordEnv, mockIdentityPassphrase)
|
||||
got, err := key.Decrypt()
|
||||
|
||||
assert.NoError(t, err)
|
||||
@@ -542,9 +538,7 @@ func TestMasterKey_Identities_Passphrase(t *testing.T) {
|
||||
t.Setenv(SopsAgeKeyFileEnv, keyPath)
|
||||
//blocks calling gpg-agent
|
||||
os.Unsetenv("XDG_RUNTIME_DIR")
|
||||
|
||||
funcDefer, _ := mockStdin(t, mockIdentityPassphrase)
|
||||
defer funcDefer()
|
||||
t.Setenv(SopsAgePasswordEnv, mockIdentityPassphrase)
|
||||
|
||||
got, err := key.Decrypt()
|
||||
assert.NoError(t, err)
|
||||
@@ -556,9 +550,7 @@ func TestMasterKey_Identities_Passphrase(t *testing.T) {
|
||||
t.Setenv(SopsAgeKeyEnv, mockEncryptedIdentity)
|
||||
//blocks calling gpg-agent
|
||||
os.Unsetenv("XDG_RUNTIME_DIR")
|
||||
|
||||
funcDefer, _ := mockStdin(t, mockIdentityPassphrase)
|
||||
defer funcDefer()
|
||||
t.Setenv(SopsAgePasswordEnv, mockIdentityPassphrase)
|
||||
|
||||
got, err := key.Decrypt()
|
||||
assert.Error(t, err)
|
||||
@@ -566,39 +558,3 @@ func TestMasterKey_Identities_Passphrase(t *testing.T) {
|
||||
assert.Nil(t, got)
|
||||
})
|
||||
}
|
||||
|
||||
// mockStdin is a helper function that lets the test pretend dummyInput as os.Stdin.
|
||||
// It will return a function for `defer` to clean up after the test.
|
||||
//
|
||||
// Note: `ioutil.TempFile` should be replaced to `os.CreateTemp` for Go v1.16 or higher.
|
||||
func mockStdin(t *testing.T, dummyInput string) (funcDefer func(), err error) {
|
||||
t.Helper()
|
||||
|
||||
oldOsStdin := os.Stdin
|
||||
|
||||
fmt.Println(t.TempDir(), t.Name())
|
||||
|
||||
tmpfile, err := ioutil.TempFile(t.TempDir(), strings.Replace(t.Name(), "/", "_", -1))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
content := []byte(dummyInput)
|
||||
|
||||
if _, err := tmpfile.Write(content); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if _, err := tmpfile.Seek(0, 0); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set stdin to the temp file
|
||||
os.Stdin = tmpfile
|
||||
|
||||
return func() {
|
||||
// clean up
|
||||
os.Stdin = oldOsStdin
|
||||
os.Remove(tmpfile.Name())
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -18,9 +18,18 @@ import (
|
||||
"golang.org/x/term"
|
||||
)
|
||||
|
||||
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) {
|
||||
password := os.Getenv(SopsAgePasswordEnv)
|
||||
if password != "" {
|
||||
return []byte(password), nil
|
||||
}
|
||||
|
||||
var in, out *os.File
|
||||
if runtime.GOOS == "windows" {
|
||||
var err error
|
||||
|
||||
Reference in New Issue
Block a user