auth_test.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853
  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/tls"
  12. "fmt"
  13. "testing"
  14. )
  15. var serverPubKey = []byte{1, 45, 45, 45, 45, 45, 66, 69, 71, 73, 78, 32, 80, 85,
  16. 66, 76, 73, 67, 32, 75, 69, 89, 45, 45, 45, 45, 45, 10, 77, 73, 73, 66, 73,
  17. 106, 65, 78, 66, 103, 107, 113, 104, 107, 105, 71, 57, 119, 48, 66, 65, 81,
  18. 69, 70, 65, 65, 79, 67, 65, 81, 56, 65, 77, 73, 73, 66, 67, 103, 75, 67, 65,
  19. 81, 69, 65, 51, 72, 115, 120, 83, 53, 80, 47, 72, 97, 88, 80, 118, 109, 51,
  20. 109, 50, 65, 68, 110, 10, 98, 117, 54, 71, 81, 102, 112, 83, 71, 111, 55,
  21. 104, 50, 103, 104, 56, 49, 112, 109, 97, 120, 107, 67, 110, 68, 67, 119,
  22. 102, 54, 109, 109, 101, 72, 55, 76, 75, 104, 115, 110, 89, 110, 78, 52, 81,
  23. 48, 99, 122, 49, 81, 69, 47, 98, 104, 100, 80, 117, 54, 106, 115, 43, 86,
  24. 97, 89, 52, 10, 67, 99, 77, 117, 98, 80, 78, 49, 103, 79, 75, 97, 89, 118,
  25. 78, 99, 103, 69, 87, 112, 116, 73, 67, 105, 50, 88, 84, 116, 116, 66, 55,
  26. 117, 104, 43, 118, 67, 77, 106, 76, 118, 106, 65, 77, 100, 54, 47, 68, 109,
  27. 120, 100, 98, 85, 66, 48, 122, 80, 71, 113, 68, 79, 103, 105, 76, 68, 10,
  28. 75, 82, 79, 79, 53, 113, 100, 55, 115, 104, 98, 55, 49, 82, 47, 88, 74, 69,
  29. 70, 118, 76, 120, 71, 88, 69, 70, 48, 90, 116, 104, 72, 101, 78, 111, 57,
  30. 102, 69, 118, 120, 70, 81, 111, 109, 98, 49, 107, 90, 57, 74, 56, 110, 66,
  31. 119, 116, 101, 53, 83, 70, 53, 89, 108, 113, 86, 50, 10, 66, 66, 53, 113,
  32. 108, 97, 122, 43, 51, 81, 83, 78, 118, 109, 67, 49, 105, 87, 102, 108, 106,
  33. 88, 98, 89, 53, 107, 51, 47, 97, 54, 109, 107, 77, 47, 76, 97, 87, 104, 97,
  34. 117, 78, 53, 80, 82, 51, 115, 67, 120, 53, 85, 117, 49, 77, 102, 100, 115,
  35. 86, 105, 107, 53, 102, 88, 77, 77, 10, 100, 120, 107, 102, 70, 43, 88, 51,
  36. 99, 104, 107, 65, 110, 119, 73, 51, 70, 117, 119, 119, 50, 87, 71, 109, 87,
  37. 79, 71, 98, 75, 116, 109, 73, 101, 85, 109, 51, 98, 73, 82, 109, 100, 70,
  38. 85, 113, 97, 108, 81, 105, 70, 104, 113, 101, 90, 50, 105, 107, 106, 104,
  39. 103, 86, 73, 57, 112, 76, 10, 119, 81, 73, 68, 65, 81, 65, 66, 10, 45, 45,
  40. 45, 45, 45, 69, 78, 68, 32, 80, 85, 66, 76, 73, 67, 32, 75, 69, 89, 45, 45,
  41. 45, 45, 45, 10}
  42. func TestScrambleOldPass(t *testing.T) {
  43. scramble := []byte{9, 8, 7, 6, 5, 4, 3, 2}
  44. vectors := []struct {
  45. pass string
  46. out string
  47. }{
  48. {" pass", "47575c5a435b4251"},
  49. {"pass ", "47575c5a435b4251"},
  50. {"123\t456", "575c47505b5b5559"},
  51. {"C0mpl!ca ted#PASS123", "5d5d554849584a45"},
  52. }
  53. for _, tuple := range vectors {
  54. ours := scrambleOldPassword(scramble, tuple.pass)
  55. if tuple.out != fmt.Sprintf("%x", ours) {
  56. t.Errorf("Failed old password %q", tuple.pass)
  57. }
  58. }
  59. }
  60. func TestScrambleSHA256Pass(t *testing.T) {
  61. scramble := []byte{10, 47, 74, 111, 75, 73, 34, 48, 88, 76, 114, 74, 37, 13, 3, 80, 82, 2, 23, 21}
  62. vectors := []struct {
  63. pass string
  64. out string
  65. }{
  66. {"secret", "f490e76f66d9d86665ce54d98c78d0acfe2fb0b08b423da807144873d30b312c"},
  67. {"secret2", "abc3934a012cf342e876071c8ee202de51785b430258a7a0138bc79c4d800bc6"},
  68. }
  69. for _, tuple := range vectors {
  70. ours := scrambleSHA256Password(scramble, tuple.pass)
  71. if tuple.out != fmt.Sprintf("%x", ours) {
  72. t.Errorf("Failed SHA256 password %q", tuple.pass)
  73. }
  74. }
  75. }
  76. func TestAuthFastCachingSHA256PasswordCached(t *testing.T) {
  77. conn, mc := newRWMockConn(1)
  78. mc.cfg.User = "root"
  79. mc.cfg.Passwd = "secret"
  80. authData := []byte{90, 105, 74, 126, 30, 48, 37, 56, 3, 23, 115, 127, 69,
  81. 22, 41, 84, 32, 123, 43, 118}
  82. plugin := "caching_sha2_password"
  83. // Send Client Authentication Packet
  84. authResp, addNUL, err := mc.auth(authData, plugin)
  85. if err != nil {
  86. t.Fatal(err)
  87. }
  88. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  89. if err != nil {
  90. t.Fatal(err)
  91. }
  92. // check written auth response
  93. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  94. authRespEnd := authRespStart + 1 + len(authResp)
  95. writtenAuthRespLen := conn.written[authRespStart]
  96. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  97. expectedAuthResp := []byte{102, 32, 5, 35, 143, 161, 140, 241, 171, 232, 56,
  98. 139, 43, 14, 107, 196, 249, 170, 147, 60, 220, 204, 120, 178, 214, 15,
  99. 184, 150, 26, 61, 57, 235}
  100. if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  101. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  102. }
  103. conn.written = nil
  104. // auth response
  105. conn.data = []byte{
  106. 2, 0, 0, 2, 1, 3, // Fast Auth Success
  107. 7, 0, 0, 3, 0, 0, 0, 2, 0, 0, 0, // OK
  108. }
  109. conn.maxReads = 1
  110. // Handle response to auth packet
  111. if err := mc.handleAuthResult(authData, plugin); err != nil {
  112. t.Errorf("got error: %v", err)
  113. }
  114. }
  115. func TestAuthFastCachingSHA256PasswordEmpty(t *testing.T) {
  116. conn, mc := newRWMockConn(1)
  117. mc.cfg.User = "root"
  118. mc.cfg.Passwd = ""
  119. authData := []byte{90, 105, 74, 126, 30, 48, 37, 56, 3, 23, 115, 127, 69,
  120. 22, 41, 84, 32, 123, 43, 118}
  121. plugin := "caching_sha2_password"
  122. // Send Client Authentication Packet
  123. authResp, addNUL, err := mc.auth(authData, plugin)
  124. if err != nil {
  125. t.Fatal(err)
  126. }
  127. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  128. if err != nil {
  129. t.Fatal(err)
  130. }
  131. // check written auth response
  132. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  133. authRespEnd := authRespStart + 1 + len(authResp)
  134. writtenAuthRespLen := conn.written[authRespStart]
  135. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  136. if writtenAuthRespLen != 0 {
  137. t.Fatalf("unexpected written auth response (%d bytes): %v",
  138. writtenAuthRespLen, writtenAuthResp)
  139. }
  140. conn.written = nil
  141. // auth response
  142. conn.data = []byte{
  143. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  144. }
  145. conn.maxReads = 1
  146. // Handle response to auth packet
  147. if err := mc.handleAuthResult(authData, plugin); err != nil {
  148. t.Errorf("got error: %v", err)
  149. }
  150. }
  151. func TestAuthFastCachingSHA256PasswordFullRSA(t *testing.T) {
  152. conn, mc := newRWMockConn(1)
  153. mc.cfg.User = "root"
  154. mc.cfg.Passwd = "secret"
  155. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  156. 62, 94, 83, 80, 52, 85}
  157. plugin := "caching_sha2_password"
  158. // Send Client Authentication Packet
  159. authResp, addNUL, err := mc.auth(authData, plugin)
  160. if err != nil {
  161. t.Fatal(err)
  162. }
  163. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  164. if err != nil {
  165. t.Fatal(err)
  166. }
  167. // check written auth response
  168. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  169. authRespEnd := authRespStart + 1 + len(authResp)
  170. writtenAuthRespLen := conn.written[authRespStart]
  171. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  172. expectedAuthResp := []byte{171, 201, 138, 146, 89, 159, 11, 170, 0, 67, 165,
  173. 49, 175, 94, 218, 68, 177, 109, 110, 86, 34, 33, 44, 190, 67, 240, 70,
  174. 110, 40, 139, 124, 41}
  175. if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  176. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  177. }
  178. conn.written = nil
  179. // auth response
  180. conn.data = []byte{
  181. 2, 0, 0, 2, 1, 4, // Perform Full Authentication
  182. }
  183. conn.queuedReplies = [][]byte{
  184. // pub key response
  185. append([]byte{byte(len(serverPubKey)), 1, 0, 4}, serverPubKey...),
  186. // OK
  187. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0},
  188. }
  189. conn.maxReads = 3
  190. // Handle response to auth packet
  191. if err := mc.handleAuthResult(authData, plugin); err != nil {
  192. t.Errorf("got error: %v", err)
  193. }
  194. if !bytes.HasPrefix(conn.written, []byte{1, 0, 0, 3, 2, 0, 1, 0, 5}) {
  195. t.Errorf("unexpected written data: %v", conn.written)
  196. }
  197. }
  198. func TestAuthFastCachingSHA256PasswordFullSecure(t *testing.T) {
  199. conn, mc := newRWMockConn(1)
  200. mc.cfg.User = "root"
  201. mc.cfg.Passwd = "secret"
  202. authData := []byte{6, 81, 96, 114, 14, 42, 50, 30, 76, 47, 1, 95, 126, 81,
  203. 62, 94, 83, 80, 52, 85}
  204. plugin := "caching_sha2_password"
  205. // Send Client Authentication Packet
  206. authResp, addNUL, err := mc.auth(authData, plugin)
  207. if err != nil {
  208. t.Fatal(err)
  209. }
  210. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  211. if err != nil {
  212. t.Fatal(err)
  213. }
  214. // Hack to make the caching_sha2_password plugin believe that the connection
  215. // is secure
  216. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  217. // check written auth response
  218. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  219. authRespEnd := authRespStart + 1 + len(authResp)
  220. writtenAuthRespLen := conn.written[authRespStart]
  221. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  222. expectedAuthResp := []byte{171, 201, 138, 146, 89, 159, 11, 170, 0, 67, 165,
  223. 49, 175, 94, 218, 68, 177, 109, 110, 86, 34, 33, 44, 190, 67, 240, 70,
  224. 110, 40, 139, 124, 41}
  225. if writtenAuthRespLen != 32 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  226. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  227. }
  228. conn.written = nil
  229. // auth response
  230. conn.data = []byte{
  231. 2, 0, 0, 2, 1, 4, // Perform Full Authentication
  232. }
  233. conn.queuedReplies = [][]byte{
  234. // OK
  235. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0},
  236. }
  237. conn.maxReads = 3
  238. // Handle response to auth packet
  239. if err := mc.handleAuthResult(authData, plugin); err != nil {
  240. t.Errorf("got error: %v", err)
  241. }
  242. if !bytes.Equal(conn.written, []byte{7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0}) {
  243. t.Errorf("unexpected written data: %v", conn.written)
  244. }
  245. }
  246. func TestAuthFastCleartextPasswordNotAllowed(t *testing.T) {
  247. _, mc := newRWMockConn(1)
  248. mc.cfg.User = "root"
  249. mc.cfg.Passwd = "secret"
  250. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  251. 103, 26, 95, 81, 17, 24, 21}
  252. plugin := "mysql_clear_password"
  253. // Send Client Authentication Packet
  254. _, _, err := mc.auth(authData, plugin)
  255. if err != ErrCleartextPassword {
  256. t.Errorf("expected ErrCleartextPassword, got %v", err)
  257. }
  258. }
  259. func TestAuthFastCleartextPassword(t *testing.T) {
  260. conn, mc := newRWMockConn(1)
  261. mc.cfg.User = "root"
  262. mc.cfg.Passwd = "secret"
  263. mc.cfg.AllowCleartextPasswords = true
  264. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  265. 103, 26, 95, 81, 17, 24, 21}
  266. plugin := "mysql_clear_password"
  267. // Send Client Authentication Packet
  268. authResp, addNUL, err := mc.auth(authData, plugin)
  269. if err != nil {
  270. t.Fatal(err)
  271. }
  272. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  273. if err != nil {
  274. t.Fatal(err)
  275. }
  276. // check written auth response
  277. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  278. authRespEnd := authRespStart + 1 + len(authResp)
  279. writtenAuthRespLen := conn.written[authRespStart]
  280. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  281. expectedAuthResp := []byte{115, 101, 99, 114, 101, 116}
  282. if writtenAuthRespLen != 6 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  283. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  284. }
  285. conn.written = nil
  286. // auth response
  287. conn.data = []byte{
  288. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  289. }
  290. conn.maxReads = 1
  291. // Handle response to auth packet
  292. if err := mc.handleAuthResult(authData, plugin); err != nil {
  293. t.Errorf("got error: %v", err)
  294. }
  295. }
  296. func TestAuthFastCleartextPasswordEmpty(t *testing.T) {
  297. conn, mc := newRWMockConn(1)
  298. mc.cfg.User = "root"
  299. mc.cfg.Passwd = ""
  300. mc.cfg.AllowCleartextPasswords = true
  301. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  302. 103, 26, 95, 81, 17, 24, 21}
  303. plugin := "mysql_clear_password"
  304. // Send Client Authentication Packet
  305. authResp, addNUL, err := mc.auth(authData, plugin)
  306. if err != nil {
  307. t.Fatal(err)
  308. }
  309. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  310. if err != nil {
  311. t.Fatal(err)
  312. }
  313. // check written auth response
  314. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  315. authRespEnd := authRespStart + 1 + len(authResp)
  316. writtenAuthRespLen := conn.written[authRespStart]
  317. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  318. if writtenAuthRespLen != 0 {
  319. t.Fatalf("unexpected written auth response (%d bytes): %v",
  320. writtenAuthRespLen, writtenAuthResp)
  321. }
  322. conn.written = nil
  323. // auth response
  324. conn.data = []byte{
  325. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  326. }
  327. conn.maxReads = 1
  328. // Handle response to auth packet
  329. if err := mc.handleAuthResult(authData, plugin); err != nil {
  330. t.Errorf("got error: %v", err)
  331. }
  332. }
  333. func TestAuthFastNativePasswordNotAllowed(t *testing.T) {
  334. _, mc := newRWMockConn(1)
  335. mc.cfg.User = "root"
  336. mc.cfg.Passwd = "secret"
  337. mc.cfg.AllowNativePasswords = false
  338. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  339. 103, 26, 95, 81, 17, 24, 21}
  340. plugin := "mysql_native_password"
  341. // Send Client Authentication Packet
  342. _, _, err := mc.auth(authData, plugin)
  343. if err != ErrNativePassword {
  344. t.Errorf("expected ErrNativePassword, got %v", err)
  345. }
  346. }
  347. func TestAuthFastNativePassword(t *testing.T) {
  348. conn, mc := newRWMockConn(1)
  349. mc.cfg.User = "root"
  350. mc.cfg.Passwd = "secret"
  351. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  352. 103, 26, 95, 81, 17, 24, 21}
  353. plugin := "mysql_native_password"
  354. // Send Client Authentication Packet
  355. authResp, addNUL, err := mc.auth(authData, plugin)
  356. if err != nil {
  357. t.Fatal(err)
  358. }
  359. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  360. if err != nil {
  361. t.Fatal(err)
  362. }
  363. // check written auth response
  364. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  365. authRespEnd := authRespStart + 1 + len(authResp)
  366. writtenAuthRespLen := conn.written[authRespStart]
  367. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  368. expectedAuthResp := []byte{53, 177, 140, 159, 251, 189, 127, 53, 109, 252,
  369. 172, 50, 211, 192, 240, 164, 26, 48, 207, 45}
  370. if writtenAuthRespLen != 20 || !bytes.Equal(writtenAuthResp, expectedAuthResp) {
  371. t.Fatalf("unexpected written auth response (%d bytes): %v", writtenAuthRespLen, writtenAuthResp)
  372. }
  373. conn.written = nil
  374. // auth response
  375. conn.data = []byte{
  376. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  377. }
  378. conn.maxReads = 1
  379. // Handle response to auth packet
  380. if err := mc.handleAuthResult(authData, plugin); err != nil {
  381. t.Errorf("got error: %v", err)
  382. }
  383. }
  384. func TestAuthFastNativePasswordEmpty(t *testing.T) {
  385. conn, mc := newRWMockConn(1)
  386. mc.cfg.User = "root"
  387. mc.cfg.Passwd = ""
  388. authData := []byte{70, 114, 92, 94, 1, 38, 11, 116, 63, 114, 23, 101, 126,
  389. 103, 26, 95, 81, 17, 24, 21}
  390. plugin := "mysql_native_password"
  391. // Send Client Authentication Packet
  392. authResp, addNUL, err := mc.auth(authData, plugin)
  393. if err != nil {
  394. t.Fatal(err)
  395. }
  396. err = mc.writeHandshakeResponsePacket(authResp, addNUL, plugin)
  397. if err != nil {
  398. t.Fatal(err)
  399. }
  400. // check written auth response
  401. authRespStart := 4 + 4 + 4 + 1 + 23 + len(mc.cfg.User) + 1
  402. authRespEnd := authRespStart + 1 + len(authResp)
  403. writtenAuthRespLen := conn.written[authRespStart]
  404. writtenAuthResp := conn.written[authRespStart+1 : authRespEnd]
  405. if writtenAuthRespLen != 0 {
  406. t.Fatalf("unexpected written auth response (%d bytes): %v",
  407. writtenAuthRespLen, writtenAuthResp)
  408. }
  409. conn.written = nil
  410. // auth response
  411. conn.data = []byte{
  412. 7, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, // OK
  413. }
  414. conn.maxReads = 1
  415. // Handle response to auth packet
  416. if err := mc.handleAuthResult(authData, plugin); err != nil {
  417. t.Errorf("got error: %v", err)
  418. }
  419. }
  420. func TestAuthSwitchCachingSHA256PasswordCached(t *testing.T) {
  421. conn, mc := newRWMockConn(2)
  422. mc.cfg.Passwd = "secret"
  423. // auth switch request
  424. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  425. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  426. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  427. 50, 0}
  428. // auth response
  429. conn.queuedReplies = [][]byte{
  430. {7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}, // OK
  431. }
  432. conn.maxReads = 3
  433. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  434. 47, 43, 9, 41, 112, 67, 110}
  435. plugin := "mysql_native_password"
  436. if err := mc.handleAuthResult(authData, plugin); err != nil {
  437. t.Errorf("got error: %v", err)
  438. }
  439. expectedReply := []byte{
  440. // 1. Packet: Hash
  441. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  442. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  443. 153, 9, 130,
  444. }
  445. if !bytes.Equal(conn.written, expectedReply) {
  446. t.Errorf("got unexpected data: %v", conn.written)
  447. }
  448. }
  449. func TestAuthSwitchCachingSHA256PasswordEmpty(t *testing.T) {
  450. conn, mc := newRWMockConn(2)
  451. mc.cfg.Passwd = ""
  452. // auth switch request
  453. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  454. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  455. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  456. 50, 0}
  457. // auth response
  458. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  459. conn.maxReads = 2
  460. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  461. 47, 43, 9, 41, 112, 67, 110}
  462. plugin := "mysql_native_password"
  463. if err := mc.handleAuthResult(authData, plugin); err != nil {
  464. t.Errorf("got error: %v", err)
  465. }
  466. expectedReply := []byte{1, 0, 0, 3, 0}
  467. if !bytes.Equal(conn.written, expectedReply) {
  468. t.Errorf("got unexpected data: %v", conn.written)
  469. }
  470. }
  471. func TestAuthSwitchCachingSHA256PasswordFullRSA(t *testing.T) {
  472. conn, mc := newRWMockConn(2)
  473. mc.cfg.Passwd = "secret"
  474. // auth switch request
  475. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  476. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  477. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  478. 50, 0}
  479. conn.queuedReplies = [][]byte{
  480. // Perform Full Authentication
  481. {2, 0, 0, 4, 1, 4},
  482. // Pub Key Response
  483. append([]byte{byte(len(serverPubKey)), 1, 0, 6}, serverPubKey...),
  484. // OK
  485. {7, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0},
  486. }
  487. conn.maxReads = 4
  488. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  489. 47, 43, 9, 41, 112, 67, 110}
  490. plugin := "mysql_native_password"
  491. if err := mc.handleAuthResult(authData, plugin); err != nil {
  492. t.Errorf("got error: %v", err)
  493. }
  494. expectedReplyPrefix := []byte{
  495. // 1. Packet: Hash
  496. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  497. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  498. 153, 9, 130,
  499. // 2. Packet: Pub Key Request
  500. 1, 0, 0, 5, 2,
  501. // 3. Packet: Encrypted Password
  502. 0, 1, 0, 7, // [changing bytes]
  503. }
  504. if !bytes.HasPrefix(conn.written, expectedReplyPrefix) {
  505. t.Errorf("got unexpected data: %v", conn.written)
  506. }
  507. }
  508. func TestAuthSwitchCachingSHA256PasswordFullSecure(t *testing.T) {
  509. conn, mc := newRWMockConn(2)
  510. mc.cfg.Passwd = "secret"
  511. // Hack to make the caching_sha2_password plugin believe that the connection
  512. // is secure
  513. mc.cfg.tls = &tls.Config{InsecureSkipVerify: true}
  514. // auth switch request
  515. conn.data = []byte{44, 0, 0, 2, 254, 99, 97, 99, 104, 105, 110, 103, 95,
  516. 115, 104, 97, 50, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 101,
  517. 11, 26, 18, 94, 97, 22, 72, 2, 46, 70, 106, 29, 55, 45, 94, 76, 90, 84,
  518. 50, 0}
  519. // auth response
  520. conn.queuedReplies = [][]byte{
  521. {2, 0, 0, 4, 1, 4}, // Perform Full Authentication
  522. {7, 0, 0, 6, 0, 0, 0, 2, 0, 0, 0}, // OK
  523. }
  524. conn.maxReads = 3
  525. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  526. 47, 43, 9, 41, 112, 67, 110}
  527. plugin := "mysql_native_password"
  528. if err := mc.handleAuthResult(authData, plugin); err != nil {
  529. t.Errorf("got error: %v", err)
  530. }
  531. expectedReply := []byte{
  532. // 1. Packet: Hash
  533. 32, 0, 0, 3, 129, 93, 132, 95, 114, 48, 79, 215, 128, 62, 193, 118, 128,
  534. 54, 75, 208, 159, 252, 227, 215, 129, 15, 242, 97, 19, 159, 31, 20, 58,
  535. 153, 9, 130,
  536. // 2. Packet: Cleartext password
  537. 7, 0, 0, 5, 115, 101, 99, 114, 101, 116, 0,
  538. }
  539. if !bytes.Equal(conn.written, expectedReply) {
  540. t.Errorf("got unexpected data: %v", conn.written)
  541. }
  542. }
  543. func TestAuthSwitchCleartextPasswordNotAllowed(t *testing.T) {
  544. conn, mc := newRWMockConn(2)
  545. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  546. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  547. conn.maxReads = 1
  548. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  549. 47, 43, 9, 41, 112, 67, 110}
  550. plugin := "mysql_native_password"
  551. err := mc.handleAuthResult(authData, plugin)
  552. if err != ErrCleartextPassword {
  553. t.Errorf("expected ErrCleartextPassword, got %v", err)
  554. }
  555. }
  556. func TestAuthSwitchCleartextPassword(t *testing.T) {
  557. conn, mc := newRWMockConn(2)
  558. mc.cfg.AllowCleartextPasswords = true
  559. mc.cfg.Passwd = "secret"
  560. // auth switch request
  561. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  562. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  563. // auth response
  564. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  565. conn.maxReads = 2
  566. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  567. 47, 43, 9, 41, 112, 67, 110}
  568. plugin := "mysql_native_password"
  569. if err := mc.handleAuthResult(authData, plugin); err != nil {
  570. t.Errorf("got error: %v", err)
  571. }
  572. expectedReply := []byte{7, 0, 0, 3, 115, 101, 99, 114, 101, 116, 0}
  573. if !bytes.Equal(conn.written, expectedReply) {
  574. t.Errorf("got unexpected data: %v", conn.written)
  575. }
  576. }
  577. func TestAuthSwitchCleartextPasswordEmpty(t *testing.T) {
  578. conn, mc := newRWMockConn(2)
  579. mc.cfg.AllowCleartextPasswords = true
  580. mc.cfg.Passwd = ""
  581. // auth switch request
  582. conn.data = []byte{22, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 99, 108,
  583. 101, 97, 114, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0}
  584. // auth response
  585. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  586. conn.maxReads = 2
  587. authData := []byte{123, 87, 15, 84, 20, 58, 37, 121, 91, 117, 51, 24, 19,
  588. 47, 43, 9, 41, 112, 67, 110}
  589. plugin := "mysql_native_password"
  590. if err := mc.handleAuthResult(authData, plugin); err != nil {
  591. t.Errorf("got error: %v", err)
  592. }
  593. expectedReply := []byte{1, 0, 0, 3, 0}
  594. if !bytes.Equal(conn.written, expectedReply) {
  595. t.Errorf("got unexpected data: %v", conn.written)
  596. }
  597. }
  598. func TestAuthSwitchNativePasswordNotAllowed(t *testing.T) {
  599. conn, mc := newRWMockConn(2)
  600. mc.cfg.AllowNativePasswords = false
  601. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  602. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  603. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  604. 31, 0}
  605. conn.maxReads = 1
  606. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  607. 48, 31, 89, 39, 55, 31}
  608. plugin := "caching_sha2_password"
  609. err := mc.handleAuthResult(authData, plugin)
  610. if err != ErrNativePassword {
  611. t.Errorf("expected ErrNativePassword, got %v", err)
  612. }
  613. }
  614. func TestAuthSwitchNativePassword(t *testing.T) {
  615. conn, mc := newRWMockConn(2)
  616. mc.cfg.AllowNativePasswords = true
  617. mc.cfg.Passwd = "secret"
  618. // auth switch request
  619. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  620. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  621. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  622. 31, 0}
  623. // auth response
  624. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  625. conn.maxReads = 2
  626. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  627. 48, 31, 89, 39, 55, 31}
  628. plugin := "caching_sha2_password"
  629. if err := mc.handleAuthResult(authData, plugin); err != nil {
  630. t.Errorf("got error: %v", err)
  631. }
  632. expectedReply := []byte{20, 0, 0, 3, 202, 41, 195, 164, 34, 226, 49, 103,
  633. 21, 211, 167, 199, 227, 116, 8, 48, 57, 71, 149, 146}
  634. if !bytes.Equal(conn.written, expectedReply) {
  635. t.Errorf("got unexpected data: %v", conn.written)
  636. }
  637. }
  638. func TestAuthSwitchNativePasswordEmpty(t *testing.T) {
  639. conn, mc := newRWMockConn(2)
  640. mc.cfg.AllowNativePasswords = true
  641. mc.cfg.Passwd = ""
  642. // auth switch request
  643. conn.data = []byte{44, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 110, 97,
  644. 116, 105, 118, 101, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 96,
  645. 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31, 48, 31, 89, 39, 55,
  646. 31, 0}
  647. // auth response
  648. conn.queuedReplies = [][]byte{{7, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0}}
  649. conn.maxReads = 2
  650. authData := []byte{96, 71, 63, 8, 1, 58, 75, 12, 69, 95, 66, 60, 117, 31,
  651. 48, 31, 89, 39, 55, 31}
  652. plugin := "caching_sha2_password"
  653. if err := mc.handleAuthResult(authData, plugin); err != nil {
  654. t.Errorf("got error: %v", err)
  655. }
  656. expectedReply := []byte{0, 0, 0, 3}
  657. if !bytes.Equal(conn.written, expectedReply) {
  658. t.Errorf("got unexpected data: %v", conn.written)
  659. }
  660. }
  661. func TestAuthSwitchOldPasswordNotAllowed(t *testing.T) {
  662. conn, mc := newRWMockConn(2)
  663. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  664. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  665. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  666. conn.maxReads = 1
  667. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  668. 84, 96, 101, 92, 123, 121, 107}
  669. plugin := "mysql_native_password"
  670. err := mc.handleAuthResult(authData, plugin)
  671. if err != ErrOldPassword {
  672. t.Errorf("expected ErrOldPassword, got %v", err)
  673. }
  674. }
  675. func TestAuthSwitchOldPassword(t *testing.T) {
  676. conn, mc := newRWMockConn(2)
  677. mc.cfg.AllowOldPasswords = true
  678. mc.cfg.Passwd = "secret"
  679. // auth switch request
  680. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  681. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  682. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  683. // auth response
  684. conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
  685. conn.maxReads = 2
  686. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  687. 84, 96, 101, 92, 123, 121, 107}
  688. plugin := "mysql_native_password"
  689. if err := mc.handleAuthResult(authData, plugin); err != nil {
  690. t.Errorf("got error: %v", err)
  691. }
  692. expectedReply := []byte{9, 0, 0, 3, 86, 83, 83, 79, 74, 78, 65, 66, 0}
  693. if !bytes.Equal(conn.written, expectedReply) {
  694. t.Errorf("got unexpected data: %v", conn.written)
  695. }
  696. }
  697. func TestAuthSwitchOldPasswordEmpty(t *testing.T) {
  698. conn, mc := newRWMockConn(2)
  699. mc.cfg.AllowOldPasswords = true
  700. mc.cfg.Passwd = ""
  701. // auth switch request
  702. conn.data = []byte{41, 0, 0, 2, 254, 109, 121, 115, 113, 108, 95, 111, 108,
  703. 100, 95, 112, 97, 115, 115, 119, 111, 114, 100, 0, 95, 84, 103, 43, 61,
  704. 49, 123, 61, 91, 50, 40, 113, 35, 84, 96, 101, 92, 123, 121, 107, 0}
  705. // auth response
  706. conn.queuedReplies = [][]byte{{8, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 0}}
  707. conn.maxReads = 2
  708. authData := []byte{95, 84, 103, 43, 61, 49, 123, 61, 91, 50, 40, 113, 35,
  709. 84, 96, 101, 92, 123, 121, 107}
  710. plugin := "mysql_native_password"
  711. if err := mc.handleAuthResult(authData, plugin); err != nil {
  712. t.Errorf("got error: %v", err)
  713. }
  714. expectedReply := []byte{1, 0, 0, 3, 0}
  715. if !bytes.Equal(conn.written, expectedReply) {
  716. t.Errorf("got unexpected data: %v", conn.written)
  717. }
  718. }