system-based authorization broken in gnome-keyring: NoOptionError: No option 'consumer_key' in section: '1'
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
launchpadlib |
Fix Released
|
Critical
|
Brad Crittenden | ||
python-launchpadlib (Ubuntu) |
Fix Released
|
High
|
Unassigned | ||
Natty |
Fix Released
|
High
|
Bryce Harrington | ||
Oneiric |
Fix Released
|
High
|
Bryce Harrington |
Bug Description
[Impact]
Some users have reported problems with corrupted keyrings, both in Gnome and KDE, when newlines are included in the password. This makes all launchpadlib-based apps unusable for affected users.
The corruption occurs because launchpadlib attempts to store a multi-line value in the keyring, but the keyring service appears to assume values are single-lined, so chokes when it encounters launchpadlib's entries.
[Workaround]
Delete the keyring (e.g. via 'seahorse') prior to running a launchpadlib-based script.
[Development Fix]
Upstream version 1.9.12 resolves the issue by base64 encoding the serialized value:
- Properly handle Unicode passwords if returned by the keyring.
- Base 64 encode serialized credentials before putting in keyring/wallet.
[Stable Fix]
For the SRU to natty and oneiric, it is proposed to cherrypick the encoding change to credentials.py and its associated test code in test_credential
[Test Case]
1. Before installing the new package, use a launchpadlib client to create a key entry in your keyring. It will be called 'network password'. For example, run 'lp-shell' and after authorization examine lp.me.
2. Open the keyring with seahorse and examine the password. It should be plaintext and have 'consumer_key' as one of the first entries. Ensure under 'details' it lists the URL for the Launchpad system you accessed above (i.e., product, staging, or qastaging)
3. Install the updated package.
4. Run the same launchpadlib client. Ensure that authorization is not required, demonstrating that the stored credentials were used.
5. Open seahorse and delete the entry for 'network password'.
6. Run the client again and reauthorize.
7. Examine the key entry in seahorse. This time it should start with '<B64>' and the rest should be base 64 encoded.
8. Finally run the client again and ensure authorization is not required.
[Regression Potential]
Low/none. When there is a corrupted key ring entry, this just reauthorizes and overwrite the old entry, same as if it had expired.
[Original Report]
Running lp:svammel to do a dry run mass bugfiling against LP, I get prompted to authorize my system to connect to launchpad, which is neat. But on a subsequent invocation of the tool, it fails with:
Traceback (most recent call last):
File "file-failures.py", line 50, in <module>
init(
File "/home/
set_
File "/home/
lp = Launchpad.
File "/usr/lib/
credential_
File "/usr/lib/
authorizati
File "/usr/lib/
return self.do_
File "/usr/lib/
return Credentials.
File "/usr/lib/
credentials
File "/usr/lib/
CREDENTIALS
File "/usr/lib/
raise NoOptionError(
ConfigParser.
At James Westby's suggestion, I had a peek inside gnome-keyring with seahorse and found this as the 'password' value of the 'network password' token:
[1]
Presumably there should be a real password here instead. :)
People experiencing this problem can work around it by opening their gnome keyring, and deleting the broken password.
Related branches
- j.c.sackett (community): Needs Information
-
Diff: 81 lines (+26/-4)1 file modifiedsrc/launchpadlib/credentials.py (+26/-4)
Changed in launchpadlib: | |
status: | New → Triaged |
importance: | Undecided → Critical |
description: | updated |
Changed in launchpadlib: | |
status: | Triaged → In Progress |
assignee: | nobody → Brad Crittenden (bac) |
Changed in launchpadlib: | |
status: | In Progress → Fix Committed |
Changed in launchpadlib: | |
status: | Fix Committed → Fix Released |
Changed in python-launchpadlib (Ubuntu Oneiric): | |
importance: | Undecided → High |
status: | New → Triaged |
description: | updated |
description: | updated |
description: | updated |
description: | updated |
description: | updated |
description: | updated |
Changed in python-launchpadlib (Ubuntu Natty): | |
status: | Triaged → In Progress |
Changed in python-launchpadlib (Ubuntu Oneiric): | |
status: | Triaged → In Progress |
Changed in python-launchpadlib (Ubuntu Natty): | |
assignee: | nobody → Bryce Harrington (bryce) |
Changed in python-launchpadlib (Ubuntu Oneiric): | |
assignee: | nobody → Bryce Harrington (bryce) |
description: | updated |
description: | updated |
Changed in python-launchpadlib (Ubuntu): | |
status: | Triaged → Fix Released |
Here's the serialize code for what is stored
so it executes the first line fine, but the rest don't have the desired
effect.
I'm not sure what would cause the other statements to have
no effect.
The write() must have an effect, otherwise you would get nothing,
so either there is something odd going on with the ConfigParserClass
or we are getting the equivalent of short read/write (the writeable_file
isn't a real file here, just an in memory one, so it's not that exactly)
There is some oddness with a credential_ save_failed that could be
involved.
Adding an upstream task for their input.
Thanks,
James