gnomedbusgnome-keyring-daemon

DBus Secret Service prompting


Hi I'm attempting to utilize the Secret Service to access secrets in Gnome Keyring.

Everything works ok if the collection I'm trying to access is already unlocked. The problem I'm running into is when the collection/secrets are locked and it needs to prompt for the user to input their password to unlock it.

According to the docs

Operations that require a prompt to complete will return a prompt object. The client application must then call the Prompt() method of the prompt object to display the prompt. Client applications can use the window-id argument to display the prompt attached to their application window.

The Prompt() method is supposed to exist within org.freedesktop.Secret.Prompt per the docs.

I'm using D-Feet to try to find that, but nothing matching that name shows up in either the Session or System bus.

enter image description here

enter image description here

Any idea if this has moved? Or if I should be doing something else to display the prompt?

Thanks!


Solution

  • The test I've done was using the create a new collection functionality as I found this the method that was easy to do that issued a prompt.

    There are two object paths returned from CreateCollection

    collection

    The new collection object, or '/' if prompting is necessary. 
    

    prompt

    A prompt object if prompting is necessary, or '/' if no prompt was needed.
    

    I then used the prompt object to call the Prompt method with a random window ID. I waited for the prompt Completed signal before continuing.

    A screenshot of the prompt:

    Prompt from secrets

    From the comments I can see you are using C#, unfortunately I don't know that so I have done my tests in Python. I'm hoping there is enough similarity to help move you forward.

    from pydbus import SessionBus
    from gi.repository import GLib
    
    properties = {"org.freedesktop.Secret.Collection.Label": GLib.Variant.new_string("MyCollection")}
    
    ses_bus = SessionBus()
    service_name = 'org.freedesktop.secrets'
    secret_service = ses_bus.get(service_name, '/org/freedesktop/secrets')
    
    mainloop = GLib.MainLoop()
    
    
    def _received_pw(dismissed, object_path):
        print("dismissed?", dismissed, object_path)
        mainloop.quit()
    
    
    def show_prompt(prompt_id):
        prompt = ses_bus.get(service_name, prompt_id)
        prompt.onCompleted = _received_pw
        prompt.Prompt("random_id_for_window")
        mainloop.run()
        print('Prompt closed')
    
    
    def add_my_collection():
        result = secret_service.CreateCollection(properties, "")
        print("result from CreateCollection", result)
        if result[1] != '/':
            show_prompt(result[1])
    
    
    def remove_my_collection():
        for test_collect in secret_service.Collections:
            if "MyCollection" in test_collect:
                this_collection = ses_bus.get(service_name, test_collect)
                result = this_collection.Delete()
                if result != '/':
                    show_prompt(result)
    
    
    def main():
        add_my_collection()
        remove_my_collection()
    
    
    if __name__ == '__main__':
        main()
    
    

    Which gave the output:

    result from CreateCollection ('/', '/org/freedesktop/secrets/prompt/p1')
    dismissed? False /org/freedesktop/secrets/collection/MyCollection
    Prompt closed
    

    I've been using busctl to monitor what has been created. For example:

    $ busctl --user tree org.freedesktop.secrets 
    └─/org
      ├─/org/freedesktop
      │ ├─/org/freedesktop/portal
      │ │ └─/org/freedesktop/portal/desktop
      │ └─/org/freedesktop/secrets
      │   ├─/org/freedesktop/secrets/collection
      │   │ ├─/org/freedesktop/secrets/collection/MyCollection
      │   │ ├─/org/freedesktop/secrets/collection/login
      │   │ │ ├─/org/freedesktop/secrets/collection/login/1
      │   │ └─/org/freedesktop/secrets/collection/session
      │   ├─/org/freedesktop/secrets/prompt
      │   │ ├─/org/freedesktop/secrets/prompt/p1
      │   │ └─/org/freedesktop/secrets/prompt/u2
      │   └─/org/freedesktop/secrets/session
      │     ├─/org/freedesktop/secrets/session/s1
      └─/org/gnome
        └─/org/gnome/keyring
          └─/org/gnome/keyring/daemon