authentication.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package binlog
  2. import (
  3. "bytes"
  4. "crypto/sha1"
  5. "crypto/sha256"
  6. )
  7. const SHA2_REQUEST_PUBLIC_KEY = 0x02
  8. const SHA2_FAST_AUTH_SUCCESS = 0x03
  9. const SHA2_PERFORM_FULL_AUTHENTICATION = 0x04
  10. type AuthMoreDataPacket struct {
  11. PacketHeader
  12. Data string
  13. }
  14. func (c *Conn) decodeAuthMoreDataResponsePacket(ph PacketHeader) (*AuthMoreDataPacket, error) {
  15. md := AuthMoreDataPacket{}
  16. md.PacketHeader = ph
  17. flag := c.getInt(TypeFixedInt, 1)
  18. switch flag {
  19. case SHA2_FAST_AUTH_SUCCESS:
  20. md.Data = "SHA2_FAST_AUTH_SUCCESS"
  21. case SHA2_REQUEST_PUBLIC_KEY:
  22. md.Data = "SHA2_REQUEST_PUBLIC_KEY"
  23. case SHA2_PERFORM_FULL_AUTHENTICATION:
  24. md.Data = "SHA2_PERFORM_FULL_AUTHENTICATION"
  25. }
  26. err := c.scanner.Err()
  27. if err != nil {
  28. return nil, err
  29. }
  30. return &md, nil
  31. }
  32. type AuthResponsePacket struct {
  33. PacketLength uint64
  34. SequenceID uint64
  35. Status uint64
  36. PluginName string
  37. AuthPluginData *bytes.Buffer
  38. }
  39. func (c *Conn) decodeAuthResponsePacket() (*AuthResponsePacket, error) {
  40. packet := AuthResponsePacket{}
  41. packet.PacketLength = c.getInt(TypeFixedInt, 3)
  42. packet.SequenceID = c.getInt(TypeFixedInt, 1)
  43. packet.Status = c.getInt(TypeFixedInt, 1)
  44. packet.PluginName = c.getString(TypeNullTerminatedString, 0)
  45. packet.AuthPluginData = c.readBytes(20)
  46. err := c.scanner.Err()
  47. if err != nil {
  48. return nil, err
  49. }
  50. return &packet, err
  51. }
  52. func (c *Conn) writeAuthSwitchPacket(ap *AuthResponsePacket) error {
  53. salt := ap.AuthPluginData.Bytes()
  54. password := []byte(c.HandshakeResponse.AuthResponse)
  55. c.authenticate(salt, password)
  56. if c.Flush() != nil {
  57. return c.Flush()
  58. }
  59. return nil
  60. }
  61. func (c *Conn) authenticate(salt []byte, password []byte) {
  62. var ar []byte
  63. salt = salt[:20] // trim null byte from end.
  64. switch c.Handshake.AuthPluginName {
  65. case "mysql_native_password":
  66. ar = c.nativeSha1Auth(salt, password)
  67. case "caching_sha2_password":
  68. ar = c.cachingSha2Auth(salt, password)
  69. }
  70. hr := c.HandshakeResponse
  71. hr.AuthResponseLength = uint64(len(ar))
  72. if hr.ClientFlag.PluginAuthLenEncClientData {
  73. c.putInt(TypeLenEncInt, hr.AuthResponseLength, 0)
  74. c.putBytes(ar)
  75. } else if hr.ClientFlag.SecureConnection {
  76. c.putInt(TypeFixedInt, hr.AuthResponseLength, 1)
  77. c.putBytes(ar)
  78. } else {
  79. c.putString(TypeNullTerminatedString, string(ar))
  80. }
  81. }
  82. func (c *Conn) nativeSha1Auth(salt []byte, password []byte) []byte {
  83. if len(password) < 1 {
  84. return nil
  85. }
  86. pHash := c.sha1Hash(password)
  87. pHashHash := c.sha1Hash(pHash)
  88. spHash := c.sha1Hash(append(salt, pHashHash...))
  89. for i := range pHash {
  90. pHash[i] ^= spHash[i]
  91. }
  92. return pHash
  93. }
  94. func (c *Conn) cachingSha2Auth(salt []byte, password []byte) []byte {
  95. if len(password) < 1 {
  96. return nil
  97. }
  98. pHash := c.sha256Hash(password)
  99. pHashHash := c.sha256Hash(pHash)
  100. pHashHashHash := c.sha256Hash(pHashHash)
  101. authData := c.sha256Hash(append(pHashHashHash, salt...))
  102. for i := range pHash {
  103. pHash[i] ^= authData[i]
  104. }
  105. return pHash
  106. }
  107. func (c *Conn) sha1Hash(word []byte) []byte {
  108. s := sha1.New()
  109. s.Write(word)
  110. return s.Sum(nil)
  111. }
  112. func (c *Conn) sha256Hash(word []byte) []byte {
  113. s := sha256.New()
  114. s.Write(word)
  115. return s.Sum(nil)
  116. }