diff --git a/.flake8 b/.flake8 index 05bd31a4..1de5103e 100644 --- a/.flake8 +++ b/.flake8 @@ -1,2 +1,3 @@ [flake8] ignore: W605 +max-line-length = 99 diff --git a/Makefile b/Makefile index 5a24ff6a..0e22f447 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,12 @@ sd-svs-disp: prep-salt ## Provisions SD Submission Viewing VM sudo qubesctl --show-output --targets sd-svs-disp-template state.highstate sudo qubesctl --show-output --targets sd-svs-disp state.highstate +sd-export: prep-salt ## Provisions SD Export VM + sudo qubesctl top.enable sd-export + sudo qubesctl top.enable sd-export-files + sudo qubesctl --show-output --targets sd-export-template state.highstate + sudo qubesctl --show-output --targets sd-export-export-dvm state.highstate + clean-salt: assert-dom0 ## Purges SD Salt configuration from dom0 @echo "Purging Salt config..." @sudo rm -rf /srv/salt/sd @@ -78,7 +84,15 @@ remove-sd-svs: assert-dom0 ## Destroys SD SVS VM remove-sd-gpg: assert-dom0 ## Destroys SD GPG keystore VM @./scripts/destroy-vm sd-gpg -clean: assert-dom0 destroy-all clean-salt ## Destroys all SD VMs +remove-sd-export: assert-dom0 detach-sd-export-usb ## Destroys SD EXPORT VMs + @./scripts/destroy-vm sd-export-usb + @./scripts/destroy-vm sd-export-usb-dvm + +detach-sd-export-usb: assert-dom0 ## Detach USB device from SD EXPORT USB VM + @qvm-kill sd-export-usb || true + @qvm-usb detach sd-export-usb || true + +clean: assert-dom0 detach-sd-export-usb destroy-all clean-salt ## Destroys all SD VMs sudo dnf -y -q remove securedrop-workstation-dom0-config || true sudo rm -f /usr/bin/securedrop-update \ /etc/cron.daily/securedrop-update-cron diff --git a/README.md b/README.md index 17dfe5af..8090c092 100644 --- a/README.md +++ b/README.md @@ -161,32 +161,101 @@ Replies and Source Deletion will be added in the next major release of the *Secu **WARNING:** Opening files from an unknown origin presents certain risks (malware, fingerprinting). While the workstation helps reduce these risks by offering VM-level isolation, transferring documents to another host without the same level of isolation may expose you to these risks. Using tools to sanitize submitted documents, such as right-clicking a .pdf and selecting "Convert to trusted PDF" in Qubes OS, may help mitigate some of these risks. Further mitigating these risks will be a focus of future development. +##### Manual export flow + Exporting documents directly from within the *SecureDrop Client* is not currently supported, but you can export documents manually via USB by following these steps: -1. Create an export VM based on the `securedrop-workstation` template. - 1. Click the Qubes menu in the upper left of the screen. - 2. Click **Create Qubes VM** - 3. Name the VM `sd-export` - 4. Set the template as `securedrop-workstation` - 5. Set networking to (none). - 6. Click **OK** to create the VM. -2. Start the VM. Again from the Qubes menu: +1. Start the `sd-export-usb` VM. Again from the Qubes menu: 1. Select "Domain: sd-export" 2. Click "export: Files". This will launch the file manager in the export VM. 3. Insert your USB drive into the workstation. A notification will pop up indicating the name of your USB device, e.g. "Innostor_PenDrive". 4. In the upper right hand side of your screen, there is a small icon in the system tray with a USB drive. Click that icon. 5. Select the name of your USB drive. - 6. Click the **+** icon next to the `sd-export` VM. + 6. Click the **+** icon next to the `sd-export-usb` VM. 3. You can use the command line in `sd-svs` to manually move selected files: ``` -qvm-copy-to-vm sd-export ~/.securedrop_client/data/name-of-file +qvm-copy-to-vm sd-export-usb ~/.securedrop_client/data/name-of-file ``` -4. You may now use the File manager that you opened in `sd-export` to move files from `~/QubesIncoming/sd-svs` to the USB drive. Delete the original file from `~/QubesIncoming/sd-svs` once it has been moved. Note that the drive and files are not encrypted, so ensure that the key is properly erased and/or destroyed after use. +4. You may now use the File manager that you opened in `sd-export-usb` to move files from `~/QubesIncoming/sd-svs` to the USB drive. Delete the original file from `~/QubesIncoming/sd-svs` once it has been moved. Note that the drive and files are not encrypted, so ensure that the key is properly erased and/or destroyed after use. The development plan is to provide functionality in the *SecureDrop Client* that automates step 3, and assists the user in taking these steps via GUI prompts. Eventually we plan to provide other methods for export, such as [OnionShare](https://onionshare.org/) (this will require the attachment of a NetVM), using a dedicated export VM template with tools such as OnionShare and Veracrypt. The next section includes instructions to approximate the OnionShare sharing flow. +##### Automated export flow (Work in progress, client integration TBD) + +The SecureDrop Workstation can automatically export to a luks-encrypted USB device provided the correct format. The file extension of the tar archive must be `.sd-export`, containing the following structure: + +``` +. +├── metadata.json +└── export_data + ├── file-to-export-1.txt + ├── file-to-export-2.pdf + ├── file-to-export-3.doc + [...] +``` + +The folder `export_data` contains all the files that will be exported to the disk, and the file `metadata.json` contains the encryption passphrase and method for the USB Transfer Device (only LUKS is supported at the moment). The file should be formatted as follows: + +``` +{ + "encryption-method": "luks" + "encryption-key": "Your encryption passhrase goes here" +} +``` + +###### Create the transfer device + +You can find instructions to create a luks-encrypted transfer device in the [SecureDrop docs](https://docs.securedrop.org/en/latest/set_up_transfer_device.html). + +###### Install-time configuration + +A single USB port will be assigned to the exporting feature. Qubes will automatically attach any USB device to the Export VM. It should be labeled and only used for exporting purposes. You will be able to use different USB Transfer Devices, but they will always need to be plugged into the same port. Note that a USB stick must be connected during the entirety of the provisioning process. If you forget, you can run `make sd-export` after the install. + + +1. Connect the USB device to the port you would like to use. Then in `dom0`, run the following command: + +``` +qvm-usb +``` + +2. Take note of the device ID (e.g. `sys-usb:3-4`) used by your USB Transfer Device +3. Populate `config.json` with this value +4. Run the configuration of the sd-export feature. + 1. If this is a new install, you can run, in `dom0`: + + ``` + make all + ``` + + 2. If the workstation has already been properly configured and you wish to reconfigure the USB export functionality, run the following commands in `dom0`: + + ``` + make remove-sd-export + make sd-export + ``` + +###### Exporting + +1. Plug in the USB drive into the dedicated export port on your workstation. +2. In `sd-svs`, run the following command: + +``` +qvm-open-in-vm sd-export-usb +``` + +###### Troubleshooting + +If you are experiencing issues with the export flow, or would like to use a different port, you can re-run the configuration steps and apply the configuration to the VMs. +In `dom0`, ensure your config.json contains the correct usb device identifier (see above) and rebuild the export machines (with the USB device attached): + +``` +make remove-sd-export +make sd-export +``` + + ##### Transferring files via OnionShare 1. Create an `sd-onionshare-template` VM based on `fedora-29`: 1. Click on the Qubes menu in the upper left, select "Template: Fedora 29", click on "fedora-29: Qube Settings", and click on **Clone Qube** diff --git a/config.json.example b/config.json.example index 593a4100..1c6cdaf4 100644 --- a/config.json.example +++ b/config.json.example @@ -2,5 +2,8 @@ "hidserv": { "hostname": "avgfxawdn6c3coe3.onion", "key": "Il8Xas7uf6rjtc0LxYwhrx" + }, + "usb": { + "device": "sys-usb:2-4" } } diff --git a/docs/images/data-flow-diagram.draw b/docs/images/data-flow-diagram.draw index 93910de9..f5786c56 100644 --- a/docs/images/data-flow-diagram.draw +++ b/docs/images/data-flow-diagram.draw @@ -1 +1 @@ -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 \ No newline at end of file +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 \ No newline at end of file diff --git a/docs/images/data-flow-diagram.png b/docs/images/data-flow-diagram.png index 408f43b9..ae003727 100644 Binary files a/docs/images/data-flow-diagram.png and b/docs/images/data-flow-diagram.png differ diff --git a/dom0/sd-dom0-qvm-rpc.sls b/dom0/sd-dom0-qvm-rpc.sls index 161db835..7d4aa2b7 100644 --- a/dom0/sd-dom0-qvm-rpc.sls +++ b/dom0/sd-dom0-qvm-rpc.sls @@ -43,6 +43,7 @@ dom0-rpc-qubes.OpenInVM: - marker_end: "### END securedrop-workstation ###" - content: | sd-svs $dispvm:sd-svs-disp allow + sd-svs sd-export-usb allow $anyvm $tag:sd-workstation deny dom0-rpc-qubes.OpenURL: file.blockreplace: diff --git a/dom0/sd-export-files.sls b/dom0/sd-export-files.sls new file mode 100644 index 00000000..11e72189 --- /dev/null +++ b/dom0/sd-export-files.sls @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +# vim: set syntax=yaml ts=2 sw=2 sts=2 et : + +## +# sd-export-files +# ======== +# +# Moves files into place on sd-export +# +## +include: + - fpf-apt-test-repo + +sd-export-template-install-cryptsetup: + pkg.installed: + - pkgs: + - cryptsetup + +sd-export-send-to-usb-script: + file.managed: + - name: /usr/bin/send-to-usb + - source: salt://sd/sd-export/send-to-usb + - user: root + - group: root + - mode: 755 + - makedirs: True + +sd-export-desktop-file: + file.managed: + - name: /usr/share/applications/send-to-usb.desktop + - source: salt://sd/sd-export/send-to-usb.desktop + - user: root + - group: root + - mode: 644 + - makedirs: True + cmd.run: + - name: sudo update-desktop-database /usr/share/applications + - require: + - file: sd-export-desktop-file + +sd-export-file-format: + file.managed: + - name: /usr/share/mime/packages/application-x-sd-export.xml + - source: salt://sd/sd-export/application-x-sd-export.xml + - user: root + - group: root + - mode: 644 + - makedirs: True + cmd.run: + - name: sudo update-mime-database /usr/share/mime + - require: + - file: sd-export-file-format + - file: sd-export-desktop-file diff --git a/dom0/sd-export-files.top b/dom0/sd-export-files.top new file mode 100644 index 00000000..1393d60f --- /dev/null +++ b/dom0/sd-export-files.top @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# vim: set syntax=yaml ts=2 sw=2 sts=2 et : + +base: + sd-export-template: + - sd-export-files diff --git a/dom0/sd-export.sls b/dom0/sd-export.sls new file mode 100644 index 00000000..36ff844e --- /dev/null +++ b/dom0/sd-export.sls @@ -0,0 +1,81 @@ +# -*- coding: utf-8 -*- +# vim: set syntax=yaml ts=2 sw=2 sts=2 et : + +# +# Installs 'sd-export' AppVM, to persistently store SD data +# This VM has no network configured. +## +include: + - sd-workstation-template + +sd-export-template: + qvm.vm: + - name: sd-export-template + - clone: + - source: securedrop-workstation + - label: red + - tags: + - add: + - sd-workstation + - require: + - sls: sd-workstation-template + +sd-export-usb-dvm: + qvm.vm: + - name: sd-export-usb-dvm + - present: + - template: sd-export-template + - label: red + - prefs: + - netvm: "" + - template_for_dispvms: True + - tags: + - add: + - sd-workstation + - require: + - qvm: sd-export-template + +# Ensure the Qubes menu is populated with relevant app entries, +# so that Nautilus/Files can be started via GUI interactions. +sd-export-template-sync-appmenus: + cmd.run: + - name: > + qvm-start --skip-if-running sd-export-template && + qvm-sync-appmenus sd-export-template + - require: + - qvm: sd-export-template + - onchanges: + - qvm: sd-export-template + +# Here we must create as the salt stack does not appear to allow us to create +# VMs with the class DispVM and attach the usb device specified in the config +# permanently to this VM +sd-export-create-named-dispvm: + cmd.run: + - name: > + qvm-check sd-export-usb || + qvm-create --class DispVM --template sd-export-usb-dvm --label red sd-export-usb + - require: + - qvm: sd-export-usb-dvm + +{% import_json "sd/config.json" as d %} + +# Persistent attachments can only be removed when the domain is off, so we must +# kill sd-export-usb before detaching the USB devices from the domain +sd-export-named-dispvm-permanently-attach-usb: + cmd.run: + - name: > + qvm-kill sd-export-usb || true ; + qvm-usb detach sd-export-usb || true ; + qvm-usb attach --persistent sd-export-usb {{ d.usb.device }} || true + - require: + - cmd: sd-export-create-named-dispvm + +sd-export-named-dispvm-add-tags: + qvm.vm: + - name: sd-export-usb + - tags: + - add: + - sd-workstation + - require: + - cmd: sd-export-create-named-dispvm diff --git a/dom0/sd-export.top b/dom0/sd-export.top new file mode 100644 index 00000000..bf1f607b --- /dev/null +++ b/dom0/sd-export.top @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +# vim: set syntax=yaml ts=2 sw=2 sts=2 et : + +base: + dom0: + - sd-export diff --git a/scripts/list-vms b/scripts/list-vms index 9a9369e2..2407f822 100755 --- a/scripts/list-vms +++ b/scripts/list-vms @@ -6,6 +6,8 @@ set -u set -o pipefail +# When adding new VMs, ensure the template is listed *after* the AppVMs that +# use it. declare -a sd_workstation_vm_names=( sd-gpg sd-proxy @@ -16,6 +18,9 @@ declare -a sd_workstation_vm_names=( sd-whonix sd-svs-disp sd-svs-disp-template + sd-export-usb + sd-export-usb-dvm + sd-export-template ) for vm in "${sd_workstation_vm_names[@]}" ; do diff --git a/scripts/prep-salt b/scripts/prep-salt index f90687d3..5605479a 100755 --- a/scripts/prep-salt +++ b/scripts/prep-salt @@ -20,6 +20,7 @@ if [[ ! -d "$SDW_SALT_DIR" ]]; then sudo cp -r sd-proxy /srv/salt/sd sudo cp -r sd-svs /srv/salt/sd sudo cp -r sd-workstation /srv/salt/sd + sudo cp -r sd-export /srv/salt/sd sudo cp dom0/* /srv/salt/ fi diff --git a/sd-export/application-x-sd-export.xml b/sd-export/application-x-sd-export.xml new file mode 100644 index 00000000..9e36ef08 --- /dev/null +++ b/sd-export/application-x-sd-export.xml @@ -0,0 +1,7 @@ + + + + Archive for transfering files from the SecureDrop workstation to an external USB device. + + + diff --git a/sd-export/send-to-usb b/sd-export/send-to-usb new file mode 100755 index 00000000..172317e4 --- /dev/null +++ b/sd-export/send-to-usb @@ -0,0 +1,151 @@ +#!/usr/bin/env python3 + +import datetime +import json +import os +import subprocess +import sys +import tarfile +import tempfile + + +def exit_gracefully(msg, e=False): + """ + Utility to print error messages, mostly used during debugging, + then exits successfully despite the error. Always exits 0, + since non-zero exit values will cause system to try alternative + solutions for mimetype handling, which we want to avoid. + """ + sys.stderr.write(msg) + sys.stderr.write("\n") + if e: + try: + e_output = e.output + except Exception: + e_output = "" + sys.stderr.write(e_output) + sys.stderr.write("\n") + # exit with 0 return code otherwise the os will attempt to open + # the file with another application + sys.exit(0) + + +def extract_tarball(): + try: + with tarfile.open(SUBMISSION_ARCHIVE) as tar: + tar.extractall(SUBMISSION_TMPDIR) + except Exception as e: + msg = "Error opening export bundle: " + exit_gracefully(msg, e=e) + + +def retrieve_metadata(): + try: + metadata_filepath = os.path.join(SUBMISSION_TMPDIR, SUBMISSION_DIRNAME, "metadata.json") + with open(metadata_filepath) as json_data: + data = json.load(json_data) + encryption_method = data["encryption-method"] + encryption_key = data["encryption-key"] + except Exception as e: + msg = "Error parsing metadata." + exit_gracefully(msg, e=e) + + # we only support luks for now + if encryption_method != "luks": + msg = "Unsupported export encryption." + exit_gracefully(msg) + + return (encryption_method, encryption_key) + + +def unlock_luks_volume(encryption_key): + # the luks device is not already unlocked + if not os.path.exists(os.path.join("/dev/mapper/", ENCRYPTED_DEVICE)): + p = subprocess.Popen( + ["sudo", "cryptsetup", "luksOpen", DEVICE, ENCRYPTED_DEVICE], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + p.communicate(input=str.encode(encryption_key, "utf-8")) + rc = p.returncode + if rc != 0: + msg = "Bad passphrase or luks error." + exit_gracefully(msg) + + +def mount_volume(): + # mount target not created + if not os.path.exists(MOUNTPOINT): + subprocess.check_call(["sudo", "mkdir", MOUNTPOINT]) + try: + subprocess.check_call( + [ + "sudo", + "mount", + os.path.join("/dev/mapper/", ENCRYPTED_DEVICE), + MOUNTPOINT + ] + ) + subprocess.check_call(["sudo", "chown", "-R", "user:user", MOUNTPOINT]) + except subprocess.CalledProcessError as e: + # clean up + subprocess.check_call(["sudo", "cryptsetup", "luksClose", ENCRYPTED_DEVICE]) + subprocess.check_call(["rm", "-rf", SUBMISSION_TMPDIR]) + msg = "An error occurred while mounting disk: " + exit_gracefully(msg, e=e) + + +def copy_submission(): + # move files to drive (overwrites files with same filename) and unmount drive + try: + TARGET_DIRNAME_path = os.path.join(MOUNTPOINT, TARGET_DIRNAME) + subprocess.check_call(["mkdir", TARGET_DIRNAME_path]) + export_data = os.path.join(SUBMISSION_TMPDIR, SUBMISSION_DIRNAME, "export_data/") + subprocess.check_call(["cp", "-r", export_data, TARGET_DIRNAME_path]) + except (subprocess.CalledProcessError, OSError) as e: + msg = "Error writing to disk:" + exit_gracefully(msg, e=e) + finally: + # Finally, we sync the filesystem, unmount the drive and lock the + # luks volume, and exit 0 + subprocess.check_call(["sync"]) + subprocess.check_call(["sudo", "umount", MOUNTPOINT]) + subprocess.check_call(["sudo", "cryptsetup", "luksClose", ENCRYPTED_DEVICE]) + subprocess.check_call(["rm", "-rf", SUBMISSION_TMPDIR]) + sys.exit(0) + + +def main(): + extract_tarball() + encryption_method, encryption_key = retrieve_metadata() + unlock_luks_volume(encryption_key) + mount_volume() + copy_submission() + + +if __name__ == "__main__": + try: + # We define globals inside the main block, rather than at the top + # of the file, to catch exceptions via exit_gracefully. All var names + # will be available to all functions called via main(). + DEVICE = "/dev/sda1" + MOUNTPOINT = "/media/usb" + ENCRYPTED_DEVICE = "encrypted_volume" + SUBMISSION_ARCHIVE = sys.argv[1] + + # Halt immediately if target file is absent + if not os.path.exists(SUBMISSION_ARCHIVE): + msg = "File does not exist" + exit_gracefully(msg) + + SUBMISSION_DIRNAME = os.path.basename(SUBMISSION_ARCHIVE).split(".")[0] + TARGET_DIRNAME = "sd-export-{}".format(datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) + SUBMISSION_TMPDIR = tempfile.mkdtemp() + + main() + except Exception as e: + # exit with 0 return code otherwise the os will attempt to open + # the file with another application + msg = "Unhandled exception:" + exit_gracefully(msg, e=e) diff --git a/sd-export/send-to-usb.desktop b/sd-export/send-to-usb.desktop new file mode 100644 index 00000000..6521a92c --- /dev/null +++ b/sd-export/send-to-usb.desktop @@ -0,0 +1,5 @@ +[Desktop Entry] +Type=Application +MimeType=application/x-sd-export +Name="Export SD submission to USB" +Exec=/usr/bin/send-to-usb diff --git a/tests/base.py b/tests/base.py index 6dfbb7f4..3753a15b 100644 --- a/tests/base.py +++ b/tests/base.py @@ -12,6 +12,7 @@ "sd-svs", "sd-svs-disp", "sd-whonix", + "sd-export-usb" ] diff --git a/tests/test_sd_export.py b/tests/test_sd_export.py new file mode 100644 index 00000000..c6dc4e47 --- /dev/null +++ b/tests/test_sd_export.py @@ -0,0 +1,26 @@ +import unittest + +from base import SD_VM_Local_Test + + +class SD_Export_Tests(SD_VM_Local_Test): + + def setUp(self): + self.vm_name = "sd-export-usb-dvm" + super(SD_Export_Tests, self).setUp() + + def test_files_are_properly_copied(self): + self.assertFilesMatch("/usr/bin/send-to-usb", + "sd-export/send-to-usb") + self.assertFilesMatch("/usr/share/applications/send-to-usb.desktop", + "sd-export/send-to-usb.desktop") + self.assertFilesMatch("/usr/share/mime/packages/application-x-sd-export.xml", # noqa + "sd-export/application-x-sd-export.xml") + + def test_sd_export_package_installed(self): + self.assertTrue(self._package_is_installed("cryptsetup")) + + +def load_tests(loader, tests, pattern): + suite = unittest.TestLoader().loadTestsFromTestCase(SD_Export_Tests) + return suite diff --git a/tests/test_vms_exist.py b/tests/test_vms_exist.py index 868eaa71..b246b712 100644 --- a/tests/test_vms_exist.py +++ b/tests/test_vms_exist.py @@ -118,6 +118,30 @@ def sd_svs_disp_template(self): self.assertTrue('sd-workstation' in vm.tags) self.assertTrue(vm.template_for_dispvms) + def sd_export_template(self): + vm = self.app.domains["sd-export-template"] + nvm = vm.netvm + self.assertTrue(nvm is None) + self.assertTrue('sd-workstation' in vm.tags) + self._check_kernel(vm) + + def sd_export_dvm(self): + vm = self.app.domains["sd-export-usb-dvm"] + nvm = vm.netvm + self.assertTrue(nvm is None) + self.assertTrue('sd-workstation' in vm.tags) + self.assertTrue(vm.template_for_dispvms) + self._check_kernel(vm) + + def sd_export(self): + vm = self.app.domains["sd-export-usb"] + nvm = vm.netvm + self.assertTrue(nvm is None) + vm_type = vm.klass + self.assertTrue(vm_type == "DispVM") + self.assertTrue('sd-workstation' in vm.tags) + self._check_kernel(vm) + def load_tests(loader, tests, pattern): suite = unittest.TestLoader().loadTestsFromTestCase(SD_VM_Tests) diff --git a/tests/vars/qubes-rpc.yml b/tests/vars/qubes-rpc.yml index 7ad02e0a..1cdd0cbd 100644 --- a/tests/vars/qubes-rpc.yml +++ b/tests/vars/qubes-rpc.yml @@ -91,6 +91,7 @@ starts_with: |- ### BEGIN securedrop-workstation ### sd-svs $dispvm:sd-svs-disp allow + sd-svs sd-export-usb allow $anyvm $tag:sd-workstation deny ### END securedrop-workstation ###