-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move MIME handling to systemd services (boot provisioning)
Fixes freedomofpress/securedrop-workstation#1042, complemented by freedomofpress/securedrop-workstation#1043. Implemention reasoning: - Failure to setup leads shutdown to make this security-critical component loud on failures - Running in disp. templates fails (e.g. sd-viewer) to prevent populating user's home directory, thus contaminating all disposables based on them. - MIME-handling behavior set via qubesdb - pass vm-specific data via the vm-config qubes feature (accessible through QubesDB) [1]. - Started after rsyslog.service to allow failure logging [1]: https://dev.qubes-os.org/projects/core-admin-client/en/latest/manpages/qvm-features.html#vm-config
- Loading branch information
Showing
7 changed files
with
112 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,7 @@ Source: securedrop-client | |
Section: unknown | ||
Priority: optional | ||
Maintainer: SecureDrop Team <[email protected]> | ||
Build-Depends: debhelper-compat (= 11), dh-apparmor, python3-virtualenv, libssl-dev, pkg-config, libclang-dev, qubesdb-dev | ||
Build-Depends: debhelper-compat (= 11), dh-apparmor, dh-exec, python3-virtualenv, libssl-dev, pkg-config, libclang-dev, qubesdb-dev | ||
Standards-Version: 3.9.8 | ||
Homepage: https://github.com/freedomofpress/securedrop-client | ||
X-Python3-Version: >= 3.5 | ||
|
@@ -55,7 +55,7 @@ Description: Whonix configuration for SecureDrop. | |
|
||
Package: securedrop-workstation-config | ||
Architecture: all | ||
Depends: rsyslog, mailcap, apparmor, nautilus, securedrop-keyring, xfce4-terminal | ||
Depends: ${python3:Depends}, python3-qubesdb, rsyslog, mailcap, apparmor, nautilus, securedrop-keyring, xfce4-terminal | ||
Description: This is the SecureDrop workstation template configuration package. | ||
This package provides dependencies and configuration for the Qubes SecureDrop workstation VM Templates. | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
#!/usr/bin/dh-exec --with=install | ||
workstation-config/mailcap.default opt/sdw/ | ||
workstation-config/mimeapps.list.sd-viewer opt/sdw/ | ||
workstation-config/mimeapps.list.sd-app opt/sdw/ | ||
workstation-config/mimeapps.list.sd-devices-dvm opt/sdw/ | ||
workstation-config/mimeapps.list.sd-devices opt/sdw/ | ||
workstation-config/open-in-dvm.desktop opt/sdw/ | ||
workstation-config/paxctld.conf opt/sdw/ | ||
workstation-config/securedrop-mime-handling.py => usr/bin/securedrop-mime-handling |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
14 changes: 14 additions & 0 deletions
14
debian/securedrop-workstation-config.securedrop-mime-handling.service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
[Unit] | ||
Description=Securedrop Mimetype Handling Override | ||
ConditionPathExists=/var/run/qubes-service/securedrop-mime-handling | ||
OnFailure=systemd-halt.service | ||
After=rsyslog.service | ||
|
||
[Service] | ||
Type=oneshot | ||
User=user | ||
ExecStart=/usr/bin/securedrop-mime-handling | ||
RemainAfterExit=yes | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#!/usr/bin/python3 | ||
## | ||
# securedrop-mime-handling | ||
# ===================== | ||
# | ||
# Overrides mimetype handling for certain VMs. Instead of relying on the | ||
# /usr/share/applications (system volume), we instead use /home/user/.local/share/ | ||
# to be provisioned on boot by systemd. | ||
## | ||
|
||
import logging | ||
import logging.handlers | ||
import sys | ||
from pathlib import Path | ||
|
||
from qubesdb import QubesDB | ||
|
||
# Configure logging | ||
syslog_handler = logging.handlers.SysLogHandler(address="/dev/log") | ||
|
||
stdout_handler = logging.StreamHandler(sys.stdout) | ||
logging.basicConfig(level=logging.INFO, handlers=[syslog_handler, stdout_handler]) | ||
logger = logging.getLogger() | ||
|
||
|
||
def create_symlink_strict(source_path_str, target_path_str, overwrite_expected=False): | ||
""" | ||
Creates a symlink, but warning when idempotence is required and failing if | ||
link source already exsits. | ||
""" | ||
source_path = Path(source_path_str) | ||
target_path = Path(target_path_str) | ||
target_path.resolve(strict=True) # raise exception if does not exist | ||
|
||
try: | ||
source_path.symlink_to(target_path) | ||
except FileExistsError as e: | ||
if source_path.is_symlink(): | ||
if source_path.readlink() == target_path: | ||
if not overwrite_expected: | ||
# Harmless situation, yet not ideal (idempotency required) | ||
logger.warning(f"'{source_path}' existed already (unexpected)") | ||
else: | ||
logger.error(f"'{source_path}' existed already and is linked to the wrong file") | ||
raise e | ||
else: | ||
logger.error(f"'{source_path}' existed already") | ||
raise e | ||
|
||
|
||
def get_mime_handling(): | ||
mime_handling = QubesDB().read("/vm-config/SD_MIME_HANDLING") | ||
if mime_handling is None or len(mime_handling) == 0: | ||
raise RuntimeError("'SD_MIME_HANDLING' qubesdb vm-config is not set") | ||
return mime_handling.decode() | ||
|
||
|
||
def main(): | ||
# Should fail on DVM templates to avoid tainting the disposables' home. | ||
# In practice we cannot detect this from within, so we have to hard-code | ||
# sd-app as the only valid non-disposable. | ||
persistent_home = QubesDB().read("/qubes-vm-persistence").decode() != "none" | ||
vm_name = QubesDB().read("/name").decode() | ||
if persistent_home and vm_name != "sd-app": | ||
sys.exit(1) | ||
|
||
# Ensure applications open with the correct tool (or disposable qube) | ||
mime_handling = get_mime_handling() | ||
mimeapps_override_path = Path(f"/opt/sdw/mimeapps.list.{mime_handling}") | ||
mimeapps_override_path.resolve(strict=True) | ||
user_apps_dir_path = Path("/home/user/.local/share/applications") | ||
user_apps_dir_path.mkdir(mode=0o755, parents=True, exist_ok=True) | ||
create_symlink_strict( | ||
user_apps_dir_path / "mimeapps.list", | ||
mimeapps_override_path, | ||
overwrite_expected=persistent_home, | ||
) | ||
|
||
# Fallback mechanism if MIME type lookup fails in tools like xdg-open | ||
create_symlink_strict( | ||
"/home/user/.mailcap", "/opt/sdw/mailcap.default", overwrite_expected=persistent_home | ||
) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |