mirror of
https://github.com/helm/helm.git
synced 2026-08-05 07:30:46 +00:00
support passing signing passphrase from file or stdin (#8394)
Signed-off-by: Sebastian Sdorra <sebastian.sdorra@cloudogu.com>
This commit is contained in:
@@ -114,6 +114,7 @@ func newPackageCmd(out io.Writer) *cobra.Command {
|
||||
f.BoolVar(&client.Sign, "sign", false, "use a PGP private key to sign this package")
|
||||
f.StringVar(&client.Key, "key", "", "name of the key to use when signing. Used if --sign is true")
|
||||
f.StringVar(&client.Keyring, "keyring", defaultKeyring(), "location of a public keyring")
|
||||
f.StringVar(&client.PassphraseFile, "passphrase-file", "", `location of a file which contains the passphrase for the signing key. Use "-" in order to read from stdin.`)
|
||||
f.StringVar(&client.Version, "version", "", "set the version on the chart to this semver version")
|
||||
f.StringVar(&client.AppVersion, "app-version", "", "set the appVersion on the chart to this version")
|
||||
f.StringVarP(&client.Destination, "destination", "d", ".", "location to write the chart.")
|
||||
|
||||
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package action
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -39,6 +40,7 @@ type Package struct {
|
||||
Sign bool
|
||||
Key string
|
||||
Keyring string
|
||||
PassphraseFile string
|
||||
Version string
|
||||
AppVersion string
|
||||
Destination string
|
||||
@@ -120,7 +122,15 @@ func (p *Package) Clearsign(filename string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := signer.DecryptKey(promptUser); err != nil {
|
||||
passphraseFetcher := promptUser
|
||||
if p.PassphraseFile != "" {
|
||||
passphraseFetcher, err = passphraseFileFetcher(p.PassphraseFile, os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := signer.DecryptKey(passphraseFetcher); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -141,3 +151,34 @@ func promptUser(name string) ([]byte, error) {
|
||||
fmt.Println()
|
||||
return pw, err
|
||||
}
|
||||
|
||||
func passphraseFileFetcher(passphraseFile string, stdin *os.File) (provenance.PassphraseFetcher, error) {
|
||||
file, err := openPassphraseFile(passphraseFile, stdin)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
reader := bufio.NewReader(file)
|
||||
passphrase, _, err := reader.ReadLine()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return func(name string) ([]byte, error) {
|
||||
return passphrase, nil
|
||||
}, nil
|
||||
}
|
||||
|
||||
func openPassphraseFile(passphraseFile string, stdin *os.File) (*os.File, error) {
|
||||
if passphraseFile == "-" {
|
||||
stat, err := stdin.Stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if (stat.Mode() & os.ModeNamedPipe) == 0 {
|
||||
return nil, errors.New("specified reading passphrase from stdin, without input on stdin")
|
||||
}
|
||||
return stdin, nil
|
||||
}
|
||||
return os.Open(passphraseFile)
|
||||
}
|
||||
|
||||
@@ -17,8 +17,12 @@ limitations under the License.
|
||||
package action
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"helm.sh/helm/v3/internal/test/ensure"
|
||||
"helm.sh/helm/v3/pkg/chart"
|
||||
)
|
||||
|
||||
@@ -42,3 +46,57 @@ func TestSetVersion(t *testing.T) {
|
||||
t.Error("Expected bogus version to return an error.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassphraseFileFetcher(t *testing.T) {
|
||||
secret := "secret"
|
||||
directory := ensure.TempFile(t, "passphrase-file", []byte(secret))
|
||||
defer os.RemoveAll(directory)
|
||||
|
||||
fetcher, err := passphraseFileFetcher(path.Join(directory, "passphrase-file"), nil)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to create passphraseFileFetcher", err)
|
||||
}
|
||||
|
||||
passphrase, err := fetcher("key")
|
||||
if err != nil {
|
||||
t.Fatal("Unable to fetch passphrase")
|
||||
}
|
||||
|
||||
if string(passphrase) != secret {
|
||||
t.Errorf("Expected %s got %s", secret, string(passphrase))
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassphraseFileFetcher_WithLineBreak(t *testing.T) {
|
||||
secret := "secret"
|
||||
directory := ensure.TempFile(t, "passphrase-file", []byte(secret+"\n\n."))
|
||||
defer os.RemoveAll(directory)
|
||||
|
||||
fetcher, err := passphraseFileFetcher(path.Join(directory, "passphrase-file"), nil)
|
||||
if err != nil {
|
||||
t.Fatal("Unable to create passphraseFileFetcher", err)
|
||||
}
|
||||
|
||||
passphrase, err := fetcher("key")
|
||||
if err != nil {
|
||||
t.Fatal("Unable to fetch passphrase")
|
||||
}
|
||||
|
||||
if string(passphrase) != secret {
|
||||
t.Errorf("Expected %s got %s", secret, string(passphrase))
|
||||
}
|
||||
}
|
||||
|
||||
func TestPassphraseFileFetcher_WithInvalidStdin(t *testing.T) {
|
||||
directory := ensure.TempDir(t)
|
||||
defer os.RemoveAll(directory)
|
||||
|
||||
stdin, err := ioutil.TempFile(directory, "non-existing")
|
||||
if err != nil {
|
||||
t.Fatal("Unable to create test file", err)
|
||||
}
|
||||
|
||||
if _, err := passphraseFileFetcher("-", stdin); err == nil {
|
||||
t.Error("Expected passphraseFileFetcher returning an error")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user