Last active
October 21, 2023 03:44
-
-
Save DamnedFacts/9817b6e400a66961725b49099cc6f9da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import argparse | |
import smtplib | |
import ssl | |
import dns.resolver # Required for DNS lookup | |
from email.mime.text import MIMEText | |
def get_mx_record(domain): | |
""" | |
Retrieve the highest priority MX record for the specified domain. | |
""" | |
try: | |
records = dns.resolver.resolve(domain, 'MX') | |
except (dns.resolver.NoAnswer, dns.resolver.NXDOMAIN): | |
print(f"No MX record found for domain {domain}") | |
return None | |
records = sorted(records, key=lambda record: record.preference) | |
return str(records[0].exchange).rstrip('.') | |
def test_mail( | |
smtp_server, | |
smtp_port, | |
smtp_user, | |
smtp_password, | |
from_email, | |
to_email, | |
subject="Test email", | |
body="This is a test email", | |
use_tls=True, | |
certfile=None, | |
keyfile=None, | |
direct_send=False # Flag for direct sending | |
): | |
""" | |
Send a test email. If direct_send is enabled, it bypasses the specified SMTP server | |
and sends the email directly to the recipient's domain SMTP server. | |
""" | |
if direct_send: | |
domain = to_email.split('@')[-1] | |
mx_record = get_mx_record(domain) | |
if mx_record is None: | |
return # Exit if we couldn't find an MX record | |
smtp_server = mx_record | |
# Setup the email message | |
msg = MIMEText(body) | |
msg["Subject"] = subject | |
msg["From"] = from_email | |
msg["To"] = to_email | |
try: | |
context = ssl.create_default_context() | |
if certfile and keyfile: | |
context.load_cert_chain(certfile=certfile, keyfile=keyfile) | |
with smtplib.SMTP(smtp_server, smtp_port) as server: | |
server.ehlo() # It's good practice to identify ourselves to the SMTP server. | |
# If we're not doing direct send or if we're using TLS, start the TLS session | |
if use_tls or not direct_send: | |
server.starttls(context=context) | |
server.ehlo() # Re-identify ourselves over the encrypted connection. | |
if smtp_user and smtp_password and not direct_send: | |
server.login(smtp_user, smtp_password) | |
server.sendmail(from_email, [to_email], msg.as_string()) | |
print("Email sent successfully!") | |
except Exception as e: | |
print(f"Failed to send email. Error: {e}") | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser(description="Send a test email.") | |
parser.add_argument("from_email", help="The email address to send from.") | |
parser.add_argument("to_email", help="The email address to send to.") | |
parser.add_argument( | |
"--smtp_server", help="The SMTP server address.", default="") | |
parser.add_argument("--smtp_port", type=int, | |
help="The SMTP server port.", default=25) | |
parser.add_argument( | |
"--smtp_user", help="The SMTP server username.", default="") | |
parser.add_argument("--smtp_password", | |
help="The SMTP server password.", default="") | |
parser.add_argument("--subject", help="Email subject.", | |
default="Test email") | |
parser.add_argument("--body", help="Email body.", | |
default="This is a test email.") | |
parser.add_argument( | |
"--use_tls", help="Use TLS for the SMTP connection.", action="store_true") | |
parser.add_argument( | |
"--certfile", help="Path to the client certificate file.", default="") | |
parser.add_argument( | |
"--keyfile", help="Path to the client key file.", default="") | |
parser.add_argument( | |
"--direct_send", help="Send email directly to the recipient's SMTP server based on MX lookup.", action="store_true") | |
args = parser.parse_args() | |
# If direct_send is active, use_tls is adapted to ensure compatibility with the recipient's server. | |
use_tls = args.use_tls if not args.direct_send else True | |
test_mail( | |
args.smtp_server, | |
args.smtp_port, | |
args.smtp_user, | |
args.smtp_password, | |
args.from_email, | |
args.to_email, | |
args.subject, | |
args.body, | |
use_tls, | |
args.certfile, | |
args.keyfile, | |
args.direct_send | |
) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment