[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[minion-cvs] Changed base-64 encoding to wrap at 64-characters inste...
Update of /home/minion/cvsroot/src/minion/lib/mixminion
In directory moria.mit.edu:/tmp/cvs-serv4265/lib/mixminion
Modified Files:
Common.py Crypto.py Packet.py test.py
Log Message:
Changed base-64 encoding to wrap at 64-characters instead of 76.
Why was this necessary? Because Outlook breaks up long lines, you see.
But it isn't as simple as that. If Outlook simply turned "ABC\n" into
"AB\nC\n", we'd be fine. Instead, Outlook searches for a plus sign, and
turns "A+BC\n" into "A+B\nA+C\n", thus **corrupting** the data.
I hope those responsible for this feature -- which they doubtlessly
thought was very clever indeed -- are deeply, deeply ashamed of
themselves.
Clippy helpfully says: "You seem to be corrupting user data. Do you
want me to teach you about transport layers?"
Index: Common.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Common.py,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -d -r1.61 -r1.62
--- Common.py 13 Feb 2003 07:03:49 -0000 1.61
+++ Common.py 16 Feb 2003 04:50:55 -0000 1.62
@@ -7,13 +7,14 @@
__all__ = [ 'IntervalSet', 'Lockfile', 'LOG', 'LogStream', 'MixError',
'MixFatalError', 'MixProtocolError', 'UIError', 'UsageError',
- 'ceilDiv', 'checkPrivateDir', 'createPrivateDir', 'floorDiv',
+ 'ceilDiv', 'checkPrivateDir', 'createPrivateDir',
+ 'encodeBase64', 'floorDiv',
'formatBase64', 'formatDate', 'formatFnameTime', 'formatTime',
'installSIGCHLDHandler', 'isSMTPMailbox', 'openUnique',
'previousMidnight', 'readPossiblyGzippedFile', 'secureDelete',
'stringContains', 'succeedingMidnight', 'waitForChildren' ]
-import base64
+import binascii
import bisect
import calendar
import fcntl
@@ -121,8 +122,21 @@
def formatBase64(s):
"""Convert 's' to a one-line base-64 representation."""
- return base64.encodestring(s).replace("\n", "")
+ return binascii.b2a_base64(s).strip()
+def encodeBase64(s, lineWidth=64):
+ """Convert 's' to a multiline base-64 representation. Improves upon
+ base64.encodestring by having a variable line width. Implementation
+ is based upon that function.
+ """
+ # XXXX003 test me
+ pieces = []
+ bytesPerLine = floorDiv(lineWidth, 4) * 3
+ for i in xrange(0, len(s), bytesPerLine):
+ chunk = s[i:i+bytesPerLine]
+ pieces.append(binascii.b2a_base64(chunk))
+ return "".join(pieces)
+
#----------------------------------------------------------------------
def createPrivateDir(d, nocreate=0):
"""Create a directory, and all parent directories, checking permissions
Index: Crypto.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Crypto.py,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- Crypto.py 11 Feb 2003 22:18:10 -0000 1.40
+++ Crypto.py 16 Feb 2003 04:50:55 -0000 1.41
@@ -8,7 +8,6 @@
the functions in mixminion.Crypto, and not call _minionlib's crypto
functionality themselves."""
-import base64
import binascii
import copy_reg
import errno
@@ -580,7 +579,7 @@
mode = "wb"
while 1:
bytes = self.getBytes(6)
- base = base64.encodestring(bytes).strip().replace("/","-")
+ base = binascii.b2a_base64(bytes).strip().replace("/","-")
fname = os.path.join(dir, "%s%s"%(prefix,base))
try:
fd = os.open(fname, flags, 0600)
Index: Packet.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/Packet.py,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- Packet.py 13 Feb 2003 10:56:40 -0000 1.33
+++ Packet.py 16 Feb 2003 04:50:55 -0000 1.34
@@ -24,15 +24,14 @@
'parseTextEncodedMessage', 'parseTextReplyBlocks', 'uncompressData'
]
-import base64
import binascii
import re
import struct
import sys
import zlib
from socket import inet_ntoa, inet_aton
-from mixminion.Common import MixError, MixFatalError, floorDiv, formatTime, \
- isSMTPMailbox, LOG
+from mixminion.Common import MixError, MixFatalError, encodeBase64, \
+ floorDiv, formatTime, isSMTPMailbox, LOG
from mixminion.Crypto import sha1
if sys.version_info[:3] < (2,2,0):
@@ -520,7 +519,7 @@
def packAsText(self):
"""Returns the external text representation of this reply block"""
- text = base64.encodestring(self.pack())
+ text = encodeBase64(self.pack())
if not text.endswith("\n"):
text += "\n"
return "%s\nVersion: 0.1\n%s%s\n"%(RB_TEXT_START,text,RB_TEXT_END)
@@ -733,7 +732,7 @@
preNL = postNL = ""
if self.messageType != 'TXT':
- c = base64.encodestring(c)
+ c = encodeBase64(c)
else:
#XXXX004 disable "decoding handle" format
if (c.startswith("Decoding-handle:") or
Index: test.py
===================================================================
RCS file: /home/minion/cvsroot/src/minion/lib/mixminion/test.py,v
retrieving revision 1.90
retrieving revision 1.91
diff -u -d -r1.90 -r1.91
--- test.py 14 Feb 2003 17:51:57 -0000 1.90
+++ test.py 16 Feb 2003 04:50:55 -0000 1.91
@@ -1223,12 +1223,12 @@
eq(mt3.pack(), start+"\nDecoding-handle: gotcha!\nFoobar\n"+end)
# Text generation: binary case
v = hexread("00D1E50FED1F1CE5")*12
- v64 = base64.encodestring(v)
+ v64 = encodeBase64(v)
mb1 = tem(v, "BIN")
eq(mb1.pack(), start+"""\
Message-type: binary
-ANHlD+0fHOUA0eUP7R8c5QDR5Q/tHxzlANHlD+0fHOUA0eUP7R8c5QDR5Q/tHxzlANHlD+0fHOUA
-0eUP7R8c5QDR5Q/tHxzlANHlD+0fHOUA0eUP7R8c5QDR5Q/tHxzl
+ANHlD+0fHOUA0eUP7R8c5QDR5Q/tHxzlANHlD+0fHOUA0eUP7R8c5QDR5Q/tHxzl
+ANHlD+0fHOUA0eUP7R8c5QDR5Q/tHxzlANHlD+0fHOUA0eUP7R8c5QDR5Q/tHxzl
"""+end)
eq(mb1.pack(), start+"Message-type: binary\n"+v64+end)
# Overcompressed
@@ -2250,7 +2250,7 @@
self.assertEquals(pbin, pkt.getContents())
self.assert_(pkt.isPlaintext())
self.failIf(pkt.isPrintingAscii())
- self.assertEquals(base64.encodestring(pkt.getContents()),
+ self.assertEquals(encodeBase64(pkt.getContents()),
pkt.getAsciiContents())
# with an overcompressed content
pcomp = " "*4096
@@ -2265,7 +2265,7 @@
self.assert_(not pkt.isPlaintext())
self.assert_(pkt.isOvercompressed())
self.assert_(pkt.getAsciiContents(),
- base64.encodestring(compressData(pcomp)))
+ encodeBase64(compressData(pcomp)))
m = befm(p, SMTP_TYPE, "nobody@invalid", [self.server1],
[self.server3], getRSAKey(0,1024))
@@ -2278,7 +2278,7 @@
self.assert_(pkt.isEncrypted())
self.assert_(not pkt.isPrintingAscii())
self.assertEquals(len(pkt.getContents()), 28*1024)
- self.assertEquals(base64.encodestring(pkt.getContents()),
+ self.assertEquals(encodeBase64(pkt.getContents()),
pkt.getAsciiContents())
def test_rejected(self):
@@ -4079,11 +4079,11 @@
# Tests escapeMessageForEmail
self.assert_(stringContains(eme(FDPFast('plain',message)), message))
expect = "BEGINS =======\nMessage-type: binary\n"+\
- base64.encodestring(binmessage)+"====="
+ encodeBase64(binmessage)+"====="
self.assert_(stringContains(eme(FDPFast('plain',binmessage)), expect))
expect = "BEGINS =======\nDecoding-handle: "+\
base64.encodestring(tag)+\
- base64.encodestring(binmessage)+"====="
+ encodeBase64(binmessage)+"====="
self.assert_(stringContains(eme(FDPFast('enc',binmessage,tag)),
expect))
@@ -4113,9 +4113,10 @@
======= TYPE III ANONYMOUS MESSAGE BEGINS =======
Decoding-handle: eHh4eHh4eHh4eHh4eHh4eHh4eHg=
-7/rOqx76yt7v+s6rHvrK3u/6zqse+sre7/rOqx76yt7v+s6rHvrK3u/6zqse+sre7/rOqx76yt7v
-+s6rHvrK3u/6zqse+sre7/rOqx76yt7v+s6rHvrK3u/6zqse+sre7/rOqx76yt7v+s6rHvrK3u/6
-zqse+sre7/rOqx76yt7v+s6rHvrK3u/6zqse+sre7/rOqx76yt7v+s6rHvrK3g==
+7/rOqx76yt7v+s6rHvrK3u/6zqse+sre7/rOqx76yt7v+s6rHvrK3u/6zqse+sre
+7/rOqx76yt7v+s6rHvrK3u/6zqse+sre7/rOqx76yt7v+s6rHvrK3u/6zqse+sre
+7/rOqx76yt7v+s6rHvrK3u/6zqse+sre7/rOqx76yt7v+s6rHvrK3u/6zqse+sre
+7/rOqx76yt7v+s6rHvrK3g==
======== TYPE III ANONYMOUS MESSAGE ENDS ========
"""