Beispiel #1
0
 def test_insert_exception_header_no_separator(self):
     try:
         raise Exception("Test")
     except Exception:
         pass
     msg, details = insert_exception_header(malformed1)
     self._verify_details(details)
     self._verify_exception_header(msg, details)
Beispiel #2
0
 def test_insert_exception_header(self):
     try:
         raise Exception("Test")
     except Exception:
         pass
     msg, details = insert_exception_header(good1)
     self._verify_details(details)
     self._verify_exception_header(msg, details)
Beispiel #3
0
 def get_full_message(self):
     """Retrieve the RFC822 message from the IMAP server and return a
     new IMAPMessage object that has the same details as this message,
     but also has the substance."""
     if self.got_substance:
         return self
     assert self.id, "Cannot get substance of message without an id"
     assert self.uid, "Cannot get substance of message without an UID"
     assert self.imap_server, "Cannot do anything without IMAP connection"
     try:
         self.imap_server.SelectFolder(self.folder.name)
     except BadIMAPResponseError:
         self.could_not_retrieve = True
         print >> sys.stderr, "Could not select folder %s for message " \
               "%s (uid %s)" % (self.folder.name, self.id, self.uid)
         return self
     try:
         response = self.imap_server.uid("FETCH", self.uid,
                                         self.rfc822_command)
     except MemoryError:
         self.could_not_retrieve = True
         print >> sys.stderr, "MemoryError with message %s (uid %s)" % \
               (self.id, self.uid)
         return self
     command = "uid fetch %s" % (self.uid,)
     response_data = self.imap_server.check_response(command, response)
     data = self.imap_server.extract_fetch_data(response_data)
     rfc822_data = None
     for msg_data in data.itervalues():
         if self.rfc822_key in msg_data:
             rfc822_data = msg_data[self.rfc822_key]
             break
     if rfc822_data is None:
         raise BadIMAPResponseError("FETCH response", response_data)
     try:
         new_msg = email.message_from_string(rfc822_data, IMAPMessage)
     except:
         self.invalid = True
         text, details = message.insert_exception_header(
             rfc822_data, self.id)
         self.invalid_content = text
         self.got_substance = True
         print >> sys.stderr, details
         return self            
     new_msg.folder = self.folder
     new_msg.previous_folder = self.previous_folder
     new_msg.rfc822_command = self.rfc822_command
     new_msg.rfc822_key = self.rfc822_key
     new_msg.imap_server = self.imap_server
     new_msg.uid = self.uid
     new_msg.setId(self.id)
     new_msg.got_substance = True
     if not new_msg.has_key(options["Headers", "mailid_header_name"]):
         new_msg[options["Headers", "mailid_header_name"]] = self.id
     if options["globals", "verbose"]:
         sys.stdout.write(chr(8) + "*")
     return new_msg
 def test_insert_exception_header_no_separator(self):
     # Cause an exception to insert.
     try:
         raise Exception("Test")
     except Exception:
         pass
     msg, details = insert_exception_header(malformed1)
     self._verify_details(details)
     self._verify_exception_header(msg, details)
Beispiel #5
0
 def test_insert_exception_header_and_id(self):
     try:
         raise Exception("Test")
     except Exception:
         pass
     id = "Message ID"
     msg, details = insert_exception_header(good1, id)
     self._verify_details(details)
     self._verify_exception_header(msg, details)
     msg = email.message_from_string(msg)
     headerName = options["Headers", "mailid_header_name"]
     header = email.Header.Header(id, header_name=headerName)
     self.assertEqual(msg[headerName], str(header).replace('\n', '\r\n'))
Beispiel #6
0
 def onRetr(self, command, args, response):
     """Classifies the message.  If the result is ham, then simply
     pass it through.  If the result is an unsure or spam, move it
     to the appropriate IMAP folder."""
     if re.search(r'\n\r?\n', response):
         terminatingDotPresent = (response[-4:] == '\n.\r\n')
         if terminatingDotPresent:
             response = response[:-3]
         ok, messageText = response.split('\n', 1)
         try:
             msg = email.message_from_string(messageText,
                                             _class=message.SBHeaderMessage)
             (prob, clues) = state.bayes.spamprob(msg.tokenize(),
                                                  evidence=True)
             msg.addSBHeaders(prob, clues)
             if (command == 'RETR' or
                 (command == 'TOP' and
                  len(args) == 2 and args[1] == '99999999')):
                 cls = msg.GetClassification()
                 dest_folder = None
                 if cls == options["Headers", "header_ham_string"]:
                     state.numHams += 1
                     headers = []
                     for name, value in msg.items():
                         header = "%s: %s" % (name, value)
                         headers.append(re.sub(r'\r?\n', '\r\n', header))
                     body = re.split(r'\n\r?\n', messageText, 1)[1]
                     messageText = "\r\n".join(headers) + "\r\n\r\n" + body
                 elif prob > options["Categorization", "spam_cutoff"]:
                     dest_folder = self.spam_folder
                     state.numSpams += 1
                 else:
                     dest_folder = self.unsure_folder
                     state.numUnsure += 1
                 if dest_folder:
                     msg = StringIO.StringIO(msg.as_string())
                     date = imaplib.Time2Internaldate(time.time())[1:-1]
                     dest_folder.addMessage(msg, (), date)
                     messageText = self.intercept_message % (prob,)
         except:
             messageText, details = \
                          message.insert_exception_header(messageText)
             print >> sys.stderr, details
         retval = ok + "\n" + messageText
         if terminatingDotPresent:
             retval += '.\r\n'
         return retval
     else:
         return response
 def test_insert_exception_header_and_id(self):
     # Cause an exception to insert.
     try:
         raise Exception("Test")
     except Exception:
         pass
     id = "Message ID"
     msg, details = insert_exception_header(good1, id)
     self._verify_details(details)
     self._verify_exception_header(msg, details)
     # Check that ID header is inserted.
     msg = email.message_from_string(msg)
     headerName = options["Headers", "mailid_header_name"]
     header = email.Header.Header(id, header_name=headerName)
     self.assertEqual(msg[headerName], str(header).replace('\n', '\r\n'))
 def test_insert_exception_header_and_id(self):
     # Cause an exception to insert.
     try:
         raise Exception("Test")
     except Exception:
         pass
     id = "Message ID"
     msg, details = insert_exception_header(good1, id)
     self._verify_details(details)
     self._verify_exception_header(msg, details)
     # Check that ID header is inserted.
     msg = email.message_from_string(msg)
     headerName = options["Headers", "mailid_header_name"]
     header = email.Header.Header(id, header_name=headerName)
     self.assertEqual(msg[headerName], str(header).replace("\n", "\r\n"))
