Aller au menu - Aller au contenu

Icône TP : zSpam, le filtre anti-spam du zéro

Avatar
Mise à jour : 11/03/2012
Difficulté : Intermédiaire Intermédiaire Creative Commons BY-NC-ND
515 visites depuis 7 jours, dont 0 sur ce chapitre classé 220/786
Avant de s'attaquer à la consultation de ses e-mails via le protocole IMAP, je vous propose un petit exercice qui va nous permettre de retravailler avec le module Net::POP3.

L'objectif étant bien évidemment de vous faire manipuler ce que nous venons de voir dans le chapitre précédent !
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

L'énoncé

Le but de ce TP est de créer une sorte de filtre anti-spams ultra simple.

Notre zSpam fonctionne suivant les étapes suivantes :
  • le programme demande à l'utilisateur de saisir une adresse e-mail suspecte ;
  • le programme se connecte au serveur et supprime tous les e-mails provenant de l'adresse électronique saisie lors l'étape précédente.

Toutes les fonctions à utiliser ont été décrites dans le chapitre précédent ! Si vous avez des doutes, n'hésitez pas à y jeter un coup d'oeil !

Une solution

Je vous fais part de ma solution. Bien évidemment, il ne s'agit pas de LA solution !

Secret (cliquez pour afficher)
Code : Perl
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/perl -w

use strict;
use Net::POP3;

my $mail;

#Saisie de l'adresse
print "Saisir l'adresse électronique qui vous spamme : ";
$mail = <STDIN>;
chop($mail);

#Connexion au serveur
my $pop = Net::POP3->new('pop.wanadoo.fr') or die 'Impossible de se connecter au serveur : '.$!;

#Connexion au compte
$pop->login('*****@wanadoo.fr', '*****') or die 'Erreur d\'identification !';

#Récupération de la liste des messages
my $index = $pop->list() or die 'Impossible de lister les messages !';

#On boucle sur la liste des e-mails
foreach my $msgnum (keys %$index) {
        my $msg = $pop->top($msgnum) or die 'Impossible de récupérer le message n°'.$msgnum.' !';
        my $tmp = sprintf("@$msg");

        #On cherche l'expéditeur dans les en-têtes des mails
        if($tmp =~ m/.*From: .*<$mail>.*/) {
                #On supprime le message
                if($pop->delete($msgnum)) {
                        print 'Message n°'.$msgnum." supprimé avec succès\n";
                }
                else {
                        print 'Impossible de supprimer le message n°'.$msgnum."\n";
                }
        }
}

#On quitte le serveur pour que les modifications s'effectuent
$pop->quit() or die 'Un problème est survenu avec la méthode quit() !';


Quelques explications


Le contenu de la boucle foreach n'est peut-être pas évident pour tout le monde. C'est pourquoi je vous propose quelques explications.

Étape 1 : récupération de l'en-tête


La première étape consiste à récupérer l'en-tête de notre message puisque c'est dans cette en-tête que l'on trouve les différentes informations sur l'expéditeur de l'e-mail.

Comme nous l'avons vu au cours du chapitre précédent, c'est la fonction top() qui nous permet de récupérer l'en-tête. Dans notre cas, nous la stockons dans la variable du nom de $msg.

Code : Perl
1
$msg = $pop->top($msgnum);


Étape 2a : comparaison de l'en-tête


La seconde étape consiste à vérifier l'expéditeur du message dont nous venons de récupérer l'en-tête. La variable $msg étant une référence à un tableau, nous ne pouvons pas l'utiliser directement dans une expression rationnelle, même sous la forme @$msg.

Vous pouvez toujours essayer, mais voici ce que risque de vous pondre votre programme lors de son exécution :

Code : Console
Applying pattern match (m//) to @array will act on scalar(@array)


Afin de pouvoir effectuer la comparaison, vous pouvez utiliser ma petite astuce qui consiste à écrire la valeur de référence dans une variable temporaire (ici $tmp) grâce à la fonction sprintf().

Voici la fameuse ligne dans mon programme :

Code : Perl
1
my $tmp = sprintf("@$msg");


Étape 2b : comparaison de l'en-tête (suite)


Nous pouvons maintenant chercher l'expéditeur dans la valeur de la variable $tmp. Pour cela, nous utilisons une expression rationnelle.

A noter que l'expéditeur suit le mot clef From: et peut se trouver sous plusieurs formes :

Code : Autre
1
2
From: <*****@wanadoo.fr>
From: Wapiti 89 <*****@wanadoo.fr>


Voici donc ce que donne la recherche dans mon programme :

Code : Perl
1
$tmp =~ m/.*From: .*<$mail>.*/


Étape 3 : suppression des e-mails


Lorsque l'expéditeur est trouvé dans l'en-tête, nous supprimons l'e-mail grâce à la fonction delete().

Tout comme moi, vous pouvez imbriquer tout ça dans un if afin de vérifier que la suppression a bien eu lieu, mais ce n'est en aucun cas une obligation.

Code : Perl
1
2
3
4
5
6
if($pop->delete($msgnum)) {
         print 'Message n°'.$msgnum." supprimé avec succès\n";
}
else {
         print 'Impossible de supprimer le message n°'.$msgnum."\n";
}


Si vous avez des problèmes, des doutes ou des questions, je vous encourage à les poser sur le forum du site !

Quelques améliorations possibles

Pour améliorer ce petit programme, vous pouvez par exemple :
  • vérifier que l'adresse électronique saisie est correcte à l'aide d'une expression rationnelle ;
  • permettre à l'utilisateur de régler l'anti-spam sur une adresse e-mail, un sujet ou encore un mot clef (dans le corps ou le sujet du message) ;
  • permettre à l'utilisateur de confirmer ou non la suppression d'un e-mail en l'affichant à l'écran.
Maintenant que vous êtes plus familier avec le protocole POP3 et le module Net::POP3, je vous propose de s'attaquer au protocole IMAP grâce au module Net::IMAP::Simple.
Chapitre précédent Sommaire Chapitre suivant

Partager

Il n'y a pas encore de commentaire pour ce tuto.