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