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{1, 0, 0, 3, 0}
- 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{1, 0, 0, 3, 0}
- 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)
- }
- }
|