webmailer.sh

Introduction

Origine du script

Vous êtes au boulot dans une entreprise qui considère que vous n'avez pas besoin d'avoir accès à Internet sur votre poste. Vous devez vous cententer d'un pauvre email (avec un peu de chance vous avez échappé à Lotus Notes). Cela dit parfois vous aimeriez bien avoir accès à vos sites favoris ou bien consulter une adresse particulière. Ce script vous permettra de configurer votre PC personnel branché en permanence à Internet et doté d'un serveur de mail type postfix de façon à ce qu'il vous relaye des pages web par mail (d'où son nom).

Note de compatibilité

Comme je travaille sous OpenBSD, je préfère préciser que ce script est probablement compatible avec tous les UNIX pas trop exotiques. En effet, il n'utilise pas de commandes spécifiques GNU/Linux comme seq qui permet de sortir une séquence de nombres et qui est souvent utilisé avec les boucles for (NdM : la commande seqUsage: seq [OPTION]... DERNIER
ou: seq [OPTION]... PERMIER DERNIER
ou: seq [OPTION]... PREMIER INCRÉMENT DERNIER
Afficher les nombres du PREMIER jusqu'au DERNIER,
selon le PAS d'incrémentation.
fait partie du package GNU shellutils). Du coup, le code est parfois un peu tiré par les cheveux. Cela dit, rien ne vous empêche de modifier un peu le code pour en simplifier la structure.

Par contre je ne garantis pas que certaines structures comme l'utilisation de parenthèses au lieu de crochets dans les tests des structures conditionnelles ne pose pas quelques problèmes sous GNU/Linux (Je n'ai pas de machine sous la main pour m'en assurer).

Le shell utilisé pour ce script est tout simplement sh.

Pré-requis

Pour faire fonctionner ce script, vous devez :

  1. Disposer d'un PC personnel sous Linux/Unix connecté en permanence à Internet (type Freebox).
  2. Avoir sur cette connexion une adresse IP fixe et un DNS associé, ou un service de type DynDNS (le DNS d'une freebox se termine par fbx.proxad.net).
  3. Avoir un serveur mail sur ce PC personnel qui puisse être atteint de l'extérieur (gare à la sécurité !).

Mise en garde

L'utilisation de ce script au sein du système d'information de l'entreprise peut être un moyen de contourner la politique de sécurité mise en oeuvre au sein de celui-ci. Elle peut donc être considérée par l'entreprise comme un acte de piratage et être passible de sanctions.

Explication du fonctionnement du script

L'idée est d'envoyer un mail avec l'adresse de la page web que l'on souhaite voir, que le PC réceptionne cet email, le traite et renvoie en réponse un mail contenant en pièce jointe la page web que l'on souhaitait voir.

Pour cela, nous devons créer un utilisateur spécifique pour le script. Appelons par exemple cet utilisateur webmailer. Dans ce cas, en supossant par ailleurs que votre PC est relié à Internet par une freebox dont le DNS serait xyz98-82-235-256-28.fbx.proxad.net, l'adresse email à laquelle envoyer l'adresse de la page que l'on souhaite est webmailer@xyz98-82-235-256-28.fbx.proxad.net (Vous aurez noté que j'ai utilisé des noms et adresses IP bidons dans cet exemple).

Les mails sous Unix sont gérés dans un fichier plat que l'on trouve dans /var/mail. Pour webmailer, le fichier en question est /var/mail/webmailer. Pour bien comprendre comment il se présente, envoyons un mail de test à cette adresse avec comme sujet http://www.google.fr et sans corps. Voici alors le contenu du fichier (certaines infos ont été modifiées ;)

-bash-3.00# cat /var/mail/
clarkwan   root       webmailer
-bash-3.00# cat /var/mail/webmailer
From christophe.eyquem@free.fr  Sat Feb 25 20:22:17 2006
Return-Path: <mon.adresse@free.fr>
X-Original-To: webmailer@xyz98-82-235-256-28.fbx.proxad.net
Delivered-To: webmailer@xyz98-82-235-256-28.fbx.proxad.net
Received: from smtp3-g19.free.fr (smtp3-g19.free.fr [212.256.20.255])
        by xyz98-82-235-256-28.fbx.proxad.net (Postfix) with ESMTP id 13138C5657
        for <webmailer@xyz98-82-235-256-28.fbx.proxad.net>; Sat, 25 Feb 2006
