Skip to content

Commit 6483af4

Browse files
authored
Merge pull request #296 from benaclejames/featt/module-md5-check
feat(module_installer): Utilize MD5 hash during module install flow
2 parents 2ab5749 + 5eb50f8 commit 6483af4

File tree

2 files changed

+29
-3
lines changed

2 files changed

+29
-3
lines changed

VRCFaceTracking.Core/Models/TrackingModuleMetadata.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,9 @@ public string DllFileName
7070
{
7171
get; set;
7272
} = "(No DLL provided)";
73+
74+
public string FileHash
75+
{
76+
get; set;
77+
}
7378
}

VRCFaceTracking.Core/Services/ModuleInstaller.cs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System.IO.Compression;
22
using System.Runtime.Versioning;
3+
using System.Security.Cryptography;
34
using Microsoft.Extensions.Logging;
45
using Newtonsoft.Json;
56
using VRCFaceTracking.Core.Helpers;
@@ -52,11 +53,23 @@ private static void MoveDirectory(string source, string dest)
5253
Directory.Delete(source, true);
5354
}
5455

55-
private static async Task DownloadModuleToFile(TrackingModuleMetadata moduleMetadata, string filePath)
56+
private static async Task DownloadModuleToFile(TrackingModuleMetadata moduleMetadata, string filePath, string md5Hash = null)
5657
{
5758
using var client = new HttpClient();
5859
var response = await client.GetAsync(moduleMetadata.DownloadUrl);
5960
var content = await response.Content.ReadAsByteArrayAsync();
61+
if (!string.IsNullOrEmpty(md5Hash))
62+
{
63+
using var md5 = MD5.Create();
64+
var hash = md5.ComputeHash(content);
65+
var hashStr = BitConverter.ToString(hash).Replace("-", string.Empty).ToLowerInvariant();
66+
67+
if (!string.Equals(hashStr, md5Hash.ToLowerInvariant(), StringComparison.OrdinalIgnoreCase))
68+
{
69+
throw new InvalidDataException($"MD5 hash mismatch. Expected {md5Hash}, got {hashStr}");
70+
}
71+
}
72+
6073
await File.WriteAllBytesAsync(filePath, content);
6174
await Task.CompletedTask;
6275
}
@@ -214,7 +227,7 @@ public async Task<string> InstallRemoteModule(TrackingModuleMetadata moduleMetad
214227
try
215228
{
216229
tempZipPath = Path.Combine(tempDirectory, "module.zip");
217-
await DownloadModuleToFile(moduleMetadata, tempZipPath);
230+
await DownloadModuleToFile(moduleMetadata, tempZipPath, moduleMetadata.FileHash);
218231
}
219232
catch (Exception e)
220233
{
@@ -280,7 +293,15 @@ public async Task<string> InstallRemoteModule(TrackingModuleMetadata moduleMetad
280293
}
281294
Directory.CreateDirectory(moduleDirectory);
282295

283-
await DownloadModuleToFile(moduleMetadata, dllPath);
296+
try
297+
{
298+
await DownloadModuleToFile(moduleMetadata, dllPath, moduleMetadata.FileHash);
299+
}
300+
catch (Exception e)
301+
{
302+
_logger.LogError($"Failed to download module data for {moduleMetadata.ModuleName}. {e}");
303+
return null;
304+
}
284305

285306
_logger.LogDebug("Downloaded module {module} to {dllPath}", moduleMetadata.ModuleId, dllPath);
286307
}

0 commit comments

Comments
 (0)