node-keytar icon indicating copy to clipboard operation
node-keytar copied to clipboard

`Timeout was reached` when running with sudo

Open samuela opened this issue 5 years ago • 7 comments

Keytar seems to run just fine in user-mode, but when running with sudo I get the following error trying to load credentials:

credentialsError: Error calling StartServiceByName for org.freedesktop.secrets: Timeout was reached

This is on Ubuntu 18.10.

samuela avatar Feb 25 '19 06:02 samuela

I've tested this with libsecret-1-dev 0.18.6-3 installed as well as without it installed and the result is exactly the same. I'm actually rather surprised that keytar works at all without libsecret-1-dev installed...

samuela avatar Feb 25 '19 06:02 samuela

And here's the output of journalctl -xe:

Feb 24 22:41:13 darthvader-VirtualBox sudo[19243]: darthvader : TTY=pts/0 ; PWD=/home/darthvader/nu/skainswo/nuvemfs/packages/cli ; USER=root ; COMMAND=./bin/
Feb 24 22:41:13 darthvader-VirtualBox sudo[19243]: pam_unix(sudo:session): session opened for user root by (uid=0)
Feb 24 22:41:37 darthvader-VirtualBox dbus-daemon[13309]: [session uid=0 pid=13307] Activating service name='org.freedesktop.secrets' requested by ':1.4' (uid
Feb 24 22:41:37 darthvader-VirtualBox gnome-keyring-daemon[19259]: couldn't create socket directory: /home/darthvader/.cache/keyring-YEJTXZ: Permission denied
Feb 24 22:41:37 darthvader-VirtualBox gnome-keyring-d[19259]: couldn't create socket directory: /home/darthvader/.cache/keyring-YEJTXZ: Permission denied
Feb 24 22:41:37 darthvader-VirtualBox gnome-keyring-daemon[19259]: couldn't bind to control socket: /home/darthvader/.cache/keyring-YEJTXZ/control: Permission
Feb 24 22:41:37 darthvader-VirtualBox gnome-keyring-d[19259]: couldn't bind to control socket: /home/darthvader/.cache/keyring-YEJTXZ/control: Permission deni
Feb 24 22:42:02 darthvader-VirtualBox sudo[19243]: pam_unix(sudo:session): session closed for user root

samuela avatar Feb 25 '19 06:02 samuela

I'm actually rather surprised that keytar works at all without libsecret-1-dev installed...

This is a dependency for building the library, and isn't needed at runtime (i.e. in a packaged app).

Feb 24 22:41:37 darthvader-VirtualBox gnome-keyring-daemon[19259]: couldn't create socket directory: /home/darthvader/.cache/keyring-YEJTXZ: Permission denied
Feb 24 22:41:37 darthvader-VirtualBox gnome-keyring-d[19259]: couldn't create socket directory: /home/darthvader/.cache/keyring-YEJTXZ: Permission denied
Feb 24 22:41:37 darthvader-VirtualBox gnome-keyring-daemon[19259]: couldn't bind to control socket: /home/darthvader/.cache/keyring-YEJTXZ/control: Permission
Feb 24 22:41:37 darthvader-VirtualBox gnome-keyring-d[19259]: couldn't bind to control socket: /home/darthvader/.cache/keyring-YEJTXZ/control: Permission deni

This looks like the gnome-keyring-daemon that keytar communicates with is trying to do something inside the user's ~/.cache directory (as root) and is being blocked. This likely means it never replies to the request from keytar for credentials until the timeout hits.

shiftkey avatar Feb 25 '19 17:02 shiftkey

@shiftkey Makes sense. Is there any way to use keytar with sudo? It seems as though this should be possible, since the root user should always be able to su user -c "anything...".

samuela avatar Feb 25 '19 19:02 samuela

Ok, so after some investigation it turns out that this is a result of keytar being unable to talk with the secrets service over dbus. In order to connect to dbus as necessary there are two requirements:

  • The (e)uid of the process must match the uid of dbus session.
  • DBUS_SESSION_BUS_ADDRESS must be set correctly

Fixing the euid issue is easy enough:

// Drop down to the logname user.
process.seteuid("yourusername");
// Do keytar stuff.
const tokensString = await keytar.getPassword(SERVICE, KEYNAME);
// Return to root.
process.seteuid(0);

Fixing the DBUS_SESSION_BUS_ADDRESS issue is a bit less straightforward. You can simply forward all environment variables through sudo: sudo -E your-program.... But this requires users to add this weird flag anytime they want to run your app. Depending on what you're building this may or may not be acceptable. AFAICT there's no easy way around this.

samuela avatar Feb 26 '19 23:02 samuela

See eg https://stackoverflow.com/questions/6496847/access-another-users-d-bus-session.

samuela avatar Feb 26 '19 23:02 samuela

Any update on this issue ...

HumHongeKamyaab avatar Aug 30 '21 15:08 HumHongeKamyaab