Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
linux-fingerprint-r503 — Connexion par empreinte digitale au bureau Linux à l'aide d'un capteur Grow R503 + Arduino + d'un démon de remplacement de fprintd en Rust | Kitploit
Outils/GitHubGitHub/matpb/linux-fingerprint-r503
Sécurité des Systèmes EmbarquésCryptographieTests d'IntrusionSécurité MatérielleAuthentificationRed Teaming
GitHubmatpb/linux-fingerprint-r503

linux-fingerprint-r503

Connexion par empreinte digitale au bureau Linux à l'aide d'un capteur Grow R503 + Arduino + d'un démon de remplacement de fprintd en Rust

Voir le dépôt
442il y a 1 moisVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

linux-fingerprint-r503 — connexion par empreinte digitale pour Linux avec un Grow R503 + Arduino

CI r503d firmware Rust 2024 Platform: Linux License: MIT

Un lecteur d'empreintes digitales USB fait de pièces détachées pour les bureaux Linux. Coût total des pièces moins de 15 $. Remplacement direct du fprintd amont — PAM, Paramètres KDE, Paramètres GNOME, fprintd-verify, sudo avec le doigt, déverrouillage d'écran avec le doigt fonctionnent tous.

À partir de fw=1.0 / r503d 1.0.0 la liaison Arduino↔hôte est authentifiée : chaque commande et réponse porte un MAC SipHash-2-4 lié à un secret apparié par TOFU dans l'EEPROM. Les attaques par rejeu et par échange à chaud contre la liaison série USB sont bloquées. Voir SPEC.md §13 pour la conception complète, y compris ce que le modèle de menace ne couvre pas.

Capteur R503 monté dans un boîtier en bois découpé à la main, anneau bleu lumineux

si seulement j'avais une imprimante 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:~
## Pourquoi

Les lecteurs d'empreintes digitales USB matériels pour Linux sont rares, chers, et ceux qui existent (Validity, Synaptics, etc.) sont rétro-ingénierés via des pilotes libfprint instables qui cessent de fonctionner avec les mises à jour du firmware des fabricants. Le protocole du Grow R503 est **public**, le côté Arduino est votre propre code, et la couche de compatibilité libfprint n'est que du D-Bus.

Vous vous retrouvez aussi avec un lecteur d'empreintes dont vous pouvez lire le code source, de haut en bas.

## Liste du matériel

| Composant | Notes | Coût approx. |
|------|-------|------|
| Capteur d'empreintes digitales capacitif Grow R503 | Le modèle rond avec l'anneau RGB | ~$10 |
| Arduino Uno R3 / Nano / Mega / toute carte ATmega328 | Tout ce qui exécute SoftwareSerial | $5–$25 |
| 4–6 fils de connexion | Dupont / breadboard | négligeable |

C'est tout. **Ni level shifter, ni diviseur de tension** — voir [`SPEC.md` §3.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md) pour savoir pourquoi (la ligne RX du R503 tolère 5 V en pratique ; la fiche technique ment).

## Câblage```
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)

Si votre R503 est livré avec le connecteur JST-SH, coupez un pigtail 6 broches JST-SH vers Dupont pour sortir les fils. Le brun est parfois vert selon le vendeur — vérifiez par rapport au fil qui va dans la broche RXD du connecteur JST, pas la couleur.

Prérequis

Testé sur Fedora 44 KDE ; devrait fonctionner sur toute distribution basée sur systemd avec fprintd, pam_fprintd et une toolchain Rust récente.

Paquets système :

DistributionCompilationExécution
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

Les paquets tss-esapi ne sont nécessaires que si vous prévoyez d'utiliser --pair --seal-tpm (SPEC §13.12). Le démon se compile et s'exécute sans TPM sinon — tss-esapi est une dépendance de compilation obligatoire mais une dépendance d'exécution facultative (le chemin de code n'est emprunté que lorsque /var/lib/r503d/key.tpm existe).

Rust 1.95+, arduino-cli dans votre $PATH.

Avez-vous un TPM2 ?```bash ls /dev/tpmrm0 && tpm2_pcrread sha256:7 | head -3

root@kitploit:~
Si les deux réussissent, votre hôte peut utiliser le chemin de la clé scellée. Si `/dev/tpmrm0` est
absent (matériel ancien, TPM désactivé dans le BIOS, ou une VM sans TPM virtuel),
restez avec le flux de clé en texte brut par défaut.

## Compilation et installation

### 1. Flasher le firmware

Ouvrez `firmware/r503fp/r503fp.ino` dans l'IDE Arduino et téléversez. Ou avec
`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`

Le firmware utilise Adafruit_Fingerprint. L'IDE proposera de l'installer lors de la première compilation.

Si arduino-cli upload échoue avec not in sync: resp=0x7e, votre bootloader est l'autre variante — remplacez atmega328 ↔ atmega328old et réessayez. Les deux fonctionnent ; la différence réside uniquement dans le débit en bauds du bootloader.

2. Compiler le démon

Nécessite Rust 1.95+.```bash cd pcside/daemon cargo build --release

root@kitploit:~
### 3. Installation```bash
sudo bash pcside/daemon/dist/install.sh

Ce script :

  • installe target/release/r503d vers /usr/local/bin/r503d
  • crée /var/lib/r503d/ (mode 0700 root:root) pour la clé, l'état, et le registre d'emplacements utilisateur
  • écrit la règle udev qui expose l'Arduino en /dev/r503 et verrouille le nœud de périphérique en root:root 0600 (seul le démon, qui tourne en root, en a besoin ; cela ferme le chemin par défaut 0660 root:dialout afin qu'aucun autre utilisateur local ne puisse ouvrir le port — audit de sécurité 2026-05-28 / H1). Conséquence : après l'installation, toute commande manuelle arduino-cli/serial-monitor à destination de /dev/r503 nécessite sudo.
  • installe l'unité systemd (/etc/systemd/system/r503d.service)
  • surcharge l'entrée de lancement automatique D-Bus pour net.reactivated.Fprint
  • installe l'action polkit (/usr/share/polkit-1/actions/net.reactivated.fprint.device.r503d.policy) utilisée par le contrôle d'identité de l'appelant

C'est idempotent — relancez-le après chaque cargo build --release pour redéployer le nouveau binaire.

4. Appairer le Nano avec le démon

Un Nano fraîchement flashé n'est pas appairé — le démon lui parlerait, mais le firmware rejetterait chaque commande tramée. Choisissez l'un des deux flux ci-dessous ; les deux aboutissent à un Nano appairé et un démon fonctionnel. Le flux scellé par TPM est recommandé si votre hôte dispose d'un TPM2 (voir Prérequis pour la vérification rapide).

Le fichier opt-in (/etc/r503d/allow-pair) utilisé dans les deux flux existe pour déjouer un attaquant qui se précipite à votre bureau avec son propre Nano — l'appairage sans root est impossible. r503d --pair supprime le marqueur avant d'envoyer la clé au Nano : si l'hôte plante entre la validation côté Nano et la persistance côté hôte, la porte est déjà fermée, donc la prochaine tentative d'appairage nécessite qu'un administrateur exécute touch sur le marqueur à nouveau. Un abandon avant envoi (pas de marqueur, ou « déjà appairé ») laisse le marqueur intact pour une nouvelle tentative.

4a. Appairage avec clé en clair (défaut)

Utilisez ceci si vous n'avez pas de périphérique TPM2, ou si vous n'avez pas besoin de résistance aux attaques par disque hors ligne.```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:~
The input chunk is empty — there is no source text provided to translate. Please supply chunk 15 of 37 and I will translate it into French.```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)

4b. Appairage scellé TPM (recommandé sur les hôtes TPM2, SPEC §13.12)

Même procédure, avec en plus --seal-tpm. La clé générée est scellée sur PCR7 (politique Secure Boot + clés) et écrite dans /var/lib/r503d/key.tpm au lieu du fichier key en clair. Les attaquants accédant au disque hors ligne (dd d'une partition non montée, insertion du SSD dans un hôte hostile) n'obtiennent que du texte chiffré.```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

root@kitploit:~
I don't see any source text to translate — the input after `INPUT:` is empty. Please provide the actual chunk content (19/37) and I'll translate it into French right away.```bash
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)

Les mises à jour du noyau, les mises à jour de l'initrd, les mises à jour du firmware UEFI via fwupd et les mises à jour de grub2 ne modifient pas PCR7 et ne nécessitent pas de rescellage. PCR7 ne change qu'en cas de modifications de la politique Secure Boot, d'inscriptions MOK ou de déplacement du disque vers un autre hôte — auquel cas le démon refuse de démarrer avec TPM_RC_POLICY_FAIL et dist/reseal-tpm.sh récupère en ~90 secondes. Voir Récupération : PCR7 modifié.

5. Enrôlement et vérification```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

root@kitploit:~
Les boîtes de dialogue d'empreintes digitales du compte utilisateur
de KDE Settings (Plasma 6) et de GNOME Control Center pilotent `r503d` exactement comme elles pilotent le `fprintd` en amont.

### Réappairage / rotation de clé

Si vous voulez une nouvelle clé (clé compromise, remplacement matériel prévu, paranoïa):```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

Reprenez le même chemin d'appairage que celui d'origine. Si vous avez initialement utilisé --seal-tpm, effectuez la rotation avec --seal-tpm — sinon la rotation vous rétrograde silencieusement vers une clé en clair sur le disque.

Récupération : PCR7 a changé, il faut resceller

Si vous avez utilisé --pair --seal-tpm et avez ensuite modifié un élément que PCR7 mesure (Secure Boot désactivé/activé, nouveau MOK inscrit, disque déplacé vers une autre machine), le démon refusera de démarrer avec un message du journal concernant TPM_RC_POLICY_FAIL. La récupération se fait en une commande :```bash sudo bash pcside/daemon/dist/reseal-tpm.sh

root@kitploit:~
Le script arrête `r503d`, reflashe `firmware/r503fp_wipe/` pour effacer l'EEPROM du Nano, reflashe le firmware principal, crée `/etc/r503d/allow-pair`, exécute `r503d --reseal-tpm` pour générer une nouvelle clé scellée au PCR7 *actuel*, puis relance le démon. Temps réel : ~90 secondes. Les doigts enregistrés sont conservés — les gabarits vivent sur la flash du capteur R503, pas sur le Nano.

Le script nécessite `arduino-cli`. S'il est installé dans le `$HOME/.local/bin` de votre utilisateur, il est détecté automatiquement via `$SUDO_USER` ; sinon, définissez `ARDUINO_CLI=/full/path/to/arduino-cli` avant de l'exécuter.

### Récupération : `state.json` perdu (désynchronisation du compteur)

Si la clé hôte est intacte mais que `/var/lib/r503d/state.json` est manquant ou a été restauré (récupération d'une ancienne sauvegarde, rm accidentel), le compteur du démon retombe derrière le `last_seen` du Nano et chaque commande tramée se heurte à `ERR replay`. `r503d --status` signale ce problème ; la solution est une seule commande :```bash
sudo systemctl stop r503d
sudo r503d --resync                         # reads Nano last_seen, sets host counter to last_seen+1
sudo systemctl start r503d

Pas de réappairage, pas de reflash — la clé ne bouge jamais. La requête status sur laquelle s'appuie --resync n'est pas authentifiée, mais elle ne peut que faire avancer le compteur hôte vers l'avant pour correspondre à ce que le Nano a déjà validé, donc elle ne peut jamais rendre une ancienne trame rejouable (dans le pire des cas, un MITM menteur force un autre ERR replay, ce qu'il pouvait déjà faire en brouillant les trames). Voir SPEC.md §13.11.

Récupération : clé hôte entièrement perdue

La commande authentifiée --unpair a besoin de la clé pour autoriser. Si toutes les copies sur disque ont disparu (panne disque, rm accidentel, key + key.bak toutes deux supprimées, ou blob key.tpm perdu), vous avez besoin de la trappe de secours reflash-to-wipe — la même procédure que dist/reseal-tpm.sh automatise pour le cas de changement de PCR7 ci-dessus :```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

root@kitploit:~
Si `sudo arduino-cli` signale command-not-found (arduino-cli se trouve dans votre
`~/.local/bin`, pas dans le `PATH` de root), lancez-le via
`sudo env "PATH=$PATH" arduino-cli …` ou indiquez le chemin absolu.

Ce n'est pas une porte dérobée qu'un attaquant pourrait utiliser : le ré-appairage nécessite root sur
l'hôte (le fichier d'opt-in et la CLI `--pair` nécessitent tous deux root), donc un
Nano reflashé ne peut pas être mis en confiance sans que vous soyez déjà
root.

### Désinstaller```bash
sudo bash pcside/daemon/dist/uninstall.sh

Restaure tout, démasque fprintd, laisse /var/lib/r503d/ (clé, état, utilisateurs) en place au cas où vous voudriez réinstaller plus tard. Supprimez ce répertoire manuellement si vous voulez une véritable table rase.

Comment ça fonctionne

L'Arduino exécute un petit firmware à protocole ASCII (firmware/r503fp/) qui parle le protocole binaire natif R30x ("Sync Word") du R503 sur son côté UART et échange des commandes texte orientées lignes avec l'hôte via USB-CDC: ping, info, enroll N, verify, delete N, clear, led off. Protocole v1 complet dans SPEC.md §5.

Depuis fw=1.0 (jalon E des travaux sur le canal authentifié v2), chaque commande et réponse est encapsulée dans une trame C <counter> <body> M <mac> / R <counter> <seq> <body> M <mac>, authentifiée par MAC avec SipHash-2-4 sur une clé de 128 bits appariée par TOFU. Le Nano conserve un compteur monotone à nivellement d'usure dans l'EEPROM ; le démon conserve un compteur correspondant dans /var/lib/r503d/state.json. Les tentatives de rejeu (côté firmware incoming <= last_seen) sont rejetées comme ERR replay ; les trames falsifiées sont rejetées avec ERR mac_invalid. Spécification complète, modèle de menace et limitations connues dans SPEC.md §13.

Le démon Rust (r503d) parle D-Bus sur net.reactivated.Fprint — bit pour bit la même interface que celle exposée par fprintd en amont — donc chaque client fprintd fonctionne sans modification. Un sidecar JSON dans /var/lib/r503d/users.json mappe (utilisateur, doigt) vers les indices d'emplacement dans la mémoire flash interne du R503.

Disposition :``` 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)

root@kitploit:~
## Modèle de sécurité — résumé rapide

L'authentification de niveau filaire cible une menace spécifique —
**« femme de chambre malveillante avec cinq minutes et un Nano de rechange »** plus un processus local hostile sur `/dev/r503` — pas des États-nations ni des attaquants matériels avec des laboratoires. Déploiement sur poste de travail mono-utilisateur avec une liste documentée des cas hors périmètre. Le modèle de menace complet se trouve dans [`SPEC.md` §13.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md) ; les preuves d'implémentation et de revue se trouvent dans [`docs/REVIEW-2026-05-28.md`](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/docs/REVIEW-2026-05-28.md). Un audit distinct d'élévation de privilèges de type adversaire (2026-05-28) et sa passe de validation/remédiation par revendication sont dans [`docs/SECURITY-AUDIT-2026-05-28.html`](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/docs/SECURITY-AUDIT-2026-05-28.html) et [`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).

