Seni: менеджер входа
Seni это менеджер входа для niri на Wayland. Он заменяет GDM: демон на Rust отвечает за безопасность, гретер и экран блокировки написаны на Vala, GTK4 и libadwaita. Общее описание, причины появления и смысл названия есть на странице проекта. Здесь технические подробности.
Исходный код: plafonlinux/Seni, лицензия GPL-2.0 или новее.
Как это выглядит#
Экран входа: пароль последнего пользователя, смена пользователя маленькой ссылкой.

Экран блокировки: часы, дата, имя и поле пароля.

Состав#
| Часть | Что это |
|---|---|
crates/seni/ | Демон seni (Rust, tokio, zbus) и seni-unlock-helper |
greeter/ | Гретер seni-greeter (Vala, GTK4, libadwaita) |
lockscreen/ | Экран блокировки seni-lockscreen (Vala, протокол ext-session-lock-v1) |
idl/ | Описание D-Bus-интерфейса, единый источник для Rust и Vala |
data/pam/ | PAM-конфигурации seni, seni-session, seni-autologin, seni-unlock |
tests/ | Тесты контрактов, сквозная проверка D-Bus, антипаттерны Vala |
Архитектура#
systemd
└─ seni.service (Rust, root, tokio + zbus)
├─ слежение за рабочими местами через logind
├─ PAM в отдельном потоке (диалог идёт через каналы и D-Bus в гретер)
├─ запуск гретера: cage seni-greeter (пользователь _greeter)
└─ при входе: проверка PAM, открытие сессии, сброс привилегий, запуск niri
seni-greeter (Vala, GTK4, libadwaita, внутри cage)
└─ клиент D-Bus org.plafon.Seni
seni-lockscreen (Vala, GTK4, ext-session-lock-v1, внутри сессии niri)
└─ seni-unlock-helper (PAM-сервис seni-unlock, без открытия новой сессии)Отдельный рабочий процесс, как у GDM, не нужен: Rust безопасен по памяти, и PAM работает внутри процесса демона.
D-Bus#
Интерфейс описан в idl/org.plafon.Seni.xml, оттуда генерируются привязки и для демона (zbus), и для гретера (gdbus-codegen). Основные интерфейсы:
Manager: список пользователей и сессий;UserVerifier: начало проверки, ответ на запрос PAM, отмена и сигналы о ходе проверки;Greeter: выбор пользователя и сессии, автовход, запуск сессии.
Разрешения шины лежат в data/dbus/org.plafon.Seni.conf.
PAM#
Привязка к PAM написана вручную, на несколько десятков строк FFI. Стандартный крейт pam тянет через bindgen и libclang сотни пакетов, а нужна лишь небольшая поверхность вызовов: pam_start, pam_authenticate, pam_acct_mgmt, pam_setcred, pam_open_session, pam_end.
PAM-сервисы:
| Сервис | Для чего |
|---|---|
seni-session | Единственный сервис интерактивного входа: проверка и открытие сессии одним дескриптором |
seni-autologin | Автовход |
seni-unlock | Разблокировка экрана: только проверка пароля, без новой сессии |
Особенности ALT: пустой /etc/pam.d/login ведёт в other с запретом, реальная цепочка идёт через common-login и system-auth, а проверку выполняет pam_tcb. Блокировку попыток обеспечивает pam_faillock в образе: 10 попыток за 15 минут, блокировка на 5 минут.
Чтобы logind признал сессию активной на рабочем месте, перед open_session в окружение PAM передаются XDG_SEAT и XDG_SESSION_TYPE. Без них сессия регистрируется как «неопределённая» и дисплей ей не передаётся.
Безопасность#
- Демон на Rust, привилегированный код без небезопасного управления памятью, кроме тонкой привязки к PAM.
- Пароль идёт через каналы, не через аргументы командной строки, и затирается в памяти при освобождении.
- Гретер работает от пользователя
_greeter. - Экран блокировки не запускает ничего сам, проверку пароля делает помощник
seni-unlock-helper. Он запускается с правами группыchkpwd(так принято в ALT для блокировщиков), проверяет только учётную запись запустившего пользователя и не открывает новую сессию. - PAM и D-Bus в проекте ревьюятся строго: безопасность важнее скорости.
Настройка#
| Файл | Что в нём |
|---|---|
/etc/seni/greeter.json | Обои, размытие и его сила, цветовая схема |
/etc/seni/autologin | Автовход: строка имя разрешает автовход по запросу гретера, строка имя boot входит один раз за загрузку |
/etc/seni/colors.css | Цвета гретера, создаётся при старте демона из палитры рабочего стола |
Пример greeter.json:
{
"background": { "wallpaper": "/usr/share/backgrounds/default.jpg", "blur": true, "blur_strength": 20 },
"appearance": { "color_scheme": "dark" }
}Значения здесь показывают формат файла. Путь к обоям и сила размытия подставьте свои.
Сборка и проверка#
Сборка идёт в контейнере:
podman build -t seni-dev -f Containerfile .
# демон
podman run --rm -v "$PWD":/src seni-dev bash -c 'cd /src && cargo build'
# гретер
podman run --rm -v "$PWD":/src seni-dev \
bash -c 'cd /src/greeter && meson setup builddir && meson compile -C builddir'Тесты:
cargo test
SENI_BIN=target/debug/seni bash tests/e2e_dbus.sh
python3 tests/test_vala_antipatterns.pyСквозная проверка D-Bus проходит весь путь от запроса проверки до завершения проверки пароля.
Проверка гретера без экрана#
cage умеет работать без реального экрана (WLR_BACKENDS=headless), а grim снимает с него скриншот. Так гретер можно проверить визуально в контейнере. Понадобятся шрифты и иконки (без них интерфейс получится пустым), собственная системная шина и пользователь _greeter.
Ограничения#
- Вход пользователей из доменов (SSSD, IPA) пока не поддерживается: демон читает локальный список пользователей, ручного ввода имени нет.
- Настройки гретера лежат в файле, страница в Tuner в планах.