[Bug 1864204] Re: nondeterministic failure when no keyring backends are available
Brian Murray
brian at ubuntu.com
Fri Mar 20 20:31:17 UTC 2020
Hello Dan, or anyone else affected,
Accepted python-keyring into eoan-proposed. The package will build now
and be available at https://launchpad.net/ubuntu/+source/python-
keyring/18.0.1-1ubuntu1 in a few hours, and then in the -proposed
repository.
Please help us by testing this new package. See
https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how
to enable and use -proposed. Your feedback will aid us getting this
update out to other Ubuntu users.
If this package fixes the bug for you, please add a comment to this bug,
mentioning the version of the package you tested and change the tag from
verification-needed-eoan to verification-done-eoan. If it does not fix
the bug for you, please add a comment stating that, and change the tag
to verification-failed-eoan. In either case, without details of your
testing we will not be able to proceed.
Further information regarding the verification process can be found at
https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in
advance for helping!
N.B. The updated package will be released to -updates after the bug(s)
fixed by this package have been verified and the package has been in
-proposed for a minimum of 7 days.
** Changed in: python-keyring (Ubuntu Eoan)
Status: In Progress => Fix Committed
** Tags added: verification-needed verification-needed-eoan
--
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:
New
Status in python-keyring package in Ubuntu:
Fix Released
Status in python-launchpadlib package in Ubuntu:
In Progress
Status in python-keyring source package in Eoan:
Fix Committed
Status in python-launchpadlib source package in Eoan:
In Progress
Status in python-keyring source package in Focal:
Fix Released
Status in python-launchpadlib source package in Focal:
In Progress
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, although simply re-running the test multiple
times should be enough to eventually test both backends.
>>> 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]
And regressions would likely occur when no keyring backends, or only a
single keyring backend, are/is availble, since this lowers the
priority of the 'chainer' keyring backend, and the intention of this
is to fix the existing problem when there is no keyring backend.
It should be noted that because the current behavior is non-
deterministic, alternating between no error at all and raised
RuntimeError, some existing users of python-keyring that occasionally
do not see any error (but then also occasionally see RuntimeError
raised) will now always see NoKeyringError raised (which does inherit
from RuntimeError, to keep backwards compatibility for users that
currently catch RuntimeError).
That is not actually a regression, since the behavior was non-
deterministic; one way had to be chosen, and always raising error when
there are no keyring backends is more appropriate than always silently
failing when there are no keyring backends.
[scope]
This affects Eoan and later, including upstream.
This does not affect Bionic or earlier, as they do not have the commit
that introduces the bug.
this was introduced upstream by commit
0114733e91f249246c8fec9e659cd7ba2388ea0d which was first included in
version 16.1.0.
[other info]
this affects any application that uses the python-launchpadlib
library, as that internally uses keyrings.
Opened upstream PR to at least make the behavior deterministic:
https://github.com/jaraco/keyring/pull/424
Also adds new 'NoKeyringError' so callers can catch that specific
error instead of raising generic RuntimeError.
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