92 lines
3.3 KiB
Python
92 lines
3.3 KiB
Python
import smtplib
|
|
import imaplib
|
|
import time
|
|
import ssl
|
|
import argparse
|
|
import uuid
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('host', type = str)
|
|
parser.add_argument('--mailfrom', default = 'foo@example.com')
|
|
parser.add_argument('--rcptto', default = 'awesome@vacu.store')
|
|
parser.add_argument('--submission', default = False, action='store_true')
|
|
parser.add_argument('--smtp-starttls', default = None, action='store_true')
|
|
parser.add_argument('--imap-insecure', default = False, action = 'store_true')
|
|
parser.add_argument('--username')
|
|
parser.add_argument('--password')
|
|
parser.add_argument('--expect-recipient-refused',
|
|
dest = 'expect',
|
|
action = 'store_const',
|
|
const = 'recipient_refused',
|
|
default = 'received'
|
|
)
|
|
parser.add_argument('--expect-sent', dest = 'expect', action = 'store_const', const = 'sent')
|
|
parser.add_argument('--expect-imap-error', dest = 'expect', action = 'store_const', const = 'imap_error')
|
|
|
|
args = parser.parse_args()
|
|
|
|
print(f"got args {args!r}")
|
|
|
|
# smtp_starttls = args.smtp_starttls
|
|
# if smtp_starttls is None:
|
|
# smtp_starttls = args.submission
|
|
|
|
username = args.username
|
|
password = args.password
|
|
if password is None:
|
|
password = username
|
|
|
|
if (username is None or password is None) and (args.submission or args.expect == 'received'):
|
|
assert False, "Bad args"
|
|
|
|
msg_magic = str(uuid.uuid4())
|
|
|
|
def mk_ctx():
|
|
ctx = ssl.create_default_context()
|
|
ctx.check_hostname = False
|
|
ctx.verify_mode = ssl.CERT_NONE
|
|
return ctx
|
|
|
|
try:
|
|
smtp = None
|
|
if args.submission:
|
|
smtp = smtplib.SMTP_SSL(args.host, port=465, context = mk_ctx())
|
|
else:
|
|
smtp = smtplib.SMTP(args.host, port=25)
|
|
smtp.ehlo()
|
|
if args.smtp_starttls:
|
|
smtp.starttls(context = mk_ctx())
|
|
smtp.ehlo()
|
|
if args.submission:
|
|
smtp.login(username, password)
|
|
smtp.sendmail(args.mailfrom, args.rcptto, 'Subject: Test\n\n' + msg_magic)
|
|
smtp.close()
|
|
except smtplib.SMTPRecipientsRefused:
|
|
assert args.expect == 'recipient_refused', "Server rejected message as recipients refused"
|
|
else:
|
|
assert (not args.expect == 'recipient_refused'), "Server was supposed to reject this message, but it didn't"
|
|
|
|
if args.expect == 'received' or args.expect == 'imap_error':
|
|
time.sleep(3)
|
|
try:
|
|
with imaplib.IMAP4_SSL(args.host, ssl_context = mk_ctx()) as imap:
|
|
# if not args.imap_insecure:
|
|
# imap.starttls(ssl_context = mk_ctx())
|
|
imap.login(username, password)
|
|
imap.select()
|
|
status, refs = imap.search(None, 'ALL')
|
|
assert status == 'OK', f"imap SEARCH command failed {status!r} {refs!r}"
|
|
any_okay = False
|
|
for ref in refs[0].split(b' '):
|
|
print(f"fetching {ref!r}")
|
|
status, msgs = imap.fetch(ref, 'BODY[TEXT]')
|
|
assert status == 'OK', f"imap FETCH command failed {status!r} {refs!r}"
|
|
print(f"got msgs {msgs!r}")
|
|
found_msg = msgs[0][1].strip()
|
|
print(f"Found {found_msg}, looking for {msg_magic}")
|
|
any_okay = any_okay or found_msg == msg_magic.encode('ascii')
|
|
assert any_okay, "Could not find the message in the mailbox"
|
|
except imaplib.IMAP4.error as e:
|
|
assert args.expect == 'imap_error', f"IMAP error: {e}"
|
|
else:
|
|
assert not args.expect == 'imap_error', "Expected an IMAP error, but didn't get one" |