20:22:17 +0100 (CET)
Received: from [10.0.0.2] (xyz98-82-235-256-28.fbx.proxad.net [82.235.256.28])
        by smtp3-g19.free.fr (Postfix) with ESMTP id 408D2040B3
        for <webmailer@xyz98-82-235-256-28.fbx.proxad.net>; Sat, 25 Feb 2006
20:22:16 +0100 (CET)
Message-ID: <4400AE81.6542704@free.fr>
Date: Sat, 25 Feb 2006 20:22:41 +0100
From: Mon NOM <mon.adresse@free.fr>
User-Agent: Thunderbird 1.5 (Windows/20051201)
MIME-Version: 1.0
To:  webmailer@xyz98-82-235-256-28.fbx.proxad.net
Subject: http://www.google.fr
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

On constate dans ce fichier qu'il y a deux lignes qui nous intéressent particulièrement, ces lignes correspondent au mail que l'on a envoyé :

From: Mon NOM <mon.adresse@free.fr>
Subject: http://www.google.fr

Le script, dont on présente les détails du fonctionnement dans le paragraphe suivant, va traiter le fichier de mails de webmailer et va recherche la présence de ces lignes. A chaque fois qu'il trouvera ces deux lignes, il lancera une commande wgetGNU Wget 1.10.2, un récupérateur réseau non interactif.
Usage: wget [OPTION]... [URL]...
pour télécharger la page web, la mettra dans une archive tar et fera un petit mail à l'expéditeur avec cette archive en pièce jointe. Une fois le script créé, il suffira d'automatiser son exécution avec cron.

A vos claviers (et boutons de souris du milieu)

Le script étape par étape

Voilà la description du code ligne par ligne :

Nouc commençons par dire quel shell utiliser pour l'exécution du script :

#!/bin/sh

Nous créons un répertoire temporaire dans lequel seront téléchargées les pages web demandées par email :

mkdir /tmp/webmailer

Nous créons le fichier de mail de l'utilisateur webmailer pour que la commande catUsage: cat [OPTION] [FICHIER]...
Concaténer le(s) FICHIER(s), ou de l'ENTRÉE
standard, vers la sortie standard.
ne renvoie pas d'erreur (la commande touchUsage: touch [OPTION]... FICHIER...
Mettre à jour les dates d'accès et de modification
de chaque FICHIER selon la date courante.
Les arguments obligatoires pour les options de formes
longues le sont aussi pour les options de formes courtes.
change les dates d'accès et de modification d'un fichier, et crée le fichier passé en argument s'iil n'existe pas) :

touch /var/mail/webmailer

Voici la commande principale de traitement du fichier de mails. Une première commande grepUsage: grep [OPTION]... PATRON [FICHIER] ...
Recherche du PATRON dans chaque FICHIER ou sur l'entrée standard.
Exemple: grep -i 'hello world» menu.h main.c
permet de nettoyer une bonne partie du fichier. Puis, nous utilisons Stream EDitor (sed) pour manipuler les lignes restantes du fichier à l'aide d'une expression rationnelle (regexp). Celle-ci sélectionne dans ces lignes l'adresse email de l'expéditeur ainsi que le sujet du mail, qui est donc l'adresse de la page web à télécharger. Tout ceci est redirigé dans un fichier /tmp/webmailer.txt.

cat /var/mail/webmailer | grep -e "From:" -e "Subject:" | sed -e "s/.*<\([a-z\.]*@[a-z]*.[a-z]*\)>.*/\1/g" -e "s/Subject: //g" > /tmp/webmailer.txt

Ces quelques variables vont nous servir dans la boucle principale du script, qui va traiter une par une les demandes de renvoi de pages webs contenues dans les mails. La première contiendra l'url de la page web demandée, la seconde l'email à qui envoyer la réponse et la troisièle un flag pour savoir si la ligne suivante à lire est un email (m) ou une url (u). La valeur initiale de cette variable est mise à m car la première ligne du fichier texte sera une adresse email.

webmailer_url=""
webmailer_mail=""
webmailer_ope="m"

