Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking β€œSign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[auto-bump] [no-release-notes] dependency by fulghum #2789

Merged
merged 5 commits into from
Dec 11, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Enabling support for the caching_sha2_password auth plugin
fulghum committed Dec 10, 2024
commit 9d7d61249806000b69f9ac93f1bdbad6bc461a02
64 changes: 43 additions & 21 deletions enginetest/enginetests.go
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ package enginetest

import (
"context"
"crypto/tls"
dsql "database/sql"
"fmt"
"io"
@@ -2010,11 +2011,19 @@ func TestUserAuthentication(t *testing.T, h Harness) {
User: "root",
Address: "localhost",
})

tlsCert, err := tls.LoadX509KeyPair("./testdata/selfsigned_cert.pem", "./testdata/selfsigned_key.pem")
require.NoError(t, err)
tlsConfig := tls.Config{
Certificates: []tls.Certificate{tlsCert},
}

serverConfig := server.Config{
Protocol: "tcp",
Address: fmt.Sprintf("localhost:%d", port),
MaxConnections: 1000,
AllowClearTextWithoutTLS: true,
Protocol: "tcp",
Address: fmt.Sprintf("localhost:%d", port),
MaxConnections: 1000,
TLSConfig: &tlsConfig,
RequireSecureTransport: true,
}

e := mustNewEngine(t, clientHarness)
@@ -2055,24 +2064,37 @@ func TestUserAuthentication(t *testing.T, h Harness) {
}()

for _, assertion := range script.Assertions {
conn, err := dbr.Open("mysql", fmt.Sprintf("%s:%s@tcp(localhost:%d)/?allowCleartextPasswords=true",
assertion.Username, assertion.Password, port), nil)
require.NoError(t, err)
r, err := conn.Query(assertion.Query)
if assertion.ExpectedErr || len(assertion.ExpectedErrStr) > 0 || assertion.ExpectedErrKind != nil {
if !assert.Error(t, err) {
require.NoError(t, r.Close())
} else if len(assertion.ExpectedErrStr) > 0 {
assert.Equal(t, assertion.ExpectedErrStr, err.Error())
} else if assertion.ExpectedErrKind != nil {
assert.True(t, assertion.ExpectedErrKind.Is(err))
}
} else {
if assert.NoError(t, err) {
require.NoError(t, r.Close())
t.Run(assertion.Query, func(t *testing.T) {
conn, err := dbr.Open("mysql", fmt.Sprintf("%s:%s@tcp(localhost:%d)/?allowCleartextPasswords=true&tls=skip-verify",
assertion.Username, assertion.Password, port), nil)
require.NoError(t, err)
r, err := conn.Query(assertion.Query)
if assertion.ExpectedErr || len(assertion.ExpectedErrStr) > 0 || assertion.ExpectedErrKind != nil {
if !assert.Error(t, err) {
require.NoError(t, r.Close())
} else if len(assertion.ExpectedErrStr) > 0 {
assert.Equal(t, assertion.ExpectedErrStr, err.Error())
} else if assertion.ExpectedErrKind != nil {
assert.True(t, assertion.ExpectedErrKind.Is(err))
}
} else {
if assert.NoError(t, err) {
require.NoError(t, r.Close())
}
if assertion.ExpectedAuthPlugin != "" {
// NOTE: This query works as long as there is only one account configured for the current user
r, err := conn.Query("SELECT plugin FROM mysql.user WHERE user=SUBSTRING_INDEX(USER(),'@',1);")
require.NoError(t, err)
require.True(t, r.Next())
var authPlugin string
err = r.Scan(&authPlugin)
require.False(t, r.Next())
require.NoError(t, err)
require.Equal(t, assertion.ExpectedAuthPlugin, authPlugin)
}
}
}
require.NoError(t, conn.Close())
require.NoError(t, conn.Close())
})
}
})
}
187 changes: 159 additions & 28 deletions enginetest/queries/priv_auth_queries.go
Original file line number Diff line number Diff line change
@@ -95,12 +95,13 @@ type ServerAuthenticationTest struct {

// ServerAuthenticationTestAssertion is within a ServerAuthenticationTest to assert functionality.
type ServerAuthenticationTestAssertion struct {
Username string
Password string
Query string
ExpectedErr bool
ExpectedErrKind *errors.Kind
ExpectedErrStr string
Username string
Password string
Query string
ExpectedErr bool
ExpectedErrKind *errors.Kind
ExpectedErrStr string
ExpectedAuthPlugin string
}

// UserPrivTests test the user and privilege systems. These tests always have the root account available, and the root
@@ -740,7 +741,37 @@ var UserPrivTests = []UserPrivilegeTest{
},
},
},

{
Name: "Migrate a user from mysql_native_password to caching_sha2_password",
SetUpScript: []string{
"CREATE USER testuser1@`127.0.0.1` identified with mysql_native_password by 'pass1';",
},
Assertions: []UserPrivilegeTestAssertion{
{
Query: "select user, host, plugin, authentication_string from mysql.user where user='testuser1';",
Expected: []sql.Row{{"testuser1", "127.0.0.1", "mysql_native_password", "*22A99BA288DB55E8E230679259740873101CD636"}},
},
{
Query: "ALTER USER testuser1@`127.0.0.1` IDENTIFIED WITH caching_sha2_password BY 'pass1';",
Expected: []sql.Row{{types.NewOkResult(0)}},
},
{
// caching_sha2_password auth uses a random salt to create the authentication
// string. Since it's not a consistent value during each test run, we just sanity
// check the first bytes of metadata (digest type, iterations) in the auth string.
Query: "select user, host, plugin, authentication_string like '$A$005$%' from mysql.user where user='testuser1';",
Expected: []sql.Row{{"testuser1", "127.0.0.1", "caching_sha2_password", true}},
},
{
Query: "ALTER USER testuser1@`127.0.0.1` IDENTIFIED WITH caching_sha2_password;",
Expected: []sql.Row{{types.NewOkResult(0)}},
},
{
Query: "select user, host, plugin, authentication_string from mysql.user where user='testuser1';",
Expected: []sql.Row{{"testuser1", "127.0.0.1", "caching_sha2_password", ""}},
},
},
},
{
Name: "Dynamic privilege support",
SetUpScript: []string{
@@ -2604,10 +2635,10 @@ var ServerAuthTests = []ServerAuthenticationTest{
},
Assertions: []ServerAuthenticationTestAssertion{
{
Username: "rand_user",
Password: "rand_pass",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: false,
Username: "rand_user",
Password: "rand_pass",
Query: "SELECT * FROM mysql.user;",
ExpectedAuthPlugin: "mysql_native_password",
},
{
Username: "rand_user",
@@ -2630,17 +2661,17 @@ var ServerAuthTests = []ServerAuthenticationTest{
},
},
{
Name: "Create User with plugin specification",
Name: "Create User explicitly with mysql_native_password plugin",
SetUpScript: []string{
"CREATE USER ranuse@localhost IDENTIFIED WITH mysql_native_password BY 'ranpas';",
"GRANT ALL ON *.* TO ranuse@localhost WITH GRANT OPTION;",
},
Assertions: []ServerAuthenticationTestAssertion{
{
Username: "ranuse",
Password: "ranpas",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: false,
Username: "ranuse",
Password: "ranpas",
Query: "SELECT * FROM mysql.user;",
ExpectedAuthPlugin: "mysql_native_password",
},
{
Username: "ranuse",
@@ -2656,6 +2687,103 @@ var ServerAuthTests = []ServerAuthenticationTest{
},
},
},
{
Name: "Create User explicitly with caching_sha2_password plugin",
SetUpScript: []string{
// testuser1 is created with a password
"CREATE USER testuser1@localhost IDENTIFIED WITH caching_sha2_password BY 'mypassword3';",
"GRANT ALL ON *.* TO testuser1@localhost WITH GRANT OPTION;",
// testuser2 is created without a password
"CREATE USER testuser2@localhost IDENTIFIED WITH caching_sha2_password;",
"GRANT ALL ON *.* TO testuser2@localhost WITH GRANT OPTION;",
},
Assertions: []ServerAuthenticationTestAssertion{
{
Username: "testuser1",
Password: "mypassword3",
Query: "SELECT * FROM mysql.user;",
ExpectedAuthPlugin: "caching_sha2_password",
},
{
Username: "testuser1",
Password: "what",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
ExpectedErrStr: "Error 1045 (28000): Access denied for user 'testuser1'",
},
{
Username: "testuser1",
Password: "",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
ExpectedErrStr: "Error 1045 (28000): Access denied for user 'testuser1'",
},
{
Username: "testuser2",
Password: "wrong",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
ExpectedErrStr: "Error 1045 (28000): Access denied for user 'testuser2'",
},
{
Username: "testuser2",
Password: "",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: false,
ExpectedAuthPlugin: "caching_sha2_password",
},
},
},
{
Name: "Migrate user from mysql_native_password to caching_sha2_password",
SetUpScript: []string{
// testuser1 is created with a password
"CREATE USER testuser1@localhost IDENTIFIED WITH mysql_native_password BY 'mypassword3';",
"GRANT ALL ON *.* TO testuser1@localhost WITH GRANT OPTION;",
},
Assertions: []ServerAuthenticationTestAssertion{
{
Username: "testuser1",
Password: "mypassword3",
Query: "SELECT * FROM mysql.user;",
ExpectedAuthPlugin: "mysql_native_password",
},
{
Username: "root",
Query: "ALTER USER testuser1@localhost IDENTIFIED WITH caching_sha2_password BY 'pass1';",
},
{
Username: "testuser1",
Password: "pass1",
Query: "SELECT * FROM mysql.user;",
ExpectedAuthPlugin: "caching_sha2_password",
},
{
Username: "testuser1",
Password: "wrong",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
ExpectedErrStr: "Error 1045 (28000): Access denied for user 'testuser1'",
},
{
Username: "root",
Query: "ALTER USER testuser1@localhost IDENTIFIED WITH caching_sha2_password;",
},
{
Username: "testuser1",
Password: "",
Query: "SELECT * FROM mysql.user;",
ExpectedAuthPlugin: "caching_sha2_password",
},
{
Username: "testuser1",
Password: "wrong",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
ExpectedErrStr: "Error 1045 (28000): Access denied for user 'testuser1'",
},
},
},
{
Name: "Create User with jwt plugin specification",
SetUpScript: []string{
@@ -2668,22 +2796,25 @@ var ServerAuthTests = []ServerAuthenticationTest{
},
Assertions: []ServerAuthenticationTestAssertion{
{
Username: "test-user",
Password: "what",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
Username: "test-user",
Password: "what",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
ExpectedErrStr: "Error 1045 (28000): Access denied for user 'test-user'",
},
{
Username: "test-user",
Password: "",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
Username: "test-user",
Password: "",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: true,
ExpectedErrStr: "Error 1045 (28000): Access denied for user 'test-user'",
},
{
Username: "test-user",
Password: "right-password",
Query: "SELECT * FROM mysql.user;",
ExpectedErr: false,

Username: "test-user",
Password: "right-password",
Query: "SELECT * FROM mysql.user;",
ExpectedAuthPlugin: "authentication_dolt_jwt",
},
},
},
27 changes: 27 additions & 0 deletions enginetest/testdata/selfsigned_cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN CERTIFICATE-----
MIIErDCCApQCCQCP9IKGyBYVUDANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQKDA1E
b2x0SHViLCBJbmMuMB4XDTIyMDcyMTE5NTUyN1oXDTI2MDcyMDE5NTUyN1owGDEW
MBQGA1UECgwNRG9sdEh1YiwgSW5jLjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
AgoCggIBAMRNMquL4n2bAMQmoedUFcT/zI42ThW5o9qxh9U8MhsDqKBet7JL7ruh
3FRj/yaU+3ax2lGgapcTnSJHWHPUX6MzUpqkwrLzKxqMrKQYnU2F96n3GOflllsB
8ISKBy0TIipLWKupndc893qk+j6HUQ9OrtFHwroZ6/Tg32h4LcJvhkwILb8EHZpI
fSSzi637msnXWqln1WYmX+v4ARUVVSwl5kkPGZ4PxMDQRX3ioqy2d27GbHYSo01K
tSScQvnFJeddu09l7hNTSFixRz+XU+F+jYna8xUtqHMawEpfGw8Gsu8sMV9PUfUx
6WrMb1tcyWEDvHwH6RUlhNa085eCRFznHLDZNxrgBwrslII9d9xW/JaRq43d4M0q
e7F+BazB3rImMo2QHFvtvq55N7mvp+LprMjoEneBboiz1I6M0rq7Sn58FxazgQvz
mCZmNYIrznx+S1mlJjxtC7xgDPZn5Z/68TsmT26j5UNLou7i/yb7XFdMVY6kAnoZ
BAf4+rAUEDV85OLz0kWZSJj+DdlPOl/gIhTgrgJev2Cc7THUTnuk+nGETG49DITS
ySWYLsMYFHweSTm3rG6sMyN7mdbRrUSM1bqbARm46mt89+0HGsFX1QLe3v4yda67
ic93J5mkfNPZ96K9Hth3SBbZt43DvB56ZqsFQlzBZeQ3hkk7ooulAgMBAAEwDQYJ
KoZIhvcNAQELBQADggIBAJgopHEYmETWhH06T72EpgLr3xqckCP9QZ6/UBN8eDt0
rRqMCfM5H33qpe2wojjKwFDkR8XpwF/80VflfFBt9hc1c1fuKmyQSES9gUw10uSL
Z54MCPOa+c8+hslkmJR8Na0QyWN5unnozVHf4XIChsgL1/FblXcOgQLPZygzMNM2
IjdT9XpEHiZTDZDp1NmM7rkRkcpgF2J8G2dcRjo/OGpnhH7wHgxm7hS6yWLW8xPP
8M2/8LPYA7H6HMGYeyrYuDPeVzfaHrECTft+4cjHLu/jYnVLukMMSuI9v5FjtxtX
PYtxnLv8hnbParjSnzK8cOlGdfJDRPMUw9/tvZ4bTeyTtJQYgl/jtdaU4mbdWlge
XMzkZGH3kKpsV2rPZXKJuqRq3vzfr51cQhEcnbJ5H8BsDUQADS3ind37guqoKhuZ
6vFUBTKLeYK5VZ4J18ztXhEynAf7kdROKP6XbE53qtH8qQujmOMWliSFQFdidYsj
eItzGQ4M/ZqI84UnPRL3WPdfPkWqa0x1k6PHFRcFJPp8nhl3O5V4ZdyVC3pKhzUJ
Y8sMit5RH1K8ZTYUVtEKwMX9wRMEkbfE4u/P+yItKw7QgYRdKerlDfCGZP8JY9+k
wqYmF56EVGQFaJdJ1ublVEHQkAVHOBowzccwWOV/OPi1sL+cf4RxAaY7gJpuNEIk
-----END CERTIFICATE-----
Loading