diff --git a/irc_commands/init.lua b/irc_commands/init.lua index 3d6ab50..dd5a287 100755 --- a/irc_commands/init.lua +++ b/irc_commands/init.lua @@ -1,7 +1,5 @@ local irc_users = {} -local irc_tokens = {} -local tokens_file = minetest.get_worldpath() .. "/irc_tokens" local old_chat_send_player = minetest.chat_send_player minetest.chat_send_player = function(name, message) @@ -13,94 +11,6 @@ minetest.chat_send_player = function(name, message) return old_chat_send_player(name, message) end --- Load/Save tokens -local function load_tokens() - local f = io.open(tokens_file, "r") - local tokens = {} - if f then - tokens = minetest.deserialize(f:read()) - f:close() - end - return tokens -end -irc_tokens = load_tokens() - -local function save_tokens() - local f = io.open(tokens_file, "w") - if f then - f:write(minetest.serialize(irc_tokens)) - f:close() - return true - else - minetest.log("error", "[IRC_Commands] Tokens storage file couldn't be created!") - return false - end -end - -local function generate_token(name) - local passtr = "" - for i = 1, math.random(20,40) do - passtr = passtr .. tostring(math.random(1,65535)) - end - return minetest.get_password_hash(name, passtr) -end - --- Note: You can and **should** regulary regenerate tokens -minetest.register_chatcommand("gen_token", { - description = "Generate irc token to log in", - privs = {shout = true}, - func = function(name, param) - if not minetest.get_player_by_name(name) then - return false, "You need to be logged in to the server to generate tokens" - end - local h = "" - if irc_tokens[name] then - h = " new" - end - irc_tokens[name] = generate_token(name) - minetest.chat_send_player(name, "Here is you" .. h .. " token : " .. irc_tokens[name]) - save_tokens() - - -- Disconnect any user using this login - for nick, loggedInAs in pairs(irc_users) do - if loggedInAs == name then - minetest.log("action", nick.."@IRC has been logged out from " - ..irc_users[nick] .. " (token regenerated)") - irc_users[nick] = nil - irc:say(nick, "Token regenerated. You are now logged off.") - end - end - return true - end -}) - -minetest.register_chatcommand("del_token", { - description = "Delete your entry in the token register", - privs = {shout = true}, - func = function(name) - if not minetest.get_player_by_name(name) then - return false, "You need to be logged in to the server to generate tokens" - end - if not irc_tokens[name] then - return true, "You had no entry in the tokens' register" - else - irc_tokens[name] = nil - save_tokens() - -- Disconnect any user using this login - for nick, loggedInAs in pairs(irc_users) do - if loggedInAs == name then - minetest.log("action", nick.."@IRC has been logged out from " - ..irc_users[nick] .. " (token regenerated)") - irc_users[nick] = nil - irc:say(nick, "Token regenerated. You are now logged off.") - end - end - return true, "Access for you using a token has been removed. Use /gen_token to create" .. - " a new token at any time" - end - end -}) - irc:register_hook("NickChange", function(user, newNick) for nick, player in pairs(irc_users) do if nick == user.nick then @@ -122,54 +32,45 @@ irc:register_hook("OnQuit", function(user, reason) irc_users[user.nick] = nil end) - --- Since `minetest.get_password_hash` is broken by the new SRP auth mechanism --- We will still allow to use login, but with tokens, and fall back to old hashs --- If 1° we can use them and 2° a token is generated - -function checkToken(playerName, token, usernick) - if irc_tokens[playerName] and - irc_tokens[playerName] == token then - minetest.log("action", "User " .. usernick - .." from IRC logs in as " .. playerName .. " using their token") - irc_users[usernick] = playerName - return true, "You are now logged in as " .. playerName - else - minetest.log("action", usernick.."@IRC attempted to log in as " - ..playerName.." unsuccessfully using a token") - if irc_tokens[playerName] then - return false, "Invalid token for player " .. playerName .. "." - else - return false, "No token generated by that player." - end - - end -end - irc:register_bot_command("login", { - params = " ", + params = " ", description = "Login as a user to run commands", func = function(user, args) if args == "" then - return false, "You need a username and password/token." + return false, "You need a username and password." end local playerName, password = args:match("^(%S+)%s(%S+)$") if not playerName then - return false, "Player name and password/token required." + return false, "Player name and password required." end local inChannel = false - local users = irc.conn.channels[irc.config.channel].users - for cnick, cuser in pairs(users) do + local channel = irc.conn.channels[irc.config.channel] + if not channel then + return false, "The server needs to be in its ".. + "channel for anyone to log in." + end + for cnick, cuser in pairs(channel.users) do if user.nick == cnick then inChannel = true break end end if not inChannel then - return false, "You need to be in the server's channel to login." + return false, "You need to be in the server's channel to log in." + end + local handler = minetest.get_auth_handler() + local auth = handler.get_auth(playerName) + if auth and minetest.check_password_entry(playerName, auth.password, password) then + minetest.log("action", "User "..user.nick + .." from IRC logs in as "..playerName) + irc_users[user.nick] = playerName + handler.record_login(playerName) + return true, "You are now logged in as "..playerName + else + minetest.log("action", user.nick.."@IRC attempted to log in as " + ..playerName.." unsuccessfully") + return false, "Incorrect password or player does not exist." end - - return checkToken(playerName, password, user.nick) end })