mirror of
https://github.com/getsops/sops.git
synced 2026-02-05 12:45:21 +01:00
pgp: improve handling of GnuPG home dir
There have been reports about the new logic breaking certain GnuPG shims (#1294). As this behavior is only really required when SDK users are making use of the GnuPG using SOPS as an SDK. Prefer any runtime configuration when no custom GnuPG home is configured on the key source, instead of providing an absolute `--homedir` to `gpg`. Signed-off-by: Hidde Beydals <hidde@hhh.computer>
This commit is contained in:
@@ -318,7 +318,7 @@ func (key *MasterKey) encryptWithGnuPG(dataKey []byte) error {
|
||||
fingerprint,
|
||||
"--no-encrypt-to",
|
||||
}
|
||||
err, stdout, stderr := gpgExec(key.gnuPGHome(), args, bytes.NewReader(dataKey))
|
||||
err, stdout, stderr := gpgExec(key.gnuPGHomeDir, args, bytes.NewReader(dataKey))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encrypt sops data key with pgp: %s", strings.TrimSpace(stderr.String()))
|
||||
}
|
||||
@@ -407,7 +407,7 @@ func (key *MasterKey) decryptWithGnuPG() ([]byte, error) {
|
||||
args := []string{
|
||||
"-d",
|
||||
}
|
||||
err, stdout, stderr := gpgExec(key.gnuPGHome(), args, strings.NewReader(key.EncryptedKey))
|
||||
err, stdout, stderr := gpgExec(key.gnuPGHomeDir, args, strings.NewReader(key.EncryptedKey))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to decrypt sops data key with pgp: %s",
|
||||
strings.TrimSpace(stderr.String()))
|
||||
@@ -436,27 +436,6 @@ func (key MasterKey) ToMap() map[string]interface{} {
|
||||
return out
|
||||
}
|
||||
|
||||
// gnuPGHome determines the GnuPG home directory for the MasterKey, and returns
|
||||
// its path. In order of preference:
|
||||
// 1. MasterKey.gnuPGHomeDir
|
||||
// 2. $GNUPGHOME
|
||||
// 3. user.Current().HomeDir/.gnupg
|
||||
// 4. $HOME/.gnupg
|
||||
func (key *MasterKey) gnuPGHome() string {
|
||||
if key.gnuPGHomeDir == "" {
|
||||
dir := os.Getenv("GNUPGHOME")
|
||||
if dir == "" {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return filepath.Join(os.Getenv("HOME"), ".gnupg")
|
||||
}
|
||||
return filepath.Join(usr.HomeDir, ".gnupg")
|
||||
}
|
||||
return dir
|
||||
}
|
||||
return key.gnuPGHomeDir
|
||||
}
|
||||
|
||||
// retrievePubKey attempts to retrieve the public key from the public keyring
|
||||
// by Fingerprint.
|
||||
func (key *MasterKey) retrievePubKey() (openpgp.Entity, error) {
|
||||
@@ -479,7 +458,7 @@ func (key *MasterKey) retrievePubKey() (openpgp.Entity, error) {
|
||||
func (key *MasterKey) getPubRing() (openpgp.EntityList, error) {
|
||||
path := key.pubRing
|
||||
if path == "" {
|
||||
path = filepath.Join(key.gnuPGHome(), defaultPubRing)
|
||||
path = filepath.Join(gnuPGHome(key.gnuPGHomeDir), defaultPubRing)
|
||||
}
|
||||
return loadRing(path)
|
||||
}
|
||||
@@ -490,7 +469,7 @@ func (key *MasterKey) getPubRing() (openpgp.EntityList, error) {
|
||||
func (key *MasterKey) getSecRing() (openpgp.EntityList, error) {
|
||||
path := key.secRing
|
||||
if path == "" {
|
||||
path = filepath.Join(key.gnuPGHome(), defaultSecRing)
|
||||
path = filepath.Join(gnuPGHome(key.gnuPGHomeDir), defaultSecRing)
|
||||
}
|
||||
if _, err := os.Lstat(path); err != nil {
|
||||
if !os.IsNotExist(err) {
|
||||
@@ -609,6 +588,28 @@ func gpgBinary() string {
|
||||
return binary
|
||||
}
|
||||
|
||||
// gnuPGHome determines the GnuPG home directory, and returns its path.
|
||||
// In order of preference:
|
||||
// 1. customPath
|
||||
// 2. $GNUPGHOME
|
||||
// 3. user.Current().HomeDir/.gnupg
|
||||
// 4. $HOME/.gnupg
|
||||
func gnuPGHome(customPath string) string {
|
||||
if customPath != "" {
|
||||
return customPath
|
||||
}
|
||||
|
||||
dir := os.Getenv("GNUPGHOME")
|
||||
if dir == "" {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return filepath.Join(os.Getenv("HOME"), ".gnupg")
|
||||
}
|
||||
return filepath.Join(usr.HomeDir, ".gnupg")
|
||||
}
|
||||
return dir
|
||||
}
|
||||
|
||||
// shortenFingerprint returns the short ID of the given fingerprint.
|
||||
// This is mostly used for compatability reasons, as older versions of GnuPG
|
||||
// do not always like long IDs.
|
||||
|
||||
@@ -271,7 +271,7 @@ func TestMasterKey_encryptWithGnuPG(t *testing.T) {
|
||||
args := []string{
|
||||
"-d",
|
||||
}
|
||||
err, stdout, stderr := gpgExec(key.gnuPGHome(), args, strings.NewReader(key.EncryptedKey))
|
||||
err, stdout, stderr := gpgExec(key.gnuPGHomeDir, args, strings.NewReader(key.EncryptedKey))
|
||||
assert.NoError(t, err, stderr.String())
|
||||
assert.Equal(t, data, stdout.Bytes())
|
||||
})
|
||||
@@ -529,24 +529,6 @@ func TestMasterKey_ToMap(t *testing.T) {
|
||||
}, key.ToMap())
|
||||
}
|
||||
|
||||
func TestMasterKey_gnuPGHome(t *testing.T) {
|
||||
key := &MasterKey{}
|
||||
|
||||
usr, err := user.Current()
|
||||
if err == nil {
|
||||
assert.Equal(t, filepath.Join(usr.HomeDir, ".gnupg"), key.gnuPGHome())
|
||||
} else {
|
||||
assert.Equal(t, filepath.Join(os.Getenv("HOME"), ".gnupg"), key.gnuPGHome())
|
||||
}
|
||||
|
||||
gnupgHome := "/overwrite/home"
|
||||
t.Setenv("GNUPGHOME", gnupgHome)
|
||||
assert.Equal(t, gnupgHome, key.gnuPGHome())
|
||||
|
||||
key.gnuPGHomeDir = "/home/dir/overwrite"
|
||||
assert.Equal(t, key.gnuPGHomeDir, key.gnuPGHome())
|
||||
}
|
||||
|
||||
func TestMasterKey_retrievePubKey(t *testing.T) {
|
||||
t.Run("existing fingerprint", func(t *testing.T) {
|
||||
key := NewMasterKeyFromFingerprint(mockFingerprint)
|
||||
@@ -671,6 +653,22 @@ func Test_gpgBinary(t *testing.T) {
|
||||
assert.Equal(t, overwrite, gpgBinary())
|
||||
}
|
||||
|
||||
func Test_gnuPGHome(t *testing.T) {
|
||||
usr, err := user.Current()
|
||||
if err == nil {
|
||||
assert.Equal(t, filepath.Join(usr.HomeDir, ".gnupg"), gnuPGHome(""))
|
||||
} else {
|
||||
assert.Equal(t, filepath.Join(os.Getenv("HOME"), ".gnupg"), gnuPGHome(""))
|
||||
}
|
||||
|
||||
gnupgHome := "/overwrite/home"
|
||||
t.Setenv("GNUPGHOME", gnupgHome)
|
||||
assert.Equal(t, gnupgHome, gnuPGHome(""))
|
||||
|
||||
customP := "/home/dir/overwrite"
|
||||
assert.Equal(t, customP, gnuPGHome(customP))
|
||||
}
|
||||
|
||||
func Test_shortenFingerprint(t *testing.T) {
|
||||
shortId := shortenFingerprint(mockFingerprint)
|
||||
assert.Equal(t, "9732075EA221A7EA", shortId)
|
||||
|
||||
Reference in New Issue
Block a user