Beispiel #1
0
 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
Beispiel #2
0
 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
Beispiel #4
0
    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
Beispiel #5
0
    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
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #8
0
 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
Beispiel #9
0
    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
Beispiel #10
0
    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
Beispiel #11
0
    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
Beispiel #12
0
    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
Beispiel #13
0
    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
Beispiel #14
0
    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
Beispiel #15
0
 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
Beispiel #16
0
 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
Beispiel #17
0
 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