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 }