Merge remote-tracking branch 'upstream/master' into develop (0.9.3.1)

This commit is contained in:
Mike Dickson 2024-11-14 19:43:27 -05:00
commit e572818e53
28 changed files with 1259 additions and 770 deletions

View file

@ -878,7 +878,6 @@ namespace OpenSim.ApplicationPlugins.RemoteController
int estateID = estateIDs[0];
region.EstateSettings = m_application.EstateDataService.LoadEstateSettings(region.RegionID, false);
if (region.EstateSettings.EstateID != estateID)
{
// The region is already part of an estate, but not the one we want.
@ -2128,7 +2127,7 @@ namespace OpenSim.ApplicationPlugins.RemoteController
m_log.Info("[RADMIN]: Received Estate Reload Request");
Hashtable responseData = (Hashtable)response.Value;
// Hashtable requestData = (Hashtable)request.Params[0];
//Hashtable requestData = (Hashtable)request.Params[0];
m_application.SceneManager.ForEachScene(s =>
s.RegionInfo.EstateSettings = m_application.EstateDataService.LoadEstateSettings(s.RegionInfo.RegionID, false)

View file

@ -65,7 +65,7 @@ namespace OpenSim.Data.MySQL
public List<RegionData> Get(string regionName, UUID scopeID)
{
string command = "select * from `"+m_Realm+"` where regionName like ?regionName";
if (!scopeID.IsZero())
if (scopeID.IsNotZero())
command += " and ScopeID = ?scopeID";
command += " order by regionName";
@ -73,6 +73,7 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?regionName", regionName);
if (scopeID.IsNotZero())
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
return RunCommand(cmd);
@ -82,12 +83,13 @@ namespace OpenSim.Data.MySQL
public RegionData GetSpecific(string regionName, UUID scopeID)
{
string command = "select * from `" + m_Realm + "` where regionName = ?regionName";
if (!scopeID.IsZero())
if (scopeID.IsNotZero())
command += " and ScopeID = ?scopeID";
using (MySqlCommand cmd = new MySqlCommand(command))
{
cmd.Parameters.AddWithValue("?regionName", regionName);
if (scopeID.IsNotZero())
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
List<RegionData> ret = RunCommand(cmd);
@ -102,7 +104,7 @@ namespace OpenSim.Data.MySQL
public RegionData Get(int posX, int posY, UUID scopeID)
{
string command = "select * from `" + m_Realm + "` where locX between ?startX and ?endX and locY between ?startY and ?endY";
if (!scopeID.IsZero())
if (scopeID.IsNotZero())
command += " and ScopeID = ?scopeID";
int startX = posX - (int)Constants.MaximumRegionSize;
@ -117,6 +119,7 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?startY", startY.ToString());
cmd.Parameters.AddWithValue("?endX", endX.ToString());
cmd.Parameters.AddWithValue("?endY", endY.ToString());
if (scopeID.IsNotZero())
cmd.Parameters.AddWithValue("?scopeID", scopeID.ToString());
ret = RunCommand(cmd);

View file

@ -29,10 +29,7 @@ using System;
using System.Xml;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Timers;
using OpenMetaverse;
@ -185,9 +182,9 @@ namespace OpenSim.Framework.Console
m_Server = server;
// Add our handlers
m_Server.AddHTTPHandler("/StartSession/", HandleHttpStartSession);
m_Server.AddHTTPHandler("/CloseSession/", HandleHttpCloseSession);
m_Server.AddHTTPHandler("/SessionCommand/", HandleHttpSessionCommand);
m_Server.AddHTTPHandler("/StartSession", HandleHttpStartSession);
m_Server.AddHTTPHandler("/CloseSession", HandleHttpCloseSession);
m_Server.AddHTTPHandler("/SessionCommand", HandleHttpSessionCommand);
}
public override void Output(string format)

View file

@ -831,17 +831,6 @@ namespace OpenSim.Framework.Servers.HttpServer
if (WebUtil.DebugLevel >= 5)
{
string output = System.Text.Encoding.UTF8.GetString(buffer);
if (WebUtil.DebugLevel >= 6)
{
// Always truncate binary blobs. We don't have a ContentType, so detect them using the request name.
if (requestHandler is not null && requestHandler.Name.Equals("GetMesh"))
{
if (output.Length > WebUtil.MaxRequestDiagLength)
output = string.Concat(output.AsSpan(0, WebUtil.MaxRequestDiagLength), "...");
}
}
WebUtil.LogResponseDetail(RequestNumber, output);
}
@ -2310,7 +2299,7 @@ namespace OpenSim.Framework.Servers.HttpServer
}
if (httpRequest.QueryFlags.Contains("about"))
{
httpResponse.Redirect("http://opensimulator.org/wiki/0.9.3.0_Release");
httpResponse.Redirect("http://opensimulator.org/wiki/0.9.3.1_Release");
return;
}
if (!httpRequest.QueryAsDictionary.TryGetValue("method", out string method) || string.IsNullOrWhiteSpace(method))

View file

@ -1485,6 +1485,9 @@ namespace OpenSim.Framework
return streamReader.ReadToEnd();
}
private static readonly string pathSSLRsaPriv = Path.Combine("SSL","src");
private static readonly string pathSSLcerts = Path.Combine("SSL","ssl");
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CreateOrUpdateSelfsignedCert(string certFileName, string certHostName, string certHostIp, string certPassword)
{
@ -1516,9 +1519,7 @@ namespace OpenSim.Framework
new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature , false));
// (Optional) SSL Server Authentication...
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(new X509EnhancedKeyUsageExtension([new Oid("1.3.6.1.5.5.7.3.1")], false));
request.CertificateExtensions.Add(san.Build());
@ -1527,29 +1528,86 @@ namespace OpenSim.Framework
string privateKey = Convert.ToBase64String(rsa.ExportRSAPrivateKey(), Base64FormattingOptions.InsertLineBreaks);
// Create the SSL folder and sub folders if not exists.
if (!Directory.Exists("SSL\\src\\"))
Directory.CreateDirectory("SSL\\src\\");
if (!Directory.Exists("SSL\\ssl\\"))
Directory.CreateDirectory("SSL\\ssl\\");
if (!Directory.Exists(pathSSLRsaPriv))
Directory.CreateDirectory(pathSSLRsaPriv);
if (!Directory.Exists(pathSSLcerts))
Directory.CreateDirectory(pathSSLcerts);
// Store the RSA key in SSL\src\
File.WriteAllText($"SSL\\src\\{certFileName}.txt", privateKey);
File.WriteAllText(Path.Combine(pathSSLRsaPriv, certFileName) + ".txt", privateKey);
// Export and store the .pfx and .p12 certificates in SSL\ssl\.
// Note: Pfx is a Pkcs12 certificate and both files work for OpenSim.
string sslFileNames = Path.Combine(pathSSLcerts, certFileName);
byte[] pfxCertBytes = string.IsNullOrEmpty(certPassword)
? certificate.Export(X509ContentType.Pfx)
: certificate.Export(X509ContentType.Pfx, certPassword);
File.WriteAllBytes($"SSL\\ssl\\{certFileName}.pfx", pfxCertBytes);
File.WriteAllBytes(sslFileNames + ".pfx", pfxCertBytes);
byte[] p12CertBytes = string.IsNullOrEmpty(certPassword)
? certificate.Export(X509ContentType.Pkcs12)
: certificate.Export(X509ContentType.Pkcs12, certPassword);
File.WriteAllBytes($"SSL\\ssl\\{certFileName}.p12", p12CertBytes);
File.WriteAllBytes(sslFileNames + ".p12", p12CertBytes);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ConvertPemToPKCS12(string certFileName, string fullChainPath, string privateKeyPath)
{
ConvertPemToPKCS12Certificate(certFileName, fullChainPath, privateKeyPath, null);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ConvertPemToPKCS12(string certFileName, string fullChainPath, string privateKeyPath, string outputPassword)
{
ConvertPemToPKCS12Certificate(certFileName, fullChainPath, privateKeyPath, outputPassword);
}
/// <summary>
/// Convert or renew .pem certificate to PKCS12 .pfx and .p12 usable by OpenSim.
/// the parameters are set in the startup section of OpenSim.ini
/// </summary>
/// <param name="certFileName">The output certificate file name.</param>
/// <param name="certPath">The path of fullchain.pem. If your CA don't provide
/// the fullchain file, you can set the cert.pem instead.</param>
/// <param name="keyPath">The path of the private key (privkey.pem).</param>
/// <param name="outputPassword">The output certificates password.</param>
private static void ConvertPemToPKCS12Certificate(string certFileName, string certPath, string keyPath, string outputPassword)
{
if(string.IsNullOrEmpty(certPath) || string.IsNullOrEmpty(keyPath)){
m_log.Error($"[UTIL PemToPKCS12]: Missing fullchain.pem or privkey.pem path!.");
return;
}
// Convert .pem (like Let's Encrypt files) to X509Certificate2 certificate.
X509Certificate2 certificate;
try
{
certificate = X509Certificate2.CreateFromPemFile(certPath, keyPath);
}
catch(CryptographicException e)
{
m_log.Error($"[UTIL PemToPKCS12]: {e.Message}" );
return;
}
// Create the SSL folder and ssl sub folder if not exists.
if (!Directory.Exists(pathSSLcerts))
Directory.CreateDirectory(pathSSLcerts);
string sslFileNames = System.IO.Path.Combine(pathSSLcerts, certFileName);
// Export and store the .pfx and .p12 certificates in SSL\ssl\.
byte[] pfxCertBytes = string.IsNullOrEmpty(outputPassword)
? certificate.Export(X509ContentType.Pfx)
: certificate.Export(X509ContentType.Pfx, outputPassword);
File.WriteAllBytes(sslFileNames + ".pfx", pfxCertBytes);
byte[] p12CertBytes = string.IsNullOrEmpty(outputPassword)
? certificate.Export(X509ContentType.Pkcs12)
: certificate.Export(X509ContentType.Pkcs12, outputPassword);
File.WriteAllBytes(sslFileNames + ".p12", p12CertBytes);
}
public static int fast_distance2d(int x, int y)
{
x = Math.Abs(x);
@ -3129,7 +3187,7 @@ namespace OpenSim.Framework
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
timeEndPeriod(1);
timeBeginPeriod(1);
Thread.Sleep(period);
timeEndPeriod(1);
}
@ -3137,6 +3195,37 @@ namespace OpenSim.Framework
Thread.Sleep(period);
}
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool SetProcessInformation(IntPtr hProcess, int ProcessInformationClass,
IntPtr ProcessInformation, UInt32 ProcessInformationSize);
[StructLayout(LayoutKind.Sequential)]
private struct PROCESS_POWER_THROTTLING_STATE
{
public uint Version;
public uint ControlMask;
public uint StateMask;
}
public static void DisableTimerThrottling()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
int sz = Marshal.SizeOf(typeof(PROCESS_POWER_THROTTLING_STATE));
PROCESS_POWER_THROTTLING_STATE PwrInfo = new()
{
Version = 1,
ControlMask = 4,
StateMask = 0
}; // disable that flag explicitly
nint PwrInfoPtr = Marshal.AllocHGlobal(sz);
Marshal.StructureToPtr(PwrInfo, PwrInfoPtr, false);
IntPtr handle = Process.GetCurrentProcess().Handle;
bool r = SetProcessInformation(handle, 4, PwrInfoPtr, (uint)sz);
Marshal.FreeHGlobal(PwrInfoPtr);
}
}
/// <summary>
/// Used to trigger an early library load on Windows systems.
/// </summary>

View file

@ -35,6 +35,20 @@ namespace OpenSim
public const string AssemblyVersionNumber = "0.9.3";
public const string Release = "9054";
public const Flavour VERSION_FLAVOUR = Flavour.Dev;
public enum Flavour
{
Unknown,
Dev,
RC1,
RC2,
RC3,
Release,
Post_Fixes,
Extended
}
public static string Version
{
get { return GetVersionString(VersionNumber, Release); }

View file

@ -332,7 +332,7 @@ namespace OpenSim.Framework
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void LogOutgoingDetail(string context, string output)
{
if (DebugLevel == 5)
if (DebugLevel >= 5)
{
if (output.Length > MaxRequestDiagLength)
output = output[..MaxRequestDiagLength] + "...";

View file

@ -71,7 +71,6 @@ namespace OpenSim.Region.ClientStack.LindenCaps
lock (m_scenes)
m_scenes.Remove(scene);
scene.EventManager.OnRegisterCaps -= RegisterCaps;
scene = null;
}
public void RegionLoaded(Scene scene)
@ -79,8 +78,7 @@ namespace OpenSim.Region.ClientStack.LindenCaps
scene.EventManager.OnRegisterCaps += RegisterCaps;
ISimulatorFeaturesModule simFeatures = scene.RequestModuleInterface<ISimulatorFeaturesModule>();
if(simFeatures != null)
simFeatures.AddFeature("AvatarHoverHeightEnabled",OSD.FromBoolean(true));
simFeatures?.AddFeature("AvatarHoverHeightEnabled",OSD.FromBoolean(true));
}

View file

@ -904,7 +904,12 @@ namespace OpenSim.Region.Framework.Scenes
RegionInfo.RegionSettings = rs;
if (estateDataService is not null)
RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
{
EstateSettings es = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
if (es == null)
m_log.Error($"[SCENE]: Region {Name} failed to load estate settings. Using defaults");
RegionInfo.EstateSettings = es;
}
SceneGridInfo = new GridInfo(config, RegionInfo.ServerURI);
@ -5844,7 +5849,10 @@ Environment.Exit(1);
if (estateDataService is not null)
{
bool parcelEnvOvr = RegionInfo.EstateSettings.AllowEnvironmentOverride;
RegionInfo.EstateSettings = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
EstateSettings es = estateDataService.LoadEstateSettings(RegionInfo.RegionID, false);
if (es == null)
m_log.Error($"[SCENE]: Region {RegionInfo.RegionName} failed to reload estate settings. Using defaults");
RegionInfo.EstateSettings = es;
if(parcelEnvOvr && !RegionInfo.EstateSettings.AllowEnvironmentOverride)
ClearAllParcelEnvironments();
}

View file

@ -5213,35 +5213,37 @@ namespace OpenSim.Region.Framework.Scenes
try
{
// get all the scripts in all parts
SceneObjectPart[] parts = m_parts.GetArray();
List<TaskInventoryItem> scripts = new();
for (int i = 0; i < parts.Length; i++)
{
IEntityInventory inv = parts[i].Inventory;
if(inv is not null)
scripts.AddRange(inv.GetInventoryItems(InventoryType.LSL));
}
if (scripts.Count == 0)
return false;
// extract the UUIDs
HashSet<UUID> unique = new();
foreach (TaskInventoryItem script in scripts)
unique.Add(script.ItemID);
List<UUID> ids = unique.ToList();
// Offer the list of script UUIDs to each engine found and accumulate the memory
foreach (IScriptModule e in engines)
{
if (e is not null)
// get all the scripts in all parts
SceneObjectPart[] parts = m_parts.GetArray();
List<TaskInventoryItem> scripts = new();
for (int i = 0; i < parts.Length; i++)
{
memory += e.GetScriptsMemory(ids);
IEntityInventory inv = parts[i].Inventory;
if(inv is not null)
scripts.AddRange(inv.GetInventoryItems(InventoryType.LSL));
}
if (scripts.Count == 0)
return false;
// extract the UUIDs
HashSet<UUID> unique = new();
foreach (TaskInventoryItem script in scripts)
unique.Add(script.ItemID);
List<UUID> ids = unique.ToList();
// Offer the list of script UUIDs to each engine found and accumulate the memory
foreach (IScriptModule e in engines)
{
if (e is not null)
{
memory += e.GetScriptsMemory(ids);
}
}
return true;
}
return true;
}
catch
{
return false;

View file

@ -2516,6 +2516,13 @@ namespace OpenSim.Region.ScriptEngine.Yengine
}
else
{
if (curDeclFunc.fullName != "$globalvarinit()")
{
PushXMRInst();
ilGen.Emit(curDeclFunc, OpCodes.Ldloc, curHeapSize);
ilGen.Emit(curDeclFunc, OpCodes.Stfld, heapUsedFieldInfo);
}
ilGen.Emit(stateStmt, OpCodes.Ldc_I4, index); // new state's index
ilGen.Emit(stateStmt, OpCodes.Newobj, scriptChangeStateExceptionConstructorInfo);
}

View file

@ -543,19 +543,22 @@ namespace OpenSim.Server.Base
public static Dictionary<string, object> ParseXmlResponse(string data)
{
try
if(!string.IsNullOrEmpty(data))
{
using XmlReader xr = XmlReader.Create(new StringReader(data),
ParseXmlStringResponseXmlReaderSettings, ParseXmlResponseXmlParserContext);
if(!xr.ReadToFollowing("ServerResponse"))
return new Dictionary<string, object>();
return ScanXmlResponse(xr);
try
{
using XmlReader xr = XmlReader.Create(new StringReader(data), ParseXmlStringResponseXmlReaderSettings, ParseXmlResponseXmlParserContext)
{
if (xr.ReadToFollowing("ServerResponse"))
return ScanXmlResponse(xr);
}
}
catch (Exception e)
{
m_log.Debug($"[serverUtils.ParseXmlResponse]: failed error: {e.Message}\n --string:\n{data}\n");
}
catch (Exception e)
{
m_log.DebugFormat("[serverUtils.ParseXmlResponse]: failed error: {0}\n --string:\n{1}\n", e.Message, data);
}
return new Dictionary<string, object>();
return [];
}
private static readonly XmlReaderSettings ParseXmlStreamResponseXmlReaderSettings = new()

View file

@ -194,19 +194,16 @@ namespace OpenSim.Server.Handlers
if (!string.IsNullOrEmpty(region))
{
UUID regionID = UUID.Zero;
if (UUID.TryParse(region, out regionID))
if (UUID.TryParse(region, out UUID regionID))
{
string create = (string)httpRequest.Query["create"];
bool createYN = false;
Boolean.TryParse(create, out createYN);
bool.TryParse(create, out bool createYN);
estate = m_EstateService.LoadEstateSettings(regionID, createYN);
}
}
else if (!string.IsNullOrEmpty(eid))
{
int id = 0;
if (Int32.TryParse(eid, out id))
if (int.TryParse(eid, out int id))
estate = m_EstateService.LoadEstateSettings(id);
}

View file

@ -102,6 +102,9 @@ namespace OpenSim.Server.Handlers.Grid
case "get_region_by_name":
return GetRegionByName(request);
case "get_localregion_by_name":
return GetLocalRegionByName(request);
case "get_regions_by_name":
return GetRegionsByName(request);
@ -327,21 +330,40 @@ namespace OpenSim.Server.Handlers.Grid
byte[] GetRegionByName(Dictionary<string, object> request)
{
UUID scopeID = UUID.Zero;
if (request.ContainsKey("SCOPEID"))
UUID.TryParse(request["SCOPEID"].ToString(), out scopeID);
else
m_log.WarnFormat("[GRID HANDLER]: no scopeID in request to get region by name");
if (!request.TryGetValue("SCOPEID", out object scpo) || scpo is not string scps || !UUID.TryParse(scps, out scopeID))
m_log.WarnFormat("[GRID HANDLER]: no or invalid scopeID in request to get region by name");
string regionName = string.Empty;
if (request.ContainsKey("NAME"))
regionName = request["NAME"].ToString();
GridRegion rinfo = null;
if (request.TryGetValue("NAME", out object nameo) && nameo is string regionName)
rinfo = m_GridService.GetRegionByName(scopeID, regionName);
else
m_log.WarnFormat("[GRID HANDLER]: no name in request to get region by name");
GridRegion rinfo = m_GridService.GetRegionByName(scopeID, regionName);
//m_log.DebugFormat("[GRID HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count);
Dictionary<string, object> result = [];
if (rinfo == null)
result["result"] = "null";
else
result["result"] = rinfo.ToKeyValuePairs();
Dictionary<string, object> result = new Dictionary<string, object>();
string xmlString = ServerUtils.BuildXmlResponse(result);
//m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString);
return Util.UTF8NoBomEncoding.GetBytes(xmlString);
}
byte[] GetLocalRegionByName(Dictionary<string, object> request)
{
UUID scopeID = UUID.Zero;
if (!request.TryGetValue("SCOPEID", out object scpo) || scpo is not string scps || !UUID.TryParse(scps, out scopeID))
m_log.WarnFormat("[GRID HANDLER]: no or invalid scopeID in request to get region by name");
GridRegion rinfo = null;
if (request.TryGetValue("NAME", out object nameo) && nameo is string regionName)
rinfo = m_GridService.GetLocalRegionByName(scopeID, regionName);
else
m_log.WarnFormat("[GRID HANDLER]: no name in request to get region by name");
Dictionary<string, object> result = [];
if (rinfo == null)
result["result"] = "null";
else

View file

@ -69,18 +69,24 @@ namespace OpenSim.Server.Handlers.Presence
string method = string.Empty;
try
{
Dictionary<string, object> request =
ServerUtils.ParseQueryString(body);
Dictionary<string, object> request = ServerUtils.ParseQueryString(body);
if (!request.ContainsKey("METHOD"))
if (!request.TryGetValue("METHOD", out object tmpobj) || tmpobj is not string)
return FailureResult();
method = request["METHOD"].ToString();
method = (string)tmpobj;
switch (method)
{
case "login":
return LoginAgent(request);
{
//return LoginAgent(request); this is ilegal
if (request.TryGetValue("UserID", out object uo) && uo is string user)
m_log.Debug($"[PRESENCE HANDLER]: ilegal login try from {httpRequest.RemoteIPEndPoint} for userID {user}");
else
m_log.Debug($"[PRESENCE HANDLER]: ilegal login try from {httpRequest.RemoteIPEndPoint} for unkown user");
return FailureResult();
}
case "logout":
return LogoutAgent(request);
case "logoutregion":
@ -92,11 +98,11 @@ namespace OpenSim.Server.Handlers.Presence
case "getagents":
return GetAgents(request);
}
m_log.DebugFormat("[PRESENCE HANDLER]: unknown method request: {0}", method);
m_log.Debug($"[PRESENCE HANDLER]: unknown method request: {method}");
}
catch (Exception e)
{
m_log.DebugFormat("[PRESENCE HANDLER]: Exception in method {0}: {1}", method, e);
m_log.Debug($"[PRESENCE HANDLER]: Exception in method {method}: {e.Message}");
}
return FailureResult();

View file

@ -355,23 +355,30 @@ namespace OpenSim
// Sure is not the right place for this but do the job...
// Must always be called before (all) / the HTTP servers starting for the Certs creation or renewals.
if (startupConfig is not null)
if (startupConfig.GetBoolean("EnableSelfsignedCertSupport", false))
{
if (startupConfig.GetBoolean("EnableSelfsignedCertSupport", false))
{
if(!File.Exists("SSL\\ssl\\"+ startupConfig.GetString("CertFileName") +".p12") || startupConfig.GetBoolean("CertRenewOnStartup"))
{
Util.CreateOrUpdateSelfsignedCert(
string.IsNullOrEmpty(startupConfig.GetString("CertFileName")) ? "OpenSim" : startupConfig.GetString("CertFileName"),
string.IsNullOrEmpty(startupConfig.GetString("CertHostName")) ? "localhost" : startupConfig.GetString("CertHostName"),
string.IsNullOrEmpty(startupConfig.GetString("CertHostIp")) ? "127.0.0.1" : startupConfig.GetString("CertHostIp"),
string.IsNullOrEmpty(startupConfig.GetString("CertPassword")) ? string.Empty : startupConfig.GetString("CertPassword")
);
}
if (!File.Exists("SSL\\ssl\\"+ startupConfig.GetString("CertFileName") +".p12") || startupConfig.GetBoolean("CertRenewOnStartup"))
{
Util.CreateOrUpdateSelfsignedCert(
string.IsNullOrEmpty(startupConfig.GetString("CertFileName")) ? "OpenSim" : startupConfig.GetString("CertFileName"),
string.IsNullOrEmpty(startupConfig.GetString("CertHostName")) ? "localhost" : startupConfig.GetString("CertHostName"),
string.IsNullOrEmpty(startupConfig.GetString("CertHostIp")) ? "127.0.0.1" : startupConfig.GetString("CertHostIp"),
string.IsNullOrEmpty(startupConfig.GetString("CertPassword")) ? string.Empty : startupConfig.GetString("CertPassword")
);
}
}
if (startupConfig.GetBoolean("EnableCertConverter", false))
{
Util.ConvertPemToPKCS12(
string.IsNullOrEmpty(startupConfig.GetString("outputCertName")) ? "letsencrypt" : startupConfig.GetString("outputCertName"),
string.IsNullOrEmpty(startupConfig.GetString("PemCertPublicKey")) ? string.Empty : startupConfig.GetString("PemCertPublicKey"),
string.IsNullOrEmpty(startupConfig.GetString("PemCertPrivateKey")) ? string.Empty : startupConfig.GetString("PemCertPrivateKey"),
string.IsNullOrEmpty(startupConfig.GetString("outputCertPassword")) ? string.Empty : startupConfig.GetString("outputCertPassword")
);
}
if(m_networkServersInfo.HttpUsesSSL)
if (m_networkServersInfo.HttpUsesSSL)
{
m_httpServerSSL = true;
m_httpServerPort = m_networkServersInfo.httpSSLPort;
@ -1052,7 +1059,7 @@ namespace OpenSim
m_log.WarnFormat("[ESTATE] Region {0} is not part of an estate.", regInfo.RegionName);
List<EstateSettings> estates = EstateDataService.LoadEstateSettingsAll();
Dictionary<string, EstateSettings> estatesByName = new Dictionary<string, EstateSettings>();
Dictionary<string, EstateSettings> estatesByName = [];
foreach (EstateSettings estate in estates)
estatesByName[estate.EstateName] = estate;

View file

@ -104,7 +104,7 @@ namespace OpenSim.Services.Base
"[SERVICE BASE]: Failed to load plugin {0} from {1} with args {2}",
interfaceName, dllName, string.Join(", ", strArgs.ToArray()), e);
if (e.InnerException != null)
m_log.Error($"\"[SERVICE BASE]: inner expection {e.InnerException.Message}");
m_log.Error($"[SERVICE BASE]: inner exception {e.InnerException.Message}");
return null;
}

View file

@ -35,8 +35,6 @@ using OpenMetaverse;
using Nini.Config;
using OpenSim.Framework;
using OpenSim.Framework.ServiceAuth;
using OpenSim.Services.Connectors;
using OpenSim.Services.Interfaces;
using OpenSim.Server.Base;
using System.Net.Http;
@ -45,9 +43,7 @@ namespace OpenSim.Services.Connectors
{
public class EstateDataRemoteConnector : BaseServiceConnector, IEstateDataService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string m_ServerURI = String.Empty;
private ExpiringCache<string, List<EstateSettings>> m_EstateCache = new ExpiringCache<string, List<EstateSettings>>();
@ -61,15 +57,13 @@ namespace OpenSim.Services.Connectors
public virtual void Initialise(IConfigSource source)
{
IConfig gridConfig = source.Configs["EstateService"];
if (gridConfig == null)
if (gridConfig is null)
{
m_log.Error("[ESTATE CONNECTOR]: EstateService missing from OpenSim.ini");
throw new Exception("Estate connector init error");
}
string serviceURI = gridConfig.GetString("EstateServerURI",
String.Empty);
string serviceURI = gridConfig.GetString("EstateServerURI", string.Empty);
if (serviceURI.Length == 0)
{
m_log.Error("[ESTATE CONNECTOR]: No Server URI named in section EstateService");
@ -84,45 +78,41 @@ namespace OpenSim.Services.Connectors
public List<EstateSettings> LoadEstateSettingsAll()
{
string reply = string.Empty;
string uri = m_ServerURI + "/estates";
reply = MakeRequest("GET", uri, string.Empty);
string reply = MakeRequest("GET", uri, string.Empty);
if (String.IsNullOrEmpty(reply))
return new List<EstateSettings>();
return [];
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
List<EstateSettings> estates = new List<EstateSettings>();
if (replyData != null && replyData.Count > 0)
{
m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettingsAll returned {0} elements", replyData.Count);
m_log.Debug($"[ESTATE CONNECTOR]: LoadEstateSettingsAll returned {replyData.Count} elements");
Dictionary<string, object>.ValueCollection estateData = replyData.Values;
List<EstateSettings> estates = [];
foreach (object r in estateData)
{
if (r is Dictionary<string, object>)
if (r is Dictionary<string, object> dr )
{
EstateSettings es = new EstateSettings((Dictionary<string, object>)r);
EstateSettings es = new EstateSettings(dr);
estates.Add(es);
}
}
m_EstateCache.AddOrUpdate("estates", estates, EXPIRATION);
return estates;
}
else
m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettingsAll from {0} received null or zero response", uri);
return estates;
m_log.Debug($"[ESTATE CONNECTOR]: LoadEstateSettingsAll from {uri} received empty response");
return [];
}
public List<int> GetEstatesAll()
{
List<int> eids = new List<int>();
// If we don't have them, load them from the server
List<EstateSettings> estates = null;
if (!m_EstateCache.TryGetValue("estates", out estates))
if (!m_EstateCache.TryGetValue("estates", out List<EstateSettings> estates))
estates = LoadEstateSettingsAll();
List<int> eids = [];
foreach (EstateSettings es in estates)
eids.Add((int)es.EstateID);
@ -132,11 +122,10 @@ namespace OpenSim.Services.Connectors
public List<int> GetEstates(string search)
{
// If we don't have them, load them from the server
List<EstateSettings> estates = null;
if (!m_EstateCache.TryGetValue("estates", out estates))
if (!m_EstateCache.TryGetValue("estates", out List<EstateSettings> estates))
estates = LoadEstateSettingsAll();
List<int> eids = new List<int>();
List<int> eids = [];
foreach (EstateSettings es in estates)
if (es.EstateName == search)
eids.Add((int)es.EstateID);
@ -147,13 +136,12 @@ namespace OpenSim.Services.Connectors
public List<int> GetEstatesByOwner(UUID ownerID)
{
// If we don't have them, load them from the server
List<EstateSettings> estates = null;
if (!m_EstateCache.TryGetValue("estates", out estates))
if (!m_EstateCache.TryGetValue("estates", out List<EstateSettings> estates))
estates = LoadEstateSettingsAll();
List<int> eids = new List<int>();
List<int> eids = [];
foreach (EstateSettings es in estates)
if (es.EstateOwner == ownerID)
if (es.EstateOwner.Equals(ownerID))
eids.Add((int)es.EstateID);
return eids;
@ -161,37 +149,33 @@ namespace OpenSim.Services.Connectors
public List<UUID> GetRegions(int estateID)
{
string reply = string.Empty;
// /estates/regions/?eid=int
string uri = m_ServerURI + "/estates/regions/?eid=" + estateID.ToString();
reply = MakeRequest("GET", uri, string.Empty);
string reply = MakeRequest("GET", uri, string.Empty);
if (String.IsNullOrEmpty(reply))
return new List<UUID>();
return [];
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
List<UUID> regions = new List<UUID>();
if (replyData != null && replyData.Count > 0)
{
m_log.DebugFormat("[ESTATE CONNECTOR]: GetRegions for estate {0} returned {1} elements", estateID, replyData.Count);
m_log.Debug($"[ESTATE CONNECTOR]: GetRegions for estate {estateID} returned {replyData.Count} elements");
List<UUID> regions = [];
Dictionary<string, object>.ValueCollection data = replyData.Values;
foreach (object r in data)
{
UUID uuid = UUID.Zero;
if (UUID.TryParse(r.ToString(), out uuid))
if (UUID.TryParse(r.ToString(), out UUID uuid))
regions.Add(uuid);
}
return regions;
}
else
m_log.DebugFormat("[ESTATE CONNECTOR]: GetRegions from {0} received null or zero response", uri);
return regions;
m_log.Debug($"[ESTATE CONNECTOR]: GetRegions from {uri} received null or zero response");
return [];
}
public EstateSettings LoadEstateSettings(UUID regionID, bool create)
{
string reply = string.Empty;
// /estates/estate/?region=uuid&create=[t|f]
string uri = m_ServerURI + string.Format("/estates/estate/?region={0}&create={1}", regionID, create);
@ -199,16 +183,7 @@ namespace OpenSim.Services.Connectors
// service here will return a 404 if the estate doesnt exist which is correct but the code
// assumes thats a fatal error. BTW We should never ever call Enviroinment.Exit from a supporting
// module or a library like this. So its gonna go.
reply = MakeRequest("GET", uri, string.Empty);
if (reply is null)
{
m_log.DebugFormat("[ESTATE CONNECTOR] connection to remote estates service failed");
//m_log.DebugFormat("[ESTATE CONNECTOR] simulator needs to terminate");
//Environment.Exit(-1);
return null;
}
var reply = MakeRequest("GET", uri, string.Empty);
if (String.IsNullOrEmpty(reply))
{
return null;
@ -232,11 +207,10 @@ namespace OpenSim.Services.Connectors
public EstateSettings LoadEstateSettings(int estateID)
{
string reply = string.Empty;
// /estates/estate/?eid=int
string uri = m_ServerURI + string.Format("/estates/estate/?eid={0}", estateID);
string uri = m_ServerURI + $"/estates/estate/?eid={estateID}";
reply = MakeRequest("GET", uri, string.Empty);
string reply = MakeRequest("GET", uri, string.Empty);
if (String.IsNullOrEmpty(reply))
return null;
@ -244,7 +218,7 @@ namespace OpenSim.Services.Connectors
if (replyData != null && replyData.Count > 0)
{
m_log.DebugFormat("[ESTATE CONNECTOR]: LoadEstateSettings({0}) returned {1} elements", estateID, replyData.Count);
m_log.Debug($"[ESTATE CONNECTOR]: LoadEstateSettings({estateID}) returned {replyData.Count} elements");
EstateSettings es = new EstateSettings(replyData);
return es;
}
@ -267,7 +241,7 @@ namespace OpenSim.Services.Connectors
public void StoreEstateSettings(EstateSettings es)
{
// /estates/estate/
string uri = m_ServerURI + ("/estates/estate");
string uri = m_ServerURI + "/estates/estate";
Dictionary<string, object> formdata = es.ToMap();
formdata["OP"] = "STORE";
@ -278,10 +252,12 @@ namespace OpenSim.Services.Connectors
public bool LinkRegion(UUID regionID, int estateID)
{
// /estates/estate/?eid=int&region=uuid
string uri = m_ServerURI + String.Format("/estates/estate/?eid={0}&region={1}", estateID, regionID);
string uri = m_ServerURI + $"/estates/estate/?eid={estateID}&region={regionID}";
Dictionary<string, object> formdata = new Dictionary<string, object>();
formdata["OP"] = "LINK";
Dictionary<string, object> formdata = new()
{
["OP"] = "LINK"
};
return PostRequest(uri, formdata);
}
@ -294,20 +270,21 @@ namespace OpenSim.Services.Connectors
return false;
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
bool result = false;
if (replyData != null && replyData.Count > 0)
{
if (replyData.ContainsKey("Result"))
if (replyData.TryGetValue("Result", out object ortmp) && ortmp is string srtmp)
{
if (Boolean.TryParse(replyData["Result"].ToString(), out result))
m_log.DebugFormat("[ESTATE CONNECTOR]: PostRequest {0} returned {1}", uri, result);
if (bool.TryParse(srtmp, out bool result))
{
m_log.Debug($"[ESTATE CONNECTOR]: PostRequest {uri} returned {result}");
return result;
}
}
}
else
m_log.DebugFormat("[ESTATE CONNECTOR]: PostRequest {0} received null or zero response", uri);
m_log.Debug($"[ESTATE CONNECTOR]: PostRequest {uri} received empty response");
return result;
return false;
}
/// <summary>
@ -335,22 +312,20 @@ namespace OpenSim.Services.Connectors
{
if (status == HttpStatusCode.Unauthorized)
{
m_log.Error(string.Format("[ESTATE CONNECTOR]: Web request {0} requires authentication ", uri));
m_log.Error($"[ESTATE CONNECTOR]: Web request {uri} requires authentication ");
}
else if (status != HttpStatusCode.NotFound)
{
m_log.Error(string.Format("[ESTATE CONNECTOR]: Resource {0} not found ", uri));
m_log.Error($"[ESTATE CONNECTOR]: Resource {uri} not found ");
return reply;
}
}
else
m_log.Error(string.Format(
"[ESTATE CONNECTOR]: WebException for {0} {1} {2} {3}",
verb, uri, formdata, e.Message));
m_log.Error($"[ESTATE CONNECTOR]: WebException for {verb} {uri} {formdata} {e.Message}");
}
catch (Exception e)
{
m_log.DebugFormat("[ESTATE CONNECTOR]: Exception when contacting estate server at {0}: {1}", uri, e.Message);
m_log.DebugFormat($"[ESTATE CONNECTOR]: Exception when contacting estate server at {uri}: {e.Message}");
}
return null;

View file

@ -44,9 +44,7 @@ namespace OpenSim.Services.GridService
{
public class GridService : GridServiceBase, IGridService
{
private static readonly ILog m_log =
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private string LogHeader = "[GRID SERVICE]";
private bool m_DeleteOnUnregister = true;
@ -599,7 +597,7 @@ namespace OpenSim.Services.GridService
if (!uri.ResolveDNS())
return null;
if(!m_HypergridLinker.IsLocalGrid(uri.HostUrl))
return null;
return null;
}
if (uri.HasRegionName)

View file

@ -245,7 +245,7 @@ namespace OpenSim.Services.HypergridService
else
{
reason = "Grid setup problem. Try specifying a particular region here.";
m_log.DebugFormat("[GATEKEEPER SERVICE]: Unable to send information. Please specify a default region for this grid!");
m_log.Debug("[GATEKEEPER SERVICE]: Unable to send information. Please specify a default region for this grid!");
return false;
}
}
@ -254,6 +254,7 @@ namespace OpenSim.Services.HypergridService
region = m_GridService.GetLocalRegionByName(m_ScopeID, regionName);
if (region is null)
{
m_log.DebugFormat($"[GATEKEEPER SERVICE]: LinkLocalRegion could not find local region {regionName}");
reason = "Region not found";
return false;
}

View file

@ -1,6 +1,6 @@
<configuration>
<dllmap os="windows" cpu="x86-64" dll="BulletSim" target="lib64/BulletSim-3.26-20231207-x86_64.dll" />
<dllmap os="osx" dll="BulletSim" target="lib64/libBulletSim.dylib" />
<dllmap os="osx" dll="BulletSim" target="lib64/libBulletSim-3.26-20231203-universal.dylib" />
<dllmap os="!windows,osx" cpu="x86-64" dll="BulletSim" target="lib64/libBulletSim-2.86-20170903-x86_64.so" />
<dllmap os="!windows,osx" cpu="arm64" dll="BulletSim" target="lib64/libBulletSim-arm64.so" />
</configuration>

View file

@ -310,11 +310,36 @@
; TelehubAllowLandmark = false
;; Let's Encrypt and others ".pem" certificates converter settings.
;; Enabling this feature will automatically convert the CA .pem certificates to
;; OpenSim compatible PKCS12 .p12 and .pfx certificates on every server startup.
;; The resulting certificates are stored in the bin\SSL\ssl folder.
;# {EnableCertConverter} {} {Enable pem to pkcs12 certificates converter} {true false} false
EnableCertConverter = false
;; Set the absolute path of the "fullchain.pem". If your CA don't provide this file,
;; you can use the "cert.pem" instead.
;# {PemCertPublicKey} {} {Set the path of the public key .pem} {} ""
PemCertPublicKey = ""
;; Set the absolute path of the pem private key "privkey.pem".
;# {PemCertPrivateKey} {} {Set the path of the private key .pem} {} ""
PemCertPrivateKey = ""
;; Set the name of the resulting .p12 and .pfx.
;# {outputCertName} {} {Set the name of the resulting .p12 and .pfx} {} "letsencrypt"
outputCertName = "letsencrypt"
;; Set the .p12 and .pfx password.
;# {outputCertPassword} {} {Set the .p12 and .pfx password} {} ""
outputCertPassword = ""
;; SSL selfsigned certificate settings.
;; Enable selfsigned certificate creation for local and external use. When set to true, will create a folder SSL\ and 2 sub folders SSL\ssl\ and SSL\src\.
;; Next creates and store an RSA private key in SSL\src\ and the derived selfsigned certificate in SSL\ssl\ folder.
;;Is also possible to renew the certificate on every server restart if CertRenewOnStartup is set to true.
;# {EnbleSelfsignedCertSupport} {} {Enable selfsigned certificate creation and renew} {true false} false
;# {EnableSelfsignedCertSupport} {} {Enable selfsigned certificate creation and renew} {true false} false
EnableSelfsignedCertSupport = false
;; Renew the selfsigned certificate on every server startup ?

View file

@ -400,6 +400,33 @@
; default is false
; TelehubAllowLandmark = false
; #
; # Let's Encrypt and others ".pem" certificates converter settings.
; #
;; Enabling this feature will automatically convert the CA .pem certificates to
;; OpenSim compatible PKCS12 .p12 and .pfx certificates on every server startup.
;; The resulting certificates are stored in the bin\SSL\ssl folder.
;# {EnableCertConverter} {} {Enable pem to pkcs12 certificates converter} {true false} false
EnableCertConverter = false
;; Set the absolute path of the "fullchain.pem". If your CA don't provide this file,
;; you can use the "cert.pem" instead.
;# {PemCertPublicKey} {} {Set the path of the public key .pem} {} ""
PemCertPublicKey = ""
;; Set the absolute path of the pem private key "privkey.pem".
;# {PemCertPrivateKey} {} {Set the path of the private key .pem} {} ""
PemCertPrivateKey = ""
;; Set the name of the resulting .p12 and .pfx.
;# {outputCertName} {} {Set the name of the resulting .p12 and .pfx} {} "letsencrypt"
outputCertName = "letsencrypt"
;; Set the .p12 and .pfx password.
;# {outputCertPassword} {} {Set the .p12 and .pfx password} {} ""
outputCertPassword = ""
; #
; # SSL selfsigned certificate settings.
; #
@ -2205,7 +2232,7 @@
[ServerReleaseNotes]
;; Comment or set to "" to disable
ServerReleaseNotesURL = "http://opensimulator.org/wiki/0.9.3.0_Release"
ServerReleaseNotesURL = "http://opensimulator.org/wiki/0.9.3.1_Release"
[Modules]
Include-modules = "addon-modules/*/config/*.ini"

File diff suppressed because it is too large Load diff

Binary file not shown.

Binary file not shown.

Binary file not shown.