Make private services forbid llHTTPRequest() calls by rejecting those that have the X-SecondLife-Shard header.

If you need to enable this, set AllowHttpRequestIn = true in [Network] for all private services or individual [*Service] sections.
0.8.0.4
Justin Clark-Casey 2015-03-04 17:17:12 +00:00
parent b710295607
commit 732d04cb4a
8 changed files with 182 additions and 19 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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<IServiceAuth> m_authentications = new List<IServiceAuth>();
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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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);
}
}

View File

@ -9,15 +9,27 @@ namespace OpenSim.Framework.ServiceAuth
{
public static IServiceAuth Create(IConfigSource config, string section)
{
CompoundAuthentication compoundAuth = new CompoundAuthentication();
bool allowLlHttpRequestIn
= Util.GetConfigVarFromSections<bool>(config, "AllowllHTTPRequestIn", new string[] { "Network", section }, false);
if (!allowLlHttpRequestIn)
compoundAuth.AddAuthenticator(new DisallowLlHttpRequest());
string authType = Util.GetConfigVarFromSections<string>(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;
}
}
}
}

View File

@ -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

View File

@ -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