Ejemplo n.º 1
0
    def test_global_override(self):
        """Test basic config overrdide functionality"""
        suspect = Suspect(u'*****@*****.**',
                          '*****@*****.**', '/dev/null')

        candidate = DBConfig(self.config, suspect)

        candidate.add_section('testsection')
        candidate.set('testsection', 'nooverride', '100')
        candidate.set('testsection', 'override', '100')

        self.clear_table()
        self.insert_override('*****@*****.**', 'testsection',
                             'override', '200')
        self.insert_override('%unittests.fuglu.org', 'testsection', 'override',
                             '300')
        self.insert_override('$GLOBAL', 'testsection', 'override', '400')
        self.assertEqual(int(candidate.get('testsection', 'nooverride')), 100)
        self.assertEqual(int(candidate.get('testsection', 'override')), 400)
Ejemplo n.º 2
0
    def examine(self, suspect):
        if self.rulescache is None:
            self.rulescache = RulesCache(
                self.config.get(self.section, 'rulesdir'))

        self.blockedfiletemplate = self.config.get(self.section,
                                                   'template_blockedfile')

        runtimeconfig = DBConfig(self.config, suspect)
        self.checkarchivenames = runtimeconfig.getboolean(
            self.section, 'checkarchivenames')
        self.checkarchivecontent = runtimeconfig.getboolean(
            self.section, 'checkarchivecontent')
        self.sendbounce = runtimeconfig.getboolean(self.section, 'sendbounce')

        enabledarchivetypes = runtimeconfig.get(self.section,
                                                'enabledarchivetypes')
        if enabledarchivetypes:
            enabled = [t.strip() for t in enabledarchivetypes.split(',')]
            for archtype in self.supported_archive_extensions.keys():
                if archtype not in enabled:
                    del self.supported_archive_extensions[archtype]

        returnaction = self.walk(suspect)
        return returnaction
Ejemplo n.º 3
0
    def examine(self, suspect):
        if self.rulescache is None:
            self.rulescache = RulesCache(
                self.config.get(self.section, 'rulesdir'))

        self.blockedfiletemplate = self.config.get(
            self.section, 'template_blockedfile')
        
        runtimeconfig = DBConfig(self.config, suspect)
        self.checkarchivenames = runtimeconfig.getboolean(self.section, 'checkarchivenames')
        self.checkarchivecontent = runtimeconfig.getboolean(self.section, 'checkarchivecontent')
        self.sendbounce = runtimeconfig.getboolean(self.section, 'sendbounce')

        enabledarchivetypes = runtimeconfig.get(self.section, 'enabledarchivetypes')
        if enabledarchivetypes:
            enabled = [t.strip() for t in enabledarchivetypes.split(',')]
            for archtype in self.supported_archive_extensions.keys():
                if archtype not in enabled:
                    del self.supported_archive_extensions[archtype]

        returnaction = self.walk(suspect)
        return returnaction
Ejemplo n.º 4
0
    def test_global_override(self):
        """Test basic config overrdide functionality"""
        suspect = Suspect(
            u'*****@*****.**', '*****@*****.**', '/dev/null')

        candidate = DBConfig(self.config, suspect)

        candidate.add_section('testsection')
        candidate.set('testsection', 'nooverride', '100')
        candidate.set('testsection', 'override', '100')

        self.clear_table()
        self.insert_override(
            '*****@*****.**', 'testsection', 'override', '200')
        self.insert_override(
            '%unittests.fuglu.org', 'testsection', 'override', '300')
        self.insert_override('$GLOBAL', 'testsection', 'override', '400')
        self.assertEqual(candidate.getint('testsection', 'nooverride'), 100)
        self.assertEqual(candidate.getint('testsection', 'override'), 400)
Ejemplo n.º 5
0
Archivo: sa.py Proyecto: danBLA/fuglu
 def examine(self, suspect):
     # check if someone wants to skip sa checks
     if suspect.get_tag('SAPlugin.skip') is True:
         self.logger.debug('%s Skipping SA Plugin (requested by previous plugin)' % suspect.id)
         suspect.set_tag('SAPlugin.skipreason', 'requested by previous plugin')
         return DUNNO
     
     runtimeconfig = DBConfig(self.config, suspect)
     
     spamsize = suspect.size
     maxsize = self.config.getint(self.section, 'maxsize')
     strip_oversize = self.config.getboolean(self.section, 'strip_oversize')
     
     if spamsize > maxsize and not strip_oversize:
         self.logger.info('%s Size Skip, %s > %s' % (suspect.id, spamsize, maxsize))
         suspect.debug('Too big for spamchecks. %s > %s' % (spamsize, maxsize))
         prependheader = self.config.get('main', 'prependaddedheaders')
         suspect.addheader("%sSA-SKIP" % prependheader, 'Too big for spamchecks. %s > %s' % (spamsize, maxsize))
         suspect.set_tag('SAPlugin.skipreason', 'size skip')
         return self.check_sql_blacklist(suspect)
     
     if self.config.getboolean(self.section, 'scanoriginal'):
         content = suspect.get_original_source()
     else:
         content = suspect.get_source()
     
     stripped = False
     if spamsize > maxsize:
         stripped = True
         # keep copy of original content before stripping
         content_orig = content
         # send maxsize-1 to be consistent with previous implementation
         content = suspect.source_stripped_attachments(content=content, maxsize=maxsize-1)
         self.logger.info('%s stripped attachments, body size reduced from %s to %s bytes' % (suspect.id, len(content_orig), len(content)))
     # stick to bytes
     content = force_bString(content)
     
     # prepend temporary headers set by other plugins
     tempheader = suspect.get_tag('SAPlugin.tempheader')
     if tempheader is not None:
         if isinstance(tempheader, list):
             tempheader = "\r\n".join(tempheader)
         tempheader = tempheader.strip()
         if tempheader != '':
             content = force_bString(tempheader + '\r\n') + content
     
     # add envelope sender information
     msgrep = suspect.get_message_rep()
     if not 'Return-Path' in msgrep.keys():
         content = force_bString('Return-Path: %s' % suspect.from_address + '\r\n') + content
     
     forwardoriginal = self.config.getboolean(self.section, 'forwardoriginal')
     if forwardoriginal:
         ret = self.safilter_report(content, suspect.to_address)
         if ret is None:
             suspect.debug('SA report Scan failed - please check error log')
             self.logger.error('%s SA report scan FAILED' % suspect.id)
             suspect.addheader('%sSA-SKIP' % self.config.get('main', 'prependaddedheaders'), 'SA scan failed')
             suspect.set_tag('SAPlugin.skipreason', 'scan failed')
             return self._problemcode()
         isspam, spamscore, report = ret
         suspect.tags['SAPlugin.report'] = report
     
     else:
         filtered = self.safilter(content, suspect.to_address)
         if filtered is None:
             suspect.debug('SA Scan failed - please check error log')
             self.logger.error('%s SA scan FAILED' % suspect.id)
             suspect.addheader('%sSA-SKIP' % self.config.get('main', 'prependaddedheaders'), 'SA scan failed')
             suspect.set_tag('SAPlugin.skipreason', 'scan failed')
             return self._problemcode()
         else:
             if stripped:
                 # create msgrep of filtered msg
                 if isinstance(content,str):
                     msgrep_filtered = email.message_from_string(filtered, _class=PatchedMessage)
                 else:
                     msgrep_filtered = email.message_from_bytes(filtered, _class=PatchedMessage)
                 header_new = []
                 for h,v in msgrep_filtered.items():
                     header_new.append(force_uString(h).strip() + ': ' + force_uString(v).strip())
                 # add headers to msg
                 sa_prepend = self.config.get(self.section, 'spamheader_prepend')
                 for i in header_new:
                     if sa_prepend == '' or sa_prepend is None:
                         break
                     if re.match('^' + sa_prepend + '[^:]+: ', i, re.I):
                         # in case of stripped msg add header to original content
                         content_orig = force_bString(i) + b'\r\n' + force_bString(content_orig)
                     else:
                         continue
                 content = content_orig
             else:
                 content = filtered
                 
         if isinstance(content,str):
             newmsgrep = email.message_from_string(content, _class=PatchedMessage)
         else:
             newmsgrep = email.message_from_bytes(content, _class=PatchedMessage)
         
         # if original content is forwarded there's no need to reset the attachmant
         # manager. Only header have been changed.
         suspect.set_source(content,att_mgr_reset=(not forwardoriginal))
         spamheadername = self.config.get(self.section, 'spamheader')
         isspam, spamscore, report = self._extract_spamstatus(newmsgrep, spamheadername, suspect)
         suspect.tags['SAPlugin.report'] = report
         self.logger.debug('suspect %s %s %s %s' % (suspect.id, isspam, spamscore, suspect.get_tag('SAPlugin.report')))
     
     action = DUNNO
     message = None
     
     if isspam:
         self.logger.debug('%s Message is spam' % suspect.id)
         suspect.debug('Message is spam')
         
         configaction = string_to_actioncode(
             runtimeconfig.get(self.section, 'lowspamaction'), self.config)
         if configaction is not None:
             action = configaction
         values = dict(spamscore=spamscore)
         message = apply_template(
             self.config.get(self.section, 'rejectmessage'), suspect, values)
     else:
         self.logger.debug('%s Message is not spam' % suspect.id)
         suspect.debug('Message is not spam')
     
     suspect.tags['spam']['SpamAssassin'] = isspam
     suspect.tags['highspam']['SpamAssassin'] = False
     if spamscore is not None:
         suspect.tags['SAPlugin.spamscore'] = spamscore
         highspamlevel = runtimeconfig.getfloat(self.section, 'highspamlevel')
         if spamscore >= highspamlevel:
             suspect.tags['highspam']['SpamAssassin'] = True
             configaction = string_to_actioncode(runtimeconfig.get(self.section, 'highspamaction'), self.config)
             if configaction is not None:
                 action = configaction
     return action, message
Ejemplo n.º 6
0
    def examine(self, suspect):
        # check if someone wants to skip sa checks
        if suspect.get_tag('SAPlugin.skip') is True:
            self.logger.debug(
                '%s Skipping SA Plugin (requested by previous plugin)' %
                suspect.id)
            suspect.set_tag('SAPlugin.skipreason',
                            'requested by previous plugin')
            return DUNNO

        runtimeconfig = DBConfig(self.config, suspect)

        spamsize = suspect.size
        maxsize = self.config.getint(self.section, 'maxsize')
        spamheadername = self.config.get(self.section, 'spamheader')

        if spamsize > maxsize:
            self.logger.info('%s Size Skip, %s > %s' %
                             (suspect.id, spamsize, maxsize))
            suspect.debug('Too big for spamchecks. %s > %s' %
                          (spamsize, maxsize))
            prependheader = self.config.get('main', 'prependaddedheaders')
            suspect.addheader(
                "%sSA-SKIP" % prependheader,
                'Too big for spamchecks. %s > %s' % (spamsize, maxsize))
            suspect.set_tag('SAPlugin.skipreason', 'size skip')
            return self.check_sql_blacklist(suspect)

        forwardoriginal = self.config.getboolean(self.section,
                                                 'forwardoriginal')

        if self.config.getboolean(self.section, 'scanoriginal'):
            spam = suspect.get_original_source()
        else:
            spam = suspect.get_source()

        # prepend temporary headers set by other plugins
        tempheader = suspect.get_tag('SAPlugin.tempheader')
        if tempheader is not None:
            if type(tempheader) == list:
                tempheader = "\r\n".join(tempheader)
            tempheader = tempheader.strip()
            if tempheader != '':
                spam = tempheader + '\r\n' + spam

        if forwardoriginal:
            ret = self.safilter_report(spam, suspect.to_address)
            if ret is None:
                suspect.debug('SA report Scan failed - please check error log')
                self.logger.error('%s SA report scan FAILED' % suspect.id)
                suspect.addheader(
                    '%sSA-SKIP' %
                    self.config.get('main', 'prependaddedheaders'),
                    'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason', 'scan failed')
                return self._problemcode()
            isspam, spamscore, report = ret
            suspect.tags['SAPlugin.report'] = report

        else:
            filtered = self.safilter(spam, suspect.to_address)
            if filtered is None:
                suspect.debug('SA Scan failed - please check error log')
                self.logger.error('%s SA scan FAILED' % suspect.id)
                suspect.addheader(
                    '%sSA-SKIP' %
                    self.config.get('main', 'prependaddedheaders'),
                    'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason', 'scan failed')
                return self._problemcode()
            else:
                content = filtered

            newmsgrep = email.message_from_string(content)
            suspect.set_source(content)
            isspam, spamscore = self._extract_spamstatus(
                newmsgrep, spamheadername, suspect)

        action = DUNNO
        message = None

        if isspam:
            self.logger.debug('%s Message is spam' % suspect.id)
            suspect.debug('Message is spam')

            configaction = string_to_actioncode(
                runtimeconfig.get(self.section, 'lowspamaction'), self.config)
            if configaction is not None:
                action = configaction
            values = dict(spamscore=spamscore)
            message = apply_template(
                self.config.get(self.section, 'rejectmessage'), suspect,
                values)
        else:
            self.logger.debug('%s Message is not spam' % suspect.id)
            suspect.debug('Message is not spam')

        suspect.tags['spam']['SpamAssassin'] = isspam
        suspect.tags['highspam']['SpamAssassin'] = False
        if spamscore is not None:
            suspect.tags['SAPlugin.spamscore'] = spamscore
            highspamlevel = runtimeconfig.getfloat(self.section,
                                                   'highspamlevel')
            if spamscore >= highspamlevel:
                suspect.tags['highspam']['SpamAssassin'] = True
                configaction = string_to_actioncode(
                    runtimeconfig.get(self.section, 'highspamaction'),
                    self.config)
                if configaction is not None:
                    action = configaction
        return action, message
Ejemplo n.º 7
0
    def examine(self, suspect):
        # check if someone wants to skip sa checks
        if suspect.get_tag('SAPlugin.skip') is True:
            self.logger.debug(
                '%s Skipping SA Plugin (requested by previous plugin)' %
                suspect.id)
            suspect.set_tag('SAPlugin.skipreason',
                            'requested by previous plugin')
            return DUNNO

        runtimeconfig = DBConfig(self.config, suspect)

        spamsize = suspect.size
        maxsize = self.config.getint(self.section, 'maxsize')
        strip_oversize = self.config.getboolean(self.section, 'strip_oversize')

        if spamsize > maxsize and not strip_oversize:
            self.logger.info('%s Size Skip, %s > %s' %
                             (suspect.id, spamsize, maxsize))
            suspect.debug('Too big for spamchecks. %s > %s' %
                          (spamsize, maxsize))
            prependheader = self.config.get('main', 'prependaddedheaders')
            suspect.addheader(
                "%sSA-SKIP" % prependheader,
                'Too big for spamchecks. %s > %s' % (spamsize, maxsize))
            suspect.set_tag('SAPlugin.skipreason', 'size skip')
            return self.check_sql_blacklist(suspect)

        if self.config.getboolean(self.section, 'scanoriginal'):
            content = suspect.get_original_source()
        else:
            content = suspect.get_source()

        stripped = False
        if spamsize > maxsize:
            stripped = True
            # keep copy of original content before stripping
            content_orig = content
            content = self._strip_attachments(content, maxsize)
            self.logger.info(
                '%s stripped attachments, body size reduced from %s to %s bytes'
                % (suspect.id, len(content_orig), len(content)))
        # stick to bytes
        content = force_bString(content)

        # prepend temporary headers set by other plugins
        tempheader = suspect.get_tag('SAPlugin.tempheader')
        if tempheader is not None:
            if isinstance(tempheader, list):
                tempheader = "\r\n".join(tempheader)
            tempheader = tempheader.strip()
            if tempheader != '':
                content = force_bString(tempheader + '\r\n') + content

        forwardoriginal = self.config.getboolean(self.section,
                                                 'forwardoriginal')
        if forwardoriginal:
            ret = self.safilter_report(content, suspect.to_address)
            if ret is None:
                suspect.debug('SA report Scan failed - please check error log')
                self.logger.error('%s SA report scan FAILED' % suspect.id)
                suspect.addheader(
                    '%sSA-SKIP' %
                    self.config.get('main', 'prependaddedheaders'),
                    'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason', 'scan failed')
                return self._problemcode()
            isspam, spamscore, report = ret
            suspect.tags['SAPlugin.report'] = report

        else:
            filtered = self.safilter(content, suspect.to_address)
            if filtered is None:
                suspect.debug('SA Scan failed - please check error log')
                self.logger.error('%s SA scan FAILED' % suspect.id)
                suspect.addheader(
                    '%sSA-SKIP' %
                    self.config.get('main', 'prependaddedheaders'),
                    'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason', 'scan failed')
                return self._problemcode()
            else:
                if stripped:
                    # create msgrep of filtered msg
                    msgrep_filtered = email.message_from_string(filtered)
                    header_new = []
                    header_old = []
                    # create a msgrep from original msg
                    msgrep_orig = email.message_from_string(content_orig)
                    # read all headers from after-scan and before-scan
                    for h, v in msgrep_filtered.items():
                        header_new.append(h.strip() + ': ' + v.strip())
                    for h, v in msgrep_orig.items():
                        header_old.append(h.strip() + ': ' + v.strip())
                    # create a list of headers added by spamd
                    # header diff between before-scan and after-scan msg
                    header_new = reversed(self.diff(header_new, header_old))
                    # add headers to msg
                    for i in header_new:
                        if re.match('^Received: ', i, re.I):
                            continue
                        # in case of stripped msg add header to original content
                        content_orig = i + '\r\n' + content_orig
                    content = content_orig
                else:
                    content = filtered
            if sys.version_info > (3, ):
                # Python 3 and larger
                # the basic "str" type is unicode
                if isinstance(content, str):
                    newmsgrep = email.message_from_string(content)
                else:
                    newmsgrep = email.message_from_bytes(content)
            else:
                # Python 2.x
                newmsgrep = email.message_from_string(content)
            suspect.set_source(content)
            spamheadername = self.config.get(self.section, 'spamheader')
            isspam, spamscore, report = self._extract_spamstatus(
                newmsgrep, spamheadername, suspect)
            suspect.tags['SAPlugin.report'] = report
            self.logger.debug('suspect %s %s %s %s' %
                              (suspect.id, isspam, spamscore,
                               suspect.get_tag('SAPlugin.report')))

        action = DUNNO
        message = None

        if isspam:
            self.logger.debug('%s Message is spam' % suspect.id)
            suspect.debug('Message is spam')

            configaction = string_to_actioncode(
                runtimeconfig.get(self.section, 'lowspamaction'), self.config)
            if configaction is not None:
                action = configaction
            values = dict(spamscore=spamscore)
            message = apply_template(
                self.config.get(self.section, 'rejectmessage'), suspect,
                values)
        else:
            self.logger.debug('%s Message is not spam' % suspect.id)
            suspect.debug('Message is not spam')

        suspect.tags['spam']['SpamAssassin'] = isspam
        suspect.tags['highspam']['SpamAssassin'] = False
        if spamscore is not None:
            suspect.tags['SAPlugin.spamscore'] = spamscore
            highspamlevel = runtimeconfig.getfloat(self.section,
                                                   'highspamlevel')
            if spamscore >= highspamlevel:
                suspect.tags['highspam']['SpamAssassin'] = True
                configaction = string_to_actioncode(
                    runtimeconfig.get(self.section, 'highspamaction'),
                    self.config)
                if configaction is not None:
                    action = configaction
        return action, message
