520
520
#define ACL_KEY_LENGTH (IP_ADDR_STRLEN + 1 + NAME_LEN + \
521
521
1 + USERNAME_LENGTH + 1)
523
#if defined(HAVE_OPENSSL)
525
Without SSL the handshake consists of one packet. This packet
526
has both client capabilities and scrambled password.
527
With SSL the handshake might consist of two packets. If the first
528
packet (client capabilities) has CLIENT_SSL flag set, we have to
529
switch to SSL and read the second packet. The scrambled password
530
is in the second packet and client_capabilities field will be ignored.
531
Maybe it is better to accept flags other than CLIENT_SSL from the
534
#define SSL_HANDSHAKE_SIZE 2
535
#define NORMAL_HANDSHAKE_SIZE 6
536
#define MIN_HANDSHAKE_SIZE 2
538
#define MIN_HANDSHAKE_SIZE 6
539
#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
523
/** Size of the header fields of an authentication packet. */
524
#define AUTH_PACKET_HEADER_SIZE_PROTO_41 32
525
#define AUTH_PACKET_HEADER_SIZE_PROTO_40 5
541
527
static DYNAMIC_ARRAY acl_hosts, acl_users, acl_dbs, acl_proxy_users;
542
528
static MEM_ROOT mem, memex;
8552
8538
#ifndef EMBEDDED_LIBRARY
8553
8539
NET *net= mpvio->net;
8541
bool packet_has_required_size= false;
8556
8542
DBUG_ASSERT(mpvio->status == MPVIO_EXT::FAILURE);
8558
if (pkt_len < MIN_HANDSHAKE_SIZE)
8559
return packet_error;
8561
8544
if (mpvio->connect_errors)
8562
8545
reset_host_errors(mpvio->ip);
8564
ulong client_capabilities= uint2korr(net->read_pos);
8565
if (client_capabilities & CLIENT_PROTOCOL_41)
8547
uint charset_code= 0;
8548
end= (char *)net->read_pos;
8550
In order to safely scan a head for '\0' string terminators
8551
we must keep track of how many bytes remain in the allocated
8552
buffer or we might read past the end of the buffer.
8554
size_t bytes_remaining_in_packet= pkt_len;
8557
Peek ahead on the client capability packet and determine which version of
8558
the protocol should be used.
8560
if (bytes_remaining_in_packet < 2)
8561
return packet_error;
8563
mpvio->client_capabilities= uint2korr(end);
8566
JConnector only sends server capabilities before starting SSL
8567
negotiation. The below code is patch for this.
8569
if (bytes_remaining_in_packet == 4 &&
8570
mpvio->client_capabilities & CLIENT_SSL)
8567
client_capabilities|= ((ulong) uint2korr(net->read_pos + 2)) << 16;
8568
mpvio->max_client_packet_length= uint4korr(net->read_pos + 4);
8569
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
8570
if (mpvio->charset_adapter->init_client_charset((uint) net->read_pos[8]))
8572
mpvio->client_capabilities= uint4korr(end);
8573
mpvio->max_client_packet_length= 0xfffff;
8574
charset_code= default_charset_info->number;
8575
if (mpvio->charset_adapter->init_client_charset(charset_code))
8571
8576
return packet_error;
8572
end= (char*) net->read_pos + 32;
8576
mpvio->max_client_packet_length= uint3korr(net->read_pos + 2);
8577
end= (char*) net->read_pos + 5;
8580
/* Disable those bits which are not supported by the client. */
8581
mpvio->client_capabilities&= client_capabilities;
8580
if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
8581
packet_has_required_size= bytes_remaining_in_packet >=
8582
AUTH_PACKET_HEADER_SIZE_PROTO_41;
8584
packet_has_required_size= bytes_remaining_in_packet >=
8585
AUTH_PACKET_HEADER_SIZE_PROTO_40;
8587
if (!packet_has_required_size)
8588
return packet_error;
8590
if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
8592
mpvio->client_capabilities= uint4korr(end);
8593
mpvio->max_client_packet_length= uint4korr(end + 4);
8594
charset_code= (uint)(uchar)*(end + 8);
8596
Skip 23 remaining filler bytes which have no particular meaning.
8598
end+= AUTH_PACKET_HEADER_SIZE_PROTO_41;
8599
bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_PROTO_41;
8603
mpvio->client_capabilities= uint2korr(end);
8604
mpvio->max_client_packet_length= uint3korr(end + 2);
8605
end+= AUTH_PACKET_HEADER_SIZE_PROTO_40;
8606
bytes_remaining_in_packet-= AUTH_PACKET_HEADER_SIZE_PROTO_40;
8608
Old clients didn't have their own charset. Instead the assumption
8609
was that they used what ever the server used.
8611
charset_code= default_charset_info->number;
8614
DBUG_PRINT("info", ("client_character_set: %u", charset_code));
8615
if (mpvio->charset_adapter->init_client_charset(charset_code))
8616
return packet_error;
8584
8619
#if defined(HAVE_OPENSSL)
8585
8620
DBUG_PRINT("info", ("client capabilities: %lu", mpvio->client_capabilities));
8623
If client requested SSL then we must stop parsing, try to switch to SSL,
8624
and wait for the client to send a new handshake packet.
8625
The client isn't expected to send any more bytes until SSL is initialized.
8586
8627
if (mpvio->client_capabilities & CLIENT_SSL)
8588
8629
unsigned long errptr;
8601
8642
DBUG_PRINT("info", ("Reading user information over SSL layer"));
8602
pkt_len= my_net_read(net);
8603
if (pkt_len == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE)
8643
if ((pkt_len= my_net_read(net)) == packet_error)
8605
8645
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
8607
8647
return packet_error;
8650
A new packet was read and the statistics reflecting the remaining bytes
8651
in the packet must be updated.
8653
bytes_remaining_in_packet= pkt_len;
8656
After the SSL handshake is performed the client resends the handshake
8657
packet but because of legacy reasons we chose not to parse the packet
8658
fields a second time and instead only assert the length of the packet.
8660
if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
8662
packet_has_required_size= bytes_remaining_in_packet >=
8663
AUTH_PACKET_HEADER_SIZE_PROTO_41;
8664
end= (char *)net->read_pos + AUTH_PACKET_HEADER_SIZE_PROTO_41;
8665
bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_41;
8669
packet_has_required_size= bytes_remaining_in_packet >=
8670
AUTH_PACKET_HEADER_SIZE_PROTO_40;
8671
end= (char *)net->read_pos + AUTH_PACKET_HEADER_SIZE_PROTO_40;
8672
bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_40;
8675
if (!packet_has_required_size)
8676
return packet_error;
8612
if (end > (char *)net->read_pos + pkt_len)
8613
return packet_error;
8678
#endif /* HAVE_OPENSSL */
8615
8680
if ((mpvio->client_capabilities & CLIENT_TRANSACTIONS) &&
8616
8681
opt_using_transactions)