def examine(self,suspect): try: tablename=self.config.get(self.section,'table') sender=suspect.get_value('sender') if sender is not None: from_address=strip_address(sender) from_domain=extract_domain(from_address) else: from_address=None from_domain=None recipient=suspect.get_value('recipient') if recipient is not None: to_address=strip_address(recipient) to_domain=extract_domain(to_address) else: to_address=None to_domain=None fields=suspect.values.copy() fields['from_address']=from_address fields['from_domain']=from_domain fields['to_address']=to_address fields['to_domain']=to_domain fields['timestamp']=suspect.timestamp #build query fieldmap=self.get_fieldmap() requiredcolumnnames=fieldmap.keys() dbcolumns=",".join(requiredcolumnnames) placeholders=",".join(map(lambda x:u':'+x, requiredcolumnnames)) sql_insert="INSERT INTO %s (%s) VALUES (%s)"%(tablename,dbcolumns,placeholders) # #fill the required vars into new dict with the db columns data={} for col in requiredcolumnnames: postfixfieldname=fieldmap[col] if postfixfieldname in fields: #a fiew fields are numeric.. convert them if postfixfieldname in ['recipient_count','size','encryption_keysize']: data[col]=int(fields[postfixfieldname]) else: data[col]=fields[postfixfieldname] else: data[col]=None #print sql_insert #print data conn=get_session(self.config.get(self.section,'dbconnection')) conn.execute(sql_insert,data) except Exception as e: self.logger.error("DB Writer plugin failed, Log not written. : %s"%str(e)) return DUNNO,None
def examine(self,suspect): try: tablename=self.config.get(self.section,'table') sender=suspect.get_value('sender') if sender is not None: from_address=strip_address(sender) from_domain=extract_domain(from_address) else: from_address=None from_domain=None recipient=suspect.get_value('recipient') if recipient is not None: to_address=strip_address(recipient) to_domain=extract_domain(to_address) else: to_address=None to_domain=None fields=suspect.values.copy() fields['from_address']=from_address fields['from_domain']=from_domain fields['to_address']=to_address fields['to_domain']=to_domain fields['timestamp']=suspect.timestamp #build query fieldmap=self.get_fieldmap() requiredcolumnnames=fieldmap.keys() dbcolumns=",".join(requiredcolumnnames) placeholders=",".join(map(lambda x:u':'+x, requiredcolumnnames)) sql_insert="INSERT INTO %s (%s) VALUES (%s)"%(tablename,dbcolumns,placeholders) # #fill the required vars into new dict with the db columns data={} for col in requiredcolumnnames: postfixfieldname=fieldmap[col] if postfixfieldname in fields: #a fiew fields are numeric.. convert them if postfixfieldname in ['recipient_count','size','encryption_keysize']: data[col]=int(fields[postfixfieldname]) else: data[col]=fields[postfixfieldname] else: data[col]=None #print sql_insert #print data conn=get_session(self.config.get(self.section,'dbconnection')) conn.execute(sql_insert,data) except Exception as e: self.logger.error("DB Writer plugin failed, Log not written. : %s"%str(e)) return DUNNO
def examine(self, suspect): if not SQLALCHEMY_AVAILABLE: return DUNNO from_address = suspect.get_value('sender') if from_address is None: self.logger.warning('No FROM address found') return DEFER_IF_PERMIT, 'internal policy error (no from address)' from_address = strip_address(from_address) try: from_domain = extract_domain(from_address) except ValueError as e: self.logger.warning(str(e)) return DUNNO to_address = suspect.get_value('recipient') if to_address is None: self.logger.warning('No RCPT address found') return DEFER_IF_PERMIT, 'internal policy error (no rcpt address)' to_address = strip_address(to_address) to_domain = extract_domain(to_address) listings = self._get_listings() result = DUNNO message = None compare = '' found = False for check in LISTING_TYPES: for cmp_value in check['cmp']: if cmp_value == 'to_address': compare = to_address elif cmp_value == 'from_address': compare = from_address elif cmp_value == 'from_domain': compare = from_domain if compare is None: compare = '' for scope in [GLOBALSCOPE, '%%%s' % to_domain, to_address]: if self._check_list(check['name'], listings, scope, compare): result = self._get_action(check['name']) message = self._get_message(check['name']) found = True break if found: break if found: break return result, message
def examine(self,suspect): if not SQLALCHEMY_AVAILABLE: return DUNNO from_address=suspect.get_value('sender') if from_address is None: self.logger.warning('No FROM address found') return DEFER_IF_PERMIT,'internal policy error (no from address)' from_address=strip_address(from_address) try: from_domain = extract_domain(from_address) except ValueError as e: self.logger.warning(str(e)) return DUNNO to_address=suspect.get_value('recipient') if to_address is None: self.logger.warning('No RCPT address found') return DEFER_IF_PERMIT,'internal policy error (no rcpt address)' to_address=strip_address(to_address) to_domain=extract_domain(to_address) listings = self._get_listings() result = DUNNO message = None compare = '' found = False for check in LISTING_TYPES: for cmp_value in check['cmp']: if cmp_value == 'to_address': compare = to_address elif cmp_value == 'from_address': compare = from_address elif cmp_value == 'from_domain': compare = from_domain if compare is None: compare = '' for scope in [GLOBALSCOPE, '%%%s' % to_domain, to_address]: if self._check_list(check['name'], listings, scope, compare): result = self._get_action(check['name']) message = self._get_message(check['name']) found = True break if found: break if found: break return result, message
def examine(self, suspect): if not HAVE_DNS: return DUNNO from_address = suspect.get_value('sender') if from_address is None: self.logger.warning('No FROM address found') return DEFER_IF_PERMIT, 'internal policy error (no from address)' from_address = strip_address(from_address) from_domain = extract_domain(from_address) if self._is_whitelisted(from_domain): return DUNNO from_address = self._email_normalise(from_address) addr_hash = self._create_hash(from_address) listed, message = self._ebl_lookup(addr_hash) if listed: values = { 'dnszone': self.config.get(self.section, 'dnszone', '').strip(), 'message': message, } message = apply_template( self.config.get(self.section, 'messagetemplate'), suspect, values) return REJECT, message else: return DUNNO
def examine(self, suspect): if not DNSQUERY_EXTENSION_ENABLED: return DUNNO from_address=suspect.get_value('sender') if from_address is None: self.logger.warning('No FROM address found') return DEFER_IF_PERMIT,'internal policy error (no from address)' from_address=strip_address(from_address) if self.config.getboolean(self.section,'check_srs_only') and not self._is_srs(from_address): self.logger.info('skipping non SRS address %s' % from_address) return DUNNO if HAVE_SRS and self.config.getboolean(self.section,'decode_srs'): from_address = self._decode_srs(from_address) from_domain=extract_domain(from_address) if self._is_whitelisted(from_domain): return DUNNO from_address = self._email_normalise(from_address) addr_hash = self._create_hash(from_address) listed, message = self._ebl_lookup(addr_hash) if listed: values = { 'dnszone': self.config.get(self.section,'dnszone','').strip(), 'message': message, } message = apply_template(self.config.get(self.section,'messagetemplate'),suspect, values) return REJECT, message else: return DUNNO
def _examine_spf(self, suspect, client_address, client_name): from_address = suspect.get_value('sender') if from_address is None: self.logger.warning('No FROM address found') return DEFER_IF_PERMIT, 'internal policy error (no from address)' from_address = strip_address(from_address) from_domain = extract_domain(from_address) if not self.spfrules: datafile = self.config.get('EnforceMX', 'datafile_spf') if os.path.exists(datafile): self.spfrules = RulesCache(datafile) else: return DUNNO, None action = DUNNO message = None if not self.spfrules.permitted(from_domain, client_address, client_name): action = REJECT message = 'We do not accept mail for %s from %s with name %s. Please use the official mail servers!' % ( from_domain, client_address, client_name) return action, message
def examine(self,suspect): if not have_spf: return DUNNO client_address=suspect.get_value('client_address') if client_address is None: self.logger.error('No client address found') return DUNNO if have_netaddr: ip_whitelist=self.config.get('SPFPlugin','ip_whitelist') ip_whitelist=[IPNetwork(i.strip()) for i in ip_whitelist.split(',')] for net in ip_whitelist: if IPAddress(client_address) in net: return DUNNO sender=suspect.get_value('sender') if sender is None: self.logger.warning('No RCPT address found') return DEFER_IF_PERMIT,'internal policy error (no from address)' sender_email = strip_address(sender) sender_domain = extract_domain(sender_email) domain_whitelist=self.config.get('SPFPlugin','domain_whitelist') domain_whitelist=[i.strip() for i in domain_whitelist.split(',')] if sender_domain in domain_whitelist: return DUNNO helo_name=suspect.get_value('helo_name') if helo_name is None: self.logger.error('No SMTP HELO name found') return DUNNO on_softfail=self.config.get('SPFPlugin','on_softfail') softfail = DUNNO if on_softfail == 'DEFER': softfail = DEFER_IF_PERMIT on_softerror=self.config.get('SPFPlugin','on_softerror') softerror = DUNNO if on_softerror == 'REJECT': softerror = REJECT result, explanation = spf.check2(client_address, sender_email, helo_name) self.logger.debug('Postomaat SPF check: ip: %s, from: %s, helo: %s, result: %s' % (client_address, sender_email, helo_name, result)) action = DUNNO message = None if result == 'fail': action = REJECT message = explanation elif result == 'temperror': action = DEFER_IF_PERMIT message = explanation elif result == 'softfail' and softfail != DUNNO: action = softfail message = explanation elif result == 'softerror' and softerror != DUNNO: action = softerror message = explanation return action, message
def examine(self, suspect): if not HAVE_SPF: return DUNNO client_address = suspect.get_value('client_address') helo_name = suspect.get_value('helo_name') sender = suspect.get_value('sender') if client_address is None or helo_name is None or sender is None: self.logger.error('missing client_address or helo or sender') return DUNNO if self.ip_whitelisted(client_address): self.logger.info("Client %s is whitelisted - no SPF check" % client_address) return DUNNO sender_email = strip_address(sender) if sender_email == '' or sender_email is None: return DUNNO sender_domain = extract_domain(sender_email) if sender_domain is None: self.logger.error('no domain found in sender address %s' % sender_email) return DUNNO if not self.check_this_domain(sender_domain): self.logger.debug('skipping SPF check for %s' % sender_domain) return DUNNO result, explanation = spf.check2(client_address, sender_email, helo_name) suspect.tags['spf'] = result if result != 'none': self.logger.info( 'SPF client=%s, sender=%s, h=%s result=%s : %s' % (client_address, sender_email, helo_name, result, explanation)) action = DUNNO message = apply_template( self.config.get(self.section, 'messagetemplate'), suspect, dict(result=result, explanation=explanation)) configopt = 'on_%s' % result if self.config.has_option(self.section, configopt): action = string_to_actioncode( self.config.get(self.section, configopt)) return action, message
def examine(self, suspect): encryption_protocol = suspect.get_value('encryption_protocol') recipient=suspect.get_value('recipient') rcpt_email = strip_address(recipient) if rcpt_email=='' or rcpt_email is None: return DUNNO enforce = self.enforce_domain(extract_domain(rcpt_email)) action = DUNNO message = None if enforce and encryption_protocol == '': action=string_to_actioncode(self.config.get(self.section, 'action')) message = apply_template(self.config.get(self.section,'messagetemplate'),suspect) return action, message
def examine(self,suspect): if not have_spf: return DUNNO client_address=suspect.get_value('client_address') helo_name=suspect.get_value('helo_name') sender=suspect.get_value('sender') if client_address is None or helo_name is None or sender is None: self.logger.error('missing client_address or helo or sender') return DUNNO if self.ip_whitelisted(client_address): self.logger.info("Client %s is whitelisted - no SPF check"%client_address) return DUNNO sender_email = strip_address(sender) if sender_email=='' or sender_email is None: return DUNNO selective_sender_domain_file=self.config.get(self.section,'domain_selective_spf_file') if selective_sender_domain_file!='': if self.selective_domain_loader is None: self.selective_domain_loader=FileList(selective_sender_domain_file,lowercase=True) try: sender_domain = extract_domain(sender_email) if sender_domain is None: return DUNNO except ValueError as e: self.logger.warning(str(e)) return DUNNO if not sender_domain.lower() in self.selective_domain_loader.get_list(): return DUNNO result, explanation = spf.check2(client_address, sender_email, helo_name) suspect.tags['spf']=result if result!='none': self.logger.info('SPF client=%s, sender=%s, h=%s result=%s : %s' % (client_address, sender_email, helo_name, result,explanation)) action = DUNNO message = apply_template(self.config.get(self.section,'messagetemplate'),suspect,dict(result=result,explanation=explanation)) configopt='on_%s'%result if self.config.has_option(self.section,configopt): action=self.config.get(self.section,configopt) return action, message
def examine(self,suspect): if not HAVE_SPF: return DUNNO client_address=suspect.get_value('client_address') helo_name=suspect.get_value('helo_name') sender=suspect.get_value('sender') if client_address is None or helo_name is None or sender is None: self.logger.error('missing client_address or helo or sender') return DUNNO if self.ip_whitelisted(client_address): self.logger.info("Client %s is whitelisted - no SPF check"%client_address) return DUNNO sender_email = strip_address(sender) if sender_email=='' or sender_email is None: return DUNNO sender_domain = extract_domain(sender_email) if sender_domain is None: self.logger.error('no domain found in sender address %s' % sender_email) return DUNNO if not self.check_this_domain(sender_domain): self.logger.debug('skipping SPF check for %s' % sender_domain) return DUNNO result, explanation = spf.check2(client_address, sender_email, helo_name) suspect.tags['spf'] = result if result != 'none': self.logger.info('SPF client=%s, sender=%s, h=%s result=%s : %s' % (client_address, sender_email, helo_name, result,explanation)) action = DUNNO message = apply_template(self.config.get(self.section, 'messagetemplate'), suspect, dict(result=result, explanation=explanation)) configopt = 'on_%s' % result if self.config.has_option(self.section, configopt): action=string_to_actioncode(self.config.get(self.section, configopt)) return action, message
def examine(self, suspect): if not DNSQUERY_EXTENSION_ENABLED: return DUNNO from_address = suspect.get_value('sender') if from_address is None: self.logger.warning('No FROM address found') return DEFER_IF_PERMIT, 'internal policy error (no from address)' from_address = strip_address(from_address) if self.config.getboolean( self.section, 'check_srs_only') and not self._is_srs(from_address): self.logger.info('skipping non SRS address %s' % from_address) return DUNNO if HAVE_SRS and self.config.getboolean(self.section, 'decode_srs'): from_address = self._decode_srs(from_address) from_domain = extract_domain(from_address) if self._is_whitelisted(from_domain): return DUNNO from_address = self._email_normalise(from_address) addr_hash = self._create_hash(from_address) listed, message = self._ebl_lookup(addr_hash) if listed: values = { 'dnszone': self.config.get(self.section, 'dnszone', '').strip(), 'message': message, } message = apply_template( self.config.get(self.section, 'messagetemplate'), suspect, values) return REJECT, message else: return DUNNO
def _examine_spf(self, suspect, client_address, client_name): from_address=suspect.get_value('sender') if from_address is None: self.logger.warning('No FROM address found') return DEFER_IF_PERMIT,'internal policy error (no from address)' from_address=strip_address(from_address) from_domain=extract_domain(from_address) if not self.spfrules: datafile = self.config.get('EnforceMX', 'datafile_spf') if os.path.exists(datafile): self.spfrules = RulesCache(datafile) else: return DUNNO,None action = DUNNO message = None if not self.spfrules.permitted(from_domain, client_address, client_name): action = REJECT message = 'We do not accept mail for %s from %s with name %s. Please use the official mail servers!' % (from_domain, client_address, client_name) return action, message
def _examine_mx(self, suspect, client_address, client_name): to_address=suspect.get_value('recipient') if to_address is None: self.logger.warning('No RCPT address found') return DEFER_IF_PERMIT,'internal policy error (no rcpt address)' to_address=strip_address(to_address) to_domain=extract_domain(to_address) if not self.mxrules: datafile = self.config.get('EnforceMX','datafile_mx') if os.path.exists(datafile): self.mxrules = RulesCache(datafile) else: return DUNNO,None action = DUNNO message = None if not self.mxrules.permitted(to_domain, client_address, client_name): action = REJECT message = 'We do not accept mail for %s from %s. Please send to MX records!' % (to_domain, client_address) return action, message