diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..3dc90b4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Change Log + +## dangerzone 0.1 + +- First release \ No newline at end of file diff --git a/README.md b/README.md index 7b31239..b936743 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,13 @@ Take potentially dangerous PDFs, office documents, or images and convert them to Dangerzone works like this: You give it a document that you don't know if you can trust (for example, an email attachment). Inside of a sandbox, dangerzone converts the document to a PDF (if it isn't already one), and then converts the PDF into raw pixel data: a huge list of of RGB color values for each page. Then, in a separate sandbox, dangerzone takes this pixel data and converts it back into a PDF. -**See [Installing Dangerzone](https://github.com/firstlookmedia/dangerzone/wiki/Installing-Dangerzone) to get started.** +## Getting started -Some features: +- Download [dangerzone 0.1 for Mac](https://github.com/firstlookmedia/dangerzone/releases/download/v0.1/Dangerzone.0.1.dmg) +- Download [dangerzone 0.1 for Windows](https://github.com/firstlookmedia/dangerzone/releases/download/v0.1/Dangerzone.0.1.msi) +- See [installing dangerzone](https://github.com/firstlookmedia/dangerzone/wiki/Installing-Dangerzone) on the wiki for Linux repositories + +## Some features - Sandboxes don't have network access, so if a malicious document can compromise one, it can't phone home - Dangerzone can optionally OCR the safe PDFs it creates, so it will have a text layer again @@ -30,6 +34,6 @@ Dangerzone can convert these types of document into safe PDFs: - PNG (`.png`) - TIFF (`.tif`, `.tiff`) -Dangerzone was inspired by [Qubes trusted PDF](https://blog.invisiblethings.org/2013/02/21/converting-untrusted-pdfs-into-trusted.html), but it works in non-Qubes operating systems and sandboxes the document conversion in containers instead of virtual machines (using Docker for macOS, Windows, and Debian/Ubuntu, and [podman](https://podman.io/) for Fedora). +Dangerzone was inspired by [Qubes trusted PDF](https://blog.invisiblethings.org/2013/02/21/converting-untrusted-pdfs-into-trusted.html), but it works in non-Qubes operating systems. It uses containers as sandboxes instead of virtual machines (using Docker for macOS, Windows, and Debian/Ubuntu, and [podman](https://podman.io/) for Fedora). Set up a development environment by following [these instructions](/BUILD.md). diff --git a/RELEASE.md b/RELEASE.md index 360eaeb..51bd8d4 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -6,6 +6,7 @@ This section documents the release process. Unless you're a dangerzone developer Before making a release, all of these should be complete: +* Update `version` in `pyproject.toml` * Update `dangerzone_version` in `dangerzone/__init__.py` * Update `ProductVersion` in `install/windows/Dangerzone.wxs` * CHANGELOG.md should be updated to include a list of all major changes since the last release @@ -33,6 +34,7 @@ To make a macOS release, go to macOS build machine: - Apple-trusted `Developer ID Application: FIRST LOOK PRODUCTIONS, INC.` and `Developer ID Installer: FIRST LOOK PRODUCTIONS, INC.` code-signing certificates installed - An app-specific Apple ID password saved in the login keychain called `flockagent-notarize` - Verify and checkout the git tag for this release +- Run `poetry install` - Run `poetry run ./install/macos/build_app.py --with-codesign`; this will make `dist/Dangerzone.dmg` - Notarize it: `xcrun altool --notarize-app --primary-bundle-id "media.firstlook.dangerzone" -u "micah@firstlook.org" -p "@keychain:dangerzone-notarize" --file dist/Dangerzone $VERSION.dmg` - Wait for it to get approved, check status with: `xcrun altool --notarization-history 0 -u "micah@firstlook.org" -p "@keychain:dangerzone-notarize"` @@ -51,7 +53,11 @@ To make a Windows release, go to the Windows build machine: - Build machine should be running Windows 10, and have the Windows codesigning certificate installed - Verify and checkout the git tag for this release -- Run `install\windows\build.bat`; this will make a codesigned installer package called `dist\Dangerzone-$VERSION.msi` +- Run `poetry install` +- Run `poetry shell`, then `cd ..\pyinstaller`, `python setup.py install`, `exit` +- Run `poetry run install\windows\build.bat`; this will make a codesigned installer package called `dist\Dangerzone.msi` + +Rename `Dangerzone.msi` to `Dangerzone $VERSION.msi`. ## Linux release diff --git a/dangerzone/__init__.py b/dangerzone/__init__.py index 3fa4774..690564c 100644 --- a/dangerzone/__init__.py +++ b/dangerzone/__init__.py @@ -5,6 +5,7 @@ import signal import platform import click import time +import uuid from .global_common import GlobalCommon from .main_window import MainWindow @@ -15,11 +16,12 @@ from .docker_installer import ( DockerInstaller, ) -dangerzone_version = "0.0.3" +dangerzone_version = "0.1" class Application(QtWidgets.QApplication): document_selected = QtCore.pyqtSignal(str) + application_activated = QtCore.pyqtSignal() def __init__(self): QtWidgets.QApplication.__init__(self, sys.argv) @@ -29,6 +31,9 @@ class Application(QtWidgets.QApplication): if event.type() == QtCore.QEvent.FileOpen: self.document_selected.emit(event.file()) return True + elif event.type() == QtCore.QEvent.ApplicationActivate: + self.application_activated.emit() + return True return QtWidgets.QApplication.event(self, event) @@ -66,15 +71,25 @@ def main(filename): docker_installer.start() return - windows = [] + closed_windows = {} + windows = {} + + def delete_window(window_id): + closed_windows[window_id] = windows[window_id] + del windows[window_id] # Open a document in a window def select_document(filename=None): - if len(windows) == 1 and windows[0].common.document_filename == None: - window = windows[0] + if ( + len(windows) == 1 + and windows[list(windows.keys())[0]].common.document_filename == None + ): + window = windows[list(windows.keys())[0]] else: - window = MainWindow(global_common) - windows.append(window) + window_id = uuid.uuid4().hex + window = MainWindow(global_common, window_id) + window.delete_window.connect(delete_window) + windows[window_id] = window if filename: # Validate filename @@ -100,7 +115,15 @@ def main(filename): if not select_document(filename): return True + # Open a new window, if all windows are closed + def application_activated(): + if len(windows) == 0: + select_document() + # If we get a file open event, open it app.document_selected.connect(select_document) + # If the application is activated and all windows are closed, open a new one + app.application_activated.connect(application_activated) + sys.exit(app.exec_()) diff --git a/dangerzone/main_window.py b/dangerzone/main_window.py index 5becd69..dff53d0 100644 --- a/dangerzone/main_window.py +++ b/dangerzone/main_window.py @@ -10,9 +10,12 @@ from .common import Common class MainWindow(QtWidgets.QMainWindow): - def __init__(self, global_common): + delete_window = QtCore.pyqtSignal(str) + + def __init__(self, global_common, window_id): super(MainWindow, self).__init__() self.global_common = global_common + self.window_id = window_id self.common = Common() self.setWindowTitle("dangerzone") @@ -83,5 +86,7 @@ class MainWindow(QtWidgets.QMainWindow): def closeEvent(self, e): e.accept() + self.delete_window.emit(self.window_id) + if platform.system() != "Darwin": self.global_common.app.quit() diff --git a/install/windows/Dangerzone.wxs b/install/windows/Dangerzone.wxs index 8191c50..70ddf43 100644 --- a/install/windows/Dangerzone.wxs +++ b/install/windows/Dangerzone.wxs @@ -1,5 +1,5 @@ - + diff --git a/pyproject.toml b/pyproject.toml index 732798b..9989a94 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "dangerzone" -version = "0.1.0" +version = "0.1" description = "Take potentially dangerous PDFs, office documents, or images and convert them to a safe PDF" authors = ["Micah Lee "] license = "MIT"