[Bug 1864204] [NEW] nondeterministic failure when no keyring backends are available

Dan Streetman ddstreet at canonical.com
Fri Feb 21 15:07:24 UTC 2020


Public bug reported:

[impact]

when no backends are available for python-keyring, it will sometimes
silently ignore all requests to set or get credentials, and sometimes it
will raise RuntimeError for all requests.

[test case]

when there are no backends, there are 2 built-in backends that will be
the only ones available, the 'chainer' backend and the 'fail' backend.
The 'fail' backend always has priority 0, while the 'chainer' backend
has priority 10 if it contains any actual backends, and priority 0 if it
is empty.  So in the situtation where there are no actual backends, both
'chainer' and 'fail' will have priority 0.  Since the 'backends' class
stores its backend implementation instances in a python set(), which is
unordered, it is non-deterministic which of those backends are used at
any given time.

Since the behavior is non-deterministic, simply trying this multiple
times may result in each behavior.  Rebooting or logout/login can help
'switch' the behavior.


>>> import keyring
>>> [keyring.backend.get_all_keyring()]

the above python code will show the current list of backends, and since
they both have the same priority (in this situation) the first in the
list will be used.  If the list looks like:

[[<keyring.backends.chainer.ChainerBackend object at 0x7f1f7018f3d0>,
<keyring.backends.fail.Keyring object at 0x7f1f6fff0820>]]

with 'ChainerBackend' first, all keyring functions will return silently
with None, e.g.:

>>> keyring.set_password('test', 'test', 'test')
>>> keyring.get_password('test', 'test')
>>> 

with 'fail.Keyring' first, all keyring functions will raise
RuntimeError:

>>> import keyring
>>> [keyring.backend.get_all_keyring()]
[[<keyring.backends.fail.Keyring object at 0x7f3b6ade73d0>, <keyring.backends.chainer.ChainerBackend object at 0x7f3b6ac48820>]]
>>> keyring.set_password('test', 'test', 'test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/keyring/core.py", line 63, in set_password
    _keyring_backend.set_password(service_name, username, password)
  File "/usr/lib/python3/dist-packages/keyring/backends/fail.py", line 24, in get_password
    raise RuntimeError(msg)
RuntimeError: No recommended backend was available. Install a recommended 3rd party backend package; or, install the keyrings.alt package if you want to use the non-recommended backends. See https://pypi.org/project/keyring for details.
>>> keyring.get_password('test', 'test')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/keyring/core.py", line 57, in get_password
    return _keyring_backend.get_password(service_name, username)
  File "/usr/lib/python3/dist-packages/keyring/backends/fail.py", line 24, in get_password
    raise RuntimeError(msg)
RuntimeError: No recommended backend was available. Install a recommended 3rd party backend package; or, install the keyrings.alt package if you want to use the non-recommended backends. See https://pypi.org/project/keyring for details.

[regression potential]

TBD as this is still an upstream bug

[scope]

this still affects upstream, as well as all Debian and Ubuntu releases

[other info]

this affects any application that uses the python-launchpadlib library,
as that internally uses keyrings.

** Affects: python-keyring
     Importance: Unknown
         Status: Unknown

** Affects: python-keyring (Ubuntu)
     Importance: Medium
         Status: New

** Bug watch added: github.com/jaraco/keyring/issues #372
   https://github.com/jaraco/keyring/issues/372

** Also affects: python-keyring via
   https://github.com/jaraco/keyring/issues/372
   Importance: Unknown
       Status: Unknown

** Changed in: python-keyring (Ubuntu)
   Importance: Undecided => Medium

-- 
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to python-keyring in Ubuntu.
https://bugs.launchpad.net/bugs/1864204

Title:
  nondeterministic failure when no keyring backends are available

Status in Python Keyring:
  Unknown
Status in python-keyring package in Ubuntu:
  New

Bug description:
  [impact]

  when no backends are available for python-keyring, it will sometimes
  silently ignore all requests to set or get credentials, and sometimes
  it will raise RuntimeError for all requests.

  [test case]

  when there are no backends, there are 2 built-in backends that will be
  the only ones available, the 'chainer' backend and the 'fail' backend.
  The 'fail' backend always has priority 0, while the 'chainer' backend
  has priority 10 if it contains any actual backends, and priority 0 if
  it is empty.  So in the situtation where there are no actual backends,
  both 'chainer' and 'fail' will have priority 0.  Since the 'backends'
  class stores its backend implementation instances in a python set(),
  which is unordered, it is non-deterministic which of those backends
  are used at any given time.

  Since the behavior is non-deterministic, simply trying this multiple
  times may result in each behavior.  Rebooting or logout/login can help
  'switch' the behavior.

  
  >>> import keyring
  >>> [keyring.backend.get_all_keyring()]

  the above python code will show the current list of backends, and
  since they both have the same priority (in this situation) the first
  in the list will be used.  If the list looks like:

  [[<keyring.backends.chainer.ChainerBackend object at 0x7f1f7018f3d0>,
  <keyring.backends.fail.Keyring object at 0x7f1f6fff0820>]]

  with 'ChainerBackend' first, all keyring functions will return
  silently with None, e.g.:

  >>> keyring.set_password('test', 'test', 'test')
  >>> keyring.get_password('test', 'test')
  >>> 

  with 'fail.Keyring' first, all keyring functions will raise
  RuntimeError:

  >>> import keyring
  >>> [keyring.backend.get_all_keyring()]
  [[<keyring.backends.fail.Keyring object at 0x7f3b6ade73d0>, <keyring.backends.chainer.ChainerBackend object at 0x7f3b6ac48820>]]
  >>> keyring.set_password('test', 'test', 'test')
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib/python3/dist-packages/keyring/core.py", line 63, in set_password
      _keyring_backend.set_password(service_name, username, password)
    File "/usr/lib/python3/dist-packages/keyring/backends/fail.py", line 24, in get_password
      raise RuntimeError(msg)
  RuntimeError: No recommended backend was available. Install a recommended 3rd party backend package; or, install the keyrings.alt package if you want to use the non-recommended backends. See https://pypi.org/project/keyring for details.
  >>> keyring.get_password('test', 'test')
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib/python3/dist-packages/keyring/core.py", line 57, in get_password
      return _keyring_backend.get_password(service_name, username)
    File "/usr/lib/python3/dist-packages/keyring/backends/fail.py", line 24, in get_password
      raise RuntimeError(msg)
  RuntimeError: No recommended backend was available. Install a recommended 3rd party backend package; or, install the keyrings.alt package if you want to use the non-recommended backends. See https://pypi.org/project/keyring for details.

  [regression potential]

  TBD as this is still an upstream bug

  [scope]

  this still affects upstream, as well as all Debian and Ubuntu releases

  [other info]

  this affects any application that uses the python-launchpadlib
  library, as that internally uses keyrings.

To manage notifications about this bug go to:
https://bugs.launchpad.net/python-keyring/+bug/1864204/+subscriptions



More information about the foundations-bugs mailing list