summaryrefslogtreecommitdiff
path: root/scripts/profiling/spam.py
blob: 119d8496782b6f9fb590bf69fcf9e6d1906cdbe0 (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/python

# Send a lot of messages in parallel.


import string
import smtplib
import threading
import logging
import dns.resolver

from argparse import ArgumentParser


SMTP_DEFAULT_PORT = 465
NUMBER_OF_THREADS = 20


logger = logging.getLogger(__name__)
LOG_FORMAT = '%(asctime)s %(message)s'


def _send_email(server, port, subject, to_addr, from_addr, body_text):
    """
    Send an email
    """
    body = string.join((
            "From: %s" % from_addr,
            "To: %s" % to_addr,
            "Subject: %s" % subject,
            "",
            body_text
            ), "\r\n")
    logger.debug("setting up smtp...")
    smtp = smtplib.SMTP_SSL(server, port)
    logger.info(
        "sending message: (%s, %s, %s, %i)"
        % (from_addr, to_addr, server, port))
    smtp.sendmail(from_addr, [to_addr], body)
    smtp.quit()


def _parse_args():
    parser = ArgumentParser()
    parser.add_argument(
        'target_address',
        help='The target email address to spam')
    parser.add_argument(
        'number_of_messages', type=int,
        help='The amount of messages email address to spam')
    parser.add_argument(
        '--server', '-s',
        help='The SMTP server to use')
    parser.add_argument(
        '--port', '-p', default=SMTP_DEFAULT_PORT,
        help='The SMTP port to use')
    parser.add_argument(
        '--threads', '-t', default=NUMBER_OF_THREADS,
        help='The maximum number of parallel threads to launch')
    parser.add_argument(
        '--debug', '-d', action='store_true',
        help='Print debug messages')
    return parser.parse_args()


class EmailSenderThread(threading.Thread):

    def __init__(self, server, port, subject, to_addr, from_addr, body_text,
                 finished_fun):
        threading.Thread.__init__(self)
        logger.debug("initilizing thread...")
        self._server = server
        self._port = port
        self._subject = subject
        self._to_addr = to_addr
        self._from_addr = from_addr
        self._body_text = body_text
        self._finished_fun = finished_fun

    def run(self):
        logger.debug("running thread...")
        try:
            _send_email(
                self._server, self._port, self._subject, self._to_addr,
                self._from_addr, self._body_text)
        except Exception as e:
            logger.error(e)
        finally:
            self._finished_fun()


def _launch_email_thread(server, port, subject, to_addr, from_addr, body_text,
                         finished_fun):
    logger.debug("will launch email thread...")
    thread = EmailSenderThread(
        server, port, subject, to_addr, from_addr, body_text, finished_fun)
    thread.start()
    return thread


class FinishedThreads(object):

    def __init__(self):
        self._finished = 0
        self._lock = threading.Lock()

    def signal(self):
        with self._lock:
            self._finished = self._finished + 1
            logger.info('number of messages sent: %d.' % self._finished)


def _send_messages(args):
    server = args.server
    port = args.port
    subject = "Message from Soledad script"
    to_addr = args.target_address
    from_addr = args.target_address
    body_text = "Test message"

    # configure log level
    if args.debug:
        level = logging.DEBUG
    else:
        level = logging.INFO
    logging.basicConfig(format=LOG_FORMAT, level=level)

    # get MX configuration
    if not server:
        logger.info("Resolving MX server...")
        _, domain = to_addr.split("@", 1)
        result = dns.resolver.query(domain, "MX")
        server = result[0].exchange.to_text()
        logger.info("MX server is: %s" % server)

    semaphore = threading.Semaphore(args.threads)
    threads = []
    finished_threads = FinishedThreads()

    def _finished_fun():
        semaphore.release()
        finished_threads.signal()

    for i in xrange(args.number_of_messages):
        semaphore.acquire()
        threads.append(
            _launch_email_thread(
               server, port, subject, to_addr, from_addr, body_text,
               _finished_fun))

    for t in threads:
        t.join()


if __name__ == "__main__":
    args = _parse_args()
    _send_messages(args)