示例#1
0
        public static MetadataNode Load(BlobStore blobs, byte[] hash, MetadataNode?parent = null)
        {
            var curmn = new MetadataNode();

            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(blobs.RetrieveData(hash));
            FileMetadata dirmetadata = FileMetadata.deserialize(savedobjects["DirMetadata-v1"]);

            curmn.DirMetadata = dirmetadata;
            ConcurrentDictionary <string, FileMetadata> files = new ConcurrentDictionary <string, FileMetadata>();
            var encodedFiles = BinaryEncoding.enum_decode(savedobjects["Files-v1"]) ?? new List <byte[]?>();

            foreach (var binfm in encodedFiles)
            {
                if (binfm == null)
                {
                    throw new NullReferenceException("Encoded file metadatas cannot be null");
                }
                FileMetadata newfm = FileMetadata.deserialize(binfm);
                files[newfm.FileName] = newfm;
            }
            curmn.Files = files;
            ConcurrentDictionary <string, MetadataNode> directories = new ConcurrentDictionary <string, MetadataNode>();
            var dirs = BinaryEncoding.enum_decode(savedobjects["Directories-v2"]) ?? new List <byte[]?>();

            for (int i = 0; i < dirs.Count; i++)
            {
                var          dir   = dirs[i] ?? throw new NullReferenceException("Encoded directory cannot be null");
                MetadataNode newmn = Load(blobs, dir, curmn);
                directories[newmn.DirMetadata.FileName] = newmn;
            }
            curmn.Parent      = parent;
            curmn.Directories = directories;
            return(curmn);
        }
示例#2
0
        /// <summary>
        /// Gets the reference (hash) for all immediate data of the metadatanode without loading
        /// the node into memory. Useful to keep memory usage low.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static IEnumerable <byte[]> GetAllReferencesWithoutLoad(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);
            var directories = BinaryEncoding.enum_decode(savedobjects["Directories-v2"]) ?? new List <byte[]?>();

            foreach (var reference in directories)
            {
                if (reference == null)
                {
                    throw new NullReferenceException("Directory references cannot be null");
                }
                yield return(reference);
            }
            var files = BinaryEncoding.enum_decode(savedobjects["Files-v1"]) ?? new List <byte[]?>();

            foreach (byte[]? filedata in files)
            {
                if (filedata == null)
                {
                    throw new NullReferenceException("Encoded file data cannot be null");
                }
                FileMetadata fm = FileMetadata.deserialize(filedata);
                if (fm.FileHash == null)
                {
                    throw new NullReferenceException("Stored file hashes cannot be null");
                }
                yield return(fm.FileHash);
            }
        }
示例#3
0
        public static MetadataNode Load(BlobStore blobs, byte[] hash, MetadataNode parent = null)
        {
            var curmn = new MetadataNode();

            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(blobs.RetrieveData(hash));
            FileMetadata dirmetadata = FileMetadata.deserialize(savedobjects["DirMetadata-v1"]);

            curmn.DirMetadata = dirmetadata;
            ConcurrentDictionary <string, FileMetadata> files = new ConcurrentDictionary <string, FileMetadata>();

            foreach (var binfm in BinaryEncoding.enum_decode(savedobjects["Files-v1"]))
            {
                FileMetadata newfm = FileMetadata.deserialize(binfm);
                files[newfm.FileName] = newfm;
            }
            curmn.Files = files;
            ConcurrentDictionary <string, MetadataNode> directories = new ConcurrentDictionary <string, MetadataNode>();
            var dirs = BinaryEncoding.enum_decode(savedobjects["Directories-v2"]);

            for (int i = 0; i < dirs.Count; i++)
            {
                MetadataNode newmn = Load(blobs, dirs[i], curmn);
                directories[newmn.DirMetadata.FileName] = newmn;
            }
            curmn.Parent      = parent;
            curmn.Directories = directories;
            return(curmn);
        }
示例#4
0
        public static BlobLocation deserialize(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);

            byte[] encryptedHash = savedobjects["EncryptedHash-v9"].Length == 0 ? null : savedobjects["EncryptedHash-v9"];
            string relfilepath   = Encoding.UTF8.GetString(savedobjects["RelativeFilePath-v1"]);
            int    bytelength    = BitConverter.ToInt32(savedobjects["ByteLength-v1"], 0);

            var backupsets                = BinaryEncoding.enum_decode(savedobjects["BSetReferenceCounts.BackupSets-v5"]).Select(bin => Encoding.UTF8.GetString(bin)).ToList();
            var referencecounts           = BinaryEncoding.enum_decode(savedobjects["BSetReferenceCounts.ReferenceCounts-v5"]).Select(bin => BitConverter.ToInt32(bin, 0)).ToList();
            Dictionary <string, int> bsrc = new Dictionary <string, int>();

            for (int i = 0; i < backupsets.Count; i++)
            {
                bsrc[backupsets[i]] = referencecounts[i];
            }
            var           multiblock  = BitConverter.ToBoolean(savedobjects["IsMultiBlockReference-v7"], 0);
            List <byte[]> childhashes = null;

            if (multiblock)
            {
                childhashes = BinaryEncoding.enum_decode(savedobjects["BlockHashes-v8"]).ToList();
            }
            return(new BlobLocation(encryptedHash, relfilepath, bytelength, childhashes, bsrc));
        }
