Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unlocking pass_secret_service doesn't require password. #32

Open
amano-kenji opened this issue Aug 4, 2022 · 12 comments
Open

Unlocking pass_secret_service doesn't require password. #32

amano-kenji opened this issue Aug 4, 2022 · 12 comments

Comments

@amano-kenji
Copy link

amano-kenji commented Aug 4, 2022

Because pass_secret_service doesn't actually have password?

Am I supposed to lock and unlock gpg?

@michaelk83
Copy link

Related to #11.

Am I supposed to lock and unlock gpg?

Probably, for now.

@michaelk83
Copy link

The way it's done with GPG KWallet, is you set up a passphrase-protected key via the likes of Kgpg or Kleopatra, and use that for the GPG encryption. The passphrase is prompted by GPG via pinentry, and can be cached in gpg-agent if you have it set up. Note that this means that anyone can decrypt your secrets without re-entering the passphrase, as long as it remains cached. If you want to require re-entry of the passphrase, you should either disable (or not set up) gpg-agent, or clear it when needed.

One other thing to look out for: pinentry will try to get the passphrase from Secret Service by default, which is not possible if Secret Service is backed by GPG (the same GPG that's asking for its own passphrase). This is the same bug as kwallet/#458085. The fix is to set the no-allow-external-cache option in ~/.gnupg/gpg-agent.conf, either manually, or by running echo no-allow-external-cache:8:1 | gpgconf --change-options gpg-agent.

This was referenced Sep 7, 2022
@michaelk83
Copy link

Note that this means that anyone can decrypt your secrets without re-entering the passphrase, as long as it remains cached. If you want to require re-entry of the passphrase, you should either disable (or not set up) gpg-agent, or clear it when needed.

Since I don't use GPG often, I forgot there are TTL options to remove keys from the cache automatically after some time period, mainly --default-cache-ttl and --max-cache-ttl. There are many different configuration options, so have a look at the manual and documentation.
https://man.archlinux.org/man/gpg-agent.1
https://www.gnupg.org/documentation/manuals/gnupg/Agent-Options.html

@amano-kenji
Copy link
Author

The fix is to set the no-allow-external-cache option in ~/.gnupg/gpg-agent.conf

Is this the fix for this issue?

@michaelk83
Copy link

michaelk83 commented Sep 8, 2022

The fix is to set the no-allow-external-cache option in ~/.gnupg/gpg-agent.conf

Is this the fix for this issue?

That's the fix for pinentry trying to read the GPG key passphrase from Secret Service, which would not work with pass_secret_service. (The stuff I'm talking about in the 2nd paragraph of that comment.)

The fix for the whole issue (or at least one possible fix) is everything I wrote about, put together:

  1. Set up a passphrase-protected GPG key.
  2. Set pass to use that GPG key (if you've already encrypted stuff with a different key, you'll need to decrypt them with the old key first).
  3. Set the no-allow-external-cache option to avoid the pinentry problem.
  4. Set the TTL options to make sure your keys are automatically cleared from gpg-agent when needed (as long as they stay cached, you won't be asked for the passphrase again).

@michaelk83
Copy link

if you've already encrypted stuff with a different key, you'll need to decrypt them with the old key first

I suggest setting up the new key on a fresh sub-folder with pass init -p, and then copying stuff from the old folder into the new one with pass cp. See the manual.

Note that haven't tried any of this myself, so make a backup, and proceed cautiously at your own risk...

@amano-kenji
Copy link
Author

amano-kenji commented Sep 9, 2022

Can you document this somewhere? The problem for me is that pam_gnupg automatically unlocks GPG upon unlock of swaylock and during login.

@michaelk83
Copy link

I'm not associated with this project, I only found it when discussing Secret Service over at bugs.kde.org (specifically, bug 399232). Most of this is documented in the manuals and webpages of pass and gpg-agent, as well various websites like Arch wiki. It's not specific to this project, which only provides a bridge between pass and Secret Service.

The only thing not documented in those places is the pinentry issue and fix for it, which I got from KDE bug 458085. (The option itself is documented in the manuals, but it's not obvious that you'll probably need to use it here).

From my point of view, the information I provided here and in #23 (comment) is enough aggregation of those sources. I hope it is useful, but that's as far as I'll be going with this, at least for now.

The problem for me is that pam_gnupg automatically unlocks GPG upon unlock of swaylock and during login.

You can disable pam_gnupg if you want. But even if not, the TTL options should clear the key from gpg-agent after some timeout, so you'll need to re-enter the passphrase after that. Do read the user guides and manuals of those tools.

@amano-kenji
Copy link
Author

amano-kenji commented Sep 11, 2022

Adding no-allow-external-cache to ~/.gnupg/gpg-agent.conf doesn't fix the issue.

Unlocking pass_secret_service doesn't require GPG password at all. It doesn't require any password.

But, opening a password entry in pass_secret_service may require entering GPG password if password is not cached in gpg-agent's internal cache.

I think secret service is not aware of pinentry or GPG.

@michaelk83
Copy link

As I understand it, pass_secret_service merely provides a thin translation layer from Secret Service API to pass backend. So all the password handling is done by pass, and since pass relies on GPG for its encryption, that means that in practice, all the password handling is done by GPG. This is the same as if you set up a KWallet with a GPG wallet: the password handling would be done by GPG in that case, not by KWallet.

Unlocking pass_secret_service doesn't require GPG password at all. It doesn't require any password.

I'm not even sure what you mean by "Unlocking pass_secret_service"? Calling the Secret Service Unlock() method?
pass_secret_service doesn't have any UI or store of its own, so what else is there to unlock besides the passwords in the pass backend?

When you (or a client app) call the Secret Service Unlock() method, what should (theoretically) happen is:

  1. pass_secret_service translates the requested Secret Service object paths to the matching entries in the pass backend.
  2. pass_secret_service asks the pass backend to unlock those entries.
  3. pass backend asks GPG to do the same.
  4. If the relevant keys are not cached, GPG asks for their passphrases.
  5. Unlocking ensues.

But, opening a password entry in pass_secret_service may require entering GPG password if password is not cached in gpg-agent's internal cache.

That is the correct behavior, in my understanding. I'm not sure what else you want to happen here.

I think secret service is not aware of pinentry or GPG.

The Secret Service API is not aware of the backend at all, and doesn't care about it. However, pass_secret_service is aware of the pass backend. It's still not directly aware (and shouldn't be) of GPG and pinentry. If pass were to implement a different mechanism for encryption and password handling, pass_secret_service would still work the same in its part.

Adding no-allow-external-cache to ~/.gnupg/gpg-agent.conf doesn't fix the issue.

Have you properly read #32 (comment) ?

If you're already using a passphrase-protected GPG key, then the main thing to do is set the TTL options, mainly --default-cache-ttl and --max-cache-ttl, so that your keys aren't cached longer than they need to be.

no-allow-external-cache only addresses a related side-issue: it prevents pinentry from trying to read the passphrase from Secret Service, which with pass_secret_service would mean trying to read it from the same GPG store that you need the key to unlock. It's like trying to get the key for your vault from inside that same vault, while it's locked.

But if your keys are still cached in gpg-agent, pinentry won't even be called, so of course no-allow-external-cache won't do anything in that case. The TTL options address the caching.

@amano-kenji
Copy link
Author

I'm not even sure what you mean by "Unlocking pass_secret_service"? Calling the Secret Service Unlock() method?

I locked and unlocked pass_secret_service via seahorse which is a GUI frontend to secret service API.

According to my tests, pass_secret_service's implementation of Unlock() doesn't seem to pass password request to GPG or pinentry.

On the other hand, when I tried to view a specific password entry, I was prompted to enter a password into pinentry.

I cleared GPG internal password cache before testing this.

My conclusion is that pass_secret_service should pass password request to pinentry, but it doesn't now.

@michaelk83
Copy link

I see. I'm not familiar enough with pass to say for sure, but it's possible that it operates on an "unlock-when-needed" model, rather than "unlock-in-advance". Since it stores each password in a separate encrypted file, there isn't any reason to decrypt it until the password is actually needed. If that's the case, a global Unlock() call to pass_secret_service wouldn't actually do anything.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants