1 | #!/usr/bin/env python
|
---|
2 | # Rick van der Zwet
|
---|
3 | # TODO: May need to implement some RFC checkers
|
---|
4 | #
|
---|
5 | #
|
---|
6 | import sys,smtplib,re,socket,random,string,os,getopt
|
---|
7 | import mimetypes
|
---|
8 | import time
|
---|
9 | from time import gmtime,strftime
|
---|
10 | from email.MIMEMultipart import MIMEMultipart
|
---|
11 | from email.MIMEBase import MIMEBase
|
---|
12 | from email.MIMEText import MIMEText
|
---|
13 | from email.Utils import COMMASPACE, formatdate
|
---|
14 | from email import Encoders
|
---|
15 |
|
---|
16 | __svnversion__ = "$Id: foomail.py 633 2008-06-12 19:29:56Z rick $"
|
---|
17 | __author__ = "Rick van der Zwet"
|
---|
18 |
|
---|
19 |
|
---|
20 | def usage():
|
---|
21 | print "usage %s -f <from> -r <recipient> -s <server> [--spam]" % sys.argv[0]
|
---|
22 | print "[--virus] [--file <size in kB>] [--message <file>]"
|
---|
23 | print "[--subject <string>] [--to <string>] [--cc <string>]"
|
---|
24 | print "[--force]"
|
---|
25 |
|
---|
26 | default_domain = 'example.com'
|
---|
27 | def emailparse(email):
|
---|
28 | if re.compile('.*@.*').match(email):
|
---|
29 | return(email)
|
---|
30 | else:
|
---|
31 | return(email + '@' + default_domain)
|
---|
32 |
|
---|
33 | try:
|
---|
34 | opts, args = getopt.getopt(sys.argv[1:], "f:r:s:dp:t",
|
---|
35 | ["from=","force","recipient=","server=","spam","port=","virus","files=","dry-run","message=","subject=","to=","trace","cc="])
|
---|
36 | except getopt.GetoptError:
|
---|
37 | usage()
|
---|
38 | sys.exit(128)
|
---|
39 |
|
---|
40 | spam = False
|
---|
41 | virus = False
|
---|
42 | server = False
|
---|
43 | port = "25"
|
---|
44 | trace = False
|
---|
45 | recipient = False
|
---|
46 | sender = False
|
---|
47 | files = False
|
---|
48 | force = False
|
---|
49 | dry = False
|
---|
50 | message = False
|
---|
51 | subject = False
|
---|
52 | to = False
|
---|
53 | cc = False
|
---|
54 |
|
---|
55 | tests = ""
|
---|
56 |
|
---|
57 | for o, a in opts:
|
---|
58 | if o in ("-f","--from"):
|
---|
59 | sender_raw = a
|
---|
60 | sender = emailparse(a)
|
---|
61 | elif o in ( "-r", "--recipient"):
|
---|
62 | recipient_raw = a
|
---|
63 | recipient = emailparse(a)
|
---|
64 | elif o in ("-s", "--server"):
|
---|
65 | server = a
|
---|
66 | elif o in ("-p", "--port"):
|
---|
67 | port = a
|
---|
68 | elif o == "--trace":
|
---|
69 | trace = True
|
---|
70 | elif o == "--spam":
|
---|
71 | spam = True
|
---|
72 | tests += " Spam"
|
---|
73 | elif o == "--virus":
|
---|
74 | virus = True
|
---|
75 | tests += " Virus"
|
---|
76 | elif o == "--files":
|
---|
77 | files = a
|
---|
78 | elif o in ("-d","--dry-run"):
|
---|
79 | dry = True
|
---|
80 | elif o in ("--message"):
|
---|
81 | message = a
|
---|
82 | elif o in ("--subject"):
|
---|
83 | subject = a
|
---|
84 | elif o in ("--to"):
|
---|
85 | to = a
|
---|
86 | elif o in ("--cc"):
|
---|
87 | cc = a
|
---|
88 | elif o in ("--force"):
|
---|
89 | force = True;
|
---|
90 |
|
---|
91 | error = False
|
---|
92 | if not sender:
|
---|
93 | print "No sender defined"
|
---|
94 | error = True
|
---|
95 | elif not recipient:
|
---|
96 | print "No recipient defined"
|
---|
97 | error = True
|
---|
98 | elif not server:
|
---|
99 | print "No server defined"
|
---|
100 | error = True
|
---|
101 |
|
---|
102 | if error:
|
---|
103 | usage()
|
---|
104 | sys.exit(128)
|
---|
105 |
|
---|
106 | if force:
|
---|
107 | sender = sender_raw
|
---|
108 | recipient = recipient_raw
|
---|
109 |
|
---|
110 |
|
---|
111 | #Subject here, just to keep the settings/layout a bit more constent
|
---|
112 | if not subject:
|
---|
113 | subject = 'Test email send at %a, %d %b %Y %T %z'
|
---|
114 | subject = strftime(subject,gmtime())
|
---|
115 |
|
---|
116 | if not to:
|
---|
117 | to = 'Testing received <' + recipient + '>'
|
---|
118 | to = recipient
|
---|
119 |
|
---|
120 | email = MIMEMultipart()
|
---|
121 | hostname = socket.gethostname()
|
---|
122 |
|
---|
123 | email['From'] = 'Testing sender <' + sender + '>'
|
---|
124 | email['To'] = to
|
---|
125 | if cc:
|
---|
126 | email['Cc'] = cc
|
---|
127 | email['X-Server'] = server
|
---|
128 | email['X-Port'] = port
|
---|
129 | email['X-Hostname'] = hostname
|
---|
130 | email['Message-ID' ] = '<' +''.join(random.sample(string.letters +
|
---|
131 | string.digits,10)) + '@' + email['X-Hostname'] + '>'
|
---|
132 | email['Date'] = strftime('%a, %d %b %Y %T %z',gmtime())
|
---|
133 | email['Subject'] = subject
|
---|
134 | email['X-Version'] = __svnversion__
|
---|
135 | email['X-Author'] = __author__
|
---|
136 | email['X-Tests'] = tests
|
---|
137 | #email['Reply-To'] = "Rick vd Zwet <rick@joost.com>, Wouter Simons <wouter@joost.com>"
|
---|
138 | if spam:
|
---|
139 | email['X-Spam'] = 'XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X'
|
---|
140 |
|
---|
141 |
|
---|
142 | def defaultmessage():
|
---|
143 | msg = ''
|
---|
144 | msg += \
|
---|
145 | '''
|
---|
146 | Hi,
|
---|
147 |
|
---|
148 | Sorry to bother you...
|
---|
149 |
|
---|
150 | Please ignore this message as it is used to test
|
---|
151 | and verify systems to make sure everything works
|
---|
152 | flawless.
|
---|
153 |
|
---|
154 | %(virus)s
|
---|
155 |
|
---|
156 | Technical details:\n''' % email
|
---|
157 |
|
---|
158 | for k in email.keys():
|
---|
159 | v = email[k]
|
---|
160 | msg += "* %-15s : %s\n" % (k,v)
|
---|
161 |
|
---|
162 |
|
---|
163 | msg = msg + \
|
---|
164 | '''
|
---|
165 | Best regards,
|
---|
166 | Your system administrator
|
---|
167 | --
|
---|
168 | BSD Licensed Source Code for this tool at:
|
---|
169 | https://rickvanderzwet.nl/svn/personal/foomailer
|
---|
170 | '''
|
---|
171 | return(msg)
|
---|
172 |
|
---|
173 | if message:
|
---|
174 | f = open(message,'r')
|
---|
175 | msg = f.read()
|
---|
176 | f.close()
|
---|
177 | else:
|
---|
178 | msg = defaultmessage()
|
---|
179 |
|
---|
180 | email.attach(MIMEText(msg))
|
---|
181 |
|
---|
182 | if virus:
|
---|
183 | part = MIMEBase('application', "octet-stream")
|
---|
184 | part.set_payload('X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*')
|
---|
185 | Encoders.encode_base64(part)
|
---|
186 | part.add_header('Content-Disposition', 'attachment; filename="eicar.txt"')
|
---|
187 | email.attach(part)
|
---|
188 |
|
---|
189 | if files:
|
---|
190 | for file in files.split(':'):
|
---|
191 | mimetype = mimetypes.guess_type(file)[0].split('/')
|
---|
192 | part = MIMEBase(mimetype[0],mimetype[1])
|
---|
193 | f = open(file,'r')
|
---|
194 | part.set_payload(f.read())
|
---|
195 | f.close()
|
---|
196 | Encoders.encode_base64(part)
|
---|
197 | part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(file))
|
---|
198 | email.attach(part)
|
---|
199 |
|
---|
200 | print email.as_string()
|
---|
201 |
|
---|
202 | if not dry:
|
---|
203 | mark = time.time()
|
---|
204 | server = smtplib.SMTP(server, port)
|
---|
205 | server.set_debuglevel(trace)
|
---|
206 | server.helo(hostname)
|
---|
207 | server.ehlo(hostname)
|
---|
208 | server.sendmail(sender, recipient, email.as_string())
|
---|
209 | server.quit()
|
---|
210 | print "Sending took sec: %.2f" % (time.time() - mark)
|
---|