Yubikey, Windows, bépo et esperluette (&)

Published: 15-10-2015

Updated: 02-03-2018

By: Maxime de Roucy

tags: keyboard windows yubikey

Introduction

Dans cet article je vais racconter comment j’ai galéré pour faire sortir un esperluette (&) à ma Yubikey.

Je dois depuis quelques temps travaillé sous Windows (arg…) et tapé plusieurs fois par jours une certaine chaine de caractère assez longue et complexe (je n’entrerais pas dans les détails ☺). Pour me « simplifier la vie » j’ai décidé d’utiliser ma Yubikey en mode « static password » pour générer cette séquence de caractères.

Dans l’article gestion du clavier sous GNU/Linux je détailles ce que sont les scancodes et keycodes, ainsi que leurs différents types.

L’interface graphique de configuration de la Yubikey yubikey-personalization-gui permet de configurer la yubikey en mode « static password » mais avec le layout qwerty. En fait, on écrit sont text dans un champ dédié et le logiciel traduit ce text en scancode en se basant sur une table de convertion qwerty. Donc si je configure ma yubikey après avoir écrit « q » dans ce champ, j’obtiendrait un « q » si je suis en qwerty au moment ou j’appui sur le bouton de la yubikey, un « a » si je suis en azerty, un « b » si je suis en bépo…

Une astuce consiste à passer en qwerty et taper son text sur le clavier au layout désiré (disont bépo) sans se soucié de ce qui va être entré dans le champs de text. Normalement la convertion text → scancode qui sera faite par yubikey-personalization-gui donnera le bon text dans le layout bépo. Par exemple, j’utilise abituellement un layout bépo, je veux que ma yubikey génère la séquence « bépo » (pour faire simple). Je me met temporairement en layout qwerty et après mettre placé dans le champ text, j’appui sur les touche « bépo » sur mon clavier bépo. Dans le champ, le text « qwer » s’affiche (normal je suis en qwerty). Je configure la Yubikey avec ce champ text qui sera traduit par le logiciel en « scancode des quatre première touche de lettre clavier », ce qui nous donne « bépo » dans un layout bépo.

Cette technique montre rapidement ses limites, notamment quand on veut généré des chiffre ou des caractères spéciaux.

L’outil ykpersonalize en ligne de commande est plus compliqué à manier mais beaucoup plus puissant. Il permet par exemple de configurer la yubikey en lui indiquant directement les scancodes à retourner… enfin pas tout à fait, mais j’y viens.

max@laptop % ykpersonalize -1 -v -oshort-ticket -ofixed=h:141a0815 -a00000000000000000000000000000000
max@laptop % ykpersonalize -2 -v -oshort-ticket -ofixed=h:141a0815 -a00000000000000000000000000000000 -o-static-ticket -o-strong-pw1 -o-strong-pw2 -o-man-update

Les deux commande précédente permettent respectivement de configurer les slot 1 et 2 de la yubikey avec les scancode des quatres première touche de lettre du clavier. Explications :

Ci dessus j’indique que ykpersonalize permet de configurer la yubikey en lui indiquant directement les scancodes à retourner, mais pas tout à fait. En fait lorsqu’on configure la Yubikey on ne spécifie que les scancode d’appui, la clé s’occupe elle même de trouver les scancode de relache… et c’est bien dommage. En effet parfois on veut envoyer plusieurs scancode d’appui avec d’envoyer des relache, pour faire des combinaisons de touches, Shift+A, Ctrl+C, AltGr+p… Pour indiqué à la yubikey qu’un scancode doit être précédé et suivit d’un appui et d’une relache de la touche Shift il faut ajouté 0x80 au scancode. Par exemple le scancode pour « b » en bépo est 0x14, pour obtenir un « B » je doit paramétrer la Yubikey avec le scancode 0x94. Il n’y a pas d’équivalent pour les autres touches, il est donc impossible de générer des combinaisons de touches avec Alt, AltGr ou quoique ce soit d’autre que Shift.

D’où mon problème avec le esperluette (&) car en bépo celui-ci se génére via la combinaisons de touches AltGr+p.

Pour le contourner j’ai utilisé le scancode de la touche scroll et remappé mon layout pour qu’à l’apparition de ce scancode le caractère « & » soit imprimé. Au début j’ai essayé d’utiliser la touche pause mais celle-ci à un scancode particulier qui est couplé avec numlock… bref je n’ai pas réussi à le remapper correctement sans effet de bord donc j’ai choisi d’utiliser la touche scroll.

remap sous Windows

Pour remapper un touche de clavier sous windows il existe plusieurs solutions :

J’ai choisi d’utiliser MSKLC sachant que c’est la méthode principal détaillé dans la page wiki du pilote bépo Windows. Et qu’il y a même déjà une page expliquant comment modifier ce pilote.

J’ai d’abord téléchager et installé une VM Windows gratuite pour pouvoir faire la compilation et les tests.

Installer bepo.klc.

cygwin % PATH="$PATH":'/cygdrive/c/Program Files/Microsoft Keyboard Layout Creator 1.4/bin/i386'
cygwin % kbdutool.exe -u -s bepo.klc

Modifier les fichier bepo.H et bepo.C :

--- bepo-a/bepo.H	2015-10-19 13:29:49.140863200 -0700
+++ bepo-b/bepo.H	2015-10-19 10:54:03.717515200 -0700
@@ -100,4 +100,5 @@
  #define T34 _EQ(                                        'H'                      )
 #undef  T35
  #define T35 _EQ(                                        'F'                      )
-
+#undef  T46
+#define T46 _EQ(NONAME)

--- bepo-a/bepo.C	2015-10-19 13:29:49.172047600 -0700
+++ bepo-b/bepo.C	2015-10-19 10:54:49.545518200 -0700
@@ -286,6 +286,7 @@
   {0xff         ,0      ,WCH_NONE ,WCH_NONE ,WCH_NONE ,0x02db   ,WCH_NONE },
   {VK_SPACE     ,0      ,' '      ,0x00a0   ,WCH_NONE ,'_'      ,0x202f   },
   {VK_DECIMAL   ,0      ,'.'      ,'.'      ,WCH_NONE ,WCH_NONE ,WCH_NONE },
+  {VK_NONAME    ,0      ,'&'      ,WCH_NONE ,WCH_NONE ,WCH_NONE ,WCH_NONE },
   {0            ,0      ,0        ,0        ,0        ,0        ,0        }
 };

Explications : Dans le fichier bepo.H j’indique que le scancode de la touche scroll correspond au keycode de la touche « NONAME ». Dans le fichier bepo.C j’indique que le keycode de la touche « NONAME » (VK_NONAME) correspond au keysym « & ». Les quatres éléments suivant le « ’&‘ » sont les keysym généré lorsque la touche est accompagné respectivement de Shift, Ctrl, Ctrl+Alt, Shift+Ctrl+Alt.

Pour savoir que « T46 » correspond au scancode de la touche scroll, on peut aller voir dans le fichier suivant qui indique le mapping complet correspondant au clavier qwerty.

/cygdrive/c/Program Files/Microsoft Keyboard Layout Creator 1.4/inc/kbd.h

Pourquoi je m’enmerde à mapper le scancode sur le keycode NONAME si je peux assigner directement le keysym & au keycode VK_SCROLL ? D’après ce que j’ai compris, certain keycode déclanche des actions bien spécifique, par exemple VK_SNAPSHOT permet de prendre une capture d’écran, VK_NUMLOCK toggle le status numlock de windows… Si on assigne un keysym à ces keycode cela ne supprimera pas leurs actions pour autant. Par exemple si j’assigne « a » à VK_SNAPSHOT, appuyer sur la touche de snapshot écrira « a » à l’écran et prendra une capture d’écran. VK_SCROLL toggle le status scroll de windows, et le comportement d’Excel change en fonction de ce status. En plus chez moi, ça allume une led sur le clavier… et j’aime pas ça.

Donc ma solution a été d’assigner au scan code de la touche scroll un key code qui ne déclanche aucune action et qui n’est utilisé par aucun logiciel. D’après le listing des keycodes disponible sous Windows, VK_NONAME n’est pas utilisé on peut donc en faire ce qu’on veut pour l’instant… parfait !

Une fois les fichiers modifiés on empèche leurs modification et on lance la compilation :

cygwin % attrib.exe +R bepo.H
cygwin % attrib.exe +R bepo.C
cygwin % kbdutool.exe -u -x bepo.klc

Pour savoir si vous devez utiliser x, m ou i faite simplement un file sur l’une des dll de System32 de votre système cible. Par exemple, ici je vais utilisé la dll généré par l’option -x :

cygwin % file /cygdrive/c/Windows/System32/kernel32.dll
/cygdrive/c/Windows/System32/kernel32.dll: PE32 executable (DLL) (console) Intel 80386, for MS Windows

cygwin % file bepo.dll.*
bepo.dll.i: PE32+ executable (DLL) (native) Intel Itanium, for MS Windows
bepo.dll.m: PE32+ executable (DLL) (native) x86-64, for MS Windows
bepo.dll.x: PE32 executable (DLL) (native) Intel 80386, for MS Windows

Attention si vous vous planté vous allez faire planté tous vos système de gestion de clavier. Ça veut dire plus de clavier du tous, quelque soit le layout… même pas de clavier virtuel… et bien on se sent bien con quant on a plus aucun clavier. Pour réparé il suffit d’utiliser un livecd et de supprimer la dll merdique.

Une fois qu’on a généré la dll du layout on peut la copier dans System32 à la place du layout bépo standard, et rebooter.

cygwin % cygstart --action=runas mv cygdrive/c/Windows/System32/bepo.dll{,.save}
cygwin % cygstart --action=runas cp bepo.dll cygdrive/c/Windows/System32/

Mais ce n’est pas fini ☺ Ça fonctionne très bien dans l’invite de commande windows (cmd) ou notepad… mais pas dans mintty, l’émulateur de terminal de cygwin. En fait il y a un bug dans mintty, celui-ci ne test le layout que pour certains keycode. J’ai fourni un patch au développeurs et espère qu’il sera intégré dans les prochaines versions (up : le patch est maintenant intégré et le bug n’éxiste plus).

diff --git a/src/wininput.c b/src/wininput.c
index 22c5db5..ebd975f 100644
--- a/src/wininput.c
+++ b/src/wininput.c
@@ -772,10 +772,9 @@ win_key_down(WPARAM wp, LPARAM lp)
       else if (key <= '9') app_pad_code(key);
       else if (VK_OEM_PLUS <= key && key <= VK_OEM_PERIOD)
         app_pad_code(key - VK_OEM_PLUS + '+');
-    when VK_PACKET:
-      layout();
     otherwise:
-      return 0;
+      if (!layout())
+        return false;
   }

Vous pouvez compiler facilement mintty sous cygwin en installant les paquets gcc-g++ et make. Lancer simplement make dans le répertoire des sources.