public async Task TestCheckProcessExitedWhenExited() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, new MemoryStream(Resources.helloworld_key_a_txt)); FakeDataStore.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); await New <KnownIdentities>().SetDefaultEncryptionIdentity(new LogOnIdentity(EmailAddress.Parse("*****@*****.**"), new Passphrase("test"))); FakeLauncher fakeLauncher = new FakeLauncher(); fakeLauncher.Launch(_decryptedFile1); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), new LogOnIdentity("passphrase"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); activeFile = new ActiveFile(activeFile, ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.NotShareable); Resolve.FileSystemState.Add(activeFile, fakeLauncher); ((FakeNow)New <INow>()).TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange; return(Constant.CompletedTask); }); SetupAssembly.FakeRuntimeEnvironment.Platform = Platform.WindowsDesktop; fakeLauncher.HasExited = true; await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(changedWasRaised, Is.True, "A changed event should be raised because the process has exited."); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotDecrypted), Is.True, "The ActiveFile plain text should be deleted after the checking of active files because the launcher is no longer active."); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotShareable), Is.False, "The file should be shareable after checking of active files because the launcher is no longer active."); }
public async Task TestCheckActiveFilesNotDecryptedAndDoesNotExist() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, new MemoryStream(Resources.helloworld_key_a_txt)); FakeDataStore.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); New <IDataStore>(_decryptedFile1).Delete(); activeFile = new ActiveFile(activeFile, ActiveFileStatus.NotDecrypted); Resolve.FileSystemState.Add(activeFile); await Resolve.KnownIdentities.AddAsync(activeFile.Identity); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange; return(Constant.CompletedTask); }); ((FakeNow)New <INow>()).TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); Assert.That(changedWasRaised, Is.False, "The ActiveFile should be not be modified because it's already deleted."); }
public async Task TestPurgeActiveFilesWhenFileIsLocked() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, new MemoryStream(Resources.helloworld_key_a_txt)); FakeDataStore.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); IDataStore encryptedFileInfo = New <IDataStore>(_anAxxPath); IDataStore decryptedFileInfo = New <IDataStore>(_decryptedFile1); ActiveFile activeFile = new ActiveFile(encryptedFileInfo, decryptedFileInfo, new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange; return(Constant.CompletedTask); }); using (FileLock fileLock = New <FileLocker>().Acquire(decryptedFileInfo)) { await Task.Run(() => New <ActiveFileAction>().PurgeActiveFiles(new ProgressContext())); } Assert.That(changedWasRaised, Is.False, "A changed event should not be raised because the decrypted file is locked."); }
internal static void TestOneFile(string resourceName, string password, string sha256HashValue) { string source = Path.Combine(_rootPath, "source.axx"); string destination = Path.Combine(_rootPath, "destination.file"); Stream stream = Assembly.GetAssembly(typeof(TestV2RegressionCompleteFiles)).GetManifestResourceStream("Axantum.AxCrypt.Core.Test.resources." + resourceName); FakeDataStore.AddFile(source, FakeDataStore.TestDate1Utc, FakeDataStore.TestDate2Utc, FakeDataStore.TestDate3Utc, stream); LogOnIdentity passphrase = new LogOnIdentity(password); bool ok = new AxCryptFile().Decrypt(New <IDataStore>(source), New <IDataStore>(destination), passphrase, AxCryptOptions.SetFileTimes, new ProgressContext()); Assert.That(ok, Is.True, "The Decrypt() method should return true for ok."); byte[] hash; HashAlgorithm hashAlgorithm = SHA256.Create(); Stream plainStream = New <IDataStore>(destination).OpenRead(); using (Stream cryptoStream = new CryptoStream(plainStream, hashAlgorithm, CryptoStreamMode.Read)) { plainStream = null; cryptoStream.CopyTo(Stream.Null); } hash = hashAlgorithm.Hash; Assert.That(hash.IsEquivalentTo(sha256HashValue.FromHex()), "Wrong SHA-256."); }
public async Task TestFileWasCreatedWhereAKnownFolderWasExpected() { IDataContainer betterCloudInfo = New <IDataContainer>(@"C:\BetterCloud"); IDataContainer fasterCloudInfo = New <IDataContainer>(@"C:\FasterCloud"); KnownFolder folder1 = new KnownFolder(betterCloudInfo, @"My AxCrypt", KnownFolderKind.GoogleDrive, null); KnownFolder folder2 = new KnownFolder(fasterCloudInfo, @"My AxCrypt", KnownFolderKind.Dropbox, null); FakeDataStore.AddFile(@"C:\BetterCloud\My AxCrypt", Stream.Null); FakeDataStore.AddFolder(folder2.My.FullName); KnownIdentities knownIdentities = new KnownIdentities(Resolve.FileSystemState, Resolve.SessionNotify); KnownFoldersViewModel vm = new KnownFoldersViewModel(Resolve.FileSystemState, Resolve.SessionNotify, knownIdentities); Assert.That(vm.KnownFolders.Count(), Is.EqualTo(0)); vm.KnownFolders = new KnownFolder[] { folder1, folder2 }; Assert.That(vm.KnownFolders.Count(), Is.EqualTo(2)); Assert.That(vm.KnownFolders.First().Enabled, Is.False); Assert.That(vm.KnownFolders.Last().Enabled, Is.False); await knownIdentities.SetDefaultEncryptionIdentity(new LogOnIdentity("aaa")); Assert.That(Resolve.FileSystemState.WatchedFolders.Count(), Is.EqualTo(1)); Assert.That(vm.KnownFolders.Count(), Is.EqualTo(2)); Assert.That(vm.KnownFolders.First().Enabled, Is.False); Assert.That(vm.KnownFolders.Last().Enabled, Is.True); }
public void TestDragAndDropFilesPropertyBindSetsDragAndDropFileTypes() { using (MainViewModel mvm = New <MainViewModel>()) { string encryptedFilePath = @"C:\Folder\File-txt.axx"; mvm.DragAndDropFiles = new string[] { encryptedFilePath, }; Assert.That(mvm.DragAndDropFilesTypes, Is.EqualTo(FileInfoTypes.None)); string decryptedFilePath = @"C:\Folder\File.txt"; mvm.DragAndDropFiles = new string[] { decryptedFilePath, }; Assert.That(mvm.DragAndDropFilesTypes, Is.EqualTo(FileInfoTypes.None)); FakeDataStore.AddFile(encryptedFilePath, null); mvm.DragAndDropFiles = new string[] { encryptedFilePath, decryptedFilePath, }; Assert.That(mvm.DragAndDropFilesTypes, Is.EqualTo(FileInfoTypes.EncryptedFile)); FakeDataStore.AddFile(decryptedFilePath, null); mvm.DragAndDropFiles = new string[] { encryptedFilePath, decryptedFilePath, }; Assert.That(mvm.DragAndDropFilesTypes, Is.EqualTo(FileInfoTypes.EncryptableFile | FileInfoTypes.EncryptedFile)); string folderPath = @"C:\Folder\"; mvm.DragAndDropFiles = new string[] { encryptedFilePath, decryptedFilePath, folderPath }; Assert.That(mvm.DragAndDropFilesTypes, Is.EqualTo(FileInfoTypes.EncryptableFile | FileInfoTypes.EncryptedFile)); FakeDataStore.AddFolder(folderPath); mvm.DragAndDropFiles = new string[] { encryptedFilePath, decryptedFilePath, folderPath }; Assert.That(mvm.DragAndDropFilesTypes, Is.EqualTo(FileInfoTypes.EncryptableFile | FileInfoTypes.EncryptedFile)); } }
public static void Setup() { SetupAssembly.AssemblySetup(); FakeDataStore.AddFile(_davidCopperfieldTxtPath, FakeDataStore.TestDate4Utc, FakeDataStore.TestDate5Utc, FakeDataStore.TestDate6Utc, FakeDataStore.ExpandableMemoryStream(Encoding.GetEncoding(1252).GetBytes(Resources.david_copperfield))); FakeDataStore.AddFile(_uncompressedAxxPath, FakeDataStore.ExpandableMemoryStream(Resources.uncompressable_zip)); FakeDataStore.AddFile(_helloWorldAxxPath, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); }
public void Setup() { SetupAssembly.AssemblySetup(); SetupAssembly.AssemblySetupCrypto(_cryptoImplementation); FakeDataStore.AddFile(_testTextPath, FakeDataStore.TestDate1Utc, FakeDataStore.TestDate2Utc, FakeDataStore.TestDate3Utc, FakeDataStore.ExpandableMemoryStream(Encoding.UTF8.GetBytes("This is a short file"))); FakeDataStore.AddFile(_davidCopperfieldTxtPath, FakeDataStore.TestDate4Utc, FakeDataStore.TestDate5Utc, FakeDataStore.TestDate6Utc, FakeDataStore.ExpandableMemoryStream(Encoding.GetEncoding(1252).GetBytes(Resources.david_copperfield))); FakeDataStore.AddFile(_uncompressedAxxPath, FakeDataStore.ExpandableMemoryStream(Resources.uncompressable_zip)); FakeDataStore.AddFile(_helloWorldAxxPath, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); }
public static void TestExtensions_FileFilter() { FakeDataStore.AddFile(@"c:\test.txt", null); IDataStore fileInfo = New <IDataStore>(@"c:\test.txt"); Assert.That(New <FileFilter>().IsEncryptable(fileInfo), Is.True); New <FileFilter>().AddUnencryptableExtension("txt"); Assert.That(New <FileFilter>().IsEncryptable(fileInfo), Is.False); }
public void Setup() { SetupAssembly.AssemblySetup(); SetupAssembly.AssemblySetupCrypto(_cryptoImplementation); FakeDataStore.AddFile(_davidCopperfieldTxtPath, FakeDataStore.TestDate4Utc, FakeDataStore.TestDate5Utc, FakeDataStore.TestDate6Utc, FakeDataStore.ExpandableMemoryStream(Encoding.GetEncoding(1252).GetBytes(Resources.david_copperfield))); FakeDataStore.AddFile(_uncompressedAxxPath, FakeDataStore.ExpandableMemoryStream(Resources.uncompressable_zip)); FakeDataStore.AddFile(_helloWorldAxxPath, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); TypeMap.Register.Singleton <IUIThread>(() => new FakeUIThread()); }
public void TestValidateWrongButKnownPassphraseWithRealFile() { _identities.Add(new Passphrase("b")); FakeDataStore.AddFile(@"C:\My Folder\MyFile-txt.axx", new MemoryStream(Resources.helloworld_key_a_txt)); FilePasswordViewModel npvm = new FilePasswordViewModel(@"C:\My Folder\MyFile-txt.axx"); npvm.PasswordText = "b"; Assert.That(npvm[nameof(FilePasswordViewModel.PasswordText)], Is.Not.EqualTo(String.Empty)); Assert.That(npvm.ValidationError, Is.EqualTo((int)ValidationError.WrongPassphrase)); }
public async Task TestCheckActiveFilesUpdateButWithTargetInaccessible() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); LogOnIdentity passphrase = new LogOnIdentity("a"); New <AxCryptFile>().Decrypt(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), passphrase, AxCryptOptions.None, new ProgressContext()); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), passphrase, ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); IDataStore decryptedFileInfo = New <IDataStore>(_decryptedFile1); decryptedFileInfo.SetFileTimes(utcNow.AddSeconds(30), utcNow.AddSeconds(30), utcNow.AddSeconds(30)); ((FakeNow)New <INow>()).TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); await Resolve.KnownIdentities.AddAsync(passphrase); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange && notification.FullNames.Contains(_anAxxPath); return(Constant.CompletedTask); }); EventHandler eventHandler = ((object sender, EventArgs e) => { FakeDataStore fileInfo = (FakeDataStore)sender; if (fileInfo.FullName == Path.ChangeExtension(_anAxxPath, ".tmp")) { throw new IOException("Faked access denied."); } }); FakeDataStore.OpeningForWrite += eventHandler; try { Assert.ThrowsAsync <FileOperationException>(async() => await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext())); } finally { FakeDataStore.OpeningForWrite -= eventHandler; } Assert.That(changedWasRaised, Is.False, "The ActiveFile should not be modified because it was not accessible."); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotShareable), Is.False, "The ActiveFile should not be marked as not shareable after the checking of active files."); }
public static void TestValidateWrongPassphraseWithRealFile(CryptoImplementation cryptoImplementation) { SetupAssembly.AssemblySetupCrypto(cryptoImplementation); FakeDataStore.AddFile(@"C:\My Folder\MyFile-txt.axx", new MemoryStream(Resources.helloworld_key_a_txt)); NewPasswordViewModel npvm = new NewPasswordViewModel(String.Empty, @"C:\My Folder\MyFile-txt.axx"); npvm.PasswordText = "b"; npvm.Verification = "b"; Assert.That(npvm[nameof(NewPasswordViewModel.PasswordText)], Is.Not.EqualTo("")); Assert.That(npvm.ValidationError, Is.EqualTo((int)ValidationError.WrongPassphrase)); }
public void TestSetRecentFilesComparer() { string file1 = @"C:\Folder\File3-txt.axx"; string decrypted1 = @"C:\Folder\File2.txt"; string file2 = @"C:\Folder\File2-txt.axx"; string decrypted2 = @"C:\Folder\File1.txt"; string file3 = @"C:\Folder\File1-txt.axx"; string decrypted3 = @"C:\Folder\File3.txt"; ActiveFile activeFile; ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2001, 1, 1); FakeDataStore.AddFile(file1, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file1), New <IDataStore>(decrypted1), new LogOnIdentity("passphrase1"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2002, 2, 2); FakeDataStore.AddFile(file2, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file2), New <IDataStore>(decrypted2), new LogOnIdentity("passphrase2"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2003, 3, 3); FakeDataStore.AddFile(file3, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file3), New <IDataStore>(decrypted3), new LogOnIdentity("passphrase"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); ActiveFileComparer comparer; List <ActiveFile> recentFiles; comparer = ActiveFileComparer.DateComparer; using (MainViewModel mvm = New <MainViewModel>()) { mvm.RecentFiles = Resolve.FileSystemState.ActiveFiles; mvm.RecentFilesComparer = comparer; recentFiles = mvm.RecentFiles.ToList(); Assert.That(recentFiles[0].EncryptedFileInfo.FullName, Is.EqualTo(file1.NormalizeFilePath()), "Sorted by Date, this should be number 1."); Assert.That(recentFiles[1].EncryptedFileInfo.FullName, Is.EqualTo(file2.NormalizeFilePath()), "Sorted by Date, this should be number 2."); Assert.That(recentFiles[2].EncryptedFileInfo.FullName, Is.EqualTo(file3.NormalizeFilePath()), "Sorted by Date, this should be number 3."); comparer = ActiveFileComparer.DateComparer; comparer.ReverseSort = true; mvm.RecentFilesComparer = comparer; recentFiles = mvm.RecentFiles.ToList(); } Assert.That(recentFiles[0].EncryptedFileInfo.FullName, Is.EqualTo(file3.NormalizeFilePath()), "Sorted by Date in reverse, this should be number 1."); Assert.That(recentFiles[1].EncryptedFileInfo.FullName, Is.EqualTo(file2.NormalizeFilePath()), "Sorted by Date, this should be number 2."); Assert.That(recentFiles[2].EncryptedFileInfo.FullName, Is.EqualTo(file1.NormalizeFilePath()), "Sorted by Date, this should be number 3."); }
public async Task TestSetFilesArePending() { await Resolve.KnownIdentities.SetDefaultEncryptionIdentity(new LogOnIdentity("passphrase")); FakeDataStore.AddFolder(@"C:\MyFolders\Folder1"); using (MainViewModel mvm = New <MainViewModel>()) { Assert.That(mvm.FilesArePending, Is.False); await Resolve.FileSystemState.AddWatchedFolderAsync(new WatchedFolder(@"C:\MyFolders\Folder1", Resolve.KnownIdentities.DefaultEncryptionIdentity.Tag)); FakeDataStore.AddFile(@"C:\MyFolders\Folder1\Encryptable.txt", Stream.Null); Assert.That(mvm.FilesArePending, Is.True); } }
public async Task TestCheckActiveFilesKeyIsNotSetWithoutKnownKey() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); LogOnIdentity passphrase = new LogOnIdentity("a"); New <AxCryptFile>().Decrypt(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), passphrase, AxCryptOptions.None, new ProgressContext()); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), passphrase, ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); await Resolve.FileSystemState.Save(); TypeMap.Register.Singleton <FileSystemState>(() => FileSystemState.Create(New <IDataStore>(_fileSystemStateFilePath))); IDataStore decryptedFileInfo = New <IDataStore>(_decryptedFile1); decryptedFileInfo.SetFileTimes(utcNow.AddSeconds(30), utcNow.AddSeconds(30), utcNow.AddSeconds(30)); ((FakeNow)New <INow>()).TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange; return(Constant.CompletedTask); }); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(activeFile.Identity == LogOnIdentity.Empty, "The key should be null after loading of new FileSystemState"); await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); Assert.That(changedWasRaised, Is.False, "The ActiveFile should be not be modified because the file was modified as well and thus cannot be deleted."); await Resolve.KnownIdentities.AddAsync(new LogOnIdentity("x")); await Resolve.KnownIdentities.AddAsync(new LogOnIdentity("y")); await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); Assert.That(changedWasRaised, Is.False, "The ActiveFile should be not be modified because the file was modified as well and thus cannot be deleted."); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(activeFile.Identity == LogOnIdentity.Empty, "The key should still be null after the checking of active files."); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.AssumedOpenAndDecrypted), Is.True, "The file should still be there."); Assert.That(activeFile.ThumbprintMatch(passphrase.Passphrase), Is.True, "The active file should still be known to be decryptable with the original passphrase."); }
public async Task TestTryDeleteButDecryptedSharingLocked() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, new MemoryStream(Resources.helloworld_key_a_txt)); FakeDataStore.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); ((FakeNow)New <INow>()).TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange; return(Constant.CompletedTask); }); SetupAssembly.FakeRuntimeEnvironment.Platform = Platform.WindowsDesktop; EventHandler eventHandler = ((object sender, EventArgs e) => { FakeDataStore fileInfo = (FakeDataStore)sender; if (fileInfo.FullName == _decryptedFile1) { throw new IOException("Faked sharing violation."); } }); FakeDataStore.Moving += eventHandler; FakeDataStore.Deleting += eventHandler; FakeDataStore.OpeningForWrite += eventHandler; try { await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); } finally { FakeDataStore.Deleting -= eventHandler; FakeDataStore.OpeningForWrite -= eventHandler; FakeDataStore.Moving -= eventHandler; } activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(changedWasRaised, Is.True, "A changed event should be raised because it should now be NotShareable."); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.AssumedOpenAndDecrypted), Is.True, "The ActiveFile plain text should still be there after the checking of active files because the file is NotShareable."); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotShareable), Is.True, "The ActiveFile plain text should be NotShareable after the checking of active files because the file could not be deleted."); }
public async Task TestStatusMaskAtLoad() { using (FileSystemState state = FileSystemState.Create(Resolve.WorkFolder.FileInfo.FileItemInfo("mystate.txt"))) { FakeDataStore.AddFile(_encryptedAxxPath, FakeDataStore.TestDate1Utc, FakeDataStore.TestDate2Utc, FakeDataStore.TestDate3Utc, new MemoryStream(Resources.helloworld_key_a_txt)); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_encryptedAxxPath), New <IDataStore>(_decryptedTxtPath), new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.Error | ActiveFileStatus.IgnoreChange | ActiveFileStatus.NotShareable, new V1Aes128CryptoFactory().CryptoId); state.Add(activeFile); await state.Save(); FileSystemState reloadedState = FileSystemState.Create(Resolve.WorkFolder.FileInfo.FileItemInfo("mystate.txt")); Assert.That(reloadedState, Is.Not.Null, "An instance should always be instantiated."); Assert.That(reloadedState.ActiveFiles.Count(), Is.EqualTo(1), "The reloaded state should have one active file."); Assert.That(reloadedState.ActiveFiles.First().Status, Is.EqualTo(ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.NoProcessKnown), "When reloading saved state, some statuses should be masked away and NoProcessKnown added."); } }
public async Task TestPurgeActiveFilesWhenFileIsModified() { DateTime utcNow = New <INow>().Utc; Stream axxStream = new MemoryStream(); axxStream.Write(Resources.helloworld_key_a_txt, 0, Resources.helloworld_key_a_txt.Length); axxStream.Position = 0; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, axxStream); FakeDataStore.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); Mock <AxCryptFactory> axCryptFactoryMock = new Mock <AxCryptFactory>() { CallBase = true }; axCryptFactoryMock.Setup <DecryptionParameter>(m => m.FindDecryptionParameter(It.IsAny <IEnumerable <DecryptionParameter> >(), It.IsAny <IDataStore>())).Returns((Func <IEnumerable <DecryptionParameter>, IDataStore, DecryptionParameter>)((IEnumerable <DecryptionParameter> decryptionParameters, IDataStore fileInfo) => { return(new DecryptionParameter(Passphrase.Empty, new V1Aes128CryptoFactory().CryptoId)); })); TypeMap.Register.New <AxCryptFactory>(() => axCryptFactoryMock.Object); IDataStore encryptedFileInfo = New <IDataStore>(_anAxxPath); IDataStore decryptedFileInfo = New <IDataStore>(_decryptedFile1); ActiveFile activeFile = new ActiveFile(encryptedFileInfo, decryptedFileInfo, new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.NotShareable, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); int timeCalls = 0; ((FakeNow)New <INow>()).TimeFunction = (() => { return(utcNow.AddMinutes(1).AddMilliseconds(100 * timeCalls++)); }); DateTime utcLater = New <INow>().Utc; decryptedFileInfo.SetFileTimes(utcLater, utcLater, utcLater); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange; return(Constant.CompletedTask); }); await New <ActiveFileAction>().PurgeActiveFiles(new ProgressContext()); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(changedWasRaised, Is.True, "A changed event should be raised because the decrypted file is modified."); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotDecrypted), Is.True, "The NotShareable not withstanding, the purge should have updated the file and removed the decrypted file."); }
public void Setup() { SetupAssembly.AssemblySetup(); SetupAssembly.AssemblySetupCrypto(_cryptoImplementation); _rootPath = Path.GetPathRoot(Environment.CurrentDirectory); _testTextPath = _rootPath.PathCombine("test.txt"); _davidCopperfieldTxtPath = _rootPath.PathCombine("Users", "AxCrypt", "David Copperfield.txt"); _uncompressedAxxPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).PathCombine("Uncompressed.axx"); _helloWorldAxxPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments).PathCombine("HelloWorld.axx"); FakeDataStore.AddFile(_testTextPath, FakeDataStore.TestDate1Utc, FakeDataStore.TestDate2Utc, FakeDataStore.TestDate1Utc, FakeDataStore.ExpandableMemoryStream(Encoding.UTF8.GetBytes("This is a short file"))); FakeDataStore.AddFile(_davidCopperfieldTxtPath, FakeDataStore.TestDate4Utc, FakeDataStore.TestDate5Utc, FakeDataStore.TestDate6Utc, FakeDataStore.ExpandableMemoryStream(Encoding.GetEncoding(1252).GetBytes(Resources.david_copperfield))); FakeDataStore.AddFile(_uncompressedAxxPath, FakeDataStore.ExpandableMemoryStream(Resources.uncompressable_zip)); FakeDataStore.AddFile(_helloWorldAxxPath, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); }
public async Task TestCheckActiveFilesKeyIsSet() { DateTime utcNow = New <INow>().Utc; DateTime utcJustNow = utcNow.AddMinutes(-1); FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, new MemoryStream(Resources.helloworld_key_a_txt)); FakeDataStore.AddFile(_decryptedFile1, utcJustNow, utcJustNow, utcJustNow, Stream.Null); Mock <AxCryptFactory> axCryptFactoryMock = new Mock <AxCryptFactory>() { CallBase = true }; axCryptFactoryMock.Setup <DecryptionParameter>(m => m.FindDecryptionParameter(It.IsAny <IEnumerable <DecryptionParameter> >(), It.IsAny <IDataStore>())).Returns((Func <IEnumerable <DecryptionParameter>, IDataStore, DecryptionParameter>)((IEnumerable <DecryptionParameter> decryptionParameters, IDataStore fileInfo) => { return(new DecryptionParameter(Passphrase.Empty, new V1Aes128CryptoFactory().CryptoId)); })); TypeMap.Register.New <AxCryptFactory>(() => axCryptFactoryMock.Object); ActiveFile activeFile; activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); await Resolve.KnownIdentities.AddAsync(activeFile.Identity); IDataStore decryptedFileInfo = New <IDataStore>(_decryptedFile1); decryptedFileInfo.SetFileTimes(utcNow, utcNow, utcNow); ((FakeNow)New <INow>()).TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange; return(Constant.CompletedTask); }); ((FakeNow)New <INow>()).TimeFunction = () => DateTime.UtcNow; await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); Assert.That(changedWasRaised, Is.True, "The file should be detected as modified, because it is considered open and decrypted, has a proper key, is modified, no running process so it should be re-encrypted and deleted."); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(activeFile, Is.Not.Null, "The encrypted file should be found."); Assert.That(activeFile.IsModified, Is.False, "The file should no longer be flagged as modified."); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotDecrypted), Is.True, "The file should no longer be decrypted, since it was re-encrypted and deleted."); }
public async Task TestDoNotDeleteModifiedIfNotSignedIn() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, new MemoryStream(Resources.helloworld_key_a_txt)); FakeDataStore.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), LogOnIdentity.Empty, ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); activeFile = new ActiveFile(activeFile, utcNow.AddMinutes(-1), ActiveFileStatus.AssumedOpenAndDecrypted); Resolve.FileSystemState.Add(activeFile); await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.AssumedOpenAndDecrypted), Is.True, "The ActiveFile plain text should not be deleted after the checking of active files because the user is not signed in."); }
public static void TestMoveCurrentLogFileContentToPreviousLogFile() { FakeDataStore.AddFile(@"c:\test\ReportSnapshot.txt", new MemoryStream()); FakeDataStore.AddFile(@"c:\test\ReportSnapshot.1.txt", new MemoryStream()); IReport report = new Report(@"c:\test\", 100); string previousLogText = new StreamReader(New <IDataStore>(@"c:\test\ReportSnapshot.1.txt").OpenRead(), Encoding.UTF8).ReadToEnd(); Assert.That(previousLogText.Length == 0, "Previous log file contain data."); for (int i = 0; i < 5; i++) { report.Exception(new Exception("This is a test " + i)); } previousLogText = new StreamReader(New <IDataStore>(@"c:\test\ReportSnapshot.1.txt").OpenRead(), Encoding.UTF8).ReadToEnd(); Assert.That(previousLogText.Length > 0, "Data not been coppied to pPrevious log file."); }
public async Task TestRemoveRecentFiles() { var mockFileSystemState = new Mock <FileSystemState>() { CallBase = true }; mockFileSystemState.Setup(x => x.Save()).Returns(Constant.CompletedTask); TypeMap.Register.Singleton <FileSystemState>(() => mockFileSystemState.Object); string file1 = @"C:\Folder\File3-txt.axx"; string decrypted1 = @"C:\Folder\File2.txt"; string file2 = @"C:\Folder\File2-txt.axx"; string decrypted2 = @"C:\Folder\File1.txt"; string file3 = @"C:\Folder\File1-txt.axx"; string decrypted3 = @"C:\Folder\File3.txt"; ActiveFile activeFile; FakeDataStore.AddFile(file1, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file1), New <IDataStore>(decrypted1), new LogOnIdentity("passphrase1"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); FakeDataStore.AddFile(file2, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file2), New <IDataStore>(decrypted2), new LogOnIdentity("passphrase2"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); FakeDataStore.AddFile(file3, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file3), New <IDataStore>(decrypted3), new LogOnIdentity("passphrase"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); using (MainViewModel mvm = New <MainViewModel>()) { Assert.That(await mvm.RemoveRecentFiles.CanExecuteAsync(null), Is.True, "RemoveRecentFiles should be executable by default."); await mvm.RemoveRecentFiles.ExecuteAsync(new string[] { file2 }); mockFileSystemState.Verify(x => x.RemoveActiveFile(It.IsAny <ActiveFile>()), Times.Once, "Exactly one recent file should be removed."); mockFileSystemState.ResetCalls(); await mvm.RemoveRecentFiles.ExecuteAsync(new string[] { file2 }); } mockFileSystemState.Verify(x => x.RemoveActiveFile(It.IsAny <ActiveFile>()), Times.Never, "There is no longer any matching file, so no call to remove should happen."); }
public async Task TestUpdateActiveFileWithKeyIfKeyMatchesThumbprintWithMatchingThumbprint() { IDataStore encryptedFileInfo = New <IDataStore>(_anAxxPath); IDataStore decryptedFileInfo = New <IDataStore>(_decryptedFile1); LogOnIdentity key = new LogOnIdentity("passphrase"); FakeDataStore.AddFile(_anAxxPath, FakeDataStore.TestDate1Utc, FakeDataStore.TestDate2Utc, FakeDataStore.TestDate3Utc, new MemoryStream(Resources.helloworld_key_a_txt)); ActiveFile activeFile = new ActiveFile(encryptedFileInfo, decryptedFileInfo, key, ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.NotShareable, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); await Resolve.FileSystemState.Save(); TypeMap.Register.Singleton <FileSystemState>(() => FileSystemState.Create(New <IDataStore>(_fileSystemStateFilePath))); bool updateWasMade = await New <ActiveFileAction>().UpdateActiveFileWithKeyIfKeyMatchesThumbprint(key); Assert.That(updateWasMade, Is.True, "Since there is an ActiveFile with the right thumbprint in the list, an update should be made."); }
public async Task TestDeleteModifiedWhenSignedIn() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, FakeDataStore.ExpandableMemoryStream(Resources.david_copperfield_key__aa_ae_oe__ulu_txt)); FakeDataStore.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), LogOnIdentity.Empty, ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); activeFile = new ActiveFile(activeFile, utcNow.AddMinutes(-1), ActiveFileStatus.AssumedOpenAndDecrypted); Resolve.FileSystemState.Add(activeFile); await New <KnownIdentities>().SetDefaultEncryptionIdentity(new LogOnIdentity(EmailAddress.Parse("*****@*****.**"), new Passphrase("test"))); await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotDecrypted), Is.True, "The ActiveFile plain text should be deleted after the checking of active files because the user is signed in."); }
public async Task TestCheckActiveFilesUpdateButWithTargetLockedForSharing() { DateTime utcNow = New <INow>().Utc; FakeDataStore.AddFile(_anAxxPath, utcNow, utcNow, utcNow, FakeDataStore.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); LogOnIdentity passphrase = new LogOnIdentity("a"); New <AxCryptFile>().Decrypt(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), passphrase, AxCryptOptions.None, new ProgressContext()); ActiveFile activeFile = new ActiveFile(New <IDataStore>(_anAxxPath), New <IDataStore>(_decryptedFile1), passphrase, ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); IDataStore decryptedFileInfo = New <IDataStore>(_decryptedFile1); decryptedFileInfo.SetFileTimes(utcNow.AddSeconds(30), utcNow.AddSeconds(30), utcNow.AddSeconds(30)); ((FakeNow)New <INow>()).TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); await Resolve.KnownIdentities.AddAsync(passphrase); bool changedWasRaised = false; Resolve.SessionNotify.AddCommand((SessionNotification notification) => { changedWasRaised = notification.NotificationType == SessionNotificationType.ActiveFileChange; return(Constant.CompletedTask); }); try { FakeDataStore.IsLockedFunc = (fds) => fds.FullName == _decryptedFile1; await New <ActiveFileAction>().CheckActiveFiles(new ProgressContext()); } finally { FakeDataStore.IsLockedFunc = (fds) => false; } Assert.That(changedWasRaised, Is.True, "The ActiveFile should be modified because it should now be marked as not shareable."); activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_anAxxPath); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotShareable), Is.True, "The ActiveFile should be marked as not shareable after the checking of active files."); }
public async Task TestWatchedFolderChanged() { using (FileSystemState state = FileSystemState.Create(Resolve.WorkFolder.FileInfo.FileItemInfo("mystate.txt"))) { FakeDataStore.AddFolder(_rootPath); await state.AddWatchedFolderAsync(new WatchedFolder(_rootPath, IdentityPublicTag.Empty)); Assert.That(state.ActiveFileCount, Is.EqualTo(0)); FakeDataStore.AddFile(_encryptedAxxPath, new MemoryStream(Resources.helloworld_key_a_txt)); Assert.That(state.ActiveFileCount, Is.EqualTo(0)); state.Add(new ActiveFile(New <IDataStore>(_encryptedAxxPath), New <IDataStore>(_decryptedTxtPath), new LogOnIdentity("passphrase"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId)); Assert.That(state.ActiveFileCount, Is.EqualTo(1)); New <IDataStore>(_encryptedAxxPath).Delete(); Assert.That(state.ActiveFileCount, Is.EqualTo(0), "When deleted, the active file count should be zero."); } }
public static void TestWorkFolderWatcherSimple() { TypeMap.Register.Singleton <SessionNotify>(() => new Mock <SessionNotify>().Object); using (WorkFolderWatcher wfw = new WorkFolderWatcher()) { string fileName = Resolve.WorkFolder.FileInfo.FileItemInfo("New File.txt").FullName; FakeDataStore.AddFile(fileName, null); Mock.Get(Resolve.SessionNotify).Verify(s => s.NotifyAsync(It.Is <SessionNotification>(n => n.NotificationType == SessionNotificationType.WorkFolderChange && n.FullNames.SequenceEqual(new string[] { fileName }))), Times.Once); New <IDataStore>(fileName).Delete(); Mock.Get(Resolve.SessionNotify).Verify(s => s.NotifyAsync(It.Is <SessionNotification>(n => n.NotificationType == SessionNotificationType.WorkFolderChange && n.FullNames.SequenceEqual(new string[] { fileName }))), Times.Exactly(2)); IDataStore fileSystemStateInfo = Resolve.WorkFolder.FileInfo.FileItemInfo("FileSystemState.txt"); fileSystemStateInfo.Delete(); Mock.Get(Resolve.SessionNotify).Verify(s => s.NotifyAsync(It.Is <SessionNotification>(n => n.NotificationType == SessionNotificationType.WorkFolderChange && n.FullNames.SequenceEqual(new string[] { fileSystemStateInfo.FullName }))), Times.Never); } }
public async Task TestOpenFiles() { string file1 = @"C:\Folder\File3-txt.axx"; string decrypted1 = @"C:\Folder\File2.txt"; string file2 = @"C:\Folder\File2-txt.axx"; string decrypted2 = @"C:\Folder\File1.txt"; string file3 = @"C:\Folder\File1-txt.axx"; string decrypted3 = @"C:\Folder\File3.txt"; ActiveFile activeFile; using (MainViewModel mvm = New <MainViewModel>()) { ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2001, 1, 1); FakeDataStore.AddFile(file1, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file1), New <IDataStore>(decrypted1), new LogOnIdentity("passphrase1"), ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2002, 2, 2); FakeDataStore.AddFile(file2, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file2), New <IDataStore>(decrypted2), new LogOnIdentity("passphrase2"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2003, 3, 3); FakeDataStore.AddFile(file3, new MemoryStream(Resources.helloworld_key_a_txt)); activeFile = new ActiveFile(New <IDataStore>(file3), New <IDataStore>(decrypted3), new LogOnIdentity("passphrase3"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); await Resolve.FileSystemState.Save(); Assert.That(mvm.FilesArePending, Is.True); activeFile = new ActiveFile(New <IDataStore>(file1), New <IDataStore>(decrypted1), new LogOnIdentity("passphrase"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Resolve.FileSystemState.Add(activeFile); await Resolve.FileSystemState.Save(); Assert.That(mvm.FilesArePending, Is.False); } }