[Spambayes-checkins] spambayes/scripts sb_server.py,1.29,1.30
Tony Meyer
anadelonbrin at users.sourceforge.net
Mon Nov 29 01:11:50 CET 2004
Update of /cvsroot/spambayes/spambayes/scripts
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6041/scripts
Modified Files:
sb_server.py
Log Message:
Fix error reported by Hatuka*nezumi:
Messages that did not have the required \r?\n\r?\n separator would just pass through
spambayes unproxied. Change this so that they are (everything will be a header,
though, so it may not proxy well, and might generate and exception header - but that's
better than just letting it through.
Index: sb_server.py
===================================================================
RCS file: /cvsroot/spambayes/spambayes/scripts/sb_server.py,v
retrieving revision 1.29
retrieving revision 1.30
diff -C2 -d -r1.29 -r1.30
*** sb_server.py 23 Nov 2004 23:37:15 -0000 1.29
--- sb_server.py 29 Nov 2004 00:11:46 -0000 1.30
***************
*** 457,566 ****
"""Adds the judgement header based on the raw headers and body
of the message."""
! # 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=spambayes.message.SBHeaderMessage)
! msg.setId(state.getNewMessageName())
! # Now find the spam disposition and add the header.
! (prob, clues) = state.bayes.spamprob(msg.tokenize(),\
! evidence=True)
! 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()
! if cls == options["Headers", "header_ham_string"]:
! state.numHams += 1
! elif cls == options["Headers", "header_spam_string"]:
! state.numSpams += 1
! else:
! state.numUnsure += 1
! # Suppress caching of "Precedence: bulk" or
! # "Precedence: list" ham if the options say so.
! isSuppressedBulkHam = \
! (cls == options["Headers", "header_ham_string"] and
! options["Storage", "no_cache_bulk_ham"] and
! msg.get('precedence') in ['bulk', 'list'])
! # Suppress large messages if the options say so.
! size_limit = options["Storage",
! "no_cache_large_messages"]
! isTooBig = size_limit > 0 and \
! len(messageText) > size_limit
! # Cache the message. Don't pollute the cache with test
! # messages or suppressed bulk ham.
! if (not state.isTest and
! options["Storage", "cache_messages"] and
! not isSuppressedBulkHam and not isTooBig):
! # Write the message into the Unknown cache.
! makeMessage = state.unknownCorpus.makeMessage
! message = makeMessage(msg.getId(), msg.as_string())
! state.unknownCorpus.addMessage(message)
! # We'll return the message with the headers added. We take
! # all the headers from the SBHeaderMessage, but take the body
! # directly from the POP3 conversation, because the
! # SBHeaderMessage might have "fixed" a partial message by
! # appending a closing boundary separator. Remember we can
! # be dealing with partial message here because of the timeout
! # code in onServerLine.
! 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
! except:
! # Something nasty happened while parsing or classifying -
! # report the exception in a hand-appended header and recover.
! # This is one case where an unqualified 'except' is OK, 'cos
! # anything's better than destroying people's email...
! stream = cStringIO.StringIO()
! traceback.print_exc(None, stream)
! details = stream.getvalue()
!
! # Build the header. This will strip leading whitespace from
! # the lines, so we add a leading dot to maintain indentation.
! detailLines = details.strip().split('\n')
! dottedDetails = '\n.'.join(detailLines)
! headerName = 'X-Spambayes-Exception'
! header = Header(dottedDetails, header_name=headerName)
! # Insert the header, converting email.Header's '\n' line
! # breaks to POP3's '\r\n'.
! headers, body = re.split(r'\n\r?\n', messageText, 1)
! header = re.sub(r'\r?\n', '\r\n', str(header))
! headers += "\n%s: %s\r\n\r\n" % (headerName, header)
! messageText = headers + body
! # Print the exception and a traceback.
! print >>sys.stderr, details
! # Restore the +OK and the POP3 .\r\n terminator if there was one.
! retval = ok + "\n" + messageText
! if terminatingDotPresent:
! retval += '.\r\n'
! return retval
! else:
! # Must be an error response.
! return response
def onTop(self, command, args, response):
--- 457,578 ----
"""Adds the judgement header based on the raw headers and body
of the message."""
! # Previously, we used '\n\r?\n' to detect the end of the headers in
! # case of broken emails that don't use the proper line separators,
! # and if we couldn't find it, then we assumed that the response was
! # and error response and passed it unfiltered. However, if the
! # message doesn't contain the separator (malformed mail), then this
! # would mean the message was passed straight through the proxy.
! # Since all the content is then in the headers, this probably
! # doesn't do a spammer much good, but, just in case, we now just
! # check for "+OK" and assume no error response will be given if
! # that is (which seems reasonable).
! # 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)
! if ok.strip().upper() != "+OK":
! # Must be an error response. Return unproxied.
! return response
! try:
! msg = email.message_from_string(messageText,
! _class=spambayes.message.SBHeaderMessage)
! msg.setId(state.getNewMessageName())
! # Now find the spam disposition and add the header.
! (prob, clues) = state.bayes.spamprob(msg.tokenize(),\
! evidence=True)
! 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()
! if cls == options["Headers", "header_ham_string"]:
! state.numHams += 1
! elif cls == options["Headers", "header_spam_string"]:
! state.numSpams += 1
! else:
! state.numUnsure += 1
! # Suppress caching of "Precedence: bulk" or
! # "Precedence: list" ham if the options say so.
! isSuppressedBulkHam = \
! (cls == options["Headers", "header_ham_string"] and
! options["Storage", "no_cache_bulk_ham"] and
! msg.get('precedence') in ['bulk', 'list'])
! # Suppress large messages if the options say so.
! size_limit = options["Storage",
! "no_cache_large_messages"]
! isTooBig = size_limit > 0 and \
! len(messageText) > size_limit
! # Cache the message. Don't pollute the cache with test
! # messages or suppressed bulk ham.
! if (not state.isTest and
! options["Storage", "cache_messages"] and
! not isSuppressedBulkHam and not isTooBig):
! # Write the message into the Unknown cache.
! makeMessage = state.unknownCorpus.makeMessage
! message = makeMessage(msg.getId(), msg.as_string())
! state.unknownCorpus.addMessage(message)
! # We'll return the message with the headers added. We take
! # all the headers from the SBHeaderMessage, but take the body
! # directly from the POP3 conversation, because the
! # SBHeaderMessage might have "fixed" a partial message by
! # appending a closing boundary separator. Remember we can
! # be dealing with partial message here because of the timeout
! # code in onServerLine.
! headers = []
! for name, value in msg.items():
! header = "%s: %s" % (name, value)
! headers.append(re.sub(r'\r?\n', '\r\n', header))
! try:
body = re.split(r'\n\r?\n', messageText, 1)[1]
+ except IndexError:
+ # No separator, so no body. Bad message, but proxy it
+ # through anyway (adding the missing separator).
+ messageText = "\r\n".join(headers) + "\r\n\r\n"
+ else:
messageText = "\r\n".join(headers) + "\r\n\r\n" + body
! except:
! # Something nasty happened while parsing or classifying -
! # report the exception in a hand-appended header and recover.
! # This is one case where an unqualified 'except' is OK, 'cos
! # anything's better than destroying people's email...
! stream = cStringIO.StringIO()
! traceback.print_exc(None, stream)
! details = stream.getvalue()
! # Build the header. This will strip leading whitespace from
! # the lines, so we add a leading dot to maintain indentation.
! detailLines = details.strip().split('\n')
! dottedDetails = '\n.'.join(detailLines)
! headerName = 'X-Spambayes-Exception'
! header = Header(dottedDetails, header_name=headerName)
! # Insert the header, converting email.Header's '\n' line
! # breaks to POP3's '\r\n'.
! headers, body = re.split(r'\n\r?\n', messageText, 1)
! header = re.sub(r'\r?\n', '\r\n', str(header))
! headers += "\n%s: %s\r\n\r\n" % (headerName, header)
! messageText = headers + body
! # Print the exception and a traceback.
! print >>sys.stderr, details
! # Restore the +OK and the POP3 .\r\n terminator if there was one.
! retval = ok + "\n" + messageText
! if terminatingDotPresent:
! retval += '.\r\n'
! return retval
def onTop(self, command, args, response):
***************
*** 656,659 ****
--- 668,672 ----
if options["globals", "verbose"]:
self.logFile = open('_pop3proxy.log', 'wb', 0)
+
self.servers = []
self.proxyPorts = []
More information about the Spambayes-checkins
mailing list