Modifications entre les versions 4 et 5
Version 4 à la date du 2013-03-15 20:06:05
Taille: 6885
Commentaire: coda-filter.py v2
Version 5 à la date du 2013-04-15 15:28:05
Taille: 7005
Commentaire: suppression des changements de destinaires (maintenant correctement géré niveau CODA)
Texte supprimé. Texte ajouté.
Ligne 27: Ligne 27:
# (ANNULÉ car ça ne devrait plus arriver)
Ligne 28: Ligne 29:
# (ANNULÉ car envoi déjà vers les bons destinataires)
Ligne 73: Ligne 75:
if msg['To'] in ['noreply@auf.org']:
    old_to = msg['To']
    email_to_list.remove(old_to)
    email_to_list.append(email_from)
    msg.replace_header('To', email_from)
    msg.add_header('X-Coda-Was-To', old_to)
#if msg['To'] in ['noreply@auf.org']:
# old_to = msg['To']
# email_to_list.remove(old_to)
# email_to_list.append(email_from)
# msg.replace_header('To', email_from)
# msg.add_header('X-Coda-Was-To', old_to)
Ligne 81: Ligne 83:
if email_from not in email_to_list and email_from != 'root@ca.auf.org':
    email_to_list.append(email_from)
    msg.add_header('Cc', email_from)
#if email_from not in email_to_list and email_from != 'root@ca.auf.org':
# email_to_list.append(email_from)
# msg.add_header('Cc', email_from)

Cette page décrit la technique utilisée pour intercepter les courriels sortant de Coda.

