utils.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  2. //
  3. // Copyright 2012 Julien Schmidt. All rights reserved.
  4. // http://www.julienschmidt.com
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla Public
  7. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  8. // You can obtain one at http://mozilla.org/MPL/2.0/.
  9. package mysql
  10. import (
  11. "bytes"
  12. "crypto/sha1"
  13. "encoding/binary"
  14. "io"
  15. "log"
  16. "math"
  17. "os"
  18. "regexp"
  19. "strconv"
  20. "strings"
  21. )
  22. // Logger
  23. var (
  24. errLog *log.Logger
  25. )
  26. func init() {
  27. errLog = log.New(os.Stderr, "[MySQL] ", log.Ldate|log.Ltime|log.Lshortfile)
  28. dsnPattern = regexp.MustCompile(
  29. `^(?:(?P<user>.*?)(?::(?P<passwd>.*))?@)?` + // [user[:password]@]
  30. `(?:(?P<net>[^\(]*)(?:\((?P<addr>[^\)]*)\))?)?` + // [net[(addr)]]
  31. `\/(?P<dbname>.*?)` + // /dbname
  32. `(?:\?(?P<params>[^\?]*))?$`) // [?param1=value1&paramN=valueN]
  33. }
  34. // Data Source Name Parser
  35. var dsnPattern *regexp.Regexp
  36. func parseDSN(dsn string) *config {
  37. cfg := new(config)
  38. cfg.params = make(map[string]string)
  39. matches := dsnPattern.FindStringSubmatch(dsn)
  40. names := dsnPattern.SubexpNames()
  41. for i, match := range matches {
  42. switch names[i] {
  43. case "user":
  44. cfg.user = match
  45. case "passwd":
  46. cfg.passwd = match
  47. case "net":
  48. cfg.net = match
  49. case "addr":
  50. cfg.addr = match
  51. case "dbname":
  52. cfg.dbname = match
  53. case "params":
  54. for _, v := range strings.Split(match, "&") {
  55. param := strings.SplitN(v, "=", 2)
  56. if len(param) != 2 {
  57. continue
  58. }
  59. cfg.params[param[0]] = param[1]
  60. }
  61. }
  62. }
  63. // Set default network if empty
  64. if cfg.net == "" {
  65. cfg.net = "tcp"
  66. }
  67. // Set default adress if empty
  68. if cfg.addr == "" {
  69. cfg.addr = "127.0.0.1:3306"
  70. }
  71. return cfg
  72. }
  73. // Encrypt password using 4.1+ method
  74. // http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#4.1_and_later
  75. func scramblePassword(scramble, password []byte) (result []byte) {
  76. if len(password) == 0 {
  77. return
  78. }
  79. // stage1Hash = SHA1(password)
  80. crypt := sha1.New()
  81. crypt.Write(password)
  82. stage1Hash := crypt.Sum(nil)
  83. // scrambleHash = SHA1(scramble + SHA1(stage1Hash))
  84. // inner Hash
  85. crypt.Reset()
  86. crypt.Write(stage1Hash)
  87. scrambleHash := crypt.Sum(nil)
  88. // outer Hash
  89. crypt.Reset()
  90. crypt.Write(scramble)
  91. crypt.Write(scrambleHash)
  92. scrambleHash = crypt.Sum(nil)
  93. // token = scrambleHash XOR stage1Hash
  94. result = make([]byte, 20)
  95. for i := range result {
  96. result[i] = scrambleHash[i] ^ stage1Hash[i]
  97. }
  98. return
  99. }
  100. /******************************************************************************
  101. * Read data-types from bytes *
  102. ******************************************************************************/
  103. // Read a slice from the data slice
  104. func readSlice(data []byte, delim byte) (slice []byte, err error) {
  105. pos := bytes.IndexByte(data, delim)
  106. if pos > -1 {
  107. slice = data[:pos]
  108. } else {
  109. slice = data
  110. err = io.EOF
  111. }
  112. return
  113. }
  114. func readLengthEnodedString(data []byte) ([]byte, bool, int, error) {
  115. // Get length
  116. num, isNull, n, err := bytesToLengthEncodedInteger(data)
  117. if err != nil || isNull {
  118. return nil, isNull, n, err
  119. }
  120. // Check data length
  121. if len(data) < n+int(num) {
  122. return nil, true, n, io.EOF
  123. }
  124. return data[n : n+int(num)], isNull, n + int(num), err
  125. }
  126. func readAndDropLengthEnodedString(data []byte) (n int, err error) {
  127. // Get length
  128. num, _, n, err := bytesToLengthEncodedInteger(data)
  129. if err != nil || num < 1 {
  130. return n, err
  131. }
  132. // Check data length
  133. if len(data) < n+int(num) {
  134. return n, io.EOF
  135. }
  136. return n + int(num), err
  137. }
  138. /******************************************************************************
  139. * Convert from and to bytes *
  140. ******************************************************************************/
  141. func uint24ToBytes(n uint32) (b []byte) {
  142. b = make([]byte, 3)
  143. for i := uint8(0); i < 3; i++ {
  144. b[i] = byte(n >> (i << 3))
  145. }
  146. return
  147. }
  148. func uint32ToBytes(n uint32) (b []byte) {
  149. b = make([]byte, 4)
  150. for i := uint8(0); i < 4; i++ {
  151. b[i] = byte(n >> (i << 3))
  152. }
  153. return
  154. }
  155. func uint64ToBytes(n uint64) (b []byte) {
  156. b = make([]byte, 8)
  157. for i := uint8(0); i < 8; i++ {
  158. b[i] = byte(n >> (i << 3))
  159. }
  160. return
  161. }
  162. func int64ToBytes(n int64) []byte {
  163. return uint64ToBytes(uint64(n))
  164. }
  165. func bytesToFloat32(b []byte) float32 {
  166. return math.Float32frombits(binary.LittleEndian.Uint32(b))
  167. }
  168. func bytesToFloat64(b []byte) float64 {
  169. return math.Float64frombits(binary.LittleEndian.Uint64(b))
  170. }
  171. func float64ToBytes(f float64) []byte {
  172. return uint64ToBytes(math.Float64bits(f))
  173. }
  174. func bytesToLengthEncodedInteger(b []byte) (num uint64, isNull bool, n int, err error) {
  175. switch b[0] {
  176. // 251: NULL
  177. case 0xfb:
  178. n = 1
  179. isNull = true
  180. return
  181. // 252: value of following 2
  182. case 0xfc:
  183. n = 3
  184. // 253: value of following 3
  185. case 0xfd:
  186. n = 4
  187. // 254: value of following 8
  188. case 0xfe:
  189. n = 9
  190. // 0-250: value of first byte
  191. default:
  192. num = uint64(b[0])
  193. n = 1
  194. return
  195. }
  196. switch n - 1 {
  197. case 2:
  198. num = uint64(b[0]) | uint64(b[1])<<8
  199. return
  200. case 3:
  201. num = uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16
  202. return
  203. default:
  204. num = uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 |
  205. uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 |
  206. uint64(b[6])<<48 | uint64(b[7])<<54
  207. }
  208. return
  209. }
  210. func lengthEncodedIntegerToBytes(n uint64) (b []byte) {
  211. switch {
  212. case n <= 250:
  213. b = []byte{byte(n)}
  214. case n <= 0xffff:
  215. b = []byte{0xfc, byte(n), byte(n >> 8)}
  216. case n <= 0xffffff:
  217. b = []byte{0xfd, byte(n), byte(n >> 8), byte(n >> 16)}
  218. }
  219. return
  220. }
  221. func intToByteStr(i int64) (b []byte) {
  222. return strconv.AppendInt(b, i, 10)
  223. }
  224. func uintToByteStr(u uint64) (b []byte) {
  225. return strconv.AppendUint(b, u, 10)
  226. }
  227. func float32ToByteStr(f float32) (b []byte) {
  228. return strconv.AppendFloat(b, float64(f), 'f', -1, 32)
  229. }
  230. func float64ToByteStr(f float64) (b []byte) {
  231. return strconv.AppendFloat(b, f, 'f', -1, 64)
  232. }