aboutsummaryrefslogtreecommitdiff
path: root/vendor/github.com/go-sql-driver
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/go-sql-driver')
-rw-r--r--vendor/github.com/go-sql-driver/mysql/AUTHORS3
-rw-r--r--vendor/github.com/go-sql-driver/mysql/CHANGELOG.md7
-rw-r--r--vendor/github.com/go-sql-driver/mysql/ISSUE_TEMPLATE.md21
-rw-r--r--vendor/github.com/go-sql-driver/mysql/PULL_REQUEST_TEMPLATE.md9
-rw-r--r--vendor/github.com/go-sql-driver/mysql/README.md63
-rw-r--r--vendor/github.com/go-sql-driver/mysql/driver.go20
-rw-r--r--vendor/github.com/go-sql-driver/mysql/dsn.go18
-rw-r--r--vendor/github.com/go-sql-driver/mysql/errors.go3
-rw-r--r--vendor/github.com/go-sql-driver/mysql/infile.go3
-rw-r--r--vendor/github.com/go-sql-driver/mysql/packets.go111
-rw-r--r--vendor/github.com/go-sql-driver/mysql/statement.go5
11 files changed, 165 insertions, 98 deletions
diff --git a/vendor/github.com/go-sql-driver/mysql/AUTHORS b/vendor/github.com/go-sql-driver/mysql/AUTHORS
index 466ac86..1003707 100644
--- a/vendor/github.com/go-sql-driver/mysql/AUTHORS
+++ b/vendor/github.com/go-sql-driver/mysql/AUTHORS
@@ -18,6 +18,7 @@ Chris Moos <chris at tech9computers.com>
Daniel Nichter <nil at codenode.com>
Daniël van Eeden <git at myname.nl>
DisposaBoy <disposaboy at dby.me>
+Egor Smolyakov <egorsmkv at gmail.com>
Frederick Mayle <frederickmayle at gmail.com>
Gustavo Kristic <gkristic at gmail.com>
Hanno Braun <mail at hannobraun.com>
@@ -38,11 +39,13 @@ Lucas Liu <extrafliu at gmail.com>
Luke Scott <luke at webconnex.com>
Michael Woolnough <michael.woolnough at gmail.com>
Nicola Peduzzi <thenikso at gmail.com>
+Olivier Mengué <dolmen at cpan.org>
Paul Bonser <misterpib at gmail.com>
Runrioter Wung <runrioter at gmail.com>
Soroush Pour <me at soroushjp.com>
Stan Putrya <root.vagner at gmail.com>
Stanley Gunawan <gunawan.stanley at gmail.com>
+Xiangyu Hu <xiangyu.hu at outlook.com>
Xiaobing Jiang <s7v7nislands at gmail.com>
Xiuming Chen <cc at cxm.cc>
Zhenye Xie <xiezhenye at gmail.com>
diff --git a/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md b/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
index 617ad80..6bcad7e 100644
--- a/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
+++ b/vendor/github.com/go-sql-driver/mysql/CHANGELOG.md
@@ -1,4 +1,4 @@
-## HEAD
+## Version 1.3 (2016-12-01)
Changes:
@@ -8,6 +8,8 @@ Changes:
- TLS ServerName defaults to the host (#283)
- Refactoring (#400, #410, #437)
- Adjusted documentation for second generation CloudSQL (#485)
+ - Documented DSN system var quoting rules (#502)
+ - Made statement.Close() calls idempotent to avoid errors in Go 1.6+ (#512)
New Features:
@@ -21,6 +23,7 @@ New Features:
- Support for JSON field type (#414)
- Support for multi-statements and multi-results (#411, #431)
- DSN parameter to set the driver-side max_allowed_packet value manually (#489)
+ - Native password authentication plugin support (#494, #524)
Bugfixes:
@@ -38,6 +41,8 @@ Bugfixes:
- Fixed parsing of floats into float64 when placeholders are used (#434)
- Fixed DSN tests with Go 1.7+ (#459)
- Handle ERR packets while waiting for EOF (#473)
+ - Invalidate connection on error while discarding additional results (#513)
+ - Allow terminating packets of length 0 (#516)
## Version 1.2 (2014-06-03)
diff --git a/vendor/github.com/go-sql-driver/mysql/ISSUE_TEMPLATE.md b/vendor/github.com/go-sql-driver/mysql/ISSUE_TEMPLATE.md
deleted file mode 100644
index d9771f1..0000000
--- a/vendor/github.com/go-sql-driver/mysql/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,21 +0,0 @@
-### Issue description
-Tell us what should happen and what happens instead
-
-### Example code
-```go
-If possible, please enter some example code here to reproduce the issue.
-```
-
-### Error log
-```
-If you have an error log, please paste it here.
-```
-
-### Configuration
-*Driver version (or git SHA):*
-
-*Go version:* run `go version` in your console
-
-*Server version:* E.g. MySQL 5.6, MariaDB 10.0.20
-
-*Server OS:* E.g. Debian 8.1 (Jessie), Windows 10
diff --git a/vendor/github.com/go-sql-driver/mysql/PULL_REQUEST_TEMPLATE.md b/vendor/github.com/go-sql-driver/mysql/PULL_REQUEST_TEMPLATE.md
deleted file mode 100644
index 6f5c7eb..0000000
--- a/vendor/github.com/go-sql-driver/mysql/PULL_REQUEST_TEMPLATE.md
+++ /dev/null
@@ -1,9 +0,0 @@
-### Description
-Please explain the changes you made here.
-
-### Checklist
-- [ ] Code compiles correctly
-- [ ] Created tests which fail without the change (if possible)
-- [ ] All tests passing
-- [ ] Extended the README / documentation, if necessary
-- [ ] Added myself / the copyright holder to the AUTHORS file
diff --git a/vendor/github.com/go-sql-driver/mysql/README.md b/vendor/github.com/go-sql-driver/mysql/README.md
index a110cf1..6452038 100644
--- a/vendor/github.com/go-sql-driver/mysql/README.md
+++ b/vendor/github.com/go-sql-driver/mysql/README.md
@@ -1,13 +1,9 @@
# Go-MySQL-Driver
-A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) package
+A MySQL-Driver for Go's [database/sql](https://golang.org/pkg/database/sql/) package
![Go-MySQL-Driver logo](https://raw.github.com/wiki/go-sql-driver/mysql/gomysql_m.png "Golang Gopher holding the MySQL Dolphin")
-**Latest stable Release:** [Version 1.2 (June 03, 2014)](https://github.com/go-sql-driver/mysql/releases)
-
-[![Build Status](https://travis-ci.org/go-sql-driver/mysql.png?branch=master)](https://travis-ci.org/go-sql-driver/mysql)
-
---------------------------------------
* [Features](#features)
* [Requirements](#requirements)
@@ -30,11 +26,11 @@ A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) packa
## Features
* Lightweight and [fast](https://github.com/go-sql-driver/sql-benchmark "golang MySQL-Driver performance")
* Native Go implementation. No C-bindings, just pure Go
- * Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or [custom protocols](http://godoc.org/github.com/go-sql-driver/mysql#DialFunc)
+ * Connections over TCP/IPv4, TCP/IPv6, Unix domain sockets or [custom protocols](https://godoc.org/github.com/go-sql-driver/mysql#DialFunc)
* Automatic handling of broken connections
* Automatic Connection Pooling *(by database/sql package)*
* Supports queries larger than 16MB
- * Full [`sql.RawBytes`](http://golang.org/pkg/database/sql/#RawBytes) support.
+ * Full [`sql.RawBytes`](https://golang.org/pkg/database/sql/#RawBytes) support.
* Intelligent `LONG DATA` handling in prepared statements
* Secure `LOAD DATA LOCAL INFILE` support with file Whitelisting and `io.Reader` support
* Optional `time.Time` parsing
@@ -47,14 +43,14 @@ A MySQL-Driver for Go's [database/sql](http://golang.org/pkg/database/sql) packa
---------------------------------------
## Installation
-Simple install the package to your [$GOPATH](http://code.google.com/p/go-wiki/wiki/GOPATH "GOPATH") with the [go tool](http://golang.org/cmd/go/ "go command") from shell:
+Simple install the package to your [$GOPATH](https://github.com/golang/go/wiki/GOPATH "GOPATH") with the [go tool](https://golang.org/cmd/go/ "go command") from shell:
```bash
$ go get github.com/go-sql-driver/mysql
```
-Make sure [Git is installed](http://git-scm.com/downloads) on your machine and in your system's `PATH`.
+Make sure [Git is installed](https://git-scm.com/downloads) on your machine and in your system's `PATH`.
## Usage
-_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](http://golang.org/pkg/database/sql) API then.
+_Go MySQL Driver_ is an implementation of Go's `database/sql/driver` interface. You only need to import the driver and can use the full [`database/sql`](https://golang.org/pkg/database/sql/) API then.
Use `mysql` as `driverName` and a valid [DSN](#dsn-data-source-name) as `dataSourceName`:
```go
@@ -99,13 +95,13 @@ Alternatively, [Config.FormatDSN](https://godoc.org/github.com/go-sql-driver/mys
Passwords can consist of any character. Escaping is **not** necessary.
#### Protocol
-See [net.Dial](http://golang.org/pkg/net/#Dial) for more information which networks are available.
+See [net.Dial](https://golang.org/pkg/net/#Dial) for more information which networks are available.
In general you should use an Unix domain socket if available and TCP otherwise for best performance.
#### Address
For TCP and UDP networks, addresses have the form `host:port`.
If `host` is a literal IPv6 address, it must be enclosed in square brackets.
-The functions [net.JoinHostPort](http://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](http://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form.
+The functions [net.JoinHostPort](https://golang.org/pkg/net/#JoinHostPort) and [net.SplitHostPort](https://golang.org/pkg/net/#SplitHostPort) manipulate addresses in this form.
For Unix domain sockets the address is the absolute path to the MySQL-Server-socket, e.g. `/var/run/mysqld/mysqld.sock` or `/tmp/mysql.sock`.
@@ -135,6 +131,15 @@ Default: false
`allowCleartextPasswords=true` allows using the [cleartext client side plugin](http://dev.mysql.com/doc/en/cleartext-authentication-plugin.html) if required by an account, such as one defined with the [PAM authentication plugin](http://dev.mysql.com/doc/en/pam-authentication-plugin.html). Sending passwords in clear text may be a security problem in some configurations. To avoid problems if there is any possibility that the password would be intercepted, clients should connect to MySQL Server using a method that protects the password. Possibilities include [TLS / SSL](#tls), IPsec, or a private network.
+##### `allowNativePasswords`
+
+```
+Type: bool
+Valid Values: true, false
+Default: false
+```
+`allowNativePasswords=true` allows the usage of the mysql native password method.
+
##### `allowOldPasswords`
```
@@ -215,11 +220,11 @@ Valid Values: <escaped name>
Default: UTC
```
-Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](http://golang.org/pkg/time/#LoadLocation) for details.
+Sets the location for time.Time values (when using `parseTime=true`). *"Local"* sets the system's location. See [time.LoadLocation](https://golang.org/pkg/time/#LoadLocation) for details.
Note that this sets the location for time.Time values but does not change MySQL's [time_zone setting](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html). For that see the [time_zone system variable](#system-variables), which can also be set as a DSN parameter.
-Please keep in mind, that param values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.
+Please keep in mind, that param values must be [url.QueryEscape](https://golang.org/pkg/net/url/#QueryEscape)'ed. Alternatively you can manually replace the `/` with `%2F`. For example `US/Pacific` would be `loc=US%2FPacific`.
##### `maxAllowedPacket`
```
@@ -292,7 +297,7 @@ Valid Values: true, false, skip-verify, <name>
Default: false
```
-`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side). Use a custom value registered with [`mysql.RegisterTLSConfig`](http://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
+`tls=true` enables TLS / SSL encrypted connection to the server. Use `skip-verify` if you want to use a self-signed or invalid certificate (server side). Use a custom value registered with [`mysql.RegisterTLSConfig`](https://godoc.org/github.com/go-sql-driver/mysql#RegisterTLSConfig).
##### `writeTimeout`
@@ -306,13 +311,21 @@ I/O write timeout. The value must be a decimal number with an unit suffix ( *"ms
##### System Variables
-All other parameters are interpreted as system variables:
- * `autocommit`: `"SET autocommit=<value>"`
- * [`time_zone`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `"SET time_zone=<value>"`
- * [`tx_isolation`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `"SET tx_isolation=<value>"`
- * `param`: `"SET <param>=<value>"`
+Any other parameters are interpreted as system variables:
+ * `<boolean_var>=<value>`: `SET <boolean_var>=<value>`
+ * `<enum_var>=<value>`: `SET <enum_var>=<value>`
+ * `<string_var>=%27<value>%27`: `SET <string_var>='<value>'`
+
+Rules:
+* The values for string variables must be quoted with '
+* The values must also be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!
+ (which implies values of string variables must be wrapped with `%27`)
+
+Examples:
+ * `autocommit=1`: `SET autocommit=1`
+ * [`time_zone=%27Europe%2FParis%27`](https://dev.mysql.com/doc/refman/5.5/en/time-zone-support.html): `SET time_zone='Europe/Paris'`
+ * [`tx_isolation=%27REPEATABLE-READ%27`](https://dev.mysql.com/doc/refman/5.5/en/server-system-variables.html#sysvar_tx_isolation): `SET tx_isolation='REPEATABLE-READ'`
-*The values must be [url.QueryEscape](http://golang.org/pkg/net/url/#QueryEscape)'ed!*
#### Examples
```
@@ -377,17 +390,17 @@ Files must be whitelisted by registering them with `mysql.RegisterLocalFile(file
To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::<name>` then. Choose different names for different handlers and `DeregisterReaderHandler` when you don't need it anymore.
-See the [godoc of Go-MySQL-Driver](http://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details.
+See the [godoc of Go-MySQL-Driver](https://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation") for details.
### `time.Time` support
The default internal output type of MySQL `DATE` and `DATETIME` values is `[]byte` which allows you to scan the value into a `[]byte`, `string` or `sql.RawBytes` variable in your programm.
-However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical opposite in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](http://golang.org/pkg/time/#Location) with the `loc` DSN parameter.
+However, many want to scan MySQL `DATE` and `DATETIME` values into `time.Time` variables, which is the logical opposite in Go to `DATE` and `DATETIME` in MySQL. You can do that by changing the internal output type from `[]byte` to `time.Time` with the DSN parameter `parseTime=true`. You can set the default [`time.Time` location](https://golang.org/pkg/time/#Location) with the `loc` DSN parameter.
**Caution:** As of Go 1.1, this makes `time.Time` the only variable type you can scan `DATE` and `DATETIME` values into. This breaks for example [`sql.RawBytes` support](https://github.com/go-sql-driver/mysql/wiki/Examples#rawbytes).
-Alternatively you can use the [`NullTime`](http://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`.
+Alternatively you can use the [`NullTime`](https://godoc.org/github.com/go-sql-driver/mysql#NullTime) type as the scan destination, which works with both `time.Time` and `string` / `[]byte`.
### Unicode support
@@ -422,7 +435,7 @@ That means:
* When distributing, you **must publish** the source code of any **changed files** licensed under the MPL 2.0 under a) the MPL 2.0 itself or b) a compatible license (e.g. GPL 3.0 or Apache License 2.0)
* You **needn't publish** the source code of your library as long as the files licensed under the MPL 2.0 are **unchanged**
-Please read the [MPL 2.0 FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html) if you have further questions regarding the license.
+Please read the [MPL 2.0 FAQ](https://www.mozilla.org/en-US/MPL/2.0/FAQ/) if you have further questions regarding the license.
You can read the full terms here: [LICENSE](https://raw.github.com/go-sql-driver/mysql/master/LICENSE)
diff --git a/vendor/github.com/go-sql-driver/mysql/driver.go b/vendor/github.com/go-sql-driver/mysql/driver.go
index 562ddef..0022d1f 100644
--- a/vendor/github.com/go-sql-driver/mysql/driver.go
+++ b/vendor/github.com/go-sql-driver/mysql/driver.go
@@ -134,9 +134,9 @@ func (d MySQLDriver) Open(dsn string) (driver.Conn, error) {
return mc, nil
}
-func handleAuthResult(mc *mysqlConn, cipher []byte) error {
+func handleAuthResult(mc *mysqlConn, oldCipher []byte) error {
// Read Result Packet
- err := mc.readResultOK()
+ cipher, err := mc.readResultOK()
if err == nil {
return nil // auth successful
}
@@ -150,10 +150,17 @@ func handleAuthResult(mc *mysqlConn, cipher []byte) error {
// Retry with old authentication method. Note: there are edge cases
// where this should work but doesn't; this is currently "wontfix":
// https://github.com/go-sql-driver/mysql/issues/184
+
+ // If CLIENT_PLUGIN_AUTH capability is not supported, no new cipher is
+ // sent and we have to keep using the cipher sent in the init packet.
+ if cipher == nil {
+ cipher = oldCipher
+ }
+
if err = mc.writeOldAuthPacket(cipher); err != nil {
return err
}
- err = mc.readResultOK()
+ _, err = mc.readResultOK()
} else if mc.cfg.AllowCleartextPasswords && err == ErrCleartextPassword {
// Retry with clear text password for
// http://dev.mysql.com/doc/refman/5.7/en/cleartext-authentication-plugin.html
@@ -161,7 +168,12 @@ func handleAuthResult(mc *mysqlConn, cipher []byte) error {
if err = mc.writeClearAuthPacket(); err != nil {
return err
}
- err = mc.readResultOK()
+ _, err = mc.readResultOK()
+ } else if mc.cfg.AllowNativePasswords && err == ErrNativePassword {
+ if err = mc.writeNativeAuthPacket(cipher); err != nil {
+ return err
+ }
+ _, err = mc.readResultOK()
}
return err
}
diff --git a/vendor/github.com/go-sql-driver/mysql/dsn.go b/vendor/github.com/go-sql-driver/mysql/dsn.go
index 896be9e..ac00dce 100644
--- a/vendor/github.com/go-sql-driver/mysql/dsn.go
+++ b/vendor/github.com/go-sql-driver/mysql/dsn.go
@@ -46,6 +46,7 @@ type Config struct {
AllowAllFiles bool // Allow all files to be used with LOAD DATA LOCAL INFILE
AllowCleartextPasswords bool // Allows the cleartext client side plugin
+ AllowNativePasswords bool // Allows the native password authentication method
AllowOldPasswords bool // Allows the old insecure password method
ClientFoundRows bool // Return number of matching rows instead of rows changed
ColumnsWithAlias bool // Prepend table alias to column names
@@ -101,6 +102,15 @@ func (cfg *Config) FormatDSN() string {
}
}
+ if cfg.AllowNativePasswords {
+ if hasParam {
+ buf.WriteString("&allowNativePasswords=true")
+ } else {
+ hasParam = true
+ buf.WriteString("?allowNativePasswords=true")
+ }
+ }
+
if cfg.AllowOldPasswords {
if hasParam {
buf.WriteString("&allowOldPasswords=true")
@@ -381,6 +391,14 @@ func parseDSNParams(cfg *Config, params string) (err error) {
return errors.New("invalid bool value: " + value)
}
+ // Use native password authentication
+ case "allowNativePasswords":
+ var isBool bool
+ cfg.AllowNativePasswords, isBool = readBool(value)
+ if !isBool {
+ return errors.New("invalid bool value: " + value)
+ }
+
// Use old authentication mode (pre MySQL 4.1)
case "allowOldPasswords":
var isBool bool
diff --git a/vendor/github.com/go-sql-driver/mysql/errors.go b/vendor/github.com/go-sql-driver/mysql/errors.go
index 1543a80..857854e 100644
--- a/vendor/github.com/go-sql-driver/mysql/errors.go
+++ b/vendor/github.com/go-sql-driver/mysql/errors.go
@@ -22,8 +22,9 @@ var (
ErrInvalidConn = errors.New("invalid connection")
ErrMalformPkt = errors.New("malformed packet")
ErrNoTLS = errors.New("TLS requested but server does not support TLS")
- ErrOldPassword = errors.New("this user requires old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords")
ErrCleartextPassword = errors.New("this user requires clear text authentication. If you still want to use it, please add 'allowCleartextPasswords=1' to your DSN")
+ ErrNativePassword = errors.New("this user requires mysql native password authentication.")
+ ErrOldPassword = errors.New("this user requires old password authentication. If you still want to use it, please add 'allowOldPasswords=1' to your DSN. See also https://github.com/go-sql-driver/mysql/wiki/old_passwords")
ErrUnknownPlugin = errors.New("this authentication plugin is not supported")
ErrOldProtocol = errors.New("MySQL server does not support required protocol 41+")
ErrPktSync = errors.New("commands out of sync. You can't run this command now")
diff --git a/vendor/github.com/go-sql-driver/mysql/infile.go b/vendor/github.com/go-sql-driver/mysql/infile.go
index 0f975bb..547357c 100644
--- a/vendor/github.com/go-sql-driver/mysql/infile.go
+++ b/vendor/github.com/go-sql-driver/mysql/infile.go
@@ -173,7 +173,8 @@ func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
// read OK packet
if err == nil {
- return mc.readResultOK()
+ _, err = mc.readResultOK()
+ return err
}
mc.readPacket()
diff --git a/vendor/github.com/go-sql-driver/mysql/packets.go b/vendor/github.com/go-sql-driver/mysql/packets.go
index f06752b..aafe979 100644
--- a/vendor/github.com/go-sql-driver/mysql/packets.go
+++ b/vendor/github.com/go-sql-driver/mysql/packets.go
@@ -25,9 +25,9 @@ import (
// Read packet to buffer 'data'
func (mc *mysqlConn) readPacket() ([]byte, error) {
- var payload []byte
+ var prevData []byte
for {
- // Read packet header
+ // read packet header
data, err := mc.buf.readNext(4)
if err != nil {
errLog.Print(err)
@@ -35,16 +35,10 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
return nil, driver.ErrBadConn
}
- // Packet Length [24 bit]
+ // packet length [24 bit]
pktLen := int(uint32(data[0]) | uint32(data[1])<<8 | uint32(data[2])<<16)
- if pktLen < 1 {
- errLog.Print(ErrMalformPkt)
- mc.Close()
- return nil, driver.ErrBadConn
- }
-
- // Check Packet Sync [8 bit]
+ // check packet sync [8 bit]
if data[3] != mc.sequence {
if data[3] > mc.sequence {
return nil, ErrPktSyncMul
@@ -53,7 +47,20 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
}
mc.sequence++
- // Read packet body [pktLen bytes]
+ // packets with length 0 terminate a previous packet which is a
+ // multiple of (2^24)−1 bytes long
+ if pktLen == 0 {
+ // there was no previous packet
+ if prevData == nil {
+ errLog.Print(ErrMalformPkt)
+ mc.Close()
+ return nil, driver.ErrBadConn
+ }
+
+ return prevData, nil
+ }
+
+ // read packet body [pktLen bytes]
data, err = mc.buf.readNext(pktLen)
if err != nil {
errLog.Print(err)
@@ -61,18 +68,17 @@ func (mc *mysqlConn) readPacket() ([]byte, error) {
return nil, driver.ErrBadConn
}
- isLastPacket := (pktLen < maxPacketSize)
+ // return data if this was the last packet
+ if pktLen < maxPacketSize {
+ // zero allocations for non-split packets
+ if prevData == nil {
+ return data, nil
+ }
- // Zero allocations for non-splitting packets
- if isLastPacket && payload == nil {
- return data, nil
+ return append(prevData, data...), nil
}
- payload = append(payload, data...)
-
- if isLastPacket {
- return payload, nil
- }
+ prevData = append(prevData, data...)
}
}
@@ -372,6 +378,26 @@ func (mc *mysqlConn) writeClearAuthPacket() error {
return mc.writePacket(data)
}
+// Native password authentication method
+// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse
+func (mc *mysqlConn) writeNativeAuthPacket(cipher []byte) error {
+ scrambleBuff := scramblePassword(cipher, []byte(mc.cfg.Passwd))
+
+ // Calculate the packet length and add a tailing 0
+ pktLen := len(scrambleBuff)
+ data := mc.buf.takeSmallBuffer(4 + pktLen)
+ if data == nil {
+ // can not take the buffer. Something must be wrong with the connection
+ errLog.Print(ErrBusyBuffer)
+ return driver.ErrBadConn
+ }
+
+ // Add the scramble
+ copy(data[4:], scrambleBuff)
+
+ return mc.writePacket(data)
+}
+
/******************************************************************************
* Command Packets *
******************************************************************************/
@@ -445,36 +471,43 @@ func (mc *mysqlConn) writeCommandPacketUint32(command byte, arg uint32) error {
******************************************************************************/
// Returns error if Packet is not an 'Result OK'-Packet
-func (mc *mysqlConn) readResultOK() error {
+func (mc *mysqlConn) readResultOK() ([]byte, error) {
data, err := mc.readPacket()
if err == nil {
// packet indicator
switch data[0] {
case iOK:
- return mc.handleOkPacket(data)
+ return nil, mc.handleOkPacket(data)
case iEOF:
if len(data) > 1 {
- plugin := string(data[1:bytes.IndexByte(data, 0x00)])
+ pluginEndIndex := bytes.IndexByte(data, 0x00)
+ plugin := string(data[1:pluginEndIndex])
+ cipher := data[pluginEndIndex+1 : len(data)-1]
+
if plugin == "mysql_old_password" {
// using old_passwords
- return ErrOldPassword
+ return cipher, ErrOldPassword
} else if plugin == "mysql_clear_password" {
// using clear text password
- return ErrCleartextPassword
+ return cipher, ErrCleartextPassword
+ } else if plugin == "mysql_native_password" {
+ // using mysql default authentication method
+ return cipher, ErrNativePassword
} else {
- return ErrUnknownPlugin
+ return cipher, ErrUnknownPlugin
}
} else {
- return ErrOldPassword
+ // https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::OldAuthSwitchRequest
+ return nil, ErrOldPassword
}
default: // Error otherwise
- return mc.handleErrorPacket(data)
+ return nil, mc.handleErrorPacket(data)
}
}
- return err
+ return nil, err
}
// Result Set Header Packet
@@ -674,11 +707,15 @@ func (rows *textRows) readRow(dest []driver.Value) error {
if data[0] == iEOF && len(data) == 5 {
// server_status [2 bytes]
rows.mc.status = readStatus(data[3:])
- if err := rows.mc.discardResults(); err != nil {
- return err
+ err = rows.mc.discardResults()
+ if err == nil {
+ err = io.EOF
+ } else {
+ // connection unusable
+ rows.mc.Close()
}
rows.mc = nil
- return io.EOF
+ return err
}
if data[0] == iERR {
rows.mc = nil
@@ -1079,11 +1116,15 @@ func (rows *binaryRows) readRow(dest []driver.Value) error {
// EOF Packet
if data[0] == iEOF && len(data) == 5 {
rows.mc.status = readStatus(data[3:])
- if err := rows.mc.discardResults(); err != nil {
- return err
+ err = rows.mc.discardResults()
+ if err == nil {
+ err = io.EOF
+ } else {
+ // connection unusable
+ rows.mc.Close()
}
rows.mc = nil
- return io.EOF
+ return err
}
rows.mc = nil
diff --git a/vendor/github.com/go-sql-driver/mysql/statement.go b/vendor/github.com/go-sql-driver/mysql/statement.go
index ead9a6b..7f9b045 100644
--- a/vendor/github.com/go-sql-driver/mysql/statement.go
+++ b/vendor/github.com/go-sql-driver/mysql/statement.go
@@ -24,7 +24,10 @@ type mysqlStmt struct {
func (stmt *mysqlStmt) Close() error {
if stmt.mc == nil || stmt.mc.netConn == nil {
- errLog.Print(ErrInvalidConn)
+ // driver.Stmt.Close can be called more than once, thus this function
+ // has to be idempotent.
+ // See also Issue #450 and golang/go#16019.
+ //errLog.Print(ErrInvalidConn)
return driver.ErrBadConn
}