portalapi: propagate changes on the new API, decrypt the AES256-encrypted password found in user cookie to be able to construct the basic auth headers

This commit is contained in:
Alexandre Aubin 2023-07-11 22:41:09 +02:00
parent d0dba1fd2e
commit ea0bc8a89c
3 changed files with 21 additions and 12 deletions

View file

@ -126,7 +126,7 @@ if hlp.has_access(permission) then
-- If Basic Authorization header are enable for this permission,
-- add it to the response
if permission["auth_header"] then
hlp.set_headers()
hlp.set_basic_auth_header()
end
end

View file

@ -20,7 +20,7 @@ function get_cookie_secret()
local conf_ = json.decode(conf_file:read("*all"))
conf_file:close()
local cookie_secret_path = conf_["cookie_secret_file"]
local cookie_secret_path = conf_["cookie_secret_file"] or "/etc/yunohost/.ssowat_cookie_secret"
local cookie_secret_file = assert(io.open(cookie_secret_path, "r"), "Cookie secret file is missing")
local cookie_secret = cookie_secret_file:read("*all")
cookie_secret_file:close()

View file

@ -11,7 +11,8 @@ local cache = ngx.shared.cache
local conf = config.get_config()
local Logging = require("logging")
local jwt = require("vendor.luajwtjitsi.luajwtjitsi")
local cipher = require('openssl.cipher')
local mime = require("mime")
local appender = function(self, level, message)
@ -120,17 +121,32 @@ function check_authentication()
if err ~= nil then
-- FIXME : log an authentication error to be caught by fail2ban ? or should it happen somewhere else ? (check the old code)
authUser = nil
authPasswordEnc = nil
is_logged_in = false
return is_logged_in
end
-- cf. src/authenticators/ldap_ynhuser.py in YunoHost to see how the cookie is actually created
authUser = decoded["user"]
authPasswordEnc = decoded["pwd"]
is_logged_in = true
-- Gotta update authUser and is_logged_in
return is_logged_in
end
-- Extract the user password from cookie,
-- needed to create the basic auth header
function decrypt_user_password()
-- authPasswordEnc is actually a string formatted as <password_enc_b64>|<iv_b64>
-- For example: ctl8kk5GevYdaA5VZ2S88Q==|yTAzCx0Gd1+MCit4EQl9lA==
-- The password is encoded using AES-256-CBC with the IV being the right-side data
local password_enc_b64, iv_b64 = authPasswordEnc:match("([^|]+)|([^|]+)")
local password_enc = mime.unb64(password_enc_b64)
local iv = mime.unb64(iv_b64)
return cipher.new('aes-256-cbc'):decrypt(cookie_secret, iv):final(password_enc)
end
-- Check whether a user is allowed to access a URL using the `permissions` directive
-- of the configuration file
function has_access(permission, user)
@ -172,21 +188,14 @@ function element_is_in_table(element, table)
return false
end
-- Set the authentication headers in order to pass credentials to the
-- application underneath.
function set_headers(user)
function set_basic_auth_header(user)
local user = user or authUser
-- Set `Authorization` header to enable HTTP authentification
ngx.req.set_header("Authorization", "Basic "..ngx.encode_base64(
user..":"..cache:get(user.."-password")
user..":"..decrypt_user_password()
))
-- Set optionnal additional headers (typically to pass email address)
for k, v in pairs(conf["additional_headers"]) do
ngx.req.set_header(k, cache:get(user.."-"..v))
end
end