
Inicio de sesión por huella dactilar en el escritorio de Linux mediante un sensor Grow R503 + Arduino + un daemon de reemplazo de fprintd en Rust
Un lector USB de huellas dactilares para escritorios Linux construido a partir de componentes. Coste total de las piezas inferior a 15 $. Sustituto directo del fprintd oficial: PAM, Ajustes de KDE, Ajustes de GNOME, fprintd-verify, sudo con el dedo y desbloqueo de pantalla con el dedo, todo funciona.
A partir de fw=1.0 / r503d 1.0.0 el cable Arduino↔host está autenticado: cada comando y respuesta lleva un MAC SipHash-2-4 con clave asociada a un secreto emparejado por TOFU en la EEPROM. Los ataques de reproducción y de intercambio en caliente contra el enlace serie USB quedan bloqueados. Consulta SPEC.md §13 para ver el diseño completo, incluido lo que el modelo de amenazas no cubre.

ojalá tuviera una impresora 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, …
## Por qué
Los lectores de huellas dactilares USB para Linux son escasos, caros y los
que existen (Validity, Synaptics, etc.) se basan en controladores libfprint
inestables creados mediante ingeniería inversa que se rompen con las
actualizaciones de firmware del proveedor. El protocolo del Grow R503 es **público**,
el lado de Arduino es tu propio código, y la capa de compatibilidad libfprint es solo D-Bus.
También terminas con un lector de huellas dactilares cuyo código fuente puedes leer de arriba
a abajo.
## Lista de materiales
| Pieza | Notas | Coste aprox. |
|------|-------|------|
| Sensor de huellas dactilares capacitivo Grow R503 | El redondo con el anillo RGB | ~$10 |
| Placa Arduino Uno R3 / Nano / Mega / cualquier placa ATmega328 | Cualquier placa que ejecute SoftwareSerial | $5–$25 |
| 4–6 cables puente | Dupont / placa de pruebas | trivial |
Eso es todo. **Sin cambiador de nivel, sin divisor de voltaje** — consulta [`SPEC.md` §3.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md)
para saber por qué (la línea RX del R503 tolera 5V en la práctica; la ficha técnica miente).
## Conexiones```
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 tu R503 viene con el conector JST-SH, corta un pigtail de 6 pines JST-SH a Dupont para sacar los cables. El marrón a veces es verde dependiendo del vendedor — verifica contra el cable que va al pin RXD del conector JST, no por el color.
Probado en Fedora 44 KDE; debería funcionar en cualquier distro basada en systemd con fprintd, pam_fprintd y una toolchain reciente de Rust.
Paquetes del sistema:
| Distribución | Compilación | Ejecución |
|---|---|---|
| Fedora / RHEL | rust cargo arduino-cli tpm2-tss-devel | fprintd pam fprintd-pam tpm2-tss |
| Debian / Ubuntu | rustc cargo arduino-cli libtss2-dev | fprintd libpam-fprintd libtss2-esys-3.0.2-0 |
Los paquetes tss-esapi solo son necesarios si planeas usar --pair --seal-tpm (SPEC §13.12). El daemon se compila y funciona sin un TPM de lo contrario — tss-esapi es una dependencia de compilación obligatoria pero una dependencia de ejecución opcional (la ruta de código solo se ejecuta cuando existe /var/lib/r503d/key.tpm).
Rust 1.95+, arduino-cli en tu $PATH.
¿Tienes un TPM2?```bash ls /dev/tpmrm0 && tpm2_pcrread sha256:7 | head -3
Si ambos tienen éxito, tu host puede usar la ruta de clave sellada. Si falta
`/dev/tpmrm0` (hardware antiguo, TPM deshabilitado en la BIOS o una VM sin TPM
virtual), quédate con el flujo de clave en texto plano predeterminado.
## Compilar e instalar
### 1. Grabar el firmware
Abre `firmware/r503fp/r503fp.ino` en el Arduino IDE y súbelo. O con
`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`
El firmware utiliza Adafruit_Fingerprint. El IDE ofrecerá instalarla
en la primera compilación.
Si arduino-cli upload falla con not in sync: resp=0x7e, tu bootloader
es la otra variante — intercambia atmega328 ↔ atmega328old y reintenta. Ambos
funcionan; la diferencia es solo la velocidad de baudios del bootloader.
Requiere Rust 1.95+.```bash cd pcside/daemon cargo build --release
### 3. Instalación```bash
sudo bash pcside/daemon/dist/install.sh
Ese script:
target/release/r503d en /usr/local/bin/r503d/var/lib/r503d/ (modo 0700 root:root) para la clave, el estado y el
registro de ranuras de usuario/dev/r503 y bloquea el
nodo de dispositivo a root:root 0600 (solo el daemon, que se ejecuta como root, lo necesita;
esto cierra la ruta predeterminada 0660 root:dialout para que ningún otro usuario local pueda
abrir el puerto — auditoría de seguridad 2026-05-28 / H1). Consecuencia: después de la
instalación, cualquier comando manual de arduino-cli/serial-monitor contra /dev/r503
requiere sudo./etc/systemd/system/r503d.service)net.reactivated.Fprint/usr/share/polkit-1/actions/net.reactivated.fprint.device.r503d.policy)
utilizada por la compuerta de identidad del llamanteEs idempotente — vuelve a ejecutarlo después de cada cargo build --release para
reimplementar el nuevo binario.
Un Nano recién flasheado no está vinculado — el daemon intentaría hablar con él, pero el firmware rechazaría cada comando enmarcado. Elige uno de los dos flujos siguientes; ambos terminan con un Nano vinculado y un daemon funcional. El flujo sellado con TPM se recomienda si tu equipo tiene un TPM2 (consulta Requisitos previos para la comprobación rápida).
El archivo de adhesión voluntaria (/etc/r503d/allow-pair) utilizado en ambos flujos existe para
frustrar a un atacante que corra a tu escritorio con su propio Nano — el emparejamiento
sin root es imposible. r503d --pair elimina el marcador antes de
enviar la clave al Nano: si el equipo se bloquea entre la confirmación del lado del Nano
y la persistencia del lado del host, la compuerta ya está cerrada, por lo que el siguiente intento
de emparejamiento requiere que un administrador vuelva a hacer touch al marcador. Una salida previa al envío
(sin marcador, o «ya vinculado») deja el marcador intacto para reintentar.
Utiliza esto si no tienes un dispositivo TPM2, o si no necesitas resistencia a ataques de disco fuera de línea.```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
I don't see any input text to translate. The chunk content appears to be missing from your message. Please provide the actual text for chunk 15/37 and I'll translate it from English to Spanish according to the rules.```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)
Mismo flujo, más --seal-tpm. La clave generada se sella a PCR7
(política de Secure Boot + claves) y se escribe en /var/lib/r503d/key.tpm
en lugar del archivo key en texto plano. Los atacantes con acceso sin conexión al disco (un dd de una partición
desmontada, cambio de SSD a un host hostil) solo obtienen texto cifrado.```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
No se recibió ningún texto de entrada en este chunk.```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)
Las actualizaciones del kernel, de initrd, de firmware UEFI de fwupd y de grub2
no cambian PCR7 y no requieren un nuevo sellado. PCR7 solo
cambia con ediciones de la política de Secure Boot, inscripciones de MOK
o al mover el disco a otro host — en ese punto, el daemon se niega a
iniciar con TPM_RC_POLICY_FAIL y dist/reseal-tpm.sh se recupera en
~90 segundos. Consulte Recuperación: PCR7 cambiado.
fprintd-enroll mat
fprintd-verify mat
sudo whoami
Tanto la Configuración de KDE (Plasma 6) como los diálogos de huellas dactilares de cuentas de usuario del Centro de Control de GNOME controlan `r503d` exactamente igual que controlan el `fprintd` estándar.
### Re-emparejamiento / rotación de claves
Si quieres una clave nueva (clave comprometida, cambio de hardware planificado, paranoia):```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
Haz que coincida tu ruta de emparejamiento original. Si originalmente usaste --seal-tpm, rota con --seal-tpm — de lo contrario, la rotación te degrada silenciosamente a una clave en texto plano en disco.
Si usaste --pair --seal-tpm y luego cambiaste algo que PCR7 mide (Secure Boot activado/desactivado, nuevo MOK inscrito, disco movido a otra máquina), el demonio se negará a iniciar con un mensaje de journal sobre TPM_RC_POLICY_FAIL. La recuperación es un solo comando:```bash
sudo bash pcside/daemon/dist/reseal-tpm.sh
The script stops `r503d`, reflashes `firmware/r503fp_wipe/` to wipe the
Nano EEPROM, reflashes the main firmware, creates `/etc/r503d/allow-pair`,
runs `r503d --reseal-tpm` to generate a fresh key sealed to the *current*
PCR7, and starts the daemon back up. Tiempo total: ~90 segundos. Las huellas
inscritas se conservan: las plantillas viven en la flash del sensor R503, no
en el Nano.
El script necesita `arduino-cli` disponible. Si está instalado en
`$HOME/.local/bin` de tu usuario, se detecta automáticamente mediante
`$SUDO_USER`; de lo contrario, establece `ARDUINO_CLI=/full/path/to/arduino-cli`
antes de ejecutarlo.
### Recuperación: `state.json` perdido (desincronización del contador)
Si la clave del host está intacta pero `/var/lib/r503d/state.json` falta o se
revirtió (restauraste una copia de seguridad antigua, rm accidental), el
contador del daemon queda por detrás del `last_seen` del Nano y cada comando
enmarcado rebota con `ERR replay`. `r503d --status` lo señala; la solución es
un comando:```bash
sudo systemctl stop r503d
sudo r503d --resync # reads Nano last_seen, sets host counter to last_seen+1
sudo systemctl start r503d
No hay que reemparejar ni reflashear — la clave nunca se mueve. La consulta status de la que depende --resync
no está autenticada, pero solo puede mover el contador del host hacia adelante
para que coincida con lo que el Nano ya ha confirmado, por lo que nunca puede hacer que un frame antiguo
sea repetible (en el peor caso, un MITM mentiroso provoca otro ERR replay, algo que
ya podía hacer alterando frames). Ver SPEC.md §13.11.
El comando autenticado --unpair necesita la clave para autorizarse. Si todas las
copias en disco han desaparecido (fallo de disco, rm accidental, tanto key como key.bak
eliminados, o el blob de key.tpm perdido), necesitas la vía de escape reflash-to-wipe
— el mismo procedimiento que dist/reseal-tpm.sh automatiza para el
caso de PCR7 modificado anteriormente:```bash
sudo systemctl stop r503d
sudo arduino-cli upload --fqbn arduino:avr:nano:cpu=atmega328 --port /dev/r503 firmware/r503fp_wipe/
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
If `sudo arduino-cli` reports command-not-found (arduino-cli lives in your
`~/.local/bin`, not on root's `PATH`), run it as
`sudo env "PATH=$PATH" arduino-cli …` or give the absolute path.
Esto no es una puerta trasera que un atacante pueda usar: volver a emparejar requiere ser root en el host (el archivo de opt-in y la CLI `--pair` ambos requieren root), por lo que un Nano reflasheado no puede pasar a ser de confianza sin que ya seas root.
### Desinstalación```bash
sudo bash pcside/daemon/dist/uninstall.sh
Deshace todo, desenmascara fprintd, deja /var/lib/r503d/ (clave,
estado, usuarios) en su lugar por si quieres reinstalar más adelante. Borra
ese directorio manualmente si quieres una verdadera limpieza.
El Arduino ejecuta un pequeño firmware de protocolo ASCII (firmware/r503fp/)
que se comunica mediante el protocolo binario nativo R30x ("Sync Word") del R503 en su
lado UART e intercambia comandos de texto orientados a líneas con el host a través de
USB-CDC: ping, info, enroll N, verify, delete N, clear,
led off. Protocolo v1 completo en SPEC.md §5.
Desde fw=1.0 (hito E del trabajo del canal autenticado v2), cada
comando y respuesta se envuelve en una trama C <counter> <body> M <mac> /
R <counter> <seq> <body> M <mac> protegida con MAC mediante SipHash-2-4
sobre una clave de 128 bits emparejada por TOFU. El Nano mantiene un contador monotónico
con nivelación de desgaste en la EEPROM; el daemon mantiene un contador correspondiente
en /var/lib/r503d/state.json. Los intentos de replay (del lado del firmware
incoming <= last_seen) se rechazan como ERR replay; las tramas alteradas
reciben ERR mac_invalid. Especificación completa, modelo de amenazas y limitaciones conocidas en SPEC.md §13.
El daemon de Rust (r503d) se comunica por D-Bus en net.reactivated.Fprint — bit a bit
la misma interfaz que expone el fprintd upstream — por lo que cualquier cliente fprintd
funciona sin modificaciones. Un archivo sidecar JSON en /var/lib/r503d/users.json asigna
(usuario, dedo) a índices de ranura en la memoria flash interna del R503.
Estructura:``` 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)
## Modelo de seguridad — resumen rápido
La autenticación a nivel de cable se dirige a una amenaza específica —
**"doncella malvada con cinco minutos y un Nano de repuesto"** más un proceso
local hostil en `/dev/r503` — no a estados-nación ni a atacantes de hardware
con laboratorios. Implementación de escritorio de un solo usuario con una
lista documentada de elementos fuera de alcance. El modelo de amenazas completo
se encuentra en [`SPEC.md` §13.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md); la evidencia de implementación y
revisión se encuentra en
[`docs/REVIEW-2026-05-28.md`](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/docs/REVIEW-2026-05-28.md). Una auditoría
adversarial separada de escalada de privilegios (2026-05-28) y su pasada de
validación/remediación por afirmación están en
[`docs/SECURITY-AUDIT-2026-05-28.html`](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/docs/SECURITY-AUDIT-2026-05-28.html)
y
[`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).
**Defendido:**
- Intercambio en caliente del Nano por una unidad hostil (sin clave → todas
las tramas fallan el MAC).
- Proceso local que inyecta respuestas de coincidencia falsas en `/dev/r503`.
Dos capas: el nodo de dispositivo es `root:root 0600` (regla de udev) y el
demonio lo mantiene con `TIOCEXCL`, por lo que un proceso no root no puede
abrirlo — e incluso si pudiera, no tiene clave, por lo que la trama falla la
verificación MAC.
- Replay de tramas `OK match=...` grabadas en una sesión futura.
- Manipulación por volteo de bits de cualquier campo de la trama (comparación
MAC de tiempo constante).
- Bloqueo (brick) por agotamiento del contador: un peer (o un MITM de una
sola vez durante `--resync`) que lleve el contador monotónico a `u64::MAX` y
atasque permanentemente el canal es bloqueado por un techo de contador
reservado aplicado en ambos extremos (`fw=1.1+`; SPEC §13.4 / auditoría de
2026-05-28 DoS-2).
- Denegación de servicio del sensor por parte de un usuario local: una única
compuerta de ranura de captura limita el trabajo de enroll/verificación en
curso y las rutas de borrado están controladas por acción, por lo que una
inundación de `Start`/`Stop` (o de borrados concurrentes) no puede atascar la
autenticación.
- Plantado / borrado / enumeración de huellas entre usuarios por parte de un
usuario local no root (p. ej., `mallory` llamando a `Claim "root"` y luego
inscribiendo su propio dedo) — la identidad del llamante se comprueba en cada
método D-Bus que toma `username`, y la política del bus del sistema deniega
a los llamantes que no son de `wheel` en la capa de broker.
- **Ataques fuera de línea al disco contra la clave del host** *cuando se
combina con `--seal-tpm`*: la clave en disco está sellada con TPM2 a PCR7,
por lo que un `dd` de una partición desmontada o el traslado de un SSD a un
host hostil produce solo texto cifrado. Solo se desenvuelve en la misma
máquina bajo la misma política de Secure Boot. Ver [SPEC §13.12](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).
**No defendido:**
- Compromiso de root del host (la clave está en `/var/lib/r503d/key`,
`0600 root:root`). El root en un host en ejecución también puede desellar la
variante sellada por TPM — el sellado atenúa los ataques *fuera de línea*,
no los en línea.
- Ataque físico al Nano (lectura de EEPROM ~30 s con ISP; decapado de chip;
etc.).
- Ataque de reflash de firmware (el bootloader de Arduino no tiene firma —
pero el re-parejado requiere root en el host, por lo que un Nano reflasheado
no puede ser aceptado como confiable sin comprometer el host de todos modos).
- Compromiso del lado R503 (el protocolo R30x no tiene autenticación en
absoluto; fuera de nuestro alcance).
- **Postura criptográfica.** MAC SipHash-2-4, clave compartida de 128 bits,
salida MAC de 64 bits, entradas MAC separadas por dominio. Dos
implementaciones independientes (C++ artesanal en el AVR con autoprueba KAT
en el arranque; Rust artesanal en el host, validado cruzadamente bit a bit
contra el crate de terceros `siphasher` en 1024 vectores aleatorios en CI).
La comparación MAC del host usa `subtle::ConstantTimeEq`. Los parsers de
línea se someten a fuzzing de propiedades en cada ejecución de CI
(~135 000 entradas). `cargo audit` limpio. Clave SipHash envuelta en
`zeroize::Zeroizing<...>` para que se borre al hacer drop (al igual que los
búferes de entrada MAC por trama). Un objetivo libFuzzer de `cargo fuzz` se
incluye en `pcside/daemon/fuzz/` para ejecuciones de corpus largo en
nightly. Sin auditoría humana externa de pago — eso seguiría siendo valioso,
PRs bienvenidos.
Modelo de amenazas completo con justificación: [`SPEC.md` §13.1](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).
## Limitaciones
- **El modo multiusuario funciona, pero solo para miembros de `wheel`.**
La identidad del llamante se comprueba en cada método D-Bus que toma un
`username` (`Claim`, `EnrollStart`, `VerifyStart`, `ListEnrolledFingers`,
`DeleteEnrolledFingers`); las autosolicitudes y `uid 0` (PAM) tienen éxito
silenciosamente, el acceso entre usuarios desde un llamante no root se
deniega con `net.reactivated.Fprint.Error.PermissionDenied`. La política del
bus del sistema restringe aún más qué cuentas pueden siquiera iniciar una
conversación: solo `root` y los miembros de `wheel` llegan al demonio, todos
los demás reciben `org.freedesktop.DBus.Error.AccessDenied` en la capa de
broker. ¿Necesitas realizar enroll entre usuarios? Hazte root:
`sudo fprintd-enroll target-user`. ¿Necesitas relajar la restricción de
cruce de usuarios para un kiosco / laboratorio multiusuario? Coloca una
regla JS en `/etc/polkit-1/rules.d/` dirigida a
[`net.reactivated.fprint.device.setusername`](https://gitlab.freedesktop.org/libfprint/fprintd/-/blob/master/src/net.reactivated.fprint.device.policy.in)
— el nombre de la acción replica exactamente el de fprintd upstream.
- **Un solo lector.** El demonio expone un único objeto Device en D-Bus.
Las configuraciones con varios lectores necesitan una extensión del Manager.
- **Sin emisión de `PropertiesChanged`** para las propiedades de sugerencia
`finger-present` / `finger-needed`. Todos los clientes fprintd comunes (PAM,
KDE Settings, GNOME) se basan en las señales `EnrollStatus` / `VerifyStatus`
(que sí se emiten), no en esas sugerencias por sondeo — pero un cliente
estricto que haga `Get + PropertiesChanged` verá valores obsoletos.
- **Un solo Nano = un solo punto de fallo.** Si el Nano muere, el inicio de
sesión por huella desaparece hasta que reflashes un repuesto y lo vuelves a
emparejar. Mantén un método de autenticación por contraseña habilitado como
respaldo.
- **La pérdida de State.json se recupera con un solo comando.** Si
`state.json` se pierde mientras el firmware aún tiene un `last_seen` alto,
el demonio se topa con `ERR replay` en el primer envío. Ejecuta
`sudo r503d --resync` para leer el contador del Nano y realinear el host —
sin necesidad de volver a emparejar. Ver [`SPEC.md` §13.11](https://github.com/matpb/linux-fingerprint-r503/blob/HEAD/SPEC.md).
## Solución de problemas```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 el demonio no arranca o el sensor nunca responde, la solución más común
es el cableado: consulte SPEC.md §3, en particular la
nota "sin divisor de voltaje" en §3.1. Hay un manual más detallado
en docs/TROUBLESHOOTING.md.
MIT — consulte LICENSE.
fprintd — por diseñar una interfaz D-Bus limpia que
este demonio pudiera implementar sin tener que leer nunca
el código fuente de libfprint./etc/dbus-1/system.d/net.reactivated.Fprint.conf) — solo los miembros de root y
wheel pueden hablar con el daemon; todos los demás reciben
AccessDenied en el broker, antes de que el daemon vea la llamadafprintd.service aguas arribar503d.service