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); }
/// <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); } }
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); }
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)); }
/// <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)); }
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)); }
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)); }
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); } }
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]); } }
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)); }
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); } }
/// <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); } }
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); } }
/// <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."); } }
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)); }