Skip to content

Commit 75487cd

Browse files
committed
Uniformly check file before encrypting.
Signed-off-by: Felix Fontein <felix@fontein.de>
1 parent ecb67d2 commit 75487cd

3 files changed

Lines changed: 40 additions & 12 deletions

File tree

cmd/sops/edit.go

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type runEditorUntilOkOpts struct {
3939
TmpFileName string
4040
OriginalHash []byte
4141
InputStore sops.Store
42+
OutputStore common.Store
4243
ShowMasterKeys bool
4344
Tree *sops.Tree
4445
}
@@ -147,8 +148,12 @@ func editTree(opts editOpts, tree *sops.Tree, dataKey []byte) ([]byte, error) {
147148

148149
// Let the user edit the file
149150
err = runEditorUntilOk(runEditorUntilOkOpts{
150-
InputStore: opts.InputStore, OriginalHash: origHash, TmpFileName: tmpfileName,
151-
ShowMasterKeys: opts.ShowMasterKeys, Tree: tree})
151+
InputStore: opts.InputStore,
152+
OutputStore: opts.OutputStore,
153+
OriginalHash: origHash,
154+
TmpFileName: tmpfileName,
155+
ShowMasterKeys: opts.ShowMasterKeys,
156+
Tree: tree})
152157
if err != nil {
153158
return nil, err
154159
}
@@ -213,6 +218,15 @@ func runEditorUntilOk(opts runEditorUntilOkOpts) error {
213218
// Replace the whole tree, because otherwise newBranches would
214219
// contain the SOPS metadata
215220
opts.Tree = &t
221+
} else {
222+
if userErr, _ := validateFileForEncryption(opts.OutputStore, newBranches); userErr != nil {
223+
log.WithField(
224+
"error",
225+
userErr.UserError(),
226+
).Errorf("Tree not valid for encryption. Press a key to return to the editor, or Ctrl+C to exit.")
227+
bufio.NewReader(os.Stdin).ReadByte()
228+
continue
229+
}
216230
}
217231
opts.Tree.Branches = newBranches
218232
needVersionUpdated, err := version.AIsNewerThanB(version.Version, opts.Tree.Metadata.Version)

cmd/sops/encrypt.go

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,28 @@ func (err *fileAlreadyEncryptedError) UserError() string {
5252
"encrypt files that already contain such an entry.\n\n" +
5353
"If this is an unencrypted file, rename the '" + stores.SopsMetadataKey + "' entry.\n\n" +
5454
"If this is an encrypted file and you want to edit it, use the " +
55-
"editor mode, for example: `sops my_file.yaml`"
55+
"editor mode, for example: `sops edit my_file.yaml`"
5656
return wordwrap.WrapString(message, 75)
5757
}
5858

59-
func ensureNoMetadata(opts encryptOpts, branch sops.TreeBranch) error {
60-
if opts.OutputStore.HasSopsTopLevelKey(branch) {
61-
return &fileAlreadyEncryptedError{}
59+
type needAtLeastOneDocument struct{}
60+
61+
func (err *needAtLeastOneDocument) Error() string {
62+
return "Empty file"
63+
}
64+
65+
func (err *needAtLeastOneDocument) UserError() string {
66+
return "File cannot be completely empty, it must contain at least one document"
67+
}
68+
69+
func validateFileForEncryption(outputStore sops.Store, branches []sops.TreeBranch) (sops.UserError, int) {
70+
if len(branches) < 1 {
71+
return &needAtLeastOneDocument{}, codes.NeedAtLeastOneDocument
72+
}
73+
if outputStore.HasSopsTopLevelKey(branches[0]) {
74+
return &fileAlreadyEncryptedError{}, codes.FileAlreadyEncrypted
6275
}
63-
return nil
76+
return nil, 0
6477
}
6578

6679
func metadataFromEncryptionConfig(config encryptConfig) sops.Metadata {
@@ -96,11 +109,8 @@ func encrypt(opts encryptOpts) (encryptedFile []byte, err error) {
96109
if err != nil {
97110
return nil, common.NewExitError(fmt.Sprintf("Error unmarshalling file: %s", err), codes.CouldNotReadInputFile)
98111
}
99-
if len(branches) < 1 {
100-
return nil, common.NewExitError("File cannot be completely empty, it must contain at least one document", codes.NeedAtLeastOneDocument)
101-
}
102-
if err := ensureNoMetadata(opts, branches[0]); err != nil {
103-
return nil, common.NewExitError(err, codes.FileAlreadyEncrypted)
112+
if err, code := validateFileForEncryption(opts.OutputStore, branches); err != nil {
113+
return nil, common.NewExitError(err, code)
104114
}
105115
path, err := filepath.Abs(opts.InputPath)
106116
if err != nil {

cmd/sops/set.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ func set(opts setOpts) ([]byte, bool, error) {
5151
var changed bool
5252
tree.Branches[0], changed = tree.Branches[0].Set(opts.TreePath, opts.Value)
5353

54+
if err, code := validateFileForEncryption(opts.OutputStore, tree.Branches); err != nil {
55+
return nil, false, common.NewExitError(err, code)
56+
}
57+
5458
err = common.EncryptTree(common.EncryptTreeOpts{
5559
DataKey: dataKey, Tree: tree, Cipher: opts.Cipher,
5660
})

0 commit comments

Comments
 (0)