diff options
Diffstat (limited to 'Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go')
-rw-r--r-- | Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go | 56 |
1 files changed, 50 insertions, 6 deletions
diff --git a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go index 290a3887a..76cb7c84e 100644 --- a/Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go +++ b/Godeps/_workspace/src/github.com/go-sql-driver/mysql/packets.go @@ -196,7 +196,11 @@ func (mc *mysqlConn) readInitPacket() ([]byte, error) { // return //} //return ErrMalformPkt - return cipher, nil + + // make a memory safe copy of the cipher slice + var b [20]byte + copy(b[:], cipher) + return b[:], nil } // make a memory safe copy of the cipher slice @@ -214,6 +218,7 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error { clientLongPassword | clientTransactions | clientLocalFiles | + clientPluginAuth | mc.flags&clientLongFlag if mc.cfg.clientFoundRows { @@ -228,7 +233,7 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error { // User Password scrambleBuff := scramblePassword(cipher, []byte(mc.cfg.passwd)) - pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.user) + 1 + 1 + len(scrambleBuff) + pktLen := 4 + 4 + 1 + 23 + len(mc.cfg.user) + 1 + 1 + len(scrambleBuff) + 21 + 1 // To specify a db name if n := len(mc.cfg.dbname); n > 0 { @@ -277,7 +282,10 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error { } // Filler [23 bytes] (all 0x00) - pos := 13 + 23 + pos := 13 + for ; pos < 13+23; pos++ { + data[pos] = 0 + } // User [null terminated string] if len(mc.cfg.user) > 0 { @@ -294,8 +302,13 @@ func (mc *mysqlConn) writeAuthPacket(cipher []byte) error { if len(mc.cfg.dbname) > 0 { pos += copy(data[pos:], mc.cfg.dbname) data[pos] = 0x00 + pos++ } + // Assume native client during response + pos += copy(data[pos:], "mysql_native_password") + data[pos] = 0x00 + // Send Auth packet return mc.writePacket(data) } @@ -306,7 +319,7 @@ func (mc *mysqlConn) writeOldAuthPacket(cipher []byte) error { // User password scrambleBuff := scrambleOldPassword(cipher, []byte(mc.cfg.passwd)) - // Calculate the packet lenght and add a tailing 0 + // Calculate the packet length and add a tailing 0 pktLen := len(scrambleBuff) + 1 data := mc.buf.takeSmallBuffer(4 + pktLen) if data == nil { @@ -322,6 +335,25 @@ func (mc *mysqlConn) writeOldAuthPacket(cipher []byte) error { return mc.writePacket(data) } +// Client clear text authentication packet +// http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchResponse +func (mc *mysqlConn) writeClearAuthPacket() error { + // Calculate the packet length and add a tailing 0 + pktLen := len(mc.cfg.passwd) + 1 + 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 clear password [null terminated string] + copy(data[4:], mc.cfg.passwd) + data[4+pktLen-1] = 0x00 + + return mc.writePacket(data) +} + /****************************************************************************** * Command Packets * ******************************************************************************/ @@ -405,8 +437,20 @@ func (mc *mysqlConn) readResultOK() error { return mc.handleOkPacket(data) case iEOF: - // someone is using old_passwords - return ErrOldPassword + if len(data) > 1 { + plugin := string(data[1:bytes.IndexByte(data, 0x00)]) + if plugin == "mysql_old_password" { + // using old_passwords + return ErrOldPassword + } else if plugin == "mysql_clear_password" { + // using clear text password + return ErrCleartextPassword + } else { + return ErrUnknownPlugin + } + } else { + return ErrOldPassword + } default: // Error otherwise return mc.handleErrorPacket(data) |