|
@@ -10,13 +10,12 @@ namespace PixiEditor.Extensions.Runtime;
|
|
|
|
|
|
public class ExtensionLoader
|
|
|
{
|
|
|
- private readonly Dictionary<string, OfficialExtensionData> _officialExtensionsKeys =
|
|
|
- new Dictionary<string, OfficialExtensionData>();
|
|
|
-
|
|
|
public List<Extension> LoadedExtensions { get; } = new();
|
|
|
|
|
|
public string[] PackagesPath { get; }
|
|
|
public string UnpackedExtensionsPath { get; }
|
|
|
+
|
|
|
+ public ExtensionServices Services { get; set; }
|
|
|
|
|
|
private WasmRuntime.WasmRuntime _wasmRuntime = new WasmRuntime.WasmRuntime();
|
|
|
|
|
@@ -27,11 +26,6 @@ public class ExtensionLoader
|
|
|
ValidateExtensionFolder();
|
|
|
}
|
|
|
|
|
|
- public void AddOfficialExtension(string uniqueName, OfficialExtensionData data)
|
|
|
- {
|
|
|
- _officialExtensionsKeys.Add(uniqueName, data);
|
|
|
- }
|
|
|
-
|
|
|
public void LoadExtensions()
|
|
|
{
|
|
|
foreach (var packagesPath in PackagesPath)
|
|
@@ -271,10 +265,11 @@ public class ExtensionLoader
|
|
|
|
|
|
if (fixedUniqueName.StartsWith("pixieditor".Trim(), StringComparison.OrdinalIgnoreCase))
|
|
|
{
|
|
|
- if (!IsOfficialAssemblyLegit(fixedUniqueName, assembly))
|
|
|
+ // Validate within extension store
|
|
|
+ /*if (!IsOfficialAssemblyLegit(fixedUniqueName, assembly))
|
|
|
{
|
|
|
throw new ForbiddenUniqueNameExtension();
|
|
|
- }
|
|
|
+ }*/
|
|
|
|
|
|
if (!IsAdditionalContentInstalled(fixedUniqueName))
|
|
|
{
|
|
@@ -298,66 +293,9 @@ public class ExtensionLoader
|
|
|
|
|
|
private bool IsAdditionalContentInstalled(string fixedUniqueName)
|
|
|
{
|
|
|
- if (!_officialExtensionsKeys.ContainsKey(fixedUniqueName)) return false;
|
|
|
- AdditionalContentProduct? product = _officialExtensionsKeys[fixedUniqueName].Product;
|
|
|
-
|
|
|
- if (product == null) return true;
|
|
|
-
|
|
|
- return IPlatform.Current.AdditionalContentProvider?.IsContentInstalled(product.Value) ?? false;
|
|
|
- }
|
|
|
-
|
|
|
- private bool IsOfficialAssemblyLegit(string metadataUniqueName, ExtensionEntry entry)
|
|
|
- {
|
|
|
- if (entry == null) return false; // All official extensions must have a valid assembly
|
|
|
- if (!_officialExtensionsKeys.ContainsKey(metadataUniqueName)) return false;
|
|
|
-
|
|
|
- if (entry is DllExtensionEntry dllExtensionEntry)
|
|
|
- {
|
|
|
- return VerifyAssemblySignature(metadataUniqueName, dllExtensionEntry.Assembly);
|
|
|
- }
|
|
|
-
|
|
|
- if (entry is WasmExtensionEntry wasmExtensionEntry)
|
|
|
- {
|
|
|
- return true;
|
|
|
- //TODO: Verify wasm signature somehow
|
|
|
- //return VerifyAssemblySignature(metadataUniqueName, wasmExtensionEntry.Instance);
|
|
|
- }
|
|
|
-
|
|
|
- return false;
|
|
|
+ return IPlatform.Current.AdditionalContentProvider?.IsInstalled(fixedUniqueName) ?? false;
|
|
|
}
|
|
|
|
|
|
- private bool VerifyAssemblySignature(string metadataUniqueName, Assembly assembly)
|
|
|
- {
|
|
|
- bool wasVerified = false;
|
|
|
- bool verified = StrongNameSignatureVerificationEx(assembly.Location, true, ref wasVerified);
|
|
|
- if (!verified || !wasVerified) return false;
|
|
|
-
|
|
|
- byte[]? assemblyPublicKey = assembly.GetName().GetPublicKey();
|
|
|
- if (assemblyPublicKey == null) return false;
|
|
|
-
|
|
|
- return PublicKeysMatch(assemblyPublicKey, _officialExtensionsKeys[metadataUniqueName].PublicKeyName);
|
|
|
- }
|
|
|
-
|
|
|
- private bool PublicKeysMatch(byte[] assemblyPublicKey, string pathToPublicKey)
|
|
|
- {
|
|
|
- Assembly currentAssembly = Assembly.GetExecutingAssembly();
|
|
|
- using Stream? stream =
|
|
|
- currentAssembly.GetManifestResourceStream(
|
|
|
- $"{currentAssembly.GetName().Name}.OfficialExtensions.{pathToPublicKey}");
|
|
|
- if (stream == null) return false;
|
|
|
-
|
|
|
- using MemoryStream memoryStream = new MemoryStream();
|
|
|
- stream.CopyTo(memoryStream);
|
|
|
- byte[] publicKey = memoryStream.ToArray();
|
|
|
-
|
|
|
- return assemblyPublicKey.SequenceEqual(publicKey);
|
|
|
- }
|
|
|
-
|
|
|
- //TODO: uhh, other platforms dumbass?
|
|
|
- [DllImport("mscoree.dll", CharSet = CharSet.Unicode)]
|
|
|
- static extern bool StrongNameSignatureVerificationEx(string wszFilePath, bool fForceVerification,
|
|
|
- ref bool pfWasVerified);
|
|
|
-
|
|
|
private Extension LoadExtensionEntry(ExtensionEntry entry, ExtensionMetadata metadata)
|
|
|
{
|
|
|
Extension extension = entry.CreateExtension();
|
|
@@ -444,16 +382,3 @@ public class ExtensionLoader
|
|
|
return null;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-public struct OfficialExtensionData
|
|
|
-{
|
|
|
- public string PublicKeyName { get; }
|
|
|
- public AdditionalContentProduct? Product { get; }
|
|
|
- public string? PurchaseLink { get; }
|
|
|
-
|
|
|
- public OfficialExtensionData(string publicKeyName, AdditionalContentProduct product, string? purchaseLink = null)
|
|
|
- {
|
|
|
- PublicKeyName = publicKeyName;
|
|
|
- Product = product;
|
|
|
- }
|
|
|
-}
|