The return packet from the server during authentication is
captured by read_auth_result()
. The only
argument to this function is the authentication packet returned
by the server. As the packet is a raw MySQL network protocol
packet, you must access the first byte to identify the packet
type and contents. The MYSQLD_PACKET_ERR
and
MYSQLD_PACKET_OK
constants can be used to
identify whether the authentication was successful:
function read_auth_result(auth) local state = auth.packet:byte() if state == proxy.MYSQLD_PACKET_OK then print("<-- auth ok"); elseif state == proxy.MYSQLD_PACKET_ERR then print("<-- auth failed"); else print("<-- auth ... don't know: " .. string.format("%q", auth.packet)); end end
User Comments
I tried this and "state" ended up being 255, which http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol#Types_Of_Result_Packets tells us is a result packet of type error packet -- these should probably use different constants in the proxy (if they don't already) so as not to be confused with what that page calls a "command packet". (see "Types of Result Packets" on that page)
As well, according to the "Error Packet" section of that same page, the error message starts with byte 10, so what you want in the code is:
print("<-- auth failed ... because: " .. string.format("%q", auth.packet:sub(10)));
this avoids printing out bytecode.
As per http://www.redferni.uklinux.net/mysql/MySQL-Protocol.html, if a long-password-capable client tries to authenticate to a long-password-capable server, but the given user has a short password on the server, then read_auth_result(auth) will be called twice. The first time, auth.packet:byte() will equal 254 (prompting the client to try again using the old password protocol). The second time, auth.packet:byte() will reflect whether the authentication succeeded: ==proxy.MYSQLD_PACKET_OK [ok] or, as previous comment, ==255 [failed].
Add your own comment.