diff --git a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs index f1607342d4..41aa19b67c 100644 --- a/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs +++ b/OpenSim/Framework/Servers/HttpServer/BaseStreamHandler.cs @@ -56,12 +56,17 @@ namespace OpenSim.Framework.Servers.HttpServer string path, Stream request, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse) { RequestsReceived++; - if (m_Auth != null && !m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader)) + + if (m_Auth != null) { - - httpResponse.StatusCode = (int)HttpStatusCode.Unauthorized; - httpResponse.ContentType = "text/plain"; - return new byte[0]; + HttpStatusCode statusCode; + + if (!m_Auth.Authenticate(httpRequest.Headers, httpResponse.AddHeader, out statusCode)) + { + httpResponse.StatusCode = (int)statusCode; + httpResponse.ContentType = "text/plain"; + return new byte[0]; + } } byte[] result = ProcessRequest(path, request, httpRequest, httpResponse); diff --git a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs index f33a045917..c686ca9171 100644 --- a/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs +++ b/OpenSim/Framework/ServiceAuth/BasicHttpAuthentication.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.Net; using System.Reflection; using Nini.Config; @@ -55,24 +56,28 @@ namespace OpenSim.Framework.ServiceAuth return false; } - public bool Authenticate(NameValueCollection requestHeaders, AddHeaderDelegate d) + public bool Authenticate(NameValueCollection requestHeaders, AddHeaderDelegate d, out HttpStatusCode statusCode) { - //m_log.DebugFormat("[HTTP BASIC AUTH]: Authenticate in {0}", remove_me); - if (requestHeaders != null) +// m_log.DebugFormat("[HTTP BASIC AUTH]: Authenticate in {0}", "BasicHttpAuthentication"); + + string value = requestHeaders.Get("Authorization"); + if (value != null) { - string value = requestHeaders.Get("Authorization"); - if (value != null) + value = value.Trim(); + if (value.StartsWith("Basic ")) { - value = value.Trim(); - if (value.StartsWith("Basic ")) + value = value.Replace("Basic ", string.Empty); + if (Authenticate(value)) { - value = value.Replace("Basic ", string.Empty); - if (Authenticate(value)) - return true; + statusCode = HttpStatusCode.OK; + return true; } } } + d("WWW-Authenticate", "Basic realm = \"Asset Server\""); + + statusCode = HttpStatusCode.Unauthorized; return false; } } diff --git a/OpenSim/Framework/ServiceAuth/CompoundAuthentication.cs b/OpenSim/Framework/ServiceAuth/CompoundAuthentication.cs new file mode 100644 index 0000000000..8c88d1c50f --- /dev/null +++ b/OpenSim/Framework/ServiceAuth/CompoundAuthentication.cs @@ -0,0 +1,71 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Net; + +namespace OpenSim.Framework.ServiceAuth +{ + public class CompoundAuthentication : IServiceAuth + { + private List m_authentications = new List(); + + public int Count { get { return m_authentications.Count; } } + + public void AddAuthenticator(IServiceAuth auth) + { + m_authentications.Add(auth); + } + + public void RemoveAuthenticator(IServiceAuth auth) + { + m_authentications.Remove(auth); + } + + public void AddAuthorization(NameValueCollection headers) {} + + public bool Authenticate(string data) + { + return m_authentications.TrueForAll(a => a.Authenticate(data)); + } + + public bool Authenticate(NameValueCollection requestHeaders, AddHeaderDelegate d, out HttpStatusCode statusCode) + { + foreach (IServiceAuth auth in m_authentications) + { + if (!auth.Authenticate(requestHeaders, d, out statusCode)) + return false; + } + + statusCode = HttpStatusCode.OK; + return true; + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/ServiceAuth/DisallowLlHttpRequest.cs b/OpenSim/Framework/ServiceAuth/DisallowLlHttpRequest.cs new file mode 100644 index 0000000000..1e1ee562e9 --- /dev/null +++ b/OpenSim/Framework/ServiceAuth/DisallowLlHttpRequest.cs @@ -0,0 +1,57 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Specialized; +using System.Net; + +namespace OpenSim.Framework.ServiceAuth +{ + public class DisallowLlHttpRequest : IServiceAuth + { + public void AddAuthorization(NameValueCollection headers) {} + + public bool Authenticate(string data) + { + return false; + } + + public bool Authenticate(NameValueCollection requestHeaders, AddHeaderDelegate d, out HttpStatusCode statusCode) + { +// Console.WriteLine("DisallowLlHttpRequest"); + + if (requestHeaders["X-SecondLife-Shard"] != null) + { + statusCode = HttpStatusCode.Forbidden; + return false; + } + + statusCode = HttpStatusCode.OK; + return true; + } + } +} \ No newline at end of file diff --git a/OpenSim/Framework/ServiceAuth/IServiceAuth.cs b/OpenSim/Framework/ServiceAuth/IServiceAuth.cs index 415dc12e18..3c1cfe2d6f 100644 --- a/OpenSim/Framework/ServiceAuth/IServiceAuth.cs +++ b/OpenSim/Framework/ServiceAuth/IServiceAuth.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; +using System.Net; namespace OpenSim.Framework.ServiceAuth { @@ -9,7 +10,7 @@ namespace OpenSim.Framework.ServiceAuth public interface IServiceAuth { bool Authenticate(string data); - bool Authenticate(NameValueCollection headers, AddHeaderDelegate d); + bool Authenticate(NameValueCollection headers, AddHeaderDelegate d, out HttpStatusCode statusCode); void AddAuthorization(NameValueCollection headers); } } diff --git a/OpenSim/Framework/ServiceAuth/ServiceAuth.cs b/OpenSim/Framework/ServiceAuth/ServiceAuth.cs index bc32d901bf..8956b92abb 100644 --- a/OpenSim/Framework/ServiceAuth/ServiceAuth.cs +++ b/OpenSim/Framework/ServiceAuth/ServiceAuth.cs @@ -9,15 +9,27 @@ namespace OpenSim.Framework.ServiceAuth { public static IServiceAuth Create(IConfigSource config, string section) { + CompoundAuthentication compoundAuth = new CompoundAuthentication(); + + bool allowLlHttpRequestIn + = Util.GetConfigVarFromSections(config, "AllowllHTTPRequestIn", new string[] { "Network", section }, false); + + if (!allowLlHttpRequestIn) + compoundAuth.AddAuthenticator(new DisallowLlHttpRequest()); + string authType = Util.GetConfigVarFromSections(config, "AuthType", new string[] { "Network", section }, "None"); switch (authType) { case "BasicHttpAuthentication": - return new BasicHttpAuthentication(config, section); + compoundAuth.AddAuthenticator(new BasicHttpAuthentication(config, section)); + break; } - return null; + if (compoundAuth.Count > 0) + return compoundAuth; + else + return null; } } -} +} \ No newline at end of file diff --git a/bin/Robust.HG.ini.example b/bin/Robust.HG.ini.example index 5474436d06..b0ece0d1dc 100644 --- a/bin/Robust.HG.ini.example +++ b/bin/Robust.HG.ini.example @@ -119,6 +119,12 @@ HGAssetServiceConnector = "HGAssetService@8002/OpenSim.Server.Handlers.dll:Asset ;; Hypgergrid services are not affected by this; they are publicly available ;; by design. + ;; By default, scripts are not allowed to call private services via llHttpRequest() + ;; Such calls are detected by the X-SecondLife-Shared HTTP header + ;; If you allow such calls you must be sure that they are restricted to very trusted scripters + ;; (remember scripts can also be in visiting avatar attachments). + ;; This can be overriden in individual private service sections if necessary + AllowllHTTPRequestIn = false ; * The following are for the remote console ; * They have no effect for the local or basic console types diff --git a/bin/Robust.ini.example b/bin/Robust.ini.example index 14c66a0a2b..036c637a1d 100644 --- a/bin/Robust.ini.example +++ b/bin/Robust.ini.example @@ -94,6 +94,12 @@ MapGetServiceConnector = "8002/OpenSim.Server.Handlers.dll:MapGetServiceConnecto ;; but unprotect individual services. Username and Password can also be ;; overriden if you want to use different credentials for the different services. + ;; By default, scripts are not allowed to call private services via llHttpRequest() + ;; Such calls are detected by the X-SecondLife-Shared HTTP header + ;; If you allow such calls you must be sure that they are restricted to very trusted scripters + ;; (remember scripts can also be in visiting avatar attachments). + ;; This can be overriden in individual private service sections if necessary + AllowllHTTPRequestIn = false ; * The following are for the remote console ; * They have no effect for the local or basic console types