diff --git a/src/BizHawk.Client.EmuHawk/AVOut/FFmpegDownloaderForm.cs b/src/BizHawk.Client.EmuHawk/AVOut/FFmpegDownloaderForm.cs index 49291cc6b1..f534f4f711 100644 --- a/src/BizHawk.Client.EmuHawk/AVOut/FFmpegDownloaderForm.cs +++ b/src/BizHawk.Client.EmuHawk/AVOut/FFmpegDownloaderForm.cs @@ -1,6 +1,7 @@ using System.IO; using BizHawk.Common; +using BizHawk.Common.IOExtensions; namespace BizHawk.Client.EmuHawk { @@ -30,5 +31,8 @@ namespace BizHawk.Client.EmuHawk protected override bool PostChmodCheck() => FFmpegService.QueryServiceAvailable(); + + protected override bool PreChmodCheck(FileStream extracted) + => SHA256Checksum.ComputeDigestHex(extracted.ReadAllBytes()) == FFmpegService.DownloadSHA256Checksum; } } diff --git a/src/BizHawk.Client.EmuHawk/DownloaderForm.cs b/src/BizHawk.Client.EmuHawk/DownloaderForm.cs index 83af939a84..e7c4bd7a7c 100644 --- a/src/BizHawk.Client.EmuHawk/DownloaderForm.cs +++ b/src/BizHawk.Client.EmuHawk/DownloaderForm.cs @@ -104,6 +104,8 @@ namespace BizHawk.Client.EmuHawk //last chance. exiting, don't dump the new file if (_exiting) return; exStream.CopyTo(fs); + fs.Position = 0L; + if (!PreChmodCheck(fs)) throw new Exception("download failed (pre-chmod validation)"); fs.Dispose(); if (OSTailoredCode.IsUnixHost) { @@ -113,7 +115,7 @@ namespace BizHawk.Client.EmuHawk } //make sure it worked - if (!PostChmodCheck()) throw new Exception("download failed"); + if (!PostChmodCheck()) throw new Exception("download failed (post-chmod validation)"); _succeeded = true; } @@ -141,6 +143,9 @@ namespace BizHawk.Client.EmuHawk protected virtual bool PostChmodCheck() => true; + protected virtual bool PreChmodCheck(FileStream extracted) + => true; + private void btnDownload_Click(object sender, EventArgs e) { btnDownload.Text = "Downloading..."; diff --git a/src/BizHawk.Client.EmuHawk/RetroAchievements/RAIntegrationDownloaderForm.cs b/src/BizHawk.Client.EmuHawk/RetroAchievements/RAIntegrationDownloaderForm.cs index 0b72ca395a..44a1a4f9a6 100644 --- a/src/BizHawk.Client.EmuHawk/RetroAchievements/RAIntegrationDownloaderForm.cs +++ b/src/BizHawk.Client.EmuHawk/RetroAchievements/RAIntegrationDownloaderForm.cs @@ -2,6 +2,7 @@ using System.IO; using BizHawk.Common; using BizHawk.Common.PathExtensions; +using BizHawk.Common.StringExtensions; namespace BizHawk.Client.EmuHawk { @@ -15,6 +16,11 @@ namespace BizHawk.Client.EmuHawk public RAIntegrationDownloaderForm(string downloadFrom) { + var downloadDomainName = downloadFrom.RemovePrefix("https://").SubstringBefore('/'); + if (!(downloadDomainName is "retroachievements.org" || downloadDomainName.EndsWith(".retroachievements.org"))) + { + throw new ArgumentException(paramName: nameof(downloadFrom), message: "untrusted hostname"); + } Description = string.Empty; DownloadFrom = downloadFrom; DownloadTo = Path.Combine(PathUtils.DataDirectoryPath, "dll", "RA_Integration-x64.dll"); diff --git a/src/BizHawk.Common/FFmpegService.cs b/src/BizHawk.Common/FFmpegService.cs index 8557cc150b..f6e71e7179 100644 --- a/src/BizHawk.Common/FFmpegService.cs +++ b/src/BizHawk.Common/FFmpegService.cs @@ -17,8 +17,15 @@ namespace BizHawk.Common private const string BIN_HOST_URI_WIN_X64 = "https://github.com/TASEmulators/ffmpeg-binaries/raw/master/ffmpeg-4.4.1-static-windows-x64.7z"; + private const string BIN_SHA256_LINUX_X64 = "3EA58083710F63BF920B16C7D5D24AE081E7D731F57A656FED11AF0410D4EB48"; + + private const string BIN_SHA256_WIN_X64 = "8436760AF8F81C95EFF92D854A7684E6D3CEDB872888420359FC45C8EB2664AC"; + private const string VERSION = "ffmpeg version 4.4.1"; + public static string DownloadSHA256Checksum + => OSTailoredCode.IsUnixHost ? BIN_SHA256_LINUX_X64 : BIN_SHA256_WIN_X64; + public static string FFmpegPath => Path.Combine(PathUtils.DataDirectoryPath, "dll", OSTailoredCode.IsUnixHost ? "ffmpeg" : "ffmpeg.exe"); public static readonly string Url = OSTailoredCode.IsUnixHost ? BIN_HOST_URI_LINUX_X64 : BIN_HOST_URI_WIN_X64;