Ejemplo n.º 8
0
Archivo: sa.py Proyecto: sporkman/fuglu
    def examine(self, suspect):
        # check if someone wants to skip sa checks
        if suspect.get_tag('SAPlugin.skip') == True:
            self.logger.debug(
                'Skipping SA Plugin (requested by previous plugin)')
            suspect.set_tag(
                'SAPlugin.skipreason', 'requested by previous plugin')
            return

        runtimeconfig = DBConfig(self.config, suspect)

        spamsize = suspect.size
        maxsize = self.config.getint(self.section, 'maxsize')
        spamheadername = self.config.get(self.section, 'spamheader')

        if spamsize > maxsize:
            self.logger.info('%s Size Skip, %s > %s' %
                             (suspect.id, spamsize, maxsize))
            suspect.debug('Too big for spamchecks. %s > %s' %
                          (spamsize, maxsize))
            prependheader = self.config.get('main', 'prependaddedheaders')
            suspect.addheader(
                "%sSA-SKIP" % prependheader, 'Too big for spamchecks. %s > %s' % (spamsize, maxsize))
            suspect.set_tag('SAPlugin.skipreason', 'size skip')
            return self.check_sql_blacklist(suspect)

        forwardoriginal = self.config.getboolean(
            self.section, 'forwardoriginal')

        if self.config.getboolean(self.section, 'scanoriginal'):
            spam = suspect.get_original_source()
        else:
            spam = suspect.get_source()

        # prepend temporary headers set by other plugins
        tempheader = suspect.get_tag('SAPlugin.tempheader')
        if tempheader != None:
            if type(tempheader) == list:
                tempheader = "\r\n".join(tempheader)
            tempheader = tempheader.strip()
            if tempheader != '':
                spam = tempheader + '\r\n' + spam

        if forwardoriginal:
            ret = self.safilter_report(spam, suspect.to_address)
            if ret == None:
                suspect.debug('SA report Scan failed - please check error log')
                self.logger.error('%s SA report scan FAILED' % suspect.id)
                suspect.addheader(
                    '%sSA-SKIP' % self.config.get('main', 'prependaddedheaders'), 'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason', 'scan failed')
                return self._problemcode()
            isspam, spamscore, report = ret
            suspect.tags['SAPlugin.report'] = report

        else:
            filtered = self.safilter(spam, suspect.to_address)
            content = None
            if filtered == None:
                suspect.debug('SA Scan failed - please check error log')
                self.logger.error('%s SA scan FAILED' % suspect.id)
                suspect.addheader(
                    '%sSA-SKIP' % self.config.get('main', 'prependaddedheaders'), 'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason', 'scan failed')
                return self._problemcode()
            else:
                content = filtered

            newmsgrep = email.message_from_string(content)
            suspect.set_source(content)
            isspam, spamscore = self._extract_spamstatus(
                newmsgrep, spamheadername, suspect)

        action = DUNNO
        message = None

        if isspam:
            self.logger.debug('Message is spam')
            suspect.debug('Message is spam')

            configaction = string_to_actioncode(
                runtimeconfig.get(self.section, 'lowspamaction'), self.config)
            if configaction != None:
                action = configaction
            values = dict(spamscore=spamscore)
            message = apply_template(
                self.config.get(self.section, 'rejectmessage'), suspect, values)
        else:
            self.logger.debug('Message is not spam')
            suspect.debug('Message is not spam')

        suspect.tags['spam']['SpamAssassin'] = isspam
        suspect.tags['highspam']['SpamAssassin'] = False
        if spamscore != None:
            suspect.tags['SAPlugin.spamscore'] = spamscore
            highspamlevel = runtimeconfig.getint(self.section, 'highspamlevel')
            if spamscore >= highspamlevel:
                suspect.tags['highspam']['SpamAssassin'] = True
                configaction = string_to_actioncode(
                    runtimeconfig.get(self.section, 'highspamaction'), self.config)
                if configaction != None:
                    action = configaction
        return action, message
