aboutsummaryrefslogtreecommitdiff
path: root/bugzilla/usr/sbin/sendmail
blob: 69e5816ba9d5b8ea74ce69da8c52b43d0a4d75e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#!/usr/bin/python

import os
import re
import sys
import email
import boto3
import socket
import argparse
from botocore.exceptions import NoRegionError

# These are all the sendmail options we don't support but have to accept so we
# can ignore them without messing up the command line.
#
# Format is (argument, takes parameters)
IGNORED = (
    ("-4", False),  ("-6", False),  ("-au", True),  ("-ap", True),
    ("-am", True),  ("-ba", False), ("-bd", False), ("-bi", False),
    ("-bm", False), ("-bp", False), ("-bs", False), ("-bt", False),
    ("-bv", False), ("-bz", False), ("-C", True),   ("-d", True),
    ("-E", False),  ("-h", True),   ("-m", False),  ("-M", True),
    ("-N", True),   ("-n", False),  ("-oA", True),  ("-oc", False),
    ("-od", True),  ("-oD", False), ("-oe", False), ("-oF", True),
    ("-of", False), ("-og", True),  ("-oH", True),  ("-oi", False),
    ("-oL", True),  ("-om", False), ("-oo", False), ("-oQ", True),
    ("-or", True),  ("-oS", True),  ("-os", False), ("-oT", True),
    ("-ot", False), ("-ou", True),  ("-q", True),   ("-R", True),
    ("-v", False),  ("-F", True),   ("-t", True),
)

# A rough approximation of an email address but should be good enough to pick
# emails out of a command line
SORTA_EMAIL = re.compile("\S+@\S+\.\S+")

if os.path.exists("/etc/mailname"):
    with open("/etc/mailname", "r") as fp:
        MAIL_DOMAIN = fp.read().strip()
else:
    MAIL_DOMAIN = socket.getfqdn()

# Configuration comes from the environment or metadata service
try:
    client = boto3.client("ses")
except NoRegionError:
    # TODO: Handle this better
    boto3.setup_default_session(
        aws_access_key_id="AKIAJSJZAZDLGRZVT6ZQ",
        aws_secret_access_key="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",
        region_name="us-west-2")
    client = boto3.client("ses")



def parse_args():
    parser = argparse.ArgumentParser(add_help=False)
    parser.add_argument("-V", action="store_true", dest="display_version")
    parser.add_argument("-f", nargs=1, dest="sender_addr")
    parser.add_argument("-r", nargs=1, dest="sender_addr")

    for arg, nargs in IGNORED:
        parser.add_argument(arg, nargs="?" if nargs else None)

    opts, args = parser.parse_known_args()
    addresses = [a for a in args if SORTA_EMAIL.match(a)]

    return opts, addresses


def main():
    opts, addresses = parse_args()

    if opts.display_version:
        print("SES raw mail sender (definitely not sendmail)")
        sys.exit(0)

    try:
        sender = opts.sender_addr[0]
    except (IndexError, TypeError):
        sender = None

    msg = email.message_from_string(sys.stdin.read().encode("us-ascii"))

    # Fix up cron emails
    if 'Cron Daemon' in msg.get("From"):
        msg.replace_header("From", "cron-no-reply@{}".format(MAIL_DOMAIN))

    ses_args = {"RawMessage": {"Data": msg.as_string()}}

    if sender and not SORTA_EMAIL.match(sender):
        raise Exception("Sender email does not look like an email")

    if sender:
        ses_args["Source"] = sender

    if addresses:
        ses_args["Destinations"] = addresses

    client.send_raw_email(**ses_args)


if __name__ == "__main__":
    try:
        main()
        sys.exit(0)
    except Exception as e:
        print("Error during sending:")
        print(e)
        sys.exit(1)