**Défendu :**
- Échange à chaud du Nano avec une unité hostile (pas de clé → toutes les trames échouent au MAC).
- Processus local injectant de fausses réponses de correspondance sur `/dev/r503`. Deux couches : le nœud de périphérique est `root:root 0600` (règle udev) et le démon le maintient avec `TIOCEXCL`, donc un processus non root ne peut pas l'ouvrir — et même s'il le pouvait, il n'a pas la clé, donc la trame échoue à la vérification MAC.
- Rejeu de trames `OK match=...` enregistrées lors d'une session ultérieure.
- Altération par bascule de bit de tout champ de trame (comparaison MAC à temps constant).
- Contre le brick par épuisement du compteur : un pair (ou un MITM ponctuel pendant `--resync`) qui pousse le compteur monotone vers `u64::MAX` et coince définitivement le canal est bloqué par un plafond de compteur réservé appliqué aux deux extrémités (`fw=1.1+` ; audit SPEC §13.4 / 2026-05-28, DoS-2).
- Déni de service local du capteur par un utilisateur local : un unique verrou de slot de capture plafonne le travail d'enrôlement/vérification en vol et les chemins de suppression sont contrôlés par action, donc une inondation de `Start`/`Stop` (ou de suppressions concurrentes) ne peut pas bloquer l'authentification.
- Implantation / effacement / énumération d'empreintes d'un autre utilisateur par un utilisateur local non root (par ex. `mallory` appelant `Claim "root"` puis enrôlant son propre doigt) — l'identité de l'appelant est vérifiée sur chaque méthode D-Bus prenant un `username`, et la politique du bus système refuse les appelants non-`wheel` au niveau du courtier.
- **Attaques hors ligne sur le disque contre la clé hôte** *lorsqu'elle est associée à `--seal-tpm`* : la clé sur disque est scellée TPM2 vers PCR7, donc un `dd` d'une partition démontée ou un échange de SSD dans un hôte hostile ne donne que du texte chiffré. Le déballage n'a lieu que sur la même machine sous la même politique Secure Boot. Voir [SPEC §13.12](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

**Non défendu :**
- Compromission root de l'hôte (la clé est dans `/var/lib/r503d/key`, `0600 root:root`). Le root sur un hôte en fonctionnement peut également désceller la variante scellée TPM — le scellement atténue les attaques *hors ligne*, pas les attaques en ligne.
- Attaque physique sur le Nano (lecture de l'EEPROM en ~30 s avec ISP ; décapsulation de la puce ; etc.).
- Attaque par reflashage du firmware (le bootloader Arduino n'a pas de signature — mais le ré-appairage nécessite root sur l'hôte, donc un Nano reflashé ne peut pas être mis en confiance sans compromission de l'hôte de toute façon).
- Compromission côté R503 (le protocole R30x n'a aucune authentification ; hors de notre périmètre).
- **Posture cryptographique.** MAC SipHash-2-4, clé partagée de 128 bits, sortie MAC de 64 bits, entrées MAC à séparation de domaine. Deux implémentations indépendantes (C++ codée à la main sur l'AVR avec auto-test KAT au démarrage ; Rust codé à la main sur l'hôte, validé bit à bit par recoupement avec la crate tierce `siphasher` sur 1024 vecteurs aléatoires dans le CI). La comparaison MAC côté hôte utilise `subtle::ConstantTimeEq`. Les parseurs filaires sont fuzzés par propriétés à chaque exécution CI (~135 000 entrées). `cargo audit` propre. La clé SipHash est enveloppée dans `zeroize::Zeroizing<...>` pour être purgée lors du drop (tout comme les tampons d'entrée MAC par trame). Une cible libFuzzer `cargo fuzz` est fournie dans `pcside/daemon/fuzz/` pour des exécutions sur corpus long en nightly. Aucun audit humain tiers payant — cela reste précieux, les PR sont bienvenues.

Modèle de menace complet avec justification : [`SPEC.md` §13.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

## Limitations

- **Le multi-utilisateur fonctionne, mais uniquement pour les membres de `wheel`.** L'identité de l'appelant est vérifiée sur chaque méthode D-Bus qui prend un `username` (`Claim`, `EnrollStart`, `VerifyStart`, `ListEnrolledFingers`, `DeleteEnrolledFingers`) ; les auto-requêtes et `uid 0` (PAM) réussissent silencieusement, les requêtes inter-utilisateurs provenant d'un appelant non root sont refusées avec `net.reactivated.Fprint.Error.PermissionDenied`. La politique du bus système restreint en outre les comptes qui peuvent même démarrer une conversation : seuls `root` et les membres de `wheel` atteignent le démon, tous les autres obtiennent `org.freedesktop.DBus.Error.AccessDenied` au niveau du courtier. Besoin d'un enrôlement inter-utilisateurs ? Devenez root : `sudo fprintd-enroll target-user`. Besoin d'assouplir la barrière inter-utilisateurs pour un kiosque / laboratoire multi-utilisateurs ? Déposez une règle JS dans `/etc/polkit-1/rules.d/` ciblant [`net.reactivated.fprint.device.setusername`](https://gitlab.freedesktop.org/libfprint/fprintd/-/blob/master/src/net.reactivated.fprint.device.policy.in) — le nom d'action reprend mot pour mot le fprintd en amont.
- **Un seul lecteur.** Le démon expose un unique objet Device sur D-Bus. Les configurations multi-lecteurs nécessitent une extension du Manager.
- **Aucune émission `PropertiesChanged`** pour les propriétés d'indication `finger-present` / `finger-needed`. Chaque client fprintd courant (PAM, KDE Settings, GNOME) s'appuie sur les signaux `EnrollStatus` / `VerifyStatus` (qui sont émis), pas sur ces indications interrogées — mais un client strict qui fait `Get + PropertiesChanged` verra des valeurs obsolètes.
- **Un seul Nano = point de défaillance unique.** Si le Nano meurt, la connexion par empreinte est perdue jusqu'à ce que vous reflashiez un Nano de rechange et le ré-appairiez. Gardez une méthode d'authentification par mot de passe activée en secours.
- **La perte de State.json est récupérable en une commande.** Si `state.json` est perdu alors que le firmware a toujours un `last_seen` élevé, le démon obtient `ERR replay` à la première émission. Exécutez `sudo r503d --resync` pour lire le compteur du Nano et réaligner l'hôte — aucun ré-appairage nécessaire. Voir [`SPEC.md` §13.11](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).

## Dépannage```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

Si le démon ne démarre pas ou si le capteur ne répond jamais, la solution la plus courante est le câblage — voir SPEC.md §3, en particulier la note "no voltage divider" du §3.1. Un guide plus détaillé est disponible dans docs/TROUBLESHOOTING.md.

Licence

MIT — voir LICENSE.

Crédits

  • Adafruit_Fingerprint — implémentation du protocole R30x côté Arduino.
  • zbus, serialport-rs, tokio — la pile Rust D-Bus / série / async.
  • Le projet fprintd — pour avoir conçu une interface D-Bus propre que ce démon pouvait implémenter sans jamais lire le code source de libfprint.
Télécharger l’outil
  • installe la politique restrictive du bus système (/etc/dbus-1/system.d/net.reactivated.Fprint.conf) — seuls les membres de root et wheel peuvent parler au démon ; tous les autres reçoivent AccessDenied au niveau du courtier, avant que le démon ne voie l'appel
  • arrête et masque le fprintd.service amont
  • démarre r503d.service