开发者

Email to multiple recipients via Postfix only being received by first address on the list

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)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