From e23b3a350e724674350a600dcbc63d6b854c29f0 Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Tue, 3 Jan 2023 16:28:38 -0500 Subject: [PATCH] csi: Fix parsing of '=' in secrets at command line and HTTP (#15670) The command line flag parsing and the HTTP header parsing for CSI secrets incorrectly split at more than one '=' rune, making it impossible to use secrets that included that rune. --- .changelog/15670.txt | 3 +++ command/agent/csi_endpoint.go | 5 ++--- command/agent/csi_endpoint_test.go | 2 ++ command/volume_delete.go | 5 ++--- command/volume_snapshot_create.go | 10 ++++------ command/volume_snapshot_delete.go | 5 ++--- command/volume_snapshot_list.go | 5 ++--- 7 files changed, 17 insertions(+), 18 deletions(-) create mode 100644 .changelog/15670.txt diff --git a/.changelog/15670.txt b/.changelog/15670.txt new file mode 100644 index 000000000..3d227f937 --- /dev/null +++ b/.changelog/15670.txt @@ -0,0 +1,3 @@ +```release-note:bug +csi: Fixed a bug where secrets that include '=' were incorrectly rejected +``` diff --git a/command/agent/csi_endpoint.go b/command/agent/csi_endpoint.go index fd0f69266..fb71bfd95 100644 --- a/command/agent/csi_endpoint.go +++ b/command/agent/csi_endpoint.go @@ -409,9 +409,8 @@ func parseCSISecrets(req *http.Request) structs.CSISecrets { secrets := map[string]string{} secretkvs := strings.Split(secretsHeader, ",") for _, secretkv := range secretkvs { - kv := strings.Split(secretkv, "=") - if len(kv) == 2 { - secrets[kv[0]] = kv[1] + if key, value, found := strings.Cut(secretkv, "="); found { + secrets[key] = value } } if len(secrets) == 0 { diff --git a/command/agent/csi_endpoint_test.go b/command/agent/csi_endpoint_test.go index 9805a8228..f8187fa9a 100644 --- a/command/agent/csi_endpoint_test.go +++ b/command/agent/csi_endpoint_test.go @@ -59,6 +59,8 @@ func TestHTTP_CSIParseSecrets(t *testing.T) { structs.CSISecrets(map[string]string{"one": "overwrite"})}, {"one=value_one,two=value_two", structs.CSISecrets(map[string]string{"one": "value_one", "two": "value_two"})}, + {"one=value_one=two,two=value_two", + structs.CSISecrets(map[string]string{"one": "value_one=two", "two": "value_two"})}, } for _, tc := range testCases { req, _ := http.NewRequest("GET", "/v1/plugin/csi/foo", nil) diff --git a/command/volume_delete.go b/command/volume_delete.go index 6b37d419b..12e8c832a 100644 --- a/command/volume_delete.go +++ b/command/volume_delete.go @@ -104,9 +104,8 @@ func (c *VolumeDeleteCommand) Run(args []string) int { secrets := api.CSISecrets{} for _, kv := range secretsArgs { - s := strings.Split(kv, "=") - if len(s) == 2 { - secrets[s[0]] = s[1] + if key, value, found := strings.Cut(kv, "="); found { + secrets[key] = value } else { c.Ui.Error("Secret must be in the format: -secret key=value") return 1 diff --git a/command/volume_snapshot_create.go b/command/volume_snapshot_create.go index 013b285c0..c145bb85b 100644 --- a/command/volume_snapshot_create.go +++ b/command/volume_snapshot_create.go @@ -117,9 +117,8 @@ func (c *VolumeSnapshotCreateCommand) Run(args []string) int { secrets := api.CSISecrets{} for _, kv := range secretsArgs { - s := strings.Split(kv, "=") - if len(s) == 2 { - secrets[s[0]] = s[1] + if key, value, found := strings.Cut(kv, "="); found { + secrets[key] = value } else { c.Ui.Error("Secret must be in the format: -secret key=value") return 1 @@ -128,9 +127,8 @@ func (c *VolumeSnapshotCreateCommand) Run(args []string) int { params := map[string]string{} for _, kv := range parametersArgs { - p := strings.Split(kv, "=") - if len(p) == 2 { - params[p[0]] = p[1] + if key, value, found := strings.Cut(kv, "="); found { + params[key] = value } } diff --git a/command/volume_snapshot_delete.go b/command/volume_snapshot_delete.go index d6eaccc1c..63cad502f 100644 --- a/command/volume_snapshot_delete.go +++ b/command/volume_snapshot_delete.go @@ -94,9 +94,8 @@ func (c *VolumeSnapshotDeleteCommand) Run(args []string) int { secrets := api.CSISecrets{} for _, kv := range secretsArgs { - s := strings.Split(kv, "=") - if len(s) == 2 { - secrets[s[0]] = s[1] + if key, value, found := strings.Cut(kv, "="); found { + secrets[key] = value } else { c.Ui.Error("Secret must be in the format: -secret key=value") return 1 diff --git a/command/volume_snapshot_list.go b/command/volume_snapshot_list.go index 9d42968bf..bef018b1d 100644 --- a/command/volume_snapshot_list.go +++ b/command/volume_snapshot_list.go @@ -140,9 +140,8 @@ func (c *VolumeSnapshotListCommand) Run(args []string) int { secrets := api.CSISecrets{} for _, kv := range secretsArgs { - s := strings.Split(kv, "=") - if len(s) == 2 { - secrets[s[0]] = s[1] + if key, value, found := strings.Cut(kv, "="); found { + secrets[key] = value } else { c.Ui.Error("Secret must be in the format: -secret key=value") return 1