When writing Lua steps for mysql-proxy, we need to know a few entry functions, through which we can control some of the behavior of Mysql-proxy.
- Connect_server () The function is called when the proxy server accepts a client connection request (a handshake in TCP)
- Read_handshake () will be called when the MySQL server returns the handshake accordingly
- Read_auth () is called when the client sends authentication information (username,password,port,database)
- Read_auth_result (AUT) is called when MySQL returns an authentication result
- Read_query (packet) is called when a client submits an SQL statement
- READ_QUERY_RESULT (INJ) is called when MySQL returns query results
1.connect_server use
function Read_handshake () local con = proxy.connection print ( <--Let's send him some information About Us ) print ( server-addr: " Con.server.dst.name) print ( client-addr: "
--Lets deny clients from!127.0.0.1
if con.client.src.address ~= "127.0.0.1" Then
Proxy.response.type = proxy. Mysqld_packet_err
Proxy.response.errmsg = "Only local connects is allowed"
Print ("We don t like this client");
return Proxy. Proxy_send_result
End
End
Gets the agent's linked object, which is global and can be used directly in the function. From the connection object we can get the client name and server name, through also can obtain the client's IP address, the above code is to prohibit non-native IP login mysql.
2, Read_auth use
The authentication information for the read user includes the user name, password, and database to which to connect. One of the proxies. Mysqld_packet_err is a constant in the mysql-proxy.
functionRead_auth ()LocalCon =proxy.connectionPrint("--there, look, the client was responding to the server auth packet") Print("Username:".. con.client.username)Print("Password:"..String.Format("%q", Con.client.scrambled_password)) Print("default_db:".. con.client.default_db)ifCon.client.username = ="Evil" ThenProxy.response.type=Proxy. Mysqld_packet_err proxy.response.errmsg="Evil logins is not allowed" returnProxy. Proxy_send_resultEndEnd
3.read_auth_result use
Through this method we can obtain the result of the MySQL database authentication, the authentication result is held by the Auth object, we can access its Packet property (string type), can see the return result. The first character of a string is the identification of the result.
functionRead_auth_result (auth)LocalState =auth.packet:byte () //Get the first character and convert it to an integer type ifstate = = Proxy. Mysqld_packet_ok Then Print("<--Auth OK"); ElseIfstate = = Proxy. Mysqld_packet_err Then Print("<--Auth failed"); Else Print("<--auth ... don ' t know:"..String.Format("%q", Auth.packet)); EndEnd
Use of 4.read_query
The SQL statement for the client request is stored in the packet type as a string type. Start with the first character as the identifier. Here the judge is not a query statement, yes, the second character starts the output of the query statement.
functionread_query (packet)Print("- someone sent us a query") ifPacket:byte () = = Proxy.com_query Then Print("query:".. Packet:sub (2)) ifPacket:sub (2) =="SELECT 1" ThenProxy.queries:append (1, packet)End EndEnd
5, Read_query_result use
In fact, we have the function and the Read_query function when we want to handle the SQL statement, but because of the limited time, can not continue to study the SQL processing provided by Mysql-proxy, here first put it out.
functionRead_query_result (INJ)Print("<--... ok, this only gets called when Read_query () told US") Proxy.response= { type=Proxy. Mysqld_packet_raw, packets= { "\255" .. "\255\004"..--errno "#" .. "12s23" .. "Raw, RAW, raw" } } returnProxy. Proxy_send_resultEnd
--[[$%beginlicense%$ Copyright (c), and/or, Oracle, its affiliates. All rights reserved. This program was free software; You can redistribute it and/or modify it under the terms of the GNU general public License as published by the free Softwa Re Foundation; Version 2 of the License. This program was distributed in the hope that it'll be useful, but without any WARRANTY; Without even the implied warranty of merchantability or FITNESS for A particular PURPOSE. See the GNU general public License for more details. You should has received a copy of the GNU general public License along and this program; If not, write to the Free Software Foundation, Inc., Wuyi Franklin St, Fifth Floor, Boston, MA 02110-1301 USA $%endlicense% $ --]]LocalProto =require("Mysql.proto")LocalPrep_stmts = { }functionread_query (packet)LocalCmd_type =Packet:byte ()ifCmd_type = = Proxy.com_stmt_prepare ThenProxy.queries:append (1, packet, {resultset_is_needed =true } ) returnProxy. Proxy_send_queryElseIfCmd_type = = Proxy.com_stmt_execute ThenProxy.queries:append (2, packet, {resultset_is_needed =true } ) returnProxy. Proxy_send_queryElseIfCmd_type = = Proxy.com_stmt_close ThenProxy.queries:append (3, packet, {resultset_is_needed =true } ) returnProxy. Proxy_send_queryEndEndfunctionRead_query_result (INJ)ifInj.id = =1 Then --Print the query we sent LocalStmt_prepare =assert(Proto.from_stmt_prepare_packet (inj.query))Print(("> PREPARE:%s"): Format (stmt_prepare.stmt_text))--And the Stmt-id we got for it ifInj.resultset.raw:byte () = =0 Then LocalSTMT_PREPARE_OK =assert(Proto.from_stmt_prepare_ok_packet (inj.resultset.raw))Print(("< Prepare:stmt-id =%d (Resultset-cols =%d, params =%d)"): Format (stmt_prepare_ok.stmt_id, Stmt_prepare_ok.num_columns, Stmt_prep are_ok.num_params)) prep_stmts[stmt_prepare_ok.stmt_id]={num_columns=Stmt_prepare_ok.num_columns, Num_params=Stmt_prepare_ok.num_params,}End ElseIfInj.id = =2 Then Localstmt_id =assert(Proto.stmt_id_from_stmt_execute_packet (inj.query))LocalStmt_execute =assert(Proto.from_stmt_execute_packet (Inj.query, prep_stmts[stmt_id].num_params))Print(("> Execute:stmt-id =%d"): Format (stmt_execute.stmt_id))ifStmt_execute.new_params_bound Then forNDX, Vinch Ipairs(Stmt_execute.params) Do Print(("[%d]%s (type =%d)"): Format (NDX,ToString(V.value), v.type)) End End ElseIfInj.id = =3 Then LocalStmt_close =assert(Proto.from_stmt_close_packet (inj.query))Print(("> Close:stmt-id =%d"): Format (stmt_close.stmt_id)) prep_stmts[stmt_close.stmt_id]=Nil --Cleanup EndEnd
View Code
The MySQL new interface stmt is used here, and it is not known to be able to view the following connections.
Poke me.
Lua script Programming in Mysql-proxy (i)