Arch Linux

Fingerprint

Lecteur d'empreintes ELAN 04f3:0c6e sur ASUS ROG Flow X13 : driver elanpress, PAM, écran de verrouillage et sortie de veille.

Les deux règles

A lire avant tout le reste : ces deux regles expliquent 90% des blocages

1. Le lecteur doit être libre au moment où il est réclamé

La toute premiere image capturee apres la reclamation du lecteur sert de reference « pas de doigt ». Si un doigt est deja pose a cet instant, l'empreinte devient la reference, et plus aucun contact ne sera jamais detecte de toute la session. C'est le piege parfait sur un ecran de verrouillage, ou on tend deja la main vers le capteur pendant qu'il se lance.

case CAPTURE_BG_SEND:
    if (self->background) { /* deja capture */ }
    elanpress_send_cmd (ssm, dev, cmd_get_image);  // sinon : capture le fond

Donc : lancer la commande doigt a l'ecart, attendre une seconde, puis poser.

2. Retirer complètement le doigt entre chaque étape

Le driver exige 10 trames consecutives sans contact, a 30 ms, soit 300 ms de doigt totalement absent avant d'accepter l'appui suivant (ELANPRESS_FINGER_OFF_FRAMES). Un doigt qui reste en survol au-dessus du capteur bloque l'enrolement indefiniment, sans aucune erreur. Le rythme correct : appui franc environ 1 s, retrait net environ 1 s, recommencer. Pas de glissement ni de roulement pendant l'appui.

Le bon driver

Le libfprint officiel reconnait ce capteur mais ne le fera jamais marcher

Copy command
lsusb | grep -i fingerprint

Description: Identifie le capteur. Sur le ROG Flow X13 c'est un 04f3:0c6e. Le libfprint officiel le confie a son driver elan, prevu pour les capteurs a image, alors que celui-ci est un capteur press-type. Resultat : detecte, mais l'enrolement echoue toujours sur Calibration failed!

Copy command
journalctl -u fprintd -n 50

Description: Les deux signatures du mauvais driver : Calibration failed! et Internal state machine issue: transition from AWAIT_FINGER_ON to AWAIT_FINGER_OFF should not happen!

Installation

Attention : deux forks existent, un seul fonctionne vraiment

Copy command
sudo pacman -S --needed fprintd

Description: Le demon reste celui des depots officiels. Seul libfprint sera remplace.

Copy command
pkgname=libfprint-elanpress-pr1-git
_pkgname=libfprint
pkgver=1.94.10
pkgrel=1
pkgdesc="libfprint, driver elanpress pour ELAN 04f3:0c6e"
url="https://github.com/Quoteme/libfprint"
arch=(x86_64)
license=(LGPL-2.1-or-later)
depends=(libgusb pixman nss systemd libgudev glib2)
makedepends=(git meson gobject-introspection glib2-devel)
provides=(libfprint libfprint-2.so)
conflicts=(libfprint libfprint-elanpress-git)
source=("git+https://github.com/Quoteme/libfprint.git#branch=elanpress")
sha256sums=('SKIP')

