github.com/nakagami/firebirdsql@v0.9.10/wireprotocol.go (about)

     1  /*******************************************************************************
     2  The MIT License (MIT)
     3  
     4  Copyright (c) 2013-2019 Hajime Nakagami
     5  
     6  Permission is hereby granted, free of charge, to any person obtaining a copy of
     7  this software and associated documentation files (the "Software"), to deal in
     8  the Software without restriction, including without limitation the rights to
     9  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
    10  the Software, and to permit persons to whom the Software is furnished to do so,
    11  subject to the following conditions:
    12  
    13  The above copyright notice and this permission notice shall be included in all
    14  copies or substantial portions of the Software.
    15  
    16  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    17  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    18  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    19  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    20  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    21  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    22  *******************************************************************************/
    23  
    24  package firebirdsql
    25  
    26  import (
    27  	"bufio"
    28  	"bytes"
    29  	"container/list"
    30  	"crypto/rc4"
    31  	"crypto/sha256"
    32  	"database/sql/driver"
    33  	"encoding/hex"
    34  	"errors"
    35  	"fmt"
    36  	"github.com/kardianos/osext"
    37  	"gitlab.com/nyarla/go-crypt"
    38  	"golang.org/x/crypto/chacha20"
    39  	"golang.org/x/text/encoding/charmap"
    40  	"golang.org/x/text/encoding/japanese"
    41  	"golang.org/x/text/encoding/korean"
    42  	"golang.org/x/text/encoding/simplifiedchinese"
    43  	"golang.org/x/text/encoding/traditionalchinese"
    44  	"math/big"
    45  	"net"
    46  	"os"
    47  	"strconv"
    48  	"strings"
    49  	"time"
    50  	//"unsafe"
    51  )
    52  
    53  const (
    54  	PLUGIN_LIST       = "Srp256,Srp,Legacy_Auth"
    55  	BUFFER_LEN        = 1024
    56  	MAX_CHAR_LENGTH   = 32767
    57  	BLOB_SEGMENT_SIZE = 32000
    58  )
    59  
    60  func _INFO_SQL_SELECT_DESCRIBE_VARS() []byte {
    61  	return []byte{
    62  		isc_info_sql_select,
    63  		isc_info_sql_describe_vars,
    64  		isc_info_sql_sqlda_seq,
    65  		isc_info_sql_type,
    66  		isc_info_sql_sub_type,
    67  		isc_info_sql_scale,
    68  		isc_info_sql_length,
    69  		isc_info_sql_null_ind,
    70  		isc_info_sql_field,
    71  		isc_info_sql_relation,
    72  		isc_info_sql_owner,
    73  		isc_info_sql_alias,
    74  		isc_info_sql_describe_end,
    75  	}
    76  }
    77  
    78  type wireChannel struct {
    79  	conn           net.Conn
    80  	reader         *bufio.Reader
    81  	writer         *bufio.Writer
    82  	plugin         string
    83  	rc4reader      *rc4.Cipher
    84  	rc4writer      *rc4.Cipher
    85  	chacha20reader *chacha20.Cipher
    86  	chacha20writer *chacha20.Cipher
    87  }
    88  
    89  func newWireChannel(conn net.Conn) (wireChannel, error) {
    90  	var err error
    91  	c := new(wireChannel)
    92  	c.conn = conn
    93  	c.reader = bufio.NewReader(c.conn)
    94  	c.writer = bufio.NewWriter(c.conn)
    95  
    96  	return *c, err
    97  }
    98  
    99  func (c *wireChannel) setCryptKey(plugin string, sessionKey []byte, nonce []byte) (err error) {
   100  	c.plugin = plugin
   101  	if plugin == "ChaCha" {
   102  		digest := sha256.New()
   103  		digest.Write(sessionKey)
   104  		key := digest.Sum(nil)
   105  		c.chacha20reader, err = chacha20.NewUnauthenticatedCipher(key, nonce)
   106  		c.chacha20writer, err = chacha20.NewUnauthenticatedCipher(key, nonce)
   107  	} else if plugin == "Arc4" {
   108  		c.rc4reader, err = rc4.NewCipher(sessionKey)
   109  		c.rc4writer, err = rc4.NewCipher(sessionKey)
   110  	} else {
   111  		err = errors.New(fmt.Sprintf("Unknown wire encrypto plugin name:%s", plugin))
   112  	}
   113  
   114  	return
   115  }
   116  
   117  func (c *wireChannel) Read(buf []byte) (n int, err error) {
   118  	if c.plugin != "" {
   119  		src := make([]byte, len(buf))
   120  		n, err = c.reader.Read(src)
   121  		if c.plugin == "ChaCha" {
   122  			c.chacha20reader.XORKeyStream(buf, src[0:n])
   123  		} else if c.plugin == "Arc4" {
   124  			c.rc4reader.XORKeyStream(buf, src[0:n])
   125  		}
   126  		return
   127  	}
   128  	return c.reader.Read(buf)
   129  }
   130  
   131  func (c *wireChannel) Write(buf []byte) (n int, err error) {
   132  	if c.plugin != "" {
   133  		dst := make([]byte, len(buf))
   134  		if c.plugin == "ChaCha" {
   135  			c.chacha20writer.XORKeyStream(dst, buf)
   136  		} else if c.plugin == "Arc4" {
   137  			c.rc4writer.XORKeyStream(dst, buf)
   138  		}
   139  		written := 0
   140  		for written < len(buf) {
   141  			n, err = c.writer.Write(dst[written:])
   142  			if err != nil {
   143  				return
   144  			}
   145  			written += n
   146  		}
   147  		n = written
   148  	} else {
   149  		n, err = c.writer.Write(buf)
   150  	}
   151  	return
   152  }
   153  
   154  func (c *wireChannel) Flush() error {
   155  	return c.writer.Flush()
   156  }
   157  
   158  func (c *wireChannel) Close() error {
   159  	return c.conn.Close()
   160  }
   161  
   162  type wireProtocol struct {
   163  	buf []byte
   164  
   165  	conn     wireChannel
   166  	dbHandle int32
   167  	addr     string
   168  
   169  	protocolVersion    int32
   170  	acceptArchitecture int32
   171  	acceptType         int32
   172  	lazyResponseCount  int
   173  
   174  	pluginName string
   175  	user       string
   176  	password   string
   177  	authData   []byte
   178  
   179  	charset        string
   180  	charsetByteLen int
   181  
   182  	// Time Zone
   183  	timezone string
   184  }
   185  
   186  func newWireProtocol(addr string, timezone string, charset string) (*wireProtocol, error) {
   187  	p := new(wireProtocol)
   188  	p.buf = make([]byte, 0, BUFFER_LEN)
   189  
   190  	p.addr = addr
   191  	conn, err := net.Dial("tcp", p.addr)
   192  	if err != nil {
   193  		return nil, err
   194  	}
   195  
   196  	p.conn, err = newWireChannel(conn)
   197  	p.timezone = timezone
   198  	p.charset = charset
   199  	p.charsetLen()
   200  
   201  	return p, err
   202  }
   203  
   204  // charsetLen sets the length of character depending the charset to get the correct size of column
   205  func (p *wireProtocol) charsetLen() {
   206  	// all ISO8859_X and WIN125X are 1 byte character length, so omit here
   207  	// only add charset that character length is > 1
   208  	switch p.charset {
   209  	case "UNICODE_FSS", "UTF8":
   210  		p.charsetByteLen = 4
   211  	case "BIG_5", "SJIS_0208", "KSC_5601", "EUCJ_0208", "GB_2312", "KOI8R", "KOI8U":
   212  		p.charsetByteLen = 2
   213  	default:
   214  		p.charsetByteLen = 1
   215  	}
   216  }
   217  
   218  func (p *wireProtocol) packInt(i int32) {
   219  	// pack big endian int32
   220  	p.buf = append(p.buf, []byte{byte(i >> 24 & 0xFF), byte(i >> 16 & 0xFF), byte(i >> 8 & 0xFF), byte(i & 0xFF)}...)
   221  }
   222  
   223  func (p *wireProtocol) packBytes(b []byte) {
   224  	p.buf = append(p.buf, xdrBytes(b)...)
   225  }
   226  
   227  func (p *wireProtocol) packString(s string) {
   228  	p.buf = append(p.buf, xdrBytes([]byte(p.encodeString(s)))...)
   229  }
   230  
   231  func (p *wireProtocol) appendBytes(bs []byte) {
   232  	p.buf = append(p.buf, bs...)
   233  }
   234  
   235  func getSrpClientPublicBytes(clientPublic *big.Int) (bs []byte) {
   236  	b := bytes.NewBufferString(hex.EncodeToString(bigIntToBytes(clientPublic))).Bytes()
   237  	if len(b) > 254 {
   238  		bs = bytes.Join([][]byte{
   239  			[]byte{CNCT_specific_data, byte(255), 0}, b[:254],
   240  			[]byte{CNCT_specific_data, byte(len(b)-254) + 1, 1}, b[254:],
   241  		}, nil)
   242  	} else {
   243  		bs = bytes.Join([][]byte{
   244  			[]byte{CNCT_specific_data, byte(len(b)) + 1, 0}, b,
   245  		}, nil)
   246  	}
   247  	return bs
   248  }
   249  
   250  func (p *wireProtocol) uid(user string, password string, authPluginName string, wireCrypt bool, clientPublic *big.Int) []byte {
   251  	sysUser := os.Getenv("USER")
   252  	if sysUser == "" {
   253  		sysUser = os.Getenv("USERNAME")
   254  	}
   255  	hostname, _ := os.Hostname()
   256  
   257  	sysUserBytes := bytes.NewBufferString(sysUser).Bytes()
   258  	hostnameBytes := bytes.NewBufferString(hostname).Bytes()
   259  	pluginListNameBytes := bytes.NewBufferString(PLUGIN_LIST).Bytes()
   260  	pluginNameBytes := bytes.NewBufferString(authPluginName).Bytes()
   261  	userBytes := bytes.NewBufferString(strings.ToUpper(user)).Bytes()
   262  	var wireCryptByte byte
   263  	if wireCrypt {
   264  		wireCryptByte = 1
   265  	} else {
   266  		wireCryptByte = 0
   267  	}
   268  
   269  	var specific_data []byte
   270  	if authPluginName == "Srp" || authPluginName == "Srp256" {
   271  		specific_data = getSrpClientPublicBytes(clientPublic)
   272  	} else if authPluginName == "Legacy_Auth" {
   273  		b := bytes.NewBufferString(crypt.Crypt(password, "9z")[2:]).Bytes()
   274  		specific_data = bytes.Join([][]byte{
   275  			[]byte{CNCT_specific_data, byte(len(b)) + 1, 0}, b,
   276  		}, nil)
   277  	} else {
   278  		panic(fmt.Sprintf("Unknown plugin name:%s", authPluginName))
   279  	}
   280  
   281  	return bytes.Join([][]byte{
   282  		[]byte{CNCT_login, byte(len(userBytes))}, userBytes,
   283  		[]byte{CNCT_plugin_name, byte(len(pluginNameBytes))}, pluginNameBytes,
   284  		[]byte{CNCT_plugin_list, byte(len(pluginListNameBytes))}, pluginListNameBytes,
   285  		specific_data,
   286  		[]byte{CNCT_client_crypt, 4, wireCryptByte, 0, 0, 0},
   287  		[]byte{CNCT_user, byte(len(sysUserBytes))}, sysUserBytes,
   288  		[]byte{CNCT_host, byte(len(hostnameBytes))}, hostnameBytes,
   289  		[]byte{CNCT_user_verification, 0},
   290  	}, nil)
   291  }
   292  
   293  func (p *wireProtocol) sendPackets() (written int, err error) {
   294  	p.debugPrint("\tsendPackets():%v", p.buf)
   295  	n := 0
   296  	for written < len(p.buf) {
   297  		n, err = p.conn.Write(p.buf[written:])
   298  		if err != nil {
   299  			// error while sending the package....
   300  			err = driver.ErrBadConn
   301  			break
   302  		}
   303  		written += n
   304  	}
   305  	p.conn.Flush()
   306  	p.buf = make([]byte, 0, BUFFER_LEN)
   307  	return
   308  }
   309  
   310  func (p *wireProtocol) suspendBuffer() []byte {
   311  	p.debugPrint("\tsuspendBuffer():%v", p.buf)
   312  	buf := p.buf
   313  	p.buf = make([]byte, 0, BUFFER_LEN)
   314  	return buf
   315  }
   316  
   317  func (p *wireProtocol) resumeBuffer(buf []byte) {
   318  	p.debugPrint("\tresumeBuffer():%v", buf)
   319  	p.buf = buf
   320  }
   321  
   322  func (p *wireProtocol) recvPackets(n int) ([]byte, error) {
   323  	buf := make([]byte, n)
   324  	var err error
   325  	read := 0
   326  	totalRead := 0
   327  	for totalRead < n {
   328  		read, err = p.conn.Read(buf[totalRead:n])
   329  		if err != nil {
   330  			p.debugPrint("\trecvPackets():%v:%v", buf, err)
   331  			return buf, err
   332  		}
   333  		totalRead += read
   334  	}
   335  	p.debugPrint("\trecvPackets():%v:%v", buf, err)
   336  	return buf, err
   337  }
   338  
   339  func (p *wireProtocol) recvPacketsAlignment(n int) ([]byte, error) {
   340  	padding := n % 4
   341  	if padding > 0 {
   342  		padding = 4 - padding
   343  	}
   344  	buf, err := p.recvPackets(n + padding)
   345  	return buf[0:n], err
   346  }
   347  
   348  func (p *wireProtocol) _parse_status_vector() (*list.List, int, string, error) {
   349  	sql_code := 0
   350  	gds_code := 0
   351  	gds_codes := list.New()
   352  	num_arg := 0
   353  	message := ""
   354  
   355  	b, err := p.recvPackets(4)
   356  	n := bytes_to_bint32(b)
   357  	for n != isc_arg_end {
   358  		switch {
   359  		case n == isc_arg_gds:
   360  			b, err = p.recvPackets(4)
   361  			gds_code = int(bytes_to_bint32(b))
   362  			if gds_code != 0 {
   363  				gds_codes.PushBack(gds_code)
   364  				if msg, ok := errmsgs[gds_code]; ok {
   365  					message += msg
   366  				} else {
   367  					message += fmt.Sprintf("unknown gds_code: %d", gds_code)
   368  				}
   369  				num_arg = 0
   370  			}
   371  		case n == isc_arg_number:
   372  			b, err = p.recvPackets(4)
   373  			num := int(bytes_to_bint32(b))
   374  			if gds_code == 335544436 {
   375  				sql_code = num
   376  			}
   377  			num_arg++
   378  			message = strings.Replace(message, "@"+strconv.Itoa(num_arg), strconv.Itoa(num), 1)
   379  		case n == isc_arg_string:
   380  			b, err = p.recvPackets(4)
   381  			nbytes := int(bytes_to_bint32(b))
   382  			b, err = p.recvPacketsAlignment(nbytes)
   383  			s := bytes_to_str(b)
   384  			num_arg++
   385  			message = strings.Replace(message, "@"+strconv.Itoa(num_arg), s, 1)
   386  		case n == isc_arg_interpreted:
   387  			b, err = p.recvPackets(4)
   388  			nbytes := int(bytes_to_bint32(b))
   389  			b, err = p.recvPacketsAlignment(nbytes)
   390  			s := bytes_to_str(b)
   391  			message += s
   392  		case n == isc_arg_sql_state:
   393  			b, err = p.recvPackets(4)
   394  			nbytes := int(bytes_to_bint32(b))
   395  			b, err = p.recvPacketsAlignment(nbytes)
   396  			_ = bytes_to_str(b) // skip status code
   397  		}
   398  		b, err = p.recvPackets(4)
   399  		n = bytes_to_bint32(b)
   400  	}
   401  
   402  	return gds_codes, sql_code, message, err
   403  }
   404  
   405  func (p *wireProtocol) _parse_op_response() (int32, []byte, []byte, error) {
   406  	b, err := p.recvPackets(16)
   407  	h := bytes_to_bint32(b[0:4])            // Object handle
   408  	oid := b[4:12]                          // Object ID
   409  	buf_len := int(bytes_to_bint32(b[12:])) // buffer length
   410  	buf, err := p.recvPacketsAlignment(buf_len)
   411  
   412  	gds_code_list, sql_code, message, err := p._parse_status_vector()
   413  	if gds_code_list.Len() > 0 || sql_code != 0 {
   414  		err = errors.New(message)
   415  	}
   416  
   417  	return h, oid, buf, err
   418  }
   419  
   420  func (p *wireProtocol) _guess_wire_crypt(buf []byte) (string, []byte) {
   421  	params := map[byte][]byte{}
   422  	i := 0
   423  	for i = 0; i < len(buf); {
   424  		k := buf[i]
   425  		i++
   426  		ln := int(buf[i])
   427  		i++
   428  		v := buf[i : i+ln]
   429  		i += ln
   430  		params[k] = v
   431  	}
   432  	v, ok := params[3]
   433  	if ok {
   434  		if string(v[:7]) == "ChaCha\x00" {
   435  			return "ChaCha", v[7 : len(v)-4]
   436  		}
   437  	}
   438  	return "Arc4", nil
   439  }
   440  
   441  func (p *wireProtocol) _parse_connect_response(user string, password string, options map[string]string, clientPublic *big.Int, clientSecret *big.Int) (err error) {
   442  	p.debugPrint("_parse_connect_response")
   443  
   444  	b, err := p.recvPackets(4)
   445  	opcode := bytes_to_bint32(b)
   446  
   447  	for opcode == op_dummy {
   448  		b, _ = p.recvPackets(4)
   449  		opcode = bytes_to_bint32(b)
   450  	}
   451  
   452  	if opcode == op_reject {
   453  		err = errors.New("_parse_connect_response() op_reject")
   454  		return
   455  	}
   456  	if opcode == op_response {
   457  		_, _, _, err = p._parse_op_response() // error occured
   458  		return
   459  	}
   460  
   461  	b, _ = p.recvPackets(12)
   462  	p.protocolVersion = int32(b[3])
   463  	p.acceptArchitecture = bytes_to_bint32(b[4:8])
   464  	p.acceptType = bytes_to_bint32(b[8:12])
   465  
   466  	if opcode == op_cond_accept || opcode == op_accept_data {
   467  		var readLength, ln int
   468  
   469  		b, _ := p.recvPackets(4)
   470  		ln = int(bytes_to_bint32(b))
   471  		data, _ := p.recvPacketsAlignment(ln)
   472  
   473  		b, _ = p.recvPackets(4)
   474  		ln = int(bytes_to_bint32(b))
   475  		pluginName, _ := p.recvPacketsAlignment(ln)
   476  		p.pluginName = bytes_to_str(pluginName)
   477  
   478  		b, _ = p.recvPackets(4)
   479  		isAuthenticated := bytes_to_bint32(b)
   480  		readLength += 4
   481  
   482  		b, _ = p.recvPackets(4)
   483  		ln = int(bytes_to_bint32(b))
   484  		_, _ = p.recvPacketsAlignment(ln) // keys
   485  
   486  		var authData []byte
   487  		var sessionKey []byte
   488  		if isAuthenticated == 0 {
   489  			if p.pluginName == "Srp" || p.pluginName == "Srp256" {
   490  
   491  				// TODO: normalize user
   492  
   493  				if len(data) == 0 {
   494  					p.opContAuth(bigIntToBytes(clientPublic), p.pluginName, PLUGIN_LIST, "")
   495  					b, _ := p.recvPackets(4)
   496  					op := bytes_to_bint32(b)
   497  					if op == op_response {
   498  						_, _, _, err = p._parse_op_response() // error occurred
   499  						return
   500  					}
   501  
   502  					if DEBUG_SRP && op != op_cont_auth {
   503  						panic("auth error")
   504  					}
   505  
   506  					b, _ = p.recvPackets(4)
   507  					ln = int(bytes_to_bint32(b))
   508  					data, _ = p.recvPacketsAlignment(ln)
   509  
   510  					b, _ = p.recvPackets(4)
   511  					ln = int(bytes_to_bint32(b))
   512  					_, _ = p.recvPacketsAlignment(ln) // pluginName
   513  
   514  					b, _ = p.recvPackets(4)
   515  					ln = int(bytes_to_bint32(b))
   516  					_, _ = p.recvPacketsAlignment(ln) // pluginList
   517  
   518  					b, _ = p.recvPackets(4)
   519  					ln = int(bytes_to_bint32(b))
   520  					_, _ = p.recvPacketsAlignment(ln) // keys
   521  				}
   522  
   523  				ln = int(bytes_to_int16(data[:2]))
   524  				serverSalt := data[2 : ln+2]
   525  				serverPublic := bigIntFromHexString(bytes_to_str(data[4+ln:]))
   526  				authData, sessionKey = getClientProof(strings.ToUpper(user), password, serverSalt, clientPublic, serverPublic, clientSecret, p.pluginName)
   527  				if DEBUG_SRP {
   528  					fmt.Printf("pluginName=%s\nserverSalt=%s\nserverPublic(bin)=%s\nserverPublic=%s\nauthData=%v,sessionKey=%v\n",
   529  						p.pluginName, serverSalt, data[4+ln:], serverPublic, authData, sessionKey)
   530  				}
   531  			} else if p.pluginName == "Legacy_Auth" {
   532  				authData = bytes.NewBufferString(crypt.Crypt(password, "9z")[2:]).Bytes()
   533  			} else {
   534  				err = errors.New("_parse_connect_response() Unauthorized")
   535  				return
   536  			}
   537  		}
   538  
   539  		var encrypt_plugin string
   540  		var nonce []byte
   541  
   542  		if opcode == op_cond_accept {
   543  			p.opContAuth(authData, options["auth_plugin_name"], PLUGIN_LIST, "")
   544  			var buf []byte
   545  			_, _, buf, err = p.opResponse()
   546  			if err != nil {
   547  				return
   548  			}
   549  			encrypt_plugin, nonce = p._guess_wire_crypt(buf)
   550  		}
   551  
   552  		wire_crypt := true
   553  		wire_crypt, _ = strconv.ParseBool(options["wire_crypt"])
   554  		if wire_crypt && sessionKey != nil {
   555  			// Send op_crypt
   556  			p.opCrypt(encrypt_plugin)
   557  			p.conn.setCryptKey(encrypt_plugin, sessionKey, nonce)
   558  			_, _, _, err = p.opResponse()
   559  			if err != nil {
   560  				return
   561  			}
   562  		} else {
   563  			p.authData = authData // use later opAttach and opCreate
   564  		}
   565  
   566  	} else {
   567  		if opcode != op_accept {
   568  			err = errors.New("_parse_connect_response() protocol error")
   569  			return
   570  		}
   571  	}
   572  
   573  	return
   574  }
   575  
   576  func (p *wireProtocol) _parse_select_items(buf []byte, xsqlda []xSQLVAR) (int, error) {
   577  	var err error
   578  	var ln int
   579  	index := 0
   580  	i := 0
   581  	for item := int(buf[i]); item != isc_info_end; item = int(buf[i]) {
   582  		i++
   583  		switch item {
   584  		case isc_info_sql_sqlda_seq:
   585  			ln = int(bytes_to_int16(buf[i : i+2]))
   586  			i += 2
   587  			index = int(bytes_to_int32(buf[i : i+ln]))
   588  			i += ln
   589  		case isc_info_sql_type:
   590  			ln = int(bytes_to_int16(buf[i : i+2]))
   591  			i += 2
   592  			sqltype := int(bytes_to_int32(buf[i : i+ln]))
   593  			if sqltype%2 != 0 {
   594  				sqltype--
   595  			}
   596  			xsqlda[index-1].sqltype = sqltype
   597  			i += ln
   598  		case isc_info_sql_sub_type:
   599  			ln = int(bytes_to_int16(buf[i : i+2]))
   600  			i += 2
   601  			xsqlda[index-1].sqlsubtype = int(bytes_to_int32(buf[i : i+ln]))
   602  			i += ln
   603  		case isc_info_sql_scale:
   604  			ln = int(bytes_to_int16(buf[i : i+2]))
   605  			i += 2
   606  			xsqlda[index-1].sqlscale = int(bytes_to_int32(buf[i : i+ln]))
   607  			i += ln
   608  		case isc_info_sql_length:
   609  			ln = int(bytes_to_int16(buf[i : i+2]))
   610  			i += 2
   611  			// the length defined in buffer depends on character length of charset
   612  			xsqlda[index-1].sqllen = int(bytes_to_int32(buf[i : i+ln]))
   613  			i += ln
   614  		case isc_info_sql_null_ind:
   615  			ln = int(bytes_to_int16(buf[i : i+2]))
   616  			i += 2
   617  			xsqlda[index-1].null_ok = bytes_to_int32(buf[i:i+ln]) != 0
   618  			i += ln
   619  		case isc_info_sql_field:
   620  			ln = int(bytes_to_int16(buf[i : i+2]))
   621  			i += 2
   622  			xsqlda[index-1].fieldname = bytes_to_str(buf[i : i+ln])
   623  			i += ln
   624  		case isc_info_sql_relation:
   625  			ln = int(bytes_to_int16(buf[i : i+2]))
   626  			i += 2
   627  			xsqlda[index-1].relname = bytes_to_str(buf[i : i+ln])
   628  			i += ln
   629  		case isc_info_sql_owner:
   630  			ln = int(bytes_to_int16(buf[i : i+2]))
   631  			i += 2
   632  			xsqlda[index-1].ownname = bytes_to_str(buf[i : i+ln])
   633  			i += ln
   634  		case isc_info_sql_alias:
   635  			ln = int(bytes_to_int16(buf[i : i+2]))
   636  			i += 2
   637  			xsqlda[index-1].aliasname = bytes_to_str(buf[i : i+ln])
   638  			i += ln
   639  		case isc_info_truncated:
   640  			return index, err // return next index
   641  		case isc_info_sql_describe_end:
   642  			/* NOTHING */
   643  		default:
   644  			err = errors.New(fmt.Sprintf("Invalid item [%02x] ! i=%d", buf[i], i))
   645  			break
   646  		}
   647  	}
   648  	return -1, err // no more info
   649  }
   650  
   651  func (p *wireProtocol) parse_xsqlda(buf []byte, stmtHandle int32) (int32, []xSQLVAR, error) {
   652  	var ln, col_len, next_index int
   653  	var err error
   654  	var stmt_type int32
   655  	var xsqlda []xSQLVAR
   656  	i := 0
   657  
   658  	for i < len(buf) {
   659  		if buf[i] == byte(isc_info_sql_stmt_type) && buf[i+1] == byte(0x04) && buf[i+2] == byte(0x00) {
   660  			i++
   661  			ln = int(bytes_to_int16(buf[i : i+2]))
   662  			i += 2
   663  			stmt_type = int32(bytes_to_int32(buf[i : i+ln]))
   664  			i += ln
   665  		} else if buf[i] == byte(isc_info_sql_select) && buf[i+1] == byte(isc_info_sql_describe_vars) {
   666  			i += 2
   667  			ln = int(bytes_to_int16(buf[i : i+2]))
   668  			i += 2
   669  			col_len = int(bytes_to_int32(buf[i : i+ln]))
   670  			xsqlda = make([]xSQLVAR, col_len)
   671  			next_index, err = p._parse_select_items(buf[i+ln:], xsqlda)
   672  			for next_index > 0 { // more describe vars
   673  				p.opInfoSql(stmtHandle,
   674  					bytes.Join([][]byte{
   675  						[]byte{isc_info_sql_sqlda_start, 2},
   676  						int16_to_bytes(int16(next_index)),
   677  						_INFO_SQL_SELECT_DESCRIBE_VARS(),
   678  					}, nil))
   679  
   680  				_, _, buf, err = p.opResponse()
   681  				// buf[:2] == []byte{0x04,0x07}
   682  				ln = int(bytes_to_int16(buf[2:4]))
   683  				// bytes_to_int(buf[4:4+l]) == col_len
   684  				next_index, err = p._parse_select_items(buf[4+ln:], xsqlda)
   685  			}
   686  		} else {
   687  			break
   688  		}
   689  	}
   690  
   691  	return stmt_type, xsqlda, err
   692  }
   693  
   694  func (p *wireProtocol) getBlobSegments(blobId []byte, transHandle int32) ([]byte, error) {
   695  	suspendBuf := p.suspendBuffer()
   696  	blob := []byte{}
   697  	p.opOpenBlob(blobId, transHandle)
   698  	blobHandle, _, _, err := p.opResponse()
   699  	if err != nil {
   700  		p.resumeBuffer(suspendBuf)
   701  		return nil, err
   702  	}
   703  
   704  	var rbuf []byte
   705  	var more_data int32
   706  	more_data = 1
   707  	for more_data != 2 {
   708  		p.opGetSegment(blobHandle)
   709  		more_data, _, rbuf, err = p.opResponse()
   710  		buf := rbuf
   711  		for len(buf) > 0 {
   712  			ln := int(bytes_to_int16(buf[0:2]))
   713  			blob = append(blob, buf[2:ln+2]...)
   714  			buf = buf[ln+2:]
   715  		}
   716  	}
   717  
   718  	p.opCloseBlob(blobHandle)
   719  	if p.acceptType == ptype_lazy_send {
   720  		p.lazyResponseCount++
   721  	} else {
   722  		_, _, _, err = p.opResponse()
   723  	}
   724  
   725  	p.resumeBuffer(suspendBuf)
   726  	return blob, err
   727  }
   728  
   729  func (p *wireProtocol) opConnect(dbName string, user string, password string, options map[string]string, clientPublic *big.Int) error {
   730  	p.debugPrint("opConnect")
   731  	wire_crypt := true
   732  	wire_crypt, _ = strconv.ParseBool(options["wire_crypt"])
   733  	protocols := []string{
   734  		// PROTOCOL_VERSION, Arch type (Generic=1), min, max, weight
   735  		"0000000a00000001000000000000000500000002", // 10, 1, 0, 5, 2
   736  		"ffff800b00000001000000000000000500000004", // 11, 1, 0, 5, 4
   737  		"ffff800c00000001000000000000000500000006", // 12, 1, 0, 5, 6
   738  		"ffff800d00000001000000000000000500000008", // 13, 1, 0, 5, 8
   739  		"ffff800e0000000100000000000000050000000a", // 14, 1, 0, 5, 10
   740  		"ffff800f0000000100000000000000050000000c", // 15, 1, 0, 5, 12
   741  		"ffff80100000000100000000000000050000000e", // 16, 1, 0, 5, 14
   742  		"ffff801100000001000000000000000500000010", // 17, 1, 0, 5, 16
   743  	}
   744  	p.packInt(op_connect)
   745  	p.packInt(op_attach)
   746  	p.packInt(3) // CONNECT_VERSION3
   747  	p.packInt(1) // Arch type(GENERIC)
   748  	p.packString(dbName)
   749  	p.packInt(int32(len(protocols)))
   750  	p.packBytes(p.uid(strings.ToUpper(user), password, options["auth_plugin_name"], wire_crypt, clientPublic))
   751  	buf, _ := hex.DecodeString(strings.Join(protocols, ""))
   752  	p.appendBytes(buf)
   753  	_, err := p.sendPackets()
   754  	return err
   755  }
   756  
   757  func (p *wireProtocol) opCreate(dbName string, user string, password string, role string) error {
   758  	p.debugPrint("opCreate")
   759  	var page_size int32
   760  	page_size = 4096
   761  
   762  	encode := bytes.NewBufferString(p.charset).Bytes()
   763  	userBytes := bytes.NewBufferString(strings.ToUpper(user)).Bytes()
   764  	passwordBytes := bytes.NewBufferString(password).Bytes()
   765  	roleBytes := []byte(role)
   766  	dpb := bytes.Join([][]byte{
   767  		[]byte{isc_dpb_version1},
   768  		[]byte{isc_dpb_set_db_charset, byte(len(encode))}, encode,
   769  		[]byte{isc_dpb_lc_ctype, byte(len(encode))}, encode,
   770  		[]byte{isc_dpb_user_name, byte(len(userBytes))}, userBytes,
   771  		[]byte{isc_dpb_password, byte(len(passwordBytes))}, passwordBytes,
   772  		[]byte{isc_dpb_sql_role_name, byte(len(roleBytes))}, roleBytes,
   773  		[]byte{isc_dpb_sql_dialect, 4}, int32_to_bytes(3),
   774  		[]byte{isc_dpb_force_write, 4}, bint32_to_bytes(1),
   775  		[]byte{isc_dpb_overwrite, 4}, bint32_to_bytes(1),
   776  		[]byte{isc_dpb_page_size, 4}, int32_to_bytes(page_size),
   777  		[]byte{isc_dpb_utf8_filename, 1, 1},
   778  	}, nil)
   779  
   780  	if p.authData != nil {
   781  		specificAuthData := bytes.NewBufferString(hex.EncodeToString(p.authData)).Bytes()
   782  		dpb = bytes.Join([][]byte{
   783  			dpb,
   784  			[]byte{isc_dpb_specific_auth_data, byte(len(specificAuthData))}, specificAuthData}, nil)
   785  	}
   786  	if p.timezone != "" {
   787  		tznameBytes := []byte(p.timezone)
   788  		dpb = bytes.Join([][]byte{
   789  			dpb,
   790  			[]byte{isc_dpb_session_time_zone, byte(len(tznameBytes))}, tznameBytes}, nil)
   791  	}
   792  
   793  	p.packInt(op_create)
   794  	p.packInt(0) // Database Object ID
   795  	p.packString(dbName)
   796  	p.packBytes(dpb)
   797  	_, err := p.sendPackets()
   798  	return err
   799  }
   800  
   801  func (p *wireProtocol) opAttach(dbName string, user string, password string, role string) error {
   802  	p.debugPrint("opAttach")
   803  	encode := bytes.NewBufferString(p.charset).Bytes()
   804  	userBytes := bytes.NewBufferString(strings.ToUpper(user)).Bytes()
   805  	passwordBytes := bytes.NewBufferString(password).Bytes()
   806  	roleBytes := []byte(role)
   807  
   808  	processName, err := osext.Executable()
   809  	var processNameBytes []byte
   810  	if err == nil {
   811  		if len(processName) > 255 {
   812  			//limit process name to last 255 symbols
   813  			processName = processName[len(processName)-255:]
   814  		}
   815  
   816  		processNameBytes = bytes.NewBufferString(processName).Bytes()
   817  	}
   818  	pid := int32(os.Getpid())
   819  
   820  	dpb := bytes.Join([][]byte{
   821  		[]byte{isc_dpb_version1},
   822  		[]byte{isc_dpb_sql_dialect, 4}, int32_to_bytes(3),
   823  		[]byte{isc_dpb_lc_ctype, byte(len(encode))}, encode,
   824  		[]byte{isc_dpb_user_name, byte(len(userBytes))}, userBytes,
   825  		[]byte{isc_dpb_password, byte(len(passwordBytes))}, passwordBytes,
   826  		[]byte{isc_dpb_sql_role_name, byte(len(roleBytes))}, roleBytes,
   827  		[]byte{isc_dpb_process_id, 4}, int32_to_bytes(pid),
   828  		[]byte{isc_dpb_process_name, byte(len(processNameBytes))}, processNameBytes,
   829  		[]byte{isc_dpb_utf8_filename, 1, 1},
   830  	}, nil)
   831  
   832  	if p.authData != nil {
   833  		specificAuthData := bytes.NewBufferString(hex.EncodeToString(p.authData)).Bytes()
   834  		dpb = bytes.Join([][]byte{
   835  			dpb,
   836  			[]byte{isc_dpb_specific_auth_data, byte(len(specificAuthData))}, specificAuthData}, nil)
   837  	}
   838  	if p.timezone != "" {
   839  		tznameBytes := []byte(p.timezone)
   840  		dpb = bytes.Join([][]byte{
   841  			dpb,
   842  			[]byte{isc_dpb_session_time_zone, byte(len(tznameBytes))}, tznameBytes}, nil)
   843  	}
   844  
   845  	p.packInt(op_attach)
   846  	p.packInt(0) // Database Object ID
   847  	p.packString(dbName)
   848  	p.packBytes(dpb)
   849  	_, err = p.sendPackets()
   850  	return err
   851  }
   852  
   853  func (p *wireProtocol) opContAuth(authData []byte, authPluginName string, authPluginList string, keys string) error {
   854  	p.debugPrint("opContAuth")
   855  	p.packInt(op_cont_auth)
   856  	p.packString(hex.EncodeToString(authData))
   857  	p.packString(authPluginName)
   858  	p.packString(authPluginList)
   859  	p.packString(keys)
   860  	_, err := p.sendPackets()
   861  	return err
   862  }
   863  
   864  func (p *wireProtocol) opCrypt(plugin string) error {
   865  	p.packInt(op_crypt)
   866  	p.packString(plugin)
   867  	p.packString("Symmetric")
   868  	_, err := p.sendPackets()
   869  	return err
   870  }
   871  
   872  func (p *wireProtocol) opCryptCallback() error {
   873  	p.debugPrint("opCryptCallback")
   874  	p.packInt(op_crypt_key_callback)
   875  	p.packInt(0)
   876  	p.packInt(int32(BUFFER_LEN))
   877  	_, err := p.sendPackets()
   878  	return err
   879  }
   880  
   881  func (p *wireProtocol) opDropDatabase() error {
   882  	p.debugPrint("opDropDatabase")
   883  	p.packInt(op_drop_database)
   884  	p.packInt(p.dbHandle)
   885  	_, err := p.sendPackets()
   886  	return err
   887  }
   888  
   889  func (p *wireProtocol) opTransaction(tpb []byte) error {
   890  	p.debugPrint("opTransaction")
   891  	p.packInt(op_transaction)
   892  	p.packInt(p.dbHandle)
   893  	p.packBytes(tpb)
   894  	_, err := p.sendPackets()
   895  	return err
   896  }
   897  
   898  func (p *wireProtocol) opCommit(transHandle int32) error {
   899  	p.debugPrint("opCommit():%d", transHandle)
   900  	p.packInt(op_commit)
   901  	p.packInt(transHandle)
   902  	_, err := p.sendPackets()
   903  	return err
   904  }
   905  
   906  func (p *wireProtocol) opCommitRetaining(transHandle int32) error {
   907  	p.debugPrint("opCommitRetaining():%d", transHandle)
   908  	p.packInt(op_commit_retaining)
   909  	p.packInt(transHandle)
   910  	_, err := p.sendPackets()
   911  	return err
   912  }
   913  
   914  func (p *wireProtocol) opRollback(transHandle int32) error {
   915  	p.debugPrint("opRollback():%d", transHandle)
   916  	p.packInt(op_rollback)
   917  	p.packInt(transHandle)
   918  	_, err := p.sendPackets()
   919  	return err
   920  }
   921  
   922  func (p *wireProtocol) opRollbackRetaining(transHandle int32) error {
   923  	p.debugPrint("opRollbackRetaining():%d", transHandle)
   924  	p.packInt(op_rollback_retaining)
   925  	p.packInt(transHandle)
   926  	_, err := p.sendPackets()
   927  	return err
   928  }
   929  
   930  func (p *wireProtocol) opAllocateStatement() error {
   931  	p.debugPrint("opAllocateStatement")
   932  	p.packInt(op_allocate_statement)
   933  	p.packInt(p.dbHandle)
   934  	_, err := p.sendPackets()
   935  	return err
   936  }
   937  
   938  func (p *wireProtocol) opInfoTransaction(transHandle int32, b []byte) error {
   939  	p.debugPrint("opInfoTransaction")
   940  	p.packInt(op_info_transaction)
   941  	p.packInt(transHandle)
   942  	p.packInt(0)
   943  	p.packBytes(b)
   944  	p.packInt(int32(BUFFER_LEN))
   945  	_, err := p.sendPackets()
   946  	return err
   947  }
   948  
   949  func (p *wireProtocol) opInfoDatabase(bs []byte) error {
   950  	p.debugPrint("opInfoDatabase")
   951  	p.packInt(op_info_database)
   952  	p.packInt(p.dbHandle)
   953  	p.packInt(0)
   954  	p.packBytes(bs)
   955  	p.packInt(int32(BUFFER_LEN))
   956  	_, err := p.sendPackets()
   957  	return err
   958  }
   959  
   960  func (p *wireProtocol) opFreeStatement(stmtHandle int32, mode int32) error {
   961  	p.debugPrint("opFreeStatement:<%v>", stmtHandle)
   962  	p.packInt(op_free_statement)
   963  	p.packInt(stmtHandle)
   964  	p.packInt(mode)
   965  	_, err := p.sendPackets()
   966  	return err
   967  }
   968  
   969  func (p *wireProtocol) opPrepareStatement(stmtHandle int32, transHandle int32, query string) error {
   970  	p.debugPrint("opPrepareStatement():%d,%d,%v", transHandle, stmtHandle, query)
   971  
   972  	bs := bytes.Join([][]byte{
   973  		[]byte{isc_info_sql_stmt_type},
   974  		_INFO_SQL_SELECT_DESCRIBE_VARS(),
   975  	}, nil)
   976  	p.packInt(op_prepare_statement)
   977  	p.packInt(transHandle)
   978  	p.packInt(stmtHandle)
   979  	p.packInt(3) // dialect = 3
   980  	p.packString(query)
   981  	p.packBytes(bs)
   982  	p.packInt(int32(BUFFER_LEN))
   983  	_, err := p.sendPackets()
   984  	return err
   985  }
   986  
   987  func (p *wireProtocol) opInfoSql(stmtHandle int32, vars []byte) error {
   988  	p.debugPrint("opInfoSql")
   989  	p.packInt(op_info_sql)
   990  	p.packInt(stmtHandle)
   991  	p.packInt(0)
   992  	p.packBytes(vars)
   993  	p.packInt(int32(BUFFER_LEN))
   994  	_, err := p.sendPackets()
   995  	return err
   996  }
   997  
   998  func (p *wireProtocol) opExecute(stmtHandle int32, transHandle int32, params []driver.Value) error {
   999  	p.debugPrint("opExecute():%d,%d,%v", transHandle, stmtHandle, params)
  1000  	p.packInt(op_execute)
  1001  	p.packInt(stmtHandle)
  1002  	p.packInt(transHandle)
  1003  
  1004  	if len(params) == 0 {
  1005  		p.packInt(0) // packBytes([])
  1006  		p.packInt(0)
  1007  		p.packInt(0)
  1008  	} else {
  1009  		blr, values := p.paramsToBlr(transHandle, params, p.protocolVersion)
  1010  		p.packBytes(blr)
  1011  		p.packInt(0)
  1012  		p.packInt(1)
  1013  		p.appendBytes(values)
  1014  	}
  1015  	if p.protocolVersion >= PROTOCOL_VERSION16 {
  1016  		// statement timeout
  1017  		p.appendBytes(bint32_to_bytes(0))
  1018  	}
  1019  	_, err := p.sendPackets()
  1020  	return err
  1021  }
  1022  
  1023  func (p *wireProtocol) opExecute2(stmtHandle int32, transHandle int32, params []driver.Value, outputBlr []byte) error {
  1024  	p.debugPrint("opExecute2")
  1025  	p.packInt(op_execute2)
  1026  	p.packInt(stmtHandle)
  1027  	p.packInt(transHandle)
  1028  
  1029  	if len(params) == 0 {
  1030  		p.packInt(0) // packBytes([])
  1031  		p.packInt(0)
  1032  		p.packInt(0)
  1033  	} else {
  1034  		blr, values := p.paramsToBlr(transHandle, params, p.protocolVersion)
  1035  		p.packBytes(blr)
  1036  		p.packInt(0)
  1037  		p.packInt(1)
  1038  		p.appendBytes(values)
  1039  	}
  1040  
  1041  	p.packBytes(outputBlr)
  1042  	p.packInt(0)
  1043  
  1044  	if p.protocolVersion >= PROTOCOL_VERSION16 {
  1045  		// statement timeout
  1046  		p.appendBytes(bint32_to_bytes(0))
  1047  	}
  1048  
  1049  	_, err := p.sendPackets()
  1050  	return err
  1051  }
  1052  
  1053  func (p *wireProtocol) opFetch(stmtHandle int32, blr []byte) error {
  1054  	p.debugPrint("opFetch")
  1055  	p.packInt(op_fetch)
  1056  	p.packInt(stmtHandle)
  1057  	p.packBytes(blr)
  1058  	p.packInt(0)
  1059  	p.packInt(400)
  1060  	_, err := p.sendPackets()
  1061  	return err
  1062  }
  1063  
  1064  func (p *wireProtocol) opFetchResponse(stmtHandle int32, transHandle int32, xsqlda []xSQLVAR) (*list.List, bool, error) {
  1065  	p.debugPrint("opFetchResponse")
  1066  	b, err := p.recvPackets(4)
  1067  	for bytes_to_bint32(b) == op_dummy {
  1068  		b, _ = p.recvPackets(4)
  1069  	}
  1070  
  1071  	for bytes_to_bint32(b) == op_response && p.lazyResponseCount > 0 {
  1072  		p.lazyResponseCount--
  1073  		p._parse_op_response()
  1074  		b, _ = p.recvPackets(4)
  1075  	}
  1076  	if bytes_to_bint32(b) != op_fetch_response {
  1077  		if bytes_to_bint32(b) == op_response {
  1078  			_, _, _, err := p._parse_op_response()
  1079  			if err != nil {
  1080  				return nil, false, err
  1081  			}
  1082  		}
  1083  		return nil, false, errors.New("opFetchResponse:Internal Error")
  1084  	}
  1085  	b, err = p.recvPackets(8)
  1086  	status := bytes_to_bint32(b[:4])
  1087  	count := int(bytes_to_bint32(b[4:8]))
  1088  	rows := list.New()
  1089  
  1090  	for count > 0 {
  1091  		r := make([]driver.Value, len(xsqlda))
  1092  		if p.protocolVersion < PROTOCOL_VERSION13 {
  1093  			for i, x := range xsqlda {
  1094  				var ln int
  1095  				if x.ioLength() < 0 {
  1096  					b, err = p.recvPackets(4)
  1097  					ln = int(bytes_to_bint32(b))
  1098  				} else {
  1099  					ln = x.ioLength()
  1100  				}
  1101  				raw_value, _ := p.recvPacketsAlignment(ln)
  1102  				b, err = p.recvPackets(4)
  1103  				if bytes_to_bint32(b) == 0 { // Not NULL
  1104  					r[i], err = x.value(raw_value, p.timezone, p.charset)
  1105  				}
  1106  			}
  1107  		} else { // PROTOCOL_VERSION13
  1108  			bi256 := big.NewInt(256)
  1109  			n := len(xsqlda) / 8
  1110  			if len(xsqlda)%8 != 0 {
  1111  				n++
  1112  			}
  1113  			null_indicator := new(big.Int)
  1114  			b, _ := p.recvPacketsAlignment(n)
  1115  			for n = len(b); n > 0; n-- {
  1116  				null_indicator = null_indicator.Mul(null_indicator, bi256)
  1117  				bi := big.NewInt(int64(b[n-1]))
  1118  				null_indicator = null_indicator.Add(null_indicator, bi)
  1119  			}
  1120  
  1121  			for i, x := range xsqlda {
  1122  				if null_indicator.Bit(i) != 0 {
  1123  					continue
  1124  				}
  1125  				var ln int
  1126  				if x.ioLength() < 0 {
  1127  					b, err = p.recvPackets(4)
  1128  					ln = int(bytes_to_bint32(b))
  1129  				} else {
  1130  					ln = x.ioLength()
  1131  				}
  1132  				raw_value, _ := p.recvPacketsAlignment(ln)
  1133  				r[i], err = x.value(raw_value, p.timezone, p.charset)
  1134  			}
  1135  		}
  1136  
  1137  		rows.PushBack(r)
  1138  
  1139  		b, err = p.recvPackets(12)
  1140  		// op := int(bytes_to_bint32(b[:4]))
  1141  		status = bytes_to_bint32(b[4:8])
  1142  		count = int(bytes_to_bint32(b[8:]))
  1143  	}
  1144  
  1145  	return rows, status != 100, err
  1146  }
  1147  
  1148  func (p *wireProtocol) opDetach() error {
  1149  	p.debugPrint("opDetach")
  1150  	p.packInt(op_detach)
  1151  	p.packInt(p.dbHandle)
  1152  	_, err := p.sendPackets()
  1153  	return err
  1154  }
  1155  
  1156  func (p *wireProtocol) opOpenBlob(blobId []byte, transHandle int32) error {
  1157  	p.debugPrint("opOpenBlob")
  1158  	p.packInt(op_open_blob)
  1159  	p.packInt(transHandle)
  1160  	p.appendBytes(blobId)
  1161  	_, err := p.sendPackets()
  1162  	return err
  1163  }
  1164  
  1165  func (p *wireProtocol) opCreateBlob2(transHandle int32) error {
  1166  	p.debugPrint("opCreateBlob2")
  1167  	p.packInt(op_create_blob2)
  1168  	p.packInt(0)
  1169  	p.packInt(transHandle)
  1170  	p.packInt(0)
  1171  	p.packInt(0)
  1172  	_, err := p.sendPackets()
  1173  	return err
  1174  }
  1175  
  1176  func (p *wireProtocol) opGetSegment(blobHandle int32) error {
  1177  	p.debugPrint("opGetSegment")
  1178  	p.packInt(op_get_segment)
  1179  	p.packInt(blobHandle)
  1180  	p.packInt(int32(BUFFER_LEN))
  1181  	p.packInt(0)
  1182  	_, err := p.sendPackets()
  1183  	return err
  1184  }
  1185  
  1186  func (p *wireProtocol) opPutSegment(blobHandle int32, seg_data []byte) error {
  1187  	p.debugPrint("opPutSegment")
  1188  	ln := len(seg_data)
  1189  	p.packInt(op_put_segment)
  1190  	p.packInt(blobHandle)
  1191  	p.packInt(int32(ln))
  1192  	p.packInt(int32(ln))
  1193  	p.appendBytes(seg_data)
  1194  	padding := [3]byte{0x0, 0x0, 0x0}
  1195  	p.appendBytes(padding[:((4 - ln) & 3)])
  1196  	_, err := p.sendPackets()
  1197  	return err
  1198  }
  1199  
  1200  func (p *wireProtocol) opBatchSegments(blobHandle int32, seg_data []byte) error {
  1201  	p.debugPrint("opBatchSegments")
  1202  	ln := len(seg_data)
  1203  	p.packInt(op_batch_segments)
  1204  	p.packInt(blobHandle)
  1205  	p.packInt(int32(ln + 2))
  1206  	p.packInt(int32(ln + 2))
  1207  	pad_length := ((4 - (ln + 2)) & 3)
  1208  	padding := make([]byte, pad_length)
  1209  	p.packBytes([]byte{byte(ln & 255), byte(ln >> 8)}) // little endian int16
  1210  	p.packBytes(seg_data)
  1211  	p.packBytes(padding)
  1212  	_, err := p.sendPackets()
  1213  	return err
  1214  }
  1215  
  1216  func (p *wireProtocol) opCloseBlob(blobHandle int32) error {
  1217  	p.debugPrint("opCloseBlob")
  1218  	p.packInt(op_close_blob)
  1219  	p.packInt(blobHandle)
  1220  	_, err := p.sendPackets()
  1221  	return err
  1222  }
  1223  
  1224  func (p *wireProtocol) opResponse() (int32, []byte, []byte, error) {
  1225  	p.debugPrint("opResponse")
  1226  	b, err := p.recvPackets(4)
  1227  	if err != nil {
  1228  		return 0, nil, nil, err
  1229  	}
  1230  	for bytes_to_bint32(b) == op_dummy {
  1231  		b, _ = p.recvPackets(4)
  1232  	}
  1233  	for bytes_to_bint32(b) == op_crypt_key_callback {
  1234  
  1235  		err = p.opCryptCallback()
  1236  		if err != nil {
  1237  			return 0, nil, nil, err
  1238  		}
  1239  
  1240  		b, _ = p.recvPackets(12)
  1241  		b, _ = p.recvPackets(4)
  1242  
  1243  	}
  1244  	for bytes_to_bint32(b) == op_response && p.lazyResponseCount > 0 {
  1245  		p.lazyResponseCount--
  1246  		_, _, _, _ = p._parse_op_response()
  1247  		b, _ = p.recvPackets(4)
  1248  	}
  1249  
  1250  	if bytes_to_bint32(b) != op_response {
  1251  		if DEBUG_SRP && bytes_to_bint32(b) == op_cont_auth {
  1252  			panic("auth error")
  1253  		}
  1254  		return 0, nil, nil, NewErrOpResonse(bytes_to_bint32(b))
  1255  	}
  1256  	return p._parse_op_response()
  1257  }
  1258  
  1259  func (p *wireProtocol) opSqlResponse(xsqlda []xSQLVAR) ([]driver.Value, error) {
  1260  	p.debugPrint("opSqlResponse")
  1261  	b, err := p.recvPackets(4)
  1262  	for bytes_to_bint32(b) == op_dummy {
  1263  		b, err = p.recvPackets(4)
  1264  	}
  1265  
  1266  	if bytes_to_bint32(b) != op_sql_response {
  1267  		return nil, errors.New("Error op_sql_response")
  1268  	}
  1269  
  1270  	b, err = p.recvPackets(4)
  1271  	count := int(bytes_to_bint32(b))
  1272  	if count == 0 {
  1273  		return nil, nil
  1274  	}
  1275  
  1276  	r := make([]driver.Value, len(xsqlda))
  1277  	var ln int
  1278  
  1279  	if p.protocolVersion < PROTOCOL_VERSION13 {
  1280  		for i, x := range xsqlda {
  1281  			if x.ioLength() < 0 {
  1282  				b, err = p.recvPackets(4)
  1283  				ln = int(bytes_to_bint32(b))
  1284  			} else {
  1285  				ln = x.ioLength()
  1286  			}
  1287  			raw_value, _ := p.recvPacketsAlignment(ln)
  1288  			b, err = p.recvPackets(4)
  1289  			if bytes_to_bint32(b) == 0 { // Not NULL
  1290  				r[i], err = x.value(raw_value, p.timezone, p.charset)
  1291  			}
  1292  		}
  1293  	} else { // PROTOCOL_VERSION13
  1294  		bi256 := big.NewInt(256)
  1295  		n := len(xsqlda) / 8
  1296  		if len(xsqlda)%8 != 0 {
  1297  			n++
  1298  		}
  1299  		null_indicator := new(big.Int)
  1300  		b, _ := p.recvPacketsAlignment(n)
  1301  		for n = len(b); n > 0; n-- {
  1302  			null_indicator = null_indicator.Mul(null_indicator, bi256)
  1303  			bi := big.NewInt(int64(b[n-1]))
  1304  			null_indicator = null_indicator.Add(null_indicator, bi)
  1305  		}
  1306  
  1307  		for i, x := range xsqlda {
  1308  			if null_indicator.Bit(i) != 0 {
  1309  				continue
  1310  			}
  1311  			if x.ioLength() < 0 {
  1312  				b, err = p.recvPackets(4)
  1313  				ln = int(bytes_to_bint32(b))
  1314  			} else {
  1315  				ln = x.ioLength()
  1316  			}
  1317  			raw_value, _ := p.recvPacketsAlignment(ln)
  1318  			r[i], err = x.value(raw_value, p.timezone, p.charset)
  1319  		}
  1320  	}
  1321  
  1322  	return r, err
  1323  }
  1324  
  1325  func (p *wireProtocol) createBlob(value []byte, transHandle int32) ([]byte, error) {
  1326  	buf := p.suspendBuffer()
  1327  	p.opCreateBlob2(transHandle)
  1328  	blobHandle, blobId, _, err := p.opResponse()
  1329  	if err != nil {
  1330  		p.resumeBuffer(buf)
  1331  		return blobId, err
  1332  	}
  1333  
  1334  	i := 0
  1335  	for i < len(value) {
  1336  		end := i + BLOB_SEGMENT_SIZE
  1337  		if end > len(value) {
  1338  			end = len(value)
  1339  		}
  1340  		p.opPutSegment(blobHandle, value[i:end])
  1341  		_, _, _, err := p.opResponse()
  1342  		if err != nil {
  1343  			break
  1344  		}
  1345  		i += BLOB_SEGMENT_SIZE
  1346  	}
  1347  	if err != nil {
  1348  		p.resumeBuffer(buf)
  1349  		return blobId, err
  1350  	}
  1351  
  1352  	if err = p.opCloseBlob(blobHandle); err != nil {
  1353  		return nil, err
  1354  	}
  1355  	_, _, _, err = p.opResponse()
  1356  
  1357  	p.resumeBuffer(buf)
  1358  	return blobId, err
  1359  }
  1360  
  1361  func (p *wireProtocol) paramsToBlr(transHandle int32, params []driver.Value, protocolVersion int32) ([]byte, []byte) {
  1362  	// Convert parameter array to BLR and values format.
  1363  	var v, blr []byte
  1364  	bi256 := big.NewInt(256)
  1365  
  1366  	ln := len(params) * 2
  1367  	blrList := list.New()
  1368  	valuesList := list.New()
  1369  	blrList.PushBack([]byte{5, 2, 4, 0, byte(ln & 255), byte(ln >> 8)})
  1370  
  1371  	if protocolVersion >= PROTOCOL_VERSION13 {
  1372  		nullIndicator := new(big.Int)
  1373  		for i := len(params) - 1; i >= 0; i-- {
  1374  			if params[i] == nil {
  1375  				nullIndicator.SetBit(nullIndicator, i, 1)
  1376  			}
  1377  		}
  1378  		n := len(params) / 8
  1379  		if len(params)%8 != 0 {
  1380  			n++
  1381  		}
  1382  		if n%4 != 0 { // padding
  1383  			n += 4 - n%4
  1384  		}
  1385  		for i := 0; i < n; i++ {
  1386  			var modres *big.Int = new(big.Int)
  1387  			valuesList.PushBack([]byte{byte(modres.Mod(nullIndicator, bi256).Int64())})
  1388  			nullIndicator = nullIndicator.Div(nullIndicator, bi256)
  1389  		}
  1390  	}
  1391  
  1392  	for _, param := range params {
  1393  		switch f := param.(type) {
  1394  		case string:
  1395  			f = p.encodeString(f)
  1396  			b := str_to_bytes(f)
  1397  			if len(b) < MAX_CHAR_LENGTH {
  1398  				blr, v = _bytesToBlr(b)
  1399  			} else {
  1400  				v, _ = p.createBlob(b, transHandle)
  1401  				blr = []byte{9, 0}
  1402  			}
  1403  		case int:
  1404  			blr, v = _int32ToBlr(int32(f))
  1405  		case int16:
  1406  			blr, v = _int32ToBlr(int32(f))
  1407  		case int32:
  1408  			blr, v = _int32ToBlr(f)
  1409  		case int64:
  1410  			blr, v = _int64ToBlr(int64(f))
  1411  		case float64:
  1412  			blr, v = _float64ToBlr(float64(f))
  1413  		case time.Time:
  1414  			if f.Year() == 0 {
  1415  				blr, v = _timeToBlr(f)
  1416  			} else {
  1417  				blr, v = _timestampToBlr(f)
  1418  			}
  1419  		case bool:
  1420  			if f {
  1421  				v = []byte{1, 0, 0, 0}
  1422  			} else {
  1423  				v = []byte{0, 0, 0, 0}
  1424  			}
  1425  			blr = []byte{23}
  1426  		case nil:
  1427  			v = []byte{}
  1428  			blr = []byte{14, 0, 0}
  1429  		case []byte:
  1430  			if len(f) < MAX_CHAR_LENGTH {
  1431  				blr, v = _bytesToBlr(f)
  1432  			} else {
  1433  				v, _ = p.createBlob(f, transHandle)
  1434  				blr = []byte{9, 0}
  1435  			}
  1436  		default:
  1437  			// can't convert directory
  1438  			b := str_to_bytes(fmt.Sprintf("%v", f))
  1439  			if len(b) < MAX_CHAR_LENGTH {
  1440  				blr, v = _bytesToBlr(b)
  1441  			} else {
  1442  				v, _ = p.createBlob(b, transHandle)
  1443  				blr = []byte{9, 0}
  1444  			}
  1445  		}
  1446  		valuesList.PushBack(v)
  1447  		if protocolVersion < PROTOCOL_VERSION13 {
  1448  			if param == nil {
  1449  				valuesList.PushBack([]byte{0xff, 0xff, 0xff, 0xff})
  1450  			} else {
  1451  				valuesList.PushBack([]byte{0, 0, 0, 0})
  1452  			}
  1453  		}
  1454  		blrList.PushBack(blr)
  1455  		blrList.PushBack([]byte{7, 0})
  1456  	}
  1457  	blrList.PushBack([]byte{255, 76}) // [blr_end, blr_eoc]
  1458  
  1459  	blr = flattenBytes(blrList)
  1460  	v = flattenBytes(valuesList)
  1461  
  1462  	return blr, v
  1463  }
  1464  
  1465  func (p *wireProtocol) debugPrint(s string, a ...interface{}) {
  1466  	//if len(a) > 0 {
  1467  	//	s = fmt.Sprintf(s, a...)
  1468  	//}
  1469  	//fmt.Printf("[%x] %s\n", uintptr(unsafe.Pointer(p)), s)
  1470  }
  1471  
  1472  func (p *wireProtocol) opConnectRequest() {
  1473  	p.debugPrint("opConnectRequest()")
  1474  	p.packInt(op_connect_request)
  1475  	p.packInt(p_req_async)
  1476  	p.packInt(p.dbHandle)
  1477  	p.packInt(partner_identification)
  1478  	p.sendPackets()
  1479  }
  1480  
  1481  func (p *wireProtocol) opQueEvents(auxHandle int32, epb []byte, eventId int32) {
  1482  	p.debugPrint("opQueEvents():%d %d", auxHandle, eventId)
  1483  	p.packInt(op_que_events)
  1484  	p.packInt(auxHandle)
  1485  	p.packBytes(epb)
  1486  	p.packInt(address_of_ast_routine)
  1487  	p.packInt(argument_to_ast_routine)
  1488  	p.packInt(eventId)
  1489  	p.sendPackets()
  1490  }
  1491  
  1492  func (p *wireProtocol) opCancelEvents(eventID int32) {
  1493  	p.debugPrint("opCancelEvents():%d", eventID)
  1494  	p.packInt(op_cancel_events)
  1495  	p.packInt(p.dbHandle)
  1496  	p.packInt(eventID)
  1497  	p.sendPackets()
  1498  }
  1499  
  1500  func (p *wireProtocol) opCancel(kind int) error {
  1501  	p.debugPrint("opCancel")
  1502  	p.packInt(op_cancel)
  1503  	p.packInt(int32(kind))
  1504  	_, err := p.sendPackets()
  1505  	return err
  1506  }
  1507  
  1508  func (p *wireProtocol) encodeString(str string) string {
  1509  	switch p.charset {
  1510  	case "OCTETS":
  1511  		return str
  1512  	case "UNICODE_FSS", "UTF8":
  1513  		return str
  1514  	case "SJIS_0208":
  1515  		enc := japanese.ShiftJIS.NewEncoder()
  1516  		v, _ := enc.String(str)
  1517  		return v
  1518  	case "EUCJ_0208":
  1519  		enc := japanese.EUCJP.NewEncoder()
  1520  		v, _ := enc.String(str)
  1521  		return v
  1522  	case "ISO8859_1":
  1523  		enc := charmap.ISO8859_1.NewEncoder()
  1524  		v, _ := enc.String(str)
  1525  		return v
  1526  	case "ISO8859_2":
  1527  		enc := charmap.ISO8859_2.NewEncoder()
  1528  		v, _ := enc.String(str)
  1529  		return v
  1530  	case "ISO8859_3":
  1531  		enc := charmap.ISO8859_3.NewEncoder()
  1532  		v, _ := enc.String(str)
  1533  		return v
  1534  	case "ISO8859_4":
  1535  		enc := charmap.ISO8859_5.NewEncoder()
  1536  		v, _ := enc.String(str)
  1537  		return v
  1538  	case "ISO8859_5":
  1539  		enc := charmap.ISO8859_5.NewEncoder()
  1540  		v, _ := enc.String(str)
  1541  		return v
  1542  	case "ISO8859_6":
  1543  		enc := charmap.ISO8859_6.NewEncoder()
  1544  		v, _ := enc.String(str)
  1545  		return v
  1546  	case "ISO8859_7":
  1547  		enc := charmap.ISO8859_7.NewEncoder()
  1548  		v, _ := enc.String(str)
  1549  		return v
  1550  	case "ISO8859_8":
  1551  		enc := charmap.ISO8859_8.NewEncoder()
  1552  		v, _ := enc.String(str)
  1553  		return v
  1554  	case "ISO8859_9":
  1555  		enc := charmap.ISO8859_9.NewEncoder()
  1556  		v, _ := enc.String(str)
  1557  		return v
  1558  	case "ISO8859_13":
  1559  		enc := charmap.ISO8859_13.NewEncoder()
  1560  		v, _ := enc.String(str)
  1561  		return v
  1562  	case "KSC_5601":
  1563  		enc := korean.EUCKR.NewEncoder()
  1564  		v, _ := enc.String(str)
  1565  		return v
  1566  	case "WIN1250":
  1567  		enc := charmap.Windows1250.NewEncoder()
  1568  		v, _ := enc.String(str)
  1569  		return v
  1570  	case "WIN1251":
  1571  		enc := charmap.Windows1251.NewEncoder()
  1572  		v, _ := enc.String(str)
  1573  		return v
  1574  	case "WIN1252":
  1575  		enc := charmap.Windows1252.NewEncoder()
  1576  		v, _ := enc.String(str)
  1577  		return v
  1578  	case "WIN1253":
  1579  		enc := charmap.Windows1252.NewEncoder()
  1580  		v, _ := enc.String(str)
  1581  		return v
  1582  	case "WIN1254":
  1583  		enc := charmap.Windows1252.NewEncoder()
  1584  		v, _ := enc.String(str)
  1585  		return v
  1586  	case "BIG_5":
  1587  		enc := traditionalchinese.Big5.NewEncoder()
  1588  		v, _ := enc.String(str)
  1589  		return v
  1590  	case "GB_2312":
  1591  		enc := simplifiedchinese.HZGB2312.NewEncoder()
  1592  		v, _ := enc.String(str)
  1593  		return v
  1594  	case "WIN1255":
  1595  		enc := charmap.Windows1255.NewEncoder()
  1596  		v, _ := enc.String(str)
  1597  		return v
  1598  	case "WIN1256":
  1599  		enc := charmap.Windows1256.NewEncoder()
  1600  		v, _ := enc.String(str)
  1601  		return v
  1602  	case "WIN1257":
  1603  		enc := charmap.Windows1257.NewEncoder()
  1604  		v, _ := enc.String(str)
  1605  		return v
  1606  	case "KOI8R":
  1607  		enc := charmap.KOI8R.NewEncoder()
  1608  		v, _ := enc.String(str)
  1609  		return v
  1610  	case "KOI8U":
  1611  		enc := charmap.KOI8U.NewEncoder()
  1612  		v, _ := enc.String(str)
  1613  		return v
  1614  	case "WIN1258":
  1615  		enc := charmap.Windows1258.NewEncoder()
  1616  		v, _ := enc.String(str)
  1617  		return v
  1618  	default:
  1619  		return str // If the specified charset is not supported, return the input string without any modification or encoding.
  1620  	}
  1621  }