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 async Task AddWatchedFoldersAction(IEnumerable <string> folders) { if (!folders.Any()) { return; } foreach (string folder in folders) { await _fileSystemState.AddWatchedFolderAsync(new WatchedFolder(folder, Resolve.KnownIdentities.DefaultEncryptionIdentity.Tag)); } await _fileSystemState.Save(); }
private async Task HandleSessionChangedInternalAsync(SessionNotification notification) { switch (notification.NotificationType) { case SessionNotificationType.WatchedFolderAdded: await SetWatchedFoldersAsync(); break; case SessionNotificationType.WatchedFolderRemoved: await SetWatchedFoldersAsync(); break; case SessionNotificationType.SignIn: case SessionNotificationType.SignOut: LoggedOn = Resolve.KnownIdentities.IsLoggedOn; break; case SessionNotificationType.WatchedFolderChange: FilesArePending = AreFilesPending(); break; case SessionNotificationType.KnownKeyChange: if (notification.Identity == LogOnIdentity.Empty) { throw new InvalidOperationException("Attempt to add the empty identity as a known key."); } if (!_fileSystemState.KnownPassphrases.Any(p => p.Thumbprint == notification.Identity.Passphrase.Thumbprint)) { _fileSystemState.KnownPassphrases.Add(notification.Identity.Passphrase); await _fileSystemState.Save(); } break; case SessionNotificationType.SessionStart: case SessionNotificationType.ActiveFileChange: FilesArePending = AreFilesPending(); SetRecentFiles(); break; case SessionNotificationType.LicensePolicyChanged: LicenseUpdate.Execute(null); break; case SessionNotificationType.WorkFolderChange: case SessionNotificationType.ProcessExit: case SessionNotificationType.SessionChange: default: break; } }
public static void TestWatchedFolders() { using (FileSystemState state = new FileSystemState()) { IRuntimeFileInfo stateInfo = OS.Current.FileInfo(_mystateXmlPath); state.Load(stateInfo); Assert.That(state.WatchedFolders, Is.Not.Null, "There should be a Watched Folders instance."); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(0), "There should be no Watched folders."); state.AddWatchedFolder(new WatchedFolder(_rootPath)); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(1), "There should be one Watched Folder."); state.AddWatchedFolder(new WatchedFolder(_rootPath)); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(1), "There should still only be one Watched Folder."); state.Save(); } using (FileSystemState state = new FileSystemState()) { IRuntimeFileInfo stateInfo = OS.Current.FileInfo(_mystateXmlPath); state.Load(stateInfo); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(1), "There should be one Watched Folder."); Assert.That(state.WatchedFolders.First(), Is.EqualTo(new WatchedFolder(_rootPath)), "The Watched Folder should be equal to this."); state.RemoveWatchedFolder(new WatchedFolder(_mystateXmlPath)); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(1), "There should still be one Watched folders."); state.RemoveWatchedFolder(new WatchedFolder(_rootPath)); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(0), "There should still be no Watched folders now."); } }
public async Task TestWatchedFolders() { using (FileSystemState state = FileSystemState.Create(Resolve.WorkFolder.FileInfo.FileItemInfo("mystate.txt"))) { Assert.That(state.WatchedFolders, Is.Not.Null, "There should be a Watched Folders instance."); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(0), "There should be no Watched folders."); FakeDataStore.AddFolder(_rootPath); await state.AddWatchedFolderAsync(new WatchedFolder(_rootPath, IdentityPublicTag.Empty)); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(1), "There should be one Watched Folder."); await state.AddWatchedFolderAsync(new WatchedFolder(_rootPath, IdentityPublicTag.Empty)); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(1), "There should still only be one Watched Folder."); await state.Save(); } using (FileSystemState state = FileSystemState.Create(Resolve.WorkFolder.FileInfo.FileItemInfo("mystate.txt"))) { Assert.That(state.WatchedFolders.Count(), Is.EqualTo(1), "There should be one Watched Folder."); Assert.That(state.WatchedFolders.First().Matches(_rootPath), "The Watched Folder should be equal to this."); await state.RemoveAndDecryptWatchedFolder(Resolve.WorkFolder.FileInfo.FolderItemInfo("mystate.txt")); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(1), "There should still be one Watched folders."); await state.RemoveAndDecryptWatchedFolder(New <IDataContainer>(_rootPath)); Assert.That(state.WatchedFolders.Count(), Is.EqualTo(0), "There should be no Watched folders now."); } }
public static FileOperationStatus OpenAndLaunchApplication(this FileSystemState fileSystemState, string file, IEnumerable <AesKey> keys, ProgressContext progress) { if (fileSystemState == null) { throw new ArgumentNullException("fileSystemState"); } if (file == null) { throw new ArgumentNullException("file"); } if (keys == null) { throw new ArgumentNullException("keys"); } if (progress == null) { throw new ArgumentNullException("progress"); } IRuntimeFileInfo fileInfo = OS.Current.FileInfo(file); if (!fileInfo.Exists) { if (OS.Log.IsWarningEnabled) { OS.Log.LogWarning("Tried to open non-existing '{0}'.".InvariantFormat(fileInfo.FullName)); } return(FileOperationStatus.FileDoesNotExist); } ActiveFile destinationActiveFile = fileSystemState.FindEncryptedPath(fileInfo.FullName); if (destinationActiveFile == null || !destinationActiveFile.DecryptedFileInfo.Exists) { IRuntimeFileInfo destinationFolderInfo = GetTemporaryDestinationFolder(destinationActiveFile); destinationActiveFile = TryDecrypt(fileInfo, destinationFolderInfo, keys, progress); } else { destinationActiveFile = CheckKeysForAlreadyDecryptedFile(destinationActiveFile, keys, progress); } if (destinationActiveFile == null) { return(FileOperationStatus.InvalidKey); } fileSystemState.Add(destinationActiveFile); fileSystemState.Save(); FileOperationStatus status = LaunchApplicationForDocument(fileSystemState, destinationActiveFile); return(status); }
private static FileOperationStatus LaunchApplicationForDocument(FileSystemState fileSystemState, ActiveFile destinationActiveFile) { ILauncher process; try { if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Starting process for '{0}'".InvariantFormat(destinationActiveFile.DecryptedFileInfo.FullName)); } process = OS.Current.Launch(destinationActiveFile.DecryptedFileInfo.FullName); if (process.WasStarted) { process.Exited += new EventHandler(process_Exited); } else { if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Starting process for '{0}' did not start a process, assumed handled by the shell.".InvariantFormat(destinationActiveFile.DecryptedFileInfo.FullName)); } } } catch (Win32Exception w32ex) { if (OS.Log.IsErrorEnabled) { OS.Log.LogError("Could not launch application for '{0}', Win32Exception was '{1}'.".InvariantFormat(destinationActiveFile.DecryptedFileInfo.FullName, w32ex.Message)); } return(FileOperationStatus.CannotStartApplication); } if (OS.Log.IsWarningEnabled) { if (process.HasExited) { OS.Log.LogWarning("The process seems to exit immediately for '{0}'".InvariantFormat(destinationActiveFile.DecryptedFileInfo.FullName)); } } if (OS.Log.IsInfoEnabled) { OS.Log.LogInfo("Launched and opened '{0}'.".InvariantFormat(destinationActiveFile.DecryptedFileInfo.FullName)); } destinationActiveFile = new ActiveFile(destinationActiveFile, ActiveFileStatus.AssumedOpenAndDecrypted, process); fileSystemState.Add(destinationActiveFile); fileSystemState.Save(); return(FileOperationStatus.Success); }
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 static void TestStatusMaskAtLoad() { using (FileSystemState state = new FileSystemState()) { state.Load(OS.Current.FileInfo(_mystateXmlPath)); ActiveFile activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedAxxPath), OS.Current.FileInfo(_decryptedTxtPath), new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted | ActiveFileStatus.Error | ActiveFileStatus.IgnoreChange | ActiveFileStatus.NotShareable, null); state.Add(activeFile); state.Save(); FileSystemState reloadedState = new FileSystemState(); reloadedState.Load(OS.Current.FileInfo(_mystateXmlPath)); 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), "When reloading saved state, some statuses should be masked away."); } }
public static void TestFileContainedByActiveFilesButNotDecrypted() { IEnumerable <AesKey> keys = new AesKey[] { new Passphrase("a").DerivedPassphrase }; FileOperationStatus status = _fileSystemState.OpenAndLaunchApplication(_helloWorldAxxPath, keys, new ProgressContext()); Assert.That(status, Is.EqualTo(FileOperationStatus.Success), "The launch should succeed."); IRuntimeFileInfo fileInfo = OS.Current.FileInfo(_helloWorldAxxPath); ActiveFile destinationActiveFile = _fileSystemState.FindEncryptedPath(fileInfo.FullName); destinationActiveFile.DecryptedFileInfo.Delete(); destinationActiveFile = new ActiveFile(destinationActiveFile, ActiveFileStatus.NotDecrypted); _fileSystemState.Add(destinationActiveFile); _fileSystemState.Save(); status = _fileSystemState.OpenAndLaunchApplication(_helloWorldAxxPath, keys, new ProgressContext()); Assert.That(status, Is.EqualTo(FileOperationStatus.Success), "The launch should once again succeed."); }
public async Task TestLoadExistingWithNonExistingFile() { ActiveFile activeFile; using (FileSystemState state = FileSystemState.Create(Resolve.WorkFolder.FileInfo.FileItemInfo("mystate.txt"))) { Assert.That(state, Is.Not.Null, "An instance should always be instantiated."); Assert.That(state.ActiveFiles.Count(), Is.EqualTo(0), "A new state should not have any active files."); activeFile = new ActiveFile(New <IDataStore>(_encryptedAxxPath), New <IDataStore>(_decryptedTxtPath), new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); state.Add(activeFile); await state.Save(); } using (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(0), "The reloaded state should not have an active file, since it is non-existing."); } }
private async Task EnsureKnownFoldersWatched(IEnumerable <KnownFolder> folders) { foreach (KnownFolder knownFolder in folders) { if (_fileSystemState.AllWatchedFolders.Any((wf) => wf.Path == knownFolder.My.FullName)) { continue; } if (knownFolder.My.IsFile) { continue; } if (!knownFolder.My.IsAvailable) { knownFolder.Folder.CreateFolder(knownFolder.My.Name); } await _fileSystemState.AddWatchedFolderAsync(new WatchedFolder(knownFolder.My.FullName, _knownIdentities.DefaultEncryptionIdentity.Tag)); } await _fileSystemState.Save(); }
public static FileOperationStatus OpenAndLaunchApplication(this FileSystemState fileSystemState, string file, AxCryptDocument document, ProgressContext progress) { if (fileSystemState == null) { throw new ArgumentNullException("fileSystemState"); } if (file == null) { throw new ArgumentNullException("file"); } if (document == null) { throw new ArgumentNullException("document"); } if (progress == null) { throw new ArgumentNullException("progress"); } IRuntimeFileInfo fileInfo = OS.Current.FileInfo(file); ActiveFile destinationActiveFile = fileSystemState.FindEncryptedPath(fileInfo.FullName); if (destinationActiveFile == null || !destinationActiveFile.DecryptedFileInfo.Exists) { IRuntimeFileInfo destinationFolderInfo = GetTemporaryDestinationFolder(destinationActiveFile); destinationActiveFile = DecryptActiveFileDocument(fileInfo, destinationFolderInfo, document, progress); } else { destinationActiveFile = new ActiveFile(destinationActiveFile, document.DocumentHeaders.KeyEncryptingKey); } fileSystemState.Add(destinationActiveFile); fileSystemState.Save(); FileOperationStatus status = LaunchApplicationForDocument(fileSystemState, destinationActiveFile); return(status); }
private async Task <LogOnIdentity> AddKnownIdentityFromEventAsync(LogOnEventArgs logOnArgs) { if (logOnArgs.Cancel || logOnArgs.Passphrase == Passphrase.Empty) { return(LogOnIdentity.Empty); } _userSettings.DisplayEncryptPassphrase = logOnArgs.DisplayPassphrase; Passphrase passphrase = logOnArgs.Passphrase; LogOnIdentity identity = await LogOnIdentityFromCredentialsAsync(EmailAddress.Parse(logOnArgs.UserEmail), passphrase); if (identity == LogOnIdentity.Empty) { identity = new LogOnIdentity(passphrase); _fileSystemState.KnownPassphrases.Add(passphrase); await _fileSystemState.Save(); } await _knownIdentities.AddAsync(identity); return(identity); }
public async Task TestLoadExistingWithExistingFile() { ActiveFile activeFile; using (FileSystemState state = FileSystemState.Create(Resolve.WorkFolder.FileInfo.FileItemInfo("mystate.txt"))) { Assert.That(state, Is.Not.Null, "An instance should always be instantiated."); Assert.That(state.ActiveFiles.Count(), Is.EqualTo(0), "A new state should not have any active files."); activeFile = new ActiveFile(New <IDataStore>(_encryptedAxxPath), New <IDataStore>(_decryptedTxtPath), new LogOnIdentity("passphrase"), ActiveFileStatus.AssumedOpenAndDecrypted, new V1Aes128CryptoFactory().CryptoId); state.Add(activeFile); await state.Save(); } FakeDataStore.AddFile(_encryptedAxxPath, FakeDataStore.TestDate1Utc, FakeDataStore.TestDate2Utc, FakeDataStore.TestDate3Utc, Stream.Null); using (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().ThumbprintMatch(activeFile.Identity.Passphrase), Is.True, "The reloaded thumbprint should match the key."); } }
public static void TestLoadExisting() { ActiveFile activeFile; using (FileSystemState state = new FileSystemState()) { state.Load(OS.Current.FileInfo(_mystateXmlPath)); Assert.That(state, Is.Not.Null, "An instance should always be instantiated."); Assert.That(state.ActiveFiles.Count(), Is.EqualTo(0), "A new state should not have any active files."); activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedAxxPath), OS.Current.FileInfo(_decryptedTxtPath), new AesKey(), ActiveFileStatus.AssumedOpenAndDecrypted, null); state.Add(activeFile); state.Save(); } using (FileSystemState reloadedState = new FileSystemState()) { reloadedState.Load(OS.Current.FileInfo(_mystateXmlPath)); 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().ThumbprintMatch(activeFile.Key), Is.True, "The reloaded thumbprint should match the key."); } }
public static void TestCheckActiveFilesKeyIsNotSetWithKnownKey() { DateTime utcNow = OS.Current.UtcNow; FakeRuntimeFileInfo.AddFile(_encryptedFile1, utcNow, utcNow, utcNow, FakeRuntimeFileInfo.ExpandableMemoryStream(Resources.helloworld_key_a_txt)); Passphrase passphrase = new Passphrase("a"); AxCryptFile.Decrypt(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), passphrase.DerivedPassphrase, AxCryptOptions.None, new ProgressContext()); ActiveFile activeFile = new ActiveFile(OS.Current.FileInfo(_encryptedFile1), OS.Current.FileInfo(_decryptedFile1), passphrase.DerivedPassphrase, ActiveFileStatus.AssumedOpenAndDecrypted, null); _fileSystemState.Add(activeFile); _fileSystemState.Save(); _fileSystemState.Dispose(); _fileSystemState = new FileSystemState(); _fileSystemState.Load(OS.Current.FileInfo(_fileSystemStateFilePath)); SetupAssembly.FakeRuntimeEnvironment.TimeFunction = (() => { return(utcNow.AddMinutes(1)); }); bool changedWasRaised = false; _fileSystemState.Changed += ((object sender, ActiveFileChangedEventArgs e) => { changedWasRaised = true; }); activeFile = _fileSystemState.FindEncryptedPath(_encryptedFile1); Assert.That(activeFile.Key, Is.Null, "The key should be null after loading of new FileSystemState"); _fileSystemState.KnownKeys.Add(passphrase.DerivedPassphrase); _fileSystemState.CheckActiveFiles(ChangedEventMode.RaiseOnlyOnModified, new ProgressContext()); Assert.That(changedWasRaised, Is.True, "The ActiveFile should be modified because there is now a known key."); activeFile = _fileSystemState.FindEncryptedPath(_encryptedFile1); Assert.That(activeFile.Key, Is.Not.Null, "The key should not be null after the checking of active files."); }
private async Task OpenFilesActionAsync(IEnumerable <string> files) { await _fileOperation.DoFilesAsync(files.Select(f => New <IDataStore>(f)).ToList(), OpenEncryptedWorkAsync, (status) => Task.FromResult(CheckStatusAndShowMessage(status, string.Empty))); await _fileSystemState.Save(); }