-- GIA auth provider for legacy Prosody builds that do not ship -- external auth modules. Delegates auth checks to external_auth_command. local new_sasl = require "util.sasl".new; local host = module.host; local log = module._log; local auth_cmd = module:get_option_string( "external_auth_command", "/code/utilities/prosody/auth_django.sh" ); local provider = {}; local function shell_quote(value) return "'" .. tostring(value or ""):gsub("'", "'\\''") .. "'"; end local function run_external(line) local cmd = "printf %s\\\\n " .. shell_quote(line) .. " | " .. shell_quote(auth_cmd); local handle = io.popen(cmd, "r"); if not handle then return false; end local output = handle:read("*a") or ""; handle:close(); output = output:gsub("%s+", ""); return output == "1"; end function provider.test_password(username, password) if not username or username == "" then return nil, "Auth failed. Invalid username."; end if not password or password == "" then return nil, "Auth failed. Invalid password."; end local ok = run_external("auth:" .. username .. ":" .. host .. ":" .. password); if ok then return true; end return nil, "Auth failed. Invalid username or password."; end function provider.user_exists(username) if not username or username == "" then return nil, "Auth failed. Invalid username."; end if run_external("isuser:" .. username .. ":" .. host) then return true; end return nil, "Auth failed. Invalid username."; end function provider.set_password() return nil, "method not implemented"; end function provider.users() return function() return nil end; end function provider.create_user() return nil, "method not implemented"; end function provider.delete_user() return nil, "method not implemented"; end function provider.get_sasl_handler() return new_sasl(host, { plain_test = function(_, username, password) local ok = provider.test_password(username, password); if ok then return true, true; end return false, nil; end }); end log("debug", "initializing GIA auth provider for host '%s'", host); module:provides("auth", provider);