10

I am trying to unlock the Gnome Keyring Daemon from the command line, by directly passing it a password. I tried a few variations of --daemonize, --login, --start, but I can't get it to work.

echo $password | gnome-keyring-daemon --unlock returns SSH_AUTH_SOCK=/run/user/1000/keyring/ssh but doesn't unlock anything.

Basically I want something along the lines of:

gnome-keyring-daemon unlock --pw $password

Not sure if it makes any difference, but I'm on Manjaro i3wm version, so not using a desktop environment.

Background:

I'm using KeePassXC to manage my keyring. The one downside to this is, that I can't automatically unlock the keyring on login. Since I don't want to enter two long passwords I came up with the following script as a workaround:

  • Logging in automatically unlocks Gnome Keyring Daemon
  • Gnome Keyring Daemon contains (a part of) the PW to KeePassXC as the only entry
  • enter the last characters of the pw in a prompt
  • kill Gnome Keyring Daemon
  • use the combined pw to unlock KeePassXC

Now I want to do the opposite to lock KeePassXC again:

  • Get PW to Gnome Keyring Daemon from KeePassXC
  • Kill KeePassXC
  • Unlock GnomeKeyringDaemon <- this is the part I can't get to work
1
  • You need to use echo -n as in kFYatek's answer below. Commented Feb 3, 2022 at 13:31

6 Answers 6

14

There is (now) an --unlock argument to gnome-keyring-daemon which does exactly what you want. Normally, when it's invoked, it will unlock then demonize and echo the SSH_AUTH_SOCK. If you think there might already be an existing daemon running, then you can add the --replace argument to ensure a seamless transition to the new daemon.

I log in to a headless Ubuntu 20.0.4LTS system via ssh with a public key (no password) on a regular basis, but sometimes for development purposes I need the keyring to be available. So I have the following function defined in my bash profile, and it works great to do the unlock (whether there is an existing daemon running or not):

# Linux unlock gnome keyring
function unlock-keyring ()
{
    read -rsp "Password: " pass
    export $(echo -n "$pass" | gnome-keyring-daemon --replace --unlock)
    unset pass
}
3
  • On arch linux this does not work for some reason. Command executes , status code returns , even tells you in some nicely formatted (and colorful) text that it's doing stuff. But when I try to run another process that depends on keyring being unlocked (like say a vpn client) it coughs up this: keyrings.errors.KeyringLocked and of course "Failed to unlock the collection!"
    – niken
    Commented Nov 17, 2021 at 21:01
  • @niken I haven't tried this on an arch linux box, so it might not work there. But another thing to note is that, if you type your password wrong, the --unlock output gives no indication of that being the case. So you might want to try again and type carefully :). Commented Nov 18, 2021 at 22:17
  • 1
    I pipe password via echo -n "mypassword" just like you , trying to get it to run on 1st login before starting x desktop so i can use it form cml, but cannot figure out why it wont unlock default 'login' keyring , it should by all logic , it acts like it does, but it just doesn't and not too much about it in the output, just failure by vpn client... Everything works perfectly fine once desktop loads. I can live without it , but it's really annoying cannot figure out why
    – niken
    Commented Nov 18, 2021 at 23:19
13

This is a very brutal, dirty, and probably very wrong way to do this, but after struggling with unlocking my keyring over SSH for a while, I came up with this little script:

echo 'NOTE: This script will only work if launched via source or .' >&2
echo -n 'Login password: ' >&2
read -s _UNLOCK_PASSWORD || return
killall -q -u "$(whoami)" gnome-keyring-daemon
eval $(echo -n "${_UNLOCK_PASSWORD}" \
           | gnome-keyring-daemon --daemonize --login \
           | sed -e 's/^/export /')
unset _UNLOCK_PASSWORD
echo '' >&2

And yes, when I call . ~/bin/unlock-gnome-keyring and enter my login password, it unlocks my login keyring, I can view it in seahorse running through remote X and use it via libsecret applications.

Please be warned though, I'm not a security expert and there might be serious security implications to doing it this way. I did not check whether the password is properly cleaned in memory etc., which might render you more exposed to attacks.

4
  • 1
    Thank you that solved it for me! I had two errors in my code, first I forgot the -n flag after echo and I used --unlock instead of --daemonize --login (which I tried before, but due to the missing -n flag it didn't work.) Here is my final script, that quits KeePassXC and unlocks the gnome-keyring: pass=$(secret-tool lookup GnomeKeyring Password) pkill keepassxc echo -n $pass | gnome-keyring-daemon --daemonize --login unset pass Commented Aug 5, 2020 at 10:42
  • 1
    Just in case someone wants to try this, be extremely careful and make a backup of your keyrings before. I lost access to my login.keyring trying to follow these examples (see unix.stackexchange.com/questions/652215/…)
    – ChennyStar
    Commented Jun 1, 2021 at 9:52
  • ok this is interesing so the password has to be fed to the keyring somehow
    – Fuseteam
    Commented Oct 7, 2021 at 18:59
  • This is very helpful to allow use of http svn subversion usage via ssh or scripts! stackoverflow.com/questions/2899209/…
    – poleguy
    Commented Jun 9, 2023 at 16:27
4

I couldn't get any combination of the echo -n "pass" | gnome-keyring-daemon commands to work. I also tried the secret-tool command and several Python libraries, but most were outdated and none of them unlocked my keyring in Seahorse - or just triggered the GUI password prompt.

The only thing that worked for me was a Python script I found, available on Github and Codeberg, that does the job for me as long as I have Python installed. Downloading the script is as simple as running:

wget https://codeberg.org/umglurf/gnome-keyring-unlock/raw/branch/main/unlock.py
chmod +x unlock.py

After that, the following command unlocks the default keyring named 'Login' (usually present, the gnome-keyring-daemon command also creates it if it doesn't exist):

./unlock.py <<<PASSWORDHERE

If you also want to unlock a non-default keyring, just create an item in the 'Login' keyring with the name and password of that keyring. That gives you the option to automatically unlock that keyring whenever the 'Login' keyring is unlocked.

0

Based on [unlock.py][1], here is a bash version that uses nc (netcat) for the socket work:

#! /bin/bash

# password is on stdin

unlock-keyring() ( # note, runs in a subshell
  # helper functions for binary reads & writes on socket
  plain() {
    LANG=C LC_ALL= "$@"
  }

  readx1() {
    IFS="" plain read -d "" -rn 1
    plain printf -v "$1" '%02x' "'$REPLY"
  }

  readi4() {
    test "$1" != "_answer" && declare -n _answer="$1"
    _answer=""
    readx1 REPLY && _answer+=$REPLY &&
    readx1 REPLY && _answer+=$REPLY &&
    readx1 REPLY && _answer+=$REPLY &&
    readx1 REPLY && _answer+=$REPLY &&
    printf -v _answer $(( 0x$_answer ))
  }
  
  writei4() {
    local hex
    printf -v hex "%08x" $1
    printf '%b' "\x${hex:0:2}" "\x${hex:2:2}" "\x${hex:4:2}" "\x${hex:6:2}"
  }

  local REPLY
  read -rs || { test $? = 1 && test "${#REPLY}" != 0 ; } || return $?

  if test -S "$KEYRING_SOCKET"
  then :
  elif test -S "$GNOME_KEYRING_CONTROL/control"
  then KEYRING_SOCKET="$GNOME_KEYRING_CONTROL/control"
  elif test -S "$XDG_RUNTIME_DIR/keyring/control"
  then KEYRING_SOCKET="$XDG_RUNTIME_DIR/keyring/control"
  else return 1
  fi

  # could use socat instead
  coproc nc { nc -U "$KEYRING_SOCKET" ; } || return $?

  printf '\0' >&${nc[1]} || return $?

  # packet length
  writei4 $(( 12 + ${#REPLY} )) >&${nc[1]} || return $?
  
  # unlock code = 1
  writei4 1 >&${nc[1]} || return $?

  # password length  
  writei4 ${#REPLY} >&${nc[1]} || return $?

  # password not including trailing newline, curse you bash for <<<
  tr -d '\n' <<<"$REPLY"  >&${nc[1]} || return $?

  # read responses
  readi4 len <&${nc[0]} || return $?
  test "$len" = 8 || return $?
  readi4 len <&${nc[0]} || return $?
  test $len -lt 127 && return $len || return 127
)

unlock-keyring
0

For some use cases it can be handy to just remove the password on the keyring. Therefore there's no need to unlock it:

On Ubuntu 22.04: search for 'seahorse' and open. Right click on 'Login' under ' Passwords' (might need to do a few times, didn't work at first). In the context menu pick 'Change Password'. Enter the current password and leave the new password fields blank. Accept 'Store passwords unencrypted?'.

0

This works for me, changed form brotskydotcom's answer.

# Add to ~/.bashrc

function unlock()
{
    read -rsp "keyring password:" keyringPass
    echo -n "$keyringPass" | gnome-keyring-daemon -dr --unlock
    unset keyringPass
}

function lock()
{
    pkill -u "$(whoami)" -f gnome-keyring-daemon
}

explanation

gnome-keyring-daemon:
-r(replace): replace a running keyring daemon
-d(daemon): keyring daemon will exit when current process ends without this option
--unlock unlock 'Login' keyring, it will not unlock any other keyrings, eg: 'Default keyring'.

lock:
Kill the keyring daemon processes would lock the keyring.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .