public async Task TestForEach() { using (FileSystemState state = FileSystemState.Create(Resolve.WorkFolder.FileInfo.FileItemInfo("mystate.txt"))) { ActiveFile activeFile; activeFile = new ActiveFile(New <IDataStore>(_encrypted1AxxPath), New <IDataStore>(_decrypted1TxtPath), new LogOnIdentity("passphrase1"), ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.Error | ActiveFileStatus.IgnoreChange | ActiveFileStatus.NotShareable, new V1Aes128CryptoFactory().CryptoId); state.Add(activeFile); activeFile = new ActiveFile(New <IDataStore>(_encrypted2AxxPath), New <IDataStore>(_decrypted2TxtPath), new LogOnIdentity("passphrase2"), ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.Error | ActiveFileStatus.IgnoreChange | ActiveFileStatus.NotShareable, new V1Aes128CryptoFactory().CryptoId); state.Add(activeFile); activeFile = new ActiveFile(New <IDataStore>(_encrypted3AxxPath), New <IDataStore>(_decrypted3TxtPath), new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.Error | ActiveFileStatus.IgnoreChange | ActiveFileStatus.NotShareable, new V1Aes128CryptoFactory().CryptoId); state.Add(activeFile); Assert.That(state.ActiveFiles.Count(), Is.EqualTo(3), "There should be three."); int i = 0; await state.ForEach((ActiveFile activeFileArgument) => { ++i; return(Task.FromResult(activeFileArgument)); }); Assert.That(i, Is.EqualTo(3), "The iteration should have visited three active files."); i = 0; await state.ForEach((ActiveFile activeFileArgument) => { ++i; return(Task.FromResult(new ActiveFile(activeFileArgument, activeFile.Status | ActiveFileStatus.Error))); }); Assert.That(i, Is.EqualTo(3), "The iteration should have visited three active files."); } }
private static ActiveFile TryDecryptToActiveFile(IDataStore encryptedDataStore, IEnumerable <LogOnIdentity> identities) { ActiveFile activeFile = null; foreach (LogOnIdentity identity in identities) { if (Resolve.Log.IsInfoEnabled) { Resolve.Log.LogInfo("Decrypting '{0}'".InvariantFormat(encryptedDataStore.FullName)); } using (FileLock encryptedLock = New <FileLocker>().Acquire(encryptedDataStore)) { using (IAxCryptDocument document = New <AxCryptFile>().Document(encryptedDataStore, identity, new ProgressContext())) { if (!document.PassphraseIsValid) { continue; } activeFile = DestinationActiveFileFromDocument(encryptedDataStore, activeFile?.DecryptedFileInfo?.Container, identity, document); break; } } } return(activeFile); }
private static void UpdateListViewItem(ListViewItem item, ActiveFile activeFile) { OpenFileProperties openProperties = OpenFileProperties.Create(activeFile.EncryptedFileInfo); item.SubItems[nameof(ColumnName.EncryptedPath)].Text = activeFile.EncryptedFileInfo.FullName; item.SubItems[nameof(ColumnName.AccessedDate)].Text = activeFile.Properties.LastActivityTimeUtc.ToLocalTime().ToString(CultureInfo.CurrentCulture); item.SubItems[nameof(ColumnName.AccessedDate)].Tag = activeFile.Properties.LastActivityTimeUtc; item.SubItems[nameof(ColumnName.ModifiedDate)].Text = activeFile.EncryptedFileInfo.LastWriteTimeUtc.ToLocalTime().ToString(CultureInfo.CurrentCulture); item.SubItems[nameof(ColumnName.ModifiedDate)].Tag = activeFile.EncryptedFileInfo.LastWriteTimeUtc; LogOnIdentity decryptIdentity = ValidateActiveFileIdentity(activeFile.Identity); UpdateStatusDependentPropertiesOfListViewItem(item, activeFile, activeFile.EncryptedFileInfo.IsKeyShared(decryptIdentity)); try { if (activeFile.Properties.CryptoId != Guid.Empty) { item.SubItems[nameof(ColumnName.CryptoName)].Text = Resolve.CryptoFactory.Create(activeFile.Properties.CryptoId).Name; if (activeFile.VisualState.HasFlag(ActiveFileVisualStates.LowEncryption)) { item.SubItems[nameof(ColumnName.CryptoName)].ForeColor = Styling.WarningColor; } } } catch (ArgumentException aex) { New <IReport>().Exception(aex); item.SubItems[nameof(ColumnName.CryptoName)].Text = Texts.UnknownCrypto; } }
private void UpdateRecentFilesListView(ActiveFile activeFile) { recentFilesListView.ListViewItemSorter = null; ListViewItem item = recentFilesListView.Items[activeFile.EncryptedFileInfo.FullName]; if (item == null) { string text = Path.GetFileName(activeFile.DecryptedFileInfo.FullName); item = recentFilesListView.Items.Add(text); item.Name = activeFile.EncryptedFileInfo.FullName; ListViewItem.ListViewSubItem dateColumn = item.SubItems.Add(String.Empty); dateColumn.Name = "Date"; //MLHIDE ListViewItem.ListViewSubItem encryptedPathColumn = item.SubItems.Add(String.Empty); encryptedPathColumn.Name = "EncryptedPath"; //MLHIDE } UpdateListViewItem(item, activeFile); recentFilesListView.ListViewItemSorter = _currentRecentFilesSorter; while (recentFilesListView.Items.Count > Settings.Default.MaxNumberRecentFiles) { recentFilesListView.Items.RemoveAt(recentFilesListView.Items.Count - 1); } }
public static void TestDecryptedActiveFiles() { using (FileSystemState state = new FileSystemState()) { state.Load(OS.Current.FileInfo(_mystateXmlPath)); ActiveFile decryptedFile1 = new ActiveFile(OS.Current.FileInfo(_encryptedAxxPath), OS.Current.FileInfo(_decryptedTxtPath), new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted, null); state.Add(decryptedFile1); ActiveFile decryptedFile2 = new ActiveFile(OS.Current.FileInfo(_encrypted2AxxPath), OS.Current.FileInfo(_decrypted2TxtPath), new AesKey(), ActiveFileStatus.DecryptedIsPendingDelete, null); state.Add(decryptedFile2); ActiveFile notDecryptedFile = new ActiveFile(OS.Current.FileInfo(_encrypted3AxxPath), OS.Current.FileInfo(_decrypted3TxtPath), new AesKey(), ActiveFileStatus.NotDecrypted, null); state.Add(notDecryptedFile); ActiveFile errorFile = new ActiveFile(OS.Current.FileInfo(_encrypted4AxxPath), OS.Current.FileInfo(_decrypted4TxtPath), new AesKey(), ActiveFileStatus.Error, null); state.Add(errorFile); IList <ActiveFile> decryptedFiles = state.DecryptedActiveFiles; Assert.That(decryptedFiles.Count, Is.EqualTo(2), "There should be two decrypted files."); Assert.That(decryptedFiles.Contains(decryptedFile1), "A file marked as AssumedOpenAndDecrypted should be found."); Assert.That(decryptedFiles.Contains(decryptedFile2), "A file marked as DecryptedIsPendingDelete should be found."); Assert.That(decryptedFiles.Contains(notDecryptedFile), Is.Not.True, "A file marked as NotDecrypted should not be found."); } }
private static ActiveFile TryDecrypt(IRuntimeFileInfo sourceFileInfo, IRuntimeFileInfo destinationFolderInfo, IEnumerable <AesKey> keys, ProgressContext progress) { ActiveFile destinationActiveFile = null; foreach (AesKey key in keys) { if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Decrypting '{0}'".InvariantFormat(sourceFileInfo.FullName)); } using (FileLock sourceLock = FileLock.Lock(sourceFileInfo)) { using (AxCryptDocument document = AxCryptFile.Document(sourceFileInfo, key, new ProgressContext())) { if (!document.PassphraseIsValid) { continue; } destinationActiveFile = DecryptActiveFileDocument(sourceFileInfo, destinationFolderInfo, document, progress); break; } } } return(destinationActiveFile); }
public static void TestDateComparer() { ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2013, 01, 01); ActiveFile activeFile1a = new ActiveFile(New <IDataStore>((@"C:\encrypted1.axx")), New <IDataStore>(@"C:\decrypted1.txt"), new LogOnIdentity("activeFile1a"), ActiveFileStatus.NotDecrypted, new V2Aes256CryptoFactory().CryptoId); ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2013, 01, 01); ActiveFile activeFile1b = new ActiveFile(New <IDataStore>((@"C:\encrypted2.axx")), New <IDataStore>(@"C:\decrypted2.txt"), new LogOnIdentity("activeFile1b"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); ActiveFileComparer comparer = ActiveFileComparer.DateComparer; Assert.That(comparer.ReverseSort, Is.False); Assert.That(comparer.Compare(activeFile1a, activeFile1b), Is.EqualTo(0)); Assert.That(comparer.Compare(activeFile1b, activeFile1a), Is.EqualTo(0)); comparer.ReverseSort = true; Assert.That(comparer.Compare(activeFile1a, activeFile1b), Is.EqualTo(0)); Assert.That(comparer.Compare(activeFile1b, activeFile1a), Is.EqualTo(0)); comparer.ReverseSort = false; ((FakeNow)New <INow>()).TimeFunction = () => new DateTime(2013, 01, 02); ActiveFile activeFile2 = new ActiveFile(New <IDataStore>((@"C:\encrypted3.axx")), New <IDataStore>(@"C:\decrypted3.txt"), new LogOnIdentity("activeFile2"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Assert.That(comparer.Compare(activeFile1a, activeFile2), Is.LessThan(0)); Assert.That(comparer.Compare(activeFile2, activeFile1a), Is.GreaterThan(0)); comparer.ReverseSort = true; Assert.That(comparer.Compare(activeFile1a, activeFile2), Is.GreaterThan(0)); Assert.That(comparer.Compare(activeFile2, activeFile1a), Is.LessThan(0)); comparer.ReverseSort = false; }
public static void TestEncryptedNameComparer() { ActiveFile activeFile1a = new ActiveFile(New <IDataStore>((@"C:\encrypted1.axx")), New <IDataStore>(@"C:\decrypted1a.txt"), new LogOnIdentity("activeFile1a"), ActiveFileStatus.NotDecrypted, new V2Aes256CryptoFactory().CryptoId); ActiveFile activeFile1b = new ActiveFile(New <IDataStore>((@"C:\encrypted1.axx")), New <IDataStore>(@"C:\decrypted1b.txt"), new LogOnIdentity("activeFile1b"), ActiveFileStatus.NotDecrypted, new V2Aes256CryptoFactory().CryptoId); ActiveFileComparer comparer = ActiveFileComparer.EncryptedNameComparer; Assert.That(comparer.ReverseSort, Is.False); Assert.That(comparer.Compare(activeFile1a, activeFile1b), Is.EqualTo(0)); Assert.That(comparer.Compare(activeFile1b, activeFile1a), Is.EqualTo(0)); comparer.ReverseSort = true; Assert.That(comparer.Compare(activeFile1a, activeFile1b), Is.EqualTo(0)); Assert.That(comparer.Compare(activeFile1b, activeFile1a), Is.EqualTo(0)); comparer.ReverseSort = false; ActiveFile activeFile2 = new ActiveFile(New <IDataStore>((@"C:\encrypted2.axx")), New <IDataStore>(@"C:\decrypted1a.txt"), new LogOnIdentity("activeFile2"), ActiveFileStatus.NotDecrypted, new V1Aes128CryptoFactory().CryptoId); Assert.That(comparer.Compare(activeFile1a, activeFile2), Is.LessThan(0)); Assert.That(comparer.Compare(activeFile2, activeFile1a), Is.GreaterThan(0)); comparer.ReverseSort = true; Assert.That(comparer.Compare(activeFile1a, activeFile2), Is.GreaterThan(0)); Assert.That(comparer.Compare(activeFile2, activeFile1a), Is.LessThan(0)); comparer.ReverseSort = false; }
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 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."); }
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."); }
private Task <FileOperationContext> VerifyAndAddActiveWorkAsync(IDataStore fullName, IProgressContext progress) { FileOperationsController operationsController = new FileOperationsController(progress); operationsController.QueryDecryptionPassphrase += HandleQueryDecryptionPassphraseEventAsync; operationsController.KnownKeyAdded = new AsyncDelegateAction <FileOperationEventArgs>(async(FileOperationEventArgs e) => { if (!_fileSystemState.KnownPassphrases.Any(i => i.Thumbprint == e.LogOnIdentity.Passphrase.Thumbprint)) { _fileSystemState.KnownPassphrases.Add(e.LogOnIdentity.Passphrase); } await _knownIdentities.AddAsync(e.LogOnIdentity); }); operationsController.Completed += (object sender, FileOperationEventArgs e) => { if (e.Status.ErrorStatus == ErrorStatus.Success) { IDataStore encryptedInfo = New <IDataStore>(e.OpenFileFullName); IDataStore decryptedInfo = New <IDataStore>(FileOperation.GetTemporaryDestinationName(e.SaveFileFullName)); ActiveFile activeFile = new ActiveFile(encryptedInfo, decryptedInfo, e.LogOnIdentity, ActiveFileStatus.NotDecrypted, e.CryptoId); _fileSystemState.Add(activeFile); } }; return(operationsController.VerifyEncryptedAsync(fullName)); }
public async Task TestFileContainedByActiveFilesButNotDecrypted() { IDataStore dataStore = New <IDataStore>(_helloWorldAxxPath); TypeMap.Register.New <ILauncher>(() => new FakeLauncher()); IEnumerable <LogOnIdentity> keys = new LogOnIdentity[] { new LogOnIdentity("a") }; FileOperation fileOperation = new FileOperation(Resolve.FileSystemState, new SessionNotify()); FileOperationContext status = await fileOperation.OpenAndLaunchApplication(keys, dataStore, new ProgressContext()); Assert.That(status.ErrorStatus, Is.EqualTo(ErrorStatus.Success), "The launch should succeed."); IDataStore fileInfo = New <IDataStore>(_helloWorldAxxPath); ActiveFile destinationActiveFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(fileInfo.FullName); destinationActiveFile.DecryptedFileInfo.Delete(); destinationActiveFile = new ActiveFile(destinationActiveFile, ActiveFileStatus.NotDecrypted); Resolve.FileSystemState.Add(destinationActiveFile); await Resolve.FileSystemState.Save(); status = await fileOperation.OpenAndLaunchApplication(keys, dataStore, new ProgressContext()); Assert.That(status.ErrorStatus, Is.EqualTo(ErrorStatus.Success), "The launch should once again succeed."); }
private void UpdateOneItem(Dictionary <string, int> currentFiles, ActiveFile file) { string text = Path.GetFileName(file.DecryptedFileInfo.FullName); ListViewItem item = new ListViewItem(text); item.UseItemStyleForSubItems = false; item.Name = file.EncryptedFileInfo.FullName; ListViewItem.ListViewSubItem accessedDateColumn = item.SubItems.Add(String.Empty); accessedDateColumn.Name = nameof(ColumnName.AccessedDate); ListViewItem.ListViewSubItem encryptedPathColumn = item.SubItems.Add(String.Empty); encryptedPathColumn.Name = nameof(ColumnName.EncryptedPath); ListViewItem.ListViewSubItem modifiedDateColumn = item.SubItems.Add(String.Empty); modifiedDateColumn.Name = nameof(ColumnName.ModifiedDate); ListViewItem.ListViewSubItem cryptoNameColumn = item.SubItems.Add(String.Empty); cryptoNameColumn.Name = nameof(ColumnName.CryptoName); UpdateListViewItem(item, file); int i; if (!currentFiles.TryGetValue(item.Name, out i)) { Items.Add(item); return; } if (!CompareRecentFileItem(item, Items[i])) { Items[i] = item; } }
private static Task ChangeEncryptionAsync(IEnumerable <string> files, EncryptionParameters encryptionParameters) { return(Resolve.ParallelFileOperation.DoFilesAsync(files.Select(f => New <IDataStore>(f)), async(IDataStore file, IProgressContext progress) => { ActiveFile activeFile = New <FileSystemState>().FindActiveFileFromEncryptedPath(file.FullName); LogOnIdentity decryptIdentity = activeFile?.Identity ?? New <KnownIdentities>().DefaultEncryptionIdentity; await New <AxCryptFile>().ChangeEncryptionAsync(file, decryptIdentity, encryptionParameters, progress); if (activeFile != null) { New <FileSystemState>().Add(new ActiveFile(activeFile, encryptionParameters.CryptoId, New <KnownIdentities>().DefaultEncryptionIdentity)); await New <FileSystemState>().Save(); } return new FileOperationContext(file.FullName, ErrorStatus.Success); }, async(FileOperationContext foc) => { if (foc.ErrorStatus != ErrorStatus.Success) { New <IStatusChecker>().CheckStatusAndShowMessage(foc.ErrorStatus, foc.FullName, foc.InternalMessage); return; } await Resolve.SessionNotify.NotifyAsync(new SessionNotification(SessionNotificationType.ActiveFileChange, files)); })); }
private Task <bool> WipeFileOperationAsync() { if (_eventArgs.Skip) { _eventArgs.Status = new FileOperationContext(String.Empty, ErrorStatus.Success); return(Constant.TrueTask); } ActiveFile activeFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(_eventArgs.SaveFileFullName); if (activeFile != null && activeFile.Status.HasFlag(ActiveFileStatus.AssumedOpenAndDecrypted)) { _eventArgs.Status = new FileOperationContext(_eventArgs.OpenFileFullName, ErrorStatus.FileLocked); return(Constant.FalseTask); } _progress.NotifyLevelStart(); try { using (FileLock wipeFileLock = New <FileLocker>().Acquire(New <IDataStore>(_eventArgs.SaveFileFullName))) { New <AxCryptFile>().Wipe(wipeFileLock, _progress); } } finally { _progress.NotifyLevelFinished(); } _eventArgs.Status = new FileOperationContext(String.Empty, ErrorStatus.Success); return(Constant.TrueTask); }
public void TestConstructor() { LogOnIdentity key = new LogOnIdentity("key"); IDataStore decryptedFileInfo = New <IDataStore>(_testTextPath); IDataStore encryptedFileInfo = New <IDataStore>(_helloWorldAxxPath); ActiveFile activeFile = new ActiveFile(encryptedFileInfo, decryptedFileInfo, key, ActiveFileStatus.None, new V1Aes128CryptoFactory().CryptoId); decryptedFileInfo = activeFile.DecryptedFileInfo; Assert.That(decryptedFileInfo.IsAvailable, Is.True, "The file should exist in the fake file system."); Assert.That(decryptedFileInfo.FullName, Is.EqualTo(_testTextPath), "The file should be named as it was in the constructor"); Assert.That(decryptedFileInfo.LastWriteTimeUtc, Is.EqualTo(decryptedFileInfo.LastWriteTimeUtc), "When a LastWriteTime is not specified, the decrypted file should be used to determine the value."); ((FakeNow)New <INow>()).TimeFunction = (() => { return(DateTime.UtcNow.AddMinutes(1)); }); ActiveFile otherFile = new ActiveFile(activeFile, ActiveFileStatus.AssumedOpenAndDecrypted); Assert.That(otherFile.Status, Is.EqualTo(ActiveFileStatus.AssumedOpenAndDecrypted), "The status should be as given in the constructor."); Assert.That(otherFile.DecryptedFileInfo.FullName, Is.EqualTo(activeFile.DecryptedFileInfo.FullName), "This should be copied from the original instance."); Assert.That(otherFile.EncryptedFileInfo.FullName, Is.EqualTo(activeFile.EncryptedFileInfo.FullName), "This should be copied from the original instance."); Assert.That(otherFile.Identity, Is.EqualTo(activeFile.Identity), "This should be copied from the original instance."); Assert.That(otherFile.Properties.LastActivityTimeUtc, Is.GreaterThan(activeFile.Properties.LastActivityTimeUtc), "This should not be copied from the original instance, but should be a later time."); Assert.That(otherFile.ThumbprintMatch(activeFile.Identity.Passphrase), Is.True, "The thumbprints should match."); activeFile.DecryptedFileInfo.LastWriteTimeUtc = activeFile.DecryptedFileInfo.LastWriteTimeUtc.AddDays(1); otherFile = new ActiveFile(activeFile, New <INow>().Utc, ActiveFileStatus.AssumedOpenAndDecrypted); Assert.That(activeFile.IsModified, Is.True, "The original instance has not been encrypted since the last change."); Assert.That(otherFile.IsModified, Is.False, "The copy indicates that it has been encrypted and thus is not modified."); }
public void TestVisualStateHiEncryption() { ActiveFile activeFile; LogOnIdentity key = new LogOnIdentity("key"); activeFile = new ActiveFile(New <IDataStore>(@"C:\encrypted.axx"), New <IDataStore>(@"C:\decrypted.txt"), key, ActiveFileStatus.NotDecrypted, new V2Aes256CryptoFactory().CryptoId); Assert.That(activeFile.VisualState, Is.EqualTo(ActiveFileVisualStates.EncryptedWithKnownKey)); activeFile = new ActiveFile(activeFile); Assert.That(activeFile.VisualState, Is.EqualTo(ActiveFileVisualStates.EncryptedWithoutKnownKey)); activeFile = new ActiveFile(activeFile, ActiveFileStatus.DecryptedIsPendingDelete); Assert.That(activeFile.VisualState, Is.EqualTo(ActiveFileVisualStates.DecryptedWithoutKnownKey)); activeFile = new ActiveFile(activeFile, key); Assert.That(activeFile.VisualState, Is.EqualTo(ActiveFileVisualStates.DecryptedWithKnownKey)); activeFile = new ActiveFile(activeFile, ActiveFileStatus.AssumedOpenAndDecrypted); Assert.That(activeFile.VisualState, Is.EqualTo(ActiveFileVisualStates.DecryptedWithKnownKey)); activeFile = new ActiveFile(activeFile); Assert.That(activeFile.VisualState, Is.EqualTo(ActiveFileVisualStates.DecryptedWithoutKnownKey)); activeFile = new ActiveFile(activeFile, ActiveFileStatus.Error); Assert.Throws <InvalidOperationException>(() => { if (activeFile.VisualState == ActiveFileVisualStates.None) { } }); }
public static void TestPurgeActiveFilesWhenFileIsModified() { DateTime utcNow = OS.Current.UtcNow; FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, Stream.Null); FakeRuntimeFileInfo.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); IRuntimeFileInfo encryptedFileInfo = OS.Current.FileInfo(_encryptedFile1); IRuntimeFileInfo decryptedFileInfo = OS.Current.FileInfo(_decryptedFile1); ActiveFile activeFile = new ActiveFile(encryptedFileInfo, decryptedFileInfo, new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.NotShareable, null); _fileSystemState.Add(activeFile); SetupAssembly.FakeRuntimeEnvironment.TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); DateTime utcLater = OS.Current.UtcNow; decryptedFileInfo.SetFileTimes(utcLater, utcLater, utcLater); bool changedWasRaised = false; _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); _fileSystemState.PurgeActiveFiles(new ProgressContext()); activeFile = _fileSystemState.FindEncryptedPath(_encryptedFile1); 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."); }
private void InitializePropertyValues() { WatchedFoldersEnabled = false; WatchedFolders = new string[0]; DragAndDropFiles = new string[0]; RecentFiles = new ActiveFile[0]; SelectedRecentFiles = new string[0]; SelectedWatchedFolders = new string[0]; DecryptedFiles = new ActiveFile[0]; DebugMode = _userSettings.DebugMode; FolderOperationMode = _userSettings.FolderOperationMode; DownloadVersion = DownloadVersion.Empty; VersionUpdateStatus = DownloadVersion.CalculateStatus(New <IVersion>().Current, New <INow>().Utc, _userSettings.LastUpdateCheckUtc); License = New <LicensePolicy>().Capabilities; EncryptionUpgradeMode = _userSettings.EncryptionUpgradeMode; AddWatchedFolders = new AsyncDelegateAction <IEnumerable <string> >((folders) => AddWatchedFoldersActionAsync(folders), (folders) => Task.FromResult(LoggedOn)); RemoveRecentFiles = new AsyncDelegateAction <IEnumerable <string> >((files) => RemoveRecentFilesAction(files)); EncryptPendingFiles = new AsyncDelegateAction <object>((parameter) => EncryptPendingFilesAction()); ClearPassphraseMemory = new AsyncDelegateAction <object>((parameter) => ClearPassphraseMemoryAction()); DecryptWatchedFolders = new AsyncDelegateAction <IEnumerable <string> >((folders) => DecryptWatchedFoldersAction(folders), (folders) => Task.FromResult(LoggedOn)); OpenSelectedFolder = new DelegateAction <string>((folder) => OpenSelectedFolderAction(folder)); AxCryptUpdateCheck = new AsyncDelegateAction <DateTime>((utc) => AxCryptUpdateCheckAction(utc)); LicenseUpdate = new DelegateAction <object>((o) => License = New <LicensePolicy>().Capabilities); RemoveWatchedFolders = new AsyncDelegateAction <IEnumerable <string> >((folders) => RemoveWatchedFoldersAction(folders), (folders) => Task.FromResult(LoggedOn)); WarnIfAnyDecryptedFiles = new AsyncDelegateAction <object>((o) => WarnIfAnyDecryptedFilesActionAsync()); DecryptFileEnabled = true; OpenEncryptedEnabled = true; RandomRenameEnabled = true; }
public static void TestCheckProcessExitedWhenExited() { DateTime utcNow = OS.Current.UtcNow; FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, Stream.Null); FakeRuntimeFileInfo.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); FakeLauncher fakeLauncher = new FakeLauncher(_decryptedFile1); ActiveFile activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.NotShareable, fakeLauncher); _fileSystemState.Add(activeFile); SetupAssembly.FakeRuntimeEnvironment.TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); SetupAssembly.FakeRuntimeEnvironment.Platform = Platform.WindowsDesktop; fakeLauncher.HasExited = true; _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); activeFile = _fileSystemState.FindEncryptedPath(_encryptedFile1); 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 static void TestPurgeActiveFilesWhenFileIsLocked() { DateTime utcNow = OS.Current.UtcNow; FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, Stream.Null); FakeRuntimeFileInfo.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); IRuntimeFileInfo encryptedFileInfo = OS.Current.FileInfo(_encryptedFile1); IRuntimeFileInfo decryptedFileInfo = OS.Current.FileInfo(_decryptedFile1); ActiveFile activeFile = new ActiveFile(encryptedFileInfo, decryptedFileInfo, new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted, null); _fileSystemState.Add(activeFile); bool changedWasRaised = false; _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); using (FileLock fileLock = FileLock.Lock(decryptedFileInfo)) { _fileSystemState.PurgeActiveFiles(new ProgressContext()); } Assert.That(changedWasRaised, Is.False, "A changed event should not be raised because the decrypted file is locked."); }
public static void TestCheckActiveFilesNotDecryptedAndDoesNotExist() { DateTime utcNow = OS.Current.UtcNow; FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, Stream.Null); FakeRuntimeFileInfo.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); ActiveFile activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted, null); OS.Current.FileInfo(_decryptedFile1).Delete(); activeFile = new ActiveFile(activeFile, ActiveFileStatus.NotDecrypted, null); _fileSystemState.Add(activeFile); bool changedWasRaised = false; _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); SetupAssembly.FakeRuntimeEnvironment.TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); Assert.That(changedWasRaised, Is.False, "The ActiveFile should be not be modified because it's already deleted."); }
public static void TestCheckActiveFilesNoDeleteWhenNotDesktopWindows() { DateTime utcNow = OS.Current.UtcNow; FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, Stream.Null); FakeRuntimeFileInfo.AddFile(_decryptedFile1, utcNow, utcNow, utcNow, Stream.Null); ActiveFile activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted, null); _fileSystemState.Add(activeFile); SetupAssembly.FakeRuntimeEnvironment.TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); SetupAssembly.FakeRuntimeEnvironment.Platform = Platform.Unknown; _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); Assert.That(changedWasRaised, Is.False, "No change should be raised when the file is not modified and not Desktop Windows."); activeFile = _fileSystemState.FindEncryptedPath(_encryptedFile1); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.AssumedOpenAndDecrypted), Is.True, "Nothing should happen with the file when not running as Desktop Windows."); SetupAssembly.FakeRuntimeEnvironment.Platform = Platform.WindowsDesktop; changedWasRaised = false; _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); Assert.That(changedWasRaised, Is.True, "Since the file should be deleted because running as Desktop Windows the changed event should be raised."); activeFile = _fileSystemState.FindEncryptedPath(_encryptedFile1); Assert.That(activeFile.Status.HasMask(ActiveFileStatus.NotDecrypted), Is.True, "The file should be deleted and marked as Not Decrypted when running as Desktop Windows."); }
public static void TestCheckActiveFilesKeyIsSet() { DateTime utcNow = OS.Current.UtcNow; DateTime utcJustNow = utcNow.AddMinutes(-1); FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, Stream.Null); FakeRuntimeFileInfo.AddFile(_decryptedFile1, utcJustNow, utcJustNow, utcJustNow, Stream.Null); ActiveFile activeFile; activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted, null); _fileSystemState.Add(activeFile); IRuntimeFileInfo decryptedFileInfo = OS.Current.FileInfo(_decryptedFile1); decryptedFileInfo.SetFileTimes(utcNow, utcNow, utcNow); SetupAssembly.FakeRuntimeEnvironment.TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, 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 = _fileSystemState.FindEncryptedPath(_encryptedFile1); 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 static void TestCheckActiveFilesIsLocked() { DateTime utcNow = OS.Current.UtcNow; DateTime utcYesterday = utcNow.AddDays(-1); FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, Stream.Null); FakeRuntimeFileInfo.AddFile(_decryptedFile1, utcYesterday, utcYesterday, utcYesterday, Stream.Null); ActiveFile activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), new AesKey(), ActiveFileStatus.NotDecrypted, null); SetupAssembly.FakeRuntimeEnvironment.TimeFunction = (() => { return(utcNow.AddMinutes(10)); }); bool changedWasRaised = false; _fileSystemState.Add(activeFile); _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); using (FileLock fileLock = FileLock.Lock(activeFile.EncryptedFileInfo)) { _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); } Assert.That(changedWasRaised, Is.False, "The file should be not be detected as decrypted being created because the encrypted file is locked."); using (FileLock fileLock = FileLock.Lock(activeFile.DecryptedFileInfo)) { _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); } Assert.That(changedWasRaised, Is.False, "The file should be not be detected as decrypted being created because the decrypted file is locked."); }
public static bool IsDisplayEquivalentTo(this ActiveFile left, ActiveFile right) { if (object.ReferenceEquals(left, right)) { return(true); } if (left.Properties != right.Properties) { return(false); } if (left.Status != right.Status) { return(false); } if (left.DecryptedFileInfo.FullName != right.DecryptedFileInfo.FullName) { return(false); } if (left.EncryptedFileInfo.FullName != right.EncryptedFileInfo.FullName) { return(false); } if (left.IsShared != right.IsShared) { return(false); } return(true); }
public async Task TestFileAlreadyDecryptedButWithUnknownKey() { IDataStore dataStore = New <IDataStore>(_helloWorldAxxPath); TypeMap.Register.New <ILauncher>(() => new FakeLauncher()); IEnumerable <LogOnIdentity> keys = new LogOnIdentity[] { new LogOnIdentity("a") }; DateTime utcNow = DateTime.UtcNow; ((FakeNow)New <INow>()).TimeFunction = () => { return(utcNow); }; FileOperation fileOperation = new FileOperation(Resolve.FileSystemState, new SessionNotify()); FileOperationContext status = await fileOperation.OpenAndLaunchApplication(keys, dataStore, new ProgressContext()); Assert.That(status.ErrorStatus, Is.EqualTo(ErrorStatus.Success), "The launch should succeed."); ActiveFile destinationActiveFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(dataStore.FullName); Assert.That(destinationActiveFile.DecryptedFileInfo.LastWriteTimeUtc, Is.Not.EqualTo(utcNow), "The decryption should restore the time stamp of the original file, and this is not now."); destinationActiveFile.DecryptedFileInfo.SetFileTimes(utcNow, utcNow, utcNow); IEnumerable <LogOnIdentity> badKeys = new LogOnIdentity[] { new LogOnIdentity("b") }; status = await fileOperation.OpenAndLaunchApplication(badKeys, dataStore, new ProgressContext()); Assert.That(status.ErrorStatus, Is.EqualTo(ErrorStatus.InvalidKey), "The launch should fail this time, since the key is not known."); destinationActiveFile = Resolve.FileSystemState.FindActiveFileFromEncryptedPath(dataStore.FullName); Assert.That(destinationActiveFile.DecryptedFileInfo.LastWriteTimeUtc, Is.EqualTo(utcNow), "There should be no decryption, and thus the time stamp should be as just set."); }
public virtual async Task <FileOperationContext> OpenAndLaunchApplication(IEnumerable <LogOnIdentity> identities, IDataStore encryptedDataStore, IProgressContext progress) { if (identities == null) { throw new ArgumentNullException(nameof(identities)); } if (encryptedDataStore == null) { throw new ArgumentNullException(nameof(encryptedDataStore)); } if (progress == null) { throw new ArgumentNullException(nameof(progress)); } if (!encryptedDataStore.IsAvailable) { if (Resolve.Log.IsWarningEnabled) { Resolve.Log.LogWarning("Tried to open non-existing '{0}'.".InvariantFormat(encryptedDataStore.FullName)); } return(new FileOperationContext(encryptedDataStore.FullName, ErrorStatus.FileDoesNotExist)); } ActiveFile activeFile = _fileSystemState.FindActiveFileFromEncryptedPath(encryptedDataStore.FullName); if (activeFile == null || !activeFile.DecryptedFileInfo.IsAvailable) { activeFile = TryDecryptToActiveFile(encryptedDataStore, identities); } else { activeFile = CheckKeysForAlreadyDecryptedFile(activeFile, identities, progress); } if (activeFile == null) { return(new FileOperationContext(encryptedDataStore.FullName, ErrorStatus.InvalidKey)); } using (FileLock destinationLock = New <FileLocker>().Acquire(activeFile.DecryptedFileInfo)) { if (!activeFile.DecryptedFileInfo.IsAvailable) { activeFile = Decrypt(activeFile.Identity, activeFile.EncryptedFileInfo, destinationLock, activeFile, progress); } _fileSystemState.Add(activeFile); await _fileSystemState.Save(); if (encryptedDataStore.IsWriteProtected || !New <LicensePolicy>().Capabilities.Has(LicenseCapability.EditExistingFiles)) { activeFile.DecryptedFileInfo.IsWriteProtected = true; } FileOperationContext status = await LaunchApplicationForDocument(activeFile, destinationLock); return(status); } }
private void EncryptFile(string file, IThreadWorker worker, ProgressContext progress) { FileOperationsController operationsController = new FileOperationsController(persistentState.Current, progress); operationsController.QuerySaveFileAs += (object sender, FileOperationEventArgs e) => { using (SaveFileDialog sfd = new SaveFileDialog()) { sfd.Title = Resources.EncryptFileSaveAsDialogTitle; sfd.AddExtension = true; sfd.ValidateNames = true; sfd.CheckPathExists = true; sfd.DefaultExt = OS.Current.AxCryptExtension; sfd.FileName = e.SaveFileFullName; sfd.Filter = Resources.EncryptedFileDialogFilterPattern.InvariantFormat(OS.Current.AxCryptExtension); sfd.InitialDirectory = Path.GetDirectoryName(e.SaveFileFullName); sfd.ValidateNames = true; DialogResult saveAsResult = sfd.ShowDialog(); if (saveAsResult != DialogResult.OK) { e.Cancel = true; return; } e.SaveFileFullName = sfd.FileName; } }; operationsController.QueryEncryptionPassphrase += (object sender, FileOperationEventArgs e) => { string passphrase = AskForEncryptionPassphrase(); if (String.IsNullOrEmpty(passphrase)) { e.Cancel = true; return; } e.Passphrase = passphrase; AesKey defaultEncryptionKey = new Passphrase(e.Passphrase).DerivedPassphrase; persistentState.Current.KnownKeys.DefaultEncryptionKey = defaultEncryptionKey; }; operationsController.Completed += (object sender, FileOperationEventArgs e) => { if (e.Status == FileOperationStatus.FileAlreadyEncrypted) { e.Status = FileOperationStatus.Success; return; } if (CheckStatusAndShowMessage(e.Status, e.OpenFileFullName)) { IRuntimeFileInfo encryptedInfo = OS.Current.FileInfo(e.SaveFileFullName); IRuntimeFileInfo decryptedInfo = OS.Current.FileInfo(FileOperation.GetTemporaryDestinationName(e.OpenFileFullName)); ActiveFile activeFile = new ActiveFile(encryptedInfo, decryptedInfo, e.Key, ActiveFileStatus.NotDecrypted, null); persistentState.Current.Add(activeFile); persistentState.Current.Save(); } }; operationsController.EncryptFile(file, worker); }