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

Loading secrets generated using python-keyring in different applications #485

Open
twmr opened this issue Jan 5, 2021 · 6 comments
Open

Comments

@twmr
Copy link

twmr commented Jan 5, 2021

I want to load the secrets from a (gnome-)keyring, which were created using
python-keyring, in my editor. The editor has support for loading secrets
from the keyring. However, I had a problem finding the secrets for a
specific hostname. The reason for problem is that my editor iterates over
all the items in the Login keyring until it finds one that has an attribute
called "host" matching the desired hostname. Since python-keyring uses the
attribue "service", no match is returned in my editor.

Now comes the question(s):
Is there any reason why "service" was chosen as
the attributename of the secrets stored in the Login keyring? I guess that
the chosen attribute names are not standardized, right?

This is the item in my keyring, created using the python-keyring library.

 `-[-] Password for ’thomas.hisch’ on ’hostname’
    |-  password:    ************* [Show password]
    |-  application: Python keyring library
    |-  service:     hostname
    |-  username:    thomas.hisch
    `-  xdg:schema:  org.freedesktop.Secret.Generic

Is there also a reason why org.freedesktop.Secret.Generic was chosen as the
schema instead of creating a new schema? I'm asking because using a
different schema would allow to add support for it in my editor.

@mitya57
Copy link
Collaborator

mitya57 commented Jan 11, 2021

Is there any reason why "service" was chosen as the attributename of the secrets stored in the Login keyring?

As your link shows, this name was used since the first version of Secret Service backend. So I can only say that it was a choice of the initial author of that backend. Later in 25a63c3 we adjusted the legacy libgnome-keyring backend to use the same attributes.

Ability to configure attribute names was also requested in #448. Pull requests to add support for that are welcome.

Is there also a reason why org.freedesktop.Secret.Generic was chosen as the schema instead of creating a new schema?

Actually, the Secret Service specification does not mention anything about schemas or how to create them. (To double-check, I cloned the xdg-specs repo and ran git grep -i schema secret-service/, there are no results.)

It looks like gnome-keyring implements it as a Type property on Item objects, but it is not documented and other implementations may not support it, so we cannot use it.

I also found this comment in libsecret code, which confirms that it is a gnome-keyring only feature: https://gitlab.gnome.org/GNOME/libsecret/-/blob/0.20.4/libsecret/mock/service.py#L278.

@twmr
Copy link
Author

twmr commented Jan 11, 2021

Thx @mitya57 for your comment!

You are right, grepping for schema doesn't return any match in the
xdg-specs, but it must be stored somewhere in the Keyring, since also
secret-tool outputs a schema string:

[/org/freedesktop/secrets/collection/login/1297]
label = Password for 'thomas.hisch' on 'hostname'
secret = xxx
created = 2021-01-11 21:56:36
modified = 2021-01-11 21:56:36
schema = org.freedesktop.Secret.Generic
attribute.application = Python keyring library
attribute.service = hostname
attribute.username = thomas.hisch

In my keyring there are items created by NetworkManager that use a different
schema, so it must be possible somehow to change the schema string on the
client side. In the source code of the openvpn NM plugin you can see how the
schema is changed using the C-API of libsecret:
https://github.com/NetworkManager/NetworkManager-openvpn/blob/8bf00a9e4d8ec74457096911670e9f44d6a36d6f/auth-dialog/main.c#L62

I found out that the auth-secrets-create function of emacs mentions xdg:schema in its docstring

The key `:xdg:schema' determines the scope of the item to be
generated, i.e. for which applications the item is intended for.
This is just a string like \"org.freedesktop.NetworkManager.Mobile\"
or \"org.gnome.OnlineAccounts\", the other required keys are
determined by this.  If no `:xdg:schema' is given,
\"org.freedesktop.Secret.Generic\" is used by default.

According to the code of this function, the schema just seems to be a normal
attribute.