La boucle proprement dite lit le fichier /tmp/webmailer.txt ligne par ligne :

  1. A l'étape m, nous nous contentons de stocker l'adresse email dans la variable idoine.
  2. A l'étape u, nous stockons l'adresse de la page a télécharger dans la variable idoine. Ensuite :
    1. Nous nettoyons le répertoire temporaire /tmp/webmailer,
    2. Nous téléchargons la page demandée avec wget et nous plaçons la page dans le répertoire temporaire : l'option -P permet de choisir le répertoire de destination du téléchargement.
    3. Nous faisons une archive tar du contenu du répertoire temporaire /tmp/webmailer : nous n'avons pas besoin de connaître le nom du fichier téléchargé.
    4. Nous envoyons cette archive en pièce jointe d'un mail au destinataire. La commande uuencodeUsage: uuencode [INFILE] REMOTEFILE

      -h, --help display this help and exit
      -m, --base64 use base64 encoding as of RFC1521
      -v, --version output version information and exit
      permet de créer la pièce jointe en la redirigeant à la commande mailUsage: mail [-eIinv] [-a header] [-b bcc-addr] [-c cc-addr] [-s subject]
      to-addr [...] [-- sendmail-options [...]]
      mail [-eIiNnv] -f [name]
      mail [-eIiNnv] [-u user]
      .

while read ligne
do
        if [ $webmailer_ope == "m" ]
        then
                webmailer_mail=$ligne
                webmailer_ope="u"
        else
                webmailer_url=$ligne
                webmailer_ope="m"
                rm /tmp/webmailer/*
                /usr/local/bin/wget -P /tmp/webmailer/ $webmailer_url
                /bin/tar cvf /tmp/webmailer.tar /tmp/webmailer
                /usr/bin/uuencode /tmp/webmailer.tar archive.tar | mail -s "$webmailer_url" "$webmailer_mail"
        fi
done < /tmp/webmailer.txt

On nettoie toutes les saletés qu'on a fait :

rm /tmp/webmailer.tar
rm /tmp/webmailer.txt
rmdir /tmp/webmailer
rm /var/mail/webmailer

Et voilà ! On remarque à l'utilisation l'efficacité de ce code :

Le script en bloc

#!/bin/sh

mkdir /tmp/webmailer

touch /var/mail/webmailer

cat /var/mail/webmailer | grep -e "From:" -e "Subject:" | sed -e "s/.*<\([a-z\.]*@[a-z]*.[a-z]*\)>.*/\1/g" -e "s/Subject: //g" > /tmp/webmailer.txt

webmailer_url=""
webmailer_mail=""
webmailer_ope="m"

while read ligne
do
        if [ $webmailer_ope == "m" ]
        then
                webmailer_mail=$ligne
                webmailer_ope="u"
        else
                webmailer_url=$ligne
                webmailer_ope="m"
                rm /tmp/webmailer/*
                /usr/local/bin/wget -P /tmp/webmailer/ $webmailer_url
                /bin/tar cvf /tmp/webmailer.tar /tmp/webmailer
                /usr/bin/uuencode /tmp/webmailer.tar archive.tar | mail -s "$webmailer_url" "$webmailer_mail"
        fi
done < /tmp/webmailer.txt

rm /tmp/webmailer.tar
rm /tmp/webmailer.txt
rmdir /tmp/webmailer
rm /var/mail/webmailer

Limitations

De nombreuses améliorations sont à apporter à ce script. Certaines sont faciles, d'autres méritent plus de réflexion. En voici une liste (non exhaustive) :

  1. Protection des données. Les mails envoyés entre votre PC Linux/Unix ne sont pas cryptés. Vous pouvez améliorer la sécurité de vos données en cryptant l'archive tar à l'aide d'un mot de passe.
  2. Taille des mails. Vous pouvez ajouter une phase de compression à la création de l'archive pour optimiser la taille des mails envoyés et être plus discret sur le réseau de votre entreprise.
  3. Sécurité de l'utilisation. Vous devriez ajouter une vérification de l'email de l'expéditeur de façon à ce que tout le monde ne puisse pas accéder à ce service (qui ouvre la porte à de multiples exploits : Messieurs les hackers en herbe, n'essayez même pas chez moi, le service ne tourne pas sur mon PC !).
  4. Lisibilité des pages webs. Ce script ne télécharge que la page web brute. Vous pourriez ajouter une phase où il télécharge également les images et la feuille de style, mais il y aura beaucoup de travail d'adatpation.

Documentation sous licence GNU/Free Documentation Licence version 1.2
http://www.gnu.org/copyleft/fdl.html
Christophe Eyquem