Example #1
0
        /// <summary>
        /// Called when we receive the client's initial XMLRPC login_to_simulator request message
        /// </summary>
        /// <param name="request">The XMLRPC request</param>
        /// <returns>The response to send</returns>
        public virtual XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request, IPEndPoint remoteClient)
        {
            string loginUsername = null;

            try
            {
                XmlRpcResponse response = new XmlRpcResponse();
                Hashtable requestData = (Hashtable)request.Params[0];

                SniffLoginKey((Uri)request.Params[2], requestData);

                bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") &&
                                (requestData.Contains("passwd") || requestData.Contains("web_login_key")));

                string firstname = null;
                string lastname = null;
                LoginResponse logResponse = new LoginResponse();

                if (GoodXML)
                {
                    //make sure the user isn't already trying to log in

                    firstname = (string)requestData["first"];
                    lastname = (string)requestData["last"];

                    loginUsername = firstname + " " + lastname;

                    lock (_loginsProcessing)
                    {
                        if (_loginsProcessing.Contains(loginUsername))
                        {
                            return logResponse.CreateAlreadyLoggedInResponse();
                        }
                        else
                        {
                            _loginsProcessing.Add(loginUsername);
                        }
                    }
                }

                string startLocationRequest = "last";

                UserProfileData userProfile;
                
                string clientVersion = "Unknown";

                if (GoodXML)
                {
                    if (requestData.Contains("start"))
                    {
                        startLocationRequest = (string)requestData["start"];
                    }

                    m_log.InfoFormat(
                        "[LOGIN BEGIN]: XMLRPC Received login request message from user '{0}' '{1}'",
                        firstname, lastname);

                    if (requestData.Contains("version"))
                    {
                        clientVersion = (string)requestData["version"];
                    }

                    if (this.IsViewerBlacklisted(clientVersion))
                    {
                        m_log.DebugFormat("[LOGIN]: Denying login, Client {0} is blacklisted", clientVersion);
                        return logResponse.CreateViewerNotAllowedResponse();
                    }

                    m_log.DebugFormat(
                        "[LOGIN]: XMLRPC Client is {0}, start location is {1}", clientVersion, startLocationRequest);

                    if (!TryAuthenticateXmlRpcLogin(request, firstname, lastname, out userProfile))
                    {
                        return logResponse.CreateLoginFailedResponse();
                    }
                }
                else
                {
                    m_log.Info("[LOGIN END]: XMLRPC login_to_simulator login message did not contain all the required data");

                    return logResponse.CreateGridErrorResponse();
                }

                if (userProfile.GodLevel < m_minLoginLevel)
                {
                    return logResponse.CreateLoginBlockedResponse();
                }
                else
                {
                    // If we already have a session...
                    if (userProfile.CurrentAgent != null && userProfile.CurrentAgent.AgentOnline)
                    {
                        // Force a refresh for this due to Commit below
						UUID userID = userProfile.ID;
                        m_userManager.PurgeUserFromCaches(userID);
                        userProfile = m_userManager.GetUserProfile(userID);
                        // on an error, return the former error we returned before recovery was supported.
                        if (userProfile == null) 
                            return logResponse.CreateAlreadyLoggedInResponse();

                        //TODO: The following statements can cause trouble:
                        //      If agentOnline could not turn from true back to false normally
                        //      because of some problem, for instance, the crashment of server or client,
                        //      the user cannot log in any longer.
                        userProfile.CurrentAgent.AgentOnline = false;
                        userProfile.CurrentAgent.LogoutTime = Util.UnixTimeSinceEpoch();

                        m_userManager.CommitAgent(ref userProfile);

                        // try to tell the region that their user is dead.
                        LogOffUser(userProfile, " XMLRPC You were logged off because you logged in from another location");

                        // Don't reject the login. We've already cleaned it up, above.
                        m_log.InfoFormat(
                            "[LOGIN END]: XMLRPC Reset user {0} {1} that we believe is already logged in",
                            firstname, lastname);
                        // return logResponse.CreateAlreadyLoggedInResponse();
                    }

                    // Otherwise...
                    // Create a new agent session

                    m_userManager.ResetAttachments(userProfile.ID);


                    CreateAgent(userProfile, request);

                    // We need to commit the agent right here, even though the userProfile info is not complete
                    // at this point. There is another commit further down.
                    // This is for the new sessionID to be stored so that the region can check it for session authentication. 
                    // CustomiseResponse->PrepareLoginToRegion
                    CommitAgent(ref userProfile);

                    try
                    {
                        UUID agentID = userProfile.ID;
                        InventoryData inventData = null;

                        try
                        {
                            inventData = GetInventorySkeleton(agentID);
                        }
                        catch (Exception e)
                        {
                            m_log.ErrorFormat(
                                "[LOGIN END]: Error retrieving inventory skeleton of agent {0} - {1}",
                                agentID, e);

                            return logResponse.CreateLoginInventoryFailedResponse();
                        }

                        if (inventData != null)
                        {
                            ArrayList AgentInventoryArray = inventData.InventoryArray;

                            Hashtable InventoryRootHash = new Hashtable();
                            InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
                            ArrayList InventoryRoot = new ArrayList();
                            InventoryRoot.Add(InventoryRootHash);
                            userProfile.RootInventoryFolderID = inventData.RootFolderID;

                            logResponse.InventoryRoot = InventoryRoot;
                            logResponse.InventorySkeleton = AgentInventoryArray;
                        }

                        // Inventory Library Section
                        Hashtable InventoryLibRootHash = new Hashtable();
                        InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
                        ArrayList InventoryLibRoot = new ArrayList();
                        InventoryLibRoot.Add(InventoryLibRootHash);

                        logResponse.InventoryLibRoot = InventoryLibRoot;
                        logResponse.InventoryLibraryOwner = GetLibraryOwner();
                        logResponse.InventoryLibrary = GetInventoryLibrary();

                        logResponse.CircuitCode = Util.RandomClass.Next();
                        logResponse.Lastname = userProfile.SurName;
                        logResponse.Firstname = userProfile.FirstName;
                        logResponse.AgentID = agentID;
                        logResponse.SessionID = userProfile.CurrentAgent.SessionID;
                        logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
                        logResponse.Message = GetMessage();
                        logResponse.MapServerURI = m_MapServerURI;
                        logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
                        logResponse.StartLocation = startLocationRequest;
//                        m_log.WarnFormat("[LOGIN END]: >>> Login response for {0} SSID={1}", logResponse.AgentID, logResponse.SecureSessionID);

                        if (CustomiseResponse(logResponse, userProfile, startLocationRequest, clientVersion))
                        {
                            userProfile.LastLogin = userProfile.CurrentAgent.LoginTime;
                            CommitAgent(ref userProfile);

                            // If we reach this point, then the login has successfully logged onto the grid
                            if (StatsManager.UserStats != null)
                                StatsManager.UserStats.AddSuccessfulLogin();

                            m_log.DebugFormat(
                                "[LOGIN END]: XMLRPC Authentication of user {0} {1} successful.  Sending response to client.",
                                firstname, lastname);

                            return logResponse.ToXmlRpcResponse();
                        }
                        else
                        {
                            m_log.ErrorFormat("[LOGIN END]: XMLRPC informing user {0} {1} that login failed due to an unavailable region", firstname, lastname);
                            return logResponse.CreateDeadRegionResponse();
                        }
                    }
                    catch (Exception e)
                    {
                        m_log.Error("[LOGIN END]: XMLRPC Login failed, " + e);
                        m_log.Error(e.StackTrace);
                    }
                }

                m_log.Info("[LOGIN END]: XMLRPC Login failed.  Sending back blank XMLRPC response");
                return response;
            }
            finally
            {
                if (loginUsername != null)
                {
                    lock (_loginsProcessing)
                    {
                        _loginsProcessing.Remove(loginUsername);
                    }
                }
            }
        }
Example #2
0
        public override XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request, IPEndPoint client)
        {
            m_loginMutex.WaitOne();
            try
            {
                #region Authenticate & check if login is wellformed
                m_log.Info("[LOGIN]: Attempting login in realXtend mode...");
                XmlRpcResponse response = new XmlRpcResponse();
                Hashtable requestData = (Hashtable)request.Params[0];

                bool GoodLogin;

                string startLocationRequest = "last";

                LoginResponse logResponse = new LoginResponse();

                string account;
                string sessionHash;
                string clientVersion = "Unknown";

                if (requestData.Contains("version"))
                {
                    clientVersion = (string)requestData["version"];
                }

                account = (string)requestData["account"];
                sessionHash = (string)requestData["sessionhash"];

                m_log.InfoFormat(
                    "[REX LOGIN BEGIN]: XMLRPC Received login request message from user '{0}' '{1}'",
                    account, sessionHash);

                if (requestData.Contains("start"))
                {
                    startLocationRequest = (string)requestData["start"];
                }

                m_log.DebugFormat(
                    "[REXLOGIN]: XMLRPC Client is {0}, start location is {1}", clientVersion, startLocationRequest);

                GoodLogin = AuthenticateUser(account, sessionHash);

                if (!GoodLogin)
                {
                    m_log.InfoFormat("[LOGIN END]: XMLRPC  User {0} ({1}) failed authentication", account, sessionHash);
                    return logResponse.CreateLoginFailedResponse();
                }
                try
                {
                    string actName = account.Split('@')[0];
                    string actSrv = account.Split('@')[1];

                    RexUserProfileData userProfile = AuthenticationService.GetUserByAccount(actName, actSrv);

                    userProfile.PasswordHash = "$1$";
                    userProfile.PasswordSalt = "";


                    UUID agentID = userProfile.ID;

                    // Used to transmit the login URL to the 
                    // RexAvatar class when it connects.
                    m_userData[agentID] = userProfile;

                    logResponse.CircuitCode = Util.RandomClass.Next();

                    logResponse.Lastname = "<" + account + ">";
                    logResponse.Firstname = userProfile.FirstName + " " + userProfile.SurName;
                    logResponse.AgentID = agentID;

                    logResponse.Message = m_UserConfig.DefaultStartupMsg;

                #endregion Authenticate & check if login is wellformed

                    if (userProfile.GodLevel < m_minLoginLevel)
                    {
                        return logResponse.CreateLoginBlockedResponse();
                    }
                    else
                    {
                        #region If we already have a session...
                        
                        // agent is probably newer null because it's realXtend login, so there's probably no need for checking this,
                        // but online check is still valid
                        if (userProfile.CurrentAgent != null && userProfile.CurrentAgent.AgentOnline)
                        {
                            userProfile.CurrentAgent.AgentOnline = false;

                            // Commiting online status to userserver:
                            AuthenticationService.UpdateUserAgent(agentID.ToString(),
                                userProfile.CurrentAgent.Handle.ToString(), userProfile.CurrentAgent.Position.ToString(),
                                userProfile.GridUrl.ToString(), userProfile.AuthUrl);

                            //try to tell the region that their user is dead.
                            m_UserLoginService.LogOffUser(userProfile, " XMLRPC You were logged off because you logged in from another location");

                            if (m_warn_already_logged)
                            {
                                m_log.InfoFormat(
                                    "[LOGIN END]: XMLRPC Notifying user {0} that they are already logged in",
                                    userProfile.Name);
                                return logResponse.CreateAlreadyLoggedInResponse();
                            }

                            // This is behavior for standalone (silent logout of last hung session)
                            m_log.InfoFormat(
                                "[LOGIN]: XMLRPC User {0} is already logged in, not notifying user, kicking old presence and starting new login.",
                                userProfile.Name);
                        }

                        #endregion //If we already have a session...
                    }


                    try
                    {
                        LoginService.InventoryData inventData = null;

                        try
                        {
                            inventData = CableBeachState.LoginService.GetInventorySkeleton(agentID);
                            //inventData = GetInventorySkeleton(agentID);
                        }
                        catch (Exception e)
                        {
                            m_log.ErrorFormat(
                                "[LOGIN END]: Error retrieving inventory skeleton of agent {0} - {1}",
                                agentID, e);

                            // Let's not panic
                            if (!AllowLoginWithoutInventory())
                                return logResponse.CreateLoginInventoryFailedResponse();
                        }

                        if (inventData != null)
                        {
                            ArrayList AgentInventoryArray = inventData.InventoryArray;

                            Hashtable InventoryRootHash = new Hashtable();
                            InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
                            ArrayList InventoryRoot = new ArrayList();
                            InventoryRoot.Add(InventoryRootHash);

                            logResponse.InventoryRoot = InventoryRoot;
                            logResponse.InventorySkeleton = AgentInventoryArray;
                        }

                        // Inventory Library Section
                        Hashtable InventoryLibRootHash = new Hashtable();
                        InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000"; //UUID.Zero.ToString(); 
                        ArrayList InventoryLibRoot = new ArrayList();
                        InventoryLibRoot.Add(InventoryLibRootHash);

                        logResponse.InventoryLibRoot = InventoryLibRoot;
                        
                        //logResponse.InventoryLibraryOwner = GetLibraryOwner();
                        logResponse.InventoryLibraryOwner = CableBeachState.LoginService.GetLibraryOwner();
                        //logResponse.InventoryLibrary = GetInventoryLibrary();
                        logResponse.InventoryLibrary = CableBeachState.LoginService.GetInventoryLibrary();
            
                        logResponse.CircuitCode = Util.RandomClass.Next();
                        logResponse.Lastname = userProfile.SurName;
                        logResponse.Firstname = userProfile.FirstName;
                        logResponse.AgentID = agentID;
                        logResponse.SessionID = userProfile.CurrentAgent.SessionID = UUID.Random();
                        logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID = UUID.Random();

                        // get inventory
                        // TODO: Fetch avatar storage global inventory
                        // possibly debricated:
                        //logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
                        //List<RexFriendListItem> friendList = AuthenticationService.GetUserFriendList(agentID.ToString(), userProfile.AuthUrl);
                        //TODO: convert List<RexFriendListItem> to Buddlist

                        logResponse.StartLocation = startLocationRequest;

                        //TODO: if already trying to log in..
                        bool added = m_LoginSwitch.AddLoggingInClient(userProfile.ID, userProfile.CurrentAgent.SessionID);

                        // setup avatar
                        // then get region

                        OpenSim.Grid.UserServer.Modules.RexLogin.Avatar avatar
                            = SetUpAvatar(account, userProfile.AuthUrl, userProfile.CurrentAgent.SessionID, userProfile);

                        userProfile.Account = account;


                        // Identity: <authentication server uri>/users/<account>
                        if (!Uri.TryCreate("http://" + userProfile.AuthUrl + "/users/" + account.Split('@')[0] //+ "." + userProfile.AuthUrl
                            , UriKind.Absolute, out avatar.Identity))
                        {
                            m_log.Error("[RealXtendLogin]: Failed to parse avatar identity ");
                            OpenSim.Grid.UserServer.Modules.RexLogin.LindenLoginHelper.CreateFailureResponse(
                                "Failed to parse avatar identity", "Failed to parse avatar identity for " + account, false);
                        }

                        OpenSim.Grid.UserServer.Modules.RexLogin.LindenLoginData loginData = SetUpLindenLoginData(avatar, account,
                            logResponse.Message, userProfile.CurrentAgent.SessionID);

                        CableBeachMessages.RegionInfo startReg;
                        Vector3 startPosition;

                        

                        if (TryGetStartingRegion(avatar, startLocationRequest, ref loginData, out startReg, out startPosition))
                        {
                            string simIp = startReg.IP.ToString();
                            logResponse.SimPort = (uint)startReg.Port;
                            logResponse.SimAddress = simIp;

                            if (TryPrepareLogin(avatar,
                                startReg, startPosition, clientVersion, client.Address, ref loginData, HttpCertificate, logResponse.CircuitCode))
                            {
                                m_log.Info("[RealXtendLogin] Login to " + startReg.Name + " prepared for " + avatar.Identity + ", returning response");
                                
                                userProfile.CurrentAgent.AgentOnline = true;
                                AuthenticationService.UpdateUserAgent(agentID.ToString(),
                                    startReg.Handle.ToString(), userProfile.CurrentAgent.Position.ToString(),
                                    startReg.ToString(), userProfile.AuthUrl);
                                
                                return logResponse.ToXmlRpcResponse();
                            }
                            else
                            {
                                m_log.Info("[RealXtendLogin] Preparing Login to " + startReg.Name + " failed " + avatar.Identity
                                    + ", returning failure response");
                                OpenSim.Grid.UserServer.Modules.RexLogin.LindenLoginHelper.CreateFailureResponse(
                                    "Preparing login fail", "Preparing Login to " + startReg.Name + " failed", false);
                            }
                        }
                        else
                        {
                            m_log.ErrorFormat("[LOGIN END]: XMLRPC informing user {0} that login failed due to an unavailable region", userProfile.Name);
                            return OpenSim.Grid.UserServer.Modules.RexLogin.LindenLoginHelper.CreateLoginNoRegionResponse();
                        }
                        return OpenSim.Grid.UserServer.Modules.RexLogin.LindenLoginHelper.CreateLoginInternalErrorResponse();
                    }
                    catch (Exception e)
                    {
                        m_log.Error("[LOGIN END]: XMLRPC Login failed: " + e.StackTrace + "\nSending back blank XMLRPC response.");
                        m_log.Error(e.StackTrace);
                        return response;
                    }
                }
                catch (Exception e) {
                    m_log.Error("[LOGIN END]: XMLRPC Login failed: " + e.StackTrace + "\nSending back blank XMLRPC response.");
                    return response;                
                }
            }
            finally
            {
                m_loginMutex.ReleaseMutex();
            }

        }
Example #3
0
        /// <summary>
        /// Called when we receive the client's initial XMLRPC login_to_simulator request message
        /// </summary>
        /// <param name="request">The XMLRPC request</param>
        /// <returns>The response to send</returns>
        public virtual XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request, IPEndPoint remoteClient)
        {
            // Temporary fix
            m_loginMutex.WaitOne();

            try
            {
                //CFK: CustomizeResponse contains sufficient strings to alleviate the need for this.
                //CKF: m_log.Info("[LOGIN]: Attempting login now...");
                XmlRpcResponse response = new XmlRpcResponse();
                Hashtable requestData = (Hashtable)request.Params[0];

                SniffLoginKey((Uri)request.Params[2], requestData);

                bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") &&
                                (requestData.Contains("passwd") || requestData.Contains("web_login_key")));

                string startLocationRequest = "last";

                UserProfileData userProfile;
                LoginResponse logResponse = new LoginResponse();

                string firstname;
                string lastname;

                if (GoodXML)
                {
                    if (requestData.Contains("start"))
                    {
                        startLocationRequest = (string)requestData["start"];
                    }

                    firstname = (string)requestData["first"];
                    lastname = (string)requestData["last"];

                    m_log.InfoFormat(
                        "[LOGIN BEGIN]: XMLRPC Received login request message from user '{0}' '{1}'",
                        firstname, lastname);

                    string clientVersion = "Unknown";

                    if (requestData.Contains("version"))
                    {
                        clientVersion = (string)requestData["version"];
                    }

                    m_log.DebugFormat(
                        "[LOGIN]: XMLRPC Client is {0}, start location is {1}", clientVersion, startLocationRequest);

                    if (!TryAuthenticateXmlRpcLogin(request, firstname, lastname, out userProfile))
                    {
                        return logResponse.CreateLoginFailedResponse();
                    }
                }
                else
                {
                    m_log.Info(
                        "[LOGIN END]: XMLRPC login_to_simulator login message did not contain all the required data");

                    return logResponse.CreateGridErrorResponse();
                }

                if (userProfile.GodLevel < m_minLoginLevel)
                {
                    return logResponse.CreateLoginBlockedResponse();
                }
                else
                {
                    // If we already have a session...
                    if (userProfile.CurrentAgent != null && userProfile.CurrentAgent.AgentOnline)
                    {
                        //TODO: The following statements can cause trouble:
                        //      If agentOnline could not turn from true back to false normally
                        //      because of some problem, for instance, the crashment of server or client,
                        //      the user cannot log in any longer.
                        userProfile.CurrentAgent.AgentOnline = false;

                        m_userManager.CommitAgent(ref userProfile);

                        // try to tell the region that their user is dead.
                        LogOffUser(userProfile, " XMLRPC You were logged off because you logged in from another location");

                        if (m_warn_already_logged)
                        {
                            // This is behavior for for grid, reject login
                            m_log.InfoFormat(
                                "[LOGIN END]: XMLRPC Notifying user {0} {1} that they are already logged in",
                                firstname, lastname);

                            return logResponse.CreateAlreadyLoggedInResponse();
                        }
                        else
                        {
                            // This is behavior for standalone (silent logout of last hung session)
                            m_log.InfoFormat(
                                "[LOGIN]: XMLRPC User {0} {1} is already logged in, not notifying user, kicking old presence and starting new login.",
                                firstname, lastname);
                        }
                    }

                    // Otherwise...
                    // Create a new agent session

                    // XXYY we don't need this
                    //m_userManager.ResetAttachments(userProfile.ID);

                    CreateAgent(userProfile, request);

                    // We need to commit the agent right here, even though the userProfile info is not complete
                    // at this point. There is another commit further down.
                    // This is for the new sessionID to be stored so that the region can check it for session authentication. 
                    // CustomiseResponse->PrepareLoginToRegion
                    CommitAgent(ref userProfile);

                    try
                    {
                        UUID agentID = userProfile.ID;
                        InventoryData inventData = null;

                        try
                        {
                            inventData = GetInventorySkeleton(agentID);
                        }
                        catch (Exception e)
                        {
                            m_log.ErrorFormat(
                                "[LOGIN END]: Error retrieving inventory skeleton of agent {0} - {1}",
                                agentID, e);

                            // Let's not panic
                            if (!AllowLoginWithoutInventory())
                                return logResponse.CreateLoginInventoryFailedResponse();
                        }

                        if (inventData != null)
                        {
                            ArrayList AgentInventoryArray = inventData.InventoryArray;

                            Hashtable InventoryRootHash = new Hashtable();
                            InventoryRootHash["folder_id"] = inventData.RootFolderID.ToString();
                            ArrayList InventoryRoot = new ArrayList();
                            InventoryRoot.Add(InventoryRootHash);

                            logResponse.InventoryRoot = InventoryRoot;
                            logResponse.InventorySkeleton = AgentInventoryArray;
                        }

                        // Inventory Library Section
                        Hashtable InventoryLibRootHash = new Hashtable();
                        InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
                        ArrayList InventoryLibRoot = new ArrayList();
                        InventoryLibRoot.Add(InventoryLibRootHash);

                        logResponse.InventoryLibRoot = InventoryLibRoot;
                        logResponse.InventoryLibraryOwner = GetLibraryOwner();
                        logResponse.InventoryLibrary = GetInventoryLibrary();

                        logResponse.CircuitCode = Util.RandomClass.Next();
                        logResponse.Lastname = userProfile.SurName;
                        logResponse.Firstname = userProfile.FirstName;
                        logResponse.AgentID = agentID;
                        logResponse.SessionID = userProfile.CurrentAgent.SessionID;
                        logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
                        logResponse.Message = GetMessage();
                        logResponse.BuddList = ConvertFriendListItem(m_userManager.GetUserFriendList(agentID));
                        logResponse.StartLocation = startLocationRequest;

                        if (CustomiseResponse(logResponse, userProfile, startLocationRequest, remoteClient))
                        {
                            userProfile.LastLogin = userProfile.CurrentAgent.LoginTime;
                            CommitAgent(ref userProfile);

                            // If we reach this point, then the login has successfully logged onto the grid
                            if (StatsManager.UserStats != null)
                                StatsManager.UserStats.AddSuccessfulLogin();

                            m_log.DebugFormat(
                                "[LOGIN END]: XMLRPC Authentication of user {0} {1} successful.  Sending response to client.",
                                firstname, lastname);

                            return logResponse.ToXmlRpcResponse();
                        }
                        else
                        {
                            m_log.ErrorFormat("[LOGIN END]: XMLRPC informing user {0} {1} that login failed due to an unavailable region", firstname, lastname);
                            return logResponse.CreateDeadRegionResponse();
                        }
                    }
                    catch (Exception e)
                    {
                        m_log.Error("[LOGIN END]: XMLRPC Login failed, " + e);
                        m_log.Error(e.StackTrace);
                    }
                }

                m_log.Info("[LOGIN END]: XMLRPC Login failed.  Sending back blank XMLRPC response");
                return response;
            }
            finally
            {
                m_loginMutex.ReleaseMutex();
            }
        }