I've just tried changing the schema in python-keyring by changing the
set_password method and adding the xdg:schema attribute.

    def set_password(self, service, username, password):
        """Set password for the username of the service"""
        collection = self.get_preferred_collection()
        attributes = {
            "application": self.appid,
            "service": service,
            "username": username,
            "xdg:schema": "org.freedesktop.PythonKeyring.Secret",
        }
        label = "Password for '{}' on '{}'".format(username, service)
        with closing(collection.connection):
            collection.create_item(label, attributes, password, replace=True)

This works! Now search-tool outputs the new schema name 🎉

[/org/freedesktop/secrets/collection/login/1299]
label = Password for 'abc' on 'myserv2'
secret = xxxx
created = 2021-01-11 22:43:30
modified = 2021-01-11 22:43:30
schema = org.freedesktop.PythonKeyring.Secret
attribute.application = Python keyring library
attribute.service = myserv2
attribute.username = abc

I think that changing the SecretService backend in python-keyring to set the xdg:schema attribute, instead of creating a custom application attribute, makes it fit better into the secret-service ecosystem. WDYT?

@mitya57
Copy link
Collaborator

mitya57 commented Jan 14, 2021

"xdg:schema": "org.freedesktop.PythonKeyring.Secret",

Having a line like that does not hurt. But I think we should use a different reverse domain name, because we are affiliated with neither freedesktop.org nor python.org.

@jaraco What do you think? Maybe something like com.jaraco.PythonKeyring.Secret?

Also maybe it will be a good idea to make it configurable: if in future we make attribute names configurable, then we should also allow for changing the schema name.

@jaraco
Copy link
Owner

jaraco commented Jan 24, 2021

Is there any reason why "service" was chosen as
the attributename of the secrets stored in the Login keyring?

Probably there wasn't a lot more consideration given except for the convention that service was the argument name to the set_password method.

Is there also a reason why org.freedesktop.Secret.Generic was chosen as the
schema instead of creating a new schema?

Python keyring tries to stay agnostic, use defaults, and rely on standards defined by the tools with which it might interoperate.

To that end, I'm a little reluctant to create a new schema specific to Python keyring. I'd prefer to adopt a (most) popular schema (probably Generic) and possible allow a user to opt-in to alternate schemas (if appropriate).

Do I understand correctly that the issue here is that by using the default schema, the expected name for the service/host is host? In that case, I do agree that if the schema expects host for the relevant entity that Keyring should do the same.

Perhaps the backend could get additional support for different schemas to support the default schema and maybe a different one for KeyPassXC.

Here's what I recommend:

  • Adapt keyring to honor the Generic schema, mapping service to host, and migrating legacy users.
  • Add support for additional schemas, mapping service and username and password to relevant fields in the schema.

@mitya57
Copy link
Collaborator

mitya57 commented Jan 26, 2021

Do I understand correctly that the issue here is that by using the default schema, the expected name for the service/host is host?

I think no. If I understand correctly, org.freedesktop.Secret.Generic schema means no schema at all, so any attributes can be used.

For the record, gnome-keyring seems to support the following schemas:

  • org.freedesktop.Secret.Generic (the default)
  • org.gnome.keyring.NetworkPassword
  • org.gnome.keyring.Note
  • org.gnome.keyring.ChainedKeyring
  • org.gnome.keyring.EncryptionKey
  • org.gnome.keyring.PkStorage

The org.gnome.keyring.NetworkPassword one suits our needs the best way: it has user, domain, object, protocol, port, server and authtype attributes.

But the libsecret documentation says:

This is meant to be used by applications migrating from libgnome-keyring which stored their secrets as 'network passwords'. It is not recommended that new code use this schema.

And to remind again, the schemas concept is GNOME-specific and is not even mentioned in the specification.

@twmr
Copy link
Author

twmr commented Jan 28, 2021

I think no. If I understand correctly, org.freedesktop.Secret.Generic schema means no schema at all, so any attributes can be used.

I also think that for the generic schema any attributes can be used.

And to remind again, the schemas concept is GNOME-specific and is not even mentioned in the specification.

It's surprising that only only GNOME has the concept of schemas in the keyring. I never thought that libsecret, which contains the secret-tool command line tool that I used in the description, belongs to the GNOME project.

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