def check_for_msn_groups_headers(self, msg, target=None): """Check if the email's destination is a msn group""" to = ''.join(msg.get_decoded_header('To')) if not Regex(r"<(\S+)\@groups\.msn\.com>").search(to): return False listname = Regex(r"<(\S+)\@groups\.msn\.com>").match(to).groups()[0] server_rgx = Regex(r"from mail pickup service by " r"((?:p\d\d\.)groups\.msn\.com)\b") server = '' for rcvd in msg.get_decoded_header('Received'): if server_rgx.search(rcvd): server = server_rgx.search(rcvd).groups()[0] break if not server: return False message_id = ''.join(msg.get_decoded_header('Message-Id')) if listname == "notifications": if not Regex(r"^<\S+\@{0}".format(server)).search(message_id): return False else: msn_addr = Regex(r"^<{0}-\S+\@groups\.msn\.com>".format(listname)) if not msn_addr.search(message_id): return False msn_addr = "{0}[email protected]".format(listname) if msg.sender_address != msn_addr: return False return True
def check_freemail_header(self, msg, header, regex=None, target=None): """Check all possible 'from' headers to see if sender is freemail. It is possible to provide a regex rule to match against too. Returns True if it is or False otherwise """ self.ctxt.log.debug("FreeMail::Plugin check_freemail_header" " %s", 'with regex: ' + regex if regex else '') if not header: self.ctxt.log.warn("FreeMail::Plugin check_freemail_header" " requires an argument") return False if regex: try: check_re = Regex(regex).compile() except re.error: self.ctxt.log.warn("FreeMail::Plugin check_freemail_header" " regex error") return False else: check_re = None if not msg.msg.get(header, None): self.ctxt.log.debug( "FreeMail::Plugin check_freemail_header" " header: %s not found", header) return False header_emails = self.get_global('email_re').findall(msg.msg[header]) if not header_emails: self.ctxt.log.debug( "FreeMail::Plugin check_freemail_header" " no emails found in header: %s", header) return False for email in header_emails: if self._is_freemail(email): if check_re and not check_re.search(email): return False elif check_re and check_re.search(email): self.ctxt.log.debug( "FreeMail::Plugin check_freemail_header" " HIT! %s is freemail and matches regex", email) result = ("Header " + header + " is freemail and matches regex") if self["freemail_add_describe_email"]: _email = "(" + email.replace("@", "[at]") + ")" result = result + "\n\t" + _email return str(result) self.ctxt.log.debug( "FreeMail::Plugin check_freemail_header" " HIT! %s is freemail", email) result = "Header " + header + " is freemail" if self["freemail_add_describe_email"]: _email = "(" + email.replace("@", "[at]") + ")" result = result + "\n\t" + _email return str(result) return False
def check_freemail_from(self, msg, regex=None, target=None): """Check if in specified header gave as parameter is a freemail or no. It is possible to provide a regex rule to match against too. Returns True if it is or False otherwise """ self.ctxt.log.debug( "FreeMail::Plugin Eval rule check_freemail_from" " %s", 'with regex: ' + regex if regex else '') all_from_headers = [ 'From', 'Envelope-Sender', 'Resent-Sender', 'X-Envelope-From', 'EnvelopeFrom', 'Resent-From' ] header_emails = [] if regex: try: check_re = Regex(regex) except re.error: self.ctxt.log.warn("FreeMail::Plugin check_freemail_from" " regex error") return False else: check_re = None header_emails = msg.get_all_from_headers_addr() header_emails = sorted(set(header_emails)) if not header_emails: self.ctxt.log.debug( "FreeMail::Plugin check_freemail_from" " no emails found in from headers: %s", all_from_headers) return False for email in header_emails: if self._is_freemail(email): if check_re and not check_re.search(email): return False elif check_re and check_re.search(email): self.ctxt.log.debug( "FreeMail::Plugin check_freemail_from" " HIT! %s is freemail and matches regex", email) result = "Sender address is freemail and matches regex" if self["freemail_add_describe_email"]: _email = "(" + email.replace("@", "[at]") + ")" result = result + "\n\t" + _email return str(result) self.ctxt.log.debug( "FreeMail::Plugin check_freemail_from" " HIT! %s is freemail", email) result = "Sender address is freemail" if self["freemail_add_describe_email"]: _email = "(" + email.replace("@", "[at]") + ")" result = result + "\n\t" + _email return str(result) return False
def check_freemail_body(self, msg, regex=None, target=None): """ Check if there are free emails in body parts of the message """ self.ctxt.log.debug("FreeMail::Plugin check_freemail_body" " %s", 'with regex: ' + regex if regex else '') body_emails = self.get_global('body_emails') if not len(body_emails): self.ctxt.log.debug("FreeMail::Plugin check_freemail_body " "No emails found in body of the message") return False if regex: try: check_re = Regex(regex).compile() except re.error: self.ctxt.log.warn("FreeMail::Plugin check_freemail_from" " regex error") return False else: check_re = None if not self._parse_body(): return False if check_re: for email in self.get_global("freemail_body_emails"): if check_re.search(email): self.ctxt.log.debug( "FreeMail::Plugin check_freemail_body" " HIT! %s is freemail and matches regex", email) result = "Address from body is freemail and matches regex" if self["freemail_add_describe_email"]: _email = "(" + email.replace("@", "[at]") + ")" result = result + "\n\t" + _email return str(result) else: if len(self.get_global("freemail_body_emails")): emails = " ,".join(self.get_global("freemail_body_emails")) self.ctxt.log.debug( "FreeMail::Plugin check_freemail_body" " HIT! body has freemails: %s", emails) result = "Body has freemails" if self["freemail_add_describe_email"]: _emails = "(" + emails.replace("@", "[at]") + ")" result = result + "\n\t" + _emails return str(result) return False
def check_start(self, msg): """Verify that the domains are valid and separate wildcard domains from the rest.""" domain_re = Regex(r'^[a-z0-9.*?-]+$') freemail_domains = self.get_global('freemail_domains') freemail_temp_wc = [] for domain in freemail_domains[:]: if not domain_re.search(domain): freemail_domains.remove(domain) self.ctxt.log.warn( "FreeMail::Plugin Invalid freemail domain: %s", domain) if '*' in domain: temp = domain.replace('.', '\.') temp = temp.replace('?', '.') temp = temp.replace('*', '[^.]*') freemail_temp_wc.append(temp) if freemail_temp_wc: wild_doms = r'\@(?:{0})$'.format('|'.join(freemail_temp_wc)) self.set_global('freemail_domains_re', Regex(wild_doms)) self.set_global('freemail_domains', freemail_domains) valid_tlds = (self.get_global('util_rb_tld') + self.get_global('util_rb_2tld') + self.get_global('util_rb_3tld')) tlds_re = r'(?:{0})'.format("|".join(valid_tlds)) email_re = Regex( r""" (?=.{{0,64}}\@) # limit userpart to 64 chars (and speed up searching?) (?<![a-z0-9!#\$%&'*+\/=?^_`{{|}}~-]) # start boundary ( # capture email [a-z0-9!#\$%&'*+\/=?^_`{{|}}~-]+ # no dot in beginning (?:\.[a-z0-9!#\$%&'*+\/=?^_`{{|}}~-]+)* # no consecutive dots, no ending dot \@ (?:[a-z0-9](?:[a-z0-9-]{{0,59}}[a-z0-9])?\.){{1,4}} # max 4x61 char parts (should be enough?) {tld} # ends with valid tld ) (?!(?:[a-z0-9-]|\.[a-z0-9])) # make sure domain ends here """.format(tld=tlds_re), re.X | re.I) self.set_global('email_re', email_re) self.set_global('body_emails', set()) self.set_global("check_if_parsed", False)