Skip to content

Commit 38b25bd

Browse files
authored
Merge pull request #737 from mozilla/develop
v3.6.1 - develop -> master
2 parents 5f7d324 + 334be56 commit 38b25bd

File tree

23 files changed

+665
-441
lines changed

23 files changed

+665
-441
lines changed

CHANGELOG.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
Changelog
22
=========
33

4+
3.6.1
5+
-----
6+
Features:
7+
8+
* Add support for --unencrypted-regex (#715)
9+
10+
Changes:
11+
12+
* Use keys.openpgp.org instead of gpg.mozilla.org (#732)
13+
* Upgrade AWS SDK version (#714)
14+
* Support --input-type for exec-file (#699)
15+
16+
Bug fixes:
17+
18+
* Fixes broken Vault tests (#731)
19+
* Revert "Add standard newline/quoting behavior to dotenv store" (#706)
20+
21+
422
3.6.0
523
-----
624
Features:

README.rst

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -673,10 +673,9 @@ Example: place the following in your ``~/.bashrc``
673673
Specify a different GPG key server
674674
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
675675
676-
By default, ``sops`` uses the key server ``gpg.mozilla.org`` to retrieve the GPG
676+
By default, ``sops`` uses the key server ``keys.openpgp.org`` to retrieve the GPG
677677
keys that are not present in the local keyring.
678-
To use a different GPG key server, set the ``SOPS_GPG_KEYSERVER`` environment
679-
variable.
678+
This is no longer configurable. You can learn more about why from this write-up: [SKS Keyserver Network Under Attack](https://gist.github.com/rjhansen/67ab921ffb4084c865b3618d6955275f).
680679
681680
Example: place the following in your ``~/.bashrc``
682681
@@ -1426,9 +1425,20 @@ will encrypt the values under the ``data`` and ``stringData`` keys in a YAML fil
14261425
containing kubernetes secrets. It will not encrypt other values that help you to
14271426
navigate the file, like ``metadata`` which contains the secrets' names.
14281427
1428+
Conversely, you can opt in to only left certain keys without encrypting by using the
1429+
``--unencrypted-regex`` option, which will leave the values unencrypted of those keys
1430+
that match the supplied regular expression. For example, this command:
1431+
1432+
.. code:: bash
1433+
1434+
$ sops --encrypt --unencrypted-regex '^(description|metadata)$' k8s-secrets.yaml
1435+
1436+
will not encrypt the values under the ``description`` and ``metadata`` keys in a YAML file
1437+
containing kubernetes secrets, while encrypting everything else.
1438+
14291439
You can also specify these options in the ``.sops.yaml`` config file.
14301440
1431-
Note: these three options ``--unencrypted-suffix``, ``--encrypted-suffix``, and ``--encrypted-regex`` are
1441+
Note: these four options ``--unencrypted-suffix``, ``--encrypted-suffix``, ``--encrypted-regex`` and ``--unencrypted-regex`` are
14321442
mutually exclusive and cannot all be used in the same file.
14331443
14341444
Encryption Protocol

cmd/sops/edit.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ type editExampleOpts struct {
3737
editOpts
3838
UnencryptedSuffix string
3939
EncryptedSuffix string
40+
UnencryptedRegex string
4041
EncryptedRegex string
4142
KeyGroups []sops.KeyGroup
4243
GroupThreshold int
@@ -66,6 +67,7 @@ func editExample(opts editExampleOpts) ([]byte, error) {
6667
KeyGroups: opts.KeyGroups,
6768
UnencryptedSuffix: opts.UnencryptedSuffix,
6869
EncryptedSuffix: opts.EncryptedSuffix,
70+
UnencryptedRegex: opts.UnencryptedRegex,
6971
EncryptedRegex: opts.EncryptedRegex,
7072
Version: version.Version,
7173
ShamirThreshold: opts.GroupThreshold,
@@ -132,7 +134,7 @@ func editTree(opts editOpts, tree *sops.Tree, dataKey []byte) ([]byte, error) {
132134
if err != nil {
133135
return nil, common.NewExitError(fmt.Sprintf("Could not write output file: %s", err), codes.CouldNotWriteOutputFile)
134136
}
135-
137+
136138
// Close temporary file, since Windows won't delete the file unless it's closed beforehand
137139
defer tmpfile.Close()
138140

cmd/sops/encrypt.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type encryptOpts struct {
2222
KeyServices []keyservice.KeyServiceClient
2323
UnencryptedSuffix string
2424
EncryptedSuffix string
25+
UnencryptedRegex string
2526
EncryptedRegex string
2627
KeyGroups []sops.KeyGroup
2728
GroupThreshold int
@@ -77,6 +78,7 @@ func encrypt(opts encryptOpts) (encryptedFile []byte, err error) {
7778
KeyGroups: opts.KeyGroups,
7879
UnencryptedSuffix: opts.UnencryptedSuffix,
7980
EncryptedSuffix: opts.EncryptedSuffix,
81+
UnencryptedRegex: opts.UnencryptedRegex,
8082
EncryptedRegex: opts.EncryptedRegex,
8183
Version: version.Version,
8284
ShamirThreshold: opts.GroupThreshold,

cmd/sops/main.go

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ func main() {
109109
the "add-{kms,pgp,gcp-kms,azure-kv,hc-vault-transit}" and "rm-{kms,pgp,gcp-kms,azure-kv,hc-vault-transit}" flags.
110110
111111
To use a different GPG binary than the one in your PATH, set SOPS_GPG_EXEC.
112-
To use a GPG key server other than gpg.mozilla.org, set SOPS_GPG_KEYSERVER.
113112
114113
To select a different editor than the default (vim), set EDITOR.
115114
@@ -184,6 +183,14 @@ func main() {
184183
Name: "user",
185184
Usage: "the user to run the command as",
186185
},
186+
cli.StringFlag{
187+
Name: "input-type",
188+
Usage: "currently json, yaml, dotenv and binary are supported. If not set, sops will use the file's extension to determine the type",
189+
},
190+
cli.StringFlag{
191+
Name: "output-type",
192+
Usage: "currently json, yaml, dotenv and binary are supported. If not set, sops will use the input file's extension to determine the output format",
193+
},
187194
}, keyserviceFlags...),
188195
Action: func(c *cli.Context) error {
189196
if len(c.Args()) != 2 {
@@ -617,6 +624,10 @@ func main() {
617624
Name: "encrypted-suffix",
618625
Usage: "override the encrypted key suffix. When empty, all keys will be encrypted, unless otherwise marked with unencrypted-suffix.",
619626
},
627+
cli.StringFlag{
628+
Name: "unencrypted-regex",
629+
Usage: "set the unencrypted key suffix. When specified, only keys matching the regex will be left unencrypted.",
630+
},
620631
cli.StringFlag{
621632
Name: "encrypted-regex",
622633
Usage: "set the encrypted key suffix. When specified, only keys matching the regex will be encrypted.",
@@ -674,6 +685,7 @@ func main() {
674685
unencryptedSuffix := c.String("unencrypted-suffix")
675686
encryptedSuffix := c.String("encrypted-suffix")
676687
encryptedRegex := c.String("encrypted-regex")
688+
unencryptedRegex := c.String("unencrypted-regex")
677689
conf, err := loadConfig(c, fileName, nil)
678690
if err != nil {
679691
return toExitError(err)
@@ -689,6 +701,9 @@ func main() {
689701
if encryptedRegex == "" {
690702
encryptedRegex = conf.EncryptedRegex
691703
}
704+
if unencryptedRegex == "" {
705+
unencryptedRegex = conf.UnencryptedRegex
706+
}
692707
}
693708

694709
cryptRuleCount := 0
@@ -701,9 +716,12 @@ func main() {
701716
if encryptedRegex != "" {
702717
cryptRuleCount++
703718
}
719+
if unencryptedRegex != "" {
720+
cryptRuleCount++
721+
}
704722

705723
if cryptRuleCount > 1 {
706-
return common.NewExitError("Error: cannot use more than one of encrypted_suffix, unencrypted_suffix, or encrypted_regex in the same file", codes.ErrorConflictingParameters)
724+
return common.NewExitError("Error: cannot use more than one of encrypted_suffix, unencrypted_suffix, encrypted_regex or unencrypted_regex in the same file", codes.ErrorConflictingParameters)
707725
}
708726

709727
// only supply the default UnencryptedSuffix when EncryptedSuffix and EncryptedRegex are not provided
@@ -734,6 +752,7 @@ func main() {
734752
Cipher: aes.NewCipher(),
735753
UnencryptedSuffix: unencryptedSuffix,
736754
EncryptedSuffix: encryptedSuffix,
755+
UnencryptedRegex: unencryptedRegex,
737756
EncryptedRegex: encryptedRegex,
738757
KeyServices: svcs,
739758
KeyGroups: groups,
@@ -871,6 +890,7 @@ func main() {
871890
editOpts: opts,
872891
UnencryptedSuffix: unencryptedSuffix,
873892
EncryptedSuffix: encryptedSuffix,
893+
UnencryptedRegex: unencryptedRegex,
874894
EncryptedRegex: encryptedRegex,
875895
KeyGroups: groups,
876896
GroupThreshold: threshold,

cmd/sops/subcommand/exec/exec.go

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package exec
22

33
import (
4-
"fmt"
4+
"bytes"
55
"io/ioutil"
66
"os"
77
"runtime"
88
"strings"
99

1010
"go.mozilla.org/sops/v3/logging"
11-
"go.mozilla.org/sops/v3/stores/dotenv"
1211

1312
"github.com/sirupsen/logrus"
1413
)
@@ -85,18 +84,15 @@ func ExecWithEnv(opts ExecOpts) error {
8584
}
8685

8786
env := os.Environ()
88-
store := dotenv.Store{}
89-
90-
branches, err := store.LoadPlainFile(opts.Plaintext)
91-
if err != nil {
92-
log.Fatal(err)
93-
}
94-
95-
for _, item := range branches[0] {
96-
if item.Value == nil {
87+
lines := bytes.Split(opts.Plaintext, []byte("\n"))
88+
for _, line := range lines {
89+
if len(line) == 0 {
90+
continue
91+
}
92+
if line[0] == '#' {
9793
continue
9894
}
99-
env = append(env, fmt.Sprintf("%s=%s", item.Key, item.Value))
95+
env = append(env, string(line))
10096
}
10197

10298
cmd := BuildCommand(opts.Command)

config/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ type creationRule struct {
117117
ShamirThreshold int `yaml:"shamir_threshold"`
118118
UnencryptedSuffix string `yaml:"unencrypted_suffix"`
119119
EncryptedSuffix string `yaml:"encrypted_suffix"`
120+
UnencryptedRegex string `yaml:"unencrypted_regex"`
120121
EncryptedRegex string `yaml:"encrypted_regex"`
121122
}
122123

@@ -135,6 +136,7 @@ type Config struct {
135136
ShamirThreshold int
136137
UnencryptedSuffix string
137138
EncryptedSuffix string
139+
UnencryptedRegex string
138140
EncryptedRegex string
139141
Destination publish.Destination
140142
OmitExtensions bool
@@ -235,6 +237,7 @@ func configFromRule(rule *creationRule, kmsEncryptionContext map[string]*string)
235237
ShamirThreshold: rule.ShamirThreshold,
236238
UnencryptedSuffix: rule.UnencryptedSuffix,
237239
EncryptedSuffix: rule.EncryptedSuffix,
240+
UnencryptedRegex: rule.UnencryptedRegex,
238241
EncryptedRegex: rule.EncryptedRegex,
239242
}, nil
240243
}

config/config_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ creation_rules:
137137
kms: "1"
138138
pgp: "2"
139139
encrypted_regex: "^enc:"
140+
unencrypted_regex: "^dec:"
140141
`)
141142

142143
var sampleConfigWithInvalidParameters = []byte(`
@@ -349,6 +350,12 @@ func TestLoadConfigFileWithEncryptedSuffix(t *testing.T) {
349350
assert.Equal(t, "_enc", conf.EncryptedSuffix)
350351
}
351352

353+
func TestLoadConfigFileWithUnencryptedRegex(t *testing.T) {
354+
conf, err := parseCreationRuleForFile(parseConfigFile(sampleConfigWithRegexParameters, t), "barbar", nil)
355+
assert.Equal(t, nil, err)
356+
assert.Equal(t, "^dec:", conf.UnencryptedRegex)
357+
}
358+
352359
func TestLoadConfigFileWithEncryptedRegex(t *testing.T) {
353360
conf, err := parseCreationRuleForFile(parseConfigFile(sampleConfigWithRegexParameters, t), "barbar", nil)
354361
assert.Equal(t, nil, err)
@@ -372,9 +379,9 @@ func TestLoadConfigFileWithVaultDestinationRules(t *testing.T) {
372379
conf, err := parseDestinationRuleForFile(parseConfigFile(sampleConfigWithVaultDestinationRules, t), "vault-v2/barfoo", nil)
373380
assert.Nil(t, err)
374381
assert.NotNil(t, conf.Destination)
375-
assert.Equal(t, "http://127.0.0.1:8200/v1/secret/data/foobar/barfoo", conf.Destination.Path("barfoo"))
382+
assert.Contains(t, conf.Destination.Path("barfoo"), "/v1/secret/data/foobar/barfoo")
376383
conf, err = parseDestinationRuleForFile(parseConfigFile(sampleConfigWithVaultDestinationRules, t), "vault-v1/barfoo", nil)
377384
assert.Nil(t, err)
378385
assert.NotNil(t, conf.Destination)
379-
assert.Equal(t, "http://127.0.0.1:8200/v1/kv/barfoo/barfoo", conf.Destination.Path("barfoo"))
386+
assert.Contains(t, conf.Destination.Path("barfoo"), "/v1/kv/barfoo/barfoo")
380387
}

go.mod

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ require (
1212
github.com/Azure/go-autorest/autorest/validation v0.2.0 // indirect
1313
github.com/Microsoft/go-winio v0.4.14 // indirect
1414
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
15-
github.com/aws/aws-sdk-go v1.23.13
15+
github.com/aws/aws-sdk-go v1.33.18
1616
github.com/blang/semver v3.5.1+incompatible
1717
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
1818
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc // indirect
@@ -34,13 +34,14 @@ require (
3434
github.com/opencontainers/image-spec v1.0.1 // indirect
3535
github.com/opencontainers/runc v0.1.1 // indirect
3636
github.com/ory/dockertest v3.3.4+incompatible
37-
github.com/pkg/errors v0.8.1
37+
github.com/pkg/errors v0.9.1
3838
github.com/sirupsen/logrus v1.4.2
3939
github.com/smartystreets/goconvey v0.0.0-20190710185942-9d28bd7c0945 // indirect
40-
github.com/stretchr/testify v1.3.0
40+
github.com/stretchr/testify v1.5.1
41+
github.com/vektra/mockery v1.1.2 // indirect
4142
go.mozilla.org/gopgagent v0.0.0-20170926210634-4d7ea76ff71a
42-
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4
43-
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80
43+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550
44+
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
4445
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
4546
google.golang.org/api v0.7.0
4647
google.golang.org/grpc v1.22.1

0 commit comments

Comments
 (0)