Ejemplo n.º 9
0
    def examine(self,suspect):
        #check if someone wants to skip sa checks
        if suspect.get_tag('SAPlugin.skip')==True:
            self.logger.debug('Skipping SA Plugin (requested by previous plugin)')
            suspect.set_tag('SAPlugin.skipreason','requested by previous plugin')
            return
        
        runtimeconfig=DBConfig(self.config, suspect)
        
        spamsize=suspect.size        
        maxsize=self.config.getint(self.section, 'maxsize')
        spamheadername=self.config.get(self.section,'spamheader')
        
        if spamsize>maxsize:
            self.logger.info('%s Size Skip, %s > %s'%(suspect.id,spamsize,maxsize))
            suspect.debug('Too big for spamchecks. %s > %s'%(spamsize,maxsize))
            prependheader=self.config.get('main','prependaddedheaders')
            suspect.addheader("%sSA-SKIP"%prependheader, 'Too big for spamchecks. %s > %s'%(spamsize,maxsize))
            suspect.set_tag('SAPlugin.skipreason','size skip')
            return self.check_sql_blacklist(suspect)
            
        
        starttime=time.time()
        
        forwardoriginal=self.config.getboolean(self.section,'forwardoriginal')
        
        if self.config.getboolean(self.section,'scanoriginal'):
            spam=suspect.getOriginalSource()
        else:
            spam=suspect.getSource()
            
        #prepend temporary headers set by other plugins
        tempheader=suspect.get_tag('SAPlugin.tempheader')
        if tempheader!=None:
            if type(tempheader)==list:
                tempheader="\r\n".join(tempheader)
            tempheader=tempheader.strip()
            if tempheader!='':
                spam=tempheader+'\r\n'+spam
            
        if forwardoriginal:
            ret=self.safilter_report(spam, suspect.to_address)
            if ret==None:
                suspect.debug('SA report Scan failed - please check error log')
                self.logger.error('%s SA report scan FAILED'%suspect.id)
                suspect.addheader('%sSA-SKIP'%self.config.get('main','prependaddedheaders'),'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason','scan failed')
                return self._problemcode()
            isspam,spamscore,report=ret
            suspect.tags['SAPlugin.report']=report
            
        else:
            filtered=self.safilter(spam,suspect.to_address)
            content=None
            if filtered==None:
                suspect.debug('SA Scan failed - please check error log')
                self.logger.error('%s SA scan FAILED'%suspect.id)
                suspect.addheader('%sSA-SKIP'%self.config.get('main','prependaddedheaders'),'SA scan failed')
                suspect.set_tag('SAPlugin.skipreason','scan failed')
                return self._problemcode()
            else:
                content=filtered 
            
            newmsgrep=email.message_from_string(content)
            suspect.setSource(content)

            isspam=False
            spamheader=newmsgrep[spamheadername]
        
            spamscore=None
            if spamheader==None:
                self.logger.warning('Did not find Header %s in returned message from SA'%spamheadername)
            else:
                if len(spamheader)>2 and 'yes' in spamheader.lower():
                    isspam=True
                patt=re.compile('Score=([\-\d\.]+)',re.IGNORECASE)
                m=patt.search(spamheader)
                
                if m !=None:
                    spamscore=float(m.group(1))
                    self.logger.debug('Spamscore: %s'%spamscore)
                    suspect.debug('Spamscore: %s'%spamscore)
                else:
                    self.logger.warning('Could not extract spam score from header: %s'%spamheader)
                    suspect.debug('Could not read spam score from header %s'%spamheader)
         
        
        action=DUNNO
        message=None
        
        if isspam:
            self.logger.debug('Message is spam')
            suspect.debug('Message is spam')
            
            configaction=string_to_actioncode(runtimeconfig.get(self.section,'lowspamaction'),self.config)
            if configaction!=None:
                action=configaction
            values=dict(spamscore=spamscore)
            message=apply_template(self.config.get(self.section,'rejectmessage'), suspect, values)
        else:
            self.logger.debug('Message is not spam')
            suspect.debug('Message is not spam')   
        
            
        suspect.tags['spam']['SpamAssassin']=isspam
        suspect.tags['highspam']['SpamAssassin']=False
        if spamscore != None:
            suspect.tags['SAPlugin.spamscore']=spamscore
            highspamlevel=runtimeconfig.getint(self.section,'highspamlevel')
            if spamscore>=highspamlevel:
                suspect.tags['highspam']['SpamAssassin']=True
                configaction=string_to_actioncode(runtimeconfig.get(self.section,'highspamaction'),self.config)
                if configaction!=None:
                    action=configaction
        
        endtime=time.time()
        difftime=endtime-starttime
        suspect.tags['SAPlugin.time']="%.4f"%difftime
        return action,message
