public static void CreateUpdatePackage(System.Security.Cryptography.RSACryptoServiceProvider key, string inputfolder, string outputfolder, string manifest = null) { // Read the existing manifest UpdateInfo remoteManifest; var manifestpath = manifest ?? System.IO.Path.Combine(inputfolder, UPDATE_MANIFEST_FILENAME); using (var s = System.IO.File.OpenRead(manifestpath)) using (var sr = new System.IO.StreamReader(s)) using (var jr = new Newtonsoft.Json.JsonTextReader(sr)) remoteManifest = new Newtonsoft.Json.JsonSerializer().Deserialize <UpdateInfo>(jr); if (remoteManifest.Files == null) { remoteManifest.Files = new FileEntry[0]; } if (remoteManifest.ReleaseTime.Ticks == 0) { remoteManifest.ReleaseTime = DateTime.UtcNow; } var ignoreFiles = (from n in remoteManifest.Files where n.Ignore select n).ToArray(); var ignoreMap = ignoreFiles.ToDictionary(k => k.Path, k => "", Duplicati.Library.Utility.Utility.ClientFilenameStringComparer); remoteManifest.MD5 = null; remoteManifest.SHA256 = null; remoteManifest.Files = null; remoteManifest.UncompressedSize = 0; var localManifest = remoteManifest.Clone(); localManifest.RemoteURLS = null; inputfolder = Duplicati.Library.Utility.Utility.AppendDirSeparator(inputfolder); var baselen = inputfolder.Length; var dirsep = System.IO.Path.DirectorySeparatorChar.ToString(); ignoreMap.Add(UPDATE_MANIFEST_FILENAME, ""); var md5 = System.Security.Cryptography.MD5.Create(); var sha256 = System.Security.Cryptography.SHA256.Create(); Func <string, string> computeMD5 = (path) => { md5.Initialize(); using (var fs = System.IO.File.OpenRead(path)) return(Convert.ToBase64String(md5.ComputeHash(fs))); }; Func <string, string> computeSHA256 = (path) => { sha256.Initialize(); using (var fs = System.IO.File.OpenRead(path)) return(Convert.ToBase64String(sha256.ComputeHash(fs))); }; // Build a zip using (var archive_temp = new Duplicati.Library.Utility.TempFile()) { using (var zipfile = new Duplicati.Library.Compression.FileArchiveZip(archive_temp, new Dictionary <string, string>())) { Func <string, string, bool> addToArchive = (path, relpath) => { if (ignoreMap.ContainsKey(relpath)) { return(false); } if (path.EndsWith(dirsep)) { return(true); } using (var source = System.IO.File.OpenRead(path)) using (var target = zipfile.CreateFile(relpath, Duplicati.Library.Interface.CompressionHint.Compressible, System.IO.File.GetLastAccessTimeUtc(path))) { source.CopyTo(target); remoteManifest.UncompressedSize += source.Length; } return(true); }; // Build the update manifest localManifest.Files = (from fse in Duplicati.Library.Utility.Utility.EnumerateFileSystemEntries(inputfolder) let relpath = fse.Substring(baselen) where addToArchive(fse, relpath) select new FileEntry() { Path = relpath, LastWriteTime = System.IO.File.GetLastAccessTimeUtc(fse), MD5 = fse.EndsWith(dirsep) ? null : computeMD5(fse), SHA256 = fse.EndsWith(dirsep) ? null : computeSHA256(fse) }) .Union(ignoreFiles).ToArray(); // Write a signed manifest with the files using (var ms = new System.IO.MemoryStream()) using (var sw = new System.IO.StreamWriter(ms)) { new Newtonsoft.Json.JsonSerializer().Serialize(sw, localManifest); sw.Flush(); using (var ms2 = new System.IO.MemoryStream()) { SignatureReadingStream.CreateSignedStream(ms, ms2, key); ms2.Position = 0; using (var sigfile = zipfile.CreateFile(UPDATE_MANIFEST_FILENAME, Duplicati.Library.Interface.CompressionHint.Compressible, DateTime.UtcNow)) ms2.CopyTo(sigfile); } } } remoteManifest.CompressedSize = new System.IO.FileInfo(archive_temp).Length; remoteManifest.MD5 = computeMD5(archive_temp); remoteManifest.SHA256 = computeSHA256(archive_temp); System.IO.File.Move(archive_temp, System.IO.Path.Combine(outputfolder, "package.zip")); } // Write a signed manifest for upload using (var tf = new Duplicati.Library.Utility.TempFile()) { using (var ms = new System.IO.MemoryStream()) using (var sw = new System.IO.StreamWriter(ms)) { new Newtonsoft.Json.JsonSerializer().Serialize(sw, remoteManifest); sw.Flush(); using (var fs = System.IO.File.Create(tf)) SignatureReadingStream.CreateSignedStream(ms, fs, key); } System.IO.File.Move(tf, System.IO.Path.Combine(outputfolder, UPDATE_MANIFEST_FILENAME)); } }
public static void CreateUpdatePackage(System.Security.Cryptography.RSACryptoServiceProvider key, string inputfolder, string outputfolder, string manifest = null) { // Read the existing manifest UpdateInfo remoteManifest; var manifestpath = manifest ?? System.IO.Path.Combine(inputfolder, UPDATE_MANIFEST_FILENAME); using(var s = System.IO.File.OpenRead(manifestpath)) using(var sr = new System.IO.StreamReader(s)) using(var jr = new Newtonsoft.Json.JsonTextReader(sr)) remoteManifest = new Newtonsoft.Json.JsonSerializer().Deserialize<UpdateInfo>(jr); if (remoteManifest.Files == null) remoteManifest.Files = new FileEntry[0]; if (remoteManifest.ReleaseTime.Ticks == 0) remoteManifest.ReleaseTime = DateTime.UtcNow; var ignoreFiles = (from n in remoteManifest.Files where n.Ignore select n).ToArray(); var ignoreMap = ignoreFiles.ToDictionary(k => k.Path, k => "", Duplicati.Library.Utility.Utility.ClientFilenameStringComparer); remoteManifest.MD5 = null; remoteManifest.SHA256 = null; remoteManifest.Files = null; remoteManifest.UncompressedSize = 0; var localManifest = remoteManifest.Clone(); localManifest.RemoteURLS = null; inputfolder = Duplicati.Library.Utility.Utility.AppendDirSeparator(inputfolder); var baselen = inputfolder.Length; var dirsep = System.IO.Path.DirectorySeparatorChar.ToString(); ignoreMap.Add(UPDATE_MANIFEST_FILENAME, ""); var md5 = System.Security.Cryptography.MD5.Create(); var sha256 = System.Security.Cryptography.SHA256.Create(); Func<string, string> computeMD5 = (path) => { md5.Initialize(); using(var fs = System.IO.File.OpenRead(path)) return Convert.ToBase64String(md5.ComputeHash(fs)); }; Func<string, string> computeSHA256 = (path) => { sha256.Initialize(); using(var fs = System.IO.File.OpenRead(path)) return Convert.ToBase64String(sha256.ComputeHash(fs)); }; // Build a zip using (var archive_temp = new Duplicati.Library.Utility.TempFile()) { using (var zipfile = new Duplicati.Library.Compression.FileArchiveZip(archive_temp, new Dictionary<string, string>())) { Func<string, string, bool> addToArchive = (path, relpath) => { if (ignoreMap.ContainsKey(relpath)) return false; if (path.EndsWith(dirsep)) return true; using (var source = System.IO.File.OpenRead(path)) using (var target = zipfile.CreateFile(relpath, Duplicati.Library.Interface.CompressionHint.Compressible, System.IO.File.GetLastAccessTimeUtc(path))) { source.CopyTo(target); remoteManifest.UncompressedSize += source.Length; } return true; }; // Build the update manifest localManifest.Files = (from fse in Duplicati.Library.Utility.Utility.EnumerateFileSystemEntries(inputfolder) let relpath = fse.Substring(baselen) where addToArchive(fse, relpath) select new FileEntry() { Path = relpath, LastWriteTime = System.IO.File.GetLastAccessTimeUtc(fse), MD5 = fse.EndsWith(dirsep) ? null : computeMD5(fse), SHA256 = fse.EndsWith(dirsep) ? null : computeSHA256(fse) }) .Union(ignoreFiles).ToArray(); // Write a signed manifest with the files using (var ms = new System.IO.MemoryStream()) using (var sw = new System.IO.StreamWriter(ms)) { new Newtonsoft.Json.JsonSerializer().Serialize(sw, localManifest); sw.Flush(); using (var ms2 = new System.IO.MemoryStream()) { SignatureReadingStream.CreateSignedStream(ms, ms2, key); ms2.Position = 0; using (var sigfile = zipfile.CreateFile(UPDATE_MANIFEST_FILENAME, Duplicati.Library.Interface.CompressionHint.Compressible, DateTime.UtcNow)) ms2.CopyTo(sigfile); } } } remoteManifest.CompressedSize = new System.IO.FileInfo(archive_temp).Length; remoteManifest.MD5 = computeMD5(archive_temp); remoteManifest.SHA256 = computeSHA256(archive_temp); System.IO.File.Move(archive_temp, System.IO.Path.Combine(outputfolder, "package.zip")); } // Write a signed manifest for upload using(var tf = new Duplicati.Library.Utility.TempFile()) { using (var ms = new System.IO.MemoryStream()) using (var sw = new System.IO.StreamWriter(ms)) { new Newtonsoft.Json.JsonSerializer().Serialize(sw, remoteManifest); sw.Flush(); using (var fs = System.IO.File.Create(tf)) SignatureReadingStream.CreateSignedStream(ms, fs, key); } System.IO.File.Move(tf, System.IO.Path.Combine(outputfolder, UPDATE_MANIFEST_FILENAME)); } }