Beispiel #9
0
    def onRetr(self, command, args, response):
        """Classifies the message.  If the result is ham, then simply
        pass it through.  If the result is an unsure or spam, move it
        to the appropriate IMAP folder."""
        # XXX This is all almost from sb_server!  We could just
        # XXX extract that out into a function and call it here.

        # Use '\n\r?\n' to detect the end of the headers in case of
        # broken emails that don't use the proper line separators.
        if re.search(r'\n\r?\n', response):
            # Remove the trailing .\r\n before passing to the email parser.
            # Thanks to Scott Schlesier for this fix.
            terminatingDotPresent = (response[-4:] == '\n.\r\n')
            if terminatingDotPresent:
                response = response[:-3]

            # Break off the first line, which will be '+OK'.
            ok, messageText = response.split('\n', 1)

            try:
                msg = email.message_from_string(messageText,
                                                _class=message.SBHeaderMessage)
                # Now find the spam disposition and add the header.
                (prob, clues) = state.bayes.spamprob(msg.tokenize(),
                                                     evidence=True)

                # Note that the X-SpamBayes-MailID header will be worthless
                # because we don't know the message id at this point.  It's
                # not necessary for anything anyway, so just don't set the
                # [Headers] add_unique_id option.
                msg.addSBHeaders(prob, clues)

                # Check for "RETR" or "TOP N 99999999" - fetchmail without
                # the 'fetchall' option uses the latter to retrieve messages.
                if (command == 'RETR' or (command == 'TOP' and len(args) == 2
                                          and args[1] == '99999999')):
                    cls = msg.GetClassification()
                    dest_folder = None
                    if cls == options["Headers", "header_ham_string"]:
                        state.numHams += 1
                        headers = []
                        for name, value in msg.items():
                            header = "%s: %s" % (name, value)
                            headers.append(re.sub(r'\r?\n', '\r\n', header))
                        body = re.split(r'\n\r?\n', messageText, 1)[1]
                        messageText = "\r\n".join(headers) + "\r\n\r\n" + body
                    elif prob > options["Categorization", "spam_cutoff"]:
                        dest_folder = self.spam_folder
                        state.numSpams += 1
                    else:
                        dest_folder = self.unsure_folder
                        state.numUnsure += 1
                    if dest_folder:
                        msg = StringIO.StringIO(msg.as_string())
                        date = imaplib.Time2Internaldate(time.time())[1:-1]
                        dest_folder.addMessage(msg, (), date)

                        # We have to return something, because the client
                        # is expecting us to.  We return a short message
                        # indicating that a message was intercepted.
                        messageText = self.intercept_message % (prob, )
            except:
                messageText, details = \
                             message.insert_exception_header(messageText)

                # Print the exception and a traceback.
                print >> sys.stderr, details
            retval = ok + "\n" + messageText
            if terminatingDotPresent:
                retval += '.\r\n'
            return retval
        else:
            # Must be an error response.
            return response
    def onRetr(self, command, args, response):
        """Classifies the message.  If the result is ham, then simply
        pass it through.  If the result is an unsure or spam, move it
        to the appropriate IMAP folder."""
        # XXX This is all almost from sb_server!  We could just
        # XXX extract that out into a function and call it here.

        # Use '\n\r?\n' to detect the end of the headers in case of
        # broken emails that don't use the proper line separators.
        if re.search(r'\n\r?\n', response):
            # Remove the trailing .\r\n before passing to the email parser.
            # Thanks to Scott Schlesier for this fix.
            terminatingDotPresent = (response[-4:] == '\n.\r\n')
            if terminatingDotPresent:
                response = response[:-3]

            # Break off the first line, which will be '+OK'.
            ok, messageText = response.split('\n', 1)

            try:
                msg = email.message_from_string(messageText,
                                                _class=message.SBHeaderMessage)
                # Now find the spam disposition and add the header.
                (prob, clues) = state.bayes.spamprob(msg.tokenize(),
                                                     evidence=True)

                # Note that the X-SpamBayes-MailID header will be worthless
                # because we don't know the message id at this point.  It's
                # not necessary for anything anyway, so just don't set the
                # [Headers] add_unique_id option.
                msg.addSBHeaders(prob, clues)

                # Check for "RETR" or "TOP N 99999999" - fetchmail without
                # the 'fetchall' option uses the latter to retrieve messages.
                if (command == 'RETR' or
                    (command == 'TOP' and
                     len(args) == 2 and args[1] == '99999999')):
                    cls = msg.GetClassification()
                    dest_folder = None
                    if cls == options["Headers", "header_ham_string"]:
                        state.numHams += 1
                        headers = []
                        for name, value in msg.items():
                            header = "%s: %s" % (name, value)
                            headers.append(re.sub(r'\r?\n', '\r\n', header))
                        body = re.split(r'\n\r?\n', messageText, 1)[1]
                        messageText = "\r\n".join(headers) + "\r\n\r\n" + body
                    elif prob > options["Categorization", "spam_cutoff"]:
                        dest_folder = self.spam_folder
                        state.numSpams += 1
                    else:
                        dest_folder = self.unsure_folder
                        state.numUnsure += 1
                    if dest_folder:
                        msg = StringIO.StringIO(msg.as_string())
                        date = imaplib.Time2Internaldate(time.time())[1:-1]
                        dest_folder.addMessage(msg, (), date)

                        # We have to return something, because the client
                        # is expecting us to.  We return a short message
                        # indicating that a message was intercepted.
                        messageText = self.intercept_message % (prob,)
            except:
                messageText, details = \
                             message.insert_exception_header(messageText)

                # Print the exception and a traceback.
                print >> sys.stderr, details
            retval = ok + "\n" + messageText
            if terminatingDotPresent:
                retval += '.\r\n'
            return retval
        else:
            # Must be an error response.
            return response