auth_test.go 24 KB

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