1 Star 0 Fork 0

AJL / mysqls

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
auth_test.go 38.84 KB
一键复制 编辑 原始数据 按行查看 历史
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
// Go MySQL Driver - A MySQL-Driver for Go's database/sql package
//
// Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at http://mozilla.org/MPL/2.0/.
package mysql
import (
"bytes"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"fmt"
"testing"
)
var testPubKey = []byte("-----BEGIN PUBLIC KEY-----\n" +
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAol0Z8G8U+25Btxk/g/fm\n" +
"UAW/wEKjQCTjkibDE4B+qkuWeiumg6miIRhtilU6m9BFmLQSy1ltYQuu4k17A4tQ\n" +
"rIPpOQYZges/qsDFkZh3wyK5jL5WEFVdOasf6wsfszExnPmcZS4axxoYJfiuilrN\n" +
"hnwinBAqfi3S0sw5MpSI4Zl1AbOrHG4zDI62Gti2PKiMGyYDZTS9xPrBLbN95Kby\n" +
"FFclQLEzA9RJcS1nHFsWtRgHjGPhhjCQxEm9NQ1nePFhCfBfApyfH1VM2VCOQum6\n" +
"Ci9bMuHWjTjckC84mzF99kOxOWVU7mwS6gnJqBzpuz8t3zq8/iQ2y7QrmZV+jTJP\n" +
"WQIDAQAB\n" +
"-----END PUBLIC KEY-----\n")
var testPubKeyRSA *rsa.PublicKey
func init() {
block, _ := pem.Decode(testPubKey)
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
panic(err)
}
testPubKeyRSA = pub.(*rsa.PublicKey)
}
func TestScrambleOldPass(t *testing.T) {
scramble := []byte{9, 8, 7, 6, 5, 4, 3, 2}
vectors := []struct {
pass string
out string
}{
{" pass", "47575c5a435b4251"},
{"pass ", "47575c5a435b4251"},
{"123\t456", "575c47505b5b5559"},
{"C0mpl!ca ted#PASS123", "5d5d554849584a45"},
}
for _, tuple := range vectors {
ours := scrambleOldPassword(scramble, tuple.pass)
if tuple.out != fmt.Sprintf("%x", ours) {
t.Errorf("Failed old password %q", tuple.pass)
}
}
}
func TestScrambleSHA256Pass(t *testing.T) {
scramble := []byte{10, 47, 74, 111, 75, 73, 34, 48, 88, 76, 114, 74, 37, 13, 3, 80, 82, 2, 23, 21}
vectors := []struct {
pass string
out string
}{
{"secret", "f490e76f66d9d86665ce54d98c78d0acfe2fb0b08b423da807144873d30b312c"},
{"secret2", "abc3934a012cf342e876071c8ee202de51785b430258a7a0138bc79c4d800bc6"},
}
for _, tuple := range vectors {
ours := scrambleSHA256Password(scramble, tuple.pass)
if tuple.out != fmt.Sprintf("%x", ours) {
t.Errorf("Failed SHA256 password %q", tuple.pass)
}
}
}
func TestAuthFastCachingSHA256PasswordCached(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
authData := []byte{90, 105, 74, 126, 30, 48, 37, 56, 3, 23, 115, 127, 69,
22, 41, 84, 32, 123, 43, 118}
plugin := "caching_sha2_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{102, 32, 5, 35, 143, 161, 140, 241, 171, 232, 56,
139, 43, 14, 107, 196, 249, 170, 147, 60, 220, 204, 120, 178, 214, 15,
184, 150, 26, 61, 57, 235}
if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
2, 0, 0, 2, 1, 3, // Fast Auth Success
7, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, // OK
}
conn.maxReads = 1
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
}
func TestAuthFastCachingSHA256PasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = ""
authData := []byte{90, 105, 74, 126, 30, 48, 37, 56, 3, 23, 115, 127, 69,
22, 41, 84, 32, 123, 43, 118}
plugin := "caching_sha2_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
if writtenAuthRespLen != 0 {
t.Fatalf("unexpected written auth response (%d bytes): %v",
writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
}
conn.maxReads = 1
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
}
func TestAuthFastCachingSHA256PasswordFullRSA(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
62, 94, 83, 80, 52, 85}
plugin := "caching_sha2_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{171, 201, 138, 146, 89, 159, 11, 170, 0, 67, 165,
49, 175, 94, 218, 68, 177, 109, 110, 86, 34, 33, 44, 190, 67, 240, 70,
110, 40, 139, 124, 41}
if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
2, 0, 0, 2, 1, 4, // Perform Full Authentication
}
conn.queuedReplies = [][]byte{
// pub key response
append([]byte{byte(1 + len(testPubKey)), 1, 0, 4, 1}, testPubKey...),
// OK
{7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 3
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
if !bytes.HasPrefix(conn.written, []byte{1, 0, 0, 3, 2, 0, 1, 0, 5}) {
t.Errorf("unexpected written data: %v", conn.written)
}
}
func TestAuthFastCachingSHA256PasswordFullRSAWithKey(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
mc.cfg.pubKey = testPubKeyRSA
authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
62, 94, 83, 80, 52, 85}
plugin := "caching_sha2_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{171, 201, 138, 146, 89, 159, 11, 170, 0, 67, 165,
49, 175, 94, 218, 68, 177, 109, 110, 86, 34, 33, 44, 190, 67, 240, 70,
110, 40, 139, 124, 41}
if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
2, 0, 0, 2, 1, 4, // Perform Full Authentication
}
conn.queuedReplies = [][]byte{
// OK
{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 2
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
if !bytes.HasPrefix(conn.written, []byte{0, 1, 0, 3}) {
t.Errorf("unexpected written data: %v", conn.written)
}
}
func TestAuthFastCachingSHA256PasswordFullSecure(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
62, 94, 83, 80, 52, 85}
plugin := "caching_sha2_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// Hack to make the caching_sha2_password plugin believe that the connection
// is secure
mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{171, 201, 138, 146, 89, 159, 11, 170, 0, 67, 165,
49, 175, 94, 218, 68, 177, 109, 110, 86, 34, 33, 44, 190, 67, 240, 70,
110, 40, 139, 124, 41}
if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
2, 0, 0, 2, 1, 4, // Perform Full Authentication
}
conn.queuedReplies = [][]byte{
// OK
{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 3
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
if !bytes.Equal(conn.written, []byte{7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0}) {
t.Errorf("unexpected written data: %v", conn.written)
}
}
func TestAuthFastCleartextPasswordNotAllowed(t *testing.T) {
_, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
103, 26, 95, 81, 17, 24, 21}
plugin := "mysql_clear_password"
// Send Client Authentication Packet
_, err := mc.auth(authData, plugin)
if err != ErrCleartextPassword {
t.Errorf("expected ErrCleartextPassword, got %v", err)
}
}
func TestAuthFastCleartextPassword(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
mc.cfg.AllowCleartextPasswords = true
authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
103, 26, 95, 81, 17, 24, 21}
plugin := "mysql_clear_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{115, 101, 99, 114, 101, 116, 0}
if writtenAuthRespLen != 7 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
}
conn.maxReads = 1
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
}
func TestAuthFastCleartextPasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = ""
mc.cfg.AllowCleartextPasswords = true
authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
103, 26, 95, 81, 17, 24, 21}
plugin := "mysql_clear_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{0}
if writtenAuthRespLen != 1 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
}
conn.maxReads = 1
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
}
func TestAuthFastNativePasswordNotAllowed(t *testing.T) {
_, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
mc.cfg.AllowNativePasswords = false
authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
103, 26, 95, 81, 17, 24, 21}
plugin := "mysql_native_password"
// Send Client Authentication Packet
_, err := mc.auth(authData, plugin)
if err != ErrNativePassword {
t.Errorf("expected ErrNativePassword, got %v", err)
}
}
func TestAuthFastNativePassword(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
103, 26, 95, 81, 17, 24, 21}
plugin := "mysql_native_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{53, 177, 140, 159, 251, 189, 127, 53, 109, 252,
172, 50, 211, 192, 240, 164, 26, 48, 207, 45}
if writtenAuthRespLen != 20 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
}
conn.maxReads = 1
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
}
func TestAuthFastNativePasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = ""
authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
103, 26, 95, 81, 17, 24, 21}
plugin := "mysql_native_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
if writtenAuthRespLen != 0 {
t.Fatalf("unexpected written auth response (%d bytes): %v",
writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response
conn.data = []byte{
7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
}
conn.maxReads = 1
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
}
func TestAuthFastSHA256PasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = ""
authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
62, 94, 83, 80, 52, 85}
plugin := "sha256_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{0}
if writtenAuthRespLen != 1 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response (pub key response)
conn.data = append([]byte{byte(1 + len(testPubKey)), 1, 0, 2, 1}, testPubKey...)
conn.queuedReplies = [][]byte{
// OK
{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 2
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
if !bytes.HasPrefix(conn.written, []byte{0, 1, 0, 3}) {
t.Errorf("unexpected written data: %v", conn.written)
}
}
func TestAuthFastSHA256PasswordRSA(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
62, 94, 83, 80, 52, 85}
plugin := "sha256_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{1}
if writtenAuthRespLen != 1 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response (pub key response)
conn.data = append([]byte{byte(1 + len(testPubKey)), 1, 0, 2, 1}, testPubKey...)
conn.queuedReplies = [][]byte{
// OK
{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 2
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
if !bytes.HasPrefix(conn.written, []byte{0, 1, 0, 3}) {
t.Errorf("unexpected written data: %v", conn.written)
}
}
func TestAuthFastSHA256PasswordRSAWithKey(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
mc.cfg.pubKey = testPubKeyRSA
authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
62, 94, 83, 80, 52, 85}
plugin := "sha256_password"
// Send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// auth response (OK)
conn.data = []byte{7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0}
conn.maxReads = 1
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
}
func TestAuthFastSHA256PasswordSecure(t *testing.T) {
conn, mc := newRWMockConn(1)
mc.cfg.User = "root"
mc.cfg.Passwd = "secret"
// hack to make the caching_sha2_password plugin believe that the connection
// is secure
mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
62, 94, 83, 80, 52, 85}
plugin := "sha256_password"
// send Client Authentication Packet
authResp, err := mc.auth(authData, plugin)
if err != nil {
t.Fatal(err)
}
// unset TLS config to prevent the actual establishment of a TLS wrapper
mc.cfg.tls = nil
err = mc.writeHandshakeResponsePacket(authResp, plugin)
if err != nil {
t.Fatal(err)
}
// check written auth response
authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
authRespEnd := authRespStart + 1 + len(authResp)
writtenAuthRespLen := conn.written[authRespStart]
writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
expectedAuthResp := []byte{115, 101, 99, 114, 101, 116, 0}
if writtenAuthRespLen != 7 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
}
conn.written = nil
// auth response (OK)
conn.data = []byte{7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0}
conn.maxReads = 1
// Handle response to auth packet
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
if !bytes.Equal(conn.written, []byte{}) {
t.Errorf("unexpected written data: %v", conn.written)
}
}
func TestAuthSwitchCachingSHA256PasswordCached(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = "secret"
// auth switch request
conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
50, 0}
// auth response
conn.queuedReplies = [][]byte{
{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}, // OK
}
conn.maxReads = 3
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{
// 1. Packet: Hash
32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
153, 9, 130,
}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchCachingSHA256PasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = ""
// auth switch request
conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
50, 0}
// auth response
conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{0, 0, 0, 3}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchCachingSHA256PasswordFullRSA(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = "secret"
// auth switch request
conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
50, 0}
conn.queuedReplies = [][]byte{
// Perform Full Authentication
{2, 0, 0, 4, 1, 4},
// Pub Key Response
append([]byte{byte(1 + len(testPubKey)), 1, 0, 6, 1}, testPubKey...),
// OK
{7, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 4
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReplyPrefix := []byte{
// 1. Packet: Hash
32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
153, 9, 130,
// 2. Packet: Pub Key Request
1, 0, 0, 5, 2,
// 3. Packet: Encrypted Password
0, 1, 0, 7, // [changing bytes]
}
if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchCachingSHA256PasswordFullRSAWithKey(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = "secret"
mc.cfg.pubKey = testPubKeyRSA
// auth switch request
conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
50, 0}
conn.queuedReplies = [][]byte{
// Perform Full Authentication
{2, 0, 0, 4, 1, 4},
// OK
{7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 3
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReplyPrefix := []byte{
// 1. Packet: Hash
32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
153, 9, 130,
// 2. Packet: Encrypted Password
0, 1, 0, 5, // [changing bytes]
}
if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchCachingSHA256PasswordFullSecure(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = "secret"
// Hack to make the caching_sha2_password plugin believe that the connection
// is secure
mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
// auth switch request
conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
50, 0}
// auth response
conn.queuedReplies = [][]byte{
{2, 0, 0, 4, 1, 4}, // Perform Full Authentication
{7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0}, // OK
}
conn.maxReads = 3
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{
// 1. Packet: Hash
32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
153, 9, 130,
// 2. Packet: Cleartext password
7, 0, 0, 5, 115, 101, 99, 114, 101, 116, 0,
}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchCleartextPasswordNotAllowed(t *testing.T) {
conn, mc := newRWMockConn(2)
conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
conn.maxReads = 1
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
err := mc.handleAuthResult(authData, plugin)
if err != ErrCleartextPassword {
t.Errorf("expected ErrCleartextPassword, got %v", err)
}
}
func TestAuthSwitchCleartextPassword(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowCleartextPasswords = true
mc.cfg.Passwd = "secret"
// auth switch request
conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
// auth response
conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchCleartextPasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowCleartextPasswords = true
mc.cfg.Passwd = ""
// auth switch request
conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
// auth response
conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{1, 0, 0, 3, 0}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchNativePasswordNotAllowed(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowNativePasswords = false
conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
31, 0}
conn.maxReads = 1
authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
48, 31, 89, 39, 55, 31}
plugin := "caching_sha2_password"
err := mc.handleAuthResult(authData, plugin)
if err != ErrNativePassword {
t.Errorf("expected ErrNativePassword, got %v", err)
}
}
func TestAuthSwitchNativePassword(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowNativePasswords = true
mc.cfg.Passwd = "secret"
// auth switch request
conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
31, 0}
// auth response
conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
48, 31, 89, 39, 55, 31}
plugin := "caching_sha2_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{20, 0, 0, 3, 202, 41, 195, 164, 34, 226, 49, 103,
21, 211, 167, 199, 227, 116, 8, 48, 57, 71, 149, 146}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchNativePasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowNativePasswords = true
mc.cfg.Passwd = ""
// auth switch request
conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
31, 0}
// auth response
conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
48, 31, 89, 39, 55, 31}
plugin := "caching_sha2_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{0, 0, 0, 3}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchOldPasswordNotAllowed(t *testing.T) {
conn, mc := newRWMockConn(2)
conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
conn.maxReads = 1
authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
84, 96, 101, 92, 123, 121, 107}
plugin := "mysql_native_password"
err := mc.handleAuthResult(authData, plugin)
if err != ErrOldPassword {
t.Errorf("expected ErrOldPassword, got %v", err)
}
}
// Same to TestAuthSwitchOldPasswordNotAllowed, but use OldAuthSwitch request.
func TestOldAuthSwitchNotAllowed(t *testing.T) {
conn, mc := newRWMockConn(2)
// OldAuthSwitch request
conn.data = []byte{1, 0, 0, 2, 0xfe}
conn.maxReads = 1
authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
84, 96, 101, 92, 123, 121, 107}
plugin := "mysql_native_password"
err := mc.handleAuthResult(authData, plugin)
if err != ErrOldPassword {
t.Errorf("expected ErrOldPassword, got %v", err)
}
}
func TestAuthSwitchOldPassword(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowOldPasswords = true
mc.cfg.Passwd = "secret"
// auth switch request
conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
// auth response
conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
84, 96, 101, 92, 123, 121, 107}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{9, 0, 0, 3, 86, 83, 83, 79, 74, 78, 65, 66, 0}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
// Same to TestAuthSwitchOldPassword, but use OldAuthSwitch request.
func TestOldAuthSwitch(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowOldPasswords = true
mc.cfg.Passwd = "secret"
// OldAuthSwitch request
conn.data = []byte{1, 0, 0, 2, 0xfe}
// auth response
conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
84, 96, 101, 92, 123, 121, 107}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{9, 0, 0, 3, 86, 83, 83, 79, 74, 78, 65, 66, 0}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchOldPasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowOldPasswords = true
mc.cfg.Passwd = ""
// auth switch request
conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
// auth response
conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
84, 96, 101, 92, 123, 121, 107}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{0, 0, 0, 3}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
// Same to TestAuthSwitchOldPasswordEmpty, but use OldAuthSwitch request.
func TestOldAuthSwitchPasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.AllowOldPasswords = true
mc.cfg.Passwd = ""
// OldAuthSwitch request.
conn.data = []byte{1, 0, 0, 2, 0xfe}
// auth response
conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
conn.maxReads = 2
authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
84, 96, 101, 92, 123, 121, 107}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReply := []byte{0, 0, 0, 3}
if !bytes.Equal(conn.written, expectedReply) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchSHA256PasswordEmpty(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = ""
// auth switch request
conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
conn.queuedReplies = [][]byte{
// OK
{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 3
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReplyPrefix := []byte{
// 1. Packet: Empty Password
1, 0, 0, 3, 0,
}
if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchSHA256PasswordRSA(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = "secret"
// auth switch request
conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
conn.queuedReplies = [][]byte{
// Pub Key Response
append([]byte{byte(1 + len(testPubKey)), 1, 0, 4, 1}, testPubKey...),
// OK
{7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 3
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReplyPrefix := []byte{
// 1. Packet: Pub Key Request
1, 0, 0, 3, 1,
// 2. Packet: Encrypted Password
0, 1, 0, 5, // [changing bytes]
}
if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchSHA256PasswordRSAWithKey(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = "secret"
mc.cfg.pubKey = testPubKeyRSA
// auth switch request
conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
conn.queuedReplies = [][]byte{
// OK
{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 2
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReplyPrefix := []byte{
// 1. Packet: Encrypted Password
0, 1, 0, 3, // [changing bytes]
}
if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
func TestAuthSwitchSHA256PasswordSecure(t *testing.T) {
conn, mc := newRWMockConn(2)
mc.cfg.Passwd = "secret"
// Hack to make the caching_sha2_password plugin believe that the connection
// is secure
mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
// auth switch request
conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
conn.queuedReplies = [][]byte{
// OK
{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
}
conn.maxReads = 2
authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
47, 43, 9, 41, 112, 67, 110}
plugin := "mysql_native_password"
if err := mc.handleAuthResult(authData, plugin); err != nil {
t.Errorf("got error: %v", err)
}
expectedReplyPrefix := []byte{
// 1. Packet: Cleartext Password
7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0,
}
if !bytes.Equal(conn.written, expectedReplyPrefix) {
t.Errorf("got unexpected data: %v", conn.written)
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ltfish/mysqls.git
git@gitee.com:ltfish/mysqls.git
ltfish
mysqls
mysqls
master

搜索帮助

344bd9b3 5694891 D2dac590 5694891