YubiKey lock screen

From D3xt3r01.tk
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

What

I'm trying to make my fedora 17 ( gnome3 ) desktop lock the screen when it sees my yubikey removed from the usb slot.

HOW

Get the serial, idVendor, idProduct of the thing.

udevadm info -a -p $(udevadm info -q path -n /dev/hidraw0)

Create a /etc/udev/rules.d/85-screen-lock-toggle.rules

SUBSYSTEM=="usb", ACTION=="remove", ENV{ID_VENDOR_ID}=="1050", ENV{ID_MODEL_ID}="0010", RUN+="/usr/local/bin/gnome-lock enable"
SUBSYSTEM=="usb", ACTION=="add", ENV{ID_VENDOR_ID}=="1050", ENV{ID_MODEL_ID}=="0010", RUN+="/usr/local/bin/gnome-lock disable"

Also you should probably reload the rules:

udevadm control --reload-rules

And you should create the following script (you'll probably have to comment out default requiretty in /etc/sudoers) :

~# cat /usr/local/bin/gnome-lock
#!/bin/bash
log="/tmp/yubi_lock_log"
yubimap="/etc/yubikey_decmappings"
ykinfo=$(/usr/bin/ykinfo -q -s)
if [ ! -z "${PAM_USER}" ]
then
    	echo "AUTH-PAM $(date) $(whoami) - '${PAM_USER}' '$0'" >>${log}
        if [ "$(fgrep -wc ${PAM_USER} ${yubimap})" == "1" ]
        then
            	echo "IT REQUIRES YUBIKEY." >>${log}
                if [ -z "${ykinfo}" ]
                then
                    	echo "Didn't find a yubikey." >>${log}
                        exit 1
                fi
                echo "Searching for ${PAM_USER}:${ykinfo} in ${yubimap}. Found:" >>${log}
                fgrep -w ${PAM_USER}:${ykinfo} ${yubimap} >>${log}
                exitcode=$?
                echo "EXITCODE=${exitcode}" >>${log}
                exit ${exitcode}
        else
            	exit 0
        fi
else
    	gnome_session=$(/usr/bin/ps aux | fgrep gnome-session | head -n 1)
        user=$(echo ${gnome_session} | awk '{print $1}')
        GNOME_SESSION_PROC=$(echo $gnome_session | awk '{print $2}')
        export `grep -z DBUS_SESSION_BUS_ADDRESS /proc/$GNOME_SESSION_PROC/environ`
        export DISPLAY=":0"
        current_lock_status=$(/sbin/runuser ${user} -c "/usr/bin/qdbus org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.GetActive")
        echo "AUTH-GNOME $(date) $(whoami) - '${user}' - '${ykinfo}' - '$0' '$1'" >>${log}
        if [ "$1" == "enable" ]
        then
                if [ -n ${user} -a "$(fgrep -wc ${user} ${yubimap})" == "1" -a "${current_lock_status}" == "false" ]
                then
                        /sbin/runuser ${user} -c "/usr/bin/dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock"
                        touch /tmp/.yubikey_lock
                fi
        else
            	if [ -n ${user} -a "$(fgrep -wc ${user}:${ykinfo} ${yubimap})" == "1" ]
                then
                    	if [ -f /tmp/.yubikey_lock ]
                        then
                               	/sbin/runuser ${user} -c "dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.SetActive boolean:false"
                                rm -f /tmp/.yubikey_lock
                        fi
                fi
        fi
fi

Your /etc/yubikey_decmappings should contain user:key, you can see that with ykinfo -q -s (which key should be able to unlock what login if in multiple desktop environment )

The ykinfo binary is available in rawhide ( or >= fedora 18 ).

Also, since fedora 17 it seems for me at least that I can't use gnome-screensaver-command to query the screensaver so I switched to dbus and runuser :)

Latest changes to the script enable it to only unlock if it was locked by the yubikey !

In order for the pam method to work, you'd need these 2 lines in the required /etc/pam.d ( don't know which one your system uses. My fedora used /etc/pam.d/password-auth and /etc/pam.d/system-auth ):

auth required pam_exec.so quiet /usr/local/bin/gnome-lock
auth sufficient    pam_unix.so try_first_pass nullok

ISSUES

On an arch environment it has been said you need some other exports for this to work...

GNOME_SCREENSAVER_PROC=`ps xa | grep gnome-screensaver | head -n 1 | awk '{print $1}'`
export `grep -z DBUS_SESSION_BUS_ADDRESS /proc/$GNOME_SCREENSAVER_PROC/environ`

Also, you could probably use dbus to do the job for locking/unlocking

sudo -u ${user} dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.SetActive boolean:false # for unlock
sudo -u ${user} dbus-send --type=method_call --dest=org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock # for lock
sudo -u ${user} qdbus org.gnome.ScreenSaver /org/gnome/ScreenSaver org.gnome.ScreenSaver.GetActive # to query via qdbus
sudo -u ${user} /usr/bin/gnome-screensaver-command --query