Example #1
0
        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));
            }
        }
Example #2
0
        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));
            }
        }