Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
Инструменты/GitHubGitHub/matpb/linux-fingerprint-r503
Безопасность встроенных системКриптографияТестирование на ПроникновениеАппаратная БезопасностьАутентификацияRed Teaming
GitHubmatpb/linux-fingerprint-r503

linux-fingerprint-r503

Вход в систему Linux по отпечатку пальца с использованием датчика Grow R503 + Arduino + демона на Rust, заменяющего fprintd

Репозиторий
4421 месяц назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

linux-fingerprint-r503 — вход по отпечатку пальца в Linux с помощью Grow R503 + Arduino

CI r503d firmware Rust 2024 Platform: Linux License: MIT

Самодельный USB-сканер отпечатков пальцев для Linux. Общая стоимость компонентов менее $15. Замена для штатного fprintd — PAM, настройки KDE, настройки GNOME, fprintd-verify, sudo с пальцем, разблокировка экрана пальцем — всё работает.

Начиная с fw=1.0 / r503d 1.0.0 провод Arduino↔хост аутентифицирован: каждая команда и ответ содержат MAC SipHash-2-4, привязанный к секрету, установленному по принципу TOFU в EEPROM. Атаки повторного воспроизведения и горячей замены на последовательный USB-канал блокируются. Полное описание, включая то, что не покрывает угрозная модель, см. в SPEC.md §13.

Датчик R503, установленный в вырезанный вручную деревянный корпус, светится синее кольцо

жаль, что у меня нет 3D-принтера…``` ┌──────────┐ UART ┌─────────────┐ USB-CDC ┌──────────────────┐ │ Grow │ 57600 8N1│ Arduino │ /dev/r503 │ r503d daemon │ │ R503 │◀─────────▶│ (firmware) │◀──────────▶│ net.reactivated │ │ sensor │ 3.3V TTL │ │ framed, │ .Fprint on D-Bus│ └──────────┘ └─────────────┘ MAC'd └──────────────────┘ │ ▼ PAM, KDE, GNOME, fprintd-verify, …

root@kitploit:~
## Зачем

Аппаратные USB-сканеры отпечатков пальцев для Linux — редкость, дороги, а те,
что существуют (Validity, Synaptics и т.д.), работают через обратно разработанные
нестабильные драйверы libfprint, которые ломаются при обновлениях прошивки вендора.
Протокол Grow R503 **открыт**, сторона Arduino — ваш собственный код,
а уровень совместимости с libfprint — просто D-Bus.

В итоге вы получаете сканер отпечатков пальцев, код которого можно прочитать
от корки до корки.

## Список материалов

| Деталь | Примечания | Примерная цена |
|--------|------------|------|
| Ёмкостный датчик отпечатков пальцев Grow R503 | Круглый с RGB-кольцом | ~$10 |
| Плата Arduino Uno R3 / Nano / Mega / любая на ATmega328 | Любая, поддерживающая SoftwareSerial | $5–$25 |
| 4–6 перемычек | Dupont / макетная плата | копейки |

Вот и всё. **Никакого преобразователя уровней, никакого делителя напряжения** — см. [`SPEC.md` §3.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md)
почему (линия RX у R503 на практике терпит 5 В; даташит врёт).

## Подключение```
R503             Arduino (Uno R3 / Nano / etc.)
----             ------------------------------
Red (VCC)        3V3
White (3.3VT)    3V3                  (touch-IC supply; shares rail with red)
Black (GND)      GND
Yellow (TXD)     D2  ── SoftwareSerial RX
Brown (RXD)      D3  ── SoftwareSerial TX   (direct — no divider!)
Blue (WAKEUP)    D4                          (optional; not used by firmware yet)

Если ваш R503 поставляется с разъемом JST-SH, отрежьте 6-контактный переходник JST-SH-to-Dupont, чтобы разделить провода. Коричневый иногда бывает зеленым в зависимости от продавца — проверяйте по проводу, который идет в контакт RXD разъема JST, а не по цвету.

Предварительные требования

Протестировано на Fedora 44 KDE; должно работать на любом дистрибутиве на основе systemd с fprintd, pam_fprintd и актуальной цепочкой инструментов Rust.

Системные пакеты:

ДистрибутивСборкаСреда выполнения
Fedora / RHELrust cargo arduino-cli tpm2-tss-develfprintd pam fprintd-pam tpm2-tss
Debian / Ubunturustc cargo arduino-cli libtss2-devfprintd libpam-fprintd libtss2-esys-3.0.2-0

Пакеты tss-esapi нужны только в том случае, если вы планируете использовать --pair --seal-tpm (SPEC §13.12). В остальных случаях демон собирается и запускается без TPM — tss-esapi является жесткой зависимостью сборки, но мягкой зависимостью времени выполнения (код запускается только когда существует /var/lib/r503d/key.tpm).

Rust 1.95+, arduino-cli в вашем $PATH.

У вас есть TPM2?```bash ls /dev/tpmrm0 && tpm2_pcrread sha256:7 | head -3

root@kitploit:~
Если обе операции успешны, ваш хост может использовать путь с запечатанным ключом. Если `/dev/tpmrm0` отсутствует (старое оборудование, TPM отключен в BIOS или виртуальная машина без виртуального TPM), придерживайтесь стандартного потока с открытым ключом.

## Сборка и установка

### 1. Прошейте прошивку

Откройте `firmware/r503fp/r503fp.ino` в Arduino IDE и загрузите. Или с помощью `arduino-cli`:```bash
# Uno R3:
arduino-cli compile --fqbn arduino:avr:uno firmware/r503fp/
arduino-cli upload  --fqbn arduino:avr:uno --port /dev/ttyACM0 firmware/r503fp/

# Nano (modern Optiboot, including most Elegoo / WAVGAT clones):
arduino-cli compile --fqbn arduino:avr:nano:cpu=atmega328 firmware/r503fp/
arduino-cli upload  --fqbn arduino:avr:nano:cpu=atmega328 --port /dev/ttyUSB0 firmware/r503fp/

# Nano with legacy 57600-baud bootloader (older clones):
#   replace `cpu=atmega328` with `cpu=atmega328old`

Прошивка использует Adafruit_Fingerprint. IDE предложит установить её при первой компиляции.

Если arduino-cli upload завершается ошибкой not in sync: resp=0x7e, ваш загрузчик — другой вариант — замените atmega328 ↔ atmega328old и повторите попытку. Оба работают; разница лишь в скорости загрузчика.

2. Сборка демона

Требуется Rust 1.95+.```bash cd pcside/daemon cargo build --release

root@kitploit:~
### 3. Установка```bash
sudo bash pcside/daemon/dist/install.sh

That script:

  • устанавливает target/release/r503d в /usr/local/bin/r503d
  • создаёт /var/lib/r503d/ (режим 0700 root:root) для ключа, состояния и реестра пользовательских слотов
  • записывает правило udev, которое представляет Arduino как /dev/r503 и блокирует узел устройства с правами root:root 0600 (только демону, работающему от root, он нужен; это закрывает путь по умолчанию 0660 root:dialout, так что ни один другой локальный пользователь не сможет открыть порт — аудит безопасности 2026-05-28 / H1). Следствие: после установки любая ручная команда arduino-cli/serial-monitor для /dev/r503 требует sudo.
  • устанавливает systemd-юнит (/etc/systemd/system/r503d.service)
  • переопределяет запись автозапуска D-Bus для net.reactivated.Fprint
  • устанавливает polkit-действие (/usr/share/polkit-1/actions/net.reactivated.fprint.device.r503d.policy), используемое шлюзом идентификации вызывающего

Он идемпотентен — повторно запускайте его после каждого cargo build --release, чтобы развернуть новый бинарник.

4. Сопряжение Nano с демоном

Недавно прошитый Nano не сопряжён — демон будет с ним общаться, но прошивка будет отклонять каждую команду. Выберите один из двух описанных ниже способов; оба приводят к сопряжённому Nano и работающему демону. Способ с TPM-запечатыванием рекомендуется, если на вашем хосте есть TPM2 (см. раздел «Предварительные требования» для быстрой проверки).

Файл разрешения (/etc/r503d/allow-pair), используемый в обоих способах, существует для предотвращения атаки, при которой злоумышленник спешит к вашему рабочему месту со своим собственным Nano — сопряжение без root невозможно. r503d --pair удаляет маркер до отправки ключа на Nano: если хост выйдет из строя между подтверждением на стороне Nano и сохранением на стороне хоста, шлюз уже будет закрыт, поэтому следующая попытка сопряжения потребует от администратора снова создать маркер с помощью touch. Досрочное завершение (нет маркера или «уже сопряжено») оставляет маркер нетронутым для повторной попытки.

4a. Сопряжение с ключом в открытом виде (по умолчанию)

Используйте это, если у вас нет устройства TPM2 или если вам не нужна защита от атак на офлайн-диск.```bash sudo systemctl stop r503d sudo mkdir -p /etc/r503d sudo touch /etc/r503d/allow-pair # opt-in (see SPEC §13.5) sudo r503d --pair # 128-bit key → /var/lib/r503d/key sudo systemctl start r503d

root@kitploit:~
Приложение также позволяет настраивать переключатели подсказок и меток при отображении результатов. Кроме того, вы можете экспортировать результаты в нескольких форматах, включая Markdown, CSV и обычный текст.

## Возможности

- **Многоформатный экспорт**: Сохраняйте извлеченные данные в формате Markdown, CSV или обычного текста.
- **Переключатель подсказок и меток**: Настройте поведение подсказок и меток при просмотре данных.
- **Интерфейс командной строки (CLI)**: Автоматизируйте процесс извлечения с помощью встроенного инструмента CLI.
- **Обновления в реальном времени**: Отслеживайте ход и обновления во время процесса извлечения.
- **Удобный интерфейс**: Навигация по данным с помощью четкого и организованного пользовательского интерфейса.

## Использование CLI

После установки вы можете запустить инструмент из командной строки:

```bash
extract-scan -i input.txt -o output.csv

Полный список доступных опций можно получить командой:

root@kitploit:~
extract-scan --help

Справочник API

Если вы предпочитаете интегрировать этот инструмент в свои сценарии Python, вы можете импортировать основной модуль:

root@kitploit:~
from core import extract_data

data = extract_data('input.txt', format='csv')

Для получения дополнительных сведений обратитесь к документации.

Лицензия

Этот проект лицензирован по лицензии MIT — подробности см. в файле LICENSE.```bash sudo r503d --status

port: /dev/r503

firmware: fw=1.1 fmt=2

firmware paired: true

firmware counter: 42

host key.tpm: (absent)

host key: /var/lib/r503d/key

host key.bak: /var/lib/r503d/key.bak

tpm device: (absent)

allow-pair: (absent)

root@kitploit:~
#### 4b. TPM-опечатанное связывание (рекомендуется на хостах с TPM2, SPEC §13.12)

Тот же процесс, плюс `--seal-tpm`. Сгенерированный ключ опечатывается для **PCR7** (политика Secure Boot + ключи) и записывается в `/var/lib/r503d/key.tpm` вместо файла `key` в открытом виде. Атакующие с offline-доступом к диску (`dd` несмонтированного раздела, замена SSD во враждебный хост) получат только шифротекст.```bash
sudo systemctl stop r503d
sudo mkdir -p /etc/r503d
sudo touch /etc/r503d/allow-pair
sudo r503d --pair --seal-tpm              # seals new key to current PCR7
sudo systemctl start r503d

hexway или отправьте pull request.

Использование

root@kitploit:~
# Build Docker image
docker build -t apple_bleee .

# Run in an interactive mode
docker run -it --net=host --privileged apple_bleee

# Run in "headless" mode
# Using the predefined SSID and WIFI password of the desired network
docker run -it --net=host --privileged apple_bleee -m headless --ssid <SSID> --wifi-password <WIFI_PASSWORD>

# Run in "headless" mode with specific Actions on triggers:
# If Apple device is discovered, show db.py contents
docker run -it --net=host --privileged apple_bleee -m headless -at show_db -d </path/to/db>
# If the victim connected to the Wi-Fi, log a specific message
docker run -it --net=host --privileged apple_bleee -m headless -ac log -c "Hello, World!"

# To perform BLE DoS attack run:
docker run -it --net=host --privileged apple_bleee -m dos

# To perform BLE Spam attack run:
docker run -it --net=host --privileged apple_bleee -m spam

# To perform Password Phishing attack:
docker run --rm --net=host -v </path/to/save/passwords/>:/root/captures/ -e DISPLAY=host.docker.internal:0 --privileged apple_bleee -m phishing -p /root/captures

# AppleJuice attack:
docker run -it --net=host --privileged apple_bleee -m juice

Сборка с нуля

  1. Первоначальная настройка:

    root@kitploit:~
    sudo -i
    apt update && apt install -y python3-pip libglib2.0-dev libbluetooth-dev
    git clone https://github.com/hexway/apple_bleee.git && cd apple_bleee
    
  2. Установка зависимостей:

    root@kitploit:~
    # Install requirements for the tool
    pip3 install -r requirements.txt
    
    # Install utils for Wi-Fi and DoS attacks
    sudo apt install -y aircrack-ng
    
  3. Скопируйте конфигурацию или добавьте её вручную: config.json пример с учетными данными WiFi для DoS-атаки (опционально):

    root@kitploit:~
    {
    
root@kitploit:~
sudo r503d --status
# port:             /dev/r503
# firmware:         fw=1.1 fmt=2
# firmware paired:  true
# firmware counter: 12
# host key.tpm:     /var/lib/r503d/key.tpm
# host key:         (missing)
# host key.bak:     (missing)
# tpm device:       /dev/tpmrm0
# allow-pair:       (absent)
```
Обновления ядра, обновления initrd, обновления прошивки UEFI через `fwupd` и обновления grub2 **не** изменяют PCR7 и не требуют перезапечатывания. PCR7 изменяется только при редактировании политики Secure Boot, регистрации MOK или перемещении диска на другой хост — в этом случае демон отказывается запускаться с ошибкой `TPM_RC_POLICY_FAIL`, и `dist/reseal-tpm.sh` восстанавливает работу примерно за 90 секунд. См. раздел [Восстановление: PCR7 изменён](#recovery-pcr7-changed-need-to-reseal).

### 5. Регистрация и проверка```bash
# Enroll a finger (use KDE Settings → Users → Fingerprint Auth for a GUI):
fprintd-enroll mat

# Verify:
fprintd-verify mat

# sudo with finger:
sudo whoami
```
Оба диалога — Настройки KDE (Plasma 6) и диалог учётной записи пользователя в GNOME Control Center — управляют `r503d` точно так же, как они управляют вышестоящим `fprintd`.

### Повторная привязка / ротация ключа

Если вам нужен новый ключ (компрометация ключа, плановая замена оборудования, паранойя):```bash
sudo systemctl stop r503d
sudo r503d --unpair                        # framed; wipes Nano EEPROM + host key
sudo touch /etc/r503d/allow-pair
sudo r503d --pair                          # plaintext-key rotation
#  - or -
sudo r503d --pair --seal-tpm               # TPM-sealed rotation
sudo systemctl start r503d
```
**Совпадайте с вашим исходным путем сопряжения.** Если вы изначально использовали `--seal-tpm`, выполняйте ротацию с помощью `--seal-tpm` — в противном случае ротация незаметно понизит вас до ключа в открытом виде на диске.

### Восстановление: PCR7 изменился, требуется повторное запечатывание

Если вы использовали `--pair --seal-tpm` и позже изменили что-то, что измеряет PCR7 (Secure Boot выключен/включен, зарегистрирован новый MOK, диск перемещен на другую машину), демон откажется запускаться с сообщением в журнале о `TPM_RC_POLICY_FAIL`. Восстановление — одна команда:```bash
sudo bash pcside/daemon/dist/reseal-tpm.sh
```
Скрипт останавливает `r503d`, перепрошивает `firmware/r503fp_wipe/` для очистки EEPROM Nano, перепрошивает основную прошивку, создаёт `/etc/r503d/allow-pair`, запускает `r503d --reseal-tpm` для генерации нового ключа, запечатанного к *текущему* PCR7, и снова запускает демон. Примерное время: ~90 секунд. Зарегистрированные отпечатки сохраняются — шаблоны хранятся во флеш-памяти датчика R503, а не Nano.

Скрипту требуется наличие `arduino-cli`. Если он установлен в `$HOME/.local/bin` пользователя, он определяется автоматически через `$SUDO_USER`; в противном случае установите `ARDUINO_CLI=/full/path/to/arduino-cli` перед запуском.

### Восстановление: утерян `state.json` (рассинхронизация счётчика)

Если хост-ключ цел, но `/var/lib/r503d/state.json` отсутствует или откатился (восстановлена старая резервная копия, случайное удаление), счётчик демона отстаёт от `last_seen` Nano, и каждая кадрированная команда возвращает `ERR replay`. `r503d --status` сообщает об этом; исправление — одна команда:```bash
sudo systemctl stop r503d
sudo r503d --resync                         # reads Nano last_seen, sets host counter to last_seen+1
sudo systemctl start r503d
```
Без повторной привязки, без перепрошивки — ключ никогда не перемещается. Запрос `status`, на который полагается `--resync`, не требует аутентификации, но он может только *переместить* счётчик хоста вперёд, чтобы он соответствовал тому, что уже зафиксировал Nano, поэтому он никогда не может сделать старый кадр воспроизводимым (в худшем случае лгущий MITM вызывает ещё один `ERR replay`, что он мог бы сделать и так, искажая кадры). См. [`SPEC.md` §13.11](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

### Восстановление: хост-ключ полностью утерян

Аутентифицированная команда `--unpair` требует ключ для авторизации. Если все копии на диске утеряны (сбой диска, случайное удаление, оба файла `key` + `key.bak` удалены, или потерян `key.tpm` blob), вам понадобится запасной выход **reflash-to-wipe** — та же процедура, которую автоматизирует `dist/reseal-tpm.sh` для случая с изменённым PCR7 выше:```bash
sudo systemctl stop r503d
# /dev/r503 is root:root 0600 since install (audit H1), so the uploads need root.
sudo arduino-cli upload --fqbn arduino:avr:nano:cpu=atmega328 --port /dev/r503 firmware/r503fp_wipe/
# Wait ~1s for the wipe to complete (LED starts blinking — that's the wipe sketch).
sudo arduino-cli upload --fqbn arduino:avr:nano:cpu=atmega328 --port /dev/r503 firmware/r503fp/
sudo touch /etc/r503d/allow-pair
sudo r503d --pair
sudo systemctl start r503d
```
Если `sudo arduino-cli` сообщает «команда не найдена» (arduino-cli находится в вашем `~/.local/bin`, а не в `PATH` пользователя root), запустите его как `sudo env "PATH=$PATH" arduino-cli …` или укажите абсолютный путь.

Это не бэкдор, которым может воспользоваться злоумышленник: повторное сопряжение требует прав root на хосте (файл опционального согласия и CLI-флаг `--pair` требуют root), поэтому перепрошитый Nano не может быть доверенным, если у вас нет прав root.

### Удаление```bash
sudo bash pcside/daemon/dist/uninstall.sh
```
Отменяет всё, снимает маскировку `fprintd`, оставляет `/var/lib/r503d/` (ключ, состояние, пользователи) на месте на случай, если вы захотите переустановить позже. Удалите этот каталог вручную, если хотите получить полностью чистую установку.

## Как это работает

Arduino запускает небольшую прошивку с ASCII-протоколом (`firmware/r503fp/`), которая общается с нативным двоичным протоколом R30x ("Sync Word") R503 на своей стороне UART и обменивается построчными текстовыми командами с хостом через USB-CDC: `ping`, `info`, `enroll N`, `verify`, `delete N`, `clear`, `led off`. Полный протокол v1 в [`SPEC.md` §5](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

Начиная с `fw=1.0` (Milestone E работы с аутентифицированным каналом v2), каждая команда и ответ обёрнуты в кадр `C <counter> <body> M <mac>` / `R <counter> <seq> <body> M <mac>`, MAC-кодированные с помощью SipHash-2-4 поверх TOFU-сопоставленного 128-битного ключа. Nano хранит монотонный счётчик с выравниванием износа в EEPROM; демон хранит соответствующий счётчик в `/var/lib/r503d/state.json`. Попытки воспроизведения (на стороне прошивки `incoming <= last_seen`) отклоняются как `ERR replay`; подделанные кадры отклоняются как `ERR mac_invalid`. Полные спецификация, модель угроз и известные ограничения в [`SPEC.md` §13](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

Демон на Rust (`r503d`) общается через D-Bus на `net.reactivated.Fprint` — бит-в-бит тем же интерфейсом, который предоставляет upstream `fprintd` — так что каждый клиент `fprintd` работает без изменений. JSON-файл рядом с `/var/lib/r503d/users.json` сопоставляет (пользователь, палец) с индексами слотов во внутренней flash R503.

Структура:```
firmware/r503fp/             Arduino firmware (v2 framed ASCII protocol)
firmware/r503fp_wipe/        Emergency one-shot EEPROM wipe (lost-key recovery)
firmware/*                   Diagnostic / development sketches (ping, loopback, ...)
pcside/daemon/               Rust daemon (the fprintd replacement)
pcside/daemon/src/{crypto,framing,keystore,state,pairing}.rs
                             v2 wire protocol implementation
pcside/daemon/src/auth.rs    caller-identity gating for D-Bus methods
pcside/daemon/dist/          udev rule, systemd unit, polkit + bus policy,
                             install scripts
docs/                        Decision logs + troubleshooting
SPEC.md                      Full architecture + protocol spec (§13 = v2 auth)
```
## Модель безопасности — краткое резюме

Аутентификация на уровне проводов нацелена на конкретную угрозу — **«злая горничная с пятью минутами и запасным Nano»** плюс враждебный локальный процесс на `/dev/r503` — а не на национальные государства или аппаратных атакующих с лабораториями. Развёртывание на однопользовательском десктопе с задокументированным списком того, что не входит в область действия. Полная модель угроз находится в [`SPEC.md` §13.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md); доказательства реализации и проверки находятся в [`docs/REVIEW-2026-05-28.md`](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/docs/REVIEW-2026-05-28.md). Отдельный аудит эскалации привилегий от злоумышленника (2026-05-28) и его проход по проверке/исправлению каждого утверждения находятся в [`docs/SECURITY-AUDIT-2026-05-28.html`](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/docs/SECURITY-AUDIT-2026-05-28.html) и [`docs/SECURITY-AUDIT-2026-05-28-VALIDATION.html`](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/docs/SECURITY-AUDIT-2026-05-28-VALIDATION.html).

**Защищено:**
- Горячая замена Nano на враждебное устройство (нет ключа → все кадры не проходят MAC).
- Локальный процесс, внедряющий поддельные ответы match на `/dev/r503`. Два уровня: узел устройства имеет права `root:root 0600` (правило udev), и демон удерживает его с помощью `TIOCEXCL`, поэтому не-root процесс не может его открыть — и даже если бы мог, у него нет ключа, поэтому кадр не проходит проверку MAC.
- Повторное воспроизведение записанных кадров `OK match=...` в будущем сеансе.
- Повреждение любого поля кадра путём изменения битов (постоянное по времени сравнение MAC).
- Исчерпание счётчика: пир (или одноразовый MITM во время `--resync`), доводящий монотонный счётчик до `u64::MAX` и навсегда блокирующий канал, блокируется зарезервированным потолком счётчика, применяемым на обоих концах (`fw=1.1+`; SPEC §13.4 / аудит от 2026-05-28 DoS-2).
- Отказ в обслуживании датчика локальным пользователем: один шлюз слотов захвата ограничивает текущую работу по enroll/verify, а пути удаления заблокированы действиями, поэтому поток `Start`/`Stop` (или одновременных удалений) не может заблокировать аутентификацию.
- Подмена, удаление или перечисление отпечатков пальцев другим пользователем локальным не-root пользователем (например, `mallory` вызывает `Claim "root"`, а затем записывает свой палец) — идентификатор вызывающего проверяется на каждом методе D-Bus, принимающем `username`, и политика системной шины запрещает не-`wheel` вызывающим на уровне брокера.
- **Атаки на ключ хоста с офлайн-диска** *в сочетании с `--seal-tpm`*: ключ на диске запечатан TPM2 в PCR7, поэтому `dd` размонтированного раздела или замена SSD во враждебный хост даёт только зашифрованный текст. Распаковывается только на той же машине при той же политике Secure Boot. См. [SPEC §13.12](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

**Не защищено:**
- Компрометация root на хосте (ключ находится в `/var/lib/r503d/key`, `0600 root:root`). Root на работающем хосте также может распечатать вариант, запечатанный TPM — запечатывание ослабляет *офлайн*-атаки, не онлайн.
- Физическая атака на Nano (чтение EEPROM ~30 сек с ISP; вскрытие чипа; и т.д.).
- Атака перепрошивкой прошивки (загрузчик Arduino не имеет подписи — но повторное сопряжение требует root на хосте, поэтому перепрошитый Nano невозможно ввести в доверие без компрометации хоста).
- Компрометация со стороны R503 (протокол R30x вообще не имеет аутентификации; вне нашей области охвата).
- **Криптостойкость.** MAC на SipHash-2-4, 128-битный общий ключ, 64-битный вывод MAC, разделённые по доменам входы MAC. Две независимые реализации (самописный C++ на AVR с самотестированием KAT при загрузке; самописный Rust на хосте, побитно перекрёстно проверенный против стороннего крейта `siphasher` на 1024 случайных векторах в CI). Сравнение MAC на хосте использует `subtle::ConstantTimeEq`. Парсеры провода подвергаются property-fuzzing на каждом запуске CI (~135 000 входов). `cargo audit` чист. Ключ SipHash обёрнут в `zeroize::Zeroizing<...>`, так что он стирается при удалении (как и буферы MAC-входа для каждого кадра). Цель libFuzzer для `cargo fuzz` поставляется в `pcside/daemon/fuzz/` для запусков с длинным корпусом на nightly. Платного стороннего аукта человеком нет — он всё ещё был бы ценен, PR приветствуются.

Полная модель угроз с обоснованием: [`SPEC.md` §13.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

## Ограничения

- **Многопользовательский режим работает, но только для членов группы `wheel`.** Идентификатор вызывающего проверяется на каждом методе D-Bus, который принимает `username` (`Claim`, `EnrollStart`, `VerifyStart`, `ListEnrolledFingers`, `DeleteEnrolledFingers`); запросы от самого себя и `uid 0` (PAM) успешны, запросы от другого пользователя от не-root вызывающего отклоняются с `net.reactivated.Fprint.Error.PermissionDenied`. Политика системной шины дополнительно ограничивает, какие учётные записи могут даже начать диалог: только `root` и члены `wheel` достигают демона, все остальные получают `org.freedesktop.DBus.Error.AccessDenied` на уровне брокера. Нужно записать отпечаток другого пользователя? Станьте root: `sudo fprintd-enroll target-user`. Нужно ослабить ограничение межпользовательского доступа для киоска / многопользовательской лаборатории? Поместите правило JS в `/etc/polkit-1/rules.d/`, нацеленное на [`net.reactivated.fprint.device.setusername`](https://gitlab.freedesktop.org/libfprint/fprintd/-/blob/master/src/net.reactivated.fprint.device.policy.in) — имя действия полностью соответствует upstream fprintd.
- **Одно устройство чтения.** Демон выставляет один объект Device на D-Bus. Настройки с несколькими устройствами чтения требуют расширения Manager.
- **Нет отправки `PropertiesChanged`** для подсказок свойств `finger-present` / `finger-needed`. Каждый распространённый клиент fprintd (PAM, KDE Settings, GNOME) работает от сигналов `EnrollStatus` / `VerifyStatus` (которые отправляются), а не от этих опрашиваемых подсказок — но строгий клиент, использующий `Get + PropertiesChanged`, увидит устаревшие значения.
- **Один Nano = единственная точка отказа.** Если Nano выйдет из строя, вход по отпечатку пальца будет недоступен, пока вы не перепрошьёте запасной и не выполните повторное сопряжение. Оставьте включённым метод аутентификации по паролю как резервный.
- **Потерю State.json можно восстановить одной командой.** Если `state.json` потерян, а в прошивке всё ещё высокий `last_seen`, демон при первой отправке выдаст `ERR replay`. Запустите `sudo r503d --resync` для чтения счётчика Nano и выравнивания хоста — повторное сопряжение не требуется. См. [`SPEC.md` §13.11](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

## Устранение неполадок```bash
# Daemon logs:
sudo journalctl -u r503d.service -f

# Confirm the sensor enumerates correctly:
ls -l /dev/r503
busctl --system call net.reactivated.Fprint /net/reactivated/Fprint/Device/0 \
    net.reactivated.Fprint.Device ListEnrolledFingers s ""

# Confirm fprintd is masked and r503d owns the bus name:
systemctl is-enabled fprintd  # should print "masked"
busctl --system list | grep -i fprint
```
Если демон не запускается или сенсор никогда не отвечает, наиболее распространённое решение — это проводка — см. [`SPEC.md` §3](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md), особенно примечание **"без делителя напряжения"** в §3.1. Более подробная инструкция находится в [`docs/TROUBLESHOOTING.md`](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/docs/TROUBLESHOOTING.md).

## License

MIT — см. [LICENSE](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/LICENSE).

## Credits

- [Adafruit_Fingerprint](https://github.com/adafruit/Adafruit-Fingerprint-Sensor-Library) — реализация протокола R30x на стороне Arduino.
- [zbus](https://github.com/dbus2/zbus),
  [serialport-rs](https://github.com/serialport/serialport-rs),
  [tokio](https://tokio.rs/) — стек Rust для D-Bus / последовательного порта / асинхронности.
- Проект `fprintd` — за разработку чистого интерфейса D-Bus, под который этот демон мог быть реализован, не читая исходный код `libfprint`.
Скачать инструмент
  • устанавливает ограничительную политику системной шины (/etc/dbus-1/system.d/net.reactivated.Fprint.conf) — только члены групп root и wheel могут общаться с демоном; все остальные получают AccessDenied от брокера, прежде чем демон увидит вызов
  • останавливает и маскирует вышестоящий fprintd.service
  • запускает r503d.service