/** * Authentication handler that accepts multiple user accounts * * Copyright 2008 Epic Games, Inc. All Rights Reserved * * @author Michiel 'elmuerte' Hendriks */ class MultiWebAdminAuth extends Object implements(IWebAdminAuth) config(WebAdmin); `include(WebAdmin.uci) var WorldInfo worldinfo; var array users; /** * Contains a list of known names and the associated data (when instantiated) */ struct UserRecord { var string name; var MultiAdminData data; }; var array records; //!localization var localized string InvalidCreds, NoAdmins, msgUnsupportedHash; var HashLib hashLib; function init(WorldInfo wi) { worldinfo = wi; hashLib = new class'Sha1HashLib'; loadRecords(); loadQueryHandler(); } function loadRecords() { local array names; local int i, j; local int idx; local string tmp; GetPerObjectConfigSections(class'MultiAdminData', names); for (i = 0; i < names.length; i++) { idx = InStr(names[i], " "); if (idx == INDEX_NONE) continue; tmp = Left(names[i], idx); for (j = 0; j < records.length; j++) { if (caps(records[j].name) > caps(tmp)) { records.insert(j, 1); records[j].name = tmp; break; } } if (j == records.length) { records.length = j+1; records[j].name = tmp; } } if (records.length == 0) { records.length = 1; records[0].name = "Admin"; records[0].data = new(none, records[0].name) class'MultiAdminData'; records[0].data.bEnabled = true; tmp = worldinfo.game.consolecommand("get engine.accesscontrol adminpassword", false); if (len(tmp) == 0) tmp = "Admin"; tmp = getPasswordHash(records[0].data, tmp); records[0].data.setPassword(tmp); records[0].data.SaveConfig(); `Log("Created initial webadmin administrator account: "$records[0].name,,'WebAdmin'); } } function loadQueryHandler() { local QHMultiAdmin qh; local WebAdmin webadmin; local WebServer ws; local int i; if (WebAdmin(Outer) != none) { webadmin = WebAdmin(Outer); } else { foreach worldinfo.AllActors(class'WebServer', ws) { break; } if (ws == none) return; for (i = 0; i < ArrayCount(ws.ApplicationObjects); i++) { if (WebAdmin(ws.ApplicationObjects[i]) != none) { webadmin = WebAdmin(ws.ApplicationObjects[i]); break; } } } if (webadmin == none) return; qh = new class'QHMultiAdmin'; qh.authModule = self; qh.init(webadmin); qh.registerMenuItems(webadmin.menu); } function MultiAdminData getRecord(string username) { local int idx; idx = records.find('name', username); if (idx == INDEX_NONE) { return none; } if (records[idx].name != username) { // case sensitivity check return none; } if (records[idx].data == none) { records[idx].data = new(none, records[idx].name) class'MultiAdminData'; } return records[idx].data; } function bool removeAdminRecord(string username) { `if(`WITH_CLEAR_CONFIG) local int idx; local MultiAdminData data; idx = records.find('name', username); if (idx == INDEX_NONE) { return false; } if (records[idx].data == none) { records[idx].data = new(none, records[idx].name) class'MultiAdminData'; } data = records[idx].data; data.ClearConfig(); records.remove(idx, 1); for (idx = users.length-1; idx >= 0; idx--) { if (users[idx].adminData == data) { logout(users[idx]); } } return true; `endif return false; } function cleanup() { local MultiWebAdminUser user; foreach users(user) { user.logout(); } users.remove(0, users.length); records.length = 0; worldinfo = none; } function IWebAdminUser authenticate(string username, string password, string hashAlg, out string errorMsg) { local MultiWebAdminUser user; local MultiAdminData adminData; adminData = getRecord(username); if (adminData == none) { errorMsg = InvalidCreds; if (records.length == 0) { errorMsg @= NoAdmins; } return none; } if (hashLib != none) { if (hashAlg == "") { password = hashLib.getHash(password$username); hashAlg = hashLib.getAlgName(); } } if (!supportHashAlgorithm(hashAlg)) { errorMsg = msgUnsupportedHash; return none; } if (adminData.matchesPassword(password)) { user = worldinfo.spawn(class'MultiWebAdminUser'); user.adminData = adminData; user.init(); user.setUsername(adminData.getDisplayName()); users.AddItem(user); return user; } errorMsg = InvalidCreds; return none; } function bool logout(IWebAdminUser user) { user.logout(); users.RemoveItem(MultiWebAdminUser(user)); return true; } function bool validate(string username, string password, string hashAlg, out string errorMsg) { local MultiAdminData adminData; adminData = getRecord(username); if (adminData == none) { errorMsg = InvalidCreds; return false; } if (hashLib != none) { if (hashAlg == "") { password = hashLib.getHash(password$username); hashAlg = hashLib.getAlgName(); } } if (!supportHashAlgorithm(hashAlg)) { errorMsg = msgUnsupportedHash; return false; } if (adminData.matchesPassword(password)) { return true; } errorMsg = InvalidCreds; return false; } function bool validateUser(IWebAdminUser user, out string errorMsg) { return true; } function bool supportHashAlgorithm(string hashAlg) { return hashLib.getAlgName() ~= hashAlg; } function string getPasswordHash(MultiAdminData adminData, coerce string newpw) { if (hashLib == none) return newpw; return hashLib.getHash(newpw$adminData.name); }