Skip to content

Commit ffc1e26

Browse files
committed
Ignore encryption selection options for binary store (and warn when they are used).
Signed-off-by: Felix Fontein <[email protected]>
1 parent 8117a49 commit ffc1e26

File tree

6 files changed

+82
-6
lines changed

6 files changed

+82
-6
lines changed

cmd/sops/main.go

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,7 +1023,7 @@ func main() {
10231023
}
10241024
svcs := keyservices(c)
10251025

1026-
encConfig, err := getEncryptConfig(c, fileNameOverride, nil)
1026+
encConfig, err := getEncryptConfig(c, fileNameOverride, inputStore, nil)
10271027
if err != nil {
10281028
return toExitError(err)
10291029
}
@@ -1369,7 +1369,7 @@ func main() {
13691369
}
13701370
} else {
13711371
// File doesn't exist, edit the example file instead
1372-
encConfig, err := getEncryptConfig(c, fileName, nil)
1372+
encConfig, err := getEncryptConfig(c, fileName, inputStore, nil)
13731373
if err != nil {
13741374
return toExitError(err)
13751375
}
@@ -1908,7 +1908,7 @@ func main() {
19081908
}
19091909
var output []byte
19101910
if isEncryptMode {
1911-
encConfig, err := getEncryptConfig(c, fileNameOverride, config)
1911+
encConfig, err := getEncryptConfig(c, fileNameOverride, inputStore, config)
19121912
if err != nil {
19131913
return toExitError(err)
19141914
}
@@ -1996,7 +1996,7 @@ func main() {
19961996
output, err = edit(opts)
19971997
} else {
19981998
// File doesn't exist, edit the example file instead
1999-
encConfig, err := getEncryptConfig(c, fileNameOverride, config)
1999+
encConfig, err := getEncryptConfig(c, fileNameOverride, inputStore, config)
20002000
if err != nil {
20012001
return toExitError(err)
20022002
}
@@ -2050,7 +2050,7 @@ func main() {
20502050
}
20512051
}
20522052

2053-
func getEncryptConfig(c *cli.Context, fileName string, optionalConfig *config.Config) (encryptConfig, error) {
2053+
func getEncryptConfig(c *cli.Context, fileName string, inputStore common.Store, optionalConfig *config.Config) (encryptConfig, error) {
20542054
unencryptedSuffix := c.String("unencrypted-suffix")
20552055
encryptedSuffix := c.String("encrypted-suffix")
20562056
encryptedRegex := c.String("encrypted-regex")
@@ -2090,6 +2090,33 @@ func getEncryptConfig(c *cli.Context, fileName string, optionalConfig *config.Co
20902090
}
20912091
}
20922092

2093+
if inputStore.IsSingleValueStore() {
2094+
// Warn about settings that potentially disable encryption of the single key.
2095+
if unencryptedSuffix != "" {
2096+
log.Warn(fmt.Sprintf("Using an unencrypted suffix does not make sense with the input store (the %s store produces one key that should always be encrypted) and will be ignored.", inputStore.Name()))
2097+
}
2098+
if encryptedSuffix != "" {
2099+
log.Warn(fmt.Sprintf("Using an encrypted suffix does not make sense with the input store (the %s store produces one key that should always be encrypted) and will be ignored.", inputStore.Name()))
2100+
}
2101+
if encryptedRegex != "" {
2102+
log.Warn(fmt.Sprintf("Using an encrypted regex does not make sense with the input store (the %s store produces one key that should always be encrypted) and will be ignored.", inputStore.Name()))
2103+
}
2104+
if unencryptedRegex != "" {
2105+
log.Warn(fmt.Sprintf("Using an unencrypted regex does not make sense with the input store (the %s store produces one key that should always be encrypted) and will be ignored.", inputStore.Name()))
2106+
}
2107+
if encryptedCommentRegex != "" {
2108+
log.Warn(fmt.Sprintf("Using an encrypted comment regex does not make sense with the input store (the %s store never produces comments) and will be ignored.", inputStore.Name()))
2109+
}
2110+
// Do not warn about unencryptedCommentRegex and macOnlyEncrypted since they cannot have any effect.
2111+
unencryptedSuffix = ""
2112+
encryptedSuffix = ""
2113+
encryptedRegex = ""
2114+
unencryptedRegex = ""
2115+
encryptedCommentRegex = ""
2116+
unencryptedCommentRegex = ""
2117+
macOnlyEncrypted = false
2118+
}
2119+
20932120
cryptRuleCount := 0
20942121
if unencryptedSuffix != "" {
20952122
cryptRuleCount++
@@ -2115,7 +2142,7 @@ func getEncryptConfig(c *cli.Context, fileName string, optionalConfig *config.Co
21152142
}
21162143

21172144
// only supply the default UnencryptedSuffix when EncryptedSuffix, EncryptedRegex, and others are not provided
2118-
if cryptRuleCount == 0 {
2145+
if cryptRuleCount == 0 && !inputStore.IsSingleValueStore() {
21192146
unencryptedSuffix = sops.DefaultUnencryptedSuffix
21202147
}
21212148

sops.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,12 @@ type CheckEncrypted interface {
726726
HasSopsTopLevelKey(TreeBranch) bool
727727
}
728728

729+
// SingleValueStore is the interface for determining whether a store uses only
730+
// one single key and no comments. This is basically identifying the binary store.
731+
type SingleValueStore interface {
732+
IsSingleValueStore() bool
733+
}
734+
729735
// Store is used to interact with files, both encrypted and unencrypted.
730736
type Store interface {
731737
EncryptedFileLoader
@@ -734,6 +740,8 @@ type Store interface {
734740
PlainFileEmitter
735741
ValueEmitter
736742
CheckEncrypted
743+
SingleValueStore
744+
Name() string
737745
}
738746

739747
// MasterKeyCount returns the number of master keys available

stores/dotenv/store.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ func NewStore(c *config.DotenvStoreConfig) *Store {
2323
return &Store{config: *c}
2424
}
2525

26+
func (store *Store) IsSingleValueStore() bool {
27+
return false
28+
}
29+
30+
func (store *Store) Name() string {
31+
return "dotenv"
32+
}
33+
2634
// LoadEncryptedFile loads an encrypted file's bytes onto a sops.Tree runtime object
2735
func (store *Store) LoadEncryptedFile(in []byte) (sops.Tree, error) {
2836
branches, err := store.LoadPlainFile(in)

stores/ini/store.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ func NewStore(c *config.INIStoreConfig) *Store {
2121
return &Store{config: c}
2222
}
2323

24+
func (store *Store) IsSingleValueStore() bool {
25+
return false
26+
}
27+
28+
func (store *Store) Name() string {
29+
return "ini"
30+
}
31+
2432
func (store Store) encodeTree(branches sops.TreeBranches) ([]byte, error) {
2533
iniFile := ini.Empty(ini.LoadOptions{AllowNonUniqueSections: true})
2634
iniFile.DeleteSection(ini.DefaultSection)

stores/json/store.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,29 @@ func NewStore(c *config.JSONStoreConfig) *Store {
2222
return &Store{config: *c}
2323
}
2424

25+
func (store *Store) IsSingleValueStore() bool {
26+
return false
27+
}
28+
29+
func (store *Store) Name() string {
30+
return "json"
31+
}
32+
2533
// BinaryStore handles storage of binary data in a JSON envelope.
2634
type BinaryStore struct {
2735
store Store
2836
config config.JSONBinaryStoreConfig
2937
}
3038

39+
// The binary store uses a single key ("data") to store everything.
40+
func (store *BinaryStore) IsSingleValueStore() bool {
41+
return true
42+
}
43+
44+
func (store *BinaryStore) Name() string {
45+
return "binary"
46+
}
47+
3148
func NewBinaryStore(c *config.JSONBinaryStoreConfig) *BinaryStore {
3249
return &BinaryStore{config: *c, store: *NewStore(&config.JSONStoreConfig{
3350
Indent: c.Indent,

stores/yaml/store.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@ func NewStore(c *config.YAMLStoreConfig) *Store {
2424
return &Store{config: *c}
2525
}
2626

27+
func (store *Store) IsSingleValueStore() bool {
28+
return false
29+
}
30+
31+
func (store *Store) Name() string {
32+
return "yaml"
33+
}
34+
2735
func (store Store) appendCommentToList(comment string, list []interface{}) []interface{} {
2836
if comment != "" {
2937
for _, commentLine := range strings.Split(comment, "\n") {

0 commit comments

Comments
 (0)