0

(EDIT)

This seems to be related to https://github.com/maebert/jrnl/issues/478, I get the same error.

Sorry for not noticing it earlier, the keyring was already unlocked when I was testing it in a console. I guess it means you can't use the keyring from an ad hoc python command?

(/EDIT)


This is a follow-up question to Can you use gnome keyring in bash script, if yes then how?

Based on a reply there, I am using this line in a bash script:

[[ -z $TARGET ]] || PASS=`python -c "import keyring; print(keyring.get_password(\"$TARGET\", \"(printf '%q' $USERNAME)\"))"`

This works, except for the first time it is called in a session. Then it returns while python's keyring password prompt is still being displayed, before I had the time to enter it. As a result I get two password prompts on screen at the same time, one for the keyring password and one from yad.

Called again later in the same session, this line returns the stored password like it should.

What I'm trying to do is get the password for user $USER, for an xfreerdp session to a Windows host, from the keyring if $TARGET is set, or just continue otherwise. The next step checks if $PASS is set. If not, or if it contains 'None', it launches YAD to display a dialog to prompt for it. The '%q' printf format is to allow for a backslash in the username (domain\user).

Can something be done to make it blocking when the keyring password hasn't been entered previously?

In case someone is interested, this is the full script. It is intended to be called from other scripts, and returns the password and username in variables $\$USERVAR and $\$PASSVAR, so the actual variable names can be passed by the calling script. The #echo's are debugging helpers I commented out.

#!/bin/bash

SAVE=FALSE

case $# in
1)
   USERVAR=USER
   PASSVAR=PASS
   USERNAME=$1
   ;;
3)
   USERVAR=$1
   PASSVAR=$2
   USERNAME=$3
   ;;
4)
   USERVAR=$1
   PASSVAR=$2
   USERNAME=$3
   TARGET=$4
   ;;
*)
   echo '
getpasswd: invalid number of arguments.

Presents a username and password prompt dialog, with keyring support.
The user can accept the offered username or change it, and enter a password.

Use: getpasswd [usernamevar passwordvar] initial_username [targetname]

     usernamevar defaults to USER
     passwordvar defaults to PASS
     User name and password will be returned in usernamevar and passwordvar

     If targetname is specified,
     - the password wil be taken from the keyring if the user/target combination exists.
     - if the combination does not exist, the caller will be prompted
   and given the option to store it in the keyring.
'
   exit 1
   ;;
esac

#echo USERVAR=$USERVAR
#echo PASSVAR=$PASSVAR
#echo USERNAME=$USERNAME
#echo TARGET=$TARGET

[[ -z $TARGET ]] || PASS=`python -c "import keyring; print(keyring.get_password(\"$TARGET\", \"(printf '%q' $USERNAME)\"))"`

#echo from keyring: $PASS

if [[ -z $PASS || $PASS == "None" ]]
then
   if [[ -z $TARGET ]]
   then
      FORM=$(yad --center --width=380 \
         --window-icon="gtk-execute" --image="gcr-password"\
         --title "Login" \
         --form --field="User name" "$USERNAME"\
         --field="Password":H\
         --focus-field=2)
   else
      FORM=$(yad --center --width=380 \
         --window-icon="gtk-execute" --image="gcr-password"\
         --title "Login" \
         --form --field="User name" "$USERNAME"\
         --field="Password":H\
         --field="Save in keyring?":CHK\
         --focus-field=2)
      printf -v SAVE "%s" $(echo $FORM | awk -F '|' '{ print $3 }')
   fi
   #echo $FORM
   printf -v USERNAME "%s" $(echo $FORM | awk -F '|' '{ print $1 }')
   printf -v PASS "%s" $(echo $FORM | awk -F '|' '{ print $2 }')
fi

#echo eval $USERVAR=$(printf '%q' $USERNAME)
#echo eval $PASSVAR=$(printf '%q' $PASS)
eval $USERVAR=$(printf '%q' $USERNAME)
eval $PASSVAR=$(printf '%q' $PASS)

#echo .
#echo TARGET=$TARGET
#echo USERNAME=$USERNAME
#echo PASS=$PASS
#echo SAVE=$SAVE

if [[ -n $TARGET && -n $PASS && $PASS != "None" && $SAVE != "FALSE" ]]
then
   #echo saving to keyring
   python -c "import keyring; keyring.set_password(\"$TARGET\", \"(printf '%q' $USERNAME)\", \"$PASS\")"
fi

Call it as (for example, replace names and path as appropriate)

. getpasswd USER PASS domain\\user computername
[[ -z $PASS || $PASS == "None" ]] && exit 1
xfreerdp /v:hostname_or_ip /f /u:$USER /p:$PASS /cert-ignore +fonts /drive:ubuntu-home,$HOME /printer
0

I got it to work the way I wanted by rewriting the python command in PERL. Instead of a single line, I put it in a separate file:

#!/usr/bin/perl
use Passwd::Keyring::Gnome;
print Passwd::Keyring::Gnome->new()->get_password($ARGV[0], $ARGV[1]);

It is not 100% compatible, I have to re-store the passwords on the keyring using a similar command with set_password.

They appear in the keyring (in Seahorse) with a description like 'Passwd::Keyring unclassified passwords/target/username (by Passwd::Keyring)' instead of 'Password for username on target'. I couldn't get it to find the old passwords by playing with the arguments to new() either, as I somehow expected.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.