From cf9ebb3259b7c2c5264340d46c76f2ad2b0f8a39 Mon Sep 17 00:00:00 2001 From: Brad Davidson Date: Mon, 1 May 2023 21:17:30 +0000 Subject: [PATCH] Fail to validate server tokens that use bootstrap id/secret format Signed-off-by: Brad Davidson --- pkg/clientaccess/token.go | 4 ++++ pkg/clientaccess/token_test.go | 1 + pkg/cluster/storage.go | 4 ++-- tests/e2e/startup/startup_test.go | 12 ++++++++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/pkg/clientaccess/token.go b/pkg/clientaccess/token.go index d9ab822b9c..8538c8e476 100644 --- a/pkg/clientaccess/token.go +++ b/pkg/clientaccess/token.go @@ -165,11 +165,15 @@ func hashCA(b []byte) (string, error) { // ParseUsernamePassword returns the username and password portion of a token string, // along with a bool indicating if the token was successfully parsed. +// Kubeadm-style tokens have ID/Secret not Username/Password and therefore will return false (invalid). func ParseUsernamePassword(token string) (string, string, bool) { info, err := parseToken(token) if err != nil { return "", "", false } + if info.BootstrapTokenString != nil { + return "", "", false + } return info.Username, info.Password, true } diff --git a/pkg/clientaccess/token_test.go b/pkg/clientaccess/token_test.go index c538de164c..f004f1bc2a 100644 --- a/pkg/clientaccess/token_test.go +++ b/pkg/clientaccess/token_test.go @@ -294,6 +294,7 @@ func Test_UnitUserPass(t *testing.T) { {"K10XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX::username:password", "username", "password", true}, {"password", "", "password", true}, {"K10X::x", "", "", false}, + {"aaaaaa.bbbbbbbbbbbbbbbb", "", "", false}, } for _, testCase := range testCases { diff --git a/pkg/cluster/storage.go b/pkg/cluster/storage.go index 56c7a999a5..b10fe4fc75 100644 --- a/pkg/cluster/storage.go +++ b/pkg/cluster/storage.go @@ -271,7 +271,7 @@ func readTokenFromFile(serverToken, certs, dataDir string) (string, error) { func normalizeToken(token string) (string, error) { _, password, ok := clientaccess.ParseUsernamePassword(token) if !ok { - return password, errors.New("failed to normalize token; must be in format K10::: or ") + return password, errors.New("failed to normalize server token; must be in format K10::: or ") } return password, nil @@ -286,7 +286,7 @@ func migrateOldTokens(ctx context.Context, bootstrapList []client.Value, storage for _, bootstrapKV := range bootstrapList { // checking for empty string bootstrap key if string(bootstrapKV.Key) == emptyStringKey { - logrus.Warn("bootstrap data encrypted with empty string, deleting and resaving with token") + logrus.Warn("Bootstrap data encrypted with empty string, deleting and resaving with token") if err := doMigrateToken(ctx, storageClient, bootstrapKV, "", emptyStringKey, token, tokenKey); err != nil { return err } diff --git a/tests/e2e/startup/startup_test.go b/tests/e2e/startup/startup_test.go index 6c3858f195..64b35d3d75 100644 --- a/tests/e2e/startup/startup_test.go +++ b/tests/e2e/startup/startup_test.go @@ -252,6 +252,18 @@ var _ = Describe("Various Startup Configurations", Ordered, func() { Expect(err).NotTo(HaveOccurred()) }) }) + Context("Verify server fails to start with bootstrap token", func() { + It("Fails to start with a meaningful error", func() { + tokenYAML := "token: aaaaaa.bbbbbbbbbbbbbbbb" + err := StartK3sCluster(append(serverNodeNames, agentNodeNames...), tokenYAML, tokenYAML) + Expect(err).To(HaveOccurred()) + Expect(err).To(ContainSubstring("failed to normalize server token")) + }) + It("Kills the cluster", func() { + err := KillK3sCluster(append(serverNodeNames, agentNodeNames...)) + Expect(err).NotTo(HaveOccurred()) + }) + }) }) var failed bool