Skip to content

0002 lock

Nils Kvist edited this page Sep 29, 2022 · 6 revisions

example i3 config

bindsym $mod+x exec --no-startup-id exec xset s activate
bindsym $mod+Control+x exec --no-startup-id exec systemctl suspend
bindsym $mod+Shift+x exit # no need to exec i3-msg

i3wm is preconfigured (~/.config/i3/config) to start xss-lock --transfer-sleep-lock -- i3lock --nofork

packages

  • xss-lock
  • i3lock
  • xorg-xset
  • xsecurelock
  • xscreensaver

openSUSE doesn't have xss-lock in the official repositories.
https://build.opensuse.org/package/show/X11:Utilities/xss-lock

xss-lock

https://bitbucket.org/raymonad/xss-lock/
https://wiki.archlinux.org/title/Power_management#xss-lock
https://github.com/google/xsecurelock#automatic-locking

Synopsis: xss-lock [--transfer-sleep-lock] -- COMMAND

xss-lock is a lightweight daemon that waits for lock or sleep events to occur, when they do, xss-lock will start COMMAND.

COMMAND is usually some kind of lockscreen:

  • i3lock
  • dm-tool lock will lock the screen using lightdm
  • xsecurelock secure locker, many options

xss-lock systemd user service

It is nice to start xss-lock as a systemd service unit instead, to be sure it is actually running since it can be setup to automatically restart on-failure.

Be sure it is not started elsewhere (i3 config) when setting up the systemd unit.

~/.config/systemd/user/xss-lock.service:

[Unit]
Description=xss-lock daemon
PartOf=graphical-session.target

[Service]
ExecStart=xss-lock --transfer-sleep-lock -- i3lock --nofork
Restart=on-failure

xss-lock requires X (the display server) to be ready (DISPLAY and XAUTHORITY environment variables). So instead of enabling this unit, it is better to manually start it either from .xinitrc, .xsession, or with exec in ~/.config/i3/config with the command: systemctl --user start xss-lock.service You can also add it as a dependency to another systemd unit where you know X is setup:
Wants=xss-lock.service

XSecureLock

https://github.com/google/xsecurelock

Secure screenlock with many options, support for XScreenSaver and mpv/mplayer lockscreen backgrounds. Configured with environment variables, best set up in a wrapper script:

xsecurelock wrapper script

https://bitbucket.org/raymonad/xss-lock/src/master/doc/transfer-sleep-lock-generic-delay.sh
https://github.com/google/xsecurelock/blob/master/test/run-test.sh
https://github.com/vincentbernat/i3wm-configuration/blob/a74ca20c36241125ee81b3aa4172c515a4b6ba57/bin/xss-lock#L29

#!/bin/bash

# main reason for this script is to reliably execute stuff
# before (pre_lock) and after (post_lock) the actual lock

# the command that was started by xss-lock (this script) needs
# to close XSS_SLEEP_LOCK_FD if it is opened (--transfer-sleep-lock)

# xss-lock --transfer-sleep-lock -- xsecurelock
# the above has the same effect as using this script with empty
# pre_lock and post_lock functions. Except the XSECURELOCK_ environment
# variables needs to be defined elsewhere beforehand.

pre_lock() {
  # mediacontrol pause # strongly recommended to pause/stop media playback before sleep
  dunstctl set-paused true
}

post_lock() {
  # systemctl --user restart switcharoo@horizontal
  dunstctl set-paused false
  # xset s 0 0
  # xset dpms 0 0 0
  exit
}

export XSECURELOCK_PASSWORD_PROMPT=cursor    # default prompt
export XSECURELOCK_PASSWORD_PROMPT=asterisks
export XSECURELOCK_PASSWORD_PROMPT=hidden
export XSECURELOCK_PASSWORD_PROMPT=time
export XSECURELOCK_PASSWORD_PROMPT=time_hex

# mixed font prompts seems to be broken... (libxft?)
# export XSECURELOCK_PASSWORD_PROMPT=disco
# export XSECURELOCK_PASSWORD_PROMPT=emoticon
# export XSECURELOCK_PASSWORD_PROMPT=kaomoji
# export XSECURELOCK_PASSWORD_PROMPT=emoji

export XSECURELOCK_AUTH_BACKGROUND_COLOR='#000000'
export XSECURELOCK_AUTH_FOREGROUND_COLOR='#FFFFFF'
export XSECURELOCK_AUTH_WARNING_COLOR='#FF0000'

export XSECURELOCK_AUTH_TIMEOUT=10
# number of idle seconds before hiding the prompt

export XSECURELOCK_DISCARD_FIRST_KEYPRESS=0
# the default for DISCARD_FIRST_KEYPRESS is 1
# if it is set to 1, the first keypress will 
# not be part of the password

export XSECURELOCK_FONT="monospace"
export XSECURELOCK_DATETIME_FORMAT="%H:%M"
export XSECURELOCK_SHOW_DATETIME=0
export XSECURELOCK_SHOW_HOSTNAME=1 # 0 = disable , 2 = longform
export XSECURELOCK_SHOW_USERNAME=1

export XSECURELOCK_BLANK_DPMS_STATE=on
# specifies which DPMS state to put the screen in when blanking.
# one of: standby, suspend, off and on.
# where "on" means to not invoke DPMS at all.

export XSECURELOCK_SAVER=saver_xscreensaver
export XSECURELOCK_XSCREENSAVER_PATH=/usr/libexec/xscreensaver
# use XScreenSaver as background

pre_lock

declare -i lock_pid
# trap 'kill $lock_pid && kill -9 -1' TERM INT

if [[ -e /dev/fd/${XSS_SLEEP_LOCK_FD:--1} ]]; then
  # lock fd opened by xss-lock (suspend/hibernate)
  # systemctl suspend

  fifo_lock=$XDG_RUNTIME_DIR/xsecurelock.notify
  mkfifo "$fifo_lock"

  xsecurelock -- cat "$fifo_lock" & lock_pid=$!

  echo "Waiting for lock..."
  : > "$fifo_lock"
  echo "Locked."

  # now close our fd to signal xss-lock we're ready to sleep
  exec {XSS_SLEEP_LOCK_FD}<&-

else
  # normal lock (no sleep or suspend)
  # triggered by auto timers:
  #   - xset s 600 5
  #   - xset dpms 777 777 777
  # or manual:
  #   - xset s activate
  xsecurelock & lock_pid=$!
fi

# if xsecurelock fail: kill 'em all
wait $lock_pid || kill -9 -1

post_lock

save above script in PATH as desktop-lock (chmod +x desktop-lock)
Modify ExecStart in ~/.config/user/systemd/xss-lock.service:

ExecStart=xss-lock --transfer-sleep-lock                        \
                   --notifier "/usr/libexec/xsecurelock/dimmer" \
                   -- desktop-lock

see also

https://wiki.archlinux.org/title/Session_lock
https://wiki.archlinux.org/title/Display_Power_Management_Signaling
https://wiki.archlinux.org/title/Power_management#ACPI_events
https://man.archlinux.org/man/xset.1
https://vincent.bernat.ch/en/blog/2021-xsecurelock
https://garajau.com.br/2022/08/systemd-suspend-user-level