652
650
bool Session::authenticate()
654
/* Use "connect_timeout" value during connection phase */
655
drizzleclient_net_set_read_timeout(&net, connect_timeout);
656
drizzleclient_net_set_write_timeout(&net, connect_timeout);
660
bool connection_is_valid= _checkConnection();
661
drizzleclient_net_end_statement(this);
663
if (! connection_is_valid)
665
/* We got wrong permissions from _checkConnection() */
666
statistic_increment(aborted_connects, &LOCK_status);
670
/* Connect completed, set read/write timeouts back to default */
671
drizzleclient_net_set_read_timeout(&net, variables.net_read_timeout);
672
drizzleclient_net_set_write_timeout(&net, variables.net_write_timeout);
676
bool Session::_checkConnection()
685
if (drizzleclient_net_peer_addr(&net, ip, &peer_port, NI_MAXHOST))
687
my_error(ER_BAD_HOST_ERROR, MYF(0), security_ctx.ip.c_str());
691
security_ctx.ip.assign(ip);
693
drizzleclient_net_keepalive(&net, true);
695
uint32_t server_capabilites;
697
/* buff[] needs to big enough to hold the server_version variable */
698
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
700
server_capabilites= CLIENT_BASIC_FLAGS;
703
server_capabilites|= CLIENT_COMPRESS;
704
#endif /* HAVE_COMPRESS */
706
end= buff + strlen(server_version);
707
if ((end - buff) >= SERVER_VERSION_LENGTH)
708
end= buff + (SERVER_VERSION_LENGTH - 1);
709
memcpy(buff, server_version, end - buff);
713
int4store((unsigned char*) end, thread_id);
716
So as _checkConnection is the only entry point to authorization
717
procedure, scramble is set here. This gives us new scramble for
720
drizzleclient_create_random_string(scramble, SCRAMBLE_LENGTH, &rand);
722
Old clients does not understand long scrambles, but can ignore packet
723
tail: that's why first part of the scramble is placed here, and second
724
part at the end of packet.
726
end= strncpy(end, scramble, SCRAMBLE_LENGTH_323);
727
end+= SCRAMBLE_LENGTH_323;
729
*end++= 0; /* an empty byte for some reason */
731
int2store(end, server_capabilites);
732
/* write server characteristics: up to 16 bytes allowed */
733
end[2]=(char) default_charset_info->number;
734
int2store(end+3, server_status);
735
memset(end+5, 0, 13);
737
/* write scramble tail */
738
size_t scramble_len= SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323;
739
end= strncpy(end, scramble + SCRAMBLE_LENGTH_323, scramble_len);
742
*end++= 0; /* an empty byte for some reason */
744
/* At this point we write connection message and read reply */
745
if (drizzleclient_net_write_command(&net
746
, (unsigned char) protocol_version
747
, (unsigned char*) ""
749
, (unsigned char*) buff
750
, (size_t) (end-buff))
751
|| (pkt_len= drizzleclient_net_read(&net)) == packet_error
752
|| pkt_len < MIN_HANDSHAKE_SIZE)
754
my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
758
if (packet.alloc(variables.net_buffer_length))
759
return false; /* The error is set by alloc(). */
761
client_capabilities= uint2korr(net.read_pos);
764
client_capabilities|= ((uint32_t) uint2korr(net.read_pos + 2)) << 16;
765
max_client_packet_length= uint4korr(net.read_pos + 4);
767
end= (char*) net.read_pos + 32;
770
Disable those bits which are not supported by the server.
771
This is a precautionary measure, if the client lies. See Bug#27944.
773
client_capabilities&= server_capabilites;
775
if (end >= (char*) net.read_pos + pkt_len + 2)
777
my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
781
net.return_status= &server_status;
784
char *passwd= strchr(user, '\0')+1;
785
uint32_t user_len= passwd - user - 1;
787
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
788
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
789
uint32_t dummy_errors;
792
Old clients send null-terminated string as password; new clients send
793
the size (1 byte) + string (not null-terminated). Hence in case of empty
794
password both send '\0'.
796
This strlen() can't be easily deleted without changing protocol.
798
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
799
*passwd > 127 and become 2**32-127+ after casting to uint.
801
uint32_t passwd_len= client_capabilities & CLIENT_SECURE_CONNECTION ?
802
(unsigned char)(*passwd++) : strlen(passwd);
803
l_db= client_capabilities & CLIENT_CONNECT_WITH_DB ? l_db + passwd_len + 1 : 0;
805
/* strlen() can't be easily deleted without changing protocol */
806
uint32_t db_len= l_db ? strlen(l_db) : 0;
808
if (passwd + passwd_len + db_len > (char *) net.read_pos + pkt_len)
810
my_error(ER_HANDSHAKE_ERROR, MYF(0), security_ctx.ip.c_str());
814
/* Since 4.1 all database names are stored in utf8 */
817
db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
820
charset(), &dummy_errors)]= 0;
824
user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
825
system_charset_info, user, user_len,
826
charset(), &dummy_errors)]= '\0';
829
/* If username starts and ends in "'", chop them off */
830
if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
837
security_ctx.user.assign(user);
839
return checkUser(passwd, passwd_len, l_db);
653
if (protocol->authenticate())
656
statistic_increment(aborted_connects, &LOCK_status);
842
660
bool Session::checkUser(const char *passwd, uint32_t passwd_len, const char *in_db)
903
720
lex->current_select= 0;
906
This thread will do a blocking read from the client which
907
will be interrupted when the next command is received from
908
the client, the connection is closed or "net_wait_timeout"
909
number of seconds has passed
911
drizzleclient_net_set_read_timeout(&net, variables.net_wait_timeout);
914
XXX: this code is here only to clear possible errors of init_connect.
915
Consider moving to init_connect() instead.
917
clear_error(); // Clear error message
918
main_da.reset_diagnostics_area();
920
net_new_transaction(&net);
922
packet_length= drizzleclient_net_read(&net);
923
if (packet_length == packet_error)
925
/* Check if we can continue without closing the connection */
927
if(net.last_errno== CR_NET_PACKET_TOO_LARGE)
928
my_error(ER_NET_PACKET_TOO_LARGE, MYF(0));
929
/* Assert is invalid for dirty connection shutdown
930
* assert(session->is_error());
932
drizzleclient_net_end_statement(this);
936
return_value= false; // We have to close it.
945
l_packet= (char*) net.read_pos;
947
'packet_length' contains length of data, as it was stored in packet
948
header. In case of malformed header, drizzleclient_net_read returns zero.
949
If packet_length is not zero, drizzleclient_net_read ensures that the returned
950
number of bytes was actually read from network.
951
There is also an extra safety measure in drizzleclient_net_read:
952
it sets packet[packet_length]= 0, but only for non-zero packets.
954
if (packet_length == 0) /* safety */
956
/* Initialize with COM_SLEEP packet */
957
l_packet[0]= (unsigned char) COM_SLEEP;
960
/* Do not rely on drizzleclient_net_read, extra safety against programming errors. */
961
l_packet[packet_length]= '\0'; /* safety */
722
if (protocol->read_command(&l_packet, &packet_length) == false)
725
if (packet_length == 0)
963
728
l_command= (enum enum_server_command) (unsigned char) l_packet[0];
965
730
if (command >= COM_END)
966
731
command= COM_END; // Wrong command
968
/* Restore read timeout value */
969
drizzleclient_net_set_read_timeout(&net, variables.net_read_timeout);
971
733
assert(packet_length);
972
return_value= ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
734
return ! dispatch_command(l_command, this, l_packet+1, (uint32_t) (packet_length-1));
978
737
bool Session::readAndStoreQuery(const char *in_packet, uint32_t in_packet_length)