Public Access
Give the seated user the TPM, so nobody has to join the tss group
ADR 0007 decision 4 refused this a commit ago, on the grounds that widening
access to the machine's TPM is a system-wide decision an application package
should not make for an administrator. That refusal is overturned here, and the
reasoning it is replaced with is narrower rather than louder — because the
refusal had treated "widen access" as one thing when it is two.
Adding a person to `tss` is what the refusal was really about, and it stays the
wrong answer: permanent, effective over SSH, applying whether or not they are at
the keyboard, and needing an administrator and a fresh login before the feature
appears at all.
Tagging /dev/tpmrm0 with `uaccess` is a different thing. It is systemd's own
mechanism for this exact question — the one /dev/dri, webcams, scanners and FIDO
keys already use — and logind grants the ACL to the user of the *active local
session*, then takes it back when that session ends. Not over SSH, not on an
inactive VT, not to daemons. The rule changes neither the mode nor the group, so
everything that worked before still works and the ACL is layered on top.
tpmrm and never tpm, which is what makes it defensible at all: /dev/tpm0 is the
raw device and is exclusive, where /dev/tpmrm0 is the kernel's resource manager,
which virtualises handles and isolates callers precisely so that more than one
unprivileged program can use the chip.
◆ THE COST IS A DENIAL OF SERVICE AND NOT A DISCLOSURE, AND IT IS WRITTEN DOWN.
TPM objects are protected by their own auth values, so this lets nobody read
anybody else's sealed data. What it allows is *failed* attempts — and a TPM
answers enough of those by locking out everyone, which is the same anti-hammering
this project relies on to make a four-digit PIN safe. On a machine that unlocks
its disk with the TPM at boot, somebody sitting at it can trip that and stop the
next boot from unlocking until it recovers.
An administrator who does not accept that masks the file:
sudo ln -s /dev/null /etc/udev/rules.d/71-dodossh-tpm.rules
which is the standard override, survives upgrades, and puts DodoSSH back to
behaving as though the machine had no TPM. That is in the rule's own comments,
because the person who needs it is reading the file rather than the ADR.
Numbered 71 because 60-tpm-udev.rules is what creates the node's ownership and
73-seat-late.rules is what turns the tag into an ACL; verified in that order on
Fedora 44, along with `udevadm verify` accepting the file and the mask being
reported as "masked by previous entry". %post reloads and replays it against the
tpmrm subsystem, because a rule that waits for a reboot is a feature that does
not work on the day it is installed.
Both channels install the same path deliberately: this is about the machine's
TPM rather than about either build, the file is byte-identical from both, and
giving each its own copy would mean removing one package silently revoked the
other's access.
Phase 19 grew a check that the ACL exists for the local session and does *not*
exist for an SSH one, and another that masking the rule really does put the
machine back — then tells you to undo it before the checks that follow.
Also recorded, after it cost five confusing failures: swtpm serves exactly one
client, so a shell readiness probe sitting on the port makes the whole device-key
suite fail with "The TPM closed the connection" and nothing pointing at why.
This commit is contained in:
1 parent
4552538533
commit
c2c860b4f2
10 files changed
+220
-48
No files matched your search
+53
-26
@@ -2849,11 +2849,12 @@ because nothing on this platform refuses an unsigned package, which is a distinc
|
||||
is fine"; `build/linux/dodossh.spec` says what stands in for a signature, which is that the package comes
|
||||
from the project's own forge over TLS and from nowhere else.
|
||||
|
||||
Everything else is here, and two things are here that neither other phase has. **The update does not
|
||||
install itself**, so 19.7 is about watching a polkit prompt appear and saying no to it, where phases 16 and
|
||||
18 watch an application replace itself. And **the device key's gate is a PIN rather than a gesture**, with
|
||||
the TPM's own lockout behind it — so 19.6 is the one check in this document that deliberately breaks
|
||||
something and then tells you how to put it back.
|
||||
Everything else is here, and three things are here that neither other phase has. **The update does not
|
||||
install itself**, so 19.8 is about watching a polkit prompt appear and saying no to it, where phases 16 and
|
||||
18 watch an application replace itself. **The device key's gate is a PIN rather than a gesture**, with the
|
||||
TPM's own lockout behind it — so 19.7 deliberately breaks something and then tells you how to put it back.
|
||||
And **this package changes a permission on the machine**: 19.4 and 19.5 are about the udev rule that gives
|
||||
the seated user the TPM, checking both that it works and that masking it undoes it completely.
|
||||
|
||||
What this phase is for is the set nobody else can answer. **CI builds this package and installs nothing**,
|
||||
and every check in `scripts/ci-linux-rpm.sh` is a check on what the package *says* — its dependencies, its
|
||||
@@ -2909,32 +2910,58 @@ are the package's binary name, so they can only disagree if one was edited. A bl
|
||||
48-pixel file missing and the 256 being scaled down; `dodossh-icon.ps1` draws four sizes and the spec
|
||||
installs four.
|
||||
|
||||
### 19.4 With no access to the TPM, no device key is offered at all
|
||||
### 19.4 The udev rule gives *this* session the TPM, and gives nobody else it · **needs a real TPM**
|
||||
|
||||
On a stock Fedora install your account is not in the `tss` group, so this is the state most people are in.
|
||||
Confirm it — `id -nG | tr ' ' '
|
||||
' | grep -x tss` prints nothing — then open the security settings page.
|
||||
Installing the package should be the whole setup — no group, no administrator, no fresh login. Check it
|
||||
from a graphical session on the machine itself:
|
||||
|
||||
**Pass:** registering a device key is **not** offered, and unlocking asks for the passphrase every time.
|
||||
```bash
|
||||
getfacl /dev/tpmrm0 | grep "^user:"
|
||||
id -nG | tr ' ' '
|
||||
' | grep -x tss # expect nothing: you are not in the group
|
||||
```
|
||||
|
||||
**Failure means:** being offered it is `LinuxDeviceKeyStore.IsSupported` having answered from the presence
|
||||
of the device node rather than from opening it. Accepting the offer would put a wrap on the server that
|
||||
nothing can ever open — and the failure would arrive at the next unlock rather than now.
|
||||
**Pass:** `getfacl` shows a `user:<you>:rw-` entry that is **not** there for any other account, and you are
|
||||
not in `tss`. Now `ssh` into the same machine from elsewhere and run the same `getfacl`: the entry for you
|
||||
is still the *local* session's, and a shell that is not on the seat cannot open the device — `head -c1
|
||||
/dev/tpmrm0` answers "Permission denied".
|
||||
|
||||
### 19.5 With access to the TPM, the PIN unlocks and the TPM is what checks it
|
||||
**Failure means:** no ACL at all is the rule not having been applied. `udevadm test --action=change
|
||||
/sys/class/tpmrm/tpmrm0 | grep uaccess` says whether the tag is being set, and the load order matters —
|
||||
71 has to fall between `60-tpm-udev.rules` and `73-seat-late.rules`, which is what turns the tag into an
|
||||
ACL. If the file is present and untagged, check nothing in `/etc/udev/rules.d` is masking it. **An ACL
|
||||
granted to a remote session would be the serious one**, and would mean the tag had been put on `tpm` rather
|
||||
than `tpmrm` or the mode widened instead — neither of which this rule does.
|
||||
|
||||
`sudo usermod -aG tss $USER`, log out and back in, then register a device key from the security settings
|
||||
page and choose a PIN. Lock the vault and unlock it again.
|
||||
### 19.5 Masking the rule puts the machine back the way it was
|
||||
|
||||
```bash
|
||||
sudo ln -s /dev/null /etc/udev/rules.d/71-dodossh-tpm.rules
|
||||
sudo udevadm control --reload && sudo udevadm trigger --subsystem-match=tpmrm --action=change
|
||||
```
|
||||
|
||||
Log out and back in, then open the security settings page.
|
||||
|
||||
**Pass:** registering a device key is **not** offered, and unlocking asks for the passphrase every time —
|
||||
the same behaviour as a machine with no TPM. `udevadm test` reports the file as "masked by previous entry".
|
||||
|
||||
**Failure means:** still being offered it means `LinuxDeviceKeyStore.IsSupported` answered from the presence
|
||||
of the device node rather than from opening it. Accepting that offer would put a wrap on the server that
|
||||
nothing can ever open, and the failure would arrive at the next unlock rather than now.
|
||||
|
||||
**Then undo it** — `sudo rm /etc/udev/rules.d/71-dodossh-tpm.rules` and reload — before 19.6.
|
||||
|
||||
### 19.6 The PIN unlocks, and the TPM is what checks it
|
||||
|
||||
Register a device key from the security settings page and choose a PIN. Lock the vault and unlock it again.
|
||||
|
||||
**Pass:** registering asks for a PIN twice and shows no other prompt. Unlocking asks for it once and opens
|
||||
the vault. Cancelling that prompt lands on the passphrase screen, which works.
|
||||
|
||||
**Failure means:** no offer after joining the group is `/dev/tpmrm0` still unreadable — check `ls -l` on it
|
||||
and that the login really was restarted, because group membership is fixed at session start. A PIN prompt
|
||||
that opens the vault whatever you type would mean the unseal is not reaching the TPM at all, which is the
|
||||
one failure that would make this whole feature decorative.
|
||||
**Failure means:** a PIN prompt that opens the vault whatever you type would mean the unseal is not reaching
|
||||
the TPM at all, which is the one failure that would make this whole feature decorative.
|
||||
|
||||
### 19.6 A wrong PIN gets nothing, and the TPM stops answering
|
||||
### 19.7 A wrong PIN gets nothing, and the TPM stops answering
|
||||
|
||||
With a device key registered, lock the vault and enter a wrong PIN. Do it several times.
|
||||
|
||||
@@ -2949,7 +2976,7 @@ assertion against real firmware, where the lockout is real and recovery takes ho
|
||||
**Then put it back:** `sudo tpm2_dictionarylockout --clear-lockout`, or wait out the recovery time. Note
|
||||
which, because a user who trips this will ask — and the honest answer is that it needs an administrator.
|
||||
|
||||
### 19.7 An update is noticed, fetched, and installed by PackageKit and not by DodoSSH
|
||||
### 19.8 An update is noticed, fetched, and installed by PackageKit and not by DodoSSH
|
||||
|
||||
With the nightly installed, wait for a newer one to be published — or press **CHECK NOW** on
|
||||
PREFERENCES → UPDATES once there is one.
|
||||
@@ -2967,7 +2994,7 @@ covers the algorithm. A message naming PackageKit means it is not installed; it
|
||||
minimal install legitimately lacks it. **The vault locking or shells closing when you decline is the
|
||||
serious one** — it means `ApplyingEndsTheProcess` has been set true, which punishes somebody for saying no.
|
||||
|
||||
### 19.8 A tampered package is refused before PackageKit ever sees it
|
||||
### 19.9 A tampered package is refused before PackageKit ever sees it
|
||||
|
||||
Not reachable without editing the feed, so this is the one to reason about rather than perform unless you
|
||||
are changing that code: the manifest's `sha256` is checked after the download and the file is deleted if it
|
||||
@@ -2978,7 +3005,7 @@ does not match.
|
||||
**Failure means:** a leftover `.rpm` there after a failed update is a file somebody could reasonably install
|
||||
by hand, named as though the application had endorsed it.
|
||||
|
||||
### 19.9 The nightly installs beside the release rather than over it
|
||||
### 19.10 The nightly installs beside the release rather than over it
|
||||
|
||||
With the release package installed, install the nightly one too.
|
||||
|
||||
@@ -2991,7 +3018,7 @@ nightly that opens the release's vault already unlocked is the profile separatio
|
||||
`DodoChannel=nightly` reaching `ClientPaths`, not from the packaging, so check
|
||||
`~/.local/share/dodossh.nightly` exists rather than looking at the spec.
|
||||
|
||||
### 19.10 Nothing in the installed tree is writable by anyone but root
|
||||
### 19.11 Nothing in the installed tree is writable by anyone but root
|
||||
|
||||
```bash
|
||||
find /opt/DodoSSH ! -user root -o -perm -o+w
|
||||
@@ -3005,7 +3032,7 @@ model walked around rather than attacked. `ci-linux-rpm.sh` refuses to produce s
|
||||
sets every mode absolutely, so a hit here means one of those two was changed — it cannot arrive by accident
|
||||
from a publish directory.
|
||||
|
||||
### 19.11 Removing it leaves the vault, and leaves the other channel alone
|
||||
### 19.12 Removing it leaves the vault, and leaves the other channel alone
|
||||
|
||||
Register a device, sync something, then `sudo dnf remove dodossh`.
|
||||
|
||||
|
||||
Reference in new issue
Block a user