Git

Seni: менеджер входа

Seni это менеджер входа для niri на Wayland. Он заменяет GDM: демон на Rust отвечает за безопасность, гретер и экран блокировки написаны на Vala, GTK4 и libadwaita. Общее описание, причины появления и смысл названия есть на странице проекта. Здесь технические подробности.

Исходный код: plafonlinux/Seni, лицензия GPL-2.0 или новее.

Как это выглядит#

Экран входа: пароль последнего пользователя, смена пользователя маленькой ссылкой.

Экран входа Seni

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

Экран блокировки Seni

Состав#

ЧастьЧто это
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 в планах.