Go to file
2024-10-06 22:23:56 -07:00
async-xcb Update all dependencies 2024-10-06 22:23:56 -07:00
command Update all dependencies 2024-10-06 22:23:56 -07:00
dbus-service Update all dependencies 2024-10-06 22:23:56 -07:00
debian Remove some Debian deps 2022-08-14 22:31:38 -07:00
dialog-gtk3 Update all dependencies 2024-10-06 22:23:56 -07:00
locker Set minimum screen brightness level to 1, not 0 2024-10-06 22:23:56 -07:00
settings Update all dependencies 2024-10-06 22:23:56 -07:00
systemd Update all dependencies 2024-10-06 22:23:56 -07:00
util Update all dependencies 2024-10-06 22:23:56 -07:00
xcb-xembed Update all dependencies 2024-10-06 22:23:56 -07:00
.dockerignore Make debian package building work 2022-05-14 00:17:50 -07:00
.gitignore Make debian package building work 2022-05-14 00:17:50 -07:00
90-backlight.rules Add backlight udev rules file 2023-01-24 14:19:06 -08:00
bscreensaver.toml.example Fix inconsistency in the example config 2022-05-23 20:32:12 -07:00
build.rs Make sure build is re-run if HELPER_DIR changes 2024-08-02 10:46:29 -07:00
Cargo.lock Update all dependencies 2024-10-06 22:23:56 -07:00
Cargo.toml Update all dependencies 2024-10-06 22:23:56 -07:00
Dockerfile Make debian package building work 2022-05-14 00:17:50 -07:00
LICENSE Add license 2022-05-14 00:17:50 -07:00
Makefile Update all dependencies 2024-10-06 22:23:56 -07:00
README.md Add sysfs fallback for screen brightness 2022-09-06 18:13:04 -07:00
TODO.md Refactor a bit and add backlight brightness keys handling 2022-05-23 20:27:59 -07:00

bscreensaver

What

bsreensaver is a simple X11 screen locker for Linux that is designed to be secure (in the same vein as xscreensaver), but also secure, meaning that once the screen is locked, it will be incredibly difficult to unlock the screen without a password, even if crash-level bugs are found in many of bscreensaver's isolated components.

Why

xscreensaver is likely one of (if not the) most secure screen lockers out there. However, the unlock dialog, despite my attempts to theme it (mainly by changing colors and border widths) is extremely ugly. Even if I could get it to look decently nice, it would still not fit in with my GTK-based desktop.

The last time I looked at the other GTK-based screensavers (gnome-screensaver, xfce4-screensaver), they both embedded the unlock dialog into the main screen locking process. This is terrible for security, as GTK is a very large toolkit that is difficult to secure. Crasher bugs may not always be high-priority items for the developers to fix, especially if a crash is obscure and only happens in unlikely scenarios. Unfortunately, these types of crash bugs are critical for a screen locker, as this can mean that doing something strange (like, say, repeatedly pressing some key combination while shaking the mouse around) can cause the locker to crash, unlocking the system without authentication.

Build and Installation

bscreensaver is written in Rust, and requires cargo and a Rust compiler installed. Stable rust is fine, though something fairly recent (as of May 2022) is required.

A Makefile is provided to make things easy. Run make to build a release version of the software, and make install to install it. By default, components will be installed under /usr/local. You may pass PREFIX, BINDIR, LIBEXECDIR, DATADIR, and MANDIR to your invocation of make and make install to customize the installation. Be sure to pass these with make as well, because the build process embeds filesystem paths into the binary so the main locker process can find its helper applications.

You can also pass DESTDIR to install to a staging directory (e.g. for building distribution packages). I've also included a deb-pkg target that will use Docker to build a Debian package.

Configuration

The locker looks for a configuration file in the relative path bscreensaver/bscreensaver.toml using the XDG base directories specification. In practice, by default it should look for files in the following places:

  • /etc/xdg/bscreensaver/bscreensaver.toml
  • $HOME/.config/bscreensaver/bscreensaver.toml

Settings in these files are "additive" in that each file is read and parsed, and settings in "later" files override settings specified in "earlier" files.

A sample configuration file is included (bscreensaver.toml.example). Distributions may install this to /usr/share/doc/bscreensaver or possibly /etc/xdg/bscreensaver.

You need not edit the configuration file manually, but can instead run the bscreensaver-settings program, which displays a settings UI.

Architecture

bscreensaver is broken up into several pieces, each which run in their own isolated process:

  • locker
  • dialog
  • dbus-service
  • systemd-service
  • command
  • settings

Locker

The locker component is the most critical. It's responsible for drawing blank windows on the screen and grabbing the keyboard and mouse. When it detects mouse movement or key presses, it will run the dialog component, and examine its exit status to determine if the screen should be unlocked.

This component must not crash under any circumstances. A crash here means that a locked screen is now unlocked. This component should have has few dependencies as possible, and should handle errors in such a way that the program tries very hard to stay running even when unexpected things happen.

Command

The command component is a small bit of functionality that uses a hidden X11 window to allow the locker process to be sent commands (such as "lock", "deactivate", or "restart"). The locker process, on startup, creates a hidden X11 window, and then publishes the ID of this window in a property on the screen's root window. When someone uses the command component to send a command to the locker, the command component finds the command window's ID, and then sends it a client message.

Dialog

The dialog component draws a password prompt on the screen, and then validates that the password entered was correct. If the password is correct, the dialog exits with status 0. If not, or if authentication is canceled, it exits with a failure status.

The dialog process and locker process also communicate using the XEMBED protocol, which allows us to seamlessly embed X11 UI from one process into another.

DBus Service

The DBus service is launched by the locker process and acquires the org.freedesktop.ScreenSaver bus name, and responds to requests to inhibit and uninhibit the screen locker (for example, when you are playing a video on your computer, you don't want the screen to lock, even if you don't move the mouse or touch a key).

It communicates with the locker process using the command component. To inhibit the locker, it periodically sends a "deactivate" command to the locker, which causes it to reset its user activity timeout (assuming the locker is currently unlocked).

Systemd Service

The systemd service handles locking the screen on suspend and presenting the unlock dialog on resume. If you close the lid of your laptop, you probably want the screen to lock immediately. The bscreensaver systemd service registers a sleep inhibitor with systemd that causes it to delay sleep so that the systemd service can be notified of impending sleep, and use the command component to instruct the locker to lock, before telling systemd that it's ok to sleep.

When the computer wakes back up, it again receives a notification from systemd, which allows it to present the unlock dialog immediately after resuming.

Settings

The settings component is a standalone GTK app that presents a settings dialog, which reads from and writes to your configuration file.

Screen Brightness

If you enable the setting that allows bscreensaver to make your screen brightness keys work while the screen is locked, this should hopefully work without further intervention, if your display driver supports the XBACKLIGHT protocol. If not, bscreensaver will attempt to use the backlight controls in sysfs, which probably will not work without extra setup, as those controls are usually only accessible to root. You can give yourself (well, anyone in the video group) access by adding a udev rules file, say at /etc/udev/rules.d/90-backlight.rules:

SUBSYSTEM=="backlight", ACTION=="add", \
  RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness", \
  RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"

You may need to restart to get those settings applied, or you can just run those commands yourself (replacing %k with whatever directories happen to be located there). Your user account will also need to be in the video group; if it isn't, you'll probably need to log out and in again before any changes take effect.