Skip to content

Commit 3ada89e

Browse files
authored
Merge pull request #1393 from felixfontein/encrypted-check
Make check whether file contains invalid keys for encryption dependent on output store
2 parents cc0477c + 1bda828 commit 3ada89e

File tree

9 files changed

+88
-6
lines changed

9 files changed

+88
-6
lines changed

cmd/sops/encrypt.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ func (err *fileAlreadyEncryptedError) Error() string {
3636

3737
func (err *fileAlreadyEncryptedError) UserError() string {
3838
message := "The file you have provided contains a top-level entry called " +
39-
"'sops'. This is generally due to the file already being encrypted. " +
39+
"'sops', or for flat file formats top-level entries starting with " +
40+
"'sops_'. This is generally due to the file already being encrypted. " +
4041
"SOPS uses a top-level entry called 'sops' to store the metadata " +
4142
"required to decrypt the file. For this reason, SOPS can not " +
4243
"encrypt files that already contain such an entry.\n\n" +
@@ -47,10 +48,8 @@ func (err *fileAlreadyEncryptedError) UserError() string {
4748
}
4849

4950
func ensureNoMetadata(opts encryptOpts, branch sops.TreeBranch) error {
50-
for _, b := range branch {
51-
if b.Key == "sops" {
52-
return &fileAlreadyEncryptedError{}
53-
}
51+
if opts.OutputStore.HasSopsTopLevelKey(branch) {
52+
return &fileAlreadyEncryptedError{}
5453
}
5554
return nil
5655
}

sops.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,13 +567,20 @@ type ValueEmitter interface {
567567
EmitValue(interface{}) ([]byte, error)
568568
}
569569

570+
// CheckEncryped is the interface for testing whether a branch contains sops
571+
// metadata. This is used to check whether a file is already encrypted or not.
572+
type CheckEncryped interface {
573+
HasSopsTopLevelKey(TreeBranch) bool
574+
}
575+
570576
// Store is used to interact with files, both encrypted and unencrypted.
571577
type Store interface {
572578
EncryptedFileLoader
573579
PlainFileLoader
574580
EncryptedFileEmitter
575581
PlainFileEmitter
576582
ValueEmitter
583+
CheckEncryped
577584
}
578585

579586
// MasterKeyCount returns the number of master keys available

stores/dotenv/store.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,15 @@ func isComplexValue(v interface{}) bool {
175175
}
176176
return false
177177
}
178+
179+
// HasSopsTopLevelKey checks whether a top-level "sops" key exists.
180+
func (store *Store) HasSopsTopLevelKey(branch sops.TreeBranch) bool {
181+
for _, b := range branch {
182+
if key, ok := b.Key.(string); ok {
183+
if strings.HasPrefix(key, SopsPrefix) {
184+
return true
185+
}
186+
}
187+
}
188+
return false
189+
}

stores/dotenv/store_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,20 @@ func TestEmitEncryptedFileStability(t *testing.T) {
8080
previous = bytes
8181
}
8282
}
83+
84+
func TestHasSopsTopLevelKey(t *testing.T) {
85+
ok := (&Store{}).HasSopsTopLevelKey(sops.TreeBranch{
86+
sops.TreeItem{
87+
Key: "sops",
88+
Value: "value",
89+
},
90+
})
91+
assert.Equal(t, ok, false)
92+
ok = (&Store{}).HasSopsTopLevelKey(sops.TreeBranch{
93+
sops.TreeItem{
94+
Key: "sops_",
95+
Value: "value",
96+
},
97+
})
98+
assert.Equal(t, ok, true)
99+
}

stores/ini/store.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,3 +274,8 @@ func (store *Store) EmitExample() []byte {
274274
}
275275
return bytes
276276
}
277+
278+
// HasSopsTopLevelKey checks whether a top-level "sops" key exists.
279+
func (store *Store) HasSopsTopLevelKey(branch sops.TreeBranch) bool {
280+
return stores.HasSopsTopLevelKey(branch)
281+
}

stores/json/store.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,3 +357,13 @@ func (store *Store) EmitExample() []byte {
357357
}
358358
return bytes
359359
}
360+
361+
// HasSopsTopLevelKey checks whether a top-level "sops" key exists.
362+
func (store *Store) HasSopsTopLevelKey(branch sops.TreeBranch) bool {
363+
return stores.HasSopsTopLevelKey(branch)
364+
}
365+
366+
// HasSopsTopLevelKey checks whether a top-level "sops" key exists.
367+
func (store *BinaryStore) HasSopsTopLevelKey(branch sops.TreeBranch) bool {
368+
return stores.HasSopsTopLevelKey(branch)
369+
}

stores/stores.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,3 +506,13 @@ var ExampleFlatTree = sops.Tree{
506506
},
507507
},
508508
}
509+
510+
// HasSopsTopLevelKey returns true if the given branch has a top-level key called "sops".
511+
func HasSopsTopLevelKey(branch sops.TreeBranch) bool {
512+
for _, b := range branch {
513+
if b.Key == "sops" {
514+
return true
515+
}
516+
}
517+
return false
518+
}

stores/yaml/store.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,8 @@ func (store *Store) EmitExample() []byte {
417417
}
418418
return bytes
419419
}
420+
421+
// HasSopsTopLevelKey checks whether a top-level "sops" key exists.
422+
func (store *Store) HasSopsTopLevelKey(branch sops.TreeBranch) bool {
423+
return stores.HasSopsTopLevelKey(branch)
424+
}

stores/yaml/store_test.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,4 +380,21 @@ func TestIndent1(t *testing.T) {
380380
assert.Nil(t, err)
381381
assert.Equal(t, string(INDENT_1_OUT), string(bytes))
382382
assert.Equal(t, INDENT_1_OUT, bytes)
383-
}
383+
}
384+
385+
func TestHasSopsTopLevelKey(t *testing.T) {
386+
ok := (&Store{}).HasSopsTopLevelKey(sops.TreeBranch{
387+
sops.TreeItem{
388+
Key: "sops",
389+
Value: "value",
390+
},
391+
})
392+
assert.Equal(t, ok, true)
393+
ok = (&Store{}).HasSopsTopLevelKey(sops.TreeBranch{
394+
sops.TreeItem{
395+
Key: "sops_",
396+
Value: "value",
397+
},
398+
})
399+
assert.Equal(t, ok, false)
400+
}

0 commit comments

Comments
 (0)