I am using the Python code at the bottom of this question to send the contents of a directory to a list of recipients held within a defined file. Within this file individual addresses are separated by ; and are listed within a single string. When submitting the command required all is sent without any recorded issue, but it transpires that the email message is only sent to the first named email address on the list.
Having done some digging it seems as though the main.cf file for Postfix holds a recipient limit, with a default value of 1, which can restrict the recipient volumes. I have tried hashing the whole line out and also increasing the limit to 200, neither of which have any impact.
# dovecot 1.1.1
dovecot_destination_recipient_limit = 200
When you look at the email from the single recipients point of view, all seems well so I have to think it is the Postfix / Dovecot sendmail part which is causing the issue? See example of message output to a file rather than being sent to smtp
Content-Type: multipart/mixed; boundary="===============7543504478351047681=="
MIME-Version: 1.0
Subject: Malware submission
To: xxxxx@gmail.com;xxxxx@hotmail.com
From: me@yu.com
You will not see this in a MIME-aware mail re开发者_如何学Goader.
--===============7543504478351047681==
Content-Type: application/zip
MIME-Version: 1.0
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="sample.zip"
UEsDBAoAAAAAAHGfsT4AAAAAAAAAAAAAAAAGABwAdmlydXMvVVQJAAOVxdJNKJnSTXV4CwABBPUB
AAAEFAAAAFBLAQIeAwoAAAAAAHGfsT4AAAAAAAAAAAAAAAAGABgAAAAAAAAAEADtQQAAAAB2aXJ1
cy9VVAUAA5XF0k11eAsAAQT1AQAABBQAAABQSwUGAAAAAAEAAQBMAAAAQAAAAAAA
--===============7543504478351047681==--
The postfix mail log contains the following
May 17 21:10:41 MacBook-Pro-2 postfix/qmgr[3816]: 3FB902C186A: from=<chris.parker@email.co.uk>, size=1004, nrcpt=1 (queue active)
May 17 21:10:42 MacBook-Pro-2 postfix/smtp[3855]: 3FB902C186A: to=<xxxxo@gmail.com>, relay=gmail-smtp-in.l.google.com[209.85.143.27]:25, delay=1.3, delays=0.01/0.01/0.57/0.75, dsn=2.0.0, status=sent (250 2.0.0 OK 1305662986 k6si1621545wej.25)
May 17 21:10:42 MacBook-Pro-2 postfix/qmgr[3816]: 3FB902C186A: removed
Help please...
#!/usr/bin/env python
"""Send the contents of a directory as a MIME message."""
import os
import sys
import smtplib
# For guessing MIME type based on file name extension
import mimetypes
from optparse import OptionParser
from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
COMMASPACE = ', '
def main():
parser = OptionParser(usage="""\
Send the contents of a directory as a MIME message.
Usage: %prog [options]
Unless the -o option is given, the email is sent by forwarding to your local
SMTP server, which then does the normal delivery process. Your local machine
must be running an SMTP server.
""")
parser.add_option('-d','--directory',
type='string', action='store')
parser.add_option('-o', '--output',
type='string', action='store', metavar='FILE',
help="""Print the composed message to FILE instead of
sending the message to the SMTP server.""")
parser.add_option('-s', '--sender',
type='string', action='store', metavar='SENDER',
help='The value of the From: header (required)')
parser.add_option('-r', '--recipient',
type='string', action='append', metavar='RECIPIENT',
default=[], dest='recipients'),
parser.add_option('-f', '--recipientfile',
type='string', action='store', metavar='RECIPIENT_FILE',
dest='recipient_file', default="",
help='A To: header value (a file containing this)')
opts, args = parser.parse_args()
if not opts.sender or not (opts.recipient_file or opts.recipients):
parser.print_help()
sys.exit(1)
directory = opts.directory
if not directory:
directory = '.'
# Create the enclosing (outer) message
try:
rec_file = open(opts.recipient_file)
recipients = rec_file.read()
rec_file.close()
except IOError:
print "/!\ Bad file. Falling back to recipent -r option"
recipients = COMMASPACE.join(opts.recipients)
outer = MIMEMultipart()
outer['Subject'] = 'Malware submission'
outer['To'] = recipients
outer['From'] = opts.sender
outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'
for filename in os.listdir(directory):
path = os.path.join(directory, filename)
if not os.path.isfile(path):
continue
# Guess the content type based on the file's extension. Encoding
# will be ignored, although we should check for simple things like
# gzip'd or compressed files.
ctype, encoding = mimetypes.guess_type(path)
if ctype is None or encoding is not None:
# No guess could be made, or the file is encoded (compressed), so
# use a generic bag-of-bits type.
ctype = 'application/octet-stream'
maintype, subtype = ctype.split('/', 1)
if maintype == 'text':
fp = open(path)
# Note: we should handle calculating the charset
msg = MIMEText(fp.read(), _subtype=subtype)
fp.close()
elif maintype == 'image':
fp = open(path, 'rb')
msg = MIMEImage(fp.read(), _subtype=subtype)
fp.close()
elif maintype == 'audio':
fp = open(path, 'rb')
msg = MIMEAudio(fp.read(), _subtype=subtype)
fp.close()
else:
fp = open(path, 'rb')
msg = MIMEBase(maintype, subtype)
msg.set_payload(fp.read())
fp.close()
# Encode the payload using Base64
encoders.encode_base64(msg)
# Set the filename parameter
msg.add_header('Content-Disposition', 'attachment', filename=filename)
outer.attach(msg)
# Now send or store the message
composed = outer.as_string()
if opts.output:
fp = open(opts.output, 'w')
fp.write(composed)
fp.close()
else:
#print "Sender : " + opts.sender + ", Recipients : " + recipients #DEBUG :- Check send and recipients are correct
s = smtplib.SMTP('localhost')
s.sendmail(opts.sender, recipients, composed)
s.quit()
if __name__ == '__main__':
main()
Python code to generate email
When you define your message, you should set the To
list using a comma-separated list of recipients:
recipients = 'foo, bar'
outer['To'] = recipients
However when you call sendmail()
, you need to pass it the recipients as a list:
rcpts = [r.strip() for r in recipients.split(',') if r]
s.sendmail(sender, rcpts, composed)
精彩评论