def compose_plain_email(fromEmail, toEmail, content, headers): msg = MIMEText(content) # Setup the mail headers for (header, value) in headers.items(): msg[header] = value msg.set_charset('utf-8') headkeys = [k.lower() for k in headers.keys()] # Add required headers if not present if "message-id" not in headkeys: msg["Message-ID"] = messageid() if "date" not in headkeys: msg["Date"] = rfc822date() if "from" not in headkeys and "sender" not in headkeys: msg["From"] = fromEmail if "to" not in headkeys and "cc" not in headkeys and "bcc" not in headkeys: msg["To"] = toEmail if "reply-to" not in headkeys: msg["Reply-To"] = SUPPORT_ADDRESS if "user-agent" not in headkeys: msg["User-Agent"] = USER_AGENT return msg.as_string()
def receivedHeader(self, helo, origin, recipients): clientHostname, _ = helo myHostname = self.protocol.transport.getHost().host headerValue = 'from %s by %s with ESMTP ; %s' % (clientHostname, myHostname, smtp.rfc822date()) return 'Received: %s' % Header(headerValue)
def send_plain_email(smtphost, username, password, fromEmail, toEmail, content, headers, senderDomainName=None, port=25, requireSSL=True): requireAuth = bool(password) msg = MIMEText(content) # Setup the mail headers for (header, value) in headers.items(): msg[header] = value headkeys = [k.lower() for k in headers.keys()] # Add required headers if not present if "message-id" not in headkeys: msg["Message-ID"] = messageid() if "date" not in headkeys: msg["Date"] = rfc822date() if "from" not in headkeys and "sender" not in headkeys: msg["From"] = fromEmail if "to" not in headkeys and "cc" not in headkeys and "bcc" not in headkeys: msg["To"] = toEmail # send message f = StringIO(msg.as_string()) d = defer.Deferred() factory = ESMTPSenderFactory(username, password, fromEmail, toEmail, f, d, requireAuthentication=requireAuth, requireTransportSecurity=requireSSL) if senderDomainName is not None: factory.domain = senderDomainName connectTCP(smtphost, port, factory) return d
def receivedHeader(self, helo, origin, recipients): """ Generate a received header string for a message. @type helo: 2-L{tuple} of (L{bytes}, L{bytes}) @param helo: The client's identity as sent in the HELO command and its IP address. @type origin: L{Address} @param origin: The origination address of the message. @type recipients: L{list} of L{User} @param recipients: The destination addresses for the message. @rtype: L{bytes} @return: A received header string. """ authStr = heloStr = "" if self.user: authStr = " auth=%s" % (self.user.encode('xtext'), ) if helo[0]: heloStr = " helo=%s" % (helo[0], ) from_ = "from %s ([%s]%s%s)" % (helo[0], helo[1], heloStr, authStr) by = "by %s with %s (%s)" % (self.host, self.protocolName, longversion) for_ = "for <%s>; %s" % (' '.join(map(str, recipients)), smtp.rfc822date()) return "Received: %s\n\t%s\n\t%s" % (from_, by, for_)
def receivedHeader(self, helo, origin, recipients): #Arma el en cabezado clientHostname, clientIP = helo myHostname = self.protocol.transport.getHost().host headerValue = "from %s by %s with ESMTP ; %s" % ( clientHostname, myHostname, smtp.rfc822date()) return "Received: %s" % Header(headerValue)
def send(self, response): message = response['reply'] response['To'] = response['target'] response['Date'] = smtp.rfc822date() if 'Subject' not in response: response['Subject'] = 'Message from %s' % ibid.config['botname'] response['Content-Type'] = 'text/plain; charset=utf-8' del response['target'] del response['source'] del response['reply'] body = '' for header, value in response.items(): body += '%s: %s\n' % (header, value) body += '\n' body += message port = ':' in self.relayhost and int( self.relayhost.split(':')[1]) or 25 smtp.sendmail(self.relayhost.split(':')[0], self.address, response['To'], body.encode('utf-8'), port=port) self.log.debug(u"Sent email to %s: %s", response['To'], response['Subject'])
def receivedHeader(self, helo, origin, recipients): """ Generate a received header string for a message. @type helo: 2-L{tuple} of (L{bytes}, L{bytes}) @param helo: The client's identity as sent in the HELO command and its IP address. @type origin: L{Address} @param origin: The origination address of the message. @type recipients: L{list} of L{User} @param recipients: The destination addresses for the message. @rtype: L{bytes} @return: A received header string. """ authStr = heloStr = b"" if self.user: authStr = b" auth=" + self.user.encode('xtext') if helo[0]: heloStr = b" helo=" + helo[0] fromUser = (b"from " + helo[0] + b" ([" + helo[1] + b"]" + heloStr + authStr) by = (b"by " + self.host + b" with " + self.protocolName + b" (" + networkString(longversion) + b")") forUser = (b"for <" + b' '.join(map(bytes, recipients)) + b"> " + smtp.rfc822date()) return (b"Received: " + fromUser + b"\n\t" + by + b"\n\t" + forUser)
def receivedHeader(self, helo, origin, recipients): """ Generate a received header string for a message. @type helo: 2-L{tuple} of (L{bytes}, L{bytes}) @param helo: The client's identity as sent in the HELO command and its IP address. @type origin: L{Address} @param origin: The origination address of the message. @type recipients: L{list} of L{User} @param recipients: The destination addresses for the message. @rtype: L{bytes} @return: A received header string. """ authStr = heloStr = "" if self.user: authStr = " auth=%s" % (self.user.encode('xtext'),) if helo[0]: heloStr = " helo=%s" % (helo[0],) from_ = "from %s ([%s]%s%s)" % (helo[0], helo[1], heloStr, authStr) by = "by %s with %s (%s)" % ( self.host, self.protocolName, longversion ) for_ = "for <%s>; %s" % (' '.join(map(str, recipients)), smtp.rfc822date()) return "Received: %s\n\t%s\n\t%s" % (from_, by, for_)
def receivedHeader(self, helo, orgin, recipents): myHostname, clientIP = helo headerValue = "by %s from %s with ESMTP; %s" % ( myHostname, clientIP, smtp.rfc822date()) retval = "Recieved: %s" % Header(headerValue) #retval = "" self.logger.debug("receivedHeader: helo:%s orgin:%s recipents:%s", helo, orgin, [r.dest for r in recipents] ) return retval
def writeHeaders(self, fromAddress, toAddress, subject=None, inReplyTo=None, includeMessageID=True, contentType='text/plain; charset="utf-8"', **kwargs): """Write all headers into the response email. :param str fromAddress: The email address for the ``'From:'`` header. :param str toAddress: The email address for the ``'To:'`` header. :type subject: ``None`` or :any:`str` :param subject: The ``'Subject:'`` header. :type inReplyTo: ``None`` or :any:`str` :param inReplyTo: If set, an ``'In-Reply-To:'`` header will be generated. This should be set to the ``'Message-ID:'`` header from the client's original request email. :param bool includeMessageID: If ``True``, generate and include a ``'Message-ID:'`` header for the response. :param str contentType: The ``'Content-Type:'`` header. :kwargs: If given, the key will become the name of the header, and the value will become the contents of that header. """ fromAddress = fromAddress.decode('utf-8') if isinstance( fromAddress, bytes) else fromAddress toAddress = toAddress.decode('utf-8') if isinstance( toAddress, bytes) else toAddress self.write("From: %s" % fromAddress) self.write("To: %s" % toAddress) if includeMessageID: self.write("Message-ID: %s" % smtp.messageid()) if inReplyTo: self.write("In-Reply-To: %s" % inReplyTo) self.write("Content-Type: %s" % contentType) self.write("Date: %s" % smtp.rfc822date().decode('utf-8')) if not subject: subject = '[no subject]' if not subject.lower().startswith('re'): subject = "Re: " + subject self.write("Subject: %s" % subject) if kwargs: for headerName, headerValue in kwargs.items(): headerName = headerName.capitalize() headerName = headerName.replace(' ', '-') headerName = headerName.replace('_', '-') header = "%s: %s" % (headerName, headerValue) self.write(header) # The first blank line designates that the headers have ended: self.write(self.delimiter)
def receivedHeader(self, helo, unused, ignored): myHostname, self.clientIP = helo date = smtp.rfc822date() headerValue = 'by %s from %s with ESMTP ; %s' % ( myHostname, self.clientIP, date) log.info('Relayed (or sent directly) from: %s', self.clientIP) header = 'Received: %s' % Header(headerValue) return header
def receivedHeader(self, helo, origin, recipients): authStr = heloStr = "" if self.user: authStr = " auth=%s" % (self.user.encode('xtext'), ) if helo[0]: heloStr = " helo=%s" % (helo[0], ) from_ = "from %s ([%s]%s%s)" % (helo[0], helo[1], heloStr, authStr) by = "by %s with %s (%s)" % (self.host, self.protocolName, longversion) for_ = "for <%s>; %s" % (' '.join(map(str, recipients)), smtp.rfc822date()) return "Received: %s\n\t%s\n\t%s" % (from_, by, for_)
def receivedHeader(self, helo, origin, recipients): authStr = heloStr = "" if self.user: authStr = " auth=%s" % (self.user.encode('xtext'),) if helo[0]: heloStr = " helo=%s" % (helo[0],) from_ = "from %s ([%s]%s%s)" % (helo[0], helo[1], heloStr, authStr) by = "by %s with %s (%s)" % ( self.host, self.protocolName, longversion ) for_ = "for <%s>; %s" % (' '.join(map(str, recipients)), smtp.rfc822date()) return "Received: %s\n\t%s\n\t%s" % (from_, by, for_)
def receivedHeader(self, helo, origin, recipients): header = conf.smtp_header.format( sender_ip = helo[1], sender_host = helo[0], srv_host = conf.smtp_hostname, srv_info = conf.srv_version, sender = conf.smtp_email_delim.join([origin.local, origin.domain]), id = self.messageid, rcpt = conf.smtp_email_delim.join([recipients[0].dest.local, recipients[0].dest.domain]), date = smtp.rfc822date() ) return 'Received: %s' % Header(header)
def receivedHeader(self, helo, origin, recipients): """Create the ``Received:`` header for an incoming email. :type helo: tuple :param helo: The lines received during SMTP client HELO. :type origin: :api:`twisted.mail.smtp.Address` :param origin: The email address of the sender. :type recipients: list :param recipients: A list of :api:`twisted.mail.smtp.User` instances. """ helo_ = ' helo={0}'.format(helo[0]) if helo[0] else '' from_ = 'from %s ([%s]%s)' % (helo[0], helo[1], helo_) by_ = 'by %s with BridgeDB (%s)' % (smtp.DNSNAME, __version__) for_ = 'for %s; %s ' % (' '.join(map(str, recipients)), rfc822date()) return str('Received: %s\n\t%s\n\t%s' % (from_, by_, for_))
def receivedHeader(self, helo, origin, recipients): """Create the ``Received:`` header for an incoming email. :type helo: tuple :param helo: The lines received during SMTP client HELO. :type origin: :api:`twisted.mail.smtp.Address` :param origin: The email address of the sender. :type recipients: list :param recipients: A list of :api:`twisted.mail.smtp.User` instances. """ cameFrom = "%s (%s [%s])" % (helo[0] or origin, helo[0], helo[1]) cameFor = ', '.join(["<{0}>".format(recp.dest) for recp in recipients]) hdr = str("Received: from %s for %s; %s" % (cameFrom, cameFor, smtp.rfc822date())) return hdr
def send_plain_email(fromEmail, toEmail, content, headers): if REQUIRE_AUTH: password = FilePath(SMTP_PASSWORD_PATH).getContent().strip() else: password = None msg = MIMEText(content) # Setup the mail headers for (header, value) in headers.items(): msg[header] = value headkeys = [k.lower() for k in headers.keys()] # Add required headers if not present if "message-id" not in headkeys: msg["Message-ID"] = messageid() if "date" not in headkeys: msg["Date"] = rfc822date() if "from" not in headkeys and "sender" not in headkeys: msg["From"] = fromEmail if "to" not in headkeys and "cc" not in headkeys and "bcc" not in headkeys: msg["To"] = toEmail if "reply-to" not in headkeys: msg["Reply-To"] = SUPPORT_ADDRESS if "user-agent" not in headkeys: msg["User-Agent"] = USER_AGENT if "content-type" not in headkeys: msg["Content-Type"] = CONTENT_TYPE # send message f = StringIO(msg.as_string()) d = defer.Deferred() factory = ESMTPSenderFactory( SMTP_USERNAME, password, fromEmail, toEmail, f, d, requireAuthentication=REQUIRE_AUTH, requireTransportSecurity=REQUIRE_TRANSPORT_SECURITY) factory.domain = SENDER_DOMAIN connectTCP(SMTP_HOST, SMTP_PORT, factory) return d
def receivedHeader(self, helo, origin, recipients): """Generates the Received header for a message. Specified by IMessageDelivery interface. Args: helo: The argument to the HELO command and the client's IP address. origin: The address the message is from. recipients: A list of the addresses for which this message is bound. Returns: The full "Received" header string. """ client_hostname, _ = helo server_hostname = self.protocol.transport.getHost().host header_value = 'from %s by %s with ESMTP ; %s' % ( client_hostname, server_hostname, smtp.rfc822date()) return 'Received: %s' % (email.Header.Header(header_value),)
def receivedHeader(self, helo, origin, recipients): """Create the ``Received:`` header for an incoming email. :type helo: tuple :param helo: The lines received during SMTP client HELO. :type origin: :api:`twisted.mail.smtp.Address` :param origin: The email address of the sender. :type recipients: list :param recipients: A list of :api:`twisted.mail.smtp.User` instances. """ helo_ = b' helo=%s' % (helo[0] if helo[0] else '') from_ = b'from %s ([%s]%s)' % (helo[0], helo[1], helo_) by_ = b'by %s with BridgeDB (%s)' % (smtp.DNSNAME, __version__.encode('utf-8')) for_ = b'for %s; %s ' % (b' '.join( [str(r).encode('utf-8') for r in recipients]), rfc822date()) return 'Received: %s\n\t%s\n\t%s' % ( from_.decode('utf-8'), by_.decode('utf-8'), for_.decode('utf-8'))
def addMessage(self, msg, flags=None, date=None): #print "Add Message: %s :: %s" % (msg, flags) # passes a file handler here, need to cache fetchBodyFile so I can find the message id. # list of uids # uids[sequence_number] = msg_uid # add new uid # rpush[msg_uid] parse = Parser() email_obj = parse.parse(msg) fp = StringIO() g = Generator(fp, mangle_from_=False, maxheaderlen=60) g.flatten(email_obj) body = fp.getvalue() msg_uid = self.conn.incr("%s:mailboxes:%s:uidnext" % (self.user, self.folder)) - 1; self.conn.zadd("%s:mailboxes:%s:uidlist"% (self.user, self.folder), msg_uid, msg_uid) self.seqlist.append((msg_uid, ['\Recent'])) seq_number = len(self.seqlist) if flags: self.conn.sadd("%s:mailboxes:%s:mail:%s:flags" % (self.user, self.folder, msg_uid), *flags) self.conn.set("%s:mailboxes:%s:mail:%s:date" % (self.user, self.folder, msg_uid), rfc822date()) self.conn.incr("%s:mailboxes:%s:count" % (self.user, self.folder)) self.conn.set("%s:mailboxes:%s:mail:%s:size" % (self.user, self.folder, msg_uid), len(body)) self.conn.set("%s:mailboxes:%s:mail:%s:body" % (self.user, self.folder, msg_uid), body) self.conn.sadd("%s:mailboxes:%s:mail:%s:headers" % (self.user, self.folder, msg_uid), *(email_obj.keys())) #print email_obj.keys() for header in email_obj.keys(): self.conn.set("%s:mailboxes:%s:mail:%s:header:%s" % (self.user, self.folder, msg_uid, header.lower()), email_obj[header]) #print header, msg_uid, self.folder, self.user self.conn.incr("%s:mailboxes:%s:recent" % (self.user, self.folder)) self.recent_count += 1 self.conn.publish("%s:mailboxes:%s:channel" % (self.user, self.folder), "count %d" % (msg_uid)) return defer.succeed(seq_number)
def writeHeaders(self, fromAddress, toAddress, subject=None, inReplyTo=None, includeMessageID=True, contentType='text/plain; charset="utf-8"', **kwargs): """Write all headers into the response email. :param str fromAddress: The email address for the ``'From:'`` header. :param str toAddress: The email address for the ``'To:'`` header. :type subject: None or str :param subject: The ``'Subject:'`` header. :type inReplyTo: None or str :param inReplyTo: If set, an ``'In-Reply-To:'`` header will be generated. This should be set to the ``'Message-ID:'`` header from the client's original request email. :param bool includeMessageID: If ``True``, generate and include a ``'Message-ID:'`` header for the response. :param str contentType: The ``'Content-Type:'`` header. :kwargs: If given, the key will become the name of the header, and the value will become the Contents of that header. """ self.write("From: %s" % fromAddress) self.write("To: %s" % toAddress) if includeMessageID: self.write("Message-ID: %s" % smtp.messageid().encode('utf-8')) if inReplyTo: self.write("In-Reply-To: %s" % inReplyTo.encode('utf-8')) self.write("Content-Type: %s" % contentType.encode('utf-8')) self.write("Date: %s" % smtp.rfc822date().encode('utf-8')) if not subject: subject = '[no subject]' if not subject.lower().startswith('re'): subject = "Re: " + subject self.write("Subject: %s" % subject.encode('utf-8')) if kwargs: for headerName, headerValue in kwargs.items(): headerName = headerName.capitalize() headerName = headerName.replace(' ', '-') headerName = headerName.replace('_', '-') header = "%s: %s" % (headerName, headerValue) self.write(header.encode('utf-8')) # The first blank line designates that the headers have ended: self.write(self.delimiter)
def receivedHeader(self, helo, origin, recipients): """ Generate the 'Received:' header for a message. :param helo: The argument to the HELO command and the client's IP address. :type helo: (str, str) :param origin: The address the message is from. :type origin: twisted.mail.smtp.Address :param recipients: A list of the addresses for which this message is bound. :type: list of twisted.mail.smtp.User @return: The full "Received" header string. :type: str """ myHostname, clientIP = helo headerValue = "by bitmask.local from %s with ESMTP ; %s" % ( clientIP, smtp.rfc822date()) # email.Header.Header used for automatic wrapping of long lines return "Received: %s" % Header(s=headerValue, header_name='Received')
def send(self, response): message = response['reply'] response['To'] = response['target'] response['Date'] = smtp.rfc822date() if 'Subject' not in response: response['Subject'] = 'Message from %s' % ibid.config['botname'] response['Content-Type'] = 'text/plain; charset=utf-8' del response['target'] del response['source'] del response['reply'] body = '' for header, value in response.items(): body += '%s: %s\n' % (header, value) body += '\n' body += message port = ':' in self.relayhost and int(self.relayhost.split(':')[1]) or 25 smtp.sendmail(self.relayhost.split(':')[0], self.address, response['To'], body.encode('utf-8'), port=port) self.log.debug(u"Sent email to %s: %s", response['To'], response['Subject'])
def send_plain_email(fromEmail, toEmail, content, headers): if REQUIRE_AUTH: password = FilePath(SMTP_PASSWORD_PATH).getContent().strip() else: password = None msg = MIMEText(content) # Setup the mail headers for (header, value) in headers.items(): msg[header] = value headkeys = [k.lower() for k in headers.keys()] # Add required headers if not present if "message-id" not in headkeys: msg["Message-ID"] = messageid() if "date" not in headkeys: msg["Date"] = rfc822date() if "from" not in headkeys and "sender" not in headkeys: msg["From"] = fromEmail if "to" not in headkeys and "cc" not in headkeys and "bcc" not in headkeys: msg["To"] = toEmail if "reply-to" not in headkeys: msg["Reply-To"] = SUPPORT_ADDRESS if "user-agent" not in headkeys: msg["User-Agent"] = USER_AGENT if "content-type" not in headkeys: msg["Content-Type"] = CONTENT_TYPE # send message f = StringIO(msg.as_string()) d = defer.Deferred() factory = ESMTPSenderFactory(SMTP_USERNAME, password, fromEmail, toEmail, f, d, requireAuthentication=REQUIRE_AUTH, requireTransportSecurity=REQUIRE_TRANSPORT_SECURITY) factory.domain = SENDER_DOMAIN connectTCP(SMTP_HOST, SMTP_PORT, factory) return d
def requestAvatarId(self, credentials): api = twitter.Api( username=credentials.username, password=credentials.password, input_encoding=None, request_headers={"X-Twitter-Client": "twIMAPd", "X-Twitter-Client-Version": ".5"}, ) self.cache.set("api", api) self.cache.set("username", credentials.username) try: user = api.GetDirectMessages() try: file = open("/tmp/%s_twimap.db" % credentials.username) except IOError: createDB = True else: createDB = False conn = sqlite.connect("/tmp/%s_twimap.db" % credentials.username) cur = conn.cursor() if createDB: sql = "create table log (key text, value text)" cur.execute(sql) # sql = "create table messages (id integer primary key, folder text, headers text, seen integer default 0, deleted integer default 0, message text)" sql = "create table messages (msgid integer primary key, id integer, folder text, headers text, seen integer default 0, deleted integer default 0, message text)" cur.execute(sql) sql = "create unique index messagelist on messages (id, folder)" cur.execute(sql) sql = "create unique index folders on log (key, value)" cur.execute(sql) cur.execute('delete from log where (key = "lastcheck")') sql = 'insert into log (key, value) values ("lastcheck", "%s")' % rfc822date(time.localtime()) print "SQL :: %s" % sql cur.execute(sql) conn.commit() self.cache.set("conn", conn) return defer.succeed(credentials.username) except HTTPError: return defer.fail(credError.UnauthorizedLogin("Bad password - fool"))
def headers(self): local = time.localtime(int(self.macros['TIMET'])) user = pwd.getpwuid(os.getuid())[0] host = socket.getfqdn() ret = { 'Subject': self.subject(), 'To': self.macros['CONTACTEMAIL'], 'From': "%s@%s" % (user, host), 'Date': smtp.rfc822date(local), 'X-Nagios-Notification-Type': self.macros['NOTIFICATIONTYPE'], 'X-Nagios-Host-Name': self.macros['HOSTNAME'], 'X-Nagios-Host-State': self.macros['HOSTSTATE'], 'X-Nagios-Host-Groups': self.macros['HOSTGROUPNAMES'] } if self.type == "service": ret['X-Nagios-Service-Description'] = self.macros['SERVICEDESC'] ret['X-Nagios-Service-State'] = self.macros['SERVICESTATE'] ret['X-Nagios-Service-Groups'] = self.macros['SERVICEGROUPNAMES'] return ret
def requestAvatarId(self, credentials): api = twitter.Api(username=credentials.username, password=credentials.password, input_encoding=None, request_headers={ 'X-Twitter-Client': 'twIMAPd', 'X-Twitter-Client-Version': '.5' }) self.cache.set('api', api) self.cache.set('username', credentials.username) try: user = api.GetDirectMessages() try: file = open("/tmp/%s_twimap.db" % credentials.username) except IOError: createDB = True else: createDB = False conn = sqlite.connect("/tmp/%s_twimap.db" % credentials.username) cur = conn.cursor() if createDB: sql = "create table log (key text, value text)" cur.execute(sql) #sql = "create table messages (id integer primary key, folder text, headers text, seen integer default 0, deleted integer default 0, message text)" sql = "create table messages (msgid integer primary key, id integer, folder text, headers text, seen integer default 0, deleted integer default 0, message text)" cur.execute(sql) sql = "create unique index messagelist on messages (id, folder)" cur.execute(sql) sql = "create unique index folders on log (key, value)" cur.execute(sql) cur.execute('delete from log where (key = "lastcheck")') sql = 'insert into log (key, value) values ("lastcheck", "%s")' % rfc822date(time.localtime()) print "SQL :: %s" % sql cur.execute(sql) conn.commit() self.cache.set('conn', conn) return defer.succeed(credentials.username) except HTTPError: return defer.fail(credError.UnauthorizedLogin("Bad password - fool"))
def receivedHeader(self, helo, origin, recipients): try: return "Received: from %s (%s); %s" % (helo[1], origin, smtp.rfc822date()) except KeyError: return "Received: from %s (%s); %s" % (helo[0], origin, smtp.rfc822date()) # never tried ;P
def getInternalDate(self): return rfc822date(self.message.timestamp.timetuple())
def __init__(self, task, proxy): self.proxy = proxy self.task = task self.compute_body() self.internal_date = rfc822date(self.task['sort_time'])
def fetch(self, messages, uid): return [[seq, MaildirMessage(seq, file(filename, 'rb').read(), self.msg_info[filename.split('/')[-1]]['flags'], rfc822date())] for seq, filename in self.__fetch_(messages, uid).iteritems()]
def parseOptions(argv): o = Options() o.to = [e for e in argv if not e.startswith('-')] o.sender = getlogin() # Just be very stupid # Skip -bm -- it is the default # Add a non-standard option for querying the version of this tool. if '--version' in argv: print('mailmail version:', version) raise SystemExit() # -bp lists queue information. Screw that. if '-bp' in argv: raise _unsupportedOption # -bs makes sendmail use stdin/stdout as its transport. Screw that. if '-bs' in argv: raise _unsupportedOption # -F sets who the mail is from, but is overridable by the From header if '-F' in argv: o.sender = argv[argv.index('-F') + 1] o.to.remove(o.sender) # -i and -oi makes us ignore lone "." if ('-i' in argv) or ('-oi' in argv): raise _unsupportedOption # -odb is background delivery if '-odb' in argv: o.background = True else: o.background = False # -odf is foreground delivery if '-odf' in argv: o.background = False else: o.background = True # -oem and -em cause errors to be mailed back to the sender. # It is also the default. # -oep and -ep cause errors to be printed to stderr if ('-oep' in argv) or ('-ep' in argv): o.printErrors = True else: o.printErrors = False # -om causes a copy of the message to be sent to the sender if the sender # appears in an alias expansion. We do not support aliases. if '-om' in argv: raise _unsupportedOption # -t causes us to pick the recipients of the message from the To, Cc, and Bcc # headers, and to remove the Bcc header if present. if '-t' in argv: o.recipientsFromHeaders = True o.excludeAddresses = o.to o.to = [] else: o.recipientsFromHeaders = False o.exludeAddresses = [] requiredHeaders = { 'from': [], 'to': [], 'cc': [], 'bcc': [], 'date': [], } buffer = StringIO.StringIO() while 1: write = 1 line = sys.stdin.readline() if not line.strip(): break hdrs = line.split(': ', 1) hdr = hdrs[0].lower() if o.recipientsFromHeaders and hdr in ('to', 'cc', 'bcc'): o.to.extend([ a[1] for a in rfc822.AddressList(hdrs[1]).addresslist ]) if hdr == 'bcc': write = 0 elif hdr == 'from': o.sender = rfc822.parseaddr(hdrs[1])[1] if hdr in requiredHeaders: requiredHeaders[hdr].append(hdrs[1]) if write: buffer.write(line) if not requiredHeaders['from']: buffer.write('From: %s\r\n' % (o.sender,)) if not requiredHeaders['to']: if not o.to: raise SystemExit("No recipients specified.") buffer.write('To: %s\r\n' % (', '.join(o.to),)) if not requiredHeaders['date']: buffer.write('Date: %s\r\n' % (smtp.rfc822date(),)) buffer.write(line) if o.recipientsFromHeaders: for a in o.excludeAddresses: try: o.to.remove(a) except: pass buffer.seek(0, 0) o.body = StringIO.StringIO(buffer.getvalue() + sys.stdin.read()) return o
def receivedHeader(self, helo, origin, recipients): r = ",".join(str(u) for u in recipients) return "Received: for %s %s" % (r, rfc822date())
def receivedHeader(self, helo, origin, recipients): myHostname, clientIP = helo headerValue = "by %s from %s with ESMTP: %s" % ( myHostname, clientIP, smtp.rfc822date()) return "Received: %s" % Header(headerValue)
def receivedHeader(self, helo, origin, recipients): myHostname, clientIP = helo headerValue = 'by {} from {} with SMTP ; {}'.format(myHostname, clientIP, smtp.rfc822date( )) # this line creates the second "received" line. should probably be commented out return 'Received: {}'.format(Header(headerValue))
def receivedHeader(self, helo, origin, recipients): myHostname, clientIP = helo headerValue = 'by %s from %s with SMTP ; %s' % (myHostname, clientIP, smtp.rfc822date()) return 'Received: %s' % Header(headerValue)
def generateEmail(self, inviteState, calendar, orgEmail, orgCN, attendees, fromAddress, replyToAddress, toAddress, language='en'): details = self.getEventDetails(calendar, language=language) canceled = (calendar.propertyValue("METHOD") == "CANCEL") iconPath = self.getIconPath(details, canceled, language=language) with translationTo(language): msg = MIMEMultipart() msg["From"] = fromAddress msg["Reply-To"] = replyToAddress msg["To"] = toAddress msg["Date"] = rfc822date() msgId = messageid() msg["Message-ID"] = msgId if canceled: formatString = _("Event canceled: %(summary)s") elif inviteState == "new": formatString = _("Event invitation: %(summary)s") elif inviteState == "update": formatString = _("Event update: %(summary)s") else: formatString = _("Event reply: %(summary)s") # The translations we get back from gettext are utf-8 encoded # strings, so convert to unicode formatString = formatString.decode("utf-8") details['subject'] = msg['Subject'] = formatString % { 'summary' : details['summary'] } msgAlt = MIMEMultipart("alternative") msg.attach(msgAlt) # Get localized labels if canceled: details['inviteLabel'] = _("Event Canceled") else: if inviteState == "new": details['inviteLabel'] = _("Event Invitation") if inviteState == "update": details['inviteLabel'] = _("Event Update") else: details['inviteLabel'] = _("Event Reply") details['dateLabel'] = _("Date") details['timeLabel'] = _("Time") details['durationLabel'] = _("Duration") details['recurrenceLabel'] = _("Occurs") details['descLabel'] = _("Description") details['orgLabel'] = _("Organizer") details['attLabel'] = _("Attendees") details['locLabel'] = _("Location") plainAttendeeList = [] for cn, mailto in attendees: if cn: plainAttendeeList.append(cn if not mailto else "%s <%s>" % (cn, mailto)) elif mailto: plainAttendeeList.append("<%s>" % (mailto,)) details['plainAttendees'] = ", ".join(plainAttendeeList) details['plainOrganizer'] = (orgCN if not orgEmail else "%s <%s>" % (orgCN, orgEmail)) # The translations we get back from gettext are utf-8 encoded # strings, so convert to unicode for key in details.keys(): if isinstance(details[key], str): details[key] = details[key].decode("utf-8") # plain text version if canceled: plainTemplate = u"""%(subject)s %(orgLabel)s: %(plainOrganizer)s %(dateLabel)s: %(dateInfo)s %(recurrenceInfo)s %(timeLabel)s: %(timeInfo)s %(durationInfo)s """ else: plainTemplate = u"""%(subject)s %(orgLabel)s: %(plainOrganizer)s %(locLabel)s: %(location)s %(dateLabel)s: %(dateInfo)s %(recurrenceInfo)s %(timeLabel)s: %(timeInfo)s %(durationInfo)s %(descLabel)s: %(description)s %(attLabel)s: %(plainAttendees)s """ plainText = plainTemplate % details msgPlain = MIMEText(plainText.encode("UTF-8"), "plain", "UTF-8") msgAlt.attach(msgPlain) # html version msgHtmlRelated = MIMEMultipart("related", type="text/html") msgAlt.attach(msgHtmlRelated) htmlAttendees = [] for cn, mailto in attendees: if mailto: htmlAttendees.append('<a href="mailto:%s">%s</a>' % (mailto, cn)) else: htmlAttendees.append(cn) details['htmlAttendees'] = ", ".join(htmlAttendees) if orgEmail: details['htmlOrganizer'] = '<a href="mailto:%s">%s</a>' % ( orgEmail, orgCN) else: details['htmlOrganizer'] = orgCN details['iconName'] = iconName = "calicon.png" templateDir = config.Scheduling.iMIP.MailTemplatesDirectory.rstrip("/") templateName = "cancel.html" if canceled else "invite.html" templatePath = os.path.join(templateDir, templateName) if not os.path.exists(templatePath): # Fall back to built-in simple templates: if canceled: htmlTemplate = u"""<html> <body><div> <h1>%(subject)s</h1> <p> <h3>%(orgLabel)s:</h3> %(htmlOrganizer)s </p> <p> <h3>%(dateLabel)s:</h3> %(dateInfo)s %(recurrenceInfo)s </p> <p> <h3>%(timeLabel)s:</h3> %(timeInfo)s %(durationInfo)s </p> """ else: htmlTemplate = u"""<html> <body><div> <p>%(inviteLabel)s</p> <h1>%(summary)s</h1> <p> <h3>%(orgLabel)s:</h3> %(htmlOrganizer)s </p> <p> <h3>%(locLabel)s:</h3> %(location)s </p> <p> <h3>%(dateLabel)s:</h3> %(dateInfo)s %(recurrenceInfo)s </p> <p> <h3>%(timeLabel)s:</h3> %(timeInfo)s %(durationInfo)s </p> <p> <h3>%(descLabel)s:</h3> %(description)s </p> <p> <h3>%(attLabel)s:</h3> %(htmlAttendees)s </p> """ else: # HTML template file exists with open(templatePath) as templateFile: htmlTemplate = templateFile.read() htmlText = htmlTemplate % details msgHtml = MIMEText(htmlText.encode("UTF-8"), "html", "UTF-8") msgHtmlRelated.attach(msgHtml) # an image for html version if (iconPath != None and os.path.exists(iconPath) and htmlTemplate.find("cid:%(iconName)s") != -1): with open(iconPath) as iconFile: msgIcon = MIMEImage(iconFile.read(), _subtype='png;x-apple-mail-type=stationery;name="%s"' % (iconName,)) msgIcon.add_header("Content-ID", "<%s>" % (iconName,)) msgIcon.add_header("Content-Disposition", "inline;filename=%s" % (iconName,)) msgHtmlRelated.attach(msgIcon) # the icalendar attachment self.log_debug("Mail gateway sending calendar body: %s" % (str(calendar))) msgIcal = MIMEText(str(calendar), "calendar", "UTF-8") method = calendar.propertyValue("METHOD").lower() msgIcal.set_param("method", method) msgIcal.add_header("Content-ID", "<invitation.ics>") msgIcal.add_header("Content-Disposition", "inline;filename=invitation.ics") msg.attach(msgIcal) return msgId, msg.as_string()
def parseOptions(argv): o = Options() o.to = [e for e in argv if not e.startswith('-')] o.sender = getlogin() # Just be very stupid # Skip -bm -- it is the default # -bp lists queue information. Screw that. if '-bp' in argv: raise _unsupportedOption # -bs makes sendmail use stdin/stdout as its transport. Screw that. if '-bs' in argv: raise _unsupportedOption # -F sets who the mail is from, but is overridable by the From header if '-F' in argv: o.sender = argv[argv.index('-F') + 1] o.to.remove(o.sender) # -i and -oi makes us ignore lone "." if ('-i' in argv) or ('-oi' in argv): raise _unsupportedOption # -odb is background delivery if '-odb' in argv: o.background = True else: o.background = False # -odf is foreground delivery if '-odf' in argv: o.background = False else: o.background = True # -oem and -em cause errors to be mailed back to the sender. # It is also the default. # -oep and -ep cause errors to be printed to stderr if ('-oep' in argv) or ('-ep' in argv): o.printErrors = True else: o.printErrors = False # -om causes a copy of the message to be sent to the sender if the sender # appears in an alias expansion. We do not support aliases. if '-om' in argv: raise _unsupportedOption # -t causes us to pick the recipients of the message from the To, Cc, and Bcc # headers, and to remove the Bcc header if present. if '-t' in argv: o.recipientsFromHeaders = True o.excludeAddresses = o.to o.to = [] else: o.recipientsFromHeaders = False o.exludeAddresses = [] requiredHeaders = { 'from': [], 'to': [], 'cc': [], 'bcc': [], 'date': [], } headers = [] buffer = StringIO.StringIO() while 1: write = 1 line = sys.stdin.readline() if not line.strip(): break hdrs = line.split(': ', 1) hdr = hdrs[0].lower() if o.recipientsFromHeaders and hdr in ('to', 'cc', 'bcc'): o.to.extend( [a[1] for a in rfc822.AddressList(hdrs[1]).addresslist]) if hdr == 'bcc': write = 0 elif hdr == 'from': o.sender = rfc822.parseaddr(hdrs[1])[1] if hdr in requiredHeaders: requiredHeaders[hdr].append(hdrs[1]) if write: buffer.write(line) if not requiredHeaders['from']: buffer.write('From: %s\r\n' % (o.sender, )) if not requiredHeaders['to']: if not o.to: raise SystemExit("No recipients specified.") buffer.write('To: %s\r\n' % (', '.join(o.to), )) if not requiredHeaders['date']: buffer.write('Date: %s\r\n' % (smtp.rfc822date(), )) buffer.write(line) if o.recipientsFromHeaders: for a in o.excludeAddresses: try: o.to.remove(a) except: pass buffer.seek(0, 0) o.body = StringIO.StringIO(buffer.getvalue() + sys.stdin.read()) return o
def mxServerFound(mxServer,session): print "[CrashlogAutoSubmit] - mxServerFound -->", mxServer crashLogFilelist = [] message = StringIO.StringIO() writer = MimeWriter.MimeWriter(message) mailFrom = "*****@*****.**" mailTo = "*****@*****.**" subject = "Automatically generated crashlogmail" # Define the main body headers. writer.addheader('To', "dream-multimedia-crashlogs <*****@*****.**>") writer.addheader('From', "CrashlogAutoSubmitter <*****@*****.**>") writer.addheader('Subject', str(subject)) writer.addheader('Date', smtp.rfc822date()) if config.plugins.crashlogautosubmit.attachemail.value is True: if str(config.plugins.crashlogautosubmit.email.value) != "*****@*****.**": writer.addheader('Reply-To', str(str(config.plugins.crashlogautosubmit.email.value))) writer.addheader('MIME-Version', '1.0') writer.startmultipartbody('mixed') # start with a text/plain part part = writer.nextpart() body = part.startbody('text/plain') part.flushheaders() # Define the message body body_text1 = "\nHello\n\nHere are some crashlogs i found for you.\n" if str(config.plugins.crashlogautosubmit.email.value) == "*****@*****.**": user_email = "" else: user_email = "\nUser supplied email address: " + str(config.plugins.crashlogautosubmit.email.value) if str(config.plugins.crashlogautosubmit.name.value) == "Dreambox User": user_name = "" else: user_name = "\n\nOptional supplied name: " + str(config.plugins.crashlogautosubmit.name.value) body_text2 = "\n\nThis is an automatically generated email from the CrashlogAutoSubmit plugin.\n\n\nHave a nice day.\n" body_text = body_text1 + user_email + user_name + body_text2 body.write(body_text) list = ( (_("Yes"), "send"), (_("Yes, and don't ask again"), "send_always"), (_("No, not now"), "send_not"), (_("No, send them never"), "send_never") ) def handleError(error): print "[CrashlogAutoSubmit] - Message send Error -->", error.getErrorMessage() def handleSuccess(result): print "[CrashlogAutoSubmit] - Message sent successfully -->",result if len(crashLogFilelist): for crashlog in crashLogFilelist: if config.plugins.crashlogautosubmit.sendlog.value == "delete": os.remove(crashlog) elif config.plugins.crashlogautosubmit.sendlog.value == "rename": currfilename = str(os.path.basename(crashlog)) newfilename = "/media/hdd/" + currfilename + ".sent" os.rename(crashlog,newfilename) def send_mail(): print "[CrashlogAutoSubmit] - send_mail" if len(crashLogFilelist): for crashlog in crashLogFilelist: filename = str(os.path.basename(crashlog)) subpart = writer.nextpart() subpart.addheader("Content-Transfer-Encoding", 'base64') subpart.addheader("Content-Disposition",'attachment; filename="%s"' % filename) subpart.addheader('Content-Description', 'Enigma2 crashlog') body = subpart.startbody("%s; name=%s" % ('application/octet-stream', filename)) mimetools.encode(open(crashlog, 'rb'), body, 'base64') writer.lastpart() sending = smtp.sendmail(str(mxServer), mailFrom, mailTo, message.getvalue()) sending.addCallback(handleSuccess).addErrback(handleError) def handleAnswer(answer): answer = answer and answer[1] print "[CrashlogAutoSubmit] - handleAnswer --> ",answer if answer == "send": send_mail() elif answer == "send_always": config.plugins.crashlogautosubmit.sendmail.value = "send_always" config.plugins.crashlogautosubmit.sendmail.save() config.plugins.crashlogautosubmit.save() config.plugins.save() send_mail() elif answer in ( None, "send_never"): config.plugins.crashlogautosubmit.sendmail.value = "send_never" config.plugins.crashlogautosubmit.sendmail.save() config.plugins.crashlogautosubmit.save() config.plugins.save() elif answer == "send_not": print "[CrashlogAutoSubmit] - not sending crashlogs for this time." for crashlog in os.listdir('/media/hdd'): if crashlog.startswith("enigma2_crash_") and crashlog.endswith(".log"): print "[CrashlogAutoSubmit] - found crashlog: ",os.path.basename(crashlog) crashLogFilelist.append('/media/hdd/' + crashlog) if len(crashLogFilelist): if config.plugins.crashlogautosubmit.sendmail.value == "send": Notifications.AddNotificationWithCallback(handleAnswer, ChoiceBox, title=_("Crashlogs found!\nSend them to Dream Multimedia?"), list = list) elif config.plugins.crashlogautosubmit.sendmail.value == "send_always": send_mail() else: print "[CrashlogAutoSubmit] - no crashlogs found."
def receivedHeader(self, helo, origin, recipients): myHostname, clientIP = helo headerValue = "by %s from %s with ESMTP ; %s" % (myHostname, clientIP, smtp.rfc822date()) # email.Header.Header used for automatic wrapping of long lines return "Received: %s" % Header(headerValue)
def generateEmail(self, inviteState, calendar, orgEmail, orgCN, attendees, fromAddress, replyToAddress, toAddress, language='en'): """ Generate MIME text containing an iMIP invitation, cancellation, update or reply. @param inviteState: 'new', 'update', or 'reply'. @type inviteState: C{str} @param calendar: the iCalendar component to attach to the email. @type calendar: L{twistedcaldav.ical.Component} @param orgEmail: The email for the organizer, in C{localhost@domain} format, or C{None} if the organizer has no email address. @type orgEmail: C{str} or C{NoneType} @param orgCN: Common name / display name for the organizer. @type orgCN: C{unicode} @param attendees: A C{list} of 2-C{tuple}s of (common name, email address) similar to (orgEmail, orgCN). @param fromAddress: the address to use in the C{From:} header of the email. @type fromAddress: C{str} @param replyToAddress: the address to use in the C{Reply-To} header. @type replyToAddress: C{str} @param toAddress: the address to use in the C{To} header. @type toAddress: C{str} @param language: a 2-letter language code describing the target language that the email should be generated in. @type language: C{str} @return: a 2-tuple of C{str}s: (message ID, message text). The message ID is the value of the C{Message-ID} header, and the message text is the full MIME message, ready for transport over SMTP. """ details = self.getEventDetails(calendar, language=language) canceled = (calendar.propertyValue("METHOD") == "CANCEL") subjectFormat, labels = localizedLabels(language, canceled, inviteState) details.update(labels) details['subject'] = subjectFormat % {'summary' : details['summary']} plainText = self.renderPlainText(details, (orgCN, orgEmail), attendees, canceled) htmlText = self.renderHTML(details, (orgCN, orgEmail), attendees, canceled) msg = MIMEMultipart() msg["From"] = fromAddress msg["Subject"] = details['subject'] msg["Reply-To"] = replyToAddress msg["To"] = toAddress msg["Date"] = rfc822date() msgId = messageid() msg["Message-ID"] = msgId msgAlt = MIMEMultipart("alternative") msg.attach(msgAlt) # plain version msgPlain = MIMEText(plainText, "plain", "UTF-8") msgAlt.attach(msgPlain) # html version msgHtmlRelated = MIMEMultipart("related", type="text/html") msgAlt.attach(msgHtmlRelated) msgHtml = MIMEText(htmlText, "html", "UTF-8") msgHtmlRelated.attach(msgHtml) calendarText = str(calendar) # the icalendar attachment self.log.debug("Mail gateway sending calendar body: %s" % (calendarText,)) msgIcal = MIMEText(calendarText, "calendar", "UTF-8") method = calendar.propertyValue("METHOD").lower() msgIcal.set_param("method", method) msgIcal.add_header("Content-ID", "<invitation.ics>") msgIcal.add_header("Content-Disposition", "inline;filename=invitation.ics") msg.attach(msgIcal) return msgId, msg.as_string()
def generateEmail(self, inviteState, calendar, orgEmail, orgCN, attendees, fromAddress, replyToAddress, toAddress, language='en'): """ Generate MIME text containing an iMIP invitation, cancellation, update or reply. @param inviteState: 'new', 'update', or 'reply'. @type inviteState: C{str} @param calendar: the iCalendar component to attach to the email. @type calendar: L{twistedcaldav.ical.Component} @param orgEmail: The email for the organizer, in C{localhost@domain} format, or C{None} if the organizer has no email address. @type orgEmail: C{str} or C{NoneType} @param orgCN: Common name / display name for the organizer. @type orgCN: C{unicode} @param attendees: A C{list} of 2-C{tuple}s of (common name, email address) similar to (orgEmail, orgCN). @param fromAddress: the address to use in the C{From:} header of the email. @type fromAddress: C{str} @param replyToAddress: the address to use in the C{Reply-To} header. @type replyToAddress: C{str} @param toAddress: the address to use in the C{To} header. @type toAddress: C{str} @param language: a 2-letter language code describing the target language that the email should be generated in. @type language: C{str} @return: a 2-tuple of C{str}s: (message ID, message text). The message ID is the value of the C{Message-ID} header, and the message text is the full MIME message, ready for transport over SMTP. """ details = self.getEventDetails(calendar, language=language) canceled = (calendar.propertyValue("METHOD") == "CANCEL") subjectFormat, labels = localizedLabels(language, canceled, inviteState) details.update(labels) details['subject'] = subjectFormat % {'summary': details['summary']} plainText = self.renderPlainText(details, (orgCN, orgEmail), attendees, canceled) htmlText = self.renderHTML(details, (orgCN, orgEmail), attendees, canceled) msg = MIMEMultipart() msg["From"] = fromAddress msg["Subject"] = details['subject'] msg["Reply-To"] = replyToAddress msg["To"] = toAddress msg["Date"] = rfc822date() msgId = messageid() msg["Message-ID"] = msgId msgAlt = MIMEMultipart("alternative") msg.attach(msgAlt) # plain version msgPlain = MIMEText(plainText, "plain", "UTF-8") msgAlt.attach(msgPlain) # html version msgHtmlRelated = MIMEMultipart("related", type="text/html") msgAlt.attach(msgHtmlRelated) msgHtml = MIMEText(htmlText, "html", "UTF-8") msgHtmlRelated.attach(msgHtml) # the icalendar attachment # Make sure we always have the timezones used in the calendar data as iMIP requires VTIMEZONE # always be present (i.e., timezones-by-reference is not allowed in iMIP). calendarText = calendar.getTextWithTimezones(includeTimezones=True) self.log.debug("Mail gateway sending calendar body: %s" % (calendarText, )) msgIcal = MIMEText(calendarText, "calendar", "UTF-8") method = calendar.propertyValue("METHOD").lower() msgIcal.set_param("method", method) msgIcal.add_header("Content-ID", "<invitation.ics>") msgIcal.add_header("Content-Disposition", "inline;filename=invitation.ics") msg.attach(msgIcal) return msgId, msg.as_string()
def parseOptions(argv): o = Options() o.to = [e for e in argv if not e.startswith("-")] o.sender = getlogin() # Just be very stupid # Skip -bm -- it is the default # Add a non-standard option for querying the version of this tool. if "--version" in argv: print("mailmail version:", version) raise SystemExit() # -bp lists queue information. Screw that. if "-bp" in argv: raise _unsupportedOption # -bs makes sendmail use stdin/stdout as its transport. Screw that. if "-bs" in argv: raise _unsupportedOption # -F sets who the mail is from, but is overridable by the From header if "-F" in argv: o.sender = argv[argv.index("-F") + 1] o.to.remove(o.sender) # -i and -oi makes us ignore lone "." if ("-i" in argv) or ("-oi" in argv): raise _unsupportedOption # -odb is background delivery if "-odb" in argv: o.background = True else: o.background = False # -odf is foreground delivery if "-odf" in argv: o.background = False else: o.background = True # -oem and -em cause errors to be mailed back to the sender. # It is also the default. # -oep and -ep cause errors to be printed to stderr if ("-oep" in argv) or ("-ep" in argv): o.printErrors = True else: o.printErrors = False # -om causes a copy of the message to be sent to the sender if the sender # appears in an alias expansion. We do not support aliases. if "-om" in argv: raise _unsupportedOption # -t causes us to pick the recipients of the message from # the To, Cc, and Bcc headers, and to remove the Bcc header # if present. if "-t" in argv: o.recipientsFromHeaders = True o.excludeAddresses = o.to o.to = [] else: o.recipientsFromHeaders = False o.exludeAddresses = [] requiredHeaders = { "from": [], "to": [], "cc": [], "bcc": [], "date": [], } buffer = StringIO() while 1: write = 1 line = sys.stdin.readline() if not line.strip(): break hdrs = line.split(": ", 1) hdr = hdrs[0].lower() if o.recipientsFromHeaders and hdr in ("to", "cc", "bcc"): o.to.extend([email.utils.parseaddr(hdrs[1])[1]]) if hdr == "bcc": write = 0 elif hdr == "from": o.sender = email.utils.parseaddr(hdrs[1])[1] if hdr in requiredHeaders: requiredHeaders[hdr].append(hdrs[1]) if write: buffer.write(line) if not requiredHeaders["from"]: buffer.write("From: {}\r\n".format(o.sender)) if not requiredHeaders["to"]: if not o.to: raise SystemExit("No recipients specified.") buffer.write("To: {}\r\n".format(", ".join(o.to))) if not requiredHeaders["date"]: buffer.write("Date: {}\r\n".format(smtp.rfc822date())) buffer.write(line) if o.recipientsFromHeaders: for a in o.excludeAddresses: try: o.to.remove(a) except BaseException: pass buffer.seek(0, 0) o.body = StringIO(buffer.getvalue() + sys.stdin.read()) return o
def receivedHeader(self, helo, origin, recipients): myHostname, clientIP = helo headerValue = "by %s from %s with ESMTP ; %s" % ( myHostname, clientIP, smtp.rfc822date()) # email.Header.Header used for automatic wrapping of long lines return "Received: %s" % Header(headerValue)
def _format_smtp_message(from_addr, to_addr, subject, content, attachments): # # The central problem in formatting SMTP messages correctly is to support # non-US-ASCII characters correctly. The solution here simply mimics what # Thunderbird (Icedove) does when sending a message containing both ISO 8859-1 # and full Unicode characters. # # The solution for headers and content is unfortunately different. # # # ESMTP: # * http://www.ietf.org/rfc/rfc2821.txt # * http://www.ietf.org/rfc/rfc2822.txt # # MIME (cannot send other an US-ASCII with 2822 format): # * http://en.wikipedia.org/wiki/MIME # * http://en.wikipedia.org/wiki/Unicode_and_e-mail # * http://www.ietf.org/rfc/rfc2045.txt # * http://www.ietf.org/rfc/rfc2046.txt # * http://www.ietf.org/rfc/rfc2048.txt # * http://www.ietf.org/rfc/rfc2049.txt # * http://www.ietf.org/rfc/rfc2183.txt # FIXME: some problems with mixed UTF vs. non-UTF characters in header. # escape all? def _hdrescape(x): res = '' for i in xrange(len(x)): c = x[i] ci = ord(c) if (ci in [0x0a, 0x0d]): # suppress in headers pass elif (ci >= 0x20 and ci <= 0x7e): res += c else: # See: http://en.wikipedia.org/wiki/MIME#Encoded-Word utf = c.encode('utf-8') res += '=?UTF-8?Q?' for j in xrange(len(utf)): res += '=%02X' % ord(utf[j]) res += '?=' return res def _bodyescape(x): res = '' for i in xrange(len(x)): c = x[i] ci = ord(c) if (ci >= 0x20 and ci <= 0x7e) or (ci in [0x0a, 0x0d]): res += c else: utf = c.encode('utf-8') for j in xrange(len(utf)): res += '=%02X' % ord(utf[j]) return res # Check sanity # # No checks are done for attachments at the moment. The attachments are I/O objects # so we don't know their size off hand. However, below, when we're creating a MIME # message, we'll limit the attachment size. if (len(from_addr) > STRING_SANITY) or \ (len(to_addr) > STRING_SANITY) or \ (len(subject) > STRING_SANITY) or \ (len(content) > MAX_CONTENT_SIZE): raise Exception('parameter sanity check failed') # Escape from and to addresses - XXX: no support for non-ascii email addresses right now from_addr = from_addr.encode('ascii') to_addr = to_addr.encode('ascii') # Start building MIME message into a string I/O object fp = cStringIO.StringIO() mw = MimeWriter.MimeWriter(fp) mw.addheader('From', _hdrescape(from_addr)) mw.addheader('To', _hdrescape(to_addr)) mw.addheader('Subject', _hdrescape(subject)) mw.addheader('Date', smtp.rfc822date()) mw.addheader('Message-ID', smtp.messageid()) mw.addheader('MIME-Version', '1.0') # Add body and possibly attachments if len(attachments.keys()) == 0: # XXX: using 'plist' of startbody() results in multiline encoding, which I dislike mw.addheader('Content-Transfer-Encoding', 'quoted-printable') mw.addheader('Content-Disposition', 'inline') mw.flushheaders() f = mw.startbody('text/plain; charset=UTF-8') # XXX: format=flowed? f.write(_bodyescape(content)) else: mw.flushheaders() mw.startmultipartbody('mixed') f = mw.nextpart() f.addheader('Content-Disposition', 'inline') f.addheader('Content-Transfer-Encoding', 'quoted-printable') f.flushheaders() f2 = f.startbody('text/plain; charset=UTF-8') # XXX: format=flowed? f2.write(_bodyescape(content)) for i in attachments.keys(): f = mw.nextpart() f.addheader('Content-Disposition', 'inline; filename=%s' % i) # FIXME: filter / escape filenames f.addheader('Content-Transfer-Encoding', 'base64') f.flushheaders() mimetype, encoding = mimetypes.guess_type(i) f2 = f.startbody(mimetype) fdata = attachments[i] # We read the attachment into a variable here for base64 encoding (and # size check), this may take several megabytes of temporary memory. t = fdata.read(MAX_ATTACHMENT_SIZE + 1) if len(t) > MAX_ATTACHMENT_SIZE: raise Exception('attachment too long') f2.write(t.encode('base64')) mw.lastpart() # Done, convert to string and we're done return fp.getvalue()
def mxServerFound(mxServer, session): print "[CrashlogAutoSubmit] - mxServerFound -->", mxServer crashLogFilelist = [] message = StringIO.StringIO() writer = MimeWriter.MimeWriter(message) mailFrom = "*****@*****.**" mailTo = "*****@*****.**" subject = "Automatically generated crashlogmail" # Define the main body headers. writer.addheader( 'To', "dream-multimedia-crashlogs <*****@*****.**>") writer.addheader( 'From', "CrashlogAutoSubmitter <*****@*****.**>") writer.addheader('Subject', str(subject)) writer.addheader('Date', smtp.rfc822date()) if config.plugins.crashlogautosubmit.attachemail.value is True: if str(config.plugins.crashlogautosubmit.email.value ) != "*****@*****.**": writer.addheader( 'Reply-To', str(str(config.plugins.crashlogautosubmit.email.value))) writer.addheader('MIME-Version', '1.0') writer.startmultipartbody('mixed') # start with a text/plain part part = writer.nextpart() body = part.startbody('text/plain') part.flushheaders() # Define the message body body_text1 = "\nHello\n\nHere are some crashlogs i found for you.\n" if str(config.plugins.crashlogautosubmit.email.value ) == "*****@*****.**": user_email = "" else: user_email = "\nUser supplied email address: " + str( config.plugins.crashlogautosubmit.email.value) if str(config.plugins.crashlogautosubmit.name.value) == "Dreambox User": user_name = "" else: user_name = "\n\nOptional supplied name: " + str( config.plugins.crashlogautosubmit.name.value) body_text2 = "\n\nThis is an automatically generated email from the CrashlogAutoSubmit plugin.\n\n\nHave a nice day.\n" body_text = body_text1 + user_email + user_name + body_text2 body.write(body_text) list = ((_("Yes"), "send"), (_("Yes, and don't ask again"), "send_always"), (_("No, not now"), "send_not"), (_("No, send them never"), "send_never")) def handleError(error): print "[CrashlogAutoSubmit] - Message send Error -->", error.getErrorMessage( ) def handleSuccess(result): print "[CrashlogAutoSubmit] - Message sent successfully -->", result if len(crashLogFilelist): for crashlog in crashLogFilelist: if config.plugins.crashlogautosubmit.sendlog.value == "delete": os.remove(crashlog) elif config.plugins.crashlogautosubmit.sendlog.value == "rename": currfilename = str(os.path.basename(crashlog)) newfilename = "/media/hdd/" + currfilename + ".sent" os.rename(crashlog, newfilename) def send_mail(): print "[CrashlogAutoSubmit] - send_mail" if len(crashLogFilelist): for crashlog in crashLogFilelist: filename = str(os.path.basename(crashlog)) subpart = writer.nextpart() subpart.addheader("Content-Transfer-Encoding", 'base64') subpart.addheader("Content-Disposition", 'attachment; filename="%s"' % filename) subpart.addheader('Content-Description', 'Enigma2 crashlog') body = subpart.startbody( "%s; name=%s" % ('application/octet-stream', filename)) mimetools.encode(open(crashlog, 'rb'), body, 'base64') writer.lastpart() sending = smtp.sendmail(str(mxServer), mailFrom, mailTo, message.getvalue()) sending.addCallback(handleSuccess).addErrback(handleError) def handleAnswer(answer): answer = answer and answer[1] print "[CrashlogAutoSubmit] - handleAnswer --> ", answer if answer == "send": send_mail() elif answer == "send_always": config.plugins.crashlogautosubmit.sendmail.value = "send_always" config.plugins.crashlogautosubmit.sendmail.save() config.plugins.crashlogautosubmit.save() config.plugins.save() config.save() send_mail() elif answer in (None, "send_never"): config.plugins.crashlogautosubmit.sendmail.value = "send_never" config.plugins.crashlogautosubmit.sendmail.save() config.plugins.crashlogautosubmit.save() config.plugins.save() config.save() elif answer == "send_not": print "[CrashlogAutoSubmit] - not sending crashlogs for this time." for crashlog in os.listdir('/media/hdd'): if crashlog.startswith("enigma2_crash_") and crashlog.endswith(".log"): print "[CrashlogAutoSubmit] - found crashlog: ", os.path.basename( crashlog) crashLogFilelist.append('/media/hdd/' + crashlog) if len(crashLogFilelist): if config.plugins.crashlogautosubmit.sendmail.value == "send": Notifications.AddNotificationWithCallback( handleAnswer, ChoiceBox, title=_("Crashlogs found!\nSend them to Dream Multimedia?"), list=list) elif config.plugins.crashlogautosubmit.sendmail.value == "send_always": send_mail() else: print "[CrashlogAutoSubmit] - no crashlogs found."
def receivedHeader(self, helo, origin, recipients): myHostname, clientIP = helo headerValue = 'by {} from {} with SMTP ; {}'.format( myHostname, clientIP, smtp.rfc822date()) # this line creates the second "received" line. should probably be commented out return 'Received: {}'.format(Header(headerValue))