Comme expliqué à l'épisode
précédent, je goûte au sandwich glacé, i.e., Android 4. Voilà que
je trouve une petite crotte de ragondin dans mon dessert : pas quelque
chose de grave, mais qui m'agace un peu : quelqu'un a décidé que pour
les connexions IPv6, le sandwich glacé en question
utiliserait
une adresse
aléatoire fréquemment renouvelée, plutôt que l'adresse standard
dérivée de l'adresse MAC de l'interface Wifi —
voilà qui est bon pour les gens qui portent un chapeau en papier d'alu
sur la tête et qui ne veulent pas qu'on identifie leur adresse, mais
moi qui ne porte pas de tel chapeau je préfère que mon téléphone
utilise des adresses stables, bref, je veux désactiver
ces privacy extensions
. Sous Linux, je sais
comment faire : il faut mettre la
clé sysctl
net.ipv6.conf.wlan0.use_tempaddr
à 0. Mais là on est sous Android : comment faire ? Ma première
tentative a été d'écrire un script qui lance sysctl -w
net.ipv6.conf.wlan0.use_tempaddr=0
dans les répertoires de
démarrage (/data/local/userinit.d
) : ça ne marche pas, il
faut croire que quelqu'un change la clé ultérieurement.
C'est donc le point de départ d'un jeu de piste où on essaie de
trouver quel chemin a suivi le ragondin pour arriver jusque là. Une
petite recherche exhaustive de la chaîne dans tous les fichiers
m'apprend que ce réglage use_tempaddr
est probablement
positionné par un processus démon appelé netd
. De fait,
je constate
ici (vers les lignes 366–386) que quand ce démon reçoit une
commande interface ipv6privacyextensions $iface
enable
(après, je ne sais pas par quel canal il reçoit
des commandes
, ni comment on lui en passe), il va
écrire 2
dans /proc/sys/net/ipv6/conf/$iface/use_tempaddr
.
Une solution simple mais ignoble serait simplement de modifier le
binaire de ce démon et de changer la chaîne en question pour mettre
autre chose à la place, comme ça le démon échouera et ne fera rien.
Mais comme je suis naïf, je voudrais faire propre. Remontons donc
d'un cran. Qui passe cette commande au démon netd
et
comment ? Encore un petit peu de Google et je découvre
que la
classe com.android.server.NetworkManagementService
(vers les lignes 451–462) a une
méthode setInterfaceIpv6PrivacyExtensions
qui envoie la
commande en question au démon netd
. Très bien, mais je
ne sais pas ce que c'est que cette classe, ni comment on appelle cette
méthode. Encore un coup de Google, et j'apprends que
c'est la
classe android.net.wifi.WifiStateMachine
(vers la
ligne 1983) qui décide d'appeler la méthode en question. Et là,
le true
est hardcodé : il y a un connard quelque part
(celui qui a committé le code est un certain Irfan Sheriff, mais ce
n'est pas forcément lui l'auteur ou le décideur) qui a décidé que
je devais utiliser des adresses aléatoires. On retrouve
l'attitude que je déteste chez Google, de décider les choses pour
l'utilisateur au lieu de lui offrir une préférence (fût-elle un peu
cachée) à choisir.
Bon, alors maintenant comment je me sors de ce merdier ? Le
problème est qu'avoir accès au source est de peu de réconfort, parce
que pour pouvoir changer quoi que ce soit, il faudrait recompiler,
soit le fichier unique considéré (mais alors trouver comment faire
pour recompiler un unique fichier dans les sources des frameworks
Android, et ensuite, une fois ce fichier recompilé, comment le mettre
en place dans le téléphone, ça risque de prendre un temps vraiment
infini), soit tout Android, ce qui suppose de trouver les sources
exactes de la version que j'ai utilisée, et la façon de recompiler, ce
qui risque de ne pas être moins difficile (sans parler des dizaines de
gigas d'espace disque et des dizaines d'heures que consommerait la
compilation). Peut-être que je peux écrire une application Android
qui demande les permissions pour parler soit à
l'objet com.android.server.NetworkManagementService
soit
au démon netd
pour leur ordonner de défaire ce qu'aura
fait android.net.wifi.WifiStateMachine
, mais rien n'est
moins sûr (j'ai l'impression que les classes
en com.android
, contrairement à celles
en android
, sont des classes internes qui ne sont pas
exportées vers les applications).
Finalement, je vais peut-être opter pour le patch binaire de ce
démon netd
(en espérant que le binaire n'est pas signé ou
quoi que ce soit !). C'est quand même assez énervant que le ragondin
ait réussi à dresser un mur aussi difficile à franchir, comme ça.
Ajout : De fait,
remplacer /proc/sys/net/ipv6/conf/%s/use_tempaddr\000
par /dev/null\000
dans le binaire netd
fait
ce que je veux. Je vais me contenter de cette méthode crade.
Pour ne pas qu'on m'accuse de râler dans mon blog sans faire remonter les problèmes au bon endroit, mon bug-report est ici.
Troll : j'imagine que sur un iPhone, il y a une jolie petite case à
cocher pour choisir si on veut les privacy
extensions
sous IPv6.