mirror of
https://github.com/narrrl/proton-drive-linux.git
synced 2026-11-15 01:41:59 +01:00
fix(core): reconnect to the Secret Service after it restarts
The keyring store keeps one D-Bus connection and one Secret Service session for the whole process, and was installed once. The session lives only in the provider's memory, so after the provider restarts every read and write on it fails with NoSession until the process restarts. oo7, the provider on Fedora 45, restarts on failure and can be replaced. A daemon that met this kept every later token refresh only in memory and the kernel keyring, and the next cold boot found the spent refresh token (issue #78, B285). Every keyring call now goes through with_keyring_entry. A platform failure drops the store, unless another thread already replaced it, and the call is made once more on a new connection. A locked keyring, a dismissed prompt and a missing entry come back unchanged. Reproduced against gnome-keyring 51.1 and oo7 0.7.1 restarted with --replace in a throwaway session bus; the ignored test real_secret_service_survives_a_provider_restart passes against both. Refs #78
This commit is contained in:
1 parent
d773ba15d3
commit
38bd282d3a
4 files changed
+296
-29
No files matched your search
@@ -109,6 +109,7 @@ a live account since.
|
||||
|
||||
| Entry | Title |
|
||||
|---|---|
|
||||
| [B285](#b285--a-restarted-secret-service-leaves-the-process-on-a-dead-session) | A restarted Secret Service leaves the process on a dead session |
|
||||
| [B284](#b284--a-keyring-entry-reported-missing-discards-refreshed-session-tokens) | A keyring entry reported missing discards refreshed session tokens |
|
||||
| [B283](#b283--videos-have-no-thumbnail-outside-photos-and-a-ts-recording-looks-like-source-code) | Videos have no thumbnail outside Photos, and a `.ts` recording looks like source code |
|
||||
| [B282](#b282--a-file-kept-offline-is-downloaded-again-after-a-change-made-elsewhere) | A file kept offline is downloaded again after a change made elsewhere |
|
||||
@@ -387,6 +388,41 @@ a live account since.
|
||||
|
||||
Newest first.
|
||||
|
||||
### B285 — A restarted Secret Service leaves the process on a dead session
|
||||
|
||||
**Status:** Fixed (unverified)
|
||||
**Found:** 2026-11-14, following up [issue #78](https://github.com/narrrl/proton-drive-linux/issues/78)
|
||||
(signed out after every cold boot on Fedora 45, which replaced gnome-keyring with oo7). See
|
||||
[the investigation](ISSUE-78.md#a-restarted-secret-service).
|
||||
**Where:** `crates/pdfs-core/src/auth.rs`, `with_keyring_entry`
|
||||
|
||||
**Repro:** Write the session blob, restart the Secret Service provider
|
||||
(`gnome-keyring-daemon --replace`, or `oo7-daemon --replace`), then read or write it again from
|
||||
the same process. `dbus-secret-service-keyring-store` keeps one D-Bus connection and one Secret
|
||||
Service session for the life of the process, and pdfs installed it once. The session exists only
|
||||
in the provider's memory, so the new provider answers every `GetSecret` and `SetSecret` with
|
||||
`org.freedesktop.Secret.Error.NoSession`, for as long as the process runs. A fresh store in the
|
||||
same process reads the same entry fine. oo7's systemd unit restarts the daemon on failure, and
|
||||
both providers can be replaced, so the daemon could meet this mid-session. A token refresh after
|
||||
that point reached only memory and the kernel keyring: B61's retry kept asking on the dead
|
||||
session, and the next cold boot read the spent refresh token (`InvalidRefreshToken`).
|
||||
|
||||
**Fix:** Every keyring call goes through `with_keyring_entry`. A platform failure (which is what
|
||||
`NoSession` and other D-Bus errors become) logs "the Secret Service failed this process's
|
||||
connection; reconnecting", drops the store unless another thread already replaced it, and makes
|
||||
the call once more on a new connection and session. A locked keyring, a dismissed prompt and a
|
||||
missing entry come back unchanged. Affects the daemon, the app and the tray alike.
|
||||
|
||||
**Verified:** `auth::tests::a_dropped_secret_service_session_is_reconnected_and_retried`,
|
||||
`a_rotation_lands_at_once_after_the_keyring_restarts` and `a_locked_keyring_is_not_reconnected`
|
||||
on the in-memory store. The ignored `auth::tests::real_secret_service_survives_a_provider_restart`
|
||||
passes against gnome-keyring 51.1 and oo7 0.7.1 (built from its tag), each in a throwaway session
|
||||
bus and restarted with `--replace`; it checks that a reconnect actually happened. A standalone
|
||||
program holding one store, as before the fix, gets `NoSession` on read and write after the same
|
||||
restart under both providers. Whether the reporter's oo7 restarts during a session is not known.
|
||||
|
||||
---
|
||||
|
||||
### B284 — A keyring entry reported missing discards refreshed session tokens
|
||||
|
||||
**Status:** Fixed (unverified)
|
||||
|
||||
@@ -124,6 +124,14 @@ Existing folders stay device backups. Older builds cannot open the upgraded data
|
||||
screen there, and with nothing to scroll no more were loaded. More now load whenever the photos
|
||||
don't fill the window, also after a zoom or a resize.
|
||||
|
||||
- **Signed out after a cold boot on Fedora 45** (issue #78, B284, B285). Fedora 45 replaced the
|
||||
GNOME keyring with oo7, and two things there could keep a refreshed sign-in from being saved:
|
||||
oo7 reports the entries of a locked keyring as missing, which the client took for a sign-out,
|
||||
and a restarted oo7 no longer knew the client's connection, which then failed every save until
|
||||
the service restarted. The refreshed sign-in lived only in memory, and the next boot found the
|
||||
spent one. The client now keeps such a sign-in and saves it once the keyring can be read, and
|
||||
reconnects to a keyring service that restarted.
|
||||
|
||||
- **Thumbnails appear in the folder you are looking at as soon as they are made.** During
|
||||
**Build thumbnails**, the folder on screen kept its file icons until you left it and opened it
|
||||
again. Its tiles now fill in while the build runs, and the same goes for any tile whose
|
||||
|
||||
@@ -58,6 +58,44 @@ can resolve the default alias to a locked collection. Both have fixes in
|
||||
after the reporter's November 7 retest. Neither can be assigned as this report's cause without
|
||||
matching runtime evidence.
|
||||
|
||||
## A restarted Secret Service
|
||||
|
||||
A second path to the same symptom, independent of locking (B285). The keyring store pdfs used
|
||||
holds one D-Bus connection and one Secret Service session for the whole process, and was
|
||||
installed once. The session lives only in the provider's memory. When the provider restarts,
|
||||
the new one answers every `GetSecret` and `SetSecret` on the old session with
|
||||
`org.freedesktop.Secret.Error.NoSession`, until the pdfs process itself restarts. Reproduced
|
||||
with both gnome-keyring 51.1 and oo7 0.7.1 using `--replace`.
|
||||
|
||||
gnome-keyring practically never restarts within a desktop session. oo7 can:
|
||||
`oo7-daemon.service` has `Restart=on-failure`, the daemon allows itself to be replaced, and it
|
||||
exits on a wrong credential password and is D-Bus-activated again. A daemon that met a restarted
|
||||
provider kept every later token refresh only in memory and the kernel keyring, and a cold boot
|
||||
then left the spent refresh token in the saved blob.
|
||||
|
||||
Now a platform failure drops the store and the call is retried once on a new connection. The
|
||||
daemon log shows `the Secret Service failed this process's connection; reconnecting` when that
|
||||
happens. To check whether a machine meets this, look for oo7 restarts in the same boot:
|
||||
|
||||
```sh
|
||||
journalctl --user -b -1 -u oo7-daemon.service | grep -E 'Started|Stopped|Starting oo7|Main process exited'
|
||||
journalctl --user -b -1 -u proton-drive.service | grep -iE 'keyring|reconnecting|refresh'
|
||||
```
|
||||
|
||||
Reproduce in a throwaway session bus (never against the desktop's keyring; the runtime directory
|
||||
must be short, as it holds a Unix socket):
|
||||
|
||||
```sh
|
||||
T=$(mktemp -d /tmp/ss.XXXX); mkdir -p $T/data $T/run; chmod 700 $T/run
|
||||
XDG_DATA_HOME=$T/data XDG_RUNTIME_DIR=$T/run PDFS_SECRET_SERVICE_RESTART_TEST=1 \
|
||||
PDFS_RESTART_PROVIDER='echo -n pw | gnome-keyring-daemon --replace --unlock --components=secrets >/dev/null' \
|
||||
dbus-run-session -- sh -c 'echo -n pw | gnome-keyring-daemon --unlock --components=secrets >/dev/null; sleep 1;
|
||||
cargo test -p pdfs-core real_secret_service -- --ignored'
|
||||
```
|
||||
|
||||
For oo7, start `oo7-daemon --login` with the password on stdin instead, and restart it with
|
||||
`--login --replace` in the background.
|
||||
|
||||
## Reproduce without a Proton account or desktop keyring
|
||||
|
||||
The oo7 fixture uses fake tokens, a temporary disk keyring and a private peer-to-peer D-Bus
|
||||
|
||||
Reference in new issue
Block a user