[Nym3-commit] r494 - trunk/nymbaron/Server

zax at conuropsis.org zax at conuropsis.org
Mon Mar 20 17:29:04 CET 2006


Author: zax
Date: 2006-03-20 17:29:03 +0100 (Mon, 20 Mar 2006)
New Revision: 494

Modified:
   trunk/nymbaron/Server/Main.py
Log:
Correct a bug where Base64 encoded messages were being processed as binary.  This was resulting in spurious "No Such User" messages during Control processing.


Modified: trunk/nymbaron/Server/Main.py
===================================================================
--- trunk/nymbaron/Server/Main.py	2006-03-20 14:04:11 UTC (rev 493)
+++ trunk/nymbaron/Server/Main.py	2006-03-20 16:29:03 UTC (rev 494)
@@ -42,6 +42,7 @@
 import re
 import logging
 import time
+import string
 
 lifeCycle = User.lifeCycle
 """The life cycle of a mail received by the server for a nym""" 
@@ -113,6 +114,31 @@
             else:
                 fun(nymuser)
 
+def isMsgBinary(msg):
+    """ This function returns True is the message is binary.  It
+    checks by checking what percentage of characters are non-textual.
+    In practice, all chars in base64 should be text but we allow a little
+    margin (20%) just to be on the safe side."""
+    text_characters = "".join(map(chr, range(32, 127)) + list("\n\r\t\b"))
+    _null_trans = string.maketrans("", "")
+    txtchars = msg.translate(_null_trans, text_characters)
+    txtlen = float(len(txtchars))
+    msglen = float(len(msg))
+    # If more than 20% of the message consists of non-text characters,
+    # then it's safe to assume it's binary.
+    if txtlen / msglen > 0.20:
+        return 1
+    return 0
+
+def isMsgBase64(msg):
+    """ Base64 payload should consist of nothing but text and newline
+    characters.  Check for this and return the payload if it matches.
+    Otherwise, return False"""
+    m = re.search('binary\n\n([\S\n]+)\n-{5}END', msg, re.S)
+    if m:
+        return m.group(1)
+    return 0
+
 def processIncoming(localpart, msg):
     """Process incoming mail from the MTA
     - identifies the nym the mail is addressed to
@@ -253,6 +279,7 @@
         processCreationRequest(msg)
     else:
         try:
+            logger.debug('We are trying to process a message for %s' % h.nym)
             nymUser = User.User(h.nym, config)
         except User.NoSuchUser:
             logger.debug("No such user %s" % h.nym)
@@ -401,23 +428,20 @@
         logger.debug("Got an incoming control message")
         try:
             msg = readMessage(options.file)
-            processMessage(msg)
+            if isMsgBinary(msg):
+                logger.debug('Control message is binary')
+                processMessage(msg)
+            else:
+                msgIsBase64 = isMsgBase64(msg)
+                if msgIsBase64:
+                    logger.debug('Control message is Base64')
+                    processMessage(base64.decodestring(msgIsBase64))
+                else:
+                    raise MalformedControlMessage
+
         except MalformedControlMessage, inst:
-            logger.info("Tried to parse as binary control message, failed: %s"\
-                        % str(inst))
-            # see if we got a base64 encoded message.
-            m = re.search("binary\\n\\n(.*)\\n---", msg, re.S)
-            if m:
-                try:
-                    processMessage(base64.decodestring(m.group(1)))
-                except MalformedControlMessage, inst:
-                    # We really had garbage as input, as we can't
-                    # parse it as binary or as base64 encoded.
-                    logger.error("Parse error in incoming control message %s" % str(inst))
-                    sys.exit(2) #TODO error code            
-            else:
-                logger.error("Unable to find valid control message")
-                sys.exit(2) #TODO error code            
+            logger.error("Cannot process control message")
+            sys.exit(2) #TODO error code            
         sys.exit(0)
     
     if args[1] == "clean-surbs":



More information about the Nym3-commit mailing list