Example #1
0
        public bool LoginAgent(GridRegion source, AgentCircuitData aCircuit, GridRegion destination, out string reason)
        {
            reason = string.Empty;

            string authURL = string.Empty;

            if (aCircuit.ServiceURLs.ContainsKey("HomeURI"))
            {
                authURL = aCircuit.ServiceURLs["HomeURI"].ToString();
            }

            m_log.InfoFormat("[GATEKEEPER SERVICE]: Login request for {0} {1} @ {2} ({3}) at {4} using viewer {5}, channel {6}, IP {7}, Mac {8}, Id0 {9}, Teleport Flags: {10}. From region {11}",
                             aCircuit.firstname, aCircuit.lastname, authURL, aCircuit.AgentID, destination.RegionID,
                             aCircuit.Viewer, aCircuit.Channel, aCircuit.IPAddress, aCircuit.Mac, aCircuit.Id0, (TeleportFlags)aCircuit.teleportFlags,
                             (source == null) ? "Unknown" : string.Format("{0} ({1}){2}", source.RegionName, source.RegionID, (source.RawServerURI == null) ? "" : " @ " + source.ServerURI));

            string curViewer = Util.GetViewerName(aCircuit);
            string curMac    = aCircuit.Mac.ToString();


            //
            // Check client
            //
            if (!String.IsNullOrWhiteSpace(m_AllowedClients))
            {
                Regex arx = new Regex(m_AllowedClients);
                Match am  = arx.Match(curViewer);

                if (!am.Success)
                {
                    reason = "Login failed: client " + curViewer + " is not allowed";
                    m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is not allowed", curViewer);
                    return(false);
                }
            }

            if (!String.IsNullOrWhiteSpace(m_DeniedClients))
            {
                Regex drx = new Regex(m_DeniedClients);
                Match dm  = drx.Match(curViewer);

                if (dm.Success)
                {
                    reason = "Login failed: client " + curViewer + " is denied";
                    m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client {0} is denied", curViewer);
                    return(false);
                }
            }

            if (!String.IsNullOrWhiteSpace(m_DeniedMacs))
            {
                m_log.InfoFormat("[GATEKEEPER SERVICE]: Checking users Mac {0} against list of denied macs {1} ...", curMac, m_DeniedMacs);
                if (m_DeniedMacs.Contains(curMac))
                {
                    reason = "Login failed: client with Mac " + curMac + " is denied";
                    m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: client with mac {0} is denied", curMac);
                    return(false);
                }
            }

            //
            // Authenticate the user
            //
            if (!Authenticate(aCircuit))
            {
                reason = "Unable to verify identity";
                m_log.InfoFormat("[GATEKEEPER SERVICE]: Unable to verify identity of agent {0} {1}. Refusing service.", aCircuit.firstname, aCircuit.lastname);
                return(false);
            }
            m_log.DebugFormat("[GATEKEEPER SERVICE]: Identity verified for {0} {1} @ {2}", aCircuit.firstname, aCircuit.lastname, authURL);

            //
            // Check for impersonations
            //
            UserAccount account = null;

            if (m_UserAccountService != null)
            {
                // Check to see if we have a local user with that UUID
                account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID);
                if (account != null)
                {
                    // Make sure this is the user coming home, and not a foreign user with same UUID as a local user
                    if (m_UserAgentService != null)
                    {
                        if (!m_UserAgentService.IsAgentComingHome(aCircuit.SessionID, m_ExternalName))
                        {
                            // Can't do, sorry
                            reason = "Unauthorized";
                            m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agent {0} {1} has same ID as local user. Refusing service.",
                                             aCircuit.firstname, aCircuit.lastname);
                            return(false);
                        }
                    }
                }
            }

            //
            // Foreign agents allowed? Exceptions?
            //
            if (account == null)
            {
                bool allowed = m_ForeignAgentsAllowed;

                if (m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsAllowedExceptions))
                {
                    allowed = false;
                }

                if (!m_ForeignAgentsAllowed && IsException(aCircuit, m_ForeignsDisallowedExceptions))
                {
                    allowed = true;
                }

                if (!allowed)
                {
                    reason = "Destination does not allow visitors from your world";
                    m_log.InfoFormat("[GATEKEEPER SERVICE]: Foreign agents are not permitted {0} {1} @ {2}. Refusing service.",
                                     aCircuit.firstname, aCircuit.lastname, aCircuit.ServiceURLs["HomeURI"]);
                    return(false);
                }
            }

            //
            // Is the user banned?
            // This uses a Ban service that's more powerful than the configs
            //
            // string uui = (account != null ? aCircuit.AgentID.ToString() : Util.ProduceUserUniversalIdentifier(aCircuit));
            // if (m_BansService != null && m_BansService.IsBanned(uui, aCircuit.IPAddress, aCircuit.Id0, authURL))
            // {
            //     reason = "You are banned from this world";
            //     m_log.InfoFormat("[GATEKEEPER SERVICE]: Login failed, reason: user {0} is banned", uui);
            //     return false;
            // }

            // Check if the hardware or IP is banned
            if (m_AccessControlService != null)
            {
                if (m_AccessControlService.IsHardwareBanned(aCircuit.Mac, aCircuit.Id0) ||
                    m_AccessControlService.IsIPBanned(aCircuit.IPAddress))
                {
                    reason = "You are banned from this grid.";
                    m_log.InfoFormat("[GATEKEEPER SERVICE] Login failed for {0}, reason: hardware or ip is banned", aCircuit.AgentID);
                    return(false);
                }
            }

            UUID agentID = aCircuit.AgentID;

            if (agentID == new UUID("6571e388-6218-4574-87db-f9379718315e"))
            {
                // really?
                reason = "Invalid account ID";
                return(false);
            }

            if (m_GridUserService != null)
            {
                string       PrincipalIDstr = agentID.ToString();
                GridUserInfo guinfo         = m_GridUserService.GetGridUserInfo(PrincipalIDstr);

                if (!m_allowDuplicatePresences)
                {
                    if (guinfo != null && guinfo.Online && guinfo.LastRegionID != UUID.Zero)
                    {
                        if (SendAgentGodKillToRegion(UUID.Zero, agentID, guinfo))
                        {
                            if (account != null)
                            {
                                m_log.InfoFormat(
                                    "[GATEKEEPER SERVICE]: Login failed for {0} {1}, reason: already logged in",
                                    account.FirstName, account.LastName);
                            }
                            reason = "You appear to be already logged in on the destination grid " +
                                     "Please wait a a minute or two and retry. " +
                                     "If this takes longer than a few minutes please contact the grid owner.";
                            return(false);
                        }
                    }
                }
            }

            m_log.DebugFormat("[GATEKEEPER SERVICE]: User {0} is ok", aCircuit.Name);

            bool isFirstLogin = false;
            //
            // Login the presence, if it's not there yet (by the login service)
            //
            PresenceInfo presence = m_PresenceService.GetAgent(aCircuit.SessionID);

            if (presence != null) // it has been placed there by the login service
            {
                isFirstLogin = true;
            }

            else
            {
                if (!m_PresenceService.LoginAgent(aCircuit.AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID))
                {
                    reason = "Unable to login presence";
                    m_log.InfoFormat("[GATEKEEPER SERVICE]: Presence login failed for foreign agent {0} {1}. Refusing service.",
                                     aCircuit.firstname, aCircuit.lastname);
                    return(false);
                }
            }

            //
            // Get the region
            //
            destination = m_GridService.GetRegionByUUID(m_ScopeID, destination.RegionID);
            if (destination == null)
            {
                reason = "Destination region not found";
                return(false);
            }

            m_log.DebugFormat(
                "[GATEKEEPER SERVICE]: Destination {0} is ok for {1}", destination.RegionName, aCircuit.Name);

            //
            // Adjust the visible name
            //
            if (account != null)
            {
                aCircuit.firstname   = account.FirstName;
                aCircuit.lastname    = account.LastName;
                aCircuit.displayname = account.DisplayName;
            }
            if (account == null)
            {
                if (!aCircuit.lastname.StartsWith("@"))
                {
                    aCircuit.firstname = aCircuit.firstname + "." + aCircuit.lastname;
                }
                try
                {
                    Uri uri = new Uri(aCircuit.ServiceURLs["HomeURI"].ToString());
                    aCircuit.lastname = "@" + uri.Authority;
                }
                catch
                {
                    m_log.WarnFormat("[GATEKEEPER SERVICE]: Malformed HomeURI (this should never happen): {0}", aCircuit.ServiceURLs["HomeURI"]);
                    aCircuit.lastname = "@" + aCircuit.ServiceURLs["HomeURI"].ToString();
                }
            }

            //
            // Finally launch the agent at the destination
            //
            Constants.TeleportFlags loginFlag = isFirstLogin ? Constants.TeleportFlags.ViaLogin : Constants.TeleportFlags.ViaHGLogin;

            // Preserve our TeleportFlags we have gathered so-far
            loginFlag |= (Constants.TeleportFlags)aCircuit.teleportFlags;

            m_log.DebugFormat("[GATEKEEPER SERVICE]: Launching {0}, Teleport Flags: {1}", aCircuit.Name, loginFlag);

            EntityTransferContext ctx = new EntityTransferContext();

            if (!m_SimulationService.QueryAccess(
                    destination, aCircuit.AgentID, aCircuit.ServiceURLs["HomeURI"].ToString(),
                    true, aCircuit.startpos, new List <UUID>(), ctx, out reason))
            {
                return(false);
            }

            bool didit = m_SimulationService.CreateAgent(source, destination, aCircuit, (uint)loginFlag, ctx, out reason);

            if (didit)
            {
                m_log.DebugFormat("[GATEKEEPER SERVICE]: Login presence {0} is ok", aCircuit.Name);

                if (!isFirstLogin && m_GridUserService != null && account == null)
                {
                    // Also login foreigners with GridUser service
                    string userId = aCircuit.AgentID.ToString();
                    string first = aCircuit.firstname, last = aCircuit.lastname;
                    if (last.StartsWith("@"))
                    {
                        string[] parts = aCircuit.firstname.Split('.');
                        if (parts.Length >= 2)
                        {
                            first = parts[0];
                            last  = parts[1];
                        }
                    }

                    userId += ";" + aCircuit.ServiceURLs["HomeURI"] + ";" + first + " " + last;
                    m_GridUserService.LoggedIn(userId);

                    if (aCircuit.hasDisplayName)
                    {
                        m_log.InfoFormat("[GATEKEEPER SERVICE]: {0} {1} has arrived with a display name -> {2}", aCircuit.firstname, aCircuit.lastname, aCircuit.displayname);
                        m_GridUserService.SetDisplayName(userId, aCircuit.displayname);
                    }
                    else
                    {
                        // todo: maybe have it retrieve it?
                        m_log.InfoFormat("[GATEKEEPER SERVICE]: {0} {1} has arrived without a display name in the circuit.", aCircuit.firstname, aCircuit.lastname);
                    }
                }
            }

            return(didit);
        }