Skip to content

Commit

Permalink
Better error reporting for missing gpg binary
Browse files Browse the repository at this point in the history
The error returned by `gpgExec` has just been swallowed. Now it is
stringified and returned together with any output to stderr.

Signed-off-by: Max Jonas Werner <mail@makk.es>
  • Loading branch information
Max Jonas Werner authored and hiddeco committed Oct 9, 2023
1 parent e0c73ec commit e1862de
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 3 deletions.
17 changes: 15 additions & 2 deletions pgp/keysource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package pgp //import "github.com/getsops/sops/v3/pgp"
import (
"bytes"
"encoding/hex"
"errors"
"fmt"
"io"
"os"
Expand Down Expand Up @@ -131,9 +132,21 @@ func (d GnuPGHome) Import(armoredKey []byte) error {
}

args := []string{"--batch", "--import"}
_, stderr, err := gpgExec(d.String(), args, bytes.NewReader(armoredKey))
_, stderrBuf, err := gpgExec(d.String(), args, bytes.NewReader(armoredKey))
if err != nil {
return fmt.Errorf("failed to import armored key data into GnuPG keyring: %s", strings.TrimSpace(stderr.String()))
stderr := stderrBuf.String()
errStr := err.Error()
var sb strings.Builder
sb.WriteString("failed to import armored key data into GnuPG keyring")
if len(stderr) > 0 {
fmt.Fprintf(&sb, ": %s", stderr)
if len(errStr) > 0 {
fmt.Fprintf(&sb, ": %s", errStr)
}
} else if len(errStr) > 0 {
fmt.Fprintf(&sb, ": %s", errStr)
}
return errors.New(sb.String())
}
return nil
}
Expand Down
19 changes: 18 additions & 1 deletion pgp/keysource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,27 @@ func TestGnuPGHome_Import(t *testing.T) {
_, stderr, err = gpgExec(gnuPGHome.String(), []string{"--list-secret-keys", mockFingerprint}, nil)
assert.NoErrorf(t, err, stderr.String())

assert.Error(t, gnuPGHome.Import([]byte("invalid armored data")))
err = gnuPGHome.Import([]byte("invalid armored data"))
assert.Error(t, err)
assert.ErrorContains(t, err, "gpg: no valid OpenPGP data found.\ngpg: Total number processed: 0\n: exit status 2")
assert.Error(t, GnuPGHome("").Import(b))
}

func TestGnuPGHome_Import_With_Missing_Binary(t *testing.T) {
t.Setenv(SopsGpgExecEnv, "/does/not/exist")

gnuPGHome, err := NewGnuPGHome()
assert.NoError(t, err)
t.Cleanup(func() {
_ = os.RemoveAll(gnuPGHome.String())
})

b, err := os.ReadFile(mockPublicKey)
assert.NoError(t, err)
err = gnuPGHome.Import(b)
assert.ErrorContains(t, err, "failed to import armored key data into GnuPG keyring: fork/exec /does/not/exist: no such file or directory")
}

func TestGnuPGHome_ImportFile(t *testing.T) {
gnuPGHome, err := NewGnuPGHome()
assert.NoError(t, err)
Expand Down

0 comments on commit e1862de

Please sign in to comment.