gpg: Use a Pipe() rather than a file

Use a Pipe() rather than a file to pass the passphrase to the command
line tool. Pass the file descriptor to read the passphrase from as fd '3'.

Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
This commit is contained in:
Stefan Berger 2019-07-31 16:03:44 -04:00
parent 6a25128791
commit 5cf79913e4

View File

@ -131,18 +131,24 @@ func (gc *gpgv2Client) GetGPGPrivateKey(keyid uint64, passphrase string) ([]byte
args = append(args, []string{"--homedir", gc.gpgHomeDir}...) args = append(args, []string{"--homedir", gc.gpgHomeDir}...)
} }
tempfile, err := ioutil.TempFile("", "gpg2*") rfile, wfile, err := os.Pipe()
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "could not create temporary file") return nil, errors.Wrapf(err, "could not create pipe")
}
defer os.Remove(tempfile.Name())
if err := ioutil.WriteFile(tempfile.Name(), []byte(passphrase), 0600); err != nil {
return nil, errors.Wrapf(err, "could not write to temporary file")
} }
defer func() {
rfile.Close()
wfile.Close()
}()
// fill pipe in background
go func(passphrase string) {
wfile.Write([]byte(passphrase))
wfile.Close()
}(passphrase)
args = append(args, []string{"--pinentry-mode", "loopback", "--batch", "--passphrase-file", tempfile.Name(), "--export-secret-key", fmt.Sprintf("0x%x", keyid)}...) args = append(args, []string{"--pinentry-mode", "loopback", "--batch", "--passphrase-fd", fmt.Sprintf("%d", 3), "--export-secret-key", fmt.Sprintf("0x%x", keyid)}...)
cmd := exec.Command("gpg2", args...) cmd := exec.Command("gpg2", args...)
cmd.ExtraFiles = []*os.File{rfile}
return runGPGGetOutput(cmd) return runGPGGetOutput(cmd)
} }