decryptor: detect format of Secret data field
This checks the base64 decoded bytes from a Secret field for any of the marker bytes, thereby allowing data to be encrypted into any format. Instead of the previous behavior which assumed it to either be YAML or JSON. Signed-off-by: Hidde Beydals <hello@hidde.co>
This commit is contained in:
parent
a7639c68d3
commit
36df540a5d
|
|
@ -67,12 +67,16 @@ const (
|
||||||
// DecryptionAzureAuthFile is the name of the file containing the Azure
|
// DecryptionAzureAuthFile is the name of the file containing the Azure
|
||||||
// credentials.
|
// credentials.
|
||||||
DecryptionAzureAuthFile = "sops.azure-kv"
|
DecryptionAzureAuthFile = "sops.azure-kv"
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// maxEncryptedFileSize is the max allowed file size in bytes of an encrypted
|
// maxEncryptedFileSize is the max allowed file size in bytes of an encrypted
|
||||||
// file.
|
// file.
|
||||||
maxEncryptedFileSize int64 = 5 << 20
|
maxEncryptedFileSize int64 = 5 << 20
|
||||||
|
// unsupportedFormat is used to signal no sopsFormatToMarkerBytes format was
|
||||||
|
// detected by detectFormatFromMarkerBytes.
|
||||||
|
unsupportedFormat = formats.Format(-1)
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
// sopsFormatToString is the counterpart to
|
// sopsFormatToString is the counterpart to
|
||||||
// https://github.com/mozilla/sops/blob/v3.7.2/cmd/sops/formats/formats.go#L16
|
// https://github.com/mozilla/sops/blob/v3.7.2/cmd/sops/formats/formats.go#L16
|
||||||
sopsFormatToString = map[formats.Format]string{
|
sopsFormatToString = map[formats.Format]string{
|
||||||
|
|
@ -334,9 +338,9 @@ func (d *KustomizeDecryptor) DecryptResource(res *resource.Resource) (*resource.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if bytes.Contains(data, sopsFormatToMarkerBytes[formats.Yaml]) || bytes.Contains(data, sopsFormatToMarkerBytes[formats.Json]) {
|
if inF := detectFormatFromMarkerBytes(data); inF != unsupportedFormat {
|
||||||
outF := formatForPath(key)
|
outF := formatForPath(key)
|
||||||
out, err := d.SopsDecryptWithFormat(data, formats.Yaml, outF)
|
out, err := d.SopsDecryptWithFormat(data, inF, outF)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to decrypt and format '%s/%s' Secret field '%s': %w",
|
return nil, fmt.Errorf("failed to decrypt and format '%s/%s' Secret field '%s': %w",
|
||||||
res.GetNamespace(), res.GetName(), key, err)
|
res.GetNamespace(), res.GetName(), key, err)
|
||||||
|
|
@ -412,7 +416,7 @@ func (d *KustomizeDecryptor) decryptKustomizationEnvSources(visited map[string]s
|
||||||
}
|
}
|
||||||
for _, envFile := range gen.EnvSources {
|
for _, envFile := range gen.EnvSources {
|
||||||
format := formatForPath(envFile)
|
format := formatForPath(envFile)
|
||||||
if formatForPath(envFile) == formats.Binary {
|
if format == formats.Binary {
|
||||||
// Default to dotenv
|
// Default to dotenv
|
||||||
format = formats.Dotenv
|
format = formats.Dotenv
|
||||||
}
|
}
|
||||||
|
|
@ -740,3 +744,12 @@ func formatForPath(path string) formats.Format {
|
||||||
return formats.FormatForPath(path)
|
return formats.FormatForPath(path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func detectFormatFromMarkerBytes(b []byte) formats.Format {
|
||||||
|
for k, v := range sopsFormatToMarkerBytes {
|
||||||
|
if bytes.Contains(b, v) {
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return unsupportedFormat
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -846,7 +846,7 @@ func TestKustomizeDecryptor_DecryptResource(t *testing.T) {
|
||||||
"name": "secret",
|
"name": "secret",
|
||||||
"namespace": "test",
|
"namespace": "test",
|
||||||
},
|
},
|
||||||
"type": corev1.SecretTypeDockercfg,
|
"type": corev1.SecretTypeDockerConfigJson,
|
||||||
"data": map[string]interface{}{
|
"data": map[string]interface{}{
|
||||||
corev1.DockerConfigJsonKey: base64.StdEncoding.EncodeToString(encData),
|
corev1.DockerConfigJsonKey: base64.StdEncoding.EncodeToString(encData),
|
||||||
},
|
},
|
||||||
|
|
@ -1725,3 +1725,29 @@ func Test_formatForPath(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_detectFormatFromMarkerBytes(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
b []byte
|
||||||
|
want formats.Format
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "detects format",
|
||||||
|
b: bytes.Join([][]byte{[]byte("random other bytes"), sopsFormatToMarkerBytes[formats.Yaml], []byte("more random bytes")}, []byte(" ")),
|
||||||
|
want: formats.Yaml,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "returns unsupported format",
|
||||||
|
b: []byte("no marker bytes present"),
|
||||||
|
want: unsupportedFormat,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := detectFormatFromMarkerBytes(tt.b); got != tt.want {
|
||||||
|
t.Errorf("detectFormatFromMarkerBytes() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue