diff --git a/CHANGES b/CHANGES index 68bc957..e39da13 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ 0.9.4 UNRELEASED - Create PID directory if it is missing - Fix crash when verifying if domain for signing was not set + - Fix header folding to use \n only to align with milter protocol + requirements 0.9.3 2018-03-02 - Fixup csl dataset processing for single item lists diff --git a/dkimpy_milter/__init__.py b/dkimpy_milter/__init__.py index b0220b2..12f3128 100644 --- a/dkimpy_milter/__init__.py +++ b/dkimpy_milter/__init__.py @@ -40,6 +40,7 @@ from dkimpy_milter.util import setExceptHook from dkimpy_milter.util import write_pid from dkimpy_milter.util import read_keyfile from dkimpy_milter.util import own_socketfile +from dkimpy_milter.util import fold __version__ = "0.9.4" FWS = re.compile(r'\r?\n[ \t]+') @@ -176,7 +177,7 @@ class dkimMilter(Milter.Base): if self.arresults: h = authres.AuthenticationResultsHeader(authserv_id = self.receiver, results=self.arresults) - h = dkim.fold(str(h)) + h = fold(str(h)) if milterconfig.get('Syslog'): syslog.syslog(str(h)) name,val = str(h).split(': ',1) diff --git a/dkimpy_milter/util.py b/dkimpy_milter/util.py index 37d7343..0b37b29 100644 --- a/dkimpy_milter/util.py +++ b/dkimpy_milter/util.py @@ -16,6 +16,39 @@ # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +def fold(header): + """Fold a header line into multiple crlf-separated lines at column 72. + Borrowed from dkimpy and updated to only add \n instead of \r\n because + that's what the milter protocol wants. + + >>> text(fold(b'foo')) + 'foo' + >>> text(fold(b'foo '+b'foo'*24).splitlines()[0]) + 'foo ' + >>> text(fold(b'foo'*25).splitlines()[-1]) + ' foo' + >>> len(fold(b'foo'*25).splitlines()[0]) + 72 + """ + i = header.rfind(b"\r\n ") + if i == -1: + pre = b"" + else: + i += 3 + pre = header[:i] + header = header[i:] + maxleng = 72 + while len(header) > maxleng: + i = header[:maxleng].rfind(b" ") + if i == -1: + j = maxleng + else: + j = i + 1 + pre += header[:j] + b"\n " + header = header[j:] + namelen = 0 + return pre + header + def user_group(userid): """Return user and group from UserID""" import grp