Exemple #1
0
    def matchRules(self, ruleset, obj, suspect, attachmentname=None):
        if attachmentname == None:
            attachmentname = ""
        attachmentname = self.asciionly(attachmentname)

        if obj == None:
            self.logger.warning(
                "%s: message has unknown name or content-type attachment %s" % (suspect.id, attachmentname))
            return ATTACHMENT_DUNNO

        # remove non ascii chars
        asciirep = self.asciionly(obj)

        displayname = attachmentname
        if asciirep == attachmentname:
            displayname = ''

        if ruleset == None:
            return ATTACHMENT_DUNNO

        for action, regex, description in ruleset:
            # database description may be unicode
            description = description.encode("utf-8", "ignore")

            prog = re.compile(regex, re.I)
            if self.extremeverbosity:
                self.logger.debug('Attachment %s Rule %s' % (obj, regex))
            if isinstance(obj, bytes) and sys.version_info > (3,):
                obj = obj.decode('UTF-8', 'ignore')
            if prog.search(obj):
                self.logger.debug('Rulematch: Attachment=%s Rule=%s Description=%s Action=%s' % (
                    obj, regex, description, action))
                suspect.debug('Rulematch: Attachment=%s Rule=%s Description=%s Action=%s' % (
                    obj, regex, description, action))
                if action == 'deny':
                    self.logger.info('suspect %s contains blocked attachment %s %s' % (
                        suspect.id, displayname, asciirep))
                    blockinfo = "%s %s: %s" % (
                        displayname, asciirep, description)
                    suspect.tags['FiletypePlugin.errormessage'] = blockinfo
                    if self.config.getboolean(self.section, 'sendbounce'):
                        if suspect.is_spam() or suspect.is_virus():
                            self.logger.info(
                                "backscatter prevention: not sending attachment block bounce to %s - the message is tagged spam or virus" % suspect.from_address)
                        else:
                            self.logger.info(
                                "Sending attachment block bounce to %s" % suspect.from_address)
                            bounce = Bounce(self.config)
                            bounce.send_template_file(
                                suspect.from_address, self.blockedfiletemplate, suspect, dict(blockinfo=blockinfo))
                    return ATTACHMENT_BLOCK

                if action == 'delete':
                    self.logger.info(
                        'suspect %s contains blocked attachment %s %s -- SILENT DELETE! --' % (suspect.id, displayname, asciirep))
                    return ATTACHMENT_SILENTDELETE

                if action == 'allow':
                    return ATTACHMENT_OK
        return ATTACHMENT_DUNNO
Exemple #2
0
    def matchRules(self, ruleset, obj, suspect, attachmentname=None):
        if attachmentname is None:
            attachmentname = ""
        attachmentname = self.asciionly(attachmentname)

        if obj is None:
            self.logger.warning(
                "%s: message has unknown name or content-type attachment %s" % (suspect.id, attachmentname))
            return ATTACHMENT_DUNNO

        # remove non ascii chars
        asciirep = self.asciionly(obj)

        displayname = attachmentname
        if asciirep == attachmentname:
            displayname = ''

        if ruleset is None:
            return ATTACHMENT_DUNNO

        for action, regex, description in ruleset:
            # database description may be unicode
            description = description.encode("utf-8", "ignore")

            prog = re.compile(regex, re.I)
            if self.extremeverbosity:
                self.logger.debug('Attachment %s Rule %s' % (obj, regex))
            if isinstance(obj, bytes) and sys.version_info > (3,):
                obj = obj.decode('UTF-8', 'ignore')
            if prog.search(obj):
                self.logger.debug('Rulematch: Attachment=%s Rule=%s Description=%s Action=%s' % (
                    obj, regex, description, action))
                suspect.debug('Rulematch: Attachment=%s Rule=%s Description=%s Action=%s' % (
                    obj, regex, description, action))
                if action == 'deny':
                    self.logger.info('suspect %s contains blocked attachment %s %s' % (
                        suspect.id, displayname, asciirep))
                    suspect.tags['blocked']['FiletypePlugin'] = True
                    blockinfo = ("%s %s: %s" % (displayname, asciirep, description)).strip()
                    suspect.tags['FiletypePlugin.errormessage'] = blockinfo
                    if self.config.getboolean(self.section, 'sendbounce'):
                        if suspect.is_spam() or suspect.is_virus():
                            self.logger.info(
                                "backscatter prevention: not sending attachment block bounce to %s - the message is tagged spam or virus" % suspect.from_address)
                        else:
                            self.logger.info(
                                "Sending attachment block bounce to %s" % suspect.from_address)
                            bounce = Bounce(self.config)
                            bounce.send_template_file(
                                suspect.from_address, self.blockedfiletemplate, suspect, dict(blockinfo=blockinfo))
                    return ATTACHMENT_BLOCK

                if action == 'delete':
                    self.logger.info(
                        'suspect %s contains blocked attachment %s %s -- SILENT DELETE! --' % (suspect.id, displayname, asciirep))
                    return ATTACHMENT_SILENTDELETE

                if action == 'allow':
                    return ATTACHMENT_OK
        return ATTACHMENT_DUNNO
