Beispiel #1
0
        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);
            }
        }
Beispiel #2
0
 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;
            }
        }
Beispiel #4
0
        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.");
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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.");
            }
        }
Beispiel #9
0
        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();
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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.");
            }
        }
Beispiel #16
0
        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.");
            }
        }
Beispiel #17
0
        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();
        }