/// <summary> /// Releases the resources associated with the archive /// </summary> public void Dispose() { if (this.archive != null) this.archive.Dispose(); this.archive = null; }
/// <summary> /// Initializes a new archive instance /// </summary> /// <param name="archive"> /// The archive implementation to attach /// </param> internal Archive(Store.IArchive archive) { this.archive = archive; }
/// <summary> /// Creates and connects to a new backup archive /// </summary> /// <param name="name"> /// The name of the archive to create /// </param> /// <param name="password"> /// The security password for the archive /// </param> public void CreateArchive(String name, String password) { // validate parameters if (this.Connection == null) throw new InvalidOperationException(Strings.ConnectionNotConnected); if (this.archive != null) throw new InvalidOperationException(Strings.ConnectionAlreadyConnected); var store = this.Connection.Store; try { // verify that the archive does not already exist at the store if (store.ListArchives().Contains(name, StringComparer.OrdinalIgnoreCase)) throw new InvalidOperationException( String.Format(Strings.EngineArchiveExists, name) ); // create the archive header and encryption parameters var random = RandomNumberGenerator.Create(); var header = new Backup.Header() { CryptoIterations = DefaultCryptoIterations, ArchiveSalt = new Byte[DefaultCryptoSaltLength], PasswordSalt = new Byte[DefaultCryptoSaltLength] }; random.GetBytes(header.ArchiveSalt); random.GetBytes(header.PasswordSalt); using (var hash = CreateHasher(password, header)) header.PasswordHash = hash.GetBytes(DefaultCryptoHashLength); // attach the encryption algorithm and // delegate to the store implementation to create the archive this.crypto = CreateCrypto(password, header); this.archive = store.CreateArchive(name, header); } catch { CloseArchive(); throw; } }
/// <summary> /// Connects to an existing backup archive /// </summary> /// <param name="name"> /// The name of the archive to open /// </param> /// <param name="password"> /// The security password of the archive /// </param> public void OpenArchive(String name, String password) { // validate parameters if (this.Connection == null) throw new InvalidOperationException(Strings.ConnectionNotConnected); if (this.archive != null) throw new InvalidOperationException(Strings.ConnectionAlreadyConnected); var store = this.Connection.Store; try { // verify that the archive exists at the store and // open the archive implementation if (!store.ListArchives().Contains(name, StringComparer.OrdinalIgnoreCase)) throw new InvalidOperationException( String.Format(Strings.EngineArchiveNotFound, name) ); this.archive = store.OpenArchive(name); // authenticate the request and attach the encryption algorithm var header = this.archive.BackupIndex.FetchHeader(); using (var hash = CreateHasher(password, header)) if (!hash.GetBytes(header.PasswordHash.Length).SequenceEqual(header.PasswordHash)) throw new UnauthorizedAccessException(Strings.EngineAuthenticationFailed); this.crypto = CreateCrypto(password, header); } catch { CloseArchive(); throw; } }
/// <summary> /// Disconnects from the attached archive /// </summary> public void CloseArchive() { if (this.archive != null) this.archive.Dispose(); if (this.crypto != null) ((IDisposable)this.crypto).Dispose(); // Mono bug 701586 requires cast this.archive = null; this.crypto = null; }