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

Issues with the presented default collection #8611

Open
espenfl opened this issue Oct 20, 2022 · 11 comments
Open

Issues with the presented default collection #8611

espenfl opened this issue Oct 20, 2022 · 11 comments

Comments

@espenfl
Copy link

espenfl commented Oct 20, 2022

Overview

I am on Arch and using for instance the supplied mutt_oauth2.py script supplied with Mutt or similar I get from time to time:

Traceback (most recent call last):
  File "/home/user/.local/bin/mutt_oauth2.py", line 110, in <module>
    collection = secretstorage.get_default_collection(conn)
  File "/usr/lib/python3.10/site-packages/secretstorage/collection.py", line 177, in get_default_collection
    return Collection(connection)
  File "/usr/lib/python3.10/site-packages/secretstorage/collection.py", line 45, in __init__
    self._collection.get_property('Label')
  File "/usr/lib/python3.10/site-packages/secretstorage/util.py", line 67, in get_property
    (signature, value), = self.send_and_get_reply(msg)
  File "/usr/lib/python3.10/site-packages/secretstorage/util.py", line 48, in send_and_get_reply
    raise DBusErrorResponse(resp_msg)
jeepney.wrappers.DBusErrorResponse: [org.freedesktop.DBus.Error.UnknownObject] ("No such object path '/org/freedesktop/secrets/aliases/default'",)

Steps to Reproduce

  1. Update Arch
  2. Open KeePassXC and unlock the secret service database
  3. Run something like (Python example):
import secretstorage
with closing(secretstorage.dbus_init()) as conn:                                                                                                                                                                                                                                                                               
    collection = secretstorage.get_default_collection(conn)   
  1. Repeat during a few days until you get the error above. I typically get it a couple of times during a working day. Similar code is running every 5 minutes or so.

Expected Behavior

Not having to restart KeePassXC.

Actual Behavior

Restarting KeePassXC fixes the issue.

Context

I noticed: https://gitlab.gnome.org/GNOME/libsecret/-/merge_requests/94/diffs?commit_id=d620c79d83acc1bae0bbd7153a691f952b74ca31 which probably fixes this specific error, but then I suspect we will just not find the entries that is searched for later and another error will appear.

A bit unsure how to proceed from here as I do not exactly how KeePassXC interacts with this. But it seems that the default collection is not returned on request or established and communicated as available to DBus on KeePassXC launch.

Please advice and thanks a lot for the hard work behind KeePassXC.

KeePassXC - 2.7.1
Revision: 5916a8f

Operating System: Linux
Desktop Env: Gnome
Windowing System: Wayland

@espenfl espenfl added the bug label Oct 20, 2022
@michaelk83
Copy link

michaelk83 commented Oct 20, 2022

What is most likely happening is that the "default" alias is not being created. I think that returning "Unknown Object" makes more sense in this case than "Unknown Method", since the missing alias is an object. The fix you linked to is in libsecret, which AFAICT, Python SecretStorage doesn't use. It talks directly to DBus, so it will need to implement the same fix.

edit: Actually, that part of libsecret tries to create a "default" collection if it's missing, so it needs that fix to properly detect the condition. Python SecretStorage just errors-out if the default alias isn't there, so the specific error doesn't matter there.

On KeePassXC's side, you need to make sure that you have a group exposed to Secret Service, and that the DB that contains it is in the active tab (#8479). Then the default alias should be created.

@espenfl
Copy link
Author

espenfl commented Oct 20, 2022

@michaelk83 Thanks for the quick reply.

Notice that all this works nicely after initial launch of KeePassXC. It typically happens after a while and then a restart of KeePassXC fixes it. Could of course happen on the first at some point due to statistical sampling. Settings and database setup should be fine I think. Seems to be something else. But not sure how to track this further. DBus does not give any standard error, but I have not increased the verbosity of it. What about logging in KeePassXC to get more info there?

@michaelk83
Copy link

There is practically no logging in KeePassXC.

Do you have more than one DB open? If so, switching between them could drop/create/update the "default" alias. Otherwise, I don't see why it would suddenly disappear after some while. If you understand C++, the relevant code is at Service.cpp#L82 and Service.cpp#L164. But looking again at that code, even if you switch to a tab that doesn't have an exposed group, it should just keep the previous alias mapping, not delete it.

My only other guess is if some other client might be deleting the alias. @Aetf might have some other ideas.

You could try running dbus-monitor to see if anything touches the default alias path (/org/freedesktop/secrets/aliases/default) or calls the SetAlias method. But it can get pretty noisy, and it will only show the DBus ID of the callers, not their process.

You can run qdbus org.freedesktop.secrets to list the available object paths and check if the default alias is indeed missing or not.

@Aetf
Copy link
Contributor

Aetf commented Oct 20, 2022

That's pretty much what I would suspect. Usually KeepassXC should ensure that there's always a default alias. Maybe some race conditions while switching the tab?

dbus-monitor is definitely worth a try to see if there's anything else fishy going on

@hpfr
Copy link

hpfr commented Oct 26, 2022

On a related note, could a preference be created to force a particular default collection? Using the focused database as the default can lead to secret-tool-based applications (which always use the default collection) writing to the wrong database if you use multiple databases to handle host-specific and cross-host secrets.

Edit: Turns out you can specify the collection; this argument isn’t documented in the man page, but it’s in secret-tool store --help. Still, I think it makes sense to have a way to make the default collection independent of the focused database.

I guess a preference to specify a specific database file path wouldn’t be effective when that database isn’t open, so you’d have to fall back to the focused database then. Or maybe it could be a preference to always use the database in the first (leftmost) tab? That seems pretty reliable.

@droidmonkey
Copy link
Member

Forcing a default collection means you can NEVER use another database with secrettool unless you do your undocumented trick or constantly change your default collectionin settings. Using the left most database is even more ambiguous than the currently active database. At the end of the day, the currently active database is by far the best way to handle this situation without specifying specific database.

@hpfr
Copy link

hpfr commented Oct 26, 2022

I guess it wouldn’t be as much of a problem if keepassxc-browser didn’t simultaneously depend on the active database, as described in #7269. To elaborate a bit on the use case and problem:

  • Users have a main cross-host database with their browser passwords, e.g. their GitHub account. This can also house cross-host FDO secrets, like API tokens or IRC/IMAP/etc credentials accessed by secret-tool.
  • They also have individual host-specific databases with their host-specific FDO secrets, e.g. the Nextcloud Desktop token. This database can auto-open the main database for convenience.
  • Since many applications (such as Nextcloud) blindly write to the default FDO collection, users want to keep the host-specific database active
  • Since the browser extension can only see passwords in the active database, users also want to keep the main cross-host database active

At the moment, we’re stuck in this scenario where KeePassXC provides all the tools to be a complete secret management solution, but we can’t quite leverage simultaneously the features needed to make it happen.

Forcing a default collection means you can NEVER use another database with secret-tool unless you do your undocumented trick or constantly change your default collection in settings. Using the left most database is even more ambiguous than the currently active database. At the end of the day, the currently active database is by far the best way to handle this situation without specifying specific database.

Yeah, that’s not ideal. The problem is that many desktop applications blindly write to the default collection (it’s not like they can guess the names of users’ collections anyway, so it makes sense). Since these secrets can include app-specific tokens that are written or refreshed frequently in the background, users are forced to keep their host-specific database active all the time, which is untenable if they want to browse their actual main database. This means that even if the keepassxc-browser issue were fixed, not being able to visit the main database without worrying about writes to it by FdoSecrets clients would remain an issue.

I realize this is a complex use case and I’ve kind of backed myself into a corner with all the moving parts. I’m definitely open to ideas. Maybe there’s a better way to manage host-specific FDO secrets than a separate database. We already have hostname-based logic for auto-open, so maybe the FDO functionality could set a default collection matching the hostname, or something.

I’m optimistic we can figure something out, because the current state is agonizingly close to perfect already!

Actually, how is the default database set if the currently active database does not have groups exposed to the Freedesktop Secret Service? Maybe there’s a path forward there with the existing codebase…

@michaelk83
Copy link

could a preference be created to force a particular default collection?

#8479. For your use case, you'd map the default alias to the host-specific database. Then for the cross-host FDO secrets, you'll need to give the cross-host database some other alias (or just leave it with its natural collection name), and configure the relevant apps to write where you want them to (for KDE apps, see also frankosterfeld/qtkeychain#219). Another option is have only the host-specific FDO database, and sync to the other DB or host via KeeShare.

I think it makes very little sense to have the default alias switch between different databases, since client apps expect to find their passwords where they stored them. If the alias is switched to a different database, the passwords will not be found.

@hpfr
Copy link

hpfr commented Oct 27, 2022

Thanks, that issue looks more relevant to what I’m discussing. I’ll follow up there.

@espenfl
Copy link
Author

espenfl commented Dec 19, 2022

An update on this. I have two databases, one for secretservice and one for other things. I have AutoOpen in the other one that also unlocks the secretservice. It seems, so far that it is rather consistent the fact that I have to active the secretservice tab once and then all is good. If I do not do this (by default, the tab of the other one is activated after unlock) then I get these errors. Would it be possible to cycle all AutoOpen databases?

@bdeshi
Copy link

bdeshi commented Jul 31, 2023

hello I think I'm facing a simliar problem. and the following workaround seemingly works for me. don't know if this would be helpful.

  • after keepassxc is started but no db in unlocked yet, a default collection exists:

    dbus introspection output
    $ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.secrets /org/freedesktop/secrets/aliases org.freedesktop.DBus.Introspectable.Introspect
    
    method return time=1690786093.741389 sender=:1.119 -> destination=:1.120 serial=42 reply_serial=2
       string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
    "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
    <node>
      <interface name="org.freedesktop.DBus.Introspectable">
        <method name="Introspect">
          <arg name="xml_data" type="s" direction="out"/>
        </method>
      </interface>
      <interface name="org.freedesktop.DBus.Peer">
        <method name="Ping"/>
        <method name="GetMachineId">
          <arg name="machine_uuid" type="s" direction="out"/>
        </method>
      </interface>
      <node name="default"/>
    </node>
    "
  • but after I've unlocked a database, the default collection is gone.

    dbus introspection output
    $ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.secrets /org/freedesktop/secrets/aliases org.freedesktop.DBus.Introspectable.Introspect
    
    Error org.freedesktop.DBus.Error.UnknownObject: No such object path '/org/freedesktop/secrets/aliases'
  • then after I toggle Settings > Secret Service Integration > Enable KeePassXC Freedesktop.org Secret Service integration (applying the setting change in-between), the default collection reappears properly.

    dbus introspection output
    $ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.secrets /org/freedesktop/secrets/aliases org.freedesktop.DBus.Introspectable.Introspect
    
    method return time=1690786584.640131 sender=:1.149 -> destination=:1.152 serial=48 reply_serial=2
       string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
    "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
    <node>
      <interface name="org.freedesktop.DBus.Introspectable">
        <method name="Introspect">
          <arg name="xml_data" type="s" direction="out"/>
        </method>
      </interface>
      <interface name="org.freedesktop.DBus.Peer">
        <method name="Ping"/>
        <method name="GetMachineId">
          <arg name="machine_uuid" type="s" direction="out"/>
        </method>
      </interface>
      <node name="default"/>
    </node>
    "

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

6 participants