diff options
Adds session authentication upon NewUserConnections. Adds user key authentication (in safemode only) upon CreateChildAgents. All of this for Hypergrid users too. This addresses assorted spoofing vulnerabilities.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs | 79 |
1 files changed, 78 insertions, 1 deletions
diff --git a/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs index 87272a1..97ffeae 100644 --- a/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs +++ b/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs | |||
@@ -59,6 +59,9 @@ namespace OpenSim.Region.CoreModules.Communications.REST | |||
59 | 59 | ||
60 | protected RegionToRegionClient m_regionClient; | 60 | protected RegionToRegionClient m_regionClient; |
61 | 61 | ||
62 | protected bool m_safemode; | ||
63 | protected IPAddress m_thisIP; | ||
64 | |||
62 | #region IRegionModule | 65 | #region IRegionModule |
63 | 66 | ||
64 | public virtual void Initialise(Scene scene, IConfigSource config) | 67 | public virtual void Initialise(Scene scene, IConfigSource config) |
@@ -74,6 +77,9 @@ namespace OpenSim.Region.CoreModules.Communications.REST | |||
74 | { | 77 | { |
75 | m_log.Info("[REST COMMS]: Enabling InterregionComms RESTComms module"); | 78 | m_log.Info("[REST COMMS]: Enabling InterregionComms RESTComms module"); |
76 | m_enabled = true; | 79 | m_enabled = true; |
80 | if (config.Configs["Hypergrid"] != null) | ||
81 | m_safemode = config.Configs["Hypergrid"].GetBoolean("safemode", false); | ||
82 | |||
77 | InitOnce(scene); | 83 | InitOnce(scene); |
78 | } | 84 | } |
79 | } | 85 | } |
@@ -117,6 +123,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST | |||
117 | m_commsManager = scene.CommsManager; | 123 | m_commsManager = scene.CommsManager; |
118 | m_aScene = scene; | 124 | m_aScene = scene; |
119 | m_regionClient = new RegionToRegionClient(m_aScene); | 125 | m_regionClient = new RegionToRegionClient(m_aScene); |
126 | m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); | ||
120 | } | 127 | } |
121 | 128 | ||
122 | protected virtual void AddHTTPHandlers() | 129 | protected virtual void AddHTTPHandlers() |
@@ -148,7 +155,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST | |||
148 | { | 155 | { |
149 | m_regionClient.SendUserInformation(regInfo, aCircuit); | 156 | m_regionClient.SendUserInformation(regInfo, aCircuit); |
150 | 157 | ||
151 | return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit); | 158 | return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit, "None"); |
152 | } | 159 | } |
153 | //else | 160 | //else |
154 | // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); | 161 | // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); |
@@ -331,6 +338,7 @@ namespace OpenSim.Region.CoreModules.Communications.REST | |||
331 | responsedata["content_type"] = "text/html"; | 338 | responsedata["content_type"] = "text/html"; |
332 | responsedata["keepalive"] = false; | 339 | responsedata["keepalive"] = false; |
333 | 340 | ||
341 | |||
334 | UUID agentID; | 342 | UUID agentID; |
335 | string action; | 343 | string action; |
336 | ulong regionHandle; | 344 | ulong regionHandle; |
@@ -378,6 +386,28 @@ namespace OpenSim.Region.CoreModules.Communications.REST | |||
378 | 386 | ||
379 | protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) | 387 | protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) |
380 | { | 388 | { |
389 | if (m_safemode) | ||
390 | { | ||
391 | // Authentication | ||
392 | string authority = string.Empty; | ||
393 | string authToken = string.Empty; | ||
394 | if (!GetAuthentication(request, out authority, out authToken)) | ||
395 | { | ||
396 | m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]); | ||
397 | responsedata["int_response_code"] = 403; | ||
398 | responsedata["str_response_string"] = "Forbidden"; | ||
399 | return ; | ||
400 | } | ||
401 | if (!VerifyKey(id, authority, authToken)) | ||
402 | { | ||
403 | m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]); | ||
404 | responsedata["int_response_code"] = 403; | ||
405 | responsedata["str_response_string"] = "Forbidden"; | ||
406 | return ; | ||
407 | } | ||
408 | m_log.DebugFormat("[REST COMMS]: Authentication succeeded for {0}", id); | ||
409 | } | ||
410 | |||
381 | OSDMap args = RegionClient.GetOSDMap((string)request["body"]); | 411 | OSDMap args = RegionClient.GetOSDMap((string)request["body"]); |
382 | if (args == null) | 412 | if (args == null) |
383 | { | 413 | { |
@@ -793,6 +823,53 @@ namespace OpenSim.Region.CoreModules.Communications.REST | |||
793 | } | 823 | } |
794 | } | 824 | } |
795 | 825 | ||
826 | public static bool GetAuthentication(Hashtable request, out string authority, out string authKey) | ||
827 | { | ||
828 | authority = string.Empty; | ||
829 | authKey = string.Empty; | ||
830 | |||
831 | Uri authUri; | ||
832 | Hashtable headers = (Hashtable)request["headers"]; | ||
833 | |||
834 | // Authorization keys look like this: | ||
835 | // http://orgrid.org:8002/<uuid> | ||
836 | if (headers.ContainsKey("authorization") && (string)headers["authorization"] != "None") | ||
837 | { | ||
838 | if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri)) | ||
839 | { | ||
840 | authority = authUri.Authority; | ||
841 | authKey = authUri.PathAndQuery.Trim('/'); | ||
842 | m_log.DebugFormat("[REST COMMS]: Got authority {0} and key {1}", authority, authKey); | ||
843 | return true; | ||
844 | } | ||
845 | else | ||
846 | m_log.Debug("[REST COMMS]: Wrong format for Authorization header: " + (string)headers["authorization"]); | ||
847 | } | ||
848 | else | ||
849 | m_log.Debug("[REST COMMS]: Authorization header not found"); | ||
850 | |||
851 | return false; | ||
852 | } | ||
853 | |||
854 | bool VerifyKey(UUID userID, string authority, string key) | ||
855 | { | ||
856 | string[] parts = authority.Split(':'); | ||
857 | IPAddress ipaddr = IPAddress.None; | ||
858 | uint port = 0; | ||
859 | if (parts.Length <= 2) | ||
860 | ipaddr = Util.GetHostFromDNS(parts[0]); | ||
861 | if (parts.Length == 2) | ||
862 | UInt32.TryParse(parts[1], out port); | ||
863 | |||
864 | // local authority (standalone), local call | ||
865 | if (m_thisIP.Equals(ipaddr) && (m_aScene.RegionInfo.HttpPort == port)) | ||
866 | return ((IAuthentication)m_aScene.CommsManager.UserAdminService).VerifyKey(userID, key); | ||
867 | // remote call | ||
868 | else | ||
869 | return AuthClient.VerifyKey("http://" + authority, userID, key); | ||
870 | } | ||
871 | |||
872 | |||
796 | #endregion Misc | 873 | #endregion Misc |
797 | 874 | ||
798 | protected class RegionToRegionClient : RegionClient | 875 | protected class RegionToRegionClient : RegionClient |