示例#5
0
        /// <summary>
        /// Create an AES helper based on a previously saved keyfile and a password to decrypt it
        /// </summary>
        /// <param name="file"></param>
        /// <param name="password"></param>
        public static AesHelper CreateFromKeyFile(byte[] file, string password)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(file);

            return(CreateFromKeyFile(savedobjects["passwordsalt-v1"], savedobjects["datakeykeyhashsalt-v1"],
                                     savedobjects["datakeyiv-v1"], savedobjects["datakeykeyhash-v1"], savedobjects["encrypteddatakey-v1"], password));
        }
示例#6
0
        public static BackupRecord deserialize(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);
            DateTime backuptime = new DateTime(BitConverter.ToInt64(savedobjects["BackupTime-v1"], 0));
            string   backupmessage;

            if (savedobjects["BackupMessage-v1"] != null)
            {
                backupmessage = Encoding.UTF8.GetString(savedobjects["BackupMessage-v1"]);
            }
            else
            {
                backupmessage = null;
            }

            byte[] metadatatreehash = savedobjects["MetadataTreeHash-v2"];

            byte[] uuid;
            if (savedobjects.ContainsKey("UUID-v3"))
            {
                uuid = savedobjects["UUID-v3"];
            }
            else
            {
                uuid = new byte[16];
                UUIDGenerator.NextBytes(uuid);
            }

            return(new BackupRecord(backuptime, backupmessage, metadatatreehash, uuid));
        }
示例#7
0
        public static FileMetadata deserialize(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);
            string filename        = Encoding.UTF8.GetString(savedobjects["FileName-v1"]);
            long   numdateaccessed = BitConverter.ToInt64(savedobjects["DateAccessedUTC-v1"], 0);
            long   numdatemodified = BitConverter.ToInt64(savedobjects["DateModifiedUTC-v1"], 0);
            long   numdatecreated  = BitConverter.ToInt64(savedobjects["DateCreatedUTC-v1"], 0);
            long   filesize        = BitConverter.ToInt64(savedobjects["FileSize-v1"], 0);

            FileAttributes attributes = 0;

            if (savedobjects.ContainsKey("Attributes-v2"))
            {
                attributes = (FileAttributes)BitConverter.ToInt32(savedobjects["Attributes-v2"], 0);
            }

            byte[]? filehash = savedobjects["FileHash-v3"];
            if (filehash.Length == 0)
            {
                filehash = null;
            }

            return(new FileMetadata(filename,
                                    new DateTime(numdateaccessed),
                                    new DateTime(numdatemodified),
                                    new DateTime(numdatecreated),
                                    attributes,
                                    filesize,
                                    filehash));
        }
示例#8
0
        public static IEnumerable <byte[]> GetImmediateFileReferencesWithoutLoad(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);

            foreach (var filemdata in BinaryEncoding.enum_decode(savedobjects["Files-v1"]))
            {
                FileMetadata fm = FileMetadata.deserialize(filemdata);
                yield return(fm.FileHash);
            }
        }
示例#9
0
        public static IEnumerable <byte[]> GetImmediateChildNodeReferencesWithoutLoad(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);
            var dirs = BinaryEncoding.enum_decode(savedobjects["Directories-v2"]);

            for (int i = 0; i < dirs.Count; i++)
            {
                yield return(dirs[i]);
            }
        }
示例#10
0
            public static BackupSetKey decode(byte[] data)
            {
                Dictionary <string, byte[]> bsrData = BinaryEncoding.dict_decode(data);

                string bset          = Encoding.UTF8.GetString(bsrData["BackupSet-v1"]);
                bool   shallow       = BitConverter.ToBoolean(bsrData["Shallow-v1"]);
                bool   blobListCache = BitConverter.ToBoolean(bsrData["BlobListCache-v1"]);

                return(new BackupSetKey(bset, shallow, blobListCache));
            }
示例#11
0
        public static IEnumerable <byte[]> GetImmediateChildNodeReferencesWithoutLoad(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);
            var dirs = BinaryEncoding.enum_decode(savedobjects["Directories-v2"]) ?? new List <byte[]?>();

            for (int i = 0; i < dirs.Count; i++)
            {
                var dir = dirs[i] ?? throw new NullReferenceException("Directory reference cannot be null");
                yield return(dir);
            }
        }
