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

Backslashes in password are not handled correctly #674

Open
lajonss opened this issue Apr 5, 2024 · 5 comments
Open

Backslashes in password are not handled correctly #674

lajonss opened this issue Apr 5, 2024 · 5 comments

Comments

@lajonss
Copy link

lajonss commented Apr 5, 2024

Describe the bug
Backslashes in password (e.g. encoded unicode characters) make the library behave incorrectly.

To Reproduce

~$ cat dupapassword
\u0142u\u017c
~$ keyring set dupaservice dupauser < dupapassword
~$ keyring get dupaservice dupauser

~$

Expected behavior
I guess backslashes should be supported, or an error should be reported when trying to set such password.

Environment

  • OS: DanctNIX (based on Arch Linux ARM) with Phosh (Gnome-ish DE)
$ pip list | grep keyring
keyring               25.0.0

$ keyring --list-backends
keyring.backends.libsecret.Keyring (priority: 4.8)
keyring.backends.kwallet.DBusKeyring (priority: 4.9)
keyring.backends.SecretService.Keyring (priority: 5)
keyring.backends.fail.Keyring (priority: 0)
keyring.backends.chainer.ChainerBackend (priority: 10)

Additional context
I've stumbled upon this when using Numberstation with polish characters (ł, ż) entered as token names. Numberstation uses urllib.parse.urlencode and json.dumps to turn them into a password.

Python API returns empty string:

>>> keyring.get_password('dupaservice', 'dupauser') is None
False
>>> keyring.get_password('dupaservice', 'dupauser')
''
@jaraco
Copy link
Owner

jaraco commented Sep 21, 2024

For me on macOS, it's working as expected:

 draft 🐚 echo r'\u0142u\u017c' > dupapassword
 draft 🐚 keyring set dupaservice dupauser < dupapassword
 draft 🐚 keyring get dupaservice dupauser
\u0142u\u017c

So the issue must be with the SecretService backend or with the Secret Service itself.

@jaraco
Copy link
Owner

jaraco commented Sep 21, 2024

Looking at the backend implementation,

def get_password(self, service, username):
"""Get password of the username for the service"""
collection = self.get_preferred_collection()
with closing(collection.connection):
items = collection.search_items(self._query(service, username))
for item in items:
self.unlock(item)
return item.get_secret().decode('utf-8')
def set_password(self, service, username, password):
"""Set password for the username of the service"""
collection = self.get_preferred_collection()
attributes = self._query(service, username, application=self.appid)
label = f"Password for '{username}' on '{service}'"
with closing(collection.connection):
collection.create_item(label, attributes, password, replace=True)

I don't see anything there that would affect the encoding or escaping of characters, so I'm inclined to think the issue might be with the Secret Service.

@mitya57 do you have any insight?

@mitya57
Copy link
Collaborator

mitya57 commented Sep 21, 2024

Actually, it works fine for me too:

dmitry@l3:/tmp$ cat dupapassword 
\u0142u\u017c
dmitry@l3:/tmp$ keyring set dupaservice dupauser < dupapassword
dmitry@l3:/tmp$ keyring get dupaservice dupauser
\u0142u\u017c

@lajonss Can you reproduce the bug with SecretStorage API? E.g. like this:

>>> import secretstorage
>>> connection = secretstorage.dbus_init()
>>> collection = secretstorage.get_default_collection(connection)
>>> collection.create_item("Test", {"username": "dupauser"}, r"\u0142u\u017c")
<secretstorage.item.Item object at 0x7f92ff114980>
>>> [item] = collection.search_items({"username": "dupauser"})
>>> print(item.get_secret().decode("ascii"))
\u0142u\u017c

@lajonss
Copy link
Author

lajonss commented Sep 29, 2024

I couldn't reproduce the problem on my x86 devices.

@lajonss Can you reproduce the bug with SecretStorage API? E.g. like this:

>>> import secretstorage
>>> connection = secretstorage.dbus_init()
>>> collection = secretstorage.get_default_collection(connection)
>>> collection.create_item("Test", {"username": "dupauser"}, r"\u0142u\u017c")
<secretstorage.item.Item object at 0x7f92ff114980>
>>> [item] = collection.search_items({"username": "dupauser"})
>>> print(item.get_secret().decode("ascii"))
\u0142u\u017c

On the original device I get:

>>> print(item.get_secret().decode("ascii"))

@mitya57
Copy link
Collaborator

mitya57 commented Sep 29, 2024

Is your system 32-bit or 64-bit ARM? Also, is it running gnome-keyring or some other Secret Service implementation?

I have just tried on Debian arm64 with gnome-keyring, it works without errors and I get the expected non-empty output.

Output of dbus-monitor on your system would be helpful too (but it may be a bug in server side, not the client).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants