auth_test.go 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
  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, addNUL, err := mc.auth(authData, plugin)
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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, addNUL, err := mc.auth(authData, plugin)
  118. if err != nil {
  119. t.Fatal(err)
  120. }
  121. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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, addNUL, err := mc.auth(authData, plugin)
  154. if err != nil {
  155. t.Fatal(err)
  156. }
  157. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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, addNUL, err := mc.auth(authData, plugin)
  202. if err != nil {
  203. t.Fatal(err)
  204. }
  205. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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, addNUL, err := mc.auth(authData, plugin)
  247. if err != nil {
  248. t.Fatal(err)
  249. }
  250. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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, addNUL, err := mc.auth(authData, plugin)
  309. if err != nil {
  310. t.Fatal(err)
  311. }
  312. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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}
  322. if writtenAuthRespLen != 6 || !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, addNUL, err := mc.auth(authData, plugin)
  346. if err != nil {
  347. t.Fatal(err)
  348. }
  349. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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. if writtenAuthRespLen != 0 {
  359. t.Fatalf("unexpected written auth response (%d bytes): %v",
  360. 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, addNUL, err := mc.auth(authData, plugin)
  396. if err != nil {
  397. t.Fatal(err)
  398. }
  399. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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, addNUL, err := mc.auth(authData, plugin)
  433. if err != nil {
  434. t.Fatal(err)
  435. }
  436. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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, addNUL, err := mc.auth(authData, plugin)
  469. if err != nil {
  470. t.Fatal(err)
  471. }
  472. err = mc.writeHandshakeResponsePacket(authResp, addNUL, 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. if writtenAuthRespLen != 0 {
  482. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  483. }
  484. conn.written = nil
  485. // auth response (pub key response)
  486. conn.data = append([]byte{byte(1 + len(testPubKey)), 1, 0, 2, 1}, testPubKey...)
  487. conn.queuedReplies = [][]byte{
  488. // OK
  489. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  490. }
  491. conn.maxReads = 2
  492. // Handle response to auth packet
  493. if err := mc.handleAuthResult(authData, plugin); err != nil {
  494. t.Errorf("got error: %v", err)
  495. }
  496. if !bytes.HasPrefix(conn.written, []byte{0, 1, 0, 3}) {
  497. t.Errorf("unexpected written data: %v", conn.written)
  498. }
  499. }
  500. func TestAuthFastSHA256PasswordRSA(t *testing.T) {
  501. conn, mc := newRWMockConn(1)
  502. mc.cfg.User = "root"
  503. mc.cfg.Passwd = "secret"
  504. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  505. 62, 94, 83, 80, 52, 85}
  506. plugin := "sha256_password"
  507. // Send Client Authentication Packet
  508. authResp, addNUL, err := mc.auth(authData, plugin)
  509. if err != nil {
  510. t.Fatal(err)
  511. }
  512. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  513. if err != nil {
  514. t.Fatal(err)
  515. }
  516. // check written auth response
  517. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  518. authRespEnd := authRespStart + 1 + len(authResp)
  519. writtenAuthRespLen := conn.written[authRespStart]
  520. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  521. expectedAuthResp := []byte{1}
  522. if writtenAuthRespLen != 1 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  523. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  524. }
  525. conn.written = nil
  526. // auth response (pub key response)
  527. conn.data = append([]byte{byte(1 + len(testPubKey)), 1, 0, 2, 1}, testPubKey...)
  528. conn.queuedReplies = [][]byte{
  529. // OK
  530. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  531. }
  532. conn.maxReads = 2
  533. // Handle response to auth packet
  534. if err := mc.handleAuthResult(authData, plugin); err != nil {
  535. t.Errorf("got error: %v", err)
  536. }
  537. if !bytes.HasPrefix(conn.written, []byte{0, 1, 0, 3}) {
  538. t.Errorf("unexpected written data: %v", conn.written)
  539. }
  540. }
  541. func TestAuthFastSHA256PasswordRSAWithKey(t *testing.T) {
  542. conn, mc := newRWMockConn(1)
  543. mc.cfg.User = "root"
  544. mc.cfg.Passwd = "secret"
  545. mc.cfg.pubKey = testPubKeyRSA
  546. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  547. 62, 94, 83, 80, 52, 85}
  548. plugin := "sha256_password"
  549. // Send Client Authentication Packet
  550. authResp, addNUL, err := mc.auth(authData, plugin)
  551. if err != nil {
  552. t.Fatal(err)
  553. }
  554. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  555. if err != nil {
  556. t.Fatal(err)
  557. }
  558. // auth response (OK)
  559. conn.data = []byte{7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0}
  560. conn.maxReads = 1
  561. // Handle response to auth packet
  562. if err := mc.handleAuthResult(authData, plugin); err != nil {
  563. t.Errorf("got error: %v", err)
  564. }
  565. }
  566. func TestAuthFastSHA256PasswordSecure(t *testing.T) {
  567. conn, mc := newRWMockConn(1)
  568. mc.cfg.User = "root"
  569. mc.cfg.Passwd = "secret"
  570. // hack to make the caching_sha2_password plugin believe that the connection
  571. // is secure
  572. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  573. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  574. 62, 94, 83, 80, 52, 85}
  575. plugin := "sha256_password"
  576. // send Client Authentication Packet
  577. authResp, addNUL, err := mc.auth(authData, plugin)
  578. if err != nil {
  579. t.Fatal(err)
  580. }
  581. // unset TLS config to prevent the actual establishment of a TLS wrapper
  582. mc.cfg.tls = nil
  583. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  584. if err != nil {
  585. t.Fatal(err)
  586. }
  587. // check written auth response
  588. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  589. authRespEnd := authRespStart + 1 + len(authResp) + 1
  590. writtenAuthRespLen := conn.written[authRespStart]
  591. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  592. expectedAuthResp := []byte{115, 101, 99, 114, 101, 116, 0}
  593. if writtenAuthRespLen != 6 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  594. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  595. }
  596. conn.written = nil
  597. // auth response (OK)
  598. conn.data = []byte{7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0}
  599. conn.maxReads = 1
  600. // Handle response to auth packet
  601. if err := mc.handleAuthResult(authData, plugin); err != nil {
  602. t.Errorf("got error: %v", err)
  603. }
  604. if !bytes.Equal(conn.written, []byte{}) {
  605. t.Errorf("unexpected written data: %v", conn.written)
  606. }
  607. }
  608. func TestAuthSwitchCachingSHA256PasswordCached(t *testing.T) {
  609. conn, mc := newRWMockConn(2)
  610. mc.cfg.Passwd = "secret"
  611. // auth switch request
  612. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  613. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  614. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  615. 50, 0}
  616. // auth response
  617. conn.queuedReplies = [][]byte{
  618. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}, // OK
  619. }
  620. conn.maxReads = 3
  621. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  622. 47, 43, 9, 41, 112, 67, 110}
  623. plugin := "mysql_native_password"
  624. if err := mc.handleAuthResult(authData, plugin); err != nil {
  625. t.Errorf("got error: %v", err)
  626. }
  627. expectedReply := []byte{
  628. // 1. Packet: Hash
  629. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  630. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  631. 153, 9, 130,
  632. }
  633. if !bytes.Equal(conn.written, expectedReply) {
  634. t.Errorf("got unexpected data: %v", conn.written)
  635. }
  636. }
  637. func TestAuthSwitchCachingSHA256PasswordEmpty(t *testing.T) {
  638. conn, mc := newRWMockConn(2)
  639. mc.cfg.Passwd = ""
  640. // auth switch request
  641. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  642. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  643. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  644. 50, 0}
  645. // auth response
  646. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  647. conn.maxReads = 2
  648. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  649. 47, 43, 9, 41, 112, 67, 110}
  650. plugin := "mysql_native_password"
  651. if err := mc.handleAuthResult(authData, plugin); err != nil {
  652. t.Errorf("got error: %v", err)
  653. }
  654. expectedReply := []byte{1, 0, 0, 3, 0}
  655. if !bytes.Equal(conn.written, expectedReply) {
  656. t.Errorf("got unexpected data: %v", conn.written)
  657. }
  658. }
  659. func TestAuthSwitchCachingSHA256PasswordFullRSA(t *testing.T) {
  660. conn, mc := newRWMockConn(2)
  661. mc.cfg.Passwd = "secret"
  662. // auth switch request
  663. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  664. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  665. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  666. 50, 0}
  667. conn.queuedReplies = [][]byte{
  668. // Perform Full Authentication
  669. {2, 0, 0, 4, 1, 4},
  670. // Pub Key Response
  671. append([]byte{byte(1 + len(testPubKey)), 1, 0, 6, 1}, testPubKey...),
  672. // OK
  673. {7, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0},
  674. }
  675. conn.maxReads = 4
  676. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  677. 47, 43, 9, 41, 112, 67, 110}
  678. plugin := "mysql_native_password"
  679. if err := mc.handleAuthResult(authData, plugin); err != nil {
  680. t.Errorf("got error: %v", err)
  681. }
  682. expectedReplyPrefix := []byte{
  683. // 1. Packet: Hash
  684. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  685. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  686. 153, 9, 130,
  687. // 2. Packet: Pub Key Request
  688. 1, 0, 0, 5, 2,
  689. // 3. Packet: Encrypted Password
  690. 0, 1, 0, 7, // [changing bytes]
  691. }
  692. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  693. t.Errorf("got unexpected data: %v", conn.written)
  694. }
  695. }
  696. func TestAuthSwitchCachingSHA256PasswordFullRSAWithKey(t *testing.T) {
  697. conn, mc := newRWMockConn(2)
  698. mc.cfg.Passwd = "secret"
  699. mc.cfg.pubKey = testPubKeyRSA
  700. // auth switch request
  701. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  702. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  703. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  704. 50, 0}
  705. conn.queuedReplies = [][]byte{
  706. // Perform Full Authentication
  707. {2, 0, 0, 4, 1, 4},
  708. // OK
  709. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
  710. }
  711. conn.maxReads = 3
  712. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  713. 47, 43, 9, 41, 112, 67, 110}
  714. plugin := "mysql_native_password"
  715. if err := mc.handleAuthResult(authData, plugin); err != nil {
  716. t.Errorf("got error: %v", err)
  717. }
  718. expectedReplyPrefix := []byte{
  719. // 1. Packet: Hash
  720. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  721. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  722. 153, 9, 130,
  723. // 2. Packet: Encrypted Password
  724. 0, 1, 0, 5, // [changing bytes]
  725. }
  726. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  727. t.Errorf("got unexpected data: %v", conn.written)
  728. }
  729. }
  730. func TestAuthSwitchCachingSHA256PasswordFullSecure(t *testing.T) {
  731. conn, mc := newRWMockConn(2)
  732. mc.cfg.Passwd = "secret"
  733. // Hack to make the caching_sha2_password plugin believe that the connection
  734. // is secure
  735. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  736. // auth switch request
  737. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  738. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  739. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  740. 50, 0}
  741. // auth response
  742. conn.queuedReplies = [][]byte{
  743. {2, 0, 0, 4, 1, 4}, // Perform Full Authentication
  744. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0}, // OK
  745. }
  746. conn.maxReads = 3
  747. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  748. 47, 43, 9, 41, 112, 67, 110}
  749. plugin := "mysql_native_password"
  750. if err := mc.handleAuthResult(authData, plugin); err != nil {
  751. t.Errorf("got error: %v", err)
  752. }
  753. expectedReply := []byte{
  754. // 1. Packet: Hash
  755. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  756. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  757. 153, 9, 130,
  758. // 2. Packet: Cleartext password
  759. 7, 0, 0, 5, 115, 101, 99, 114, 101, 116, 0,
  760. }
  761. if !bytes.Equal(conn.written, expectedReply) {
  762. t.Errorf("got unexpected data: %v", conn.written)
  763. }
  764. }
  765. func TestAuthSwitchCleartextPasswordNotAllowed(t *testing.T) {
  766. conn, mc := newRWMockConn(2)
  767. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  768. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  769. conn.maxReads = 1
  770. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  771. 47, 43, 9, 41, 112, 67, 110}
  772. plugin := "mysql_native_password"
  773. err := mc.handleAuthResult(authData, plugin)
  774. if err != ErrCleartextPassword {
  775. t.Errorf("expected ErrCleartextPassword, got %v", err)
  776. }
  777. }
  778. func TestAuthSwitchCleartextPassword(t *testing.T) {
  779. conn, mc := newRWMockConn(2)
  780. mc.cfg.AllowCleartextPasswords = true
  781. mc.cfg.Passwd = "secret"
  782. // auth switch request
  783. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  784. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  785. // auth response
  786. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  787. conn.maxReads = 2
  788. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  789. 47, 43, 9, 41, 112, 67, 110}
  790. plugin := "mysql_native_password"
  791. if err := mc.handleAuthResult(authData, plugin); err != nil {
  792. t.Errorf("got error: %v", err)
  793. }
  794. expectedReply := []byte{7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0}
  795. if !bytes.Equal(conn.written, expectedReply) {
  796. t.Errorf("got unexpected data: %v", conn.written)
  797. }
  798. }
  799. func TestAuthSwitchCleartextPasswordEmpty(t *testing.T) {
  800. conn, mc := newRWMockConn(2)
  801. mc.cfg.AllowCleartextPasswords = true
  802. mc.cfg.Passwd = ""
  803. // auth switch request
  804. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  805. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  806. // auth response
  807. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  808. conn.maxReads = 2
  809. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  810. 47, 43, 9, 41, 112, 67, 110}
  811. plugin := "mysql_native_password"
  812. if err := mc.handleAuthResult(authData, plugin); err != nil {
  813. t.Errorf("got error: %v", err)
  814. }
  815. expectedReply := []byte{1, 0, 0, 3, 0}
  816. if !bytes.Equal(conn.written, expectedReply) {
  817. t.Errorf("got unexpected data: %v", conn.written)
  818. }
  819. }
  820. func TestAuthSwitchNativePasswordNotAllowed(t *testing.T) {
  821. conn, mc := newRWMockConn(2)
  822. mc.cfg.AllowNativePasswords = false
  823. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  824. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  825. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  826. 31, 0}
  827. conn.maxReads = 1
  828. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  829. 48, 31, 89, 39, 55, 31}
  830. plugin := "caching_sha2_password"
  831. err := mc.handleAuthResult(authData, plugin)
  832. if err != ErrNativePassword {
  833. t.Errorf("expected ErrNativePassword, got %v", err)
  834. }
  835. }
  836. func TestAuthSwitchNativePassword(t *testing.T) {
  837. conn, mc := newRWMockConn(2)
  838. mc.cfg.AllowNativePasswords = true
  839. mc.cfg.Passwd = "secret"
  840. // auth switch request
  841. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  842. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  843. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  844. 31, 0}
  845. // auth response
  846. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  847. conn.maxReads = 2
  848. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  849. 48, 31, 89, 39, 55, 31}
  850. plugin := "caching_sha2_password"
  851. if err := mc.handleAuthResult(authData, plugin); err != nil {
  852. t.Errorf("got error: %v", err)
  853. }
  854. expectedReply := []byte{20, 0, 0, 3, 202, 41, 195, 164, 34, 226, 49, 103,
  855. 21, 211, 167, 199, 227, 116, 8, 48, 57, 71, 149, 146}
  856. if !bytes.Equal(conn.written, expectedReply) {
  857. t.Errorf("got unexpected data: %v", conn.written)
  858. }
  859. }
  860. func TestAuthSwitchNativePasswordEmpty(t *testing.T) {
  861. conn, mc := newRWMockConn(2)
  862. mc.cfg.AllowNativePasswords = true
  863. mc.cfg.Passwd = ""
  864. // auth switch request
  865. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  866. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  867. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  868. 31, 0}
  869. // auth response
  870. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  871. conn.maxReads = 2
  872. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  873. 48, 31, 89, 39, 55, 31}
  874. plugin := "caching_sha2_password"
  875. if err := mc.handleAuthResult(authData, plugin); err != nil {
  876. t.Errorf("got error: %v", err)
  877. }
  878. expectedReply := []byte{0, 0, 0, 3}
  879. if !bytes.Equal(conn.written, expectedReply) {
  880. t.Errorf("got unexpected data: %v", conn.written)
  881. }
  882. }
  883. func TestAuthSwitchOldPasswordNotAllowed(t *testing.T) {
  884. conn, mc := newRWMockConn(2)
  885. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  886. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  887. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  888. conn.maxReads = 1
  889. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  890. 84, 96, 101, 92, 123, 121, 107}
  891. plugin := "mysql_native_password"
  892. err := mc.handleAuthResult(authData, plugin)
  893. if err != ErrOldPassword {
  894. t.Errorf("expected ErrOldPassword, got %v", err)
  895. }
  896. }
  897. func TestAuthSwitchOldPassword(t *testing.T) {
  898. conn, mc := newRWMockConn(2)
  899. mc.cfg.AllowOldPasswords = true
  900. mc.cfg.Passwd = "secret"
  901. // auth switch request
  902. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  903. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  904. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  905. // auth response
  906. conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
  907. conn.maxReads = 2
  908. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  909. 84, 96, 101, 92, 123, 121, 107}
  910. plugin := "mysql_native_password"
  911. if err := mc.handleAuthResult(authData, plugin); err != nil {
  912. t.Errorf("got error: %v", err)
  913. }
  914. expectedReply := []byte{9, 0, 0, 3, 86, 83, 83, 79, 74, 78, 65, 66, 0}
  915. if !bytes.Equal(conn.written, expectedReply) {
  916. t.Errorf("got unexpected data: %v", conn.written)
  917. }
  918. }
  919. func TestAuthSwitchOldPasswordEmpty(t *testing.T) {
  920. conn, mc := newRWMockConn(2)
  921. mc.cfg.AllowOldPasswords = true
  922. mc.cfg.Passwd = ""
  923. // auth switch request
  924. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  925. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  926. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  927. // auth response
  928. conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
  929. conn.maxReads = 2
  930. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  931. 84, 96, 101, 92, 123, 121, 107}
  932. plugin := "mysql_native_password"
  933. if err := mc.handleAuthResult(authData, plugin); err != nil {
  934. t.Errorf("got error: %v", err)
  935. }
  936. expectedReply := []byte{1, 0, 0, 3, 0}
  937. if !bytes.Equal(conn.written, expectedReply) {
  938. t.Errorf("got unexpected data: %v", conn.written)
  939. }
  940. }
  941. func TestAuthSwitchSHA256PasswordEmpty(t *testing.T) {
  942. conn, mc := newRWMockConn(2)
  943. mc.cfg.Passwd = ""
  944. // auth switch request
  945. conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
  946. 115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
  947. 33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
  948. conn.queuedReplies = [][]byte{
  949. // OK
  950. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  951. }
  952. conn.maxReads = 3
  953. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  954. 47, 43, 9, 41, 112, 67, 110}
  955. plugin := "mysql_native_password"
  956. if err := mc.handleAuthResult(authData, plugin); err != nil {
  957. t.Errorf("got error: %v", err)
  958. }
  959. expectedReplyPrefix := []byte{
  960. // 1. Packet: Empty Password
  961. 1, 0, 0, 3, 0,
  962. }
  963. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  964. t.Errorf("got unexpected data: %v", conn.written)
  965. }
  966. }
  967. func TestAuthSwitchSHA256PasswordRSA(t *testing.T) {
  968. conn, mc := newRWMockConn(2)
  969. mc.cfg.Passwd = "secret"
  970. // auth switch request
  971. conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
  972. 115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
  973. 33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
  974. conn.queuedReplies = [][]byte{
  975. // Pub Key Response
  976. append([]byte{byte(1 + len(testPubKey)), 1, 0, 4, 1}, testPubKey...),
  977. // OK
  978. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
  979. }
  980. conn.maxReads = 3
  981. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  982. 47, 43, 9, 41, 112, 67, 110}
  983. plugin := "mysql_native_password"
  984. if err := mc.handleAuthResult(authData, plugin); err != nil {
  985. t.Errorf("got error: %v", err)
  986. }
  987. expectedReplyPrefix := []byte{
  988. // 1. Packet: Pub Key Request
  989. 1, 0, 0, 3, 1,
  990. // 2. Packet: Encrypted Password
  991. 0, 1, 0, 5, // [changing bytes]
  992. }
  993. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  994. t.Errorf("got unexpected data: %v", conn.written)
  995. }
  996. }
  997. func TestAuthSwitchSHA256PasswordRSAWithKey(t *testing.T) {
  998. conn, mc := newRWMockConn(2)
  999. mc.cfg.Passwd = "secret"
  1000. mc.cfg.pubKey = testPubKeyRSA
  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 = 2
  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: Encrypted Password
  1018. 0, 1, 0, 3, // [changing bytes]
  1019. }
  1020. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  1021. t.Errorf("got unexpected data: %v", conn.written)
  1022. }
  1023. }
  1024. func TestAuthSwitchSHA256PasswordSecure(t *testing.T) {
  1025. conn, mc := newRWMockConn(2)
  1026. mc.cfg.Passwd = "secret"
  1027. // Hack to make the caching_sha2_password plugin believe that the connection
  1028. // is secure
  1029. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  1030. // auth switch request
  1031. conn.data = []byte{38, 0, 0, 2, 254, 115, 104, 97, 50, 53, 54, 95, 112, 97,
  1032. 115, 115, 119, 111, 114, 100, 0, 78, 82, 62, 40, 100, 1, 59, 31, 44, 69,
  1033. 33, 112, 8, 81, 51, 96, 65, 82, 16, 114, 0}
  1034. conn.queuedReplies = [][]byte{
  1035. // OK
  1036. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  1037. }
  1038. conn.maxReads = 2
  1039. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  1040. 47, 43, 9, 41, 112, 67, 110}
  1041. plugin := "mysql_native_password"
  1042. if err := mc.handleAuthResult(authData, plugin); err != nil {
  1043. t.Errorf("got error: %v", err)
  1044. }
  1045. expectedReplyPrefix := []byte{
  1046. // 1. Packet: Cleartext Password
  1047. 7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0,
  1048. }
  1049. if !bytes.Equal(conn.written, expectedReplyPrefix) {
  1050. t.Errorf("got unexpected data: %v", conn.written)
  1051. }
  1052. }