authentication.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. package binlog
  2. import (
  3. "crypto/sha1"
  4. "crypto/sha256"
  5. )
  6. func (c *Conn) authenticate(hr *HandshakeResponse) {
  7. switch c.Handshake.AuthPluginName {
  8. case "mysql_native_password" :
  9. c.doSha1Auth(hr)
  10. case "caching_sha2_password":
  11. c.doSha2Auth(hr)
  12. }
  13. }
  14. func (c *Conn) doSha1Auth(hr *HandshakeResponse) {
  15. }
  16. func (c *Conn) doSha2Auth(hr *HandshakeResponse) {
  17. salt := append(c.Handshake.AuthPluginDataPart1.Bytes(), c.Handshake.AuthPluginDataPart2.Bytes()...)
  18. ar := c.cachingSha2Auth(salt, []byte(hr.AuthResponse))
  19. hr.AuthResponseLength = uint64(len(ar))
  20. if hr.ClientFlag.PluginAuthLenEncClientData {
  21. c.putInt(TypeLenEncInt, hr.AuthResponseLength, 0)
  22. c.putBytes(ar)
  23. } else if hr.ClientFlag.SecureConnection {
  24. c.putInt(TypeFixedInt, hr.AuthResponseLength, 1)
  25. c.putBytes(ar)
  26. } else {
  27. c.putString(TypeNullTerminatedString, string(ar))
  28. }
  29. }
  30. func (c *Conn) nativeSha1Auth() {
  31. // SHA1(password) XOR SHA1("20-bytes random data from server" <concat> SHA1(SHA1(password)))
  32. }
  33. func (c *Conn) cachingSha2Auth(salt []byte, password []byte) []byte {
  34. if len(password) < 1 {
  35. return nil
  36. }
  37. pHash := c.sha256Hash(password)
  38. pHashHash := c.sha256Hash(pHash)
  39. pHashHashHash := c.sha256Hash(pHashHash)
  40. authData := c.sha256Hash(append(pHashHashHash, salt...))
  41. for i := range pHash {
  42. pHash[i] ^= authData[i]
  43. }
  44. return pHash
  45. }
  46. func (c *Conn) sha1Hash(word []byte) []byte {
  47. s := sha1.New()
  48. s.Write(word)
  49. return s.Sum(nil)
  50. }
  51. func (c *Conn) sha256Hash(word []byte) []byte {
  52. s := sha256.New()
  53. s.Write(word)
  54. return s.Sum(nil)
  55. }