J'ai voulu écrire ce code suite à la limitation, à mon boulot, de l'envoi de mail via SMTP : c'est restreint aux adresses internes depuis quelques mois. Pour envoyer des mails à l'extérieur, on doit passer par MAPI (et donc Outlook).
C'est un premier jet, qui fonctionne, mais est très limité (un seul destinataire, le corps du message est le source du mail d'origine)
Pour arriver à mes fins, j'ai utilisé un serveur smtp en python et extensible : http://www.hare.demon.co.uk/pysmtp.html
Pour le code de création du message et de l'envoi, j'ai consulté la doc des objets OLE idoines sur MSDN : http://msdn.microsoft.com/fr-fr/library/ms268731(VS.80).aspx
# (c)2009 David SPORN
#
# A brain-dead Python SMTP to MAPI relay server based on the smtps, smtplib and mapi
# packages.
#
# DISCLAIMER
# You are free to use this code in any way you like, subject to the
# Python disclaimers & copyrights. I make no representations about the
# suitability of this software for any purpose. It is provided "AS-IS"
# without warranty of any kind, either express or implied. So there.
#
# Sources
# http://code.activestate.com/recipes/149461/
# smtps.py
"""
smtp2mapi.py -- A very simple & dumb Python SMTP to MAPI relay server. It uses
smtps for the server side and MAPI for the client side. This is
intended for use as a proxy to an Exchange server that is restricted to MAPI
(e.g. for 'security purpose').
This blocks, waiting for RFC821 messages from clients on the given
port. When a complete SMTP message is received, it connect to the
Exchange server using the Outlook OLE component, convert the
message and send it. Obviously, Outlook must be present.
All processing is single threaded. It generally handles errors
badly. It fails especially badly if DNS or the resolved mail host
hangs. DNS or mailhost failures are not propagated back to the client,
which is bad news.
The mail address 'shutdown@shutdown.now' is interpreted
specially. This gets around a Python 1.5/Windows/WINSOCK bug that
prevents this script from being interrupted.
"""
import sys, smtps, string, smtplib, rfc822, StringIO, win32com.client.dynamic, re
#Default Mapi profile
DEFAULT_MAPI_PROFILE = "Outlook"
#
#
# This extends the smtps.SMTPServerInterface and specializes it to
# proxy requests onwards. It uses DNS to resolve each RCPT TO:
# address, then uses smtplib to forward the client mail on the
# resolved mailhost.
#
class SMTPService(smtps.SMTPServerInterface):
def initMapi(self):
self.outlook = win32com.client.dynamic.Dispatch("Outlook.Application")
self.mapi = self.outlook.GetNamespace("MAPI")
self.mapi.Logon(DEFAULT_MAPI_PROFILE)
def quitMapi(self):
self.mapi.Logoff()
self.mapi = None
def __init__(self):
self.savedTo = []
self.savedMailFrom = ''
self.shutdown = 0
self.initMapi()
def mailFrom(self, args):
# Stash who its from for later
self.savedMailFrom = smtps.stripAddress(args)
def rcptTo(self, args):
# Stashes multiple RCPT TO: addresses
self.savedTo.append(args)
def data(self, args):
data = args
sys.stdout.write('Creating message...\n\r')
subject=self.getSubject(args)
message = self.outlook.CreateItem(0)
message.Body = data
message.Subject = subject
for addressee in self.savedTo:
toHost, toFull = smtps.splitTo(addressee)
# Treat this TO address speciallt. All because of a
# WINSOCK bug!
if toFull == 'shutdown@shutdown.now':
self.shutdown = 1
return
sys.stdout.write('Adding recipient ' + toFull + '...')
message.To = toFull
sys.stdout.write('Sending message...\n\r')
message.Send()
self.savedTo = []
def quit(self, args):
if self.shutdown:
print 'Shutdown at user request\n\r'
sys.exit(0)
def frobData(self, data):
hend = string.find(data, '\n\r')
if hend != -1:
rv = data[:hend]
else:
rv = data[:]
rv = rv + 'X-Sporniket: Python SMTP to MAPI Relay'
rv = rv + data[hend:]
return rv
def getSubject(self, data):
hstart = string.find(data, 'Subject: ')
if hstart != -1:
rv = data[hstart+9:]
else:
return ''
hend = string.find(rv, '\n\r')
if hend != -1:
rv = rv[:hend]
else:
rv = rv[:]
return rv
def Usage():
print """Usage pyspy.py port
Where:
port = Client SMTP Port number (ie 25)"""
sys.exit(1)
if __name__ == '__main__':
if len(sys.argv) != 2:
Usage()
port = int(sys.argv[1])
service = SMTPService()
server = smtps.SMTPServer(port)
print 'Python SMTP to MAPI Relay Ready. (c)2009 David SPORN\n\r'
server.serve(service)
# 2eme essais
Posté par David Sporn (site web personnel) . Évalué à 1.
# 3eme version
Posté par David Sporn (site web personnel) . Évalué à 1.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.