Configuration du serveur SMTP sortant dans Coda

  • Ouvrir une session sur Coda-Web utilisant le compte INSTALL.
  • Aller dans le menu "Administration / Transports des messages / Maitre de transport de message"
  • Dans la liste déroulant sélectionner SMTP puis effectuer la recherche (cliquer sur la flèche verte)
  • Dans le champ Hôte saisir "smtp-coda.auf"
  • Dans le nom d'utilisateur saisir "reflet@ca.auf.org" ("reflet@ca.auf.org" est un alias crée préalablement)

  • Enregistrer la configuration (cliquer sur la l'icône "disquette")
  • Terminé, donc fermer la session INSTALLL

Mise en place du serveur SMTP interceptant les courriels de Coda

Mettre en place un serveur Debian standard.

Installer le paquet python, pour le script de filtrage des courriels sortant de Coda.

Créer le fichier /usr/local/sbin/coda-filter.py avec le contenu suivant :

   1 #!/usr/bin/python
   2 # -*- coding: utf-8 -*-
   3 #
   4 # Objectifs :
   5 # 05. si le destinataire est noreply@auf.org, on le remplace par l'émetteur
   6 #     (ANNULÉ car ça ne devrait plus arriver)
   7 # 10. envoyer une copie à l'émetteur, sauf s'il est déjà le destinataire
   8 #     (ANNULÉ car envoi déjà vers les bons destinataires)
   9 # 20. ajouter une en-tête X-Coda pour faciliter les filtrages 
  10 # 30. préfixer le sujet par '[CODA] '
  11 # 40. remplacer l'organisation par AuF (forme longue, au lieu de CODA)
  12 # 50. renommer l'attachement en utilisant le sujet
  13 #       Content-Type: application/pdf; name=attachment.pdf
  14 #       Content-Disposition: inline; filename=attachment.pdf
  15 #
  16 import sys
  17 import email
  18 import smtplib
  19 import re
  20 
  21 # préfixe pour le sujet
  22 SUBJECT_PREFIX = "[CODA] "
  23 # contenu pour l'en-tête X-Coda qui sera ajoutée
  24 X_CODA_VALUE = "Filtre AuF pour Coda v2"
  25 # contenu pour l'en-tête Organisation
  26 ORGANIZATION = "Agence universitaire de la Francophonie"
  27 # masque de repérage du type et numéro de document
  28 DOC_PATTERN = r'^(.*:)?\s*(\S+)\s*/\s*(\d+)\s*$'
  29 # format du nouveau nom de document (à partir du type et numéro)
  30 DOC_FORMAT = 'CODA-%s-%08d.pdf'
  31 
  32 # codes de sortie venant de <sysexits.h>
  33 EX_TEMPFAIL = 75
  34 EX_UNAVAILABLE = 69
  35 
  36 # on récupère l'expéditeur et le(s) destinataire(s) en paramètres
  37 #email_from = 'jca.test@auf.org'
  38 email_from = sys.argv[1]
  39 email_to_list = sys.argv[2:]
  40 
  41 # on tente de récupérer le message arrivant sur l'entrée standard (pipe)
  42 try:
  43     msg = email.message_from_file(sys.stdin)
  44 # en cas d'échec on demande à Postfix de considérer que c'est temporaire
  45 except Exception, err:
  46     print "Error: %s" % err
  47     sys.exit(EX_TEMPFAIL)
  48 
  49 #--------------------------------------------------------------------------
  50 # TRAITEMENTS
  51 #--------------------------------------------------------------------------
  52 
  53 # 05. si le destinataire est noreply@auf.org, on le remplace par l'émetteur
  54 #if msg['To'] in ['noreply@auf.org']:
  55 #    old_to = msg['To']
  56 #    email_to_list.remove(old_to)
  57 #    email_to_list.append(email_from)
  58 #    msg.replace_header('To', email_from)
  59 #    msg.add_header('X-Coda-Was-To', old_to)
  60 
  61 # 10. on ajoute l'émetteur aux destinataires, sauf s'il est déjà le destinataire
  62 #if email_from not in email_to_list and email_from != 'root@ca.auf.org':
  63 #    email_to_list.append(email_from)
  64 #    msg.add_header('Cc', email_from)
  65 
  66 # 20. on ajoute une en-tête pour aider aux filtrages
  67 msg.add_header('X-Coda', X_CODA_VALUE)
  68 
  69 # 30. on préfixe le sujet actuel par '[CODA] '
  70 subject = msg['Subject']
  71 msg.replace_header('Subject', SUBJECT_PREFIX + subject)
  72 
  73 # 40. on remplace l'organisation par l'AuF
  74 del msg['ORGANISATON'] # non, ce n'est pas une faute de frappe…
  75 msg.add_header('Organization', ORGANIZATION)
  76 
  77 # 50. on renomme l'attachement
  78 
  79 # construction du nouveau nom de fichier
  80 # on tente de repérer le type et numéro de document
  81 try:
  82     m = re.match(DOC_PATTERN, subject)
  83     prefix, com_type, com_num = m.groups()
  84     new_filename = DOC_FORMAT % (com_type, int(com_num))
  85 # en cas d'échec on ignore le problème
  86 except Exception, err:
  87     print "Error: %s" % err
  88     new_filename = 'document-coda.pdf'
  89 
  90 # parcours des différentes parties du courriel
  91 for part in msg.walk():
  92     if part.get_content_type() != 'application/pdf':
  93         continue
  94     # adaptation du nom de fichier dans le Content-Type
  95     try:
  96         raw_param = part.get_param('name')
  97         param = email.utils.collapse_rfc2231_value(raw_param)
  98         if param == 'attachment.pdf':
  99             part.set_param('name', new_filename)
 100     except:
 101         pass
 102     # adaptation du nom de fichier dans le Content-Disposition
 103     try:
 104         raw_param = part.get_param('filename', header='Content-Disposition')
 105         param = email.utils.collapse_rfc2231_value(raw_param)
 106         if param == 'attachment.pdf':
 107             part.set_param('filename', new_filename, header='Content-Disposition')
 108     except:
 109         pass
 110 
 111 #--------------------------------------------------------------------------
 112 
 113 # on se connecte à Postfix via le port de retour de filtrage
 114 client = smtplib.SMTP('localhost', 10026)
 115 #client.set_debuglevel(1)
 116 
 117 # on tente d'envoyer le courriel modifié
 118 try:
 119     client.sendmail(email_from, email_to_list, msg.as_string())
 120 # en cas d'échec on demande à Postfix de considérer que c'est temporaire
 121 except Exception, err:
 122     print "Error: %s" % err
 123     sys.exit(EX_TEMPFAIL)
 124 
 125 # on termine proprement
 126 client.quit()
 127 sys.exit(0)

Rendre ce script exécutable :

chmod +x /usr/local/sbin/coda-filter.py

Installer Postfix en mode Internet avec smarthost, pour qu'il puisse recevoir les courriels de Coda via SMTP, les traiter, puis les renvoyer au SMTP sortant local.

Ajouter les lignes suivantes à /etc/postfix/master.cf :

# accès au filtre pour Coda
codafilter  unix  -     n       n       -       10      pipe
  flags=Rq user=nobody null_sender=
  argv=/usr/local/sbin/coda-filter.py ${sender} ${recipient}

# accès pour le retour du filtre pour Coda (non filtré)
localhost:10026 inet n  -       n       -       10      smtpd
  -o content_filter=
  -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters,no_address_mappings
  -o smtpd_helo_restrictions=
  -o smtpd_client_restrictions=
  -o smtpd_sender_restrictions=
  -o smtpd_recipient_restrictions=permit_mynetworks,reject
  -o mynetworks=127.0.0.0/8
  -o smtpd_authorized_xforward_hosts=127.0.0.0/8

Éditer le fichier /etc/postfix/main.cf pour s'assurer qu'il contienne les valeurs suivantes :

myhostname = smtp-coda.auf
mydestination = localhost
relayhost = smtp.ca.auf.org
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 10.36.0.240/28
content_filter = codafilter:dummy

Relancer le service Postfix :

service postfix restart

Projet/Reflets/InterceptionDesCourriels (dernière édition le 2013-10-01 03:32:10 par JeanChristopheAndré)