Josh Brickner 7 лет назад
Родитель
Сommit
379a4dd6cb
6 измененных файлов с 79 добавлено и 14 удалено
  1. 40 0
      binlog/authentication.go
  2. 8 1
      binlog/connection.go
  3. 2 12
      binlog/handshake.go
  4. 8 0
      config.json
  5. 20 0
      docker-compose.yaml
  6. 1 1
      main.go

+ 40 - 0
binlog/authentication.go

@@ -1,9 +1,42 @@
 package binlog
 
 import (
+	"crypto/sha1"
 	"crypto/sha256"
 )
 
+func (c *Conn) authenticate(hr *HandshakeResponse) {
+	switch c.Handshake.AuthPluginName {
+	case "mysql_native_password" :
+		c.doSha1Auth(hr)
+	case "caching_sha2_password":
+		c.doSha2Auth(hr)
+	}
+}
+
+func (c *Conn) doSha1Auth(hr *HandshakeResponse) {
+}
+
+func (c *Conn) doSha2Auth(hr *HandshakeResponse) {
+	salt := append(c.Handshake.AuthPluginDataPart1.Bytes(), c.Handshake.AuthPluginDataPart2.Bytes()...)
+	ar := c.cachingSha2Auth(salt, []byte(hr.AuthResponse))
+	hr.AuthResponseLength = uint64(len(ar))
+	if hr.ClientFlag.PluginAuthLenEncClientData {
+		c.putInt(TypeLenEncInt, hr.AuthResponseLength, 0)
+		c.putBytes(ar)
+	} else if hr.ClientFlag.SecureConnection {
+		c.putInt(TypeFixedInt, hr.AuthResponseLength, 1)
+		c.putBytes(ar)
+	} else {
+		c.putString(TypeNullTerminatedString, string(ar))
+	}
+}
+
+func (c *Conn) nativeSha1Auth() {
+	// SHA1(password) XOR SHA1("20-bytes random data from server" <concat> SHA1(SHA1(password)))
+
+}
+
 func (c *Conn) cachingSha2Auth(salt []byte, password []byte) []byte {
 	if len(password) < 1 {
 		return nil
@@ -21,8 +54,15 @@ func (c *Conn) cachingSha2Auth(salt []byte, password []byte) []byte {
 	return pHash
 }
 
+func (c *Conn) sha1Hash(word []byte) []byte {
+	s := sha1.New()
+	s.Write(word)
+	return s.Sum(nil)
+}
+
 func (c *Conn) sha256Hash(word []byte) []byte {
 	s := sha256.New()
 	s.Write(word)
 	return s.Sum(nil)
 }
+

+ 8 - 1
binlog/connection.go

@@ -9,6 +9,7 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"io/ioutil"
 	"math"
 	"net"
 	"reflect"
@@ -55,8 +56,13 @@ func splitByBytesFunc(data []byte, atEOF bool) (advance int, token []byte, err e
 func newBinlogConfig(dsn string) (*Config, error) {
 	var err error
 
+	b, err := ioutil.ReadFile(dsn)
+	if err != nil {
+		return nil, err
+	}
+
 	config := Config{}
-	err = json.Unmarshal([]byte(dsn), &config)
+	err = json.Unmarshal(b, &config)
 
 	return &config, err
 }
@@ -124,6 +130,7 @@ func (d Driver) Open(dsn string) (driver.Conn, error) {
 		return nil, err
 	}
 
+	fmt.Printf("%+v\n", c.Handshake)
 	return c, err
 }
 

+ 2 - 12
binlog/handshake.go

@@ -133,18 +133,8 @@ func (c *Conn) writeHandshakeResponse() error {
 	c.putNullBytes(23)
 	c.putString(TypeNullTerminatedString, hr.Username)
 
-	salt := append(c.Handshake.AuthPluginDataPart1.Bytes(), c.Handshake.AuthPluginDataPart2.Bytes()...)
-	ar := c.cachingSha2Auth(salt, []byte(hr.AuthResponse))
-	hr.AuthResponseLength = uint64(len(ar))
-	if hr.ClientFlag.PluginAuthLenEncClientData {
-		c.putInt(TypeLenEncInt, hr.AuthResponseLength, 0)
-		c.putBytes(ar)
-	} else if hr.ClientFlag.SecureConnection {
-		c.putInt(TypeFixedInt, hr.AuthResponseLength, 1)
-		c.putBytes(ar)
-	} else {
-		c.putString(TypeNullTerminatedString, c.Config.Pass)
-	}
+	// Perform authentication
+	c.authenticate(hr)
 
 	// Write database name
 	if hr.ClientFlag.ConnectWithDB {

+ 8 - 0
config.json

@@ -0,0 +1,8 @@
+{
+  "host": "127.0.0.1",
+  "port": 3317,
+  "user": "root",
+  "password": "root",
+  "database": "information_schema",
+  "ssl": false
+}

+ 20 - 0
docker-compose.yaml

@@ -0,0 +1,20 @@
+version: "3"
+services:
+  mysql57:
+    image: mysql:5.7
+    environment:
+      MYSQL_ROOT_PASSWORD: root
+      MYSQL_DATABASE: root
+    ports:
+      - "3316:3306"
+    command: "--default-authentication-plugin=mysql_native_password"
+    restart: always
+  mysql56:
+    image: mysql:5.6
+    environment:
+      MYSQL_ROOT_PASSWORD: root
+      MYSQL_DATABASE: root
+    ports:
+      - "3317:3306"
+    command: "--default-authentication-plugin=mysql_native_password"
+    restart: always

+ 1 - 1
main.go

@@ -7,7 +7,7 @@ import (
 )
 
 func main() {
-	conn, err := sql.Open("mysql-binlog", "{\"host\": \"127.0.0.1\", \"port\": 3306, \"user\": \"root\", \"password\": \"root\", \"database\": \"information_schema\", \"ssl\": false}")
+	conn, err := sql.Open("mysql-binlog", "config.json")
 	if err != nil {
 		fmt.Printf("Open Error: %+v\n", err)
 	}