auth_test.go 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  1. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  2. //
  3. // Copyright 2018 The Go-MySQL-Driver Authors. All rights reserved.
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public
  6. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  7. // You can obtain one at http://mozilla.org/MPL/2.0/.
  8. package mysql
  9. import (
  10. "bytes"
  11. "crypto/rsa"
  12. "crypto/tls"
  13. "crypto/x509"
  14. "encoding/pem"
  15. "fmt"
  16. "testing"
  17. )
  18. var testPubKey = []byte("-----BEGIN PUBLIC KEY-----\n" +
  19. "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAol0Z8G8U+25Btxk/g/fm\n" +
  20. "UAW/wEKjQCTjkibDE4B+qkuWeiumg6miIRhtilU6m9BFmLQSy1ltYQuu4k17A4tQ\n" +
  21. "rIPpOQYZges/qsDFkZh3wyK5jL5WEFVdOasf6wsfszExnPmcZS4axxoYJfiuilrN\n" +
  22. "hnwinBAqfi3S0sw5MpSI4Zl1AbOrHG4zDI62Gti2PKiMGyYDZTS9xPrBLbN95Kby\n" +
  23. "FFclQLEzA9RJcS1nHFsWtRgHjGPhhjCQxEm9NQ1nePFhCfBfApyfH1VM2VCOQum6\n" +
  24. "Ci9bMuHWjTjckC84mzF99kOxOWVU7mwS6gnJqBzpuz8t3zq8/iQ2y7QrmZV+jTJP\n" +
  25. "WQIDAQAB\n" +
  26. "-----END PUBLIC KEY-----\n")
  27. var testPubKeyRSA *rsa.PublicKey
  28. func init() {
  29. block, _ := pem.Decode(testPubKey)
  30. pub, err := x509.ParsePKIXPublicKey(block.Bytes)
  31. if err != nil {
  32. panic(err)
  33. }
  34. testPubKeyRSA = pub.(*rsa.PublicKey)
  35. }
  36. func TestScrambleOldPass(t *testing.T) {
  37. scramble := []byte{9, 8, 7, 6, 5, 4, 3, 2}
  38. vectors := []struct {
  39. pass string
  40. out string
  41. }{
  42. {" pass", "47575c5a435b4251"},
  43. {"pass ", "47575c5a435b4251"},
  44. {"123\t456", "575c47505b5b5559"},
  45. {"C0mpl!ca ted#PASS123", "5d5d554849584a45"},
  46. }
  47. for _, tuple := range vectors {
  48. ours := scrambleOldPassword(scramble, tuple.pass)
  49. if tuple.out != fmt.Sprintf("%x", ours) {
  50. t.Errorf("Failed old password %q", tuple.pass)
  51. }
  52. }
  53. }
  54. func TestScrambleSHA256Pass(t *testing.T) {
  55. scramble := []byte{10, 47, 74, 111, 75, 73, 34, 48, 88, 76, 114, 74, 37, 13, 3, 80, 82, 2, 23, 21}
  56. vectors := []struct {
  57. pass string
  58. out string
  59. }{
  60. {"secret", "f490e76f66d9d86665ce54d98c78d0acfe2fb0b08b423da807144873d30b312c"},
  61. {"secret2", "abc3934a012cf342e876071c8ee202de51785b430258a7a0138bc79c4d800bc6"},
  62. }
  63. for _, tuple := range vectors {
  64. ours := scrambleSHA256Password(scramble, tuple.pass)
  65. if tuple.out != fmt.Sprintf("%x", ours) {
  66. t.Errorf("Failed SHA256 password %q", tuple.pass)
  67. }
  68. }
  69. }
  70. func TestAuthFastCachingSHA256PasswordCached(t *testing.T) {
  71. conn, mc := newRWMockConn(1)
  72. mc.cfg.User = "root"
  73. mc.cfg.Passwd = "secret"
  74. authData := []byte{90, 105, 74, 126, 30, 48, 37, 56, 3, 23, 115, 127, 69,
  75. 22, 41, 84, 32, 123, 43, 118}
  76. plugin := "caching_sha2_password"
  77. // Send Client Authentication Packet
  78. authResp, err := mc.auth(authData, plugin)
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  83. if err != nil {
  84. t.Fatal(err)
  85. }
  86. // check written auth response
  87. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  88. authRespEnd := authRespStart + 1 + len(authResp)
  89. writtenAuthRespLen := conn.written[authRespStart]
  90. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  91. expectedAuthResp := []byte{102, 32, 5, 35, 143, 161, 140, 241, 171, 232, 56,
  92. 139, 43, 14, 107, 196, 249, 170, 147, 60, 220, 204, 120, 178, 214, 15,
  93. 184, 150, 26, 61, 57, 235}
  94. if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  95. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  96. }
  97. conn.written = nil
  98. // auth response
  99. conn.data = []byte{
  100. 2, 0, 0, 2, 1, 3, // Fast Auth Success
  101. 7, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, // OK
  102. }
  103. conn.maxReads = 1
  104. // Handle response to auth packet
  105. if err := mc.handleAuthResult(authData, plugin); err != nil {
  106. t.Errorf("got error: %v", err)
  107. }
  108. }
  109. func TestAuthFastCachingSHA256PasswordEmpty(t *testing.T) {
  110. conn, mc := newRWMockConn(1)
  111. mc.cfg.User = "root"
  112. mc.cfg.Passwd = ""
  113. authData := []byte{90, 105, 74, 126, 30, 48, 37, 56, 3, 23, 115, 127, 69,
  114. 22, 41, 84, 32, 123, 43, 118}
  115. plugin := "caching_sha2_password"
  116. // Send Client Authentication Packet
  117. authResp, err := mc.auth(authData, plugin)
  118. if err != nil {
  119. t.Fatal(err)
  120. }
  121. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  122. if err != nil {
  123. t.Fatal(err)
  124. }
  125. // check written auth response
  126. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  127. authRespEnd := authRespStart + 1 + len(authResp)
  128. writtenAuthRespLen := conn.written[authRespStart]
  129. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  130. if writtenAuthRespLen != 0 {
  131. t.Fatalf("unexpected written auth response (%d bytes): %v",
  132. writtenAuthRespLen, writtenAuthResp)
  133. }
  134. conn.written = nil
  135. // auth response
  136. conn.data = []byte{
  137. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  138. }
  139. conn.maxReads = 1
  140. // Handle response to auth packet
  141. if err := mc.handleAuthResult(authData, plugin); err != nil {
  142. t.Errorf("got error: %v", err)
  143. }
  144. }
  145. func TestAuthFastCachingSHA256PasswordFullRSA(t *testing.T) {
  146. conn, mc := newRWMockConn(1)
  147. mc.cfg.User = "root"
  148. mc.cfg.Passwd = "secret"
  149. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  150. 62, 94, 83, 80, 52, 85}
  151. plugin := "caching_sha2_password"
  152. // Send Client Authentication Packet
  153. authResp, err := mc.auth(authData, plugin)
  154. if err != nil {
  155. t.Fatal(err)
  156. }
  157. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  158. if err != nil {
  159. t.Fatal(err)
  160. }
  161. // check written auth response
  162. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  163. authRespEnd := authRespStart + 1 + len(authResp)
  164. writtenAuthRespLen := conn.written[authRespStart]
  165. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  166. expectedAuthResp := []byte{171, 201, 138, 146, 89, 159, 11, 170, 0, 67, 165,
  167. 49, 175, 94, 218, 68, 177, 109, 110, 86, 34, 33, 44, 190, 67, 240, 70,
  168. 110, 40, 139, 124, 41}
  169. if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  170. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  171. }
  172. conn.written = nil
  173. // auth response
  174. conn.data = []byte{
  175. 2, 0, 0, 2, 1, 4, // Perform Full Authentication
  176. }
  177. conn.queuedReplies = [][]byte{
  178. // pub key response
  179. append([]byte{byte(1 + len(testPubKey)), 1, 0, 4, 1}, testPubKey...),
  180. // OK
  181. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
  182. }
  183. conn.maxReads = 3
  184. // Handle response to auth packet
  185. if err := mc.handleAuthResult(authData, plugin); err != nil {
  186. t.Errorf("got error: %v", err)
  187. }
  188. if !bytes.HasPrefix(conn.written, []byte{1, 0, 0, 3, 2, 0, 1, 0, 5}) {
  189. t.Errorf("unexpected written data: %v", conn.written)
  190. }
  191. }
  192. func TestAuthFastCachingSHA256PasswordFullRSAWithKey(t *testing.T) {
  193. conn, mc := newRWMockConn(1)
  194. mc.cfg.User = "root"
  195. mc.cfg.Passwd = "secret"
  196. mc.cfg.pubKey = testPubKeyRSA
  197. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  198. 62, 94, 83, 80, 52, 85}
  199. plugin := "caching_sha2_password"
  200. // Send Client Authentication Packet
  201. authResp, err := mc.auth(authData, plugin)
  202. if err != nil {
  203. t.Fatal(err)
  204. }
  205. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  206. if err != nil {
  207. t.Fatal(err)
  208. }
  209. // check written auth response
  210. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  211. authRespEnd := authRespStart + 1 + len(authResp)
  212. writtenAuthRespLen := conn.written[authRespStart]
  213. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  214. expectedAuthResp := []byte{171, 201, 138, 146, 89, 159, 11, 170, 0, 67, 165,
  215. 49, 175, 94, 218, 68, 177, 109, 110, 86, 34, 33, 44, 190, 67, 240, 70,
  216. 110, 40, 139, 124, 41}
  217. if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  218. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  219. }
  220. conn.written = nil
  221. // auth response
  222. conn.data = []byte{
  223. 2, 0, 0, 2, 1, 4, // Perform Full Authentication
  224. }
  225. conn.queuedReplies = [][]byte{
  226. // OK
  227. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  228. }
  229. conn.maxReads = 2
  230. // Handle response to auth packet
  231. if err := mc.handleAuthResult(authData, plugin); err != nil {
  232. t.Errorf("got error: %v", err)
  233. }
  234. if !bytes.HasPrefix(conn.written, []byte{0, 1, 0, 3}) {
  235. t.Errorf("unexpected written data: %v", conn.written)
  236. }
  237. }
  238. func TestAuthFastCachingSHA256PasswordFullSecure(t *testing.T) {
  239. conn, mc := newRWMockConn(1)
  240. mc.cfg.User = "root"
  241. mc.cfg.Passwd = "secret"
  242. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  243. 62, 94, 83, 80, 52, 85}
  244. plugin := "caching_sha2_password"
  245. // Send Client Authentication Packet
  246. authResp, err := mc.auth(authData, plugin)
  247. if err != nil {
  248. t.Fatal(err)
  249. }
  250. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  251. if err != nil {
  252. t.Fatal(err)
  253. }
  254. // Hack to make the caching_sha2_password plugin believe that the connection
  255. // is secure
  256. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  257. // check written auth response
  258. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  259. authRespEnd := authRespStart + 1 + len(authResp)
  260. writtenAuthRespLen := conn.written[authRespStart]
  261. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  262. expectedAuthResp := []byte{171, 201, 138, 146, 89, 159, 11, 170, 0, 67, 165,
  263. 49, 175, 94, 218, 68, 177, 109, 110, 86, 34, 33, 44, 190, 67, 240, 70,
  264. 110, 40, 139, 124, 41}
  265. if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  266. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  267. }
  268. conn.written = nil
  269. // auth response
  270. conn.data = []byte{
  271. 2, 0, 0, 2, 1, 4, // Perform Full Authentication
  272. }
  273. conn.queuedReplies = [][]byte{
  274. // OK
  275. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  276. }
  277. conn.maxReads = 3
  278. // Handle response to auth packet
  279. if err := mc.handleAuthResult(authData, plugin); err != nil {
  280. t.Errorf("got error: %v", err)
  281. }
  282. if !bytes.Equal(conn.written, []byte{7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0}) {
  283. t.Errorf("unexpected written data: %v", conn.written)
  284. }
  285. }
  286. func TestAuthFastCleartextPasswordNotAllowed(t *testing.T) {
  287. _, mc := newRWMockConn(1)
  288. mc.cfg.User = "root"
  289. mc.cfg.Passwd = "secret"
  290. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  291. 103, 26, 95, 81, 17, 24, 21}
  292. plugin := "mysql_clear_password"
  293. // Send Client Authentication Packet
  294. _, err := mc.auth(authData, plugin)
  295. if err != ErrCleartextPassword {
  296. t.Errorf("expected ErrCleartextPassword, got %v", err)
  297. }
  298. }
  299. func TestAuthFastCleartextPassword(t *testing.T) {
  300. conn, mc := newRWMockConn(1)
  301. mc.cfg.User = "root"
  302. mc.cfg.Passwd = "secret"
  303. mc.cfg.AllowCleartextPasswords = true
  304. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  305. 103, 26, 95, 81, 17, 24, 21}
  306. plugin := "mysql_clear_password"
  307. // Send Client Authentication Packet
  308. authResp, err := mc.auth(authData, plugin)
  309. if err != nil {
  310. t.Fatal(err)
  311. }
  312. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  313. if err != nil {
  314. t.Fatal(err)
  315. }
  316. // check written auth response
  317. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  318. authRespEnd := authRespStart + 1 + len(authResp)
  319. writtenAuthRespLen := conn.written[authRespStart]
  320. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  321. expectedAuthResp := []byte{115, 101, 99, 114, 101, 116, 0}
  322. if writtenAuthRespLen != 7 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  323. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  324. }
  325. conn.written = nil
  326. // auth response
  327. conn.data = []byte{
  328. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  329. }
  330. conn.maxReads = 1
  331. // Handle response to auth packet
  332. if err := mc.handleAuthResult(authData, plugin); err != nil {
  333. t.Errorf("got error: %v", err)
  334. }
  335. }
  336. func TestAuthFastCleartextPasswordEmpty(t *testing.T) {
  337. conn, mc := newRWMockConn(1)
  338. mc.cfg.User = "root"
  339. mc.cfg.Passwd = ""
  340. mc.cfg.AllowCleartextPasswords = true
  341. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  342. 103, 26, 95, 81, 17, 24, 21}
  343. plugin := "mysql_clear_password"
  344. // Send Client Authentication Packet
  345. authResp, err := mc.auth(authData, plugin)
  346. if err != nil {
  347. t.Fatal(err)
  348. }
  349. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  350. if err != nil {
  351. t.Fatal(err)
  352. }
  353. // check written auth response
  354. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  355. authRespEnd := authRespStart + 1 + len(authResp)
  356. writtenAuthRespLen := conn.written[authRespStart]
  357. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  358. expectedAuthResp := []byte{0}
  359. if writtenAuthRespLen != 1 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  360. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  361. }
  362. conn.written = nil
  363. // auth response
  364. conn.data = []byte{
  365. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  366. }
  367. conn.maxReads = 1
  368. // Handle response to auth packet
  369. if err := mc.handleAuthResult(authData, plugin); err != nil {
  370. t.Errorf("got error: %v", err)
  371. }
  372. }
  373. func TestAuthFastNativePasswordNotAllowed(t *testing.T) {
  374. _, mc := newRWMockConn(1)
  375. mc.cfg.User = "root"
  376. mc.cfg.Passwd = "secret"
  377. mc.cfg.AllowNativePasswords = false
  378. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  379. 103, 26, 95, 81, 17, 24, 21}
  380. plugin := "mysql_native_password"
  381. // Send Client Authentication Packet
  382. _, err := mc.auth(authData, plugin)
  383. if err != ErrNativePassword {
  384. t.Errorf("expected ErrNativePassword, got %v", err)
  385. }
  386. }
  387. func TestAuthFastNativePassword(t *testing.T) {
  388. conn, mc := newRWMockConn(1)
  389. mc.cfg.User = "root"
  390. mc.cfg.Passwd = "secret"
  391. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  392. 103, 26, 95, 81, 17, 24, 21}
  393. plugin := "mysql_native_password"
  394. // Send Client Authentication Packet
  395. authResp, err := mc.auth(authData, plugin)
  396. if err != nil {
  397. t.Fatal(err)
  398. }
  399. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  400. if err != nil {
  401. t.Fatal(err)
  402. }
  403. // check written auth response
  404. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  405. authRespEnd := authRespStart + 1 + len(authResp)
  406. writtenAuthRespLen := conn.written[authRespStart]
  407. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  408. expectedAuthResp := []byte{53, 177, 140, 159, 251, 189, 127, 53, 109, 252,
  409. 172, 50, 211, 192, 240, 164, 26, 48, 207, 45}
  410. if writtenAuthRespLen != 20 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  411. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  412. }
  413. conn.written = nil
  414. // auth response
  415. conn.data = []byte{
  416. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  417. }
  418. conn.maxReads = 1
  419. // Handle response to auth packet
  420. if err := mc.handleAuthResult(authData, plugin); err != nil {
  421. t.Errorf("got error: %v", err)
  422. }
  423. }
  424. func TestAuthFastNativePasswordEmpty(t *testing.T) {
  425. conn, mc := newRWMockConn(1)
  426. mc.cfg.User = "root"
  427. mc.cfg.Passwd = ""
  428. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  429. 103, 26, 95, 81, 17, 24, 21}
  430. plugin := "mysql_native_password"
  431. // Send Client Authentication Packet
  432. authResp, err := mc.auth(authData, plugin)
  433. if err != nil {
  434. t.Fatal(err)
  435. }
  436. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  437. if err != nil {
  438. t.Fatal(err)
  439. }
  440. // check written auth response
  441. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  442. authRespEnd := authRespStart + 1 + len(authResp)
  443. writtenAuthRespLen := conn.written[authRespStart]
  444. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  445. if writtenAuthRespLen != 0 {
  446. t.Fatalf("unexpected written auth response (%d bytes): %v",
  447. writtenAuthRespLen, writtenAuthResp)
  448. }
  449. conn.written = nil
  450. // auth response
  451. conn.data = []byte{
  452. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  453. }
  454. conn.maxReads = 1
  455. // Handle response to auth packet
  456. if err := mc.handleAuthResult(authData, plugin); err != nil {
  457. t.Errorf("got error: %v", err)
  458. }
  459. }
  460. func TestAuthFastSHA256PasswordEmpty(t *testing.T) {
  461. conn, mc := newRWMockConn(1)
  462. mc.cfg.User = "root"
  463. mc.cfg.Passwd = ""
  464. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  465. 62, 94, 83, 80, 52, 85}
  466. plugin := "sha256_password"
  467. // Send Client Authentication Packet
  468. authResp, err := mc.auth(authData, plugin)
  469. if err != nil {
  470. t.Fatal(err)
  471. }
  472. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  473. if err != nil {
  474. t.Fatal(err)
  475. }
  476. // check written auth response
  477. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  478. authRespEnd := authRespStart + 1 + len(authResp)
  479. writtenAuthRespLen := conn.written[authRespStart]
  480. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  481. expectedAuthResp := []byte{0}
  482. if writtenAuthRespLen != 1 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  483. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  484. }
  485. conn.written = nil
  486. // auth response (pub key response)
  487. conn.data = append([]byte{byte(1 + len(testPubKey)), 1, 0, 2, 1}, testPubKey...)
  488. conn.queuedReplies = [][]byte{
  489. // OK
  490. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  491. }
  492. conn.maxReads = 2
  493. // Handle response to auth packet
  494. if err := mc.handleAuthResult(authData, plugin); err != nil {
  495. t.Errorf("got error: %v", err)
  496. }
  497. if !bytes.HasPrefix(conn.written, []byte{0, 1, 0, 3}) {
  498. t.Errorf("unexpected written data: %v", conn.written)
  499. }
  500. }
  501. func TestAuthFastSHA256PasswordRSA(t *testing.T) {
  502. conn, mc := newRWMockConn(1)
  503. mc.cfg.User = "root"
  504. mc.cfg.Passwd = "secret"
  505. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  506. 62, 94, 83, 80, 52, 85}
  507. plugin := "sha256_password"
  508. // Send Client Authentication Packet
  509. authResp, err := mc.auth(authData, plugin)
  510. if err != nil {
  511. t.Fatal(err)
  512. }
  513. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  514. if err != nil {
  515. t.Fatal(err)
  516. }
  517. // check written auth response
  518. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  519. authRespEnd := authRespStart + 1 + len(authResp)
  520. writtenAuthRespLen := conn.written[authRespStart]
  521. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  522. expectedAuthResp := []byte{1}
  523. if writtenAuthRespLen != 1 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  524. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  525. }
  526. conn.written = nil
  527. // auth response (pub key response)
  528. conn.data = append([]byte{byte(1 + len(testPubKey)), 1, 0, 2, 1}, testPubKey...)
  529. conn.queuedReplies = [][]byte{
  530. // OK
  531. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  532. }
  533. conn.maxReads = 2
  534. // Handle response to auth packet
  535. if err := mc.handleAuthResult(authData, plugin); err != nil {
  536. t.Errorf("got error: %v", err)
  537. }
  538. if !bytes.HasPrefix(conn.written, []byte{0, 1, 0, 3}) {
  539. t.Errorf("unexpected written data: %v", conn.written)
  540. }
  541. }
  542. func TestAuthFastSHA256PasswordRSAWithKey(t *testing.T) {
  543. conn, mc := newRWMockConn(1)
  544. mc.cfg.User = "root"
  545. mc.cfg.Passwd = "secret"
  546. mc.cfg.pubKey = testPubKeyRSA
  547. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  548. 62, 94, 83, 80, 52, 85}
  549. plugin := "sha256_password"
  550. // Send Client Authentication Packet
  551. authResp, err := mc.auth(authData, plugin)
  552. if err != nil {
  553. t.Fatal(err)
  554. }
  555. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  556. if err != nil {
  557. t.Fatal(err)
  558. }
  559. // auth response (OK)
  560. conn.data = []byte{7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0}
  561. conn.maxReads = 1
  562. // Handle response to auth packet
  563. if err := mc.handleAuthResult(authData, plugin); err != nil {
  564. t.Errorf("got error: %v", err)
  565. }
  566. }
  567. func TestAuthFastSHA256PasswordSecure(t *testing.T) {
  568. conn, mc := newRWMockConn(1)
  569. mc.cfg.User = "root"
  570. mc.cfg.Passwd = "secret"
  571. // hack to make the caching_sha2_password plugin believe that the connection
  572. // is secure
  573. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  574. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  575. 62, 94, 83, 80, 52, 85}
  576. plugin := "sha256_password"
  577. // send Client Authentication Packet
  578. authResp, err := mc.auth(authData, plugin)
  579. if err != nil {
  580. t.Fatal(err)
  581. }
  582. // unset TLS config to prevent the actual establishment of a TLS wrapper
  583. mc.cfg.tls = nil
  584. err = mc.writeHandshakeResponsePacket(authResp, plugin)
  585. if err != nil {
  586. t.Fatal(err)
  587. }
  588. // check written auth response
  589. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  590. authRespEnd := authRespStart + 1 + len(authResp)
  591. writtenAuthRespLen := conn.written[authRespStart]
  592. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  593. expectedAuthResp := []byte{115, 101, 99, 114, 101, 116, 0}
  594. if writtenAuthRespLen != 7 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  595. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  596. }
  597. conn.written = nil
  598. // auth response (OK)
  599. conn.data = []byte{7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0}
  600. conn.maxReads = 1
  601. // Handle response to auth packet
  602. if err := mc.handleAuthResult(authData, plugin); err != nil {
  603. t.Errorf("got error: %v", err)
  604. }
  605. if !bytes.Equal(conn.written, []byte{}) {
  606. t.Errorf("unexpected written data: %v", conn.written)
  607. }
  608. }
  609. func TestAuthSwitchCachingSHA256PasswordCached(t *testing.T) {
  610. conn, mc := newRWMockConn(2)
  611. mc.cfg.Passwd = "secret"
  612. // auth switch request
  613. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  614. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  615. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  616. 50, 0}
  617. // auth response
  618. conn.queuedReplies = [][]byte{
  619. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}, // OK
  620. }
  621. conn.maxReads = 3
  622. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  623. 47, 43, 9, 41, 112, 67, 110}
  624. plugin := "mysql_native_password"
  625. if err := mc.handleAuthResult(authData, plugin); err != nil {
  626. t.Errorf("got error: %v", err)
  627. }
  628. expectedReply := []byte{
  629. // 1. Packet: Hash
  630. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  631. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  632. 153, 9, 130,
  633. }
  634. if !bytes.Equal(conn.written, expectedReply) {
  635. t.Errorf("got unexpected data: %v", conn.written)
  636. }
  637. }
  638. func TestAuthSwitchCachingSHA256PasswordEmpty(t *testing.T) {
  639. conn, mc := newRWMockConn(2)
  640. mc.cfg.Passwd = ""
  641. // auth switch request
  642. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  643. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  644. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  645. 50, 0}
  646. // auth response
  647. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  648. conn.maxReads = 2
  649. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  650. 47, 43, 9, 41, 112, 67, 110}
  651. plugin := "mysql_native_password"
  652. if err := mc.handleAuthResult(authData, plugin); err != nil {
  653. t.Errorf("got error: %v", err)
  654. }
  655. expectedReply := []byte{0, 0, 0, 3}
  656. if !bytes.Equal(conn.written, expectedReply) {
  657. t.Errorf("got unexpected data: %v", conn.written)
  658. }
  659. }
  660. func TestAuthSwitchCachingSHA256PasswordFullRSA(t *testing.T) {
  661. conn, mc := newRWMockConn(2)
  662. mc.cfg.Passwd = "secret"
  663. // auth switch request
  664. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  665. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  666. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  667. 50, 0}
  668. conn.queuedReplies = [][]byte{
  669. // Perform Full Authentication
  670. {2, 0, 0, 4, 1, 4},
  671. // Pub Key Response
  672. append([]byte{byte(1 + len(testPubKey)), 1, 0, 6, 1}, testPubKey...),
  673. // OK
  674. {7, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0},
  675. }
  676. conn.maxReads = 4
  677. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  678. 47, 43, 9, 41, 112, 67, 110}
  679. plugin := "mysql_native_password"
  680. if err := mc.handleAuthResult(authData, plugin); err != nil {
  681. t.Errorf("got error: %v", err)
  682. }
  683. expectedReplyPrefix := []byte{
  684. // 1. Packet: Hash
  685. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  686. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  687. 153, 9, 130,
  688. // 2. Packet: Pub Key Request
  689. 1, 0, 0, 5, 2,
  690. // 3. Packet: Encrypted Password
  691. 0, 1, 0, 7, // [changing bytes]
  692. }
  693. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  694. t.Errorf("got unexpected data: %v", conn.written)
  695. }
  696. }
  697. func TestAuthSwitchCachingSHA256PasswordFullRSAWithKey(t *testing.T) {
  698. conn, mc := newRWMockConn(2)
  699. mc.cfg.Passwd = "secret"
  700. mc.cfg.pubKey = testPubKeyRSA
  701. // auth switch request
  702. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  703. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  704. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  705. 50, 0}
  706. conn.queuedReplies = [][]byte{
  707. // Perform Full Authentication
  708. {2, 0, 0, 4, 1, 4},
  709. // OK
  710. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
  711. }
  712. conn.maxReads = 3
  713. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  714. 47, 43, 9, 41, 112, 67, 110}
  715. plugin := "mysql_native_password"
  716. if err := mc.handleAuthResult(authData, plugin); err != nil {
  717. t.Errorf("got error: %v", err)
  718. }
  719. expectedReplyPrefix := []byte{
  720. // 1. Packet: Hash
  721. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  722. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  723. 153, 9, 130,
  724. // 2. Packet: Encrypted Password
  725. 0, 1, 0, 5, // [changing bytes]
  726. }
  727. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  728. t.Errorf("got unexpected data: %v", conn.written)
  729. }
  730. }
  731. func TestAuthSwitchCachingSHA256PasswordFullSecure(t *testing.T) {
  732. conn, mc := newRWMockConn(2)
  733. mc.cfg.Passwd = "secret"
  734. // Hack to make the caching_sha2_password plugin believe that the connection
  735. // is secure
  736. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  737. // auth switch request
  738. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  739. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  740. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  741. 50, 0}
  742. // auth response
  743. conn.queuedReplies = [][]byte{
  744. {2, 0, 0, 4, 1, 4}, // Perform Full Authentication
  745. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0}, // OK
  746. }
  747. conn.maxReads = 3
  748. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  749. 47, 43, 9, 41, 112, 67, 110}
  750. plugin := "mysql_native_password"
  751. if err := mc.handleAuthResult(authData, plugin); err != nil {
  752. t.Errorf("got error: %v", err)
  753. }
  754. expectedReply := []byte{
  755. // 1. Packet: Hash
  756. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  757. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  758. 153, 9, 130,
  759. // 2. Packet: Cleartext password
  760. 7, 0, 0, 5, 115, 101, 99, 114, 101, 116, 0,
  761. }
  762. if !bytes.Equal(conn.written, expectedReply) {
  763. t.Errorf("got unexpected data: %v", conn.written)
  764. }
  765. }
  766. func TestAuthSwitchCleartextPasswordNotAllowed(t *testing.T) {
  767. conn, mc := newRWMockConn(2)
  768. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  769. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  770. conn.maxReads = 1
  771. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  772. 47, 43, 9, 41, 112, 67, 110}
  773. plugin := "mysql_native_password"
  774. err := mc.handleAuthResult(authData, plugin)
  775. if err != ErrCleartextPassword {
  776. t.Errorf("expected ErrCleartextPassword, got %v", err)
  777. }
  778. }
  779. func TestAuthSwitchCleartextPassword(t *testing.T) {
  780. conn, mc := newRWMockConn(2)
  781. mc.cfg.AllowCleartextPasswords = true
  782. mc.cfg.Passwd = "secret"
  783. // auth switch request
  784. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  785. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  786. // auth response
  787. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  788. conn.maxReads = 2
  789. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  790. 47, 43, 9, 41, 112, 67, 110}
  791. plugin := "mysql_native_password"
  792. if err := mc.handleAuthResult(authData, plugin); err != nil {
  793. t.Errorf("got error: %v", err)
  794. }
  795. expectedReply := []byte{7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0}
  796. if !bytes.Equal(conn.written, expectedReply) {
  797. t.Errorf("got unexpected data: %v", conn.written)
  798. }
  799. }
  800. func TestAuthSwitchCleartextPasswordEmpty(t *testing.T) {
  801. conn, mc := newRWMockConn(2)
  802. mc.cfg.AllowCleartextPasswords = true
  803. mc.cfg.Passwd = ""
  804. // auth switch request
  805. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  806. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  807. // auth response
  808. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  809. conn.maxReads = 2
  810. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  811. 47, 43, 9, 41, 112, 67, 110}
  812. plugin := "mysql_native_password"
  813. if err := mc.handleAuthResult(authData, plugin); err != nil {
  814. t.Errorf("got error: %v", err)
  815. }
  816. expectedReply := []byte{1, 0, 0, 3, 0}
  817. if !bytes.Equal(conn.written, expectedReply) {
  818. t.Errorf("got unexpected data: %v", conn.written)
  819. }
  820. }
  821. func TestAuthSwitchNativePasswordNotAllowed(t *testing.T) {
  822. conn, mc := newRWMockConn(2)
  823. mc.cfg.AllowNativePasswords = false
  824. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  825. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  826. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  827. 31, 0}
  828. conn.maxReads = 1
  829. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  830. 48, 31, 89, 39, 55, 31}
  831. plugin := "caching_sha2_password"
  832. err := mc.handleAuthResult(authData, plugin)
  833. if err != ErrNativePassword {
  834. t.Errorf("expected ErrNativePassword, got %v", err)
  835. }
  836. }
  837. func TestAuthSwitchNativePassword(t *testing.T) {
  838. conn, mc := newRWMockConn(2)
  839. mc.cfg.AllowNativePasswords = true
  840. mc.cfg.Passwd = "secret"
  841. // auth switch request
  842. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  843. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  844. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  845. 31, 0}
  846. // auth response
  847. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  848. conn.maxReads = 2
  849. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  850. 48, 31, 89, 39, 55, 31}
  851. plugin := "caching_sha2_password"
  852. if err := mc.handleAuthResult(authData, plugin); err != nil {
  853. t.Errorf("got error: %v", err)
  854. }
  855. expectedReply := []byte{20, 0, 0, 3, 202, 41, 195, 164, 34, 226, 49, 103,
  856. 21, 211, 167, 199, 227, 116, 8, 48, 57, 71, 149, 146}
  857. if !bytes.Equal(conn.written, expectedReply) {
  858. t.Errorf("got unexpected data: %v", conn.written)
  859. }
  860. }
  861. func TestAuthSwitchNativePasswordEmpty(t *testing.T) {
  862. conn, mc := newRWMockConn(2)
  863. mc.cfg.AllowNativePasswords = true
  864. mc.cfg.Passwd = ""
  865. // auth switch request
  866. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  867. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  868. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  869. 31, 0}
  870. // auth response
  871. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  872. conn.maxReads = 2
  873. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  874. 48, 31, 89, 39, 55, 31}
  875. plugin := "caching_sha2_password"
  876. if err := mc.handleAuthResult(authData, plugin); err != nil {
  877. t.Errorf("got error: %v", err)
  878. }
  879. expectedReply := []byte{0, 0, 0, 3}
  880. if !bytes.Equal(conn.written, expectedReply) {
  881. t.Errorf("got unexpected data: %v", conn.written)
  882. }
  883. }
  884. func TestAuthSwitchOldPasswordNotAllowed(t *testing.T) {
  885. conn, mc := newRWMockConn(2)
  886. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  887. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  888. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  889. conn.maxReads = 1
  890. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  891. 84, 96, 101, 92, 123, 121, 107}
  892. plugin := "mysql_native_password"
  893. err := mc.handleAuthResult(authData, plugin)
  894. if err != ErrOldPassword {
  895. t.Errorf("expected ErrOldPassword, got %v", err)
  896. }
  897. }
  898. // Same to TestAuthSwitchOldPasswordNotAllowed, but use OldAuthSwitch request.
  899. func TestOldAuthSwitchNotAllowed(t *testing.T) {
  900. conn, mc := newRWMockConn(2)
  901. // OldAuthSwitch request
  902. conn.data = []byte{1, 0, 0, 2, 0xfe}
  903. conn.maxReads = 1
  904. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  905. 84, 96, 101, 92, 123, 121, 107}
  906. plugin := "mysql_native_password"
  907. err := mc.handleAuthResult(authData, plugin)
  908. if err != ErrOldPassword {
  909. t.Errorf("expected ErrOldPassword, got %v", err)
  910. }
  911. }
  912. func TestAuthSwitchOldPassword(t *testing.T) {
  913. conn, mc := newRWMockConn(2)
  914. mc.cfg.AllowOldPasswords = true
  915. mc.cfg.Passwd = "secret"
  916. // auth switch request
  917. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  918. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  919. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  920. // auth response
  921. conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
  922. conn.maxReads = 2
  923. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  924. 84, 96, 101, 92, 123, 121, 107}
  925. plugin := "mysql_native_password"
  926. if err := mc.handleAuthResult(authData, plugin); err != nil {
  927. t.Errorf("got error: %v", err)
  928. }
  929. expectedReply := []byte{9, 0, 0, 3, 86, 83, 83, 79, 74, 78, 65, 66, 0}
  930. if !bytes.Equal(conn.written, expectedReply) {
  931. t.Errorf("got unexpected data: %v", conn.written)
  932. }
  933. }
  934. // Same to TestAuthSwitchOldPassword, but use OldAuthSwitch request.
  935. func TestOldAuthSwitch(t *testing.T) {
  936. conn, mc := newRWMockConn(2)
  937. mc.cfg.AllowOldPasswords = true
  938. mc.cfg.Passwd = "secret"
  939. // OldAuthSwitch request
  940. conn.data = []byte{1, 0, 0, 2, 0xfe}
  941. // auth response
  942. conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
  943. conn.maxReads = 2
  944. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  945. 84, 96, 101, 92, 123, 121, 107}
  946. plugin := "mysql_native_password"
  947. if err := mc.handleAuthResult(authData, plugin); err != nil {
  948. t.Errorf("got error: %v", err)
  949. }
  950. expectedReply := []byte{9, 0, 0, 3, 86, 83, 83, 79, 74, 78, 65, 66, 0}
  951. if !bytes.Equal(conn.written, expectedReply) {
  952. t.Errorf("got unexpected data: %v", conn.written)
  953. }
  954. }
  955. func TestAuthSwitchOldPasswordEmpty(t *testing.T) {
  956. conn, mc := newRWMockConn(2)
  957. mc.cfg.AllowOldPasswords = true
  958. mc.cfg.Passwd = ""
  959. // auth switch request
  960. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  961. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  962. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  963. // auth response
  964. conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
  965. conn.maxReads = 2
  966. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  967. 84, 96, 101, 92, 123, 121, 107}
  968. plugin := "mysql_native_password"
  969. if err := mc.handleAuthResult(authData, plugin); err != nil {
  970. t.Errorf("got error: %v", err)
  971. }
  972. expectedReply := []byte{1, 0, 0, 3, 0}
  973. if !bytes.Equal(conn.written, expectedReply) {
  974. t.Errorf("got unexpected data: %v", conn.written)
  975. }
  976. }
  977. // Same to TestAuthSwitchOldPasswordEmpty, but use OldAuthSwitch request.
  978. func TestOldAuthSwitchPasswordEmpty(t *testing.T) {
  979. conn, mc := newRWMockConn(2)
  980. mc.cfg.AllowOldPasswords = true
  981. mc.cfg.Passwd = ""
  982. // OldAuthSwitch request.
  983. conn.data = []byte{1, 0, 0, 2, 0xfe}
  984. // auth response
  985. conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
  986. conn.maxReads = 2
  987. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  988. 84, 96, 101, 92, 123, 121, 107}
  989. plugin := "mysql_native_password"
  990. if err := mc.handleAuthResult(authData, plugin); err != nil {
  991. t.Errorf("got error: %v", err)
  992. }
  993. expectedReply := []byte{1, 0, 0, 3, 0}
  994. if !bytes.Equal(conn.written, expectedReply) {
  995. t.Errorf("got unexpected data: %v", conn.written)
  996. }
  997. }
  998. func TestAuthSwitchSHA256PasswordEmpty(t *testing.T) {
  999. conn, mc := newRWMockConn(2)
  1000. mc.cfg.Passwd = ""
  1001. // auth switch request
  1002. conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
  1003. 115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
  1004. 33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
  1005. conn.queuedReplies = [][]byte{
  1006. // OK
  1007. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  1008. }
  1009. conn.maxReads = 3
  1010. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  1011. 47, 43, 9, 41, 112, 67, 110}
  1012. plugin := "mysql_native_password"
  1013. if err := mc.handleAuthResult(authData, plugin); err != nil {
  1014. t.Errorf("got error: %v", err)
  1015. }
  1016. expectedReplyPrefix := []byte{
  1017. // 1. Packet: Empty Password
  1018. 1, 0, 0, 3, 0,
  1019. }
  1020. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  1021. t.Errorf("got unexpected data: %v", conn.written)
  1022. }
  1023. }
  1024. func TestAuthSwitchSHA256PasswordRSA(t *testing.T) {
  1025. conn, mc := newRWMockConn(2)
  1026. mc.cfg.Passwd = "secret"
  1027. // auth switch request
  1028. conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
  1029. 115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
  1030. 33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
  1031. conn.queuedReplies = [][]byte{
  1032. // Pub Key Response
  1033. append([]byte{byte(1 + len(testPubKey)), 1, 0, 4, 1}, testPubKey...),
  1034. // OK
  1035. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
  1036. }
  1037. conn.maxReads = 3
  1038. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  1039. 47, 43, 9, 41, 112, 67, 110}
  1040. plugin := "mysql_native_password"
  1041. if err := mc.handleAuthResult(authData, plugin); err != nil {
  1042. t.Errorf("got error: %v", err)
  1043. }
  1044. expectedReplyPrefix := []byte{
  1045. // 1. Packet: Pub Key Request
  1046. 1, 0, 0, 3, 1,
  1047. // 2. Packet: Encrypted Password
  1048. 0, 1, 0, 5, // [changing bytes]
  1049. }
  1050. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  1051. t.Errorf("got unexpected data: %v", conn.written)
  1052. }
  1053. }
  1054. func TestAuthSwitchSHA256PasswordRSAWithKey(t *testing.T) {
  1055. conn, mc := newRWMockConn(2)
  1056. mc.cfg.Passwd = "secret"
  1057. mc.cfg.pubKey = testPubKeyRSA
  1058. // auth switch request
  1059. conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
  1060. 115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
  1061. 33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
  1062. conn.queuedReplies = [][]byte{
  1063. // OK
  1064. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  1065. }
  1066. conn.maxReads = 2
  1067. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  1068. 47, 43, 9, 41, 112, 67, 110}
  1069. plugin := "mysql_native_password"
  1070. if err := mc.handleAuthResult(authData, plugin); err != nil {
  1071. t.Errorf("got error: %v", err)
  1072. }
  1073. expectedReplyPrefix := []byte{
  1074. // 1. Packet: Encrypted Password
  1075. 0, 1, 0, 3, // [changing bytes]
  1076. }
  1077. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  1078. t.Errorf("got unexpected data: %v", conn.written)
  1079. }
  1080. }
  1081. func TestAuthSwitchSHA256PasswordSecure(t *testing.T) {
  1082. conn, mc := newRWMockConn(2)
  1083. mc.cfg.Passwd = "secret"
  1084. // Hack to make the caching_sha2_password plugin believe that the connection
  1085. // is secure
  1086. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  1087. // auth switch request
  1088. conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
  1089. 115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
  1090. 33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
  1091. conn.queuedReplies = [][]byte{
  1092. // OK
  1093. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  1094. }
  1095. conn.maxReads = 2
  1096. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  1097. 47, 43, 9, 41, 112, 67, 110}
  1098. plugin := "mysql_native_password"
  1099. if err := mc.handleAuthResult(authData, plugin); err != nil {
  1100. t.Errorf("got error: %v", err)
  1101. }
  1102. expectedReplyPrefix := []byte{
  1103. // 1. Packet: Cleartext Password
  1104. 7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0,
  1105. }
  1106. if !bytes.Equal(conn.written, expectedReplyPrefix) {
  1107. t.Errorf("got unexpected data: %v", conn.written)
  1108. }
  1109. }