diff --git a/On-Polkit.md b/On-Polkit.md new file mode 100644 index 00000000..012222b2 --- /dev/null +++ b/On-Polkit.md @@ -0,0 +1,80 @@ +## On admin configurable policy rules with Polkit v0.1xy + + +### 1 History of Polkit's admin configurable policy rules + +[This article](https://www.admin-magazine.com/Articles/Assigning-Privileges-with-sudo-and-PolicyKit) nicely (and simply) explains the intention and functionality of Polkit. + + +#### 1.1 Polkit ≤ 0.105 versus Polkit ≥ 0.106 WRT admin configured policy rules + + +* **Polkit 0.106 switched from the ".pkla (Policy Kit Local Authority / [pklocalauthority](https://www.freedesktop.org/software/polkit/docs/0.105/pklocalauthority.8.html))" file format to a JavaScript-based ".rules" configuration file format** + + See the [original announcement and explanation](https://davidz25.blogspot.com/2012/06/authorization-rules-in-polkit.html) for this change. See the fundamental differences between these two file formats [in this simple example](https://fossies.org/linux/libvirt/docs/auth.rst#unix-socket-policykit-auth).
+ The comments at this page concisely reflect the year long debates this change triggered, including most of the technical and usablility issues denoted.
+ Note that there was no migration period (in which both file formats were supported): Polkit ≤ 0.105 solely understands ".pkla" files, while Polkit ≥ 0.106 only understands ".rules" files. + + +* **Consequences / effects for Linux distributions** + + Aside of all usability issues (mainly JavaScript not being among the repertoire of an UNIX admin) and a programming languagage ("touring complete") being unsuitable and problematic to dangerous for configuration files (see sendmail.cf and some other (hi)stories), requiring a JavaScript interpreter as a fundamental depencendcy and needed early at the system start is the major technical issue: [This Ubuntu bug summarises it well](https://bugs.launchpad.net/ubuntu/+source/policykit-1/+bug/1086783). + + Consequently most Linux distributions stayed with Polkit 0.105 for a while and then started to take different approaches, often multiple of them temporally staggered: + 1. Backport fixes and even some new fuctionality from newer Polkit releases, creating Polkit 0.105-z versions. + 2. Create tools to automatically convert policy rules in the ".pkla" file format to the ".rules" file format. + 3. Extend the recent Polkit to parse ".pkla" files, e.g. by the [polkit-pkla-compat](https://pagure.io/polkit-pkla-compat) helper. + 4. Rewrite all distribution specific policy rules as ".rules" files (by the help from tools denoted in point ii above) and completly switch to recent Polkit releases: Users of these distributions have to do the same for their own policy rules, then. + + +* **Polkit versions in SailfishOS** + + As with some other components, SailfishOS tends to lag behind recent Polkit releases, which is not neccesarily a bad thing.
+ SailfishOS 2.2.0 deployed Polkit 0.104, some later release (before SailfishOS 3.2.1) switched to Polkit 0.105 and SailfishOS 4.0.1 is still deploying Polkit 0.105.
+ This looks like aforementioned approach i, although I have not checked which Polkit 0.105 variant the SailfishOS' version is based on or which backport patches it incorporates. + + +#### 1.2 Practically handling Polkit rules + +The Polkit documentation [nicely provides older releases](https://www.freedesktop.org/software/polkit/docs/)!
+Thus assess per [`pkaction --version`](https://www.freedesktop.org/software/polkit/docs/0.105/pkaction.1.html), which Polkit version you are running and use this documentation release, e.g. [its 0.105 version](https://www.freedesktop.org/software/polkit/docs/0.105/index.html).
+Specifically this is the latest and last (original) documentation of [pklocalauthority](https://www.freedesktop.org/software/polkit/docs/0.105/pklocalauthority.8.html), i.e. the ".pkla" file format.
+Nice examples with explanations for ".pkla" files: +* [libvirt's SSHPolicyKitSetup](https://wiki.libvirt.org/page/SSHPolicyKitSetup#Configuration_for_individual_users) +* [Actually a report of a resolved Gentoo bug, but it also provides a nice example](https://forums.gentoo.org/viewtopic-p-7587064.html#7587064) + +Using `pkaction`: +* `pkaction` (without any options) lists all action IDs, which Polkit controls. +* `pkaction --verbose` lists the configuration of all action IDs. +* `pkaction --verbose --action-id ` lists the configuration of the action IDs selected (supports globbing per "**\***", needs quoting then). + + +### 2 *crypto-sdcard's* use of Polkit's admin configurable policy rules + +*crypto-sdcard* deploys a single ".pkla" file in [/etc/polkit-1/localauthority/50-local.d/69-cryptosd.pkla](https://github.com/Olf0/crypto-sdcard/blob/master/polkit-1/localauthority/50-local.d/69-cryptosd.pkla), which was significantly refactored and expanded in *crypto-sdcard 1.7.0*. + +69-cryptosd.pkla (since v1.7.0) uniformly extends udisks2's default policy configuration depolyed by SailfishOS ≥ 2.2.0, which is comprised of udisks2's original configuration (e.g., [for udisks 2.7.5](https://github.com/storaged-project/udisks/blob/udisks-2.7.5/data/org.freedesktop.UDisks2.policy.in), or from its documentation, e.g. [for udisks 2.8.1](http://storaged.org/doc/udisks2-api/latest/udisks-polkit-actions.html#udisks-polkit-actions-file)) plus Jolla's patches (SailfishOS 2.2.x: [0003-Loosen-up-mount-unmount-rights.patch](https://git.sailfishos.org/mer-core/udisks2/blob/upgrade-2.2.0/rpm/0003-Loosen-up-mount-unmount-rights.patch) / SailfishOS ≥ "2.2.2" aka 3.0.0: [0003-Loosen-up-polkit-policies-to-work-from-another-seat.patch](https://git.sailfishos.org/mer-core/udisks2/blob/master/rpm/0003-Loosen-up-polkit-policies-to-work-from-another-seat.patch)). + + +#### 2.1 Intentions and considerations for these policy rules + +* Allow programs running in the root context (e.g., *crypto-sdcard*) to automatically unlock non-system crypto "containers" (if they can provide the necessary credentials). +* Carefully relax rules for some harmless actions (WRT SMART data, power saving etc.) to be programatically executed by the root or primary user on non-system devices.
+ Note that [SMART suppport seems to be disabled in SailfishOS](https://git.sailfishos.org/mer-core/udisks2/blob/master/rpm/0002-Drop-smartata-dependencies.patch). +* Alleviate some (IMO) overly careful asking (or call it "nagging with authorisations") by Polkit for some interactive actions for the primary user, plus a few additional ones for the root user. +* Allow "primary" SailfishOS users (i.e., in the `unix-group:system` for at least SailfishOS 2.2.0 - 3.x.y (< 3.2.1), rsp. in the `unix-group:media_rw` for SailfishOS ≥ 3.x.y (< 3.2.1)) to use the relaxed user rules: This usually affects only a single user (the "primary user"), either *nemo* or *defaultuser*. +* Intentionally allow all users in the `unix-group:root` (i.e., not just the `unix-user:root`) to use their relaxed rules.
+ While there is only a single user (root) in the group "root" on SailfishOS by default, this enables an admin to let additional user(s) use these relaxed rules by adding them to the "root" group as their secondary group. + + +#### 2.2 Implementation notes for 69-cryptosd.pkla (as of *crypto-sdcard 1.7.0*) + +**Workflow** + +* Get hold of udisks2's policy rules as deployed by the oldest (still SailfishOS 2.2.0) and newest ("master", i.e. currently: SailfishOS 4.1.0) SailfishOS release to be supported by *crypto-sdcard*, either by copying them from SailfishOS installations, or by downloading the right udisks2 versions of the org.freedesktop.UDisks2.policy.in file (2.7.5 and 2.8.1) plus patching them with Jolla's patches.
+ Also look at the current version of the [org.freedesktop.UDisks2.policy.in from udisks2's "master" branch](https://github.com/storaged-project/udisks/blob/master/data/org.freedesktop.UDisks2.policy.in), to anticipate future actions. +* Manually compare these three files and decide which policies to alter, separately for the root user(s) and the primary user. +* Implement these altered policies in .pkla format, two separate files for + * ... [the root user(s)](https://github.com/Olf0/crypto-sdcard/blob/69e826fd8ef1f3eacde806deaa80176886d91faf/polkit-1/localauthority/50-local.d/69-cryptosd-root.pkla). + * ... [the primary user](https://github.com/Olf0/crypto-sdcard/blob/f2eaa4fa69ee6e49e30df6ac89f77f77b06a8462/polkit-1/localauthority/50-local.d/69-cryptosd-user.pkla). +* Merge these changes into a single file while grouping actions as appropiate: [69-cryptosd.pkla](https://github.com/Olf0/crypto-sdcard/blob/master/polkit-1/localauthority/50-local.d/69-cryptosd.pkla) diff --git a/polkit-1/localauthority/50-local.d/69-cryptosd.pkla b/polkit-1/localauthority/50-local.d/69-cryptosd.pkla index 49a5cbc2..0b9e8d87 100644 --- a/polkit-1/localauthority/50-local.d/69-cryptosd.pkla +++ b/polkit-1/localauthority/50-local.d/69-cryptosd.pkla @@ -1,7 +1,154 @@ -[Placeholder for telling udisks2 to allow for "ejecting" media (SD-cards and USB-storage devices) in the future.] -[Identity=unix-group:system / media_rw (SFOS3.2.1+)] -[Action=org.freedesktop.udisks2.XXXX] -[ResultAny=yes] -[ResultInactive=yes] -[ResultActive=yes] +[Root users & primary user(s): udisks2.encrypted-*lock*, except for *-system] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.encrypted-unlock;org.freedesktop.udisks2.encrypted-unlock-other-seat;org.freedesktop.udisks2.encrypted-lock-others +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Root users: udisks2.encrypted-unlock-system] +Identity=unix-group:root +Action=org.freedesktop.udisks2.encrypted-unlock-system +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Primary user(s): udisks2.encrypted-unlock-system] +Identity=unix-group:media_rw +Action=org.freedesktop.udisks2.encrypted-unlock-system +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=auth_self_keep + +[Root users & primary user(s): udisks2.encrypted-change-passphrase, but not for *-system] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.encrypted-change-passphrase +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=yes + +[Root users: udisks2.manage-md-raid] +Identity=unix-group:root +Action=org.freedesktop.udisks2.manage-md-raid +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Primary user(s): udisks2.manage-md-raid] +Identity=unix-group:media_rw +Action=org.freedesktop.udisks2.manage-md-raid +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=auth_self_keep + +[Root users & primary user(s): udisks2.power-off-drive*, except for *-system] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.power-off-drive;org.freedesktop.udisks2.power-off-drive-other-seat +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Root users & primary user(s): udisks2.eject-media*, except for *-system] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.eject-media;org.freedesktop.udisks2.eject-media-other-seat +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=yes + +[Root users: udisks2.modify-device] +Identity=unix-group:root +Action=org.freedesktop.udisks2.modify-device +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=yes + +[Primary user(s): udisks2.modify-device] +Identity=unix-group:media_rw +Action=org.freedesktop.udisks2.modify-device +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=auth_self_keep + +[Root users & primary user(s): udisks2.modify-device-system & udisks2.modify-device-other-seat] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.modify-device-system;org.freedesktop.udisks2.modify-device-other-seat +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=auth_self_keep + +[Root users & primary user(s): udisks2.rescan] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.rescan +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Root users: udisks2.open-device] +Identity=unix-group:root +Action=org.freedesktop.udisks2.open-device +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Primary user(s): udisks2.open-device] +Identity=unix-group:media_rw +Action=org.freedesktop.udisks2.open-device +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=yes + +[Root users & primary user(s): udisks2.open-device-system] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.open-device-system +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=auth_self_keep + +[Root users: udisks2.modify-system-configuration] +Identity=unix-group:root +Action=org.freedesktop.udisks2.modify-system-configuration +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=auth_self_keep + +[Root users: udisks2.read-system-configuration-secrets] +Identity=unix-group:root +Action=org.freedesktop.udisks2.read-system-configuration-secrets +ResultAny=auth_admin +ResultInactive=auth_admin +ResultActive=auth_admin_keep + +[Root users & primary user(s): ] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.modify-drive-settings;org.freedesktop.udisks2.ata-smart-enable-disable;org.freedesktop.udisks2.ata-smart-update +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Root users: udisks2.ata-smart-simulate & udisks2.ata-smart-selftest] +Identity=unix-group:root +Action=org.freedesktop.udisks2.ata-smart-simulate;org.freedesktop.udisks2.ata-smart-selftest +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Primary user(s): udisks2.ata-smart-simulate & udisks2.ata-smart-selftest] +Identity=unix-group:media_rw +Action=org.freedesktop.udisks2.ata-smart-simulate;org.freedesktop.udisks2.ata-smart-selftest +ResultAny=auth_self +ResultInactive=auth_self +ResultActive=auth_self_keep + +[Root users & primary user(s): , except for *-system] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.ata-check-power;org.freedesktop.udisks2.ata-standby;org.freedesktop.udisks2.ata-standby-other-seat +ResultAny=yes +ResultInactive=yes +ResultActive=yes + +[Root users & primary user(s): udisks2.cancel-job*] +Identity=unix-group:root;unix-group:media_rw +Action=org.freedesktop.udisks2.cancel-job;org.freedesktop.udisks2.cancel-job-other-user +ResultAny=yes +ResultInactive=yes +ResultActive=yes diff --git a/rpm/crypto-sdcard.spec b/rpm/crypto-sdcard.spec index 7904fa25..50c0af1c 100644 --- a/rpm/crypto-sdcard.spec +++ b/rpm/crypto-sdcard.spec @@ -1,6 +1,6 @@ Name: crypto-sdcard Summary: Configuration files for unlocking and mounting encrypted SD-cards automatically -Version: 1.6.0 +Version: 1.7.0 # Since v1.3.1, the release version consists of two or three fields, separated by a dot ("."): # - The first field must contain a natural number greater than zero. # This number may be prefixed by one of {alpha,beta,stable}, e.g. "alpha13". @@ -27,7 +27,6 @@ Source: https://github.com/Olf0/%{name}/archive/%{version}-%{release}/%{n #Icon: smartmedia_mount.256x256.gif BuildArch: noarch Requires: systemd -Requires: polkit Requires: udisks2 # Better use direct dependencies on specific versions than indirect ones (here: the line above # versus the one below) in general, but ultimately decided not to do so in this special case @@ -52,17 +51,19 @@ Conflicts: crypto-sdcard_sbj %install mkdir -p %{buildroot}%{_sysconfdir}/%{name} -cp -R systemd polkit-1 udev %{buildroot}%{_sysconfdir}/ +cp -R polkit-1 systemd udev %{buildroot}%{_sysconfdir}/ %files # Regular files: %defattr(-,root,root,-) +%{_sysconfdir}/udev/rules.d/96-cryptosd.rules %{_sysconfdir}/systemd/system/cryptosd-luks@.service %{_sysconfdir}/systemd/system/cryptosd-plain@.service %{_sysconfdir}/systemd/system/mount-cryptosd-luks@.service %{_sysconfdir}/systemd/system/mount-cryptosd-plain@.service +%{_sysconfdir}/systemd/system/mnt-cryptosd-luks@.service +%{_sysconfdir}/systemd/system/mnt-cryptosd-plain@.service %{_sysconfdir}/polkit-1/localauthority/50-local.d/69-cryptosd.pkla -%{_sysconfdir}/udev/rules.d/96-cryptosd.rules # Extraordinary files / dirs: %defattr(0640,root,root,0750) %dir %{_sysconfdir}/%{name} diff --git a/systemd/system/cryptosd-luks@.service b/systemd/system/cryptosd-luks@.service index d39095fc..baf34855 100644 --- a/systemd/system/cryptosd-luks@.service +++ b/systemd/system/cryptosd-luks@.service @@ -1,5 +1,5 @@ [Unit] -Description=Open %I per cryptsetup +Description=Open /dev/disk/by-uuid/%I per cryptsetup Documentation=https://github.com/Olf0/crypto-sdcard DefaultDependencies=no After=systemd-udevd.service systemd-udev-trigger.service dev-disk-by\x2duuid-%i.device systemd-journald.service local-fs.target cryptsetup-pre.target @@ -7,11 +7,6 @@ Requisite=dev-disk-by\x2duuid-%i.device PartOf=mount-cryptosd-luks@%i.service cryptsetup.target Conflicts=umount.target shutdown.target actdead.target factory-test.target Before=umount.target shutdown.target mount-cryptosd-luks@%i.service -# That would allow this unit to keep on running, when switching to e.g., rescue.target -# (but never for the SFOS recovery!). While having an unlocked device around should be -# harmless, disable it as long as benefits and potential consequences for the SFOS updater -# are not properly evaluated: -# IgnoreOnIsolate=true AssertFileNotEmpty=/etc/crypto-sdcard/crypto_luks_%I.key [Service] @@ -22,7 +17,7 @@ RemainAfterExit=yes # ExecStartPre=/sbin/modprobe qcrypto # For various reasons (avoid (temporal) dependency on udisks2, allow for discards etc.), do # not use "udisksctl unlock --key-file", instead call cryptsetup directly: -ExecStart=/usr/sbin/cryptsetup --allow-discards -d /etc/crypto-sdcard/crypto_luks_%I.key luksOpen /dev/disk/by-uuid/%I %I +ExecStart=/usr/sbin/cryptsetup --allow-discards -d /etc/crypto-sdcard/crypto_luks_%I.key luksOpen /dev/disk/by-uuid/%I %I ; /bin/sleep 1 # "udisksctl mount" (in mount-cryptosd-luks@.service) sometimes fails when issued right after # "udisksd" (per "udisks2.service") has finished starting, because the udisks object for this # unlocked device has not been created yet. @@ -32,9 +27,10 @@ ExecStart=/usr/sbin/cryptsetup --allow-discards -d /etc/crypto-sdcard/crypto_luk # unnecessarily waste this second most of the time; that is avoided this way. # Note that using ExecStartPost= for this is futile (as irrelevant for dependencies, see # https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= ), but (only) -# units of the Type=oneshot may use multiple ExecStart= lines and / or commands. Side note: -# For non-oneshot units a solution is to move the ExecStart= command to ExecStartPre= (that -# is functionally equivalent!) and ... -ExecStart=/bin/sleep 1 +# units of the Type=oneshot may use multiple ExecStart= lines (which are *started +# concurrently*, but the last one is displayed as "main process") and / or commands in an +# ExecStart= line. Side note: For non-oneshot units a solution is to move the ExecStart= +# command to ExecStartPre= (that is *functionally equivalent*, but again displays the +# ExecStart= command as "main process") and use ExecStart=/bin/sleep 1 ExecStop=/usr/sbin/cryptsetup close %I diff --git a/systemd/system/cryptosd-plain@.service b/systemd/system/cryptosd-plain@.service index 7721f18b..105fb9ec 100644 --- a/systemd/system/cryptosd-plain@.service +++ b/systemd/system/cryptosd-plain@.service @@ -1,5 +1,5 @@ [Unit] -Description=Open %I per cryptsetup +Description=Open /dev/%I per cryptsetup Documentation=https://github.com/Olf0/crypto-sdcard DefaultDependencies=no After=systemd-udevd.service systemd-udev-trigger.service dev-%i.device systemd-journald.service local-fs.target cryptsetup-pre.target @@ -7,11 +7,6 @@ Requisite=dev-%i.device PartOf=mount-cryptosd-plain@%i.service cryptsetup.target Conflicts=umount.target shutdown.target actdead.target factory-test.target Before=umount.target shutdown.target mount-cryptosd-plain@%i.service -# That would allow this unit to keep on running, when switching to e.g., rescue.target -# (but never for the SFOS recovery!). While having an unlocked device around should be -# harmless, disable it as long as benefits and potential consequences for the SFOS updater -# are not properly evaluated: -# IgnoreOnIsolate=true AssertFileNotEmpty=/etc/crypto-sdcard/crypto_plain_%I.key [Service] @@ -28,7 +23,7 @@ StandardInput=file:/etc/crypto-sdcard/crypto_plain_%I.key StandardOutput=journal # "udisksctl unlock --key-file" does only work with LUKS "containers", not with "plain" ones, # thus call cryptsetup directly: -ExecStart=/usr/sbin/cryptsetup -d - -o ${CRYPTO_PLAIN_OFFSET} -h ${CRYPTO_PLAIN_PASSPHRASE_HASH} -s ${CRYPTO_PLAIN_KEYLENGTH} -c ${CRYPTO_PLAIN_CIPHER} --allow-discards --type plain open /dev/%I %I +ExecStart=/usr/sbin/cryptsetup -d - -o ${CRYPTO_PLAIN_OFFSET} -h ${CRYPTO_PLAIN_PASSPHRASE_HASH} -s ${CRYPTO_PLAIN_KEYLENGTH} -c ${CRYPTO_PLAIN_CIPHER} --allow-discards --type plain open /dev/%I %I ; /bin/sleep 1 # "udisksctl mount" (in mount-cryptosd-luks@.service) sometimes fails when issued right after # this unit (instance) and "udisksd" (per "udisks2.service") have finished starting, because # the udisks object for this unlocked device has not been created yet. @@ -38,9 +33,10 @@ ExecStart=/usr/sbin/cryptsetup -d - -o ${CRYPTO_PLAIN_OFFSET} -h ${CRYPTO_PLAIN_ # unnecessarily waste this second most of the time; that is avoided this way. # Note that using ExecStartPost= for this is futile (as irrelevant for dependencies, see # https://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= ), but (only) -# units of the Type=oneshot may use multiple ExecStart= lines and / or commands. Side note: -# For non-oneshot units a solution is to move the ExecStart= command to ExecStartPre= (that -# is functionally equivalent!) and ... -ExecStart=/bin/sleep 1 +# units of the Type=oneshot may use multiple ExecStart= lines (which are *started +# concurrently*, but the last one is displayed as "main process") and / or commands in an +# ExecStart= line. Side note: For non-oneshot units a solution is to move the ExecStart= +# command to ExecStartPre= (that is *functionally equivalent*, but again displays the +# ExecStart= command as "main process") and use ExecStart=/bin/sleep 1 ExecStop=/usr/sbin/cryptsetup close %I diff --git a/systemd/system/mnt-cryptosd-luks@.service b/systemd/system/mnt-cryptosd-luks@.service new file mode 100644 index 00000000..2e5a9ff2 --- /dev/null +++ b/systemd/system/mnt-cryptosd-luks@.service @@ -0,0 +1,25 @@ +[Unit] +Description=Manually mount /dev/mapper/%I directly +Documentation=https://github.com/Olf0/crypto-sdcard +DefaultDependencies=no +After=systemd-udevd.service systemd-udev-trigger.service cryptosd-luks@%i.service dev-mapper-%i.device systemd-journald.service local-fs.target cryptsetup.target +Requires=cryptosd-luks@%i.service +# "Requisite=dev-mapper-%i.device" here would prevent this unit from +# auto-starting its dependencies, when started manually: +PartOf=dev-mapper-%i.device sysinit.target +# Also conflict with umount.target (see man 7 systemd.special), as +# this is a mounting unit, though not a mount unit: +Conflicts=umount.target shutdown.target actdead.target factory-test.target +Before=alien-service-manager.service umount.target shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +#EnvironmentFile=/etc/systemd/system/cryptosd.conf +#EnvironmentFile=-/etc/crypto-sdcard/cryptosd.conf +#EnvironmentFile=-/etc/crypto-sdcard/cryptosd@%I.conf +ExecStartPre=/bin/mkdir -p /media/cryptosd-luks-%I +ExecStart=/bin/mount -v /dev/mapper/%I /media/cryptosd-luks-%I +ExecStop=/bin/umount -vr /dev/mapper/%I +ExecStopPost=/bin/rmdir /media/cryptosd-luks-%I + diff --git a/systemd/system/mnt-cryptosd-plain@.service b/systemd/system/mnt-cryptosd-plain@.service new file mode 100644 index 00000000..787eb76c --- /dev/null +++ b/systemd/system/mnt-cryptosd-plain@.service @@ -0,0 +1,25 @@ +[Unit] +Description=Manually mount /dev/mapper/%I directly +Documentation=https://github.com/Olf0/crypto-sdcard +DefaultDependencies=no +After=systemd-udevd.service systemd-udev-trigger.service cryptosd-plain@%i.service dev-mapper-%i.device systemd-journald.service local-fs.target cryptsetup.target +Requires=cryptosd-plain@%i.service +# "Requisite=dev-mapper-%i.device" here would prevent this unit from +# auto-starting its dependencies, when started manually: +PartOf=dev-mapper-%i.device sysinit.target +# Also conflict with umount.target (see man 7 systemd.special), as +# this is a mounting unit, though not a mount unit: +Conflicts=umount.target shutdown.target actdead.target factory-test.target +Before=alien-service-manager.service umount.target shutdown.target + +[Service] +Type=oneshot +RemainAfterExit=yes +#EnvironmentFile=/etc/systemd/system/cryptosd.conf +#EnvironmentFile=-/etc/crypto-sdcard/cryptosd.conf +#EnvironmentFile=-/etc/crypto-sdcard/cryptosd@%I.conf +ExecStartPre=/bin/mkdir -p /media/cryptosd-plain-%I +ExecStart=/bin/mount -v /dev/mapper/%I /media/cryptosd-plain-%I +ExecStop=/bin/umount -vr /dev/mapper/%I +ExecStopPost=/bin/rmdir /media/cryptosd-plain-%I + diff --git a/systemd/system/mount-cryptosd-luks@.service b/systemd/system/mount-cryptosd-luks@.service index dfebdd6a..57fc45c2 100644 --- a/systemd/system/mount-cryptosd-luks@.service +++ b/systemd/system/mount-cryptosd-luks@.service @@ -1,11 +1,11 @@ [Unit] -Description=Mount %I per udisks +Description=Mount /dev/mapper/%I per udisks2 Documentation=https://github.com/Olf0/crypto-sdcard After=udisks2.service cryptosd-luks@%i.service dev-mapper-%i.device start-user-session.service Requires=udisks2.service cryptosd-luks@%i.service -# This is not neccessary here, and prevents this unit from auto-starting -# its dependencies, when called manually: -# Requisite=dev-mapper-%i.device +# "Requisite=dev-mapper-%i.device" here would prevent this unit from +# auto-starting its dependencies, when started manually: +PartOf=dev-mapper-%i.device # Also conflict with umount.target (see man 7 systemd.special), as # this is a mounting unit, though not a mount unit: Conflicts=umount.target rescue.target actdead.target factory-test.target diff --git a/systemd/system/mount-cryptosd-plain@.service b/systemd/system/mount-cryptosd-plain@.service index 3395c08b..d851a05d 100644 --- a/systemd/system/mount-cryptosd-plain@.service +++ b/systemd/system/mount-cryptosd-plain@.service @@ -1,11 +1,11 @@ [Unit] -Description=Mount %I per udisks +Description=Mount /dev/mapper/%I per udisks2 Documentation=https://github.com/Olf0/crypto-sdcard After=udisks2.service cryptosd-plain@%i.service dev-mapper-%i.device start-user-session.service Requires=udisks2.service cryptosd-plain@%i.service -# This is not neccessary here, and prevents this unit from auto-starting -# its dependencies, when called manually: -# Requisite=dev-mapper-%i.device +# "Requisite=dev-mapper-%i.device" here would prevent this unit from +# auto-starting its dependencies, when started manually: +PartOf=dev-mapper-%i.device # Also conflict with umount.target (see man 7 systemd.special), as # this is a mounting unit, though not a mount unit: Conflicts=umount.target rescue.target actdead.target factory-test.target diff --git a/udev/rules.d/96-cryptosd.rules b/udev/rules.d/96-cryptosd.rules index bba27592..e47acbfa 100644 --- a/udev/rules.d/96-cryptosd.rules +++ b/udev/rules.d/96-cryptosd.rules @@ -1,30 +1,65 @@ -# Match sda0 to mmcblk1 exactly (*: per "mmcblk1*|sd[a-z][0-9]") as in SailfishOS' v2.2.0 to 4.1.0+ patched -# /lib/udev/rules.d/80-udisks2.rules, which sets (among more, which is not duplicated here; see -# https://git.sailfishos.org/mer-core/udisks2/blob/master/rpm/0005-Add-udev-rule-for-the-sda-drives.patch): -# KERNEL=="mmcblk1*|sd[a-z][0-9]", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", ENV{ID_DRIVE_FLASH_SD}="1", ENV{ID_DRIVE_MEDIA_FLASH_SD}="1" -# Unset that for USB attached storage, which is "rotational", plus set UDISKS_CAN_POWER_OFF for all devices dealt with, here: -# KERNEL=="sd[a-z][0-9]", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", ATTR{queue/rotational}=="1", ENV{ID_DRIVE_FLASH_SD}="0", ENV{ID_DRIVE_MEDIA_FLASH_SD}="0" -# KERNEL=="mmcblk1*|sd[a-z][0-9]", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", ENV{UDISKS_CAN_POWER_OFF}="1" - -# For DM-Crypt LUKS, match sda0 to mmcblk1 (*) to both SUBSYSTEM=="block", plus ENV{ID_FS_TYPE}=="crypto_LUKS" -KERNEL=="mmcblk1*|sd[a-z][0-9]", SUBSYSTEM=="block", ENV{ID_FS_TYPE}=="crypto_LUKS", ACTION=="add|change", PROGRAM=="/usr/bin/head -c 1 /etc/crypto-sdcard/crypto_luks_%E{ID_FS_UUID}", RESULT=="?", ENV{CRYPTOSD_TYPE}="LUKS" -KERNEL=="mmcblk1*|sd[a-z][0-9]", ENV{CRYPTOSD_TYPE}=="LUKS", ENV{UDISKS_SYSTEM}="0", ENV{UDISKS_AUTO}="0", ENV{UDISKS_NAME}="crypto_luks_%k_%E{ID_FS_UUID}", MODE="0660", TAG+="systemd", PROGRAM=="/bin/systemd-escape --template=cryptosd-luks@.service %E{ID_FS_UUID}", ENV{SYSTEMD_WANTS}="%c" +# Since crypto-sdcard 1.6.1, it adheres to the nomenclature used in other udev rules: +# - KERNEL=="sd*[!0-9]|sr*", ENV{DEVTYPE}=="disk" for all USB-attached (OTG) storage *devices* +# - KERNEL=="sd*[0-9]|sr*", ENV{DEVTYPE}=="partition" for all partitions on USB-attached storage devices +# - KERNEL=="sd*|sr*" for both +# - KERNEL=="mmcblk[1-9]" (the test ENV{DEVTYPE}=="disk" can be omitted) for the card in the internal slot and all external (USB-attached) SD-cards and MMCs (e.g., in readers). +# - KERNEL=="mmcblk[1-9]p[0-9]" (the test ENV{DEVTYPE}=="partition" can be omitted) for all partitions on the card in the internal slot and on all external SD-cards and MMCs. Side note: mmcblk[0-9]boot[0-9] are (e)MMC's special devices ("RPMB"). +# - KERNEL=="mmcblk[1-9]*" for both +# - KERNEL=="mmcblk[1-9]*|sd*|sr*", SUBSYSTEMS=="usb" to filter for anything attached via (presumably "external") USB. Mind that on devices without an SD-card slot mmcblk1 will be an externally attached card. +# Reference: /usr/lib/udev/rules.d/60-persistent-storage.rules +# +# Is something like KERNEL=="mmcblk[1-9]*|sd*|sr*", SUBSYSTEMS=="usb", ATTR{removable}="1" possible and reasonable (means only "removable *media*"?) ? Or without restricting it to USB-attached devices / partitions? + +SUBSYSTEM!="block", GOTO="cryptosd_mount_end" +KERNEL!="mmcblk[1-9]*|sd*|sr*", GOTO="cryptosd_open_end" + +# Ignore the additions / changes by Jolla per +# https://git.sailfishos.org/mer-core/udisks2/blob/master/rpm/0005-Add-udev-rule-for-the-sda-drives.patch +# by setting these anew / clobbering these for *all suitable* devices. +KERNEL=="mmcblk[1-9]*", ENV{DEVTYPE}=="disk", ENV{MMC_TYPE}!="?*", ENV{ID_DRIVE_FLASH_SD}="1", ENV{ID_DRIVE_MEDIA_FLASH_SD}="1" +KERNEL=="sd*", ENV{DEVTYPE}=="disk", ENV{ID_DRIVE_FLASH_SD}="1", ENV{ID_DRIVE_MEDIA_FLASH_SD}="1" +# ToDo: Only set that for storage, which is not "rotational", but also for SATA-RAIDs; check, if ATTR{queue/rotational} works!?! +#KERNEL=="sd*|sr*", ENV{DEVTYPE}=="disk", ATTR{queue/rotational}=="0", ENV{ID_DRIVE_FLASH_SD}="1", ENV{ID_DRIVE_MEDIA_FLASH_SD}="1" + +# ToDo: Set UDISKS_CAN_POWER_OFF for all suitable devices dealt with, here: +#ENV{DEVTYPE}=="disk", ATTR{power/control}=="on", ENV{UDISKS_CAN_POWER_OFF}="1" + +# ToDo: Use a test for ATA-Discard / -"Trim" to unlock appropriately: +# See for details https://github.com/Olf0/crypto-sdcard/wiki/ToDo#starting-points-for-that +# ATTR{discard_alignment}!="0", ... +# ATTR{device/queue/discard_granularity}!="0", ... +# ATTR{device/discard_alignment}!="0", ... +# ATTRS{discard_alignment}!="0", ... +# ATTRS{queue/discard_granularity}!="0", ... +# or IMPORT{parent}="...", IMPORT{db}="...", + + +# For DM-Crypt LUKS, match ENV{ID_FS_TYPE}=="crypto_LUKS" +ENV{ID_FS_TYPE}=="crypto_LUKS", ACTION=="add|change", PROGRAM=="/bin/grep -q .* /etc/crypto-sdcard/crypto_luks_%E{ID_FS_UUID}.key", ENV{CRYPTOSD_TYPE}="LUKS" +ENV{CRYPTOSD_TYPE}=="LUKS", ENV{UDISKS_SYSTEM}="0", ENV{UDISKS_AUTO}="0", ENV{UDISKS_NAME}="cryptosd_luks_dev-%k_%E{ID_FS_UUID}", MODE="0660", TAG+="systemd", PROGRAM=="/usr/bin/systemd-escape --template=cryptosd-luks@.service %E{ID_FS_UUID}", ENV{SYSTEMD_WANTS}="%c" # When above detected and assigned devices are removed -KERNEL=="mmcblk1*|sd[a-z][0-9]", ENV{CRYPTOSD_TYPE}=="LUKS", ACTION=="remove", ENV{CRYPTOSD_TYPE}="removed", ENV{UDISKS_NAME}="crypto_removed", PROGRAM=="/bin/systemd-escape --template=cryptosd-luks@.service %E{ID_FS_UUID}", ENV{SYSTEMD_WANTS}="", ENV{SYSTEMD_USER_WANTS}="", RUN{program}+="/bin/systemctl stop %c" +ENV{CRYPTOSD_TYPE}=="LUKS", ACTION=="remove", ENV{CRYPTOSD_TYPE}="removed", ENV{UDISKS_NAME}="cryptosd_removed", PROGRAM=="/bin/systemd-escape --template=cryptosd-luks@.service %E{ID_FS_UUID}", ENV{SYSTEMD_WANTS}="", ENV{SYSTEMD_USER_WANTS}="", RUN{program}+="/bin/systemctl stop %c" -# For DM-Crypt "plain", also match sda0 to mmcblk1 (*) to SUBSYSTEM=="block", but ensure (by ENV{ID_*}!="?*" statements) that it appears to be unused space +# For DM-Crypt "plain", ensure (by ENV{ID_*}!="?*" statements) that it appears to be unused space # Two rules, one for partitions and a tighter one for whole disks: -KERNEL=="mmcblk1*|sd[a-z][0-9]", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", ENV{ID_FS_USAGE}!="?*", ENV{ID_FS_TYPE}!="?*", ENV{ID_PART_TABLE_TYPE}!="?*", ACTION=="add|change", PROGRAM=="/usr/bin/head -c 1 /etc/crypto-sdcard/crypto_plain_%k", RESULT=="?", ENV{CRYPTOSD_TYPE}="PLAIN" -KERNEL=="mmcblk1*|sd[a-z][0-9]", SUBSYSTEM=="block", ENV{DEVTYPE}=="partition", ENV{ID_FS_USAGE}!="?*", ENV{ID_FS_TYPE}!="?*", ACTION=="add|change", PROGRAM=="/usr/bin/head -c 1 /etc/crypto-sdcard/crypto_plain_%k", RESULT=="?", ENV{CRYPTOSD_TYPE}="PLAIN" -KERNEL=="mmcblk1*|sd[a-z][0-9]", ENV{CRYPTOSD_TYPE}=="PLAIN", ENV{UDISKS_SYSTEM}="0", ENV{UDISKS_AUTO}="0", ENV{UDISKS_NAME}="crypto_plain_%k", MODE="0660", TAG+="systemd", ENV{SYSTEMD_WANTS}="cryptosd-plain@%k.service" +ENV{DEVTYPE}=="disk", ENV{ID_FS_USAGE}!="?*", ENV{ID_FS_TYPE}!="?*", ENV{ID_PART_TABLE_TYPE}!="?*", ACTION=="add|change", PROGRAM=="/bin/grep -q .* /etc/crypto-sdcard/crypto_plain_%k.key", ENV{UDISKS_PARTITIONABLE}="0", ENV{CRYPTOSD_TYPE}="PLAIN" +ENV{DEVTYPE}=="partition", ENV{ID_FS_USAGE}!="?*", ENV{ID_FS_TYPE}!="?*", ACTION=="add|change", PROGRAM=="/bin/grep -q .* /etc/crypto-sdcard/crypto_plain_%k.key", ENV{CRYPTOSD_TYPE}="PLAIN" +ENV{CRYPTOSD_TYPE}=="PLAIN", ENV{UDISKS_SYSTEM}="0", ENV{UDISKS_AUTO}="0", ENV{UDISKS_NAME}="cryptosd_plain_dev-%k", MODE="0660", TAG+="systemd", ENV{SYSTEMD_WANTS}="cryptosd-plain@%k.service" # When above detected and assigned devices are removed -KERNEL=="mmcblk1*|sd[a-z][0-9]", ENV{CRYPTOSD_TYPE}=="PLAIN", ACTION=="remove", ENV{CRYPTOSD_TYPE}="removed", ENV{UDISKS_NAME}="crypto_removed", ENV{SYSTEMD_WANTS}="", ENV{SYSTEMD_USER_WANTS}="", RUN{program}+="/bin/systemctl stop cryptosd-plain@%k.service" +ENV{CRYPTOSD_TYPE}=="PLAIN", ACTION=="remove", ENV{CRYPTOSD_TYPE}="removed", ENV{UDISKS_NAME}="cryptosd_removed", ENV{SYSTEMD_WANTS}="", ENV{SYSTEMD_USER_WANTS}="", RUN{program}+="/bin/systemctl stop cryptosd-plain@%k.service" + +LABEL="cryptosd_open_end" + -# Carefully match resulting virtual node dm-[0-9] to trigger mounting it; see /lib/udev/rules.d/10-dm.rules for details -KERNEL=="dm-[0-9]", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", ENV{DM_UDEV_RULES_VSN}=="[2-9]", ENV{DM_NAME}=="????????-????-????-????-????????????|????-????", ACTION=="change", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="0", ENV{CRYPTOSD_TYPE}="mount-LUKS", ENV{UDISKS_SYSTEM}="0", ENV{UDISKS_AUTO}="0", ENV{UDISKS_NAME}="mount_crypto_luks_%E{DM_NAME}", MODE="0660", TAG+="systemd", PROGRAM=="/bin/systemd-escape --template=mount-cryptosd-luks@.service %E{DM_NAME}", ENV{SYSTEMD_WANTS}="%c" -KERNEL=="dm-[0-9]", ENV{CRYPTOSD_TYPE}=="mount-LUKS", ACTION=="remove", ENV{CRYPTOSD_TYPE}="mount-removed", ENV{UDISKS_NAME}="mount_crypto_removed", ENV{SYSTEMD_WANTS}="", ENV{SYSTEMD_USER_WANTS}="", PROGRAM=="/bin/systemd-escape --template=mount-cryptosd-luks@.service %E{DM_NAME}", RUN{program}+="/bin/systemctl stop %c" +KERNEL!="dm-[0-9]*", GOTO="cryptosd_mount_end" + +# Carefully match resulting virtual node dm-[0-9]* to trigger mounting it; see /lib/udev/rules.d/10-dm.rules for details +ENV{ID_FS_USAGE}=="filesystem", ENV{DM_UDEV_RULES_VSN}=="[2-9]", ENV{DM_NAME}=="????????-????-????-????-????????????|????-????", ACTION=="change", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="0", ENV{CRYPTOSD_TYPE}="mount-LUKS", ENV{UDISKS_SYSTEM}="0", ENV{UDISKS_AUTO}="0", ENV{UDISKS_NAME}="mount_cryptosd_luks_%E{DM_NAME}", MODE="0660", TAG+="systemd", PROGRAM=="/bin/systemd-escape --template=mount-cryptosd-luks@.service %E{DM_NAME}", ENV{SYSTEMD_WANTS}="%c" +ENV{CRYPTOSD_TYPE}=="mount-LUKS", ACTION=="remove", ENV{CRYPTOSD_TYPE}="mount-removed", ENV{UDISKS_NAME}="mount_cryptosd_removed", ENV{SYSTEMD_WANTS}="", ENV{SYSTEMD_USER_WANTS}="", PROGRAM=="/bin/systemd-escape --template=mount-cryptosd-luks@.service %E{DM_NAME}", RUN{program}+="/bin/systemctl stop %c" # Ditto for DM-Crypt "plain" -KERNEL=="dm-[0-9]", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", ENV{DM_UDEV_RULES_VSN}=="[2-9]", ENV{DM_NAME}=="mmcblk1*|sd[a-z][0-9]", ACTION=="change", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="0", ENV{CRYPTOSD_TYPE}="mount-PLAIN", ENV{UDISKS_SYSTEM}="0", ENV{UDISKS_AUTO}="0", ENV{UDISKS_NAME}="mount_crypto_plain_%E{DM_NAME}", MODE="0660", TAG+="systemd", ENV{SYSTEMD_WANTS}="mount-cryptosd-plain@%E{DM_NAME}.service" -KERNEL=="dm-[0-9]", ENV{CRYPTOSD_TYPE}=="mount-PLAIN", ACTION=="remove", ENV{CRYPTOSD_TYPE}="mount-removed", ENV{UDISKS_NAME}="mount_crypto_removed", ENV{SYSTEMD_WANTS}="", ENV{SYSTEMD_USER_WANTS}="", RUN{program}+="/bin/systemctl stop mount-cryptosd-plain@%E{DM_NAME}.service" +ENV{ID_FS_USAGE}=="filesystem", ENV{DM_UDEV_RULES_VSN}=="[2-9]", ENV{DM_NAME}=="mmcblk[1-9]*|sd*|sr*", ACTION=="change", ENV{DM_UDEV_PRIMARY_SOURCE_FLAG}=="1", ENV{DM_ACTIVATION}=="1", ENV{DM_SUSPENDED}=="0", ENV{CRYPTOSD_TYPE}="mount-PLAIN", ENV{UDISKS_SYSTEM}="0", ENV{UDISKS_AUTO}="0", ENV{UDISKS_NAME}="mount_cryptosd_plain_%E{DM_NAME}", MODE="0660", TAG+="systemd", ENV{SYSTEMD_WANTS}="mount-cryptosd-plain@%E{DM_NAME}.service" +ENV{CRYPTOSD_TYPE}=="mount-PLAIN", ACTION=="remove", ENV{CRYPTOSD_TYPE}="mount-removed", ENV{UDISKS_NAME}="mount_cryptosd_removed", ENV{SYSTEMD_WANTS}="", ENV{SYSTEMD_USER_WANTS}="", RUN{program}+="/bin/systemctl stop mount-cryptosd-plain@%E{DM_NAME}.service" + +LABEL="cryptosd_mount_end"