Exemple #3
0
    def test_bounce(self):
        """Test bounce message, especially the encoding"""
        suspect = Suspect('*****@*****.**',
                          '*****@*****.**', '/dev/null')

        # include non-ascii charset unicode characters to make sure the encoding/decoding
        # works correctly
        displayname = u"((testing placeholder for displayname -> äää))"
        asciirep = u"((testing placeholder for asciirep -> üüü))"
        description = u"((testing placeholder for description -> ööö))"

        blockinfo = ("%s %s: %s" %
                     (displayname, asciirep, description)).strip()
        blockedfiletemplate = os.path.join(
            *[CONFDIR, "templates", "blockedfile.tmpl.dist"])

        bounce = Bounce(self.config)
        bounce.send_template_file(suspect.from_address, blockedfiletemplate,
                                  suspect, dict(blockinfo=blockinfo))

        # might be needed to wait for a bit to make sure answer is available
        counter = 0
        while self.smtp.suspect is None and counter < 20:
            counter = counter + 1
            time.sleep(0.05)  # sleep is needed to

        gotback = self.smtp.suspect
        self.assertFalse(gotback == None,
                         "Did not get message from dummy smtp server")

        # get message received by dummy smtp server
        msg = gotback.get_message_rep()
        receivedMsg = msg.get_payload(decode='utf-8')

        # Build the message according to what Bounce is doing so it can be compared
        # to what was received from DummySMTPServer
        with open(blockedfiletemplate) as fp:
            templatecontent = fp.read()

        blockinfo = ("%s %s: %s" %
                     (displayname, asciirep, description)).strip()
        message = apply_template(templatecontent, suspect,
                                 dict(blockinfo=blockinfo))
        messageB = force_bString(message)

        # modify received message to add header parts from template
        messageToCompare = force_bString("To: " + msg['To'] + "\nSubject: " +
                                         msg['Subject'] +
                                         "\n\n") + force_bString(receivedMsg)

        # make sure comparison will not fail because of newlines
        # For example, Python 2.6 has only one "\n" at the end of the received message, whereas Python 2.7 and 3 have to
        messageToCompare = messageToCompare.replace(b"\r", b"\n").replace(
            b"\n\n", b"\n")
        messageB = messageB.replace(b"\r", b"\n").replace(b"\n\n", b"\n")

        self.assertEqual(messageB, messageToCompare)
    def matchRules(self,ruleset,obj,suspect,attachmentname=None):
        if attachmentname==None:
            attachmentname=""
        attachmentname=self.asciionly(attachmentname)
        
        if obj==None:
            self.logger.warning("%s: message has unknown name or content-type attachment %s"%(suspect.id,attachmentname))
            return ATTACHMENT_DUNNO
        
        # remove non ascii chars
        asciirep=self.asciionly(obj)
        
        displayname=attachmentname
        if asciirep==attachmentname:
            displayname=''
        
        if ruleset==None:
            return ATTACHMENT_DUNNO

        for regex in ruleset.keys():
            prog=re.compile(regex,re.I)
            if self.extremeverbosity:
                self.logger.debug('Attachment %s Rule %s'%(obj,regex))
            if prog.search( obj):
                info=ruleset[regex]
                action=info[0]
                description=info[2]
                self.logger.debug('Rulematch: Attachment=%s Rule=%s Description=%s Action=%s'%(obj,regex,description,action))
                suspect.debug('Rulematch: Attachment=%s Rule=%s Description=%s Action=%s'%(obj,regex,description,action))
                if action=='deny':
                    self.logger.info('suspect %s contains blocked attachment %s %s'%(suspect.id,displayname,asciirep))
                    blockinfo="%s %s: %s"%(displayname,asciirep,description)
                    suspect.tags['FiletypePlugin.errormessage']=blockinfo
                    if self.config.getboolean(self.section,'sendbounce'):
                        self.logger.info("Sending attachment block bounce to %s"%suspect.from_address)
                        bounce=Bounce(self.config)
                        bounce.send_template_file(suspect.from_address, self.blockedfiletemplate, suspect,dict(blockinfo=blockinfo))
                    return ATTACHMENT_BLOCK

                if action=='delete':
                    self.logger.info('suspect %s contains blocked attachment %s %s -- SILENT DELETE! --'%(suspect.id,displayname,asciirep))
                    return ATTACHMENT_SILENTDELETE

                if action=='allow':
                    return ATTACHMENT_OK
        return ATTACHMENT_DUNNO