pkgver() {
  cd "$_pkgname"
  local d
  d=$(git describe --long --tags 2>/dev/null | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g')
  if [[ -n "$d" ]]; then
    printf '%s\n' "$d"
  else
    printf '1.94.10.r%s.g%s\n' "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
  fi
}

build() {
  arch-meson "$_pkgname" build -Ddoc=false
  meson compile -C build
}

package() {
  meson install -C build --destdir "$pkgdir"
}

Description: A coller dans un dossier vide sous le nom PKGBUILD, puis makepkg -si. J'utilise la branche du PR de Quoteme, pas le paquet AUR libfprint-elanpress-git : ce dernier attend que le capteur rapporte l'etat 0xcc, que ce modele n'envoie qu'une seule fois par demarrage. Resultat, il enrole une fois puis n'a plus jamais rien detecte. La branche du PR lit l'image et detecte elle-meme la presence du doigt. Le repli dans pkgver() est indispensable : le fork est clone sans tags, git describe ne renvoie rien et makepkg refuse une version vide.

Copy command
sudo tee /etc/udev/rules.d/99-fingerprint-nosuspend.rules <<'RULE'
ACTION=="add|change", SUBSYSTEM=="usb", ATTR{idVendor}=="04f3", \
  ATTR{idProduct}=="0c6e", TEST=="power/control", ATTR{power/control}="on"
RULE
sudo udevadm control --reload-rules
sudo udevadm trigger --action=change --subsystem-match=usb

Description: libfprint marque ce PID comme eligible a l'autosuspend USB via ID_AUTOSUSPEND=1. Ce quirk visait le driver elan, qui gerait le reveil. elanpress non : sans cette regle le capteur dort au bout de 2 secondes et ne repond plus.

Copy command
sudo systemctl stop fprintd && fprintd-list $USER

Description: Verifie quel driver tourne. Attendu : ElanTech press-type fingerprint sensor (press). Si la sortie dit encore ElanTech Fingerprint Sensor, c'est le driver officiel. fprintd redemarre seul via D-Bus.

Enrôlement

Les deux regles de gestuelle ci-dessus ne sont pas du confort : sans elles le driver attend indefiniment

Copy command
fprintd-enroll -f right-index-finger

Description: Environ 8 etapes jusqu'a enroll-completed. Lancer doigt a l'ecart, attendre une seconde, puis poser. Decaler legerement la zone du doigt entre les appuis (bords, pointe).

Copy command
fprintd-enroll -f right-middle-finger
fprintd-enroll -f right-ring-finger

Description: L'astuce contre les no-match : pam_fprintd fait un identify contre tous les doigts enroles, pas seulement celui qui est vise. J'enrole donc le meme index dans trois emplacements, avec des angles differents. Le matching hote d'elanpress est encore rudimentaire, trois modeles font une difference nette.

Copy command
fprintd-verify

Description: Trois sorties possibles, et la distinction compte : verify-match tout va bien, verify-no-match le doigt est lu mais ne correspond pas, fige sur Verify started! le capteur ne voit rien et il faut revoir la gestuelle.

Copy command
fprintd-delete $USER

Description: A faire imperativement apres tout changement de driver. Un template enrole avec un autre driver donne verify-no-match en boucle, sans aucune erreur dans les logs. Ca m'a coute une heure.

PAM

sufficient en tete de pile : le mot de passe reste toujours utilisable, aucun risque de lockout

Copy command
# En tete de la pile auth de /etc/pam.d/{sudo,polkit-1,sddm} :
auth       sufficient                  pam_fprintd.so

Description: sufficient veut dire que si l'empreinte passe, c'est valide. Si elle echoue ou si le capteur ne repond pas, PAM continue vers les lignes suivantes et demande le mot de passe.

Copy command
sudo cp -a /usr/lib/pam.d/polkit-1 /etc/pam.d/polkit-1

Description: polkit-1 n'existe pas dans /etc/pam.d par defaut, il vit dans /usr/lib/pam.d. Le copier avant de l'editer, sinon la modification saute a la prochaine mise a jour de polkit.

Copy command
sudo -k && sudo true

Description: Le test. Doit afficher Placez votre index droit sur le lecteur d'empreintes, puis basculer sur le mot de passe si aucun doigt n'est pose.

Écran de verrouillage

pam_fprintd ne suffit pas ici : ni hyprlock ni Quickshell ne passent par la pile PAM du systeme

Copy command
strings /usr/bin/hyprlock | grep auth:fingerprint

Description: hyprlock a son propre client fprintd en D-Bus depuis la 0.7, desactive par defaut. Il faut un bloc auth { fingerprint { enabled = true } } dans le fichier de conf reellement charge - attention si plusieurs configs coexistent, seule celle passee en -c compte.

Copy command
auth sufficient pam_fprintd.so

Description: Cote Quickshell, le PamContext dedie pointe vers un fichier PAM local au shell (chez moi services/pam/fprintd.conf). Une seule ligne suffit dans ce fichier.

Copy command
pkill -f 'qs -p <shell>' && qs -p <shell> -d

Description: Le piege : le shell ne teste la presence d'empreintes qu'une seule fois, a son demarrage. S'il tournait deja avant l'enrolement, le drapeau reste faux et le lecteur n'est jamais ecoute. Relancer le shell apres tout enrolement ou changement de driver.

Copy command
onPamMessage: { if (fingerPam.messageIsError) { ... } }

Description: Sans ce handler, aucun retour visuel sur les refus : pam_fprintd reessaie plusieurs fois en interne et chaque refus arrive en message PAM, pas dans onCompleted. L'ecran reste fige sur son invitation et donne l'impression d'un lecteur mort. messageIsError distingue le refus de l'invitation sans lire le texte, qui suit la locale systeme.

Sortie de veille

Le probleme qui revient a chaque reveil sur un portable

Copy command
sudo systemctl stop fprintd

Description: Le deblocage immediat, sans reboot. Au reveil libfprint garde le device marque suspendu et le claim precedent reste accroche : Cannot run while suspended, ou The device has already been opened!

Copy command
# /etc/systemd/system/fprintd-resume.service
[Unit]
Description=Libere le lecteur d'empreintes apres une sortie de veille
After=suspend.target hibernate.target hybrid-sleep.target

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl stop fprintd.service

[Install]
WantedBy=suspend.target hibernate.target hybrid-sleep.target

Description: Le correctif permanent, a activer avec systemctl enable fprintd-resume.service. Aucune perte : fprintd est active a la demande par D-Bus et rouvre le device avec un etat neuf a la premiere sollicitation.

Copy command
lsusb -t

Description: A savoir aussi : fprintd n'autorise qu'un seul client a la fois. Lancer fprintd-verify dans un terminal pendant que l'ecran de verrouillage reclame le lecteur en boucle produit le meme already been opened. Deverrouiller d'abord.

Dépannage

Copy command
sudo systemctl stop fprintd
sudo G_MESSAGES_DEBUG=all /usr/lib/fprintd -t 120 > /tmp/fprintd.log 2>&1 &
fprintd-enroll -f right-index-finger
grep -iE "elanpress|finger|touch|background" /tmp/fprintd.log

Description: Le driver en mode verbeux. Ce qu'on cherche : finger lifted between enrollment stages a chaque etape signifie que le driver suit correctement le doigt. Son absence alors que le doigt est bien retire pointe un seuil de detection mal calibre, et la c'est un bug a remonter en amont.

Copy command
echo 3-3 | sudo tee /sys/bus/usb/drivers/usb/unbind
sleep 1
echo 3-3 | sudo tee /sys/bus/usb/drivers/usb/bind

Description: Rebind USB, remet l'etat interne du capteur a zero quand il est completement coince. Verifier le numero de bus avec lsusb -t, il peut changer. Arreter fprintd avant.

Polkit

Une popup de mot de passe pendant un fprintd-verify ne vient jamais du verify. La politique net.reactivated.fprint.device dit exactement qui demande quoi en session active :

verify       allow_active = yes              # jamais de mot de passe
enroll       allow_active = auth_self_keep   # ton mot de passe, puis memorise
setusername  allow_active = auth_admin_keep  # mot de passe admin

C'est donc un enrol, et le keep explique que la popup ne revienne pas ensuite.

Maintenance

Le paquet est compile localement. Une mise a jour de glib2, systemd ou libgusb peut casser l'ABI. Si l'empreinte cesse de fonctionner, recompiler avec makepkg -si puis sudo systemctl stop fprintd. pacman -Syu ne reinstalle pas libfprint officiel par-dessus, grace a provides et conflicts, mais verifier ne coute rien :

pacman -Q | grep libfprint