fs/config: only run --password-command once when using --daemon - #9872
Merged
Merged
Conversation
Decrypting the config with --daemon runs --password-command twice, which means two authentications when the command needs one, such as a hardware key touch for `pass show`. SetConfigPassword saves the obscured key to the temp file named by _RCLONE_CONFIG_KEY_FILE so the daemon process can pick it up, but the process that wrote it then read and deleted that file itself before daemonizing. The daemon started with the variable pointing at a file that was already gone, found no key, and ran the password command again. Skip acquiring a password when _RCLONE_CONFIG_KEY_FILE is set, as the PassConfigKeyForDaemonization documentation already describes, and only consume the key file in a process that has no key of its own. The parent then leaves the key for the daemon, and the daemon uses it. Fixes rclone#7341
ncw
approved these changes
Sep 8, 2026
ncw
left a comment
Member
There was a problem hiding this comment.
Thank you :-)
One thing you noted that I agree is worth a follow-up: if the parent fails after loading the config but before the daemon starts (say the remote does not exist), the temp key file is left behind. That was already true for the interactive prompt, so no regression, but removing it from the parent at exit would tidy that up if you felt like a second PR.
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What does this change do?
With
--daemon,--password-commandis run twice, so a command that needs an authentication — the issue's exampleis
pass show, which wants a hardware key touch — asks for it twice.SetConfigPasswordsaves the obscured key to the temp file named by_RCLONE_CONFIG_KEY_FILEso the daemon processcan pick it up. But the process that wrote that file then read and deleted it itself, on the very next pass through
Decrypt's loop, before it daemonized. The daemon started with the variable pointing at a file that was alreadygone, found no key, and ran the password command a second time.
Two guards fix it, both restoring behaviour that is already documented or already implemented elsewhere:
_RCLONE_CONFIG_KEY_FILEis set. ThePassConfigKeyForDaemonizationdoc commentalready says "If
_RCLONE_CONFIG_KEY_FILEis present, password prompt is skipped andRCLONE_CONFIG_PASSignored" — the code just did not honour it for the pre-loop password acquisition.
leaves it in place.
This makes
--password-commandbehave the way typing the password manually already does. On the manual pathgetConfigPasswordis called from inside the loop, after the_RCLONE_CONFIG_KEY_FILEcheck, so the parent neverreads back the file it just wrote — which matches @ncw's comment on the issue that the manual case works and there is
already a mechanism for this.
One consequence worth naming: now that the parent no longer consumes its own key file, a temp file holding the
obscured key survives if the daemon child never starts. That is already what the manual-password path does today, so
it is not a new class of exposure, but it is a real difference from the previous
--password-commandbehaviour.Testing
TestConfigLoadEncryptedWithPassCommandAndDaemonwalks the handoff in one process: it loads the config withPassConfigKeyForDaemonizationset, asserts the key file still exists afterwards, then clears the key to simulatethe daemon starting and loads again with
--password-commandchanged to return the wrong password. The secondload can only succeed by using the key file, and the file must be gone afterwards.
I checked the test pins both guards rather than merely passing, by mutating them one at a time:
_RCLONE_CONFIG_KEY_FILEguard → the simulated daemon re-runs the command, gets the wrongpassword and fails to decrypt;
len(configKey) == 0guard on the key-file read → the parent deletes its own key file and the firstassertion fails.
go build ./...,make quicktestandgolangci-lint run ./fs/config/...all pass.No documentation change: the intended behaviour is already described in the
PassConfigKeyForDaemonizationcomment.Linked issue
Fixes #7341
Checklist
test_allpasses for this backend — not a backend change.