8000 trust: add flag --skip-trusted by indradhanush · Pull Request #3812 · rkt/rkt · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content
This repository was archived by the owner on Feb 24, 2020. It is now read-only.

trust: add flag --skip-trusted #3812

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions Documentation/subcommands/trust.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ $ find /etc/rkt/trustedkeys/
| `--prefix` | `` | A URL prefix | Prefix to limit trust to |
| `--root` | `false` | `true` or `false` | Add root key from filesystem without a prefix |
| `--skip-fingerprint-review` | `false` | `true` or `false` | Accept key without fingerprint confirmation |
| `--skip-trusted` | `true` | `true` or `false` | Skip previously downloaded and trusted pubkeys |

## Global options

Expand Down
2 changes: 1 addition & 1 deletion rkt/image/namefetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ func (f *nameFetcher) maybeFetchPubKeys(appName string) {
if f.TrustKeysFromHTTPS {
accept = pubkey.AcceptForce
}
err := m.AddKeys(pkls, appName, accept)
err := m.AddKeys(pkls, appName, accept, true)
if err != nil {
log.PrintE("error adding keys", err)
}
Expand Down
14 changes: 13 additions & 1 deletion rkt/pubkey/pubkey.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ func (m *Manager) GetPubKeyLocations(prefix string) ([]string, error) {
}

// AddKeys adds the keys listed in pkls at prefix
func (m *Manager) AddKeys(pkls []string, prefix string, accept AcceptOption) error {
func (m *Manager) AddKeys(pkls []string, prefix string, accept AcceptOption, skipTrusted bool) error {
ensureLogger(m.Debug)
if m.Ks == nil {
return fmt.Errorf("no keystore available to add keys to")
Expand All @@ -110,6 +110,18 @@ func (m *Manager) AddKeys(pkls []string, prefix string, accept AcceptOption) err
return errwrap.Wrap(fmt.Errorf("error displaying the key %s", pkl), err)
}

if skipTrusted {
trusted, err := m.Ks.TrustedKeyPrefixExists(prefix)
if err != nil {
return errwrap.Wrap(fmt.Errorf("error in determining if key %s is trusted", pkl), err)
}

if trusted {
log.Printf("Already trusted %q for prefix %q.\n", pkl, prefix)
continue
}
}

if m.TrustKeysFromHTTPS && u.Scheme == "https" {
accept = AcceptForce
}
Expand Down
6 changes: 4 additions & 2 deletions rkt/trust.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import (

var (
cmdTrust = &cobra.Command{
Use: "trust [--prefix=PREFIX] [--insecure-allow-http] [--skip-fingerprint-review] [--root] [PUBKEY ...]",
Use: "trust [--prefix=PREFIX] [--insecure-allow-http] [--skip-fingerprint-review] [--skip-trusted] [--root] [PUBKEY ...]",
Short: "Trust a key for image verification",
Long: `Adds keys to the local keystore for use in verifying signed images.

Expand All @@ -46,6 +46,7 @@ specified. Path to a key file must be given (no discovery).`,
flagRoot bool
flagAllowHTTP bool
flagSkipFingerprintReview bool
flagSkipTrusted bool
)

func init() {
Expand All @@ -54,6 +55,7 @@ func init() {
cmdTrust.Flags().BoolVar(&flagRoot, "root", false, "add root key from filesystem without a prefix")
cmdTrust.Flags().BoolVar(&flagSkipFingerprintReview, "skip-fingerprint-review", false, "accept key without fingerprint confirmation")
cmdTrust.Flags().BoolVar(&flagAllowHTTP, "insecure-allow-http", false, "allow HTTP use for key discovery and/or retrieval")
cmdTrust.Flags().BoolVar(&flagSkipTrusted, "skip-trusted", false, "skip previously downloaded and trusted pubkeys")
}

func runTrust(cmd *cobra.Command, args []string) (exit int) {
Expand Down Expand Up @@ -110,7 +112,7 @@ Otherwise, trust at the root domain (not recommended) must be explicitly request
acceptOpt = pubkey.AcceptForce
}

if err := m.AddKeys(pkls, flagPrefix, acceptOpt); err != nil {
if err := m.AddKeys(pkls, flagPrefix, acceptOpt, flagSkipTrusted); err != nil {
stderr.PrintE("error adding keys", err)
return 254
}
Expand Down
50 changes: 50 additions & 0 deletions tests/rkt_tests.go
Original file line number Diff line number Diff line change
Expand Up @@ -894,6 +894,56 @@ func runRktTrust(t *testing.T, ctx *testutils.RktRunCtx, prefix string, keyIndex
}
}

func assertTrustPrompt(t *testing.T, prefix string, child *gexpect.ExpectSubprocess) {
expected := "Are you sure you want to trust this key"
if err := expectWithOutput(child, expected); err != nil {
t.Fatalf("Expected but didn't find %q in %v", expected, err)
}

if err := child.SendLine("yes"); err != nil {
t.Fatalf("Cannot confirm rkt trust: %s", err)
}

expected = fmt.Sprintf(`Added key for prefix "%s" at`, prefix)
if err := expectWithOutput(child, expected); err != nil {
t.Fatalf("Expected but didn't find %q in %v", expected, err)
}
}

func runRktTrustSkipTrustedTrue(t *testing.T, ctx *testutils.RktRunCtx, prefix string, keyIndex int, alreadyTrusted bool) {
keyFile := fmt.Sprintf("key%d.gpg", keyIndex)
cmd := fmt.Sprintf(`%s trust --prefix %s --skip-trusted %s`, ctx.Cmd(), prefix, keyFile)

child := spawnOrFail(t, cmd)
defer waitOrFail(t, child, 0)

if !alreadyTrusted {
assertTrustPrompt(t, prefix, child)
return
}

expected := "Already trusted"
if err := expectWithOutput(child, expected); err != nil {
t.Fatalf("Expected but didn't find %q in %v", expected, err)
}
}

func runRktTrustSkipTrustedFalse(t *testing.T, ctx *testutils.RktRunCtx, prefix string, keyIndex int, alreadyTrusted bool) {
if alreadyTrusted {
// Trust the key ahead of time to ensure that
// --skip-trusted=false overwrites the trusted key.
runRktTrust(t, ctx, prefix, keyIndex)
}

keyFile := fmt.Sprintf("key%d.gpg", keyIndex)
cmd := fmt.Sprintf(`%s trust --prefix %s --skip-trusted=false %s`, ctx.Cmd(), prefix, keyFile)

child := spawnOrFail(t, cmd)
defer waitOrFail(t, child, 0)

assertTrustPrompt(t, prefix, child)
}

func generatePodManifestFile(t *testing.T, manifest *schema.PodManifest) string {
tmpDir := testutils.GetValueFromEnvOrPanic("FUNCTIONAL_TMP")
f, err := ioutil.TempFile(tmpDir, "rkt-test-manifest-")
Expand Down
34 changes: 34 additions & 0 deletions tests/rkt_trust_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ func TestTrust(t *testing.T) {
imageFile2 := patchTestACI("rkt-inspect-trust2.aci", "--exec=/inspect --print-msg=Hello", "--name=rkt-alternative.com/my-app")
defer os.Remove(imageFile2)

imageFile3 := patchTestACI("rkt-inspect-trust3.aci", "--exec=/inspect --print-msg=Hello", "--name=rkt-skip-trusted.com/my-app")
defer os.Remove(imageFile3)

imageFile4 := patchTestACI("rkt-inspect-trust4.aci", "--exec=/inspect --print-msg=Hello", "--name=rkt-skip-trusted-alternative.com/my-app")
defer os.Remove(imageFile3)

ctx := testutils.NewRktRunCtx()
defer ctx.Cleanup()

Expand All @@ -47,6 +53,10 @@ func TestTrust(t *testing.T) {
defer os.Remove(ascFile)
ascFile = runSignImage(t, imageFile2, 1)
defer os.Remove(ascFile)
ascFile = runSignImage(t, imageFile3, 1)
defer os.Remove(ascFile)
ascFile = runSignImage(t, imageFile4, 1)
defer os.Remove(ascFile)

t.Logf("Run the signed image without trusting the key: it should fail\n")
runImage(t, ctx, imageFile, "openpgp: signature made by unknown entity", true)
Expand Down Expand Up @@ -78,6 +88,30 @@ func TestTrust(t *testing.T) {
runImage(t, ctx, imageFile, "Hello", false)
runImage(t, ctx, imageFile2, "openpgp: signature made by unknown entity", true)

t.Logf("Skip trusted key (rkt trust --skip-trusted) with trusted key absent\n")
runRktTrustSkipTrustedTrue(t, ctx, "rkt-skip-trusted.com/my-app", 1, false)

t.Logf("Now the image can be executed\n")
runImage(t, ctx, imageFile3, "Hello", false)

t.Logf("Skip trusted key (rkt trust --skip-trusted) with trusted key present\n")
runRktTrustSkipTrustedTrue(t, ctx, "rkt-skip-trusted.com/my-app", 1, true)

t.Logf("Now the image can be executed\n")
runImage(t, ctx, imageFile3, "Hello", false)

t.Logf("Don't skip trusted key (rkt trust --skip-trusted=false) with trusted key present\n")
runRktTrustSkipTrustedFalse(t, ctx, "rkt-skip-trusted.com/my-app", 1, true)

t.Logf("Now the image can be executed\n")
runImage(t, ctx, imageFile3, "Hello", false)

t.Logf("Don't skip trusted key (rkt trust --skip-trusted=false) with trusted key absent\n")
runRktTrustSkipTrustedFalse(t, ctx, "rkt-skip-trusted-alternative.com/my-app", 1, false)

t.Logf("Now the image can be executed\n")
runImage(t, ctx, imageFile4, "Hello", false)

t.Logf("Trust the key for all images (rkt trust --root)\n")
runRktTrust(t, ctx, "", 1)

Expand Down
0