Ejemplo n.º 10
0
    def examine(self, suspect):
        if suspect.get_tag('RSpamd.skip') is True:
            self.logger.debug(
                '%s Skipping RSpamd Plugin (requested by previous plugin)' %
                suspect.id)
            suspect.set_tag('RSpamd.skipreason',
                            'requested by previous plugin')
            return DUNNO

        maxsize = self.config.getint(self.section, 'maxsize')
        if suspect.size > maxsize:
            self.logger.info('%s Size Skip, %s > %s' %
                             (suspect.id, suspect.size, maxsize))
            suspect.debug('Too big for spamchecks. %s > %s' %
                          (suspect.size, maxsize))
            prependheader = self.config.get('main', 'prependaddedheaders')
            suspect.addheader(
                "%sRSPAMD-SKIP" % prependheader,
                'Too big for spamchecks. %s > %s' % (suspect.size, maxsize))
            suspect.set_tag('RSpamd.skipreason', 'size skip')
            return DUNNO

        runtimeconfig = DBConfig(self.config, suspect)

        isspam, spamscore, report, symbols = self.rspamd_json(suspect)

        action = DUNNO
        message = None

        if isspam is None:
            return self._problemcode()

        elif isspam:
            self.logger.debug('%s Message is spam' % suspect.id)
            suspect.debug('Message is spam')

            configaction = string_to_actioncode(
                runtimeconfig.get(self.section, 'lowspamaction'), self.config)
            if configaction is not None:
                action = configaction
            values = dict(spamscore=spamscore)
            message = apply_template(
                self.config.get(self.section, 'rejectmessage'), suspect,
                values)
        else:
            self.logger.debug('%s Message is not spam' % suspect.id)
            suspect.debug('Message is not spam')

        suspect.tags['RSpamd.report'] = '\n'.join(report)
        suspect.tags['spam']['RSpamd'] = isspam
        suspect.tags['highspam']['RSpamd'] = False
        if spamscore is not None:
            suspect.tags['RSpamd.spamscore'] = spamscore
            highspamlevel = runtimeconfig.getfloat(self.section,
                                                   'highspamlevel')
            if spamscore >= highspamlevel:
                suspect.tags['highspam']['RSpamd'] = True
                configaction = string_to_actioncode(
                    runtimeconfig.get(self.section, 'highspamaction'),
                    self.config)
                if configaction is not None:
                    action = configaction

        forwardoriginal = self.config.getboolean(self.section,
                                                 'forwardoriginal')
        if not forwardoriginal:
            # rspamd sample headers: https://github.com/vstakhov/rspamd/issues/799
            suspect.addheader(
                '%sRSPAMD-Spam' %
                self.config.get('main', 'prependaddedheaders'),
                'yes' if isspam else 'no')
            suspect.addheader(
                '%sRSPAMD-Spam-Symbols' %
                self.config.get('main', 'prependaddedheaders'),
                ','.join(symbols))

        return action, message