Example #4
0
        XmlRpcResponse LoginHandler(XmlRpcRequest request, Uri requestUrl)
        {
            XmlRpcResponse response = new XmlRpcResponse();
            Hashtable requestData = (Hashtable)request.Params[0];
            IPEndPoint remoteClient = null;
            if (request.Params.Count > 1)
                remoteClient = request.Params[1] as IPEndPoint;

            UserProfileData userProfile;
            LoginResponse logResponse = new LoginResponse();

            UUID sessionID;
            IsXmlRpcLogin(requestUrl, out sessionID);
            m_log.Info("[CABLE BEACH XMLRPC]: XML-RPC Received login request message with sessionID " + sessionID);

            string startLocationRequest = "last";
            if (requestData.Contains("start"))
                startLocationRequest = (requestData["start"] as string) ?? "last";

            string clientVersion = "Unknown";
            if (requestData.Contains("version"))
                clientVersion = (requestData["version"] as string) ?? "Unknown";

            if (TryAuthenticateXmlRpcLogin(sessionID, out userProfile))
            {
                try
                {
                    UUID agentID = userProfile.ID;
                    LoginService.InventoryData skeleton = null;

                    try { skeleton = CableBeachState.LoginService.GetInventorySkeleton(agentID); }
                    catch (Exception e)
                    {
                        m_log.ErrorFormat("[CABLE BEACH XMLRPC]: Error retrieving inventory skeleton of agent {0} - {1}",
                            agentID, e);

                        // Let's not panic
                        if (!CableBeachState.LoginService.AllowLoginWithoutInventory())
                            return logResponse.CreateLoginInventoryFailedResponse();
                    }

                    #region Inventory Skeletons

                    if (skeleton != null)
                    {
                        ArrayList AgentInventoryArray = skeleton.InventoryArray;

                        Hashtable InventoryRootHash = new Hashtable();
                        InventoryRootHash["folder_id"] = skeleton.RootFolderID.ToString();
                        ArrayList InventoryRoot = new ArrayList();
                        InventoryRoot.Add(InventoryRootHash);

                        logResponse.InventoryRoot = InventoryRoot;
                        logResponse.InventorySkeleton = AgentInventoryArray;
                    }

                    // Inventory Library Section
                    Hashtable InventoryLibRootHash = new Hashtable();
                    InventoryLibRootHash["folder_id"] = "00000112-000f-0000-0000-000100bba000";
                    ArrayList InventoryLibRoot = new ArrayList();
                    InventoryLibRoot.Add(InventoryLibRootHash);

                    logResponse.InventoryLibRoot = InventoryLibRoot;
                    logResponse.InventoryLibraryOwner = CableBeachState.LoginService.GetLibraryOwner();
                    logResponse.InventoryLibrary = CableBeachState.LoginService.GetInventoryLibrary();

                    logResponse.CircuitCode = Util.RandomClass.Next();
                    logResponse.Lastname = userProfile.SurName;
                    logResponse.Firstname = userProfile.FirstName;
                    logResponse.AgentID = agentID;
                    logResponse.SessionID = userProfile.CurrentAgent.SessionID;
                    logResponse.SecureSessionID = userProfile.CurrentAgent.SecureSessionID;
                    logResponse.Message = CableBeachState.LoginService.GetMessage();
                    logResponse.BuddList = CableBeachState.LoginService.ConvertFriendListItem(CableBeachState.LoginService.UserManager.GetUserFriendList(agentID));
                    logResponse.StartLocation = startLocationRequest;

                    #endregion Inventory Skeletons

                    if (CableBeachState.LoginService.CustomiseResponse(logResponse, userProfile, startLocationRequest, remoteClient))
                    {
                        userProfile.LastLogin = userProfile.CurrentAgent.LoginTime;
                        CableBeachState.LoginService.CommitAgent(ref userProfile);

                        // If we reach this point, then the login has successfully logged onto the grid
                        if (StatsManager.UserStats != null)
                            StatsManager.UserStats.AddSuccessfulLogin();

                        m_log.DebugFormat("[CABLE BEACH XMLRPC]: Authentication of user {0} {1} successful. Sending response to client",
                            userProfile.FirstName, userProfile.FirstName);

                        return logResponse.ToXmlRpcResponse();
                    }
                    else
                    {
                        m_log.ErrorFormat("[CABLE BEACH XMLRPC]: Informing user {0} {1} that login failed due to an unavailable region",
                            userProfile.FirstName, userProfile.FirstName);

                        return logResponse.CreateDeadRegionResponse();
                    }
                }
                catch (Exception e)
                {
                    m_log.Error("[CABLE BEACH XMLRPC]: Login failed, returning a blank response. Error: " + e);
                    return response;
                }
            }
            else
            {
                m_log.Warn("[CABLE BEACH XMLRPC]: Authentication failed using sessionID " + sessionID + ", there are " +
                    CableBeachState.PendingLogins.Count + " valid pending logins");
                return logResponse.CreateLoginFailedResponse();
            }
        }