Brian J. Tarricone
742ff7b92c
Some drivers/displays don't support the xbacklight stuff, so fall back to sysfs if needed. This usually will require some extra permissions setup on the user's part.
172 lines
7.1 KiB
Markdown
172 lines
7.1 KiB
Markdown
# 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.
|