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

Use the keyring python module with gnome-keyring #609

Open
rkouznetsov opened this issue Dec 1, 2022 · 3 comments
Open

Use the keyring python module with gnome-keyring #609

rkouznetsov opened this issue Dec 1, 2022 · 3 comments

Comments

@rkouznetsov
Copy link

Not exactly a bug, but a lack of documentation. Sorry if it is not the right use of keyring.

In a shell script I can get a needed password from gnome-keyring to a variable or feed it via pipe to some program:

passwd=$(secret-tool lookup user myname domain somehost.com)

If I got it right, keyring can be used for the same purpose in a python script. I could not find any minimal working example example to do that in python with keyring module. There probably must be a better way than using os.popen(cmd).read() with the above shell command...

The example from the README file

$ python
  >>> import keyring
  >>> keyring.get_keyring()
  <keyring.backends.SecretService.Keyring object at 0x7f9b9c971ba8>
  >>> keyring.set_password("system", "username", "password")
  >>> keyring.get_password("system", "username")

launces "KDE Wallet Service" configuration which is not relevant for me, since I use gnome-keyring...

Thank you!

Environment

  • OS: Ubuntu 22.04
$ dpkg -l |grep python3-keyring
ii  python3-keyring                               23.5.0-1                                all          store and access your passwords safely
$ keyring --list-backends
keyring.backends.kwallet.DBusKeyring (priority: 4.9)
keyring.backends.fail.Keyring (priority: 0)
keyring.backends.chainer.ChainerBackend (priority: 10)
keyring.backends.libsecret.Keyring (priority: 4.8)
@jaraco
Copy link
Owner

jaraco commented Dec 7, 2022

Keyring tries to use the most relevant backend available, and in your environment, it believes the kwallet.DBusKeyring is the best backend for your environment. You can see that preference in the debugging command (DBusKeyring has the highest priority at 4.9). My guess is you probably want to be using the SecretService backend, but for whatever reason, it's not viable on your system.

See the section in the readme on configuring for headless Linux systems, which gives some tips around making the SecretService backend work in constrained environments.

You can also manually construct that backend:

import keyring.backends.SecretService
kr = keyring.backends.SecretService.Keyring()
kr.priority

You'll get an exception when kr.priority runs indicating why it's not viable (probably "SecretStorage required" or similar).

You can configure keyring to manually use that keyring on your system, but that's not going to help you any if that keyring isn't viable, so I'm assuming you don't want that.

When it comes to coding for others to use, you'll want to simply use keyring.get_password/set_password, etc., and leave it to the library to resolve the best backend for each user.

Hope that helps.

@rkouznetsov
Copy link
Author

Thank you! I have checked the manual about a headless setup.
Looks like by default in Ubuntu Mate 22.04 the library fails to resolve the best backend.

keyring.get_password call triggers a dialog
Untitled
despite gnome-keyring-daemon is perfectly up and running.

kr.priority complains about

---> 3 kr.priority

/usr/lib/python3/dist-packages/keyring/util/properties.py in __get__(self, cls, owner)
     22 
     23     def __get__(self, cls, owner):
---> 24         return self.fget.__get__(None, owner)()
     25 
     26 

/usr/lib/python3/dist-packages/keyring/backends/SecretService.py in priority(cls)
     46                     )
     47         except exceptions.SecretStorageException as e:
---> 48             raise RuntimeError("Unable to initialize SecretService: %s" % e)
     49         return 5
     50 

RuntimeError: Unable to initialize SecretService: Environment variable DBUS_SESSION_BUS_ADDRESS is unset

secret-tool works just fine in the same environment. So there must be some other way secret-tool knows about DBUS (or works with gnome-keyring without it)...

@takluyver
Copy link
Contributor

Is there anything odd about your terminal or shell session, which could cause an environment variable from your login not to show up there?

D-Bus is normally launched, and that environment variable set, when you log in. There is a fallback way to find the D-Bus session bus using X11, which might be how secret-tool is working. The pure-Python code behind the SecretService backend doesn't implement this fallback - I wrote the D-Bus layer for this, but I'd rather not delve into X APIs when that's clearly not the way the world is going.

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

3 participants