summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsr55 <[email protected]>2016-03-12 16:19:53 +0000
committersr55 <[email protected]>2016-03-12 16:20:22 +0000
commit39613ae76e39b5a8ddaae50aa5d5665796acc726 (patch)
tree5f07ea0e79de1929e2e73037ee9f23fa9d634d91
parent1a972f68a412ae06b000930a189bb06bcb5ba6e6 (diff)
WinGui: Add SHA1 Verification of the update downloads and don't start the installer if the hash check fails.
-rw-r--r--win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs5
-rw-r--r--win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs5
-rw-r--r--win/CS/HandBrakeWPF/Services/UpdateService.cs40
-rw-r--r--win/CS/HandBrakeWPF/Utilities/AppcastReader.cs6
-rw-r--r--win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs11
5 files changed, 56 insertions, 11 deletions
diff --git a/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs b/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs
index bc49a2ee3..61c2bd36e 100644
--- a/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs
+++ b/win/CS/HandBrakeWPF/Model/UpdateCheckInformation.cs
@@ -53,5 +53,10 @@ namespace HandBrakeWPF.Model
/// Gets or sets the error that occurred, if any. This will be null if no error occured.
/// </summary>
public Exception Error { get; set; }
+
+ /// <summary>
+ /// Gets or sets the expected sh a 1 hash.
+ /// </summary>
+ public string ExpectedSHA1Hash { get; set; }
}
}
diff --git a/win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs b/win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs
index cd1b50e9f..571d5c931 100644
--- a/win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs
+++ b/win/CS/HandBrakeWPF/Services/Interfaces/IUpdateService.cs
@@ -40,12 +40,15 @@ namespace HandBrakeWPF.Services.Interfaces
/// <param name="url">
/// The url.
/// </param>
+ /// <param name="expectedSHA1Hash">
+ /// The expected SHA-1 Hash.
+ /// </param>
/// <param name="completed">
/// The complete.
/// </param>
/// <param name="progress">
/// The progress.
/// </param>
- void DownloadFile(string url, Action<DownloadStatus> completed, Action<DownloadStatus> progress);
+ void DownloadFile(string url, string expectedSHA1Hash, Action<DownloadStatus> completed, Action<DownloadStatus> progress);
}
}
diff --git a/win/CS/HandBrakeWPF/Services/UpdateService.cs b/win/CS/HandBrakeWPF/Services/UpdateService.cs
index f49836b6a..732193ac4 100644
--- a/win/CS/HandBrakeWPF/Services/UpdateService.cs
+++ b/win/CS/HandBrakeWPF/Services/UpdateService.cs
@@ -12,6 +12,8 @@ namespace HandBrakeWPF.Services
using System;
using System.IO;
using System.Net;
+ using System.Security.Cryptography;
+ using System.Text;
using System.Threading;
using HandBrake.ApplicationServices.Utilities;
@@ -125,6 +127,7 @@ namespace HandBrakeWPF.Services
DownloadFile = reader.DownloadFile,
Build = reader.Build,
Version = reader.Version,
+ ExpectedSHA1Hash = reader.Hash
};
callback(info2);
@@ -142,13 +145,16 @@ namespace HandBrakeWPF.Services
/// <param name="url">
/// The url.
/// </param>
+ /// <param name="expectedSha1Hash">
+ /// The expected Sha 1 Hash.
+ /// </param>
/// <param name="completed">
/// The complete.
/// </param>
/// <param name="progress">
/// The progress.
/// </param>
- public void DownloadFile(string url, Action<DownloadStatus> completed, Action<DownloadStatus> progress)
+ public void DownloadFile(string url, string expectedSha1Hash, Action<DownloadStatus> completed, Action<DownloadStatus> progress)
{
ThreadPool.QueueUserWorkItem(
delegate
@@ -172,11 +178,9 @@ namespace HandBrakeWPF.Services
int bytesSize;
byte[] downBuffer = new byte[2048];
- long flength = 0;
while ((bytesSize = responceStream.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
localStream.Write(downBuffer, 0, bytesSize);
- flength = localStream.Length;
progress(new DownloadStatus { BytesRead = localStream.Length, TotalBytes = fileSize});
}
@@ -184,21 +188,45 @@ namespace HandBrakeWPF.Services
localStream.Close();
completed(
- flength != fileSize
+ GetSHA1(tempPath) != expectedSha1Hash
? new DownloadStatus
{
WasSuccessful = false,
- Message = "Partial Download. File is Incomplete. Please Retry the download."
+ Message = "Download Failed. SHA1 Checksum Failed. Please visit the website to download this update."
}
: new DownloadStatus { WasSuccessful = true, Message = "Download Complete." });
}
catch (Exception exc)
{
- progress(new DownloadStatus { WasSuccessful = false, Exception = exc, Message = "Download Failed." });
+ progress(new DownloadStatus { WasSuccessful = false, Exception = exc, Message = "Download Failed. Please visit the website to download this update." });
}
});
}
+ /// <summary>
+ /// The get sh a 1.
+ /// </summary>
+ /// <param name="fileName">
+ /// The file name.
+ /// </param>
+ /// <returns>
+ /// The <see cref="string"/>.
+ /// </returns>
+ public static String GetSHA1(String fileName)
+ {
+ FileStream file = new FileStream(fileName, FileMode.Open);
+ SHA1 sha1 = new SHA1CryptoServiceProvider();
+ byte[] retVal = sha1.ComputeHash(file);
+ file.Close();
+
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < retVal.Length; i++)
+ {
+ sb.Append(retVal[i].ToString("x2"));
+ }
+ return sb.ToString();
+ }
+
#endregion
}
} \ No newline at end of file
diff --git a/win/CS/HandBrakeWPF/Utilities/AppcastReader.cs b/win/CS/HandBrakeWPF/Utilities/AppcastReader.cs
index 49d7f4714..b534ee8c6 100644
--- a/win/CS/HandBrakeWPF/Utilities/AppcastReader.cs
+++ b/win/CS/HandBrakeWPF/Utilities/AppcastReader.cs
@@ -40,6 +40,11 @@ namespace HandBrakeWPF.Utilities
public string DownloadFile { get; private set; }
/// <summary>
+ /// Gets the hash for verifying the download completed correctly.
+ /// </summary>
+ public string Hash { get; private set; }
+
+ /// <summary>
/// Get the build information from the required appcasts. Run before accessing the public vars.
/// </summary>
/// <param name="input">
@@ -61,6 +66,7 @@ namespace HandBrakeWPF.Utilities
this.Version = verShort.ToString().Replace("sparkle:shortVersionString=", string.Empty).Replace(
"\"", string.Empty);
this.DownloadFile = nodeItem["windows"].InnerText;
+ this.Hash = nodeItem["windowsHash"].InnerText;
this.DescriptionUrl = new Uri(nodeItem["sparkle:releaseNotesLink"].InnerText);
}
catch (Exception)
diff --git a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs
index 3176070d0..69df5a635 100644
--- a/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs
+++ b/win/CS/HandBrakeWPF/ViewModels/OptionsViewModel.cs
@@ -1124,7 +1124,7 @@ namespace HandBrakeWPF.ViewModels
public void DownloadUpdate()
{
this.UpdateMessage = "Preparing for Update ...";
- this.updateService.DownloadFile(this.updateInfo.DownloadFile, this.DownloadComplete, this.DownloadProgress);
+ this.updateService.DownloadFile(this.updateInfo.DownloadFile, this.updateInfo.ExpectedSHA1Hash, this.DownloadComplete, this.DownloadProgress);
}
/// <summary>
@@ -1412,10 +1412,13 @@ namespace HandBrakeWPF.ViewModels
private void DownloadComplete(DownloadStatus info)
{
this.UpdateAvailable = false;
- this.UpdateMessage = info.WasSuccessful ? Resources.OptionsViewModel_UpdateDownloaded : Resources.OptionsViewModel_UpdateFailed;
+ this.UpdateMessage = info.WasSuccessful ? Resources.OptionsViewModel_UpdateDownloaded : info.Message;
- Process.Start(Path.Combine(Path.GetTempPath(), "handbrake-setup.exe"));
- Execute.OnUIThread(() => Application.Current.Shutdown());
+ if (info.WasSuccessful)
+ {
+ Process.Start(Path.Combine(Path.GetTempPath(), "handbrake-setup.exe"));
+ Execute.OnUIThread(() => Application.Current.Shutdown());
+ }
}
/// <summary>