示例#12
0
        /// <summary>
        /// Gets the reference (hash) for all immediate data of the metadatanode without loading
        /// the node into memory. Useful to keep memory usage low.
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public static IEnumerable <byte[]> GetAllReferencesWithoutLoad(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);

            foreach (var reference in BinaryEncoding.enum_decode(savedobjects["Directories-v2"]))
            {
                yield return(reference);
            }
            foreach (byte[] filedata in BinaryEncoding.enum_decode(savedobjects["Files-v1"]))
            {
                FileMetadata fm = FileMetadata.deserialize(filedata);
                yield return(fm.FileHash);
            }
        }
示例#13
0
        public static IEnumerable <byte[]> GetImmediateFileReferencesWithoutLoad(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);
            var encodedFiles = BinaryEncoding.enum_decode(savedobjects["Files-v1"]) ?? new List <byte[]?>();

            foreach (var filemdata in encodedFiles)
            {
                if (filemdata == null)
                {
                    throw new Exception("File metadata objects cannot be null here");
                }
                FileMetadata fm = FileMetadata.deserialize(filemdata);
                if (fm.FileHash == null)
                {
                    throw new NullReferenceException("Stored files must have file hashes");
                }
                yield return(fm.FileHash);
            }
        }
示例#14
0
        /// <summary>
        /// Create an AES helper based on a previously saved keyfile and a password to decrypt it
        /// </summary>
        /// <param name="file"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        public static AesHelper CreateFromKeyFile(byte[] file, string password)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(file);
            var phasher     = new Rfc2898DeriveBytes(password, savedobjects["passwordsalt-v1"]);
            var datakeykey  = phasher.GetBytes(16);
            var phashhasher = new Rfc2898DeriveBytes(datakeykey, savedobjects["datakeykeyhashsalt-v1"], 8192);
            var phashhash   = phashhasher.GetBytes(IVSize);

            if (phashhash.SequenceEqual(savedobjects["datakeykeyhash-v1"]))
            {
                return(new AesHelper(datakeykey, savedobjects["passwordsalt-v1"], savedobjects["datakeykeyhash-v1"],
                                     savedobjects["datakeykeyhashsalt-v1"],
                                     DecryptAesDataKey(savedobjects["encrypteddatakey-v1"], datakeykey, savedobjects["datakeyiv-v1"]),
                                     savedobjects["datakeyiv-v1"]));
            }
            else
            {
                throw new PasswordIncorrectException("The password used to decrypt the keyfile " +
                                                     "does not match the file used to creat it.");
            }
        }
示例#15
0
        public static BlobLocation deserialize(byte[] data)
        {
            Dictionary <string, byte[]> savedobjects = BinaryEncoding.dict_decode(data);

            byte[]? encryptedHash = savedobjects["EncryptedHash-v9"].Length == 0 ? null : savedobjects["EncryptedHash-v9"];
            string relfilepath = Encoding.UTF8.GetString(savedobjects["RelativeFilePath-v1"]);
            int    bytelength  = BitConverter.ToInt32(savedobjects["ByteLength-v1"], 0);

            var encodedBackupSets = BinaryEncoding.enum_decode(savedobjects["BSetReferenceCounts.BackupSets-v5"]);

            if (encodedBackupSets == null)
            {
                throw new Exception("Backup sets are required");
            }
            List <BackupSetKey> backupsets = new List <BackupSetKey>();

            foreach (var bin in encodedBackupSets)
            {
                if (bin == null)
                {
                    throw new Exception("Backup sets cannot be null");
                }
                backupsets.Add(BackupSetKey.decode(bin));
            }

            List <byte[]?>?encodedRefCounts = BinaryEncoding.enum_decode(savedobjects["BSetReferenceCounts.ReferenceCounts-v5"]);

            if (encodedRefCounts == null)
            {
                throw new Exception("Reference counts are required");
            }
            List <int> referencecounts = new List <int>();

            foreach (var bin in encodedRefCounts)
            {
                if (bin == null)
                {
                    throw new Exception("Reference counts cannot be null");
                }
                referencecounts.Add(BitConverter.ToInt32(bin, 0));
            }
            Dictionary <BackupSetKey, int> bsrc = new Dictionary <BackupSetKey, int>();

            for (int i = 0; i < backupsets.Count; i++)
            {
                bsrc[backupsets[i]] = referencecounts[i];
            }
            var           multiblock  = BitConverter.ToBoolean(savedobjects["IsMultiBlockReference-v7"], 0);
            List <byte[]>?childhashes = null;

            if (multiblock)
            {
                childhashes = new List <byte[]>();
                var binchildhashes = BinaryEncoding.enum_decode(savedobjects["BlockHashes-v8"]);
                if (binchildhashes == null)
                {
                    throw new Exception("Multiblock blobs must have child hashes");
                }
                foreach (var bin in binchildhashes)
                {
                    if (bin == null)
                    {
                        throw new Exception("Child hashes cannot be null");
                    }
                    childhashes.Add(bin);
                }
            }

            return(new BlobLocation(encryptedHash, relfilepath, bytelength, childhashes, bsrc));
        }