mckaygerhard
52bdddc111
* there are two king of administrators: those that have many of the privilegies and the user that are pointed in config file, auth_rx never initialized this from zero cos always assumed a starting point as migration, so never need or really detect who are the admin of the server, cos after migration the admin already has previous privilegies from plain db file. * override all the possible handlers with right detection of the admin user from the config file, on admin detected, no matter what .. give it all the (on fly) privilegies currently on server * still a privilegied user at this commit can erase the admin or change the password if have also enought privilegies * WARNING: this commit will depends of the previusly commit as of 2aef6adf19 for right admin name detection. * fix engine detection for 5.4 due callbacks handler * wrongly invoked register_on_authplayer over 5.0+ engines
207 lines
7.8 KiB
Lua
207 lines
7.8 KiB
Lua
--------------------------------------------------------
|
|
-- Minetest :: Auth Redux Mod v2.13 (auth_rx)
|
|
--
|
|
-- See README.txt for licensing and release notes.
|
|
-- Copyright (c) 2017-2018, Leslie E. Krause
|
|
--------------------------------------------------------
|
|
|
|
local world_path = minetest.get_worldpath( )
|
|
local mod_name = minetest.get_current_modname() or "auth_rx"
|
|
local mod_path = minetest.get_modpath( mod_name )
|
|
|
|
dofile( mod_path .. "/helpers.lua" )
|
|
dofile( mod_path .. "/filter.lua" )
|
|
dofile( mod_path .. "/db.lua" )
|
|
dofile( mod_path .. "/watchdog.lua" )
|
|
local __commands = dofile( mod_path .. "/commands.lua" )
|
|
|
|
AuthInitFile( world_path, "auth.db" )
|
|
|
|
-----------------------------------------------------
|
|
-- Registered Authentication Handler
|
|
-----------------------------------------------------
|
|
local auth_filter = AuthFilter( world_path, "greenlist.mt" )
|
|
local auth_db = AuthDatabase( world_path, "auth.db" )
|
|
local auth_watchdog = AuthWatchdog( )
|
|
local is_50 = minetest.has_feature("object_use_texture_alpha")
|
|
local is_54 = minetest.has_feature("direct_velocity_on_players")
|
|
|
|
if is_50 then
|
|
if minetest.register_on_auth_fail then
|
|
minetest.register_on_auth_fail( function ( player_name, player_ip )
|
|
auth_db.on_login_failure( player_name, player_ip )
|
|
auth_watchdog.on_failure( convert_ipv4( player_ip ) )
|
|
end )
|
|
end
|
|
end
|
|
|
|
if is_54 then
|
|
if minetest.register_on_authplayer then
|
|
minetest.register_on_authplayer( function ( player_name, player_ip, is_success )
|
|
if is_success then
|
|
return
|
|
end
|
|
auth_db.on_login_failure( player_name, player_ip )
|
|
auth_watchdog.on_failure( convert_ipv4( player_ip ) )
|
|
end )
|
|
end
|
|
end
|
|
|
|
minetest.register_on_prejoinplayer( function ( player_name, player_ip )
|
|
local rec = auth_db.select_record( player_name )
|
|
local meta = auth_watchdog.get_metadata( convert_ipv4( player_ip ) )
|
|
|
|
if rec then
|
|
auth_db.on_login_attempt( player_name, player_ip )
|
|
else
|
|
-- prevent creation of case-insensitive duplicate accounts
|
|
local uname = string.lower( player_name )
|
|
for cname in auth_db.records( ) do
|
|
if string.lower( cname ) == uname then
|
|
return string.format( "A player named %s already exists on this server.", cname )
|
|
end
|
|
end
|
|
end
|
|
|
|
local res = auth_filter.is_enabled and auth_filter.process( {
|
|
name = { type = FILTER_TYPE_STRING, value = player_name },
|
|
addr = { type = FILTER_TYPE_ADDRESS, value = convert_ipv4( player_ip ) },
|
|
is_new = { type = FILTER_TYPE_BOOLEAN, value = rec == nil },
|
|
privs_list = { type = FILTER_TYPE_SERIES, value = rec and rec.assigned_privs or { } },
|
|
users_list = { type = FILTER_TYPE_SERIES, value = auth_db.search( true ) },
|
|
cur_users = { type = FILTER_TYPE_NUMBER, value = #auth_db.search( true ) },
|
|
max_users = { type = FILTER_TYPE_NUMBER, value = get_minetest_config( "max_users" ) },
|
|
lifetime = { type = FILTER_TYPE_PERIOD, value = rec and rec.lifetime or 0 },
|
|
sessions = { type = FILTER_TYPE_NUMBER, value = rec and rec.total_sessions or 0 },
|
|
failures = { type = FILTER_TYPE_NUMBER, value = rec and rec.total_failures or 0 },
|
|
attempts = { type = FILTER_TYPE_NUMBER, value = rec and rec.total_attempts or 0 },
|
|
owner = { type = FILTER_TYPE_STRING, value = get_minetest_config( "name" ) },
|
|
uptime = { type = FILTER_TYPE_PERIOD, value = minetest.get_server_uptime( ) },
|
|
oldlogin = { type = FILTER_TYPE_MOMENT, value = rec and rec.oldlogin or 0 },
|
|
newlogin = { type = FILTER_TYPE_MOMENT, value = rec and rec.newlogin or 0 },
|
|
ip_names_list = { type = FILTER_TYPE_SERIES, value = meta.previous_names or { } },
|
|
ip_prelogin = { type = FILTER_TYPE_MOMENT, value = meta.prelogin or 0 },
|
|
ip_oldcheck = { type = FILTER_TYPE_MOMENT, value = meta.oldcheck or 0 },
|
|
ip_newcheck = { type = FILTER_TYPE_MOMENT, value = meta.newcheck or 0 },
|
|
ip_failures = { type = FILTER_TYPE_NUMBER, value = meta.count_failures or 0 },
|
|
ip_attempts = { type = FILTER_TYPE_NUMBER, value = meta.count_attempts or 0 }
|
|
}, true ) or nil
|
|
|
|
auth_watchdog.on_attempt( convert_ipv4( player_ip ), player_name )
|
|
|
|
return res
|
|
end )
|
|
|
|
minetest.register_on_joinplayer( function ( player )
|
|
local player_name
|
|
local player_oj
|
|
local player_ip
|
|
if player ~= nil then
|
|
player_name = player:get_player_name( )
|
|
player_oj = minetest.get_player_information( player_name )
|
|
player_ip = player_oj.address -- this doesn't work in singleplayer!
|
|
auth_db.on_login_success( player_name, player_ip )
|
|
auth_db.on_session_opened( player_name )
|
|
auth_watchdog.on_success( convert_ipv4( player_ip ) )
|
|
minetest.log( "warning", "[auth_rx] in authentication database players success joined ".. player_name )
|
|
else
|
|
minetest.log( "error", "[auth_rx] incomplete auth process on player obj nil ip obj address" )
|
|
end
|
|
end )
|
|
|
|
minetest.register_on_leaveplayer( function ( player )
|
|
|
|
local name
|
|
if player ~= nil then
|
|
name = player:get_player_name( )
|
|
auth_db.on_session_closed( name )
|
|
minetest.log( "warning", "[auth_rx] player "..name.." leaving" )
|
|
else
|
|
minetest.log( "error", "[auth_rx] incomplete player leaving without writing in dbx due nil object" )
|
|
end
|
|
end )
|
|
|
|
minetest.register_on_shutdown( function( )
|
|
auth_db.disconnect( )
|
|
end )
|
|
|
|
minetest.register_authentication_handler( {
|
|
-- translate old auth hooks to new database backend
|
|
get_auth = function( username )
|
|
minetest.log( "verbose" , "[auth_rx] get_auth handler access to some resource for " .. username )
|
|
local rec = auth_db.select_record( username )
|
|
if rec then
|
|
local assigned_privs = rec.assigned_privs
|
|
|
|
if get_minetest_config( "name" ) == username then
|
|
-- grant server operator all privileges
|
|
assigned_privs = { }
|
|
for priv in pairs( minetest.registered_privileges ) do
|
|
table.insert( assigned_privs, priv )
|
|
end
|
|
end
|
|
|
|
return { password = rec.password, privileges = unpack_privileges( assigned_privs ), last_login = rec.newlogin }
|
|
end
|
|
end,
|
|
create_auth = function( username, password )
|
|
minetest.log( "verbose" , "[auth_rx] create_auth handler new user over server for " .. username )
|
|
local rec = auth_db.create_record( username, password )
|
|
if rec then
|
|
local assigned_privs = get_default_privs( )
|
|
|
|
if get_minetest_config( "name" ) == username then
|
|
-- grant server operator all privileges
|
|
assigned_privs = { }
|
|
for priv in pairs( minetest.registered_privileges ) do
|
|
table.insert( assigned_privs, priv )
|
|
end
|
|
end
|
|
|
|
auth_db.set_assigned_privs( username, assigned_privs )
|
|
end
|
|
end,
|
|
delete_auth = function( username )
|
|
minetest.log( "verbose" , "[auth_rx] delete_auth handler for " .. username )
|
|
-- server operator's privileges are immutable
|
|
if get_minetest_config( "name" ) ~= username then
|
|
local rec = auth_db.delete_record( username )
|
|
if rec then
|
|
minetest.log( "info", "Deleted player '" .. username .. "' in authenatication database" )
|
|
end
|
|
end
|
|
end,
|
|
set_password = function ( username, password )
|
|
minetest.log( "verbose" , "[auth_rx] set_password handler for " .. username )
|
|
local rec = auth_db.set_password( username, password )
|
|
if rec then
|
|
minetest.log( "info", "Reset password of player '" .. username .. "' in authentication database" )
|
|
end
|
|
end,
|
|
set_privileges = function ( username, privileges )
|
|
minetest.log( "verbose" , "[auth_rx] set_privileges handler grants for " .. username )
|
|
local assigned_privs = pack_privileges( privileges )
|
|
-- server operator's privileges are immutable
|
|
if get_minetest_config( "name" ) == username then
|
|
assigned_privs = { }
|
|
for priv in pairs( minetest.registered_privileges ) do
|
|
table.insert( assigned_privs, priv )
|
|
end
|
|
end
|
|
|
|
if auth_db.set_assigned_privs( username, assigned_privs ) then
|
|
minetest.notify_authentication_modified( username )
|
|
end
|
|
end,
|
|
record_login = function ( ) end,
|
|
reload = function ( ) end,
|
|
iterate = auth_db.records
|
|
} )
|
|
|
|
auth_db.connect( )
|
|
auth_filter.is_enabled = true
|
|
|
|
__commands( { auth_db = auth_db, auth_filter = auth_filter } )
|
|
|
|
print("[auth_rx] mod authentication database loaded" )
|