<commit_before>using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using OpenSim.Framework.Servers.HttpServer;
using Nini.Config;
using Aurora.Framework;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using Aurora.Simulation.Base;
using log4net;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using DataManager = Aurora.DataManager.DataManager;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;

namespace Aurora.Modules
{
    public class InterWorldCommunications : IService, ICommunicationService
    {
        #region Declares

        protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        /// <summary>
        /// The 'AuroraInterWorldConnectors' config 
        /// </summary>
        protected IConfig m_config;
        /// <summary>
        /// The registry where we can get services
        /// </summary>
        protected IRegistryCore m_registry;
        /// <summary>
        /// Whether we are enabled or not
        /// </summary>
        protected bool m_Enabled = false;
        /// <summary>
        /// Should connections that come to us that are not authenticated be allowed to connect?
        /// </summary>
        public bool m_allowUntrustedConnections = false;
        /// <summary>
        /// Untrusted connections automatically get this trust level
        /// </summary>
        public TrustLevel m_untrustedConnectionsDefaultTrust = TrustLevel.Low;
        /// <summary>
        /// All connections that we have to other hosts
        /// (Before sending the initial connection requests, 
        ///   this MAY contain connections that we do not currently have)
        /// </summary>
        protected List<Connection> Connections;
        /// <summary>
        /// The class that sends requests to other hosts
        /// </summary>
        public IWCOutgoingConnections OutgoingPublicComms;

        public IRegistryCore Registry
        {
            get { return m_registry; }
        }

        #endregion

        #region Private members

        #region Contact and build connections

        /// <summary>
        /// Send an initial request to get secure Urls from any and all connections we have
        /// </summary>
        private void ContactOtherServers()
        {
            List<Connection> NewConnections = new List<Connection>(Connections);
            foreach (Connection connection in NewConnections)
            {
                TryAddConnection(connection);
            }
        }

        /// <summary>
        /// Query the database for any connections that we have stored
        /// </summary>
        /// <returns></returns>
        private List<Connection> BuildConnections()
        {
            List<Connection> connections = new List<Connection>();
            //Ask the database for the connectors
            IGenericsConnector genericsConnector = DataManager.DataManager.RequestPlugin<IGenericsConnector>();
            if (genericsConnector != null)
                connections = genericsConnector.GetGenerics<Connection>(UUID.Zero, "InterWorldConnections", new Connection());
            return connections;
        }

        private void AddConnection(Connection c)
        {
            if (!Connections.Contains(c))
            {
                Connections.Add(c);
                IGenericsConnector genericsConnector = DataManager.DataManager.RequestPlugin<IGenericsConnector>();
                if (genericsConnector != null)
                    genericsConnector.AddGeneric(UUID.Zero, "InterWorldConnections", c.URL, c.ToOSD());
            }
        }

        private void TryAddConnection(Connection c)
        {
            IWCCertificate cert = OutgoingPublicComms.QueryRemoteHost(c);
            if (cert != null)
            {
                c.Certificate = cert;
                IConfigurationService configService = m_registry.RequestModuleInterface<IConfigurationService>();
                //Give the Urls to the config service
                configService.AddNewUrls(cert.SessionHash, cert.SecureUrls);
                AddConnection(c);
                c.Active = true;
            }
            else
                c.Active = false;
        }

        #endregion

        #region Find Connections

        private Connection FindConnectionBySessionHash(Connection connection)
        {
            foreach (Connection c in Connections)
            {
                if (c.Certificate.SessionHash == connection.Certificate.SessionHash)//This is the connection we are looking for
                {
                    return c;
                }
            }
            //No connection found
            return null;
        }

        private Connection FindConnectionByURL(string url)
        {
            foreach (Connection c in Connections)
            {
                if (c.URL == url)//This is the connection we are looking for
                {
                    return c;
                }
            }
            //No connection found
            return null;
        }

        #endregion

        #endregion

        #region Console Commands

        private void AddConsoleCommands()
        {
            MainConsole.Instance.Commands.AddCommand("IWC", true, "iwc add connection", "iwc add connection",
                "Add an IWC connection to another host.", AddIWCConnection);
            MainConsole.Instance.Commands.AddCommand("IWC", true, "iwc remove connection", "iwc remove connection",
                "Remove an IWC connection from another host.", RemoveIWCConnection);
            MainConsole.Instance.Commands.AddCommand("IWC", true, "iwc show connections", "iwc show connections",
                "Shows all active IWC connections.", ShowIWCConnections);
        }

        #region Commands

        /// <summary>
        /// Add a certificate for the given connection
        /// </summary>
        /// <param name="module"></param>
        /// <param name="cmds"></param>
        private void AddIWCConnection(string module, string[] cmds)
        {
            string Url = MainConsole.Instance.CmdPrompt("Url to the connection");
            //Be user friendly, add the http:// if needed as well as the final /
            Url = (Url.StartsWith("http://") || Url.StartsWith("https://")) ? Url : "http://" + Url;
            Url = Url.EndsWith("/") ? Url + "iwcconnection" : Url + "/iwcconnection";

            Connection con = FindConnectionByURL(Url);
            if(con != null)
            {
                if (con.Active)
                {
                    m_log.Warn("A connection to this server already exists.");
                }
                else
                {
                    string activate = MainConsole.Instance.CmdPrompt("A connection to this server already exists, do you wish to active it?");
                    if (activate == "yes" || activate == "true")
                    {
                        TryAddConnection(con);
                    }
                }
                return;
            }
            con = new Connection();
            con.URL = Url;
            string RegionName = MainConsole.Instance.CmdPrompt("Name of the region that this connection will be for");
            Scene region = null;
            while (true)
            {
                SceneManager manager = m_registry.RequestModuleInterface<SceneManager>();
                if (manager == null)
                    break;
                else
                {
                    manager.TryGetScene(RegionName, out region);
                    if (region == null)
                        RegionName = MainConsole.Instance.CmdPrompt("Name of the region that this connection will be for");
                    else
                        break;
                }
            }
            string timeUntilExpires = MainConsole.Instance.CmdPrompt("Time until the connection expires (ends, in days)");
            string trustLevel = MainConsole.Instance.CmdPrompt("Trust level of this connection");
            int timeInDays = int.Parse(timeUntilExpires);

            
            //Build the certificate
            IWCCertificate cert = new IWCCertificate();
            cert.SessionHash = UUID.Random().ToString();
            cert.RegionHandle = region.RegionInfo.RegionHandle;
            cert.ValidUntil = DateTime.Now.AddDays(timeInDays);

            //Add the certificate now
            CertificateVerification.AddCertificate(cert);

            con.Certificate = cert;
            con.TrustLevel = (TrustLevel)Enum.Parse(typeof(TrustLevel), trustLevel);

            TryAddConnection(con);
        }

        private void RemoveIWCConnection(string module, string[] cmds)
        {
            string Url = MainConsole.Instance.CmdPrompt("Url to the connection");
            Connection c = FindConnectionByURL(Url);
            if (c == null)
            {
                m_log.Warn("Could not find the connection.");
                return;
            }
            OutgoingPublicComms.DeleteRemoteHost(c);
            Connections.Remove(c);
            IConfigurationService configService = m_registry.RequestModuleInterface<IConfigurationService>();
            //Remove the Urls from the config service
            //configService.RemoveNewUrls(cert.SessionHash);
        }

        private void ShowIWCConnections(string module, string[] cmds)
        {
            m_log.InfoFormat("Showing {0} active IWC connections.", Connections.Count);
            for (int i = 0; i < Connections.Count; i++)
            {
                m_log.Info("Url: " + Connections[i].URL);
                m_log.Info("TrustLevel: " + Connections[i].TrustLevel);
                m_log.Info("Valid Until: " + Connections[i].Certificate.ValidUntil);
                m_log.Info("Active: " + Connections[i].Active);
                m_log.Info("-------------");
            }
        }

        #endregion

        #endregion

        #region IService Members

        public void Initialize(IConfigSource source, IRegistryCore registry)
        {
            m_config = source.Configs["AuroraInterWorldConnectors"];
            if (m_config != null)
            {
                m_Enabled = m_config.GetBoolean("Enabled", false);
                m_allowUntrustedConnections = m_config.GetBoolean("AllowUntrustedConnections", m_allowUntrustedConnections);
                m_untrustedConnectionsDefaultTrust = (TrustLevel)Enum.Parse(typeof(TrustLevel), m_config.GetString("UntrustedConnectionsDefaultTrust", m_untrustedConnectionsDefaultTrust.ToString()));
            }

            registry.RegisterModuleInterface<ICommunicationService>(this);
            m_registry = registry;
        }

        public void Start(IConfigSource source, IRegistryCore registry)
        {
            if (m_Enabled)
            {
                registry.RegisterModuleInterface<InterWorldCommunications>(this);
                //Set up the public connection
                MainServer.Instance.AddStreamHandler(new IWCIncomingConnections(this));

                //Startup outgoing
                OutgoingPublicComms = new IWCOutgoingConnections(this);

                //Make our connection strings.
                Connections = BuildConnections();

                ContactOtherServers();

                AddConsoleCommands();
            }
        }

        public void FinishedStartup()
        {
        }

        #endregion

        #region ICommunicationService

        public GridRegion GetRegionForGrid(string regionName, string Url)
        {
            Connection c = FindConnectionByURL(Url);
            if (c != null)
            {
                //If we are already connected, the grid services are together, so we already know of the region if it exists, therefore, it does not exist
                return null;
            }
            else
            {
                c = new Connection();

                //Build the certificate
                IWCCertificate cert = new IWCCertificate();
                cert.SessionHash = UUID.Random().ToString();
                cert.ValidUntil = DateTime.Now.AddDays(1); //One day for now...

                //Add the certificate now
                CertificateVerification.AddCertificate(cert);

                c.Certificate = cert;
                c.TrustLevel = m_untrustedConnectionsDefaultTrust; //Least amount of our trust for them
                //Be user friendly, add the http:// if needed as well as the final /
                Url = (Url.StartsWith("http://") || Url.StartsWith("https://")) ? Url : "http://" + Url;
                Url = Url.EndsWith("/") ? Url + "iwcconnection" : Url + "/iwcconnection";
                c.URL = Url;

                cert = OutgoingPublicComms.QueryRemoteHost(c);
                if (cert != null)
                {
                    c.Certificate = cert;
                    IConfigurationService configService = m_registry.RequestModuleInterface<IConfigurationService>();
                    //Give the Urls to the config service
                    configService.AddNewUrls(cert.SessionHash, cert.SecureUrls);
                    AddConnection(c);
                    m_log.Warn("Added connection to " + Url + ".");
                    IGridService gridService = m_registry.RequestModuleInterface<IGridService>();
                    if (gridService != null)
                    {
                        List<GridRegion> regions = gridService.GetRegionsByName(UUID.Zero, regionName, 1);
                        if (regions != null && regions.Count > 0)
                            return regions[0];
                    }
                }
                else
                {
                    m_log.Warn("Could not add connection to " + Url + ".");
                }
            }
            return null;
        }

        public OSDMap GetUrlsForUser(GridRegion region, UUID userID)
        {
            IGridRegistrationService r = Registry.RequestModuleInterface<IGridRegistrationService>();
            return r.GetUrlForRegisteringClient(userID.ToString(), region.RegionHandle);
        }

        #endregion
    }

    /// <summary>
    /// This class deals with sending requests to other hosts
    /// </summary>
    public class IWCOutgoingConnections
    {
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private InterWorldCommunications IWC;

        public IWCOutgoingConnections(InterWorldCommunications iwc)
        {
            IWC = iwc;
        }

        /// <summary>
        /// Query the given host (by connection) and verify that we can connect to it.
        /// </summary>
        /// <param name="connector">The host to connect to</param>
        /// <returns>The connection that has been recieved from the host</returns>
        public IWCCertificate QueryRemoteHost(Connection connection)
        {
            OSDMap request = connection.Certificate.ToOSD(false);
            request["Method"] = "Query";
            OSDMap reply = WebUtils.PostToService(connection.URL, request);
            if (reply["Success"].AsBoolean())
            {
                if (reply["_Result"].Type != OSDType.Map)
                {
                    m_log.Warn("[IWC]: Unable to connect successfully to " + connection.URL + ", connection did not have all the required data.");
                    return null;
                }
                OSDMap innerReply = (OSDMap)reply["_Result"];
                if (innerReply["Result"].AsString() == "Successful")
                {
                    IWCCertificate c = new IWCCertificate();
                    c.FromOSD(innerReply);
                    m_log.Error("[IWC]: Connected successfully to " + connection.URL);
                    return c;
                }
                m_log.Warn("[IWC]: Unable to connect successfully to " + connection.URL + ", " + innerReply["Result"]);
            }
            else
            {
                m_log.Warn("[IWC]: Unable to connect successfully to " + connection.URL);
            }
            return null;
        }

        public void DeleteRemoteHost(Connection connection)
        {
            OSDMap request = connection.Certificate.ToOSD(false);
            request["Method"] = "Delete";
            OSDMap reply = WebUtils.PostToService(connection.URL, request);
            if (!reply["Success"].AsBoolean())
            {
                m_log.Warn("[IWC]: Failed to delete remote host @ " + connection.URL);
            }
        }
    }

    /// <summary>
    /// This class deals with incoming requests (secure and insecure) from other hosts
    /// </summary>
    public class IWCIncomingConnections : BaseStreamHandler
    {
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private InterWorldCommunications IWC;

        public IWCIncomingConnections(InterWorldCommunications iwc) :
            base("POST", "/iwcconnection")
        {
            IWC = iwc;
        }

        public override byte[] Handle(string path, Stream requestData,
                OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            StreamReader sr = new StreamReader(requestData);
            string body = sr.ReadToEnd();
            sr.Close();
            body = body.Trim();

            OSDMap args = WebUtils.GetOSDMap(body);
            if (args == null)
            {
                //No data or not an json OSDMap
                return FailureResult();
            }
            else
            {
                if (args.ContainsKey("Method"))
                {
                    string Method = args["Method"].AsString();
                    if (Method == "Query")
                        return Query(args);
                    else if (Method == "Delete")
                        return Delete(args);
                }
            }
            return FailureResult();
        }

        /// <summary>
        /// This is the initial request to join this host
        /// We need to verify passwords and add sessionHashes to our database
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private byte[] Query(OSDMap request)
        {
            IWCCertificate Certificate = new IWCCertificate();
            //Pull the connection info out of the request
            Certificate.FromOSD(request);

            //Lets make sure that they are allowed to connect to us
            if (!CertificateVerification.VerifyCertificate(Certificate))
            {
                //Make sure the other host is not trying to spoof one of our certificates
                if (CertificateVerification.GetCertificateBySessionHash(Certificate.SessionHash) != null)
                {
                    //SPOOF! XXXXXX
                    return FailureResult();
                }
                //This is an untrusted connection otherwise
                if (!IWC.m_allowUntrustedConnections)
                    return FailureResult(); //We don't allow them

                //Give them the default untrusted connection level
                Certificate.TrustLevel = IWC.m_untrustedConnectionsDefaultTrust;
            }

            //Update them in the database so that they can connect again later
            CertificateVerification.AddCertificate(Certificate);

            BuildSecureUrlsForConnection(Certificate);

            OSDMap result = Certificate.ToOSD(false);
            result["Result"] = "Successful";

            m_log.WarnFormat("[IWC]: {0} successfully connected to us.", Certificate.RegionHandle);

            return Return(result);
        }

