diff --git a/cli/context/store/metadata_test.go b/cli/context/store/metadata_test.go index 8c6389894b2d..8514fc420390 100644 --- a/cli/context/store/metadata_test.go +++ b/cli/context/store/metadata_test.go @@ -6,11 +6,13 @@ package store import ( "os" "path/filepath" + "runtime" "testing" "github.com/containerd/errdefs" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" + "gotest.tools/v3/skip" ) func testMetadata(name string) Metadata { @@ -73,6 +75,28 @@ func TestMetadataRespectJsonAnnotation(t *testing.T) { assert.Assert(t, is.Contains(string(bytes), "another_very_recognizable_field_name")) } +func TestMetadataCreateDirectoryPermissions(t *testing.T) { + skip.If(t, runtime.GOOS == "windows", "unix permissions are not supported on Windows") + + configDir := filepath.Join(t.TempDir(), ".docker") + testee := metadataStore{root: filepath.Join(configDir, "contexts", metadataDir), config: testCfg} + assert.NilError(t, testee.createOrUpdate(testMetadata("test"))) + + // All directories, including the config-directory if it did not yet exist, + // should only be accessible by the current user, matching the permissions + // used when saving the config-file. + for _, dir := range []string{ + configDir, + filepath.Dir(testee.root), + testee.root, + testee.contextDir(contextdirOf("test")), + } { + fi, err := os.Stat(dir) + assert.NilError(t, err) + assert.Check(t, is.Equal(fi.Mode().Perm(), os.FileMode(0o700)), dir) + } +} + func TestMetadataList(t *testing.T) { testee := metadataStore{root: t.TempDir(), config: testCfg} wholeData := []Metadata{ diff --git a/cli/context/store/metadatastore.go b/cli/context/store/metadatastore.go index 1751e820690b..bf6b264d2aee 100644 --- a/cli/context/store/metadatastore.go +++ b/cli/context/store/metadatastore.go @@ -32,7 +32,7 @@ func (s *metadataStore) contextDir(id contextdir) string { func (s *metadataStore) createOrUpdate(meta Metadata) error { contextDir := s.contextDir(contextdirOf(meta.Name)) - if err := os.MkdirAll(contextDir, 0o755); err != nil { + if err := os.MkdirAll(contextDir, 0o700); err != nil { return err } bytes, err := json.Marshal(&meta) diff --git a/cli/context/store/tlsstore.go b/cli/context/store/tlsstore.go index c1f5f8caa2cb..f49982b4ad21 100644 --- a/cli/context/store/tlsstore.go +++ b/cli/context/store/tlsstore.go @@ -23,10 +23,6 @@ func (s *tlsStore) endpointDir(name, endpointName string) string { } func (s *tlsStore) createOrUpdate(name, endpointName, filename string, data []byte) error { - parentOfRoot := filepath.Dir(s.root) - if err := os.MkdirAll(parentOfRoot, 0o755); err != nil { - return err - } endpointDir := s.endpointDir(name, endpointName) if err := os.MkdirAll(endpointDir, 0o700); err != nil { return err diff --git a/cli/context/store/tlsstore_test.go b/cli/context/store/tlsstore_test.go index 799362d54e14..274fd3986c25 100644 --- a/cli/context/store/tlsstore_test.go +++ b/cli/context/store/tlsstore_test.go @@ -1,10 +1,15 @@ package store import ( + "os" + "path/filepath" + "runtime" "testing" "github.com/containerd/errdefs" "gotest.tools/v3/assert" + is "gotest.tools/v3/assert/cmp" + "gotest.tools/v3/skip" ) func TestTlsCreateUpdateGetRemove(t *testing.T) { @@ -32,6 +37,31 @@ func TestTlsCreateUpdateGetRemove(t *testing.T) { assert.ErrorType(t, err, errdefs.IsNotFound) } +func TestTlsCreateDirectoryPermissions(t *testing.T) { + skip.If(t, runtime.GOOS == "windows", "unix permissions are not supported on Windows") + + configDir := filepath.Join(t.TempDir(), ".docker") + testee := tlsStore{root: filepath.Join(configDir, "contexts", tlsDir)} + + const contextName = "test-ctx" + assert.NilError(t, testee.createOrUpdate(contextName, "test-ep", "test-data", []byte("data"))) + + // All directories, including the config-directory if it did not yet exist, + // should only be accessible by the current user, matching the permissions + // used when saving the config-file. + for _, dir := range []string{ + configDir, + filepath.Dir(testee.root), + testee.root, + testee.contextDir(contextName), + testee.endpointDir(contextName, "test-ep"), + } { + fi, err := os.Stat(dir) + assert.NilError(t, err) + assert.Check(t, is.Equal(fi.Mode().Perm(), os.FileMode(0o700)), dir) + } +} + func TestTlsListAndBatchRemove(t *testing.T) { testee := tlsStore{root: t.TempDir()}