Récepteur d’évènements (SMTP Sink) en code managé
Pour Exchange et le service SMTP de Windows Serveur
Introduction
Dans cet article, nous allons voir comment écrire un récepteur d’évènements qui sera appelé à la réception d’un email.
Ce récepteur agira à la manière d’un « catchall » qui redirigera tous les emails pour le domaine « toto.com » vers l’adresse « david.lopez@bewise.fr ».
Prérequis :
- Visual Studio 2005 ou 2008
- Windows Server 2000, 2003 ou 2008
- Exchange 2000 ou 2003 OU IIS 6 ou 7 avec le service SMTP installé
- Le Framework .NET 2.0
Développement du récepteur
Pour entrer directement dans le vif du sujet, je vous passerai les premières manipulations qui consistent à générer un wrapper managé de l’API d’Exchange, les DLL sont fournies dans les sources de l’article.
Dans Visual Studio (ici la version 2008) nous allons créer un nouveau projet de type Class Library en C# avec le Framework .NET 2.0 et référencer les 2 DLL nécessaires qui sont : Microsoft.Exchange.Transport.EventInterop.dll et Microsoft.Exchange.Transport.EventWrappers.dll.
Nous allons maintenant créer la classe du récepteur, elle devra implémenter l’interface IMailTransportSubmission de l’api d’Exchange.
public class CatchAllSink : IMailTransportSubmission, IEventIsCacheable
L’interface nous demande d’implémenter la méthode suivante :
public void OnMessageSubmission(MailMsg pIMailMsg, IMailTransportNotify pINotify, IntPtr pvNotifyContext)
Dans cette méthode, nous avons l’email en paramètre, il nous reste juste à changer le destinataire du mail.
Message msg = new Message(pIMailMsg);
RecipsAdd newRecips = msg.AllocNewList();
newRecips.AddSMTPRecipient("moncatchall@mondomaine.com");
msg.WriteList(newRecips);
msg = null;
Voilà pour ce qui est du développement en lui-même, nous allons maintenant préparer notre assembly à être déployée.
Préparation du déploiement
Pour cela, nous devons signer l’assembly, allez dans les propriétés du projet (sur le projet, clic droit puis Propriétés)
Puis décorer notre classe par l’attribut GUID, pour générer ce Guid faites Menu Outils, Créer GUID, choix 4.
[Guid("A3CA69D3-AA44-482b-9D19-D887E157532D")]
public class CatchAllSink : IMailTransportSubmission
Puis il nous faut rendre notre assembly « COM Visible » :
Recompilez et c’est tout !
Maintenant que tout est prêt, nous allons voir comment déployer notre récepteur sur le serveur de messagerie.
Déploiement
Afin d’enregistrer notre récepteur au sein d’Exchange, Microsoft nous fourni un script vbs qui s’occupe de tout, voici l’adresse pour le récupérer : http://msdn.microsoft.com/en-us/library/ms528023(EXCHG.10).aspx
Une fois votre projet compilé, vous devez avoir 5 fichiers à déployer :
- Votre assembly Bewise.Exchange.CatchAllSink.dll + Bewise.Exchange.CatchAllSink.tlb
- Les assembly de l’api Exchange (Microsoft.Exchange.Transport.EventInterop.dll et Microsoft.Exchange.Transport.EventWrappers.dll)
- Le script smtpreg.vbs
Première étape, nous allons enregistrer les assembly de l’api Exchange avec regAsm :
"C:\Windows\Microsoft.NET\Framework\v2.0.50727\regAsm.exe" Microsoft.Exchange.Transport.EventInterop.dll /codebase
"C:\Windows\Microsoft.NET\Framework\v2.0.50727\regAsm.exe" Microsoft.Exchange.Transport.EventWrappers.dll /codebase
Ensuite nous enregistrons notre asssembly contenant le récepteur :
"C:\Windows\Microsoft.NET\Framework\v2.0.50727\regAsm.exe" Bewise.Exchange.CatchAllSink.dll /tlb: Bewise.Exchange.CatchAllSink.tlb /codebase
La dernière étape consiste à enregistrer le récepteur au sein d’exchange grâce au script vbs fourni par Microsoft :
cscript smtpreg.vbs /add 1 OnTransportSubmission "Exchange_CatchAll_Sink" Bewise.Exchange.CatchAllSink.CatchAllSink "rcpt to=*@toto.com"
Explication de la commande :
- cscript smtpreg.vbs /add : lancement du script en ajout
- 1 : l’instance sur laquelle on veut déployer, si vous avez plusieurs SMTP virtuels par exemple
- OnTransportSubmission : L’évènement sur lequel le récepteur va réagir
- "Exchange_CatchAll_Sink" : le nom du récepteur (évitez les espaces)
- Bewise.Exchange.CatchAllSink.CatchAllSink : la classe du récepteur qui implémente l’interface IMailTransportSubmission
- "rcpt to=*@toto.com" : indique que seuls les emails contenant une adresse @toto.com déclencheront le récepteur.
Si tout se passe bien, voici ce que vous devez voir à l’écran :
Pour vérifier que le récepteur est bien actif, voici la commande qui liste tous les évènements inscrits :
cscript smtpreg.vbs /enum
RollBack
Pour désactiver le récepteur, il vous suffit de taper la commande suivainte :
cscript smtpreg.vbs /remove 1 OnTransportSubmission "Exchange_CatchAll_Sink"
Explication de la commande :
- cscript smtpreg.vbs /remove : lancement du script en suppression
- 1 : L’instance sur laquelle on va supprimer le récepteur
- OnTransportSubmission : l’évènement concerné
- "Exchange_CatchAll_Sink" : le nom du récepteur que l’on a donné lors de l’ajout
Conclusion
Nous avons vu comment ajouter des fonctionnalités à Exchange ou le service SMTP de Windows Serveur, nous pouvons très bien envisager de concevoir un antispam de la même manière, d’ailleurs certains antispam pour Exchange sont développés de cette façon.