Skip to content

Commit

Permalink
Merge pull request #259 from freedomofpress/84-sd-export
Browse files Browse the repository at this point in the history
Add sd-export VMs and basic export flow
  • Loading branch information
conorsch authored Jun 6, 2019
2 parents 3e1a8ab + dbe00eb commit 7729205
Show file tree
Hide file tree
Showing 20 changed files with 468 additions and 13 deletions.
1 change: 1 addition & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[flake8]
ignore: W605
max-line-length = 99
16 changes: 15 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
91 changes: 80 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 <name-of-file>
```

###### 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**
Expand Down
3 changes: 3 additions & 0 deletions config.json.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@
"hidserv": {
"hostname": "avgfxawdn6c3coe3.onion",
"key": "Il8Xas7uf6rjtc0LxYwhrx"
},
"usb": {
"device": "sys-usb:2-4"
}
}
2 changes: 1 addition & 1 deletion docs/images/data-flow-diagram.draw

Large diffs are not rendered by default.

Binary file modified docs/images/data-flow-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions dom0/sd-dom0-qvm-rpc.sls
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
53 changes: 53 additions & 0 deletions dom0/sd-export-files.sls
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions dom0/sd-export-files.top
Original file line number Diff line number Diff line change
@@ -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
81 changes: 81 additions & 0 deletions dom0/sd-export.sls
Original file line number Diff line number Diff line change
@@ -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
6 changes: 6 additions & 0 deletions dom0/sd-export.top
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# -*- coding: utf-8 -*-
# vim: set syntax=yaml ts=2 sw=2 sts=2 et :

base:
dom0:
- sd-export
5 changes: 5 additions & 0 deletions scripts/list-vms
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
1 change: 1 addition & 0 deletions scripts/prep-salt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
7 changes: 7 additions & 0 deletions sd-export/application-x-sd-export.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="application/x-sd-export">
<comment>Archive for transfering files from the SecureDrop workstation to an external USB device.</comment>
<glob pattern="*.sd-export"/>
</mime-type>
</mime-info>
Loading

0 comments on commit 7729205

Please sign in to comment.