Modifications entre les versions 4 et 6 (s'étendant sur 2 versions)
Version 4 à la date du 2013-03-15 20:06:05
Taille: 6885
Commentaire: coda-filter.py v2
Version 6 à la date du 2013-08-01 05:10:18
Taille: 7176
Commentaire: décodage du sujet au besoin (RFC-2047)
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 37: Ligne 39:
from email.header import decode_header
Ligne 73: Ligne 76:
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 84:
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)
Ligne 90: Ligne 93:
try:
    parts = decode_header(subject)
    subject = u' '.join([unicode(s, e or 'ascii') for s,e in parts])
except:
    pass

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