        /// <summary>
        /// This is a request to remove the remote host from our list of current connections.
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private byte[] Delete(OSDMap request)
        {
            IWCCertificate Certificate = new IWCCertificate();
            //Pull the connection info out of the request
            Certificate.FromOSD(request);

            //Make sure that they are verified to connect
            if (!CertificateVerification.VerifyCertificate(Certificate))
                return FailureResult();

            //Remove them from our list of connections
            CertificateVerification.RemoveCertificate(Certificate);

            return SuccessfulResult();<commit_msg>Attempt to reactivate connections between IWC instances if they are not active.<commit_after>using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using OpenSim.Framework.Servers.HttpServer;
using Nini.Config;
using Aurora.Framework;
using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using Aurora.Simulation.Base;
using log4net;
using OpenSim.Services.Interfaces;
using OpenMetaverse;
using OpenMetaverse.StructuredData;
using DataManager = Aurora.DataManager.DataManager;
using GridRegion = OpenSim.Services.Interfaces.GridRegion;

namespace Aurora.Modules
{
    public class InterWorldCommunications : IService, ICommunicationService
    {
        #region Declares

        protected static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        /// <summary>
        /// The 'AuroraInterWorldConnectors' config 
        /// </summary>
        protected IConfig m_config;
        /// <summary>
        /// The registry where we can get services
        /// </summary>
        protected IRegistryCore m_registry;
        /// <summary>
        /// Whether we are enabled or not
        /// </summary>
        protected bool m_Enabled = false;
        /// <summary>
        /// Should connections that come to us that are not authenticated be allowed to connect?
        /// </summary>
        public bool m_allowUntrustedConnections = false;
        /// <summary>
        /// Untrusted connections automatically get this trust level
        /// </summary>
        public TrustLevel m_untrustedConnectionsDefaultTrust = TrustLevel.Low;
        /// <summary>
        /// All connections that we have to other hosts
        /// (Before sending the initial connection requests, 
        ///   this MAY contain connections that we do not currently have)
        /// </summary>
        protected List<Connection> Connections;
        /// <summary>
        /// The class that sends requests to other hosts
        /// </summary>
        public IWCOutgoingConnections OutgoingPublicComms;

        public IRegistryCore Registry
        {
            get { return m_registry; }
        }

        #endregion

        #region Private members

        #region Contact and build connections

        /// <summary>
        /// Send an initial request to get secure Urls from any and all connections we have
        /// </summary>
        private void ContactOtherServers()
        {
            List<Connection> NewConnections = new List<Connection>(Connections);
            foreach (Connection connection in NewConnections)
            {
                TryAddConnection(connection);
            }
        }

        /// <summary>
        /// Query the database for any connections that we have stored
        /// </summary>
        /// <returns></returns>
        private List<Connection> BuildConnections()
        {
            List<Connection> connections = new List<Connection>();
            //Ask the database for the connectors
            IGenericsConnector genericsConnector = DataManager.DataManager.RequestPlugin<IGenericsConnector>();
            if (genericsConnector != null)
                connections = genericsConnector.GetGenerics<Connection>(UUID.Zero, "InterWorldConnections", new Connection());
            return connections;
        }

        private void AddConnection(Connection c)
        {
            if (!Connections.Contains(c))
            {
                Connections.Add(c);
                IGenericsConnector genericsConnector = DataManager.DataManager.RequestPlugin<IGenericsConnector>();
                if (genericsConnector != null)
                    genericsConnector.AddGeneric(UUID.Zero, "InterWorldConnections", c.URL, c.ToOSD());
            }
        }

        public void TryAddConnection(Connection c)
        {
            IWCCertificate cert = OutgoingPublicComms.QueryRemoteHost(c);
            if (cert != null)
            {
                c.Certificate = cert;
                IConfigurationService configService = m_registry.RequestModuleInterface<IConfigurationService>();
                //Give the Urls to the config service
                configService.AddNewUrls(cert.SessionHash, cert.SecureUrls);
                AddConnection(c);
                c.Active = true;
            }
            else
                c.Active = false;
        }

        #endregion

        #region Find Connections

        public Connection FindConnectionBySessionHash(string hash)
        {
            foreach (Connection c in Connections)
            {
                if (c.Certificate.SessionHash == hash)//This is the connection we are looking for
                {
                    return c;
                }
            }
            //No connection found
            return null;
        }

        private Connection FindConnectionByURL(string url)
        {
            foreach (Connection c in Connections)
            {
                if (c.URL == url)//This is the connection we are looking for
                {
                    return c;
                }
            }
            //No connection found
            return null;
        }

        #endregion

        #endregion

        #region Console Commands

        private void AddConsoleCommands()
        {
            MainConsole.Instance.Commands.AddCommand("IWC", true, "iwc add connection", "iwc add connection",
                "Add an IWC connection to another host.", AddIWCConnection);
            MainConsole.Instance.Commands.AddCommand("IWC", true, "iwc remove connection", "iwc remove connection",
                "Remove an IWC connection from another host.", RemoveIWCConnection);
            MainConsole.Instance.Commands.AddCommand("IWC", true, "iwc show connections", "iwc show connections",
                "Shows all active IWC connections.", ShowIWCConnections);
        }

        #region Commands

        /// <summary>
        /// Add a certificate for the given connection
        /// </summary>
        /// <param name="module"></param>
        /// <param name="cmds"></param>
        private void AddIWCConnection(string module, string[] cmds)
        {
            string Url = MainConsole.Instance.CmdPrompt("Url to the connection");
            //Be user friendly, add the http:// if needed as well as the final /
            Url = (Url.StartsWith("http://") || Url.StartsWith("https://")) ? Url : "http://" + Url;
            Url = Url.EndsWith("/") ? Url + "iwcconnection" : Url + "/iwcconnection";

            Connection con = FindConnectionByURL(Url);
            if(con != null)
            {
                if (con.Active)
                {
                    m_log.Warn("A connection to this server already exists.");
                }
                else
                {
                    string activate = MainConsole.Instance.CmdPrompt("A connection to this server already exists, do you wish to active it?");
                    if (activate == "yes" || activate == "true")
                    {
                        TryAddConnection(con);
                    }
                }
                return;
            }
            con = new Connection();
            con.URL = Url;
            string RegionName = MainConsole.Instance.CmdPrompt("Name of the region that this connection will be for");
            Scene region = null;
            while (true)
            {
                SceneManager manager = m_registry.RequestModuleInterface<SceneManager>();
                if (manager == null)
                    break;
                else
                {
                    manager.TryGetScene(RegionName, out region);
                    if (region == null)
                        RegionName = MainConsole.Instance.CmdPrompt("Name of the region that this connection will be for");
                    else
                        break;
                }
            }
            string timeUntilExpires = MainConsole.Instance.CmdPrompt("Time until the connection expires (ends, in days)");
            string trustLevel = MainConsole.Instance.CmdPrompt("Trust level of this connection");
            int timeInDays = int.Parse(timeUntilExpires);

            
            //Build the certificate
            IWCCertificate cert = new IWCCertificate();
            cert.SessionHash = UUID.Random().ToString();
            cert.RegionHandle = region.RegionInfo.RegionHandle;
            cert.ValidUntil = DateTime.Now.AddDays(timeInDays);

            //Add the certificate now
            CertificateVerification.AddCertificate(cert);

            con.Certificate = cert;
            con.TrustLevel = (TrustLevel)Enum.Parse(typeof(TrustLevel), trustLevel);

            TryAddConnection(con);
        }

        private void RemoveIWCConnection(string module, string[] cmds)
        {
            string Url = MainConsole.Instance.CmdPrompt("Url to the connection");
            Connection c = FindConnectionByURL(Url);
            if (c == null)
            {
                m_log.Warn("Could not find the connection.");
                return;
            }
            OutgoingPublicComms.DeleteRemoteHost(c);
            Connections.Remove(c);
            IConfigurationService configService = m_registry.RequestModuleInterface<IConfigurationService>();
            //Remove the Urls from the config service
            //configService.RemoveNewUrls(cert.SessionHash);
        }

        private void ShowIWCConnections(string module, string[] cmds)
        {
            m_log.InfoFormat("Showing {0} active IWC connections.", Connections.Count);
            for (int i = 0; i < Connections.Count; i++)
            {
                m_log.Info("Url: " + Connections[i].URL);
                m_log.Info("TrustLevel: " + Connections[i].TrustLevel);
                m_log.Info("Valid Until: " + Connections[i].Certificate.ValidUntil);
                m_log.Info("Active: " + Connections[i].Active);
                m_log.Info("-------------");
            }
        }

        #endregion

        #endregion

        #region IService Members

        public void Initialize(IConfigSource source, IRegistryCore registry)
        {
            m_config = source.Configs["AuroraInterWorldConnectors"];
            if (m_config != null)
            {
                m_Enabled = m_config.GetBoolean("Enabled", false);
                m_allowUntrustedConnections = m_config.GetBoolean("AllowUntrustedConnections", m_allowUntrustedConnections);
                m_untrustedConnectionsDefaultTrust = (TrustLevel)Enum.Parse(typeof(TrustLevel), m_config.GetString("UntrustedConnectionsDefaultTrust", m_untrustedConnectionsDefaultTrust.ToString()));
            }

            registry.RegisterModuleInterface<ICommunicationService>(this);
            m_registry = registry;
        }

        public void Start(IConfigSource source, IRegistryCore registry)
        {
            if (m_Enabled)
            {
                registry.RegisterModuleInterface<InterWorldCommunications>(this);
                //Set up the public connection
                MainServer.Instance.AddStreamHandler(new IWCIncomingConnections(this));

                //Startup outgoing
                OutgoingPublicComms = new IWCOutgoingConnections(this);

                //Make our connection strings.
                Connections = BuildConnections();

                ContactOtherServers();

                AddConsoleCommands();
            }
        }

        public void FinishedStartup()
        {
        }

        #endregion

        #region ICommunicationService

        public GridRegion GetRegionForGrid(string regionName, string Url)
        {
            Connection c = FindConnectionByURL(Url);
            if (c != null)
            {
                //If we are already connected, the grid services are together, so we already know of the region if it exists, therefore, it does not exist
                return null;
            }
            else
            {
                c = new Connection();

                //Build the certificate
                IWCCertificate cert = new IWCCertificate();
                cert.SessionHash = UUID.Random().ToString();
                cert.ValidUntil = DateTime.Now.AddDays(1); //One day for now...

                //Add the certificate now
                CertificateVerification.AddCertificate(cert);

                c.Certificate = cert;
                c.TrustLevel = m_untrustedConnectionsDefaultTrust; //Least amount of our trust for them
                //Be user friendly, add the http:// if needed as well as the final /
                Url = (Url.StartsWith("http://") || Url.StartsWith("https://")) ? Url : "http://" + Url;
                Url = Url.EndsWith("/") ? Url + "iwcconnection" : Url + "/iwcconnection";
                c.URL = Url;

                cert = OutgoingPublicComms.QueryRemoteHost(c);
                if (cert != null)
                {
                    c.Certificate = cert;
                    IConfigurationService configService = m_registry.RequestModuleInterface<IConfigurationService>();
                    //Give the Urls to the config service
                    configService.AddNewUrls(cert.SessionHash, cert.SecureUrls);
                    AddConnection(c);
                    m_log.Warn("Added connection to " + Url + ".");
                    IGridService gridService = m_registry.RequestModuleInterface<IGridService>();
                    if (gridService != null)
                    {
                        List<GridRegion> regions = gridService.GetRegionsByName(UUID.Zero, regionName, 1);
                        if (regions != null && regions.Count > 0)
                            return regions[0];
                    }
                }
                else
                {
                    m_log.Warn("Could not add connection to " + Url + ".");
                }
            }
            return null;
        }

        public OSDMap GetUrlsForUser(GridRegion region, UUID userID)
        {
            IGridRegistrationService r = Registry.RequestModuleInterface<IGridRegistrationService>();
            return r.GetUrlForRegisteringClient(userID.ToString(), region.RegionHandle);
        }

        #endregion
    }

    /// <summary>
    /// This class deals with sending requests to other hosts
    /// </summary>
    public class IWCOutgoingConnections
    {
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private InterWorldCommunications IWC;

        public IWCOutgoingConnections(InterWorldCommunications iwc)
        {
            IWC = iwc;
        }

        /// <summary>
        /// Query the given host (by connection) and verify that we can connect to it.
        /// </summary>
        /// <param name="connector">The host to connect to</param>
        /// <returns>The connection that has been recieved from the host</returns>
        public IWCCertificate QueryRemoteHost(Connection connection)
        {
            OSDMap request = connection.Certificate.ToOSD(false);
            request["Method"] = "Query";
            OSDMap reply = WebUtils.PostToService(connection.URL, request);
            if (reply["Success"].AsBoolean())
            {
                if (reply["_Result"].Type != OSDType.Map)
                {
                    m_log.Warn("[IWC]: Unable to connect successfully to " + connection.URL + ", connection did not have all the required data.");
                    return null;
                }
                OSDMap innerReply = (OSDMap)reply["_Result"];
                if (innerReply["Result"].AsString() == "Successful")
                {
                    IWCCertificate c = new IWCCertificate();
                    c.FromOSD(innerReply);
                    m_log.Error("[IWC]: Connected successfully to " + connection.URL);
                    return c;
                }
                m_log.Warn("[IWC]: Unable to connect successfully to " + connection.URL + ", " + innerReply["Result"]);
            }
            else
            {
                m_log.Warn("[IWC]: Unable to connect successfully to " + connection.URL);
            }
            return null;
        }

        public void DeleteRemoteHost(Connection connection)
        {
            OSDMap request = connection.Certificate.ToOSD(false);
            request["Method"] = "Delete";
            OSDMap reply = WebUtils.PostToService(connection.URL, request);
            if (!reply["Success"].AsBoolean())
            {
                m_log.Warn("[IWC]: Failed to delete remote host @ " + connection.URL);
            }
        }
    }

    /// <summary>
    /// This class deals with incoming requests (secure and insecure) from other hosts
    /// </summary>
    public class IWCIncomingConnections : BaseStreamHandler
    {
        private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        private InterWorldCommunications IWC;

        public IWCIncomingConnections(InterWorldCommunications iwc) :
            base("POST", "/iwcconnection")
        {
            IWC = iwc;
        }

        public override byte[] Handle(string path, Stream requestData,
                OSHttpRequest httpRequest, OSHttpResponse httpResponse)
        {
            StreamReader sr = new StreamReader(requestData);
            string body = sr.ReadToEnd();
            sr.Close();
            body = body.Trim();

            OSDMap args = WebUtils.GetOSDMap(body);
            if (args == null)
            {
                //No data or not an json OSDMap
                return FailureResult();
            }
            else
            {
                if (args.ContainsKey("Method"))
                {
                    string Method = args["Method"].AsString();
                    if (Method == "Query")
                        return Query(args);
                    else if (Method == "Delete")
                        return Delete(args);
                }
            }
            return FailureResult();
        }

        /// <summary>
        /// This is the initial request to join this host
        /// We need to verify passwords and add sessionHashes to our database
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private byte[] Query(OSDMap request)
        {
            IWCCertificate Certificate = new IWCCertificate();
            //Pull the connection info out of the request
            Certificate.FromOSD(request);

            //Lets make sure that they are allowed to connect to us
            if (!CertificateVerification.VerifyCertificate(Certificate))
            {
                //Make sure the other host is not trying to spoof one of our certificates
                if (CertificateVerification.GetCertificateBySessionHash(Certificate.SessionHash) != null)
                {
                    //SPOOF! XXXXXX
                    return FailureResult();
                }
                //This is an untrusted connection otherwise
                if (!IWC.m_allowUntrustedConnections)
                    return FailureResult(); //We don't allow them

                //Give them the default untrusted connection level
                Certificate.TrustLevel = IWC.m_untrustedConnectionsDefaultTrust;
            }

            //Update them in the database so that they can connect again later
            CertificateVerification.AddCertificate(Certificate);
            
            Connection ourConnectionToThem = IWC.FindConnectionBySessionHash(Certificate.SessionHash);
            if (ourConnectionToThem != null)
            {
                //Verify that our connection is ok with them as well
                //Tenitively set to active so that we don't get a loop
                ourConnectionToThem.Active = true;
                Util.FireAndForget(QueryOtherHost, ourConnectionToThem);
            }

            BuildSecureUrlsForConnection(Certificate);

            OSDMap result = Certificate.ToOSD(false);
            result["Result"] = "Successful";

            m_log.WarnFormat("[IWC]: {0} successfully connected to us.", Certificate.RegionHandle);

            return Return(result);
        }

        private void QueryOtherHost(object o)
        {
            Connection ourConnectionToThem = (Connection)o;
            IWC.TryAddConnection(ourConnectionToThem);
        }

        /// <summary>
        /// This is a request to remove the remote host from our list of current connections.
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private byte[] Delete(OSDMap request)
        {
            IWCCertificate Certificate = new IWCCertificate();
            //Pull the connection info out of the request
            Certificate.FromOSD(request);

            //Make sure that they are verified to connect
            if (!CertificateVerification.VerifyCertificate(Certificate))
                return FailureResult();

            //Remove them from our list of connections
            CertificateVerification.RemoveCertificate(Certificate);

            return SuccessfulResult();
{'fraction_non_alphanumeric': 0.09000023634515847, 'fraction_numerical': 0.00037815225355108603, 'mean_word_length': 1.698641494993303, 'pattern_counts': {'":': 0, '<': 137, '<?xml version=': 0, '>': 137, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5760274', 'n_tokens_mistral': 10352, 'n_tokens_neox': 9858, 'n_words': 2679}