Exemple #5
0
    def send_vacation_reply(self, suspect, vacation):
        """send the vacation reply"""
        # http://mg.pov.lt/blog/unicode-emails-in-python

        bounce = Bounce(self.config)
        self.logger.debug('generating vacation message from %s to %s' % (
            suspect.to_address, suspect.from_address))

        # check subject
        subj = vacation.subject
        if subj is None or subj.strip() == '':
            self.logger.errror('Vacation has no subject, not sending message')
            return None

        # We must choose the body charset manually
        body = vacation.body
        if body is None:
            body = ''

        for body_charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8':
            try:
                body.encode(body_charset)
            except UnicodeError:
                pass
            else:
                break

        msg = MIMEText(body.encode(body_charset), 'plain', body_charset)

        h = Header(vacation.subject, 'ISO-8859-1')
        msg['Subject'] = h
        msg['Precedence'] = 'bulk'
        msg['Auto-Submitted'] = 'auto-replied'
        msg['From'] = suspect.to_address
        msg['To'] = suspect.from_address

        msgcontent = msg.as_string()
        queueid = bounce.send_template_string(
            suspect.from_address, msgcontent, suspect, dict())
        self.log_bounce(suspect, vacation)
        self.logger.info('%s sent autoresponder bounce to %s with queueid %s' % (suspect.id, suspect.from_address, queueid))
        suspect.set_tag('Vacation.bounce.queueid', queueid)
        return msgcontent
Exemple #6
0
    def send_vacation_reply(self, suspect, vacation):
        """send the vacation reply"""
        # http://mg.pov.lt/blog/unicode-emails-in-python

        bounce = Bounce(self.config)
        self.logger.debug('generating vacation message from %s to %s' % (
            suspect.to_address, suspect.from_address))

        # check subject
        subj = vacation.subject
        if subj == None or subj.strip() == '':
            self.logger.errror('Vacation has no subject, not sending message')
            return None

        # We must choose the body charset manually
        body = vacation.body
        if body == None:
            body = ''

        for body_charset in 'US-ASCII', 'ISO-8859-1', 'UTF-8':
            try:
                body.encode(body_charset)
            except UnicodeError:
                pass
            else:
                break

        msg = MIMEText(body.encode(body_charset), 'plain', body_charset)

        h = Header(vacation.subject, 'ISO-8859-1')
        msg['Subject'] = h
        msg['Precedence'] = 'bulk'
        msg['Auto-Submitted'] = 'auto-replied'
        msg['From'] = suspect.to_address
        msg['To'] = suspect.from_address

        msgcontent = msg.as_string()
        bounce.send_template_string(
            suspect.from_address, msgcontent, suspect, dict())
        self.log_bounce(suspect, vacation)
        return msgcontent
Exemple #7
0
    def send_vacation_reply(self, suspect, vacation):
        """send the vacation reply"""
        # http://mg.pov.lt/blog/unicode-emails-in-python

        bounce = Bounce(self.config)
        self.logger.debug("generating vacation message from %s to %s" % (suspect.to_address, suspect.from_address))

        # check subject
        subj = vacation.subject
        if subj == None or subj.strip() == "":
            self.logger.errror("Vacation has no subject, not sending message")
            return None

        # We must choose the body charset manually
        body = vacation.body
        if body == None:
            body = ""

        for body_charset in "US-ASCII", "ISO-8859-1", "UTF-8":
            try:
                body.encode(body_charset)
            except UnicodeError:
                pass
            else:
                break

        msg = MIMEText(body.encode(body_charset), "plain", body_charset)

        h = Header(vacation.subject, "ISO-8859-1")
        msg["Subject"] = h
        msg["Precedence"] = "bulk"
        msg["Auto-Submitted"] = "auto-replied"
        msg["From"] = suspect.to_address
        msg["To"] = suspect.from_address

        msgcontent = msg.as_string()
        bounce.send_template_string(suspect.from_address, msgcontent, suspect, dict())
        self.log_bounce(suspect, vacation)
        return msgcontent
Exemple #8
0
    def send_vacation_reply(self, suspect, vacation):
        """send the vacation reply"""
        # http://mg.pov.lt/blog/unicode-emails-in-python

        bounce = Bounce(self.config)
        self.logger.debug('generating vacation message from %s to %s' % (
            suspect.to_address, suspect.from_address))
        try:
            from email.mime.text import MIMEText
            from email.header import Header
        except ImportError, e:
            # python 2.4
            from email.MIMEText import MIMEText
            from email.Header import Header