hwchen / keyring-rs

Cross-platform library and utility to manage passwords
Apache License 2.0
450 stars 49 forks source link

Automatically fallback if a default Linux keyring is not available? #133

Closed connor4312 closed 1 year ago

connor4312 commented 1 year ago

I recently enabled systemd under WSL and tried our application there. I ran into a problem that credentials were not getting stored correctly, and using gdbus introspect found that there was only a session ('/org/freedesktop/secrets/collection/session') credential collection, and no default collection.

I wondered whether it would be appropriate for this crate to automatically fallback to the session collection (i.e. get_any_collection() from SS) if the default collection doesn't exist.

connor4312 commented 1 year ago

It's actually a little tricky to set this manually. I tried using get_any_collection() and passing the collection path as the keyring "target", but this ended up with a collection whose alias was the that path instead of just being the session, and SS doesn't have a get_alias() method on its Collection. (Is it just the path basename? I'm not a keyring expert.) Perhaps this should be documented too 🙂

brotskydotcom commented 1 year ago

Why are you trying to run a linux build of keyring on a Windows box? Can't you just use the Windows build?

Since WSL typically runs headless, and headless Windows doesn't have an accessible secure store (sort of like headless Linux), it's not clear to me what the behavior of a default collection would be or how it would be secured. Perhaps that existing collection is just a bridge to the underlying Windows secure store?

If you really want to use a linux build of keyring on Windows under WSL, I think you will need to use the secret-service crate directly to create a new collection with the "default" alias before you make any keyring calls. I don't know what that new collection's semantics would be in terms of security or persistence across sessions. Probably some experimentation is called for.

connor4312 commented 1 year ago

This is running in WSL which is effectively an Ubuntu VM. It's also actually default behavior, I believe, to X forward back to Windows, so for example when unlocking my keyring in WSL I see the ubuntu keyring password prompt. But I think that's not super relevant for the issue.

I'm guessing you could hit this by manually installing gnome-keyring and dependencies on a base Ubuntu server image. For instance it looks like another user hit this same issue, or at least the same symptoms I was getting, on a Raspberry Pi https://github.com/microsoft/vscode-remote-release/issues/8628

It's actually a little tricky to set this manually. I tried using get_any_collection() and passing the collection path as the keyring "target", but this ended up with a collection whose alias was the that path instead of just being the session, and SS doesn't have a get_alias() method on its Collection. (Is it just the path basename? I'm not a keyring expert.) Perhaps this should be documented too 🙂

I think documenting this is still worthwhile ^

brotskydotcom commented 1 year ago

I agree this is worth documenting, which is why I have updated the docs of the the secret-service keystore to note this problem when running under WSL. In the docs I refer to this issue for more detail. That doc update is why I closed this documentation bug. Do you think there's something more that can be done in the docs?

Separately, I still don't think I understand what your expectations are around this working "out of the box". My understanding is that creation of the default (login) collection on Linux boxes is typically done by Gnome driven from PAM, and that WSL (both 1 and 2) do not use PAM for login even when running graphic apps. I think you are going to have to run some secret-service code to create a default collection on your WSL if you want the secret service keystore to work as expected. You should only have to do this once on each machine, but since the code is idempotent you could just do it every time as part of your startup.

One last thought: Is there a way of detecting whether the current process is running under WSL? If so, we could possibly update the keyring's secret-service keystore to detect WSL and create a default collection if there isn't one. Even if detection of WSL isn't possible, I suppose we could control this behavior with environment variables, but I wouldn't want to add code that always creates a default collection rather than throwing an error (on every platform).

connor4312 commented 1 year ago

I would note that this is not exclusive to WSL. I verified that I was able to get the exact same behavior with a simple apt install gnome-keyring on a Ubuntu server machine I had lying around, so it seems to be more a property of "headless" installs.

I don't really have the keychain expertise to recommend the best solution here, and I think it's a case-by-case basis as well--a session keychain is probably not the right solution for our case, but it could be for others'. The Python keyring project has some instructions for this too https://pypi.org/project/keyring/#using-keyring-on-headless-linux-systems

brotskydotcom commented 1 year ago

The difficulties with using the secret-service keystore on headless Linux systems have been documented in the keyring docs since version 1.0. See my comments above about WSL running headless and this section of the docs for details.

Since you are running on WSL which is on Windows, and you can run windows executables from your Linux environment, my suggestion (also made above) would be that you use the Windows build of keyring rather than the Linux one. You could, for instance, invoke the keyring cli example from your development environment to both set and read your credentials.