From a3e434cee404aa8c52b3c64dc844d98aaa2863a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benoi=CC=82t=20Bourbie=CC=81?= Date: Thu, 29 Aug 2019 13:39:58 -0700 Subject: [PATCH] fix: handling unpadded base64 encoded docker auth field docker-credential-desk does not pad anymore the auth field. it is then possible to have unpadded auth field. field might be encoded either with RawStdEncoding or StdEncoding we now determine if it is correctly padded in order to handle both cases. --- pkg/credentialprovider/config.go | 15 +++++++++++++- pkg/credentialprovider/config_test.go | 29 +++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/pkg/credentialprovider/config.go b/pkg/credentialprovider/config.go index 729483a2918..8816f833e55 100644 --- a/pkg/credentialprovider/config.go +++ b/pkg/credentialprovider/config.go @@ -282,7 +282,20 @@ func (ident DockerConfigEntry) MarshalJSON() ([]byte, error) { // decodeDockerConfigFieldAuth deserializes the "auth" field from dockercfg into a // username and a password. The format of the auth field is base64(:). func decodeDockerConfigFieldAuth(field string) (username, password string, err error) { - decoded, err := base64.StdEncoding.DecodeString(field) + + var decoded []byte + + // StdEncoding can only decode padded string + // RawStdEncoding can only decode unpadded string + // a string is correctly padded if and only if its length is a multiple of 4 + if (len(field) % 4) == 0 { + // decode padded data + decoded, err = base64.StdEncoding.DecodeString(field) + } else { + // decode unpadded data + decoded, err = base64.RawStdEncoding.DecodeString(field) + } + if err != nil { return } diff --git a/pkg/credentialprovider/config_test.go b/pkg/credentialprovider/config_test.go index c5f73cafdb6..a0723d9f1e8 100644 --- a/pkg/credentialprovider/config_test.go +++ b/pkg/credentialprovider/config_test.go @@ -17,6 +17,7 @@ limitations under the License. package credentialprovider import ( + "encoding/base64" "encoding/json" "io/ioutil" "os" @@ -208,6 +209,34 @@ func TestDecodeDockerConfigFieldAuth(t *testing.T) { password: "bar", }, + // some test as before but with field not well padded + { + input: "Zm9vOmJhcg", + username: "foo", + password: "bar", + }, + + // standard encoding (with padding) + { + input: base64.StdEncoding.EncodeToString([]byte("foo:bar")), + username: "foo", + password: "bar", + }, + + // raw encoding (without padding) + { + input: base64.RawStdEncoding.EncodeToString([]byte("foo:bar")), + username: "foo", + password: "bar", + }, + + // the input is encoded with encodeDockerConfigFieldAuth (standard encoding) + { + input: encodeDockerConfigFieldAuth("foo", "bar"), + username: "foo", + password: "bar", + }, + // good base64 data, but no colon separating username & password { input: "cGFudHM=",