diff options
Diffstat (limited to 'custom/extensions/auth-inline.lua')
| -rw-r--r-- | custom/extensions/auth-inline.lua | 66 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 file changed, 25 insertions, 41 deletions
diff --git a/custom/extensions/auth-inline.lua b/custom/extensions/auth-inline.lua index aa4b9f1..5489189 100644 --- a/custom/extensions/auth-inline.lua +++ b/custom/extensions/auth-inline.lua @@ -11,11 +11,9 @@ -- be the same Lua that cgit was built against. Lua 5.5 will not do, because -- luaossl has no 5.5 build. -- --- Serve cgit over HTTPS and terminate TLS in the web server in front of it. --- The session cookie is marked Secure by default, so a browser only sends it --- back over HTTPS, and on an instance served over plain HTTP with no TLS --- anywhere the cookie never comes back and login appears to loop until --- cookie_insecure below is set. +-- The session cookie is marked Secure by default, so a browser only sends +-- it back over HTTPS. On an instance served over plain HTTP login loops +-- until cookie_insecure below is set. -- -- Two libraries are needed. luaossl provides openssl.rand and openssl.hmac and -- lives at <https://github.com/wahern/luaossl>, and luaposix provides @@ -42,16 +40,10 @@ -- luarocks install luaossl OPENSSL_DIR="$(brew --prefix openssl)" -- luarocks install luaposix -- --- Some distributions package both as well, for example lua-luaossl and --- lua-posix on Debian, and such a package has to be built for the same Lua --- version as cgit. --- --- The cookie carries only a user name and there is no server-side session --- store, so deleting an account does not revoke a cookie already issued until --- it expires, and instances that share a secret file accept each other's --- cookies. The login form carries no CSRF token. Both are acceptable for --- gating read access to a git browser, so weigh them before guarding anything --- more sensitive. +-- There is no server-side session store and no CSRF token, so a deleted +-- account's cookie stays valid until it expires and instances sharing a +-- secret file accept each other's cookies. That is acceptable for gating +-- read access to a git browser, so weigh it before guarding anything more. local sysstat = require("posix.sys.stat") local unistd = require("posix.unistd") @@ -59,13 +51,11 @@ local rand = require("openssl.rand") local hmac = require("openssl.hmac") -- The values that follow are the configuration and are meant to be edited. --- Nothing below them needs changing for ordinary use. -- Protected repositories and the users allowed into each. A repository named -- here is protected and one that is not named is public. The repository key --- has to match exactly, while user names match whatever their case. Replace --- the examples below with your own. They are commented out, so an unedited --- copy protects nothing and grants no accounts. +-- has to match exactly, while user names match regardless of case. The +-- examples are commented out, so an unedited copy protects nothing. local protected_repos = { -- ["secret-repo"] = { alice = true, bob = true }, -- ["another"] = { alice = true }, @@ -73,8 +63,6 @@ local protected_repos = { -- Accounts as name and hash. Generate a hash with -- mkpasswd -m sha-512 -R 300000 --- Replace the examples below. They are not real credentials and must not be --- deployed as they stand. local users = { -- alice = "$6$rounds=300000$REPLACE_THIS_SALT$REPLACE_THIS_HASH", -- bob = "$6$rounds=300000$REPLACE_THIS_SALT$REPLACE_THIS_HASH", @@ -95,8 +83,7 @@ local cookie_name = "cgitauth" -- more tightly. local cookie_path = "/" --- Leave this false so the cookie is marked Secure and only travels over HTTPS. --- Set it true only if cgit is served over plain HTTP with no TLS anywhere. +-- Set this true only if cgit is served over plain HTTP with no TLS anywhere. local cookie_insecure = false -- A throwaway hash of the documented shape, used only to spend the same work @@ -108,9 +95,8 @@ local dummy_hash = "$6$rounds=300000$0000000000000000$" -- open decodes is kept here for the calls that follow. local action, http, cgit, post --- The two lookups below, account_hash and repo_userset, are the only part of --- this script that differs from auth-file.lua. Replacing them is all it takes --- to keep accounts somewhere else. +-- The two lookups below, account_hash and repo_userset, are the only part +-- of this script that differs from auth-file.lua. -- The configured tables are folded to lowercased user names once, so that a -- lookup matches whatever case the login form was filled in with, the way @@ -186,14 +172,9 @@ local function pattern_escape(s) return (string.gsub(s, "([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")) end --- The stored token was already URL encoded by secure_value, so it comes back --- verbatim and the write path in set_cookie stays symmetric with this read --- path. 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. +-- The token comes back still URL encoded by secure_value. Decoding it here +-- would break the signature check for any value carrying a percent escape. +-- The name is escaped because it lands in a Lua pattern. function get_cookie(cookies, name) cookies = string.gsub(";" .. (cookies or "") .. ";", "%s*;%s*", ";") return string.match(cookies, ";" .. pattern_escape(name) .. "=(.-);") @@ -478,18 +459,21 @@ function body() html_attr(secure_value("redirect", target, 0)) html("'>") html("<table>") - html("<tr><td><label for='username'>Username:</label></td><td><input id='username' name='username' autocomplete='username' autofocus></td></tr>") - html("<tr><td><label for='password'>Password:</label></td><td><input id='password' name='password' type='password' autocomplete='current-password'></td></tr>") - html("<tr><td colspan='2'><input value='Login' type='submit'></td></tr>") + html("<tr><td><label for='username'>Username:</label></td><td>") + html("<input id='username' name='username'") + html(" autocomplete='username' autofocus></td></tr>") + html("<tr><td><label for='password'>Password:</label></td><td>") + html("<input id='password' name='password' type='password'") + html(" autocomplete='current-password'></td></tr>") + html("<tr><td colspan='2'>") + html("<input value='Login' type='submit'></td></tr>") html("</table></form>") return 0 end --- cgit calls filter_open with the action name followed by the request fields --- in a fixed order, so they are unpacked here into the tables the functions --- above read. Only a post reaches filter_write, carrying the form body, and --- filter_close is where the action finally runs and answers cgit. +-- filter_open unpacks the action and request fields cgit passes in fixed +-- order, filter_write collects a post body, and filter_close runs the action. local actions = {} actions["authenticate-post"] = authenticate_post |
