From edf340e359fe209797c584a387f897ac09c90b8b Mon Sep 17 00:00:00 2001 From: Alex Dowad Date: Mon, 18 Apr 2022 11:47:49 +0200 Subject: [PATCH] Support 'trust' authentication method In the PostgreSQL server's response to the initial login packet, it includes a field indicating what kind of authentication the server would like the client to use. We were not checking that field. If it is 0, that means no authentication is needed and the client can just go ahead. As a bonus, since we are now checking the value of that field, we can provide a more specific error message if the server wants to use an authentication type which this library does not currently support. --- lib/resty/postgres.lua | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/lib/resty/postgres.lua b/lib/resty/postgres.lua index 6907180..3e481ba 100644 --- a/lib/resty/postgres.lua +++ b/lib/resty/postgres.lua @@ -230,23 +230,31 @@ function connect(self, opts) if typ ~= 'R' then return nil, "handshake error, got packet type:" .. typ end - local auth_type = string.sub(packet, 1, 4) - local salt = string.sub(packet, 5, 8) - -- send passsowrd - req = {_to_cstring(_compute_token(self, user, password, salt))} - req_len = 40 - local bytes, err = _send_packet(self, req, req_len, 'p') - if not bytes then - return nil, "failed to send client authentication packet2: " .. err - end - -- receive response - packet, typ, err = _recv_packet(self) - if typ ~= 'R' then - return nil, "auth return type not support" - end - if packet ~= AUTH_REQ_OK then - return nil, "authentication failed" + local auth_type = _get_byte4(packet, 1) + + if auth_type == 5 then + -- Authentication type 5 is MD5 password encryption + local salt = string.sub(packet, 5, 8) + -- send password + req = {_to_cstring(_compute_token(self, user, password, salt))} + req_len = 40 + local bytes, err = _send_packet(self, req, req_len, 'p') + if not bytes then + return nil, "failed to send client authentication packet2: " .. err + end + -- receive response + packet, typ, err = _recv_packet(self) + if typ ~= 'R' then + return nil, "authentication response packet type was '"..typ.."'; expected 'R'" + end + if packet ~= AUTH_REQ_OK then + return nil, "authentication failed" + end + elseif auth_type ~= 0 then + -- 0 means authentication was already successful (with no password required) + return nil, "authentication failed: server wants to use type "..auth_type..", but we only support MD5 password encryption (type 5)" end + while true do packet, typ, err = _recv_packet(self) if not packet then