diff --git a/OpenSim/Framework/Communications/LoginService.cs b/OpenSim/Framework/Communications/LoginService.cs index 9cfac1c285..f0a0a0b66a 100644 --- a/OpenSim/Framework/Communications/LoginService.cs +++ b/OpenSim/Framework/Communications/LoginService.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.IO; using System.Threading; using libsecondlife; using libsecondlife.StructuredData; @@ -79,7 +80,7 @@ namespace OpenSim.Framework.UserManagement Hashtable requestData = (Hashtable) request.Params[0]; bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && - requestData.Contains("passwd")); + (requestData.Contains("passwd") || requestData.Contains("web_login_key"))); bool GoodLogin = false; UserProfileData userProfile; @@ -89,7 +90,8 @@ namespace OpenSim.Framework.UserManagement { string firstname = (string) requestData["first"]; string lastname = (string) requestData["last"]; - string passwd = (string) requestData["passwd"]; + + userProfile = GetTheUser(firstname, lastname); if (userProfile == null) @@ -100,8 +102,29 @@ namespace OpenSim.Framework.UserManagement return logResponse.CreateLoginFailedResponse(); } + if (requestData.Contains("passwd")) + { + string passwd = (string)requestData["passwd"]; + GoodLogin = AuthenticateUser(userProfile, passwd); + } + else if (requestData.Contains("web_login_key")) + { + LLUUID webloginkey = null; + try + { + webloginkey = new LLUUID((string)requestData["web_login_key"]); + } + catch (System.Exception) + { + return logResponse.CreateFailedResponse(); + } + GoodLogin = AuthenticateUser(userProfile, webloginkey); - GoodLogin = AuthenticateUser(userProfile, passwd); + } + else + { + return logResponse.CreateFailedResponse(); + } } else { @@ -334,6 +357,105 @@ namespace OpenSim.Framework.UserManagement { } + public Hashtable ProcessHTMLLogin(Hashtable keysvals) + { + Hashtable returnactions = new Hashtable(); + int statuscode = 200; + + returnactions["int_response_code"] = statuscode; + returnactions["str_response_string"] = GetDefaultLoginForm(); + + if (keysvals.ContainsKey("show_login_form")) + { + if ((string)keysvals["show_login_form"] == "TRUE") + { + + } + else + { + + + } + + } + return returnactions; + + } + + public string GetLoginForm() + { + string file = Path.Combine(Util.configDir(), "http_loginform.html"); + if (!File.Exists(file)) + return GetDefaultLoginForm(); + + StreamReader sr = File.OpenText(file); + string result = sr.ReadToEnd(); + sr.Close(); + return result; + } + + public string GetDefaultLoginForm() + { + string responseString = + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + "Second Life Login"; + responseString = responseString + ""; + responseString = responseString + "
"; + + responseString = responseString + "
"; + + responseString = responseString + "
[$errors]
"; + responseString = responseString + "
"; + responseString = responseString + "First Name:"; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + "
"; + responseString = responseString + "Last Name:"; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + "
"; + responseString = responseString + "Password:"; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + "
"; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + "
Connecting...
"; + + responseString = responseString + "
"; + responseString = responseString + "Create new account | "; + responseString = responseString + "Forgot password?"; + responseString = responseString + "
"; + + responseString = responseString + "
[$clientchannelinfo] | [$clientversion]=[$clientlanguage]
"; + responseString = responseString + "
"; + responseString = responseString + ""; + responseString = responseString + "
"; + responseString = responseString + ""; + responseString = responseString + ""; + responseString = responseString + ""; + return responseString; + } + /// /// Saves a target agent to the database /// @@ -353,14 +475,33 @@ namespace OpenSim.Framework.UserManagement /// Authenticated? public virtual bool AuthenticateUser(UserProfileData profile, string password) { + bool passwordSuccess = false; MainLog.Instance.Verbose( "LOGIN", "Authenticating {0} {1} ({2})", profile.username, profile.surname, profile.UUID); + // Web Login method seems to also occasionally send the hashed password itself + + password = password.Remove(0, 3); //remove $1$ string s = Util.Md5Hash(password + ":" + profile.passwordSalt); - return profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase); + passwordSuccess = (profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase) + || profile.passwordHash.Equals(password.ToString(),StringComparison.InvariantCultureIgnoreCase)); + + return passwordSuccess; + } + + public virtual bool AuthenticateUser(UserProfileData profile, LLUUID webloginkey) + { + bool passwordSuccess = false; + MainLog.Instance.Verbose( + "LOGIN", "Authenticating {0} {1} ({2})", profile.username, profile.surname, profile.UUID); + + // Match web login key unless it's the default weblogin key LLUUID.Zero + passwordSuccess = ((profile.webLoginKey==webloginkey) && profile.webLoginKey != LLUUID.Zero); + + return passwordSuccess; } /// diff --git a/OpenSim/Framework/Communications/UserManagerBase.cs b/OpenSim/Framework/Communications/UserManagerBase.cs index bea56ea0e7..2d72629db3 100644 --- a/OpenSim/Framework/Communications/UserManagerBase.cs +++ b/OpenSim/Framework/Communications/UserManagerBase.cs @@ -222,6 +222,23 @@ namespace OpenSim.Framework.UserManagement } + public void StoreWebLoginKey(LLUUID agentID, LLUUID webLoginKey) + { + + foreach (KeyValuePair plugin in _plugins) + { + try + { + plugin.Value.StoreWebLoginKey(agentID, webLoginKey); + } + catch (Exception e) + { + MainLog.Instance.Verbose("USERSTORAGE", + "Unable to Store WebLoginKey via " + plugin.Key + "(" + e.ToString() + ")"); + } + } + } + public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) { foreach (KeyValuePair plugin in _plugins) diff --git a/OpenSim/Framework/Data.DB4o/DB4oUserData.cs b/OpenSim/Framework/Data.DB4o/DB4oUserData.cs index c6ac5265a1..47521e499d 100644 --- a/OpenSim/Framework/Data.DB4o/DB4oUserData.cs +++ b/OpenSim/Framework/Data.DB4o/DB4oUserData.cs @@ -132,7 +132,13 @@ namespace OpenSim.Framework.Data.DB4o return null; } } + public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey) + { + UserProfileData user = GetUserByUUID(AgentID); + user.webLoginKey = WebLoginKey; + UpdateUserProfile(user); + } #region User Friends List Data public void AddNewUserFriend(LLUUID friendlistowner, LLUUID friend, uint perms) diff --git a/OpenSim/Framework/Data.MSSQL/MSSQLUserData.cs b/OpenSim/Framework/Data.MSSQL/MSSQLUserData.cs index db3c1d624d..429ed394cc 100644 --- a/OpenSim/Framework/Data.MSSQL/MSSQLUserData.cs +++ b/OpenSim/Framework/Data.MSSQL/MSSQLUserData.cs @@ -297,7 +297,13 @@ namespace OpenSim.Framework.Data.MSSQL return null; } } - + public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey) + { + UserProfileData user = GetUserByUUID(AgentID); + user.webLoginKey = WebLoginKey; + UpdateUserProfile(user); + + } /// /// Creates a new users profile /// @@ -358,7 +364,8 @@ namespace OpenSim.Framework.Data.MSSQL "profileAboutText = @profileAboutText," + "profileFirstText = @profileFirstText," + "profileImage = @profileImage," + - "profileFirstImage = @profileFirstImage where " + + "profileFirstImage = @profileFirstImage, " + + "webLoginKey = @webLoginKey where " + "UUID = @keyUUUID;", database.getConnection()); SqlParameter param1 = new SqlParameter("@uuid", user.UUID.ToString()); SqlParameter param2 = new SqlParameter("@username", user.username); @@ -383,6 +390,7 @@ namespace OpenSim.Framework.Data.MSSQL SqlParameter param21 = new SqlParameter("@profileImage", LLUUID.Zero.ToString()); SqlParameter param22 = new SqlParameter("@profileFirstImage", LLUUID.Zero.ToString()); SqlParameter param23 = new SqlParameter("@keyUUUID", user.UUID.ToString()); + SqlParameter param24 = new SqlParameter("@webLoginKey", user.webLoginKey.UUID.ToString()); command.Parameters.Add(param1); command.Parameters.Add(param2); command.Parameters.Add(param3); @@ -406,6 +414,7 @@ namespace OpenSim.Framework.Data.MSSQL command.Parameters.Add(param21); command.Parameters.Add(param22); command.Parameters.Add(param23); + command.Parameters.Add(param24); try { int affected = command.ExecuteNonQuery(); diff --git a/OpenSim/Framework/Data.MySQL/MySQLUserData.cs b/OpenSim/Framework/Data.MySQL/MySQLUserData.cs index e53ab189bd..76ad5513f7 100644 --- a/OpenSim/Framework/Data.MySQL/MySQLUserData.cs +++ b/OpenSim/Framework/Data.MySQL/MySQLUserData.cs @@ -466,6 +466,39 @@ namespace OpenSim.Framework.Data.MySQL { UserProfileData profile = GetUserByName(user, last); return GetAgentByUUID(profile.UUID); + } + + public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey) + { + + Dictionary param = new Dictionary(); + param["?UUID"] = AgentID.UUID.ToString(); + param["?webLoginKey"] = WebLoginKey.UUID.ToString(); + + try + { + lock (database) + { + IDbCommand updater = + database.Query( + "update users " + + "SET webLoginKey = ?webLoginKey " + + "where UUID = ?UUID", + param); + updater.ExecuteNonQuery(); + + } + } + catch (Exception e) + { + database.Reconnect(); + MainLog.Instance.Error(e.ToString()); + return; + } + + + + } /// diff --git a/OpenSim/Framework/Data.SQLite/SQLiteUserData.cs b/OpenSim/Framework/Data.SQLite/SQLiteUserData.cs index cbbb3491a7..f1f76c45aa 100644 --- a/OpenSim/Framework/Data.SQLite/SQLiteUserData.cs +++ b/OpenSim/Framework/Data.SQLite/SQLiteUserData.cs @@ -373,6 +373,29 @@ namespace OpenSim.Framework.Data.SQLite } } + + public void StoreWebLoginKey(LLUUID AgentID, LLUUID WebLoginKey) + { + DataTable users = ds.Tables["users"]; + lock (ds) + { + DataRow row = users.Rows.Find(Util.ToRawUuidString(AgentID)); + if (row == null) + { + MainLog.Instance.Warn("WEBLOGIN", "Unable to store new web login key for non-existant user"); + } + else + { + UserProfileData user = GetUserByUUID(AgentID); + user.webLoginKey = WebLoginKey; + fillUserRow(row, user); + da.Update(ds, "users"); + + } + } + + } + /// /// Creates a new user profile /// @@ -392,6 +415,7 @@ namespace OpenSim.Framework.Data.SQLite else { fillUserRow(row, user); + } // This is why we're getting the 'logins never log-off'.. because It isn't clearing the // useragents table once the useragent is null diff --git a/OpenSim/Framework/IUserData.cs b/OpenSim/Framework/IUserData.cs index eba2329dbb..9fd6fa815e 100644 --- a/OpenSim/Framework/IUserData.cs +++ b/OpenSim/Framework/IUserData.cs @@ -80,6 +80,12 @@ namespace OpenSim.Framework /// The current agent session UserAgentData GetAgentByName(string fname, string lname); + /// + /// Stores new web-login key for user during web page login + /// + /// + void StoreWebLoginKey(LLUUID agentID, LLUUID webLoginKey); + /// /// Adds a new User profile to the database ///