using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Security.Cryptography;
using libsecondlife;
using Nwc.XmlRpc;
using OpenSim.Framework.Console;
using OpenSim.Framework.Data;
using OpenSim.Framework.Interfaces;
using OpenSim.Framework.Utilities;
using OpenSim.Framework.Communications;
using OpenSim.Framework.Configuration;
namespace OpenSim.Framework.UserManagement
{
public class LoginService
{
protected string m_welcomeMessage = "Welcome to OpenSim";
protected UserManagerBase m_userManager = null;
protected IInventoryServices m_inventoryServer = null;
public LoginService(UserManagerBase userManager, IInventoryServices inventoryServer, string welcomeMess)
{
m_userManager = userManager;
m_inventoryServer = inventoryServer;
if (welcomeMess != "")
{
m_welcomeMessage = welcomeMess;
}
}
///
/// Main user login function
///
/// The XMLRPC request
/// The response to send
public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request)
{
System.Console.WriteLine("Attempting login now...");
XmlRpcResponse response = new XmlRpcResponse();
Hashtable requestData = (Hashtable)request.Params[0];
bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && requestData.Contains("passwd"));
bool GoodLogin = false;
UserProfileData userProfile;
LoginResponse logResponse = new LoginResponse();
if (GoodXML)
{
string firstname = (string)requestData["first"];
string lastname = (string)requestData["last"];
string passwd = (string)requestData["passwd"];
userProfile = GetTheUser(firstname, lastname);
if (userProfile == null)
return logResponse.CreateLoginFailedResponse();
GoodLogin = AuthenticateUser(userProfile, passwd);
}
else
{
return logResponse.CreateGridErrorResponse();
}
if (!GoodLogin)
{
return logResponse.CreateLoginFailedResponse();
}
else
{
// If we already have a session...
if (userProfile.currentAgent != null && userProfile.currentAgent.agentOnline)
{
// Reject the login
return logResponse.CreateAlreadyLoggedInResponse();
}
// Otherwise...
// Create a new agent session
CreateAgent(userProfile, request);
try
{
LLUUID agentID = userProfile.UUID;
LLUUID libraryFolderID;
LLUUID personalFolderID;
m_inventoryServer.GetRootFoldersForUser(agentID, out libraryFolderID, out personalFolderID);
if (personalFolderID == LLUUID.Zero)
{
m_inventoryServer.CreateNewUserInventory(libraryFolderID, agentID);
m_inventoryServer.GetRootFoldersForUser(agentID, out libraryFolderID, out personalFolderID);
}
// The option "inventory-lib-owner" requires that we return the id of the
// owner of the library inventory.
Hashtable dynamicStruct = new Hashtable();
dynamicStruct["agent_id"] = libraryFolderID.ToStringHyphenated();
logResponse.InventoryLibraryOwner.Add(dynamicStruct);
// The option "inventory-lib-root" requires that we return the id of the
// root folder of the library inventory.
dynamicStruct = new Hashtable();
dynamicStruct["folder_id"] = libraryFolderID.ToStringHyphenated();
logResponse.InventoryLibraryRoot.Add(dynamicStruct);
// The option "inventory-root" requires that we return the id of the
// root folder of the users inventory.
dynamicStruct = new Hashtable();
dynamicStruct["folder_id"] = personalFolderID.ToStringHyphenated();
logResponse.InventoryRoot.Add(dynamicStruct);
// The option "inventory-skeleton" requires that we return the structure of the
// users folder hierachy
logResponse.InventorySkeleton = GetInventorySkeleton(personalFolderID);
// The option "inventory-skel-lib" requires that we return the structure of the
// library folder hierachy
logResponse.InventoryLibrarySkeleton = GetInventorySkeleton(libraryFolderID);
// Circuit Code
uint circode = (uint)(Util.RandomClass.Next());
logResponse.Lastname = userProfile.surname;
logResponse.Firstname = userProfile.username;
logResponse.AgentID = agentID.ToStringHyphenated();
logResponse.SessionID = userProfile.currentAgent.sessionID.ToStringHyphenated();
logResponse.SecureSessionID = userProfile.currentAgent.secureSessionID.ToStringHyphenated();
logResponse.CircuitCode = (Int32)circode;
//logResponse.RegionX = 0; //overwritten
//logResponse.RegionY = 0; //overwritten
logResponse.Home = "!!null temporary value {home}!!"; // Overwritten
//logResponse.LookAt = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n";
//logResponse.SimAddress = "127.0.0.1"; //overwritten
//logResponse.SimPort = 0; //overwritten
logResponse.Message = this.GetMessage();
try
{
this.CustomiseResponse(logResponse, userProfile);
}
catch (Exception e)
{
System.Console.WriteLine(e.ToString());
return logResponse.CreateDeadRegionResponse();
//return logResponse.ToXmlRpcResponse();
}
CommitAgent(ref userProfile);
return logResponse.ToXmlRpcResponse();
}
catch (Exception E)
{
System.Console.WriteLine(E.ToString());
}
//}
}
return response;
}
///
/// Customises the login response and fills in missing values.
///
/// The existing response
/// The user profile
public virtual void CustomiseResponse(LoginResponse response, UserProfileData theUser)
{
}
///
/// Saves a target agent to the database
///
/// The users profile
/// Successful?
public bool CommitAgent(ref UserProfileData profile)
{
// Saves the agent to database
return true;
}
///
/// Checks a user against it's password hash
///
/// The users profile
/// The supplied password
/// Authenticated?
public virtual bool AuthenticateUser(UserProfileData profile, string password)
{
MainLog.Instance.Verbose(
"Authenticating " + profile.username + " " + profile.surname);
password = password.Remove(0, 3); //remove $1$
string s = Util.Md5Hash(password + ":" + profile.passwordSalt);
return profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase);
}
///
///
///
///
///
public void CreateAgent(UserProfileData profile, XmlRpcRequest request)
{
this.m_userManager.CreateAgent(profile, request);
}
///
///
///
///
///
///
public virtual UserProfileData GetTheUser(string firstname, string lastname)
{
return this.m_userManager.GetUserProfile(firstname, lastname);
}
///
///
///
///
public virtual string GetMessage()
{
return m_welcomeMessage;
}
///
/// Create a structure of the generic inventory structure of a specified folder
///
///
protected virtual ArrayList GetInventorySkeleton(LLUUID folderID)
{
List folders = m_inventoryServer.RequestFirstLevelFolders(folderID);
ArrayList temp = new ArrayList();
foreach (InventoryFolderBase ifb in folders)
{
LLUUID tempFolderID = ifb.folderID;
LLUUID tempParentID = ifb.parentID;
Hashtable TempHash = new Hashtable();
TempHash["folder_id"] = tempFolderID.ToStringHyphenated();
TempHash["name"] = ifb.name;
TempHash["parent_id"] = tempParentID.ToStringHyphenated();
TempHash["type_default"] = (Int32)ifb.type;
TempHash["version"] = (Int32)ifb.version+1;
temp.Add(TempHash);
}
return temp;
}
}
}