mirror of
https://github.com/zeek/zeek.git
synced 2025-10-06 16:48:19 +00:00
mysql: Add mysql_auth_plugin, mysql_auth_more_data and mysql_auth_switch_request events
Remove caching_sha2_password parsing/state from the analyzer and implement the generic events. If we actually want to peak into the authentication mechanism, we could write a separate analyzer for it. For now, treat it as opaque values that are exposed to script land. The added tests show the --get-server-public-key in use where mysql_auth_more_data contains an RSA public key.
This commit is contained in:
parent
8a92945b06
commit
40f1c2cb6d
7 changed files with 151 additions and 62 deletions
|
@ -142,9 +142,7 @@ enum state {
|
|||
|
||||
enum ConnectionExpected {
|
||||
EXPECT_HANDSHAKE,
|
||||
EXPECT_SHA2_AUTH,
|
||||
EXPECT_PUB_KEY,
|
||||
EXPECT_AUTH_SWITCH_RESP,
|
||||
EXPECT_AUTH_DATA,
|
||||
};
|
||||
|
||||
enum Expected {
|
||||
|
@ -157,7 +155,6 @@ enum Expected {
|
|||
EXPECT_RESULTSET,
|
||||
EXPECT_REST_OF_PACKET,
|
||||
EXPECT_AUTH_SWITCH,
|
||||
EXPECT_SHA2_AUTH_RESP,
|
||||
};
|
||||
|
||||
enum EOFType {
|
||||
|
@ -176,12 +173,6 @@ enum Client_Capabilities {
|
|||
CLIENT_QUERY_ATTRIBUTES = 0x08000000,
|
||||
};
|
||||
|
||||
enum SHA2_Auth_State {
|
||||
REQUEST_PUBLIC_KEY = 2,
|
||||
FAST_AUTH_SUCCESS = 3,
|
||||
PERFORM_FULL_AUTHENTICATION = 4,
|
||||
};
|
||||
|
||||
type NUL_String = RE/[^\0]*\0/;
|
||||
type EmptyOrNUL_String = RE/([^\0]*\0)?/;
|
||||
|
||||
|
@ -304,7 +295,10 @@ type Handshake_Plain_v10(cap_flags: uint32) = record {
|
|||
} &let {
|
||||
update_auth_plugin: bool = $context.connection.set_auth_plugin(auth_plugin)
|
||||
&if( cap_flags & CLIENT_PLUGIN_AUTH );
|
||||
update_expected: bool = $context.connection.update_expected_from_auth()
|
||||
|
||||
# Switch client state into expecting more auth data. If the server responds
|
||||
# with an OK_Packet before, will switch into COMMAND_PHASE.
|
||||
update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_AUTH_DATA)
|
||||
&if( cap_flags & CLIENT_PLUGIN_AUTH );
|
||||
};
|
||||
|
||||
|
@ -334,46 +328,11 @@ type Handshake_Response_Packet_v9 = record {
|
|||
password : bytestring &restofdata;
|
||||
};
|
||||
|
||||
# SHA2 Auth
|
||||
|
||||
type SHA2_Auth_Packet = record {
|
||||
state: bytestring &restofdata;
|
||||
} &let {
|
||||
update_state : bool = $context.connection.update_state(COMMAND_PHASE)
|
||||
&if(state[0] == FAST_AUTH_SUCCESS);
|
||||
update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_PUB_KEY)
|
||||
&if(state[1] == REQUEST_PUBLIC_KEY);
|
||||
};
|
||||
|
||||
type Public_Key_Packet = record {
|
||||
pad : uint8;
|
||||
pub_key: bytestring &restofdata;
|
||||
} &let {
|
||||
update_expectation: bool = $context.connection.set_next_expected(EXPECT_SHA2_AUTH_RESP);
|
||||
};
|
||||
|
||||
type SHA2_Auth_Response_Packet = record {
|
||||
data: bytestring &restofdata;
|
||||
} &let {
|
||||
update_state: bool = $context.connection.update_state(COMMAND_PHASE);
|
||||
};
|
||||
|
||||
# Auth Switch
|
||||
|
||||
type Auth_Switch_Response_Packet = record {
|
||||
data : bytestring &restofdata;
|
||||
} &let {
|
||||
update_expected: bool = $context.connection.update_expected_from_auth();
|
||||
};
|
||||
|
||||
# Connection Phase
|
||||
|
||||
type Connection_Phase_Packets = case $context.connection.get_conn_expectation() of {
|
||||
EXPECT_HANDSHAKE -> handshake_resp : Handshake_Response_Packet;
|
||||
EXPECT_SHA2_AUTH -> sha2_auth : SHA2_Auth_Packet;
|
||||
EXPECT_PUB_KEY -> pub_key : Public_Key_Packet;
|
||||
EXPECT_AUTH_SWITCH_RESP -> atuh_switch_resp : Auth_Switch_Response_Packet;
|
||||
default -> unknown : empty;
|
||||
EXPECT_HANDSHAKE -> handshake_resp: Handshake_Response_Packet;
|
||||
EXPECT_AUTH_DATA -> auth_data: AuthMoreData(true);
|
||||
};
|
||||
|
||||
# Command Request
|
||||
|
@ -420,7 +379,6 @@ type Command_Response(pkt_len: uint32) = case $context.connection.get_expectatio
|
|||
EXPECT_REST_OF_PACKET -> rest : bytestring &restofdata;
|
||||
EXPECT_STATUS -> status : Command_Response_Status;
|
||||
EXPECT_AUTH_SWITCH -> auth_switch : AuthSwitchRequest;
|
||||
EXPECT_SHA2_AUTH_RESP -> sha2_auth_resp: SHA2_Auth_Response_Packet;
|
||||
EXPECT_EOF_THEN_RESULTSET -> eof : EOFIfLegacyThenResultset(pkt_len);
|
||||
default -> unknown : empty;
|
||||
};
|
||||
|
@ -429,6 +387,10 @@ type Command_Response_Status = record {
|
|||
pkt_type: uint8;
|
||||
response: case pkt_type of {
|
||||
0x00 -> data_ok: OK_Packet;
|
||||
# When still in the CONNECTION_PHASE, the server can reply
|
||||
# with AuthMoreData which is 0x01 stuffed opaque payload.
|
||||
# https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_packets_protocol_auth_more_data.html
|
||||
0x01 -> auth_more_data: AuthMoreData(false);
|
||||
0xfe -> data_eof: EOF_Packet(EOF_END);
|
||||
0xff -> data_err: ERR_Packet;
|
||||
default -> unknown: empty;
|
||||
|
@ -523,13 +485,20 @@ type ColumnDefinition41(first_byte: uint8) = record {
|
|||
filler : padding[2];
|
||||
};
|
||||
|
||||
# Opaque auth data exchanged during the connection phase between client and server.
|
||||
type AuthMoreData(is_orig: bool) = record {
|
||||
data : bytestring &restofdata;
|
||||
};
|
||||
|
||||
type AuthSwitchRequest = record {
|
||||
status: uint8 &enforce(status==254);
|
||||
name : NUL_String;
|
||||
data : bytestring &restofdata;
|
||||
} &let {
|
||||
update_auth_plugin : bool = $context.connection.set_auth_plugin(name);
|
||||
update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_AUTH_SWITCH_RESP);
|
||||
update_conn_expectation: bool = $context.connection.set_next_conn_expected(EXPECT_AUTH_DATA);
|
||||
# After an AuthSwitchRequest, server replies with OK_Packet, ERR_Packet or AuthMoreData.
|
||||
update_expectation: bool = $context.connection.set_next_expected(EXPECT_STATUS);
|
||||
};
|
||||
|
||||
type ColumnDefinition320 = record {
|
||||
|
@ -638,18 +607,6 @@ refine connection MySQL_Conn += {
|
|||
return true;
|
||||
%}
|
||||
|
||||
function update_expected_from_auth(): bool
|
||||
%{
|
||||
if ( auth_plugin_ == "caching_sha2_password" )
|
||||
{
|
||||
conn_expected_ = EXPECT_SHA2_AUTH;
|
||||
if ( expected_ == EXPECT_AUTH_SWITCH )
|
||||
expected_ = EXPECT_STATUS;
|
||||
}
|
||||
|
||||
return true;
|
||||
%}
|
||||
|
||||
function get_deprecate_eof(): bool
|
||||
%{
|
||||
return deprecate_eof_;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue