vendredi 14 juin 2019

Chapitre 61 : Accès à un site web par son nom et aux données d’une page en assembleur ARM


Au chapitre 56 lors de la présentation des fonctions des sockets, je vous avais demandé de réfléchir à la récupération de l’adresse IP d’un site en utilisant la commande Linux ping puisqu’il n’existe pas à ma connaissance d’un appel système Linux qui effectue cela. Il aurait été possible et plus simple d’utiliser la fonction de la librairie C gethostbyname, mais dans ce cas, autant tout programmer en C !!!
Dans ce chapitre, nous allons effectuer l’accès à un site web en fonction de son nom (www.toto par exemple) en utilisant non pas la commande ping mais la commande host.
Pour cela, nous devons résoudre quelques petits problèmes : lancer depuis un programme assembleur l commande Linux host, récupérer son résultat, analyser son contenu pour extraire et convertir l’adresse IP. Ensuite nous réutiliserons les instructions liées à la création et à l’utilisation d’une socket vues au chapitre 56.
Pour illustrer cela, nous allons nous connecter au site de météoFrance, charger la page /previsions-meteo-france/bulletin-France, et extraire le texte du bulletin météo du jour. ( voir le source du programme).
Pour lancer la commande host, nous utilisons l’appel système Linux execve code x0b en lui passant comme argument une zone mémoire qui contient l’adresse du nom de l’exécutable à lancer (/usr/bin/host) et l’adresse du nom du site pour lequel nous recherchons l’adresse IP. Hélas, cet appel système ne retourne rien et s’arrête si son exécution réussit !!. mais il affiche le résultat dans la console de sortie.
Il nous faut donc exécuter l’appel système dans un thread (fils) et attendre sa fin pour récupérer son résultat dans le thread parent. Dans ce thread, nous utilisons l’appel système WAIT4 pour attendre le signal de fin du fils et pour récupérer le résultat de la console, il nous faut créer un pipe puis une dérivation (appel système dup2 code 0x3F pour enfin lire les données par l’appel système READ.
Maintenant, que nous avons le résultat de la commande host dans un buffer mémoire, il nous suffit d’extraire l’adresse IP par la fonction extchaine et de la convertir en adresse IP de la structure sockaddr_in necessaire à la création de la socket.
Ensuite nous utilisons les fonctions de création, connexion , lancement de la requête et lecture des données de la socket pour alimenter un buffer contenant la page complète. Pour terminer, il faut rechercher les balises encadrant le texte à afficher pour l’extraire, effectuer quelques remplacements (<br/>) et l’afficher.
J’ai fait simple et donc le texte affiché peut nécessiter encore quelques corrections !!
Ce programme peut être adapté pour accéder à d’autres informations d’autres sites.

Ce que j’ai bien sûr fait et cela m’a fait découvrir qu’il ne fonctionnait pas pour les sites sécurisés  (protocole https). J’ai donc dû l’adapter pour résoudre ce problème en utilisant la librairie Openssl disponible sur le Raspberry.
Pour pouvoir créer un programme assembleur avec cette librairie, nous devons d’abord installer le package libssl-dev et modifier les options pour le linker : -lssl -lcrypto
Pour l’exemple, notre programme va afficher le cours du bitcoin en se connectant sur le site bitcoin.fr et en chargeant la page /le-cours-du-bitcoin/.
Nous reprenons toute la partie de notre premier programme concernant le lancement de la commande host, la récupération de l’adresse IP et la création de la socket ( le port utilisé sera le 443 à la place du port habituel 80).
A partir de là, nous allons faire appel aux fonctions de la librairie openssl pour initialiser les données nécessaires(OPENSSL_init_crypto, ERR_load_BIO_strings), créer une connexion sécurisée (OPENSSL_init_ssl) et effectuer le lien entre cette connexion et la socket(SSL_set_fd). Puis nous lancerons la requête par l’appel SSL_write et récupérerons la réponse par SSL_read. Remarque : il est nécessaire de programmer une boucle de lecture car c’est le serveur qui pilote l’envoi des données par bloc).
Ensuite dans la routine analyseReponse, nous cherchons les mots clés précedents le cours du bitcoin que nous extrayons avec la sous routine extChaine et nous terminons par l’affichage du libellé et du cours.
Je n’ai pas trop regardé en détail les possibilités de la librairie openssl, ni le détail des paramètres à passer aux différentes fonctions par manque de temps !!!

Aucun commentaire:

Enregistrer un commentaire