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)
        {
            // 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 #2
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 #3
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();
            }
        }