/usr/share/lua/5.1/cgilua/authentication.lua is in lua-cgi 5.2~alpha2-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 | -- CGILua authentication Module
-- Author: Leonardo Godinho
--
-- Offers a basic API for authentication assuming the presence of
-- cgilua.POST.user, cgilua.POST.pass, cgilua.QUERY.logout, cgilua.QUERY[tokenName]
--
-- The API consists in the functions
-- check(username, passwd) - Checks if the pair username/passwd is authenticated by the configured method
-- checkURL() - returns the URL for the checking script
-- configure(options, methods) - configures the authentication framework (see /examples/authentication_conf.lua)
-- logoutURL() - returns the URL for the logout page
-- refURL() - returns the original URL being checked for authentication
-- username() - returns the authenticated user if existent
--
-- The authenticated user can be persisted by using a cookie or an ID in the URL
--
-- $Id: authentication.lua,v 1.2 2007/12/05 19:41:13 carregal Exp $
local mime=require"mime" -- from LuaSocket
local md5=require"md5"
local cookies = require"cgilua.cookies"
local cgilua = require"cgilua"
local string = require"string"
local math = require"math"
local error = error
local M = {}
local authenticatedUser
local configuration
local _check -- check function provided by the configuration
-- Callback functions to manipulate Tokens in the URL
-- if not defined, CGILua standard URLs are assumed
-- Returns the current token
function M.getToken()
return cgilua.QUERY[configuration.tokenName]
end
-- Sets the current token
function M.setToken(token)
cgilua.QUERY[configuration.tokenName] = token
end
-- Returns the current URL
function M.currentURL()
local script_name = cgilua.servervariable"SCRIPT_NAME"
local path_info = cgilua.servervariable"PATH_INFO" or ""
local query_string = cgilua.servervariable"QUERY_STRING" or ""
if query_string ~= "" then
query_string = "?"..query_string
end
return cgilua.mkabsoluteurl(script_name..path_info..query_string)
end
-- URL Base64 encoder and decoder functions
-- (http://en.wikipedia.org/wiki/Base64)
--
-- '=' is replaced by ''
-- '+' and '/' are respectively replaced by '*' and '-'
function M.encodeURLbase64(str)
local b64str = mime.b64(str)
local urlb64str = string.gsub(b64str,"=","")
urlb64str = string.gsub(urlb64str,"+","*")
urlb64str = string.gsub(urlb64str,"/","-")
urlb64str = string.gsub(urlb64str," ","_")
return urlb64str
end
function M.decodeURLbase64(urlb64str)
local b64str = string.gsub(urlb64str,"*","+")
b64str = string.gsub(b64str,"-","/")
b64str = string.gsub(b64str,"_"," ")
local b64strPadLen = math.fmod(4 - math.fmod(string.len(b64str), 4), 4)
b64str = b64str..string.rep("=", b64strPadLen)
local str = mime.unb64(b64str)
return str
end
-- Returns the authenticated username or nil if no user is authenticated
function M.username()
if authenticatedUser == nil then
local authenticatedUserData
local token
if configuration.tokenPersistence == "url" then
token = M.getToken()
elseif configuration.tokenPersistence == "cookie" then
token = cgilua.cookies.get(configuration.tokenName)
end
if token then
authenticatedUserData = md5.decrypt(M.decodeURLbase64(token), configuration.criptKey)
-- check if IP in crypted data match with client IP
local authenticatedUserIP = authenticatedUserData and string.gsub(authenticatedUserData, ",.*$","") or nil
if authenticatedUserIP ~= cgilua.servervariable("REMOTE_ADDR") then
return nil
end
authenticatedUser=authenticatedUserData and string.gsub(authenticatedUserData, "^.*,", "") or nil
end
end
return authenticatedUser
end
-- encrypt the user IP and username for the user hash token
local function cryptUserData()
if authenticatedUser then
local userData = cgilua.servervariable("REMOTE_ADDR") ..",".. authenticatedUser
local cryptedUserData = M.encodeURLbase64(md5.crypt(userData, configuration.criptKey))
return cryptedUserData
end
end
-- defines the logged user name and sets the user hash token
local function setUser(username)
authenticatedUser = username
if username then
local cryptedUserData = cryptUserData()
if configuration.tokenPersistence == "url" then
M.setToken(cryptedUserData)
cgilua.cookies.delete(configuration.tokenName) -- removes an eventual previous cookie token
elseif configuration.tokenPersistence == "cookie" then
cgilua.cookies.set(configuration.tokenName, cryptedUserData)
M.setToken() -- remove an eventual previous token from the URLs
end
end
end
-- User logout, clear everything
function M.logout()
setUser()
cgilua.cookies.delete(configuration.tokenName)
M.setToken()
cgilua.QUERY.logout = nil
end
-- Checks if a user name/password is authenticated by the configured method
-- if the user is authenticaded then login the user else logout the user
-- returns true if the user has been succesfully authenticated or false plus
-- an error message when the authentication fails
function M.check(name, pass)
name = name or cgilua.POST.user
pass = pass or cgilua.POST.pass
if name then
-- Tries to authenticate the user using the configured method
local retauth,errauth = _check(name, pass)
if retauth then
setUser(name)
return true
else
M.logout()
return false, errauth
end
else
local authuser = M.username()
if authuser then
if cgilua.QUERY.logout ~= nil then
M.logout()
return false
end
end
return authuser
end
end
-- Returns a authentication URL with ref URL as a parameter,
-- accepts an optional value for the logout action
function M.checkURL(ref, tologout)
local token
if configuration.tokenPersistence == "url" then
token = M.getToken()
elseif configuration.tokenPersistence == "cookie" then
token = cgilua.cookies.get(configuration.tokenName)
end
-- As HTTP header referer information can violate privacy,
-- some browsers allow the user to disable the sending of referer information.
-- Some proxy and firewall software will also filter out referer information,
-- to avoid leaking the location of non-public websites.
-- So we send the current URL as an URL parameter to the login URL.
M.setToken()
local args = {ref = ref or M.currentURL(), logout = tologout}
if string.find(configuration.checkURL, "^https?:") then
local params = "?"..urlcode.encodetable(args)
return configuration.checkURL..params
end
return cgilua.mkabsoluteurl(cgilua.mkurlpath(configuration.checkURL, args))
end
-- Returns the logout URL, based on the login URL
function M.logoutURL()
return M.checkURL(nil, 1)
end
-- Returns the referenced URL, the one supposed to be offered only for authenticated users
function M.refURL()
local url
local baseURL = cgilua.QUERY.ref or configuration.checkURL
if string.find(baseURL, "\?") then
url = string.gsub(baseURL, "\?", "?"..configuration.tokenName.."="..cryptUserData().."&")
else
url = baseURL.."?"..configuration.tokenName.."="..cryptUserData()
end
return url
end
-- Sets the current configuration
function M.configure(options, methods)
configuration = options
local method = methods[options.method] or {}
if method.check then
_check = method.check
end
if method.username then
username = method.username
end
end
return M
|