From ee9aca9c5270e22407c3aa4aa96c76ca92f90bb9 Mon Sep 17 00:00:00 2001 From: Melanie Date: Thu, 25 Nov 2010 20:34:55 +0100 Subject: Add the ability for gods to impersonate users. For this, bit 6 needs to be set in the target's UserFlags and the impersonator must have UserLevel 200 or above. The user can then log in using the target's name and their own password. --- .../PasswordAuthenticationService.cs | 62 +++++++++++++++++++--- 1 file changed, 55 insertions(+), 7 deletions(-) (limited to 'OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs') diff --git a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs index 17619ff..cf7496f 100644 --- a/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs +++ b/OpenSim/Services/AuthenticationService/PasswordAuthenticationService.cs @@ -51,6 +51,12 @@ namespace OpenSim.Services.AuthenticationService LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); + public PasswordAuthenticationService(IConfigSource config, IUserAccountService userService) : + base(config, userService) + { + m_log.Debug("[AUTH SERVICE]: Started with User Account access"); + } + public PasswordAuthenticationService(IConfigSource config) : base(config) { @@ -58,28 +64,70 @@ namespace OpenSim.Services.AuthenticationService public string Authenticate(UUID principalID, string password, int lifetime) { + m_log.DebugFormat("[AUTH SERVICE]: Authenticating for {0}, user account service present: {1}", principalID, m_UserAccountService != null); AuthenticationData data = m_Database.Get(principalID); + UserAccount user = null; + if (m_UserAccountService != null) + user = m_UserAccountService.GetUserAccount(UUID.Zero, principalID); + + if (data == null || data.Data == null) + { + m_log.DebugFormat("[AUTH SERVICE]: PrincipalID {0} or its data not found", principalID); + return String.Empty; + } + + if (!data.Data.ContainsKey("passwordHash") || + !data.Data.ContainsKey("passwordSalt")) + { + return String.Empty; + } + + string hashed = Util.Md5Hash(password + ":" + + data.Data["passwordSalt"].ToString()); + + m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString()); - if (data != null && data.Data != null) + if (data.Data["passwordHash"].ToString() == hashed) { - if (!data.Data.ContainsKey("passwordHash") || + return GetToken(principalID, lifetime); + } + + if (user == null) + { + m_log.DebugFormat("[PASS AUTH]: No user record for {0}", principalID); + return String.Empty; + } + + int impersonateFlag = 1 << 6; + + if ((user.UserFlags & impersonateFlag) == 0) + return String.Empty; + + List accounts = m_UserAccountService.GetUserAccountsWhere(UUID.Zero, "UserLevel >= 200"); + if (accounts == null || accounts.Count == 0) + return String.Empty; + + foreach (UserAccount a in accounts) + { + data = m_Database.Get(a.PrincipalID); + if (data == null || data.Data == null || + !data.Data.ContainsKey("passwordHash") || !data.Data.ContainsKey("passwordSalt")) { - return String.Empty; + continue; } - string hashed = Util.Md5Hash(password + ":" + + hashed = Util.Md5Hash(password + ":" + data.Data["passwordSalt"].ToString()); - m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString()); - if (data.Data["passwordHash"].ToString() == hashed) { + m_log.DebugFormat("[PASS AUTH]: {0} {1} impersonating {2}, proceeding with login", a.FirstName, a.LastName, principalID); return GetToken(principalID, lifetime); } } - m_log.DebugFormat("[AUTH SERVICE]: PrincipalID {0} or its data not found", principalID); + m_log.DebugFormat("[PASS AUTH]: Impersonation of {0} failed", principalID); return String.Empty; } } -- cgit v1.1