diff options
context:
space:
mode:
-rw-r--r--custom/extensions/auth-file.lua18
-rw-r--r--custom/extensions/auth-inline.lua11
2 files changed, 26 insertions, 3 deletions
diff --git a/custom/extensions/auth-file.lua b/custom/extensions/auth-file.lua
index 5415ca7..9c9c2ee 100644
--- a/custom/extensions/auth-file.lua
+++ b/custom/extensions/auth-file.lua
@@ -136,6 +136,11 @@ end
-- Return the stored password hash for a user, or nil. Reads the users file
-- fresh each call. A missing or unreadable file, and any unparsable line, are
-- skipped rather than fatal.
+--
+-- The hash is trimmed as well as the name. f:lines() strips the newline but
+-- not a carriage return, so a users file saved with CRLF endings would
+-- otherwise hand crypt a hash with a trailing \r and fail every login with
+-- nothing in the log to say why.
function account_hash(user)
if user == nil then
return nil
@@ -149,7 +154,7 @@ function account_hash(user)
local u, h = string.match(line, "(.-):(.+)")
if u ~= nil and trim(u):lower() == wanted then
f:close()
- return h
+ return trim(h)
end
end
f:close()
@@ -234,13 +239,22 @@ function parse_qs(qs)
return tab
end
+-- Escape the Lua pattern magic characters, so a name is matched literally.
+local function pattern_escape(s)
+ return (string.gsub(s, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1"))
+end
+
-- Return the value of the named cookie, or nil. The stored token was already
-- url-encoded by secure_value, so it is returned verbatim, which keeps the
-- write path (set_cookie) and the read path symmetric. Decoding it here would
-- break the signature check for any value carrying a percent escape.
+--
+-- The name is escaped because it lands in a pattern. A cookie_name holding a
+-- magic character, say "cgit-auth", would otherwise read as a pattern and stop
+-- matching its own cookie while matching names nobody configured.
function get_cookie(cookies, name)
cookies = string.gsub(";" .. (cookies or "") .. ";", "%s*;%s*", ";")
- return string.match(cookies, ";" .. name .. "=(.-);")
+ return string.match(cookies, ";" .. pattern_escape(name) .. "=(.-);")
end
function tohex(b)
diff --git a/custom/extensions/auth-inline.lua b/custom/extensions/auth-inline.lua
index 168a444..0cd9da9 100644
--- a/custom/extensions/auth-inline.lua
+++ b/custom/extensions/auth-inline.lua
@@ -206,13 +206,22 @@ function parse_qs(qs)
return tab
end
+-- Escape the Lua pattern magic characters, so a name is matched literally.
+local function pattern_escape(s)
+ return (string.gsub(s, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1"))
+end
+
-- Return the value of the named cookie, or nil. The stored token was already
-- url-encoded by secure_value, so it is returned verbatim, which keeps the
-- write path (set_cookie) and the read path symmetric. Decoding it here would
-- break the signature check for any value carrying a percent escape.
+--
+-- The name is escaped because it lands in a pattern. A cookie_name holding a
+-- magic character, say "cgit-auth", would otherwise read as a pattern and stop
+-- matching its own cookie while matching names nobody configured.
function get_cookie(cookies, name)
cookies = string.gsub(";" .. (cookies or "") .. ";", "%s*;%s*", ";")
- return string.match(cookies, ";" .. name .. "=(.-);")
+ return string.match(cookies, ";" .. pattern_escape(name) .. "=(.-);")
end
function tohex(b)