valimail / authentication-headers Goto Github PK
View Code? Open in Web Editor NEWlibrary for the generation of email authentication headers
License: Other
library for the generation of email authentication headers
License: Other
For example, this code does not catch the following errors:
dns.resolver.NoNameservers: All nameservers failed to answer the query ...
dns.exception.Timeout: The DNS operation timed out after 5.00025124217713 seconds
def check_dkim(msg, dnsfunc=None):
try:
d = DKIM(msg)
if(dnsfunc):
res = d.verify(dnsfunc=dnsfunc) and 'pass' or 'fail'
else:
res = d.verify() and 'pass' or 'fail'
except DKIMException as e:
res = 'fail'
I have fixed this on my independently maintained fork but I wanted to file it so you were aware.
This is currently in the README:
authenticate_message(message, "example.com", ip='192.168.50.81', mail_from="test.com", helo="domain.of.sender.net")
However this is how it is defined in the Python code:
authenticate_message(msg, authserv_id, prev=None, spf=False, dkim=True, arc=False, dmarc=True, ip=None, mail_from=None, helo=None, dnsfunc=None, psddmarc=False):
The arguments aren't the same, and unless I'm missing something, this usage from the README would not work properly.
20|smtp | Error: Traceback (most recent call last):
20|smtp | File "/var/www/production/source/node_modules/authheaders/scripts/authenticate-message.py", line 36, in <module>
20|smtp | main()
20|smtp | File "/var/www/production/source/node_modules/authheaders/scripts/authenticate-message.py", line 25, in main
20|smtp | header = authheaders.authenticate_message(msg=message, authserv_id=authservId, ip=ip, mail_from=mailFrom, helo=helo, spf=True, dkim=True, arc=True)
20|smtp | File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 298, in authenticate_message
20|smtp | return str(auth_res)
20|smtp | File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 476, in __str__
20|smtp | return ''.join((self.HEADER_FIELD_NAME, ': ', self.header_value()))
20|smtp | File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 492, in header_value
20|smtp | strs.append(str(result))
20|smtp | File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 222, in __str__
20|smtp | strs.append(str(property_))
20|smtp | File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 132, in __str__
20|smtp | return '%s.%s=%s' % (self.type, self.name, self.value.quote_if_needed())
20|smtp | AttributeError: 'str' object has no attribute 'quote_if_needed'
20|smtp | at ChildProcess.<anonymous> (/var/www/production/source/node_modules/authheaders/index.js:61:44)
20|smtp | at ChildProcess.emit (events.js:323:22)
20|smtp | at maybeClose (internal/child_process.js:1021:16)
20|smtp | at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
You can see the error occurs here in the code:
return '%s.%s=%s' % (self.type, self.name, self.value.quote_if_needed())
In authheaders 0.15.1 there are except DNSException
clauses at lines 279 and 305, but DNSException
is neither imported nor defined.
Hi! 👋
I package this project for Arch Linux. I would like to point out that the newly added dependency on importlib_resources
is problematic/ not needed:
The importlib_resources project has been introduced to upstream the module as importlib.resources into cpython. This work has been completed with Python 3.7 (which has been released in 2018) and AFAIK the project now exists to add further features only.
That all being said: According to https://www.python.org/downloads/ the range of currently supported Python versions is 3.8 - 3.12 and I am wondering why #28 added a dependency on importlib_resources
and not importlib.resources
, which would not require to have another dependency at all. If anything downstream distributions want to get rid of importlib_resources
and replace it with importlib.resources
not the other way round!
Furthermore, I am wondering about the definition of requirements as is done here:
authentication-headers/setup.py
Lines 108 to 123 in 1e81143
Why is this project targeting 3.3, a Python version that has been introduced in 2012 and EOL'ed in 2017? Relatedly, each requirement can be made to depend on a particular Python version! There is no need to specify them all again.
Closing:
For downstreams using importlib_resources
has no benefit and it would be much preferred if importlib.resources
was used.
Targeting EOL'ed Python versions without testing against them (or any of the newer ones) should be circumvented, as it introduces more and more workarounds etc. It is much cleaner and more straight forward to only target Python versions actually supported by the Python project!
I wasn't able to get Travis to build unless I either upgraded from xenial to bionic (which put my version to 3.6), or manually used pyenv command on xenial to upgrade from v3.5 to v3.6.
https://travis-ci.com/github/forwardemail/authheaders (see build history)
When parsing an email whose From field is formatted like:
From: "Lastname, Firstname" <[email protected]>
authentication fails with a trace like:
Traceback (most recent call last):
File "authheaders/test/test_authentication.py", line 124, in test_authenticate_headers
res = authenticate_message(self.message8, "example.com", spf=False, dkim=False, dmarc=True, dnsfunc=self.dnsfunc)
File "/code/conda_envs/fdsn_website/lib/python2.7/site-packages/authheaders/__init__.py", line 289, in authenticate_message
dmarc_result = check_dmarc(msg, spf_result, dkim_result, dnsfunc=dnsfunc, psddmarc=psddmarc)
File "/code/conda_envs/fdsn_website/lib/python2.7/site-packages/authheaders/__init__.py", line 220, in check_dmarc
from_domain = get_domain_part(from_header)
File "/code/conda_envs/fdsn_website/lib/python2.7/site-packages/authheaders/__init__.py", line 49, in get_domain_part
return res[0].decode('ascii')
IndexError: list index out of range
I think the problem is at
https://github.com/ValiMail/authentication-headers/blob/master/authheaders/__init__.py#L214
from_headers = [x[1].split(b',') for x in headers if x[0].lower() == b"from"][0]
This yields an email address of Firstname" <[email protected]>
for the example above.
I would propose a fix using email.utils.getaddresses
:
from_headers = [a[1] for a in getaddresses(x[1] for x in headers if x[0].lower() == b"from")]
This worked for me, and passes all the other unit tests.
If this fix seems reasonable, I can submit a PR for it.
I have a message that produces this, but it is unwieldy and I tried to edit it down, but that produced a different issue.
Here's a traceback
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/opt/mailman/mm/venv/lib/python3.9/site-packages/mailman/utilities/retry.py", line 44, in f_retry
return f(*args, **kwargs)
File "/opt/mailman/mm/venv/lib/python3.9/site-packages/mailman/handlers/validate_authenticity.py", line 93, in authenticate
auth_result = authenticate_message(
File "/opt/mailman/mm/venv/lib/python3.9/site-packages/authheaders/__init__.py", line 416, in authenticate_message
arc_result = check_arc(msg, None, dnsfunc=dnsfunc)
File "/opt/mailman/mm/venv/lib/python3.9/site-packages/authheaders/__init__.py", line 316, in check_arc
return ARCAuthenticationResult(result=cv.decode('ascii'), result_comment=comment)
AttributeError: 'NoneType' object has no attribute 'decode'
The relevant code is:
def check_arc(msg, logger=None, dnsfunc=None):
""" Compute the chain validation status of an inbound message.
@param msg: an RFC822 formatted message (with either \\n or \\r\\n line endings)
@param logger: An optional logger
@param dnsfunc: An optional dns lookup function (intended for testing)
"""
a = ARC(msg)
try:
if(dnsfunc):
cv, results, comment = a.verify(dnsfunc=dnsfunc)
else:
cv, results, comment = a.verify()
except DKIMException as e:
cv, results, comment = CV_Fail, [], "%s" % e
except DNSException as e:
cv, results, comment = CV_Fail, [], "%s" % e
except Exception as e:
cv, results, comment = CV_Fail, [], "%s" % e
if comment == 'success':
comment = None
return ARCAuthenticationResult(result=cv.decode('ascii'), result_comment=comment)
The problem is the verify
method of the ARC
instance can return cv = None per lines 1186-1188 in dkim/init.py
for result in result_data:
if result['cv'] == CV_Fail:
return None, result_data, "ARC-Seal[%d] reported failure, the chain is terminated" % result['instance']
and this results in the exception.
Hi! I'd like to package python-authheaders for Arch Linux (as I need it for mailman3).
However, the latest release 0.12.1 is missing a detached PGP signature (although former versions have this, both on pypi and here on github).
I know this probably happened for no bad reason, but in the light of last year's supply chain attacks on several distros and language repositories, @kitterma I'm hereby asking you to please add a PGP signature to the last release, so that downstreams can verify it.
This is similar to #5 and #15, but is not fixed by the fix for those.
Given a message with
From: "Joe User"
authenticate_message(msg.as_bytes(), 'example.com', dmarc=True)
fails with
File "/opt/mailman/mm/venv/lib/python3.9/site-packages/authheaders/__init__.py", line 396, in authenticate_message
dmarc_result = check_dmarc(msg, spf_result, dkim_result, dnsfunc=dnsfunc, psddmarc=psddmarc)
File "/opt/mailman/mm/venv/lib/python3.9/site-packages/authheaders/__init__.py", line 343, in check_dmarc
from_domain = get_domain_part(from_header)
File "/opt/mailman/mm/venv/lib/python3.9/site-packages/authheaders/__init__.py", line 53, in get_domain_part
return res[0].lower().decode('ascii')
IndexError: list index out of range
This is with authheaders=0.15.2.
Granted this is a defective message, but I think rather than throwing IndexError, authenticate_message should return something with dmarc=permerror
There seems to be a bug when trying to parse DKIM... It's trying to use 0th key but it doesn't exist, and thus throws this error.
Traceback (most recent call last):␊
File "/Users/user/Projects/authheaders/scripts/authenticate-message.py", line 33, in <module>␊
main()␊
File "/Users/user/Projects/authheaders/scripts/authenticate-message.py", line 24, in main␊
header = authheaders.authenticate_message(msg=message, authserv_id=authservId, ip=ip, mail_from=mailFrom, helo=helo, spf=True, dkim=True, arc=True)␊
File "/usr/local/lib/python3.8/site-packages/authheaders/__init__.py", line 282, in authenticate_message␊
dkim_result = check_dkim(msg)␊
File "/usr/local/lib/python3.8/site-packages/authheaders/__init__.py", line 63, in check_dkim␊
res = d.verify() and 'pass' or 'fail'␊
File "/usr/local/lib/python3.8/site-packages/dkim/__init__.py", line 940, in verify␊
return self.verify_sig(sig, include_headers, sigheaders[idx], dnsfunc)␊
File "/usr/local/lib/python3.8/site-packages/dkim/__init__.py", line 773, in verify_sig␊
self.pk, self.keysize, self.ktag, self.seqtlsrpt = load_pk_from_dns(name,␊
File "/usr/local/lib/python3.8/site-packages/dkim/__init__.py", line 481, in load_pk_from_dns␊
s = dnsfunc(name, timeout=timeout)␊
File "/usr/local/lib/python3.8/site-packages/dkim/dnsplug.py", line 88, in get_txt␊
txt = _get_txt(unicode_name, timeout)␊
File "/usr/local/lib/python3.8/site-packages/dkim/dnsplug.py", line 34, in get_txt_dnspython␊
return b"".join(r.items[0].strings)␊
KeyError: 0
authheaders.dmarc_lookup.answer_to_dict() throws IndexError: list index out of range if given a string ending with an empty quoted value. Examples of dmark records which throw this error are:
_dmarc.wheaton.edu. 3600 IN TXT "v=DMARC1; p=none; rua=mailto:[email protected],mailto:[email protected]; ruf=mailto:[email protected],mailto:[email protected]; fo=1;" ""
and
_dmarc.virginia.edu. 3600 IN TXT "v=DMARC1; p=reject; rua=mailto:[email protected]; ruf=mailto:[email protected]; sp=none;" "" ""
File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 291, in authenticate_message
dmarc_result = check_dmarc(msg, spf_result, dkim_result, dnsfunc=dnsfunc, psddmarc=psddmarc)
File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 240, in check_dmarc
from_domain = get_domain_part(from_header)
File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 51, in get_domain_part
return res[0].decode('ascii')
IndexError: list index out of range
Error: Traceback (most recent call last):
File "/var/www/production/source/node_modules/authheaders/scripts/authenticate-message.py", line 33, in <module>
main()
File "/var/www/production/source/node_modules/authheaders/scripts/authenticate-message.py", line 24, in main
header = authheaders.authenticate_message(msg=message, authserv_id=authservId, ip=ip, mail_from=mailFrom, helo=helo, spf=True, dkim=True, arc=True)
File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 291, in authenticate_message
dmarc_result = check_dmarc(msg, spf_result, dkim_result, dnsfunc=dnsfunc, psddmarc=psddmarc)
File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 240, in check_dmarc
from_domain = get_domain_part(from_header)
File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 51, in get_domain_part
return res[0].decode('ascii')
IndexError: list index out of range
This is similar to #26, but in this case the invalid DMARC record is v=DMARC1;p=none;pct=100;rua=mailto:[email protected];mailto:[email protected];ri=3600;fo=1;
. This record is invalid because it contains a field missing the tag=
portion, i.e., ;mailto:[email protected]
should be something like ;ruf=mailto:[email protected]
but ruf=
is missing.
This results in
Dec 22 04:54:28 2023 (28) Traceback (most recent call last):
File "/usr/lib/python3.10/site-packages/mailman/core/runner.py", line 179, in _one_iteration
self._process_one_file(msg, msgdata)
File "/usr/lib/python3.10/site-packages/mailman/core/runner.py", line 272, in _process_one_file
keepqueued = self._dispose(mlist, msg, msgdata)
File "/usr/lib/python3.10/site-packages/mailman/runners/pipeline.py", line 37, in _dispose process(mlist, msg, msgdata, pipeline)
File "/usr/lib/python3.10/site-packages/mailman/core/pipelines.py", line 53, in process
handler.process(mlist, msg, msgdata)
File "/usr/lib/python3.10/site-packages/mailman/handlers/validate_authenticity.py", line 125, in process
authenticate(msg, msgdata)
File "/usr/lib/python3.10/site-packages/mailman/utilities/retry.py", line 44, in f_retry
return f(*args, **kwargs)
File "/usr/lib/python3.10/site-packages/mailman/handlers/validate_authenticity.py", line 93, in authenticate
auth_result = authenticate_message(
File "/usr/lib/python3.10/site-packages/authheaders/__init__.py", line 395, in authenticate_message
dmarc_result = check_dmarc(msg, spf_result, dkim_result, dnsfunc=dnsfunc, psddmarc=psddmarc)
File "/usr/lib/python3.10/site-packages/authheaders/__init__.py", line 343, in check_dmarc
result, result_comment, from_domain, policy = dmarc_per_from(from_domain, spf_result, dkim_result, dnsfunc, psddmarc)
File "/usr/lib/python3.10/site-packages/authheaders/__init__.py", line 90, in dmarc_per_from
record, orgdomain = receiver_record(from_domain)
File "/usr/lib/python3.10/site-packages/authheaders/dmarc_lookup.py", line 117, in receiver_record
retval = lookup_receiver_record(hostSansDmarc, dnsfunc)
File "/usr/lib/python3.10/site-packages/authheaders/dmarc_lookup.py", line 92, in lookup_receiver_record
tags = answer_to_dict(str(result))
File "/usr/lib/python3.10/site-packages/authheaders/dmarc_lookup.py", line 42, in answer_to_dict
retval = {t[0].strip().lower(): t[1].strip().lower() for t in rawTags}
File "/usr/lib/python3.10/site-packages/authheaders/dmarc_lookup.py", line 42, in <dictcomp>
retval = {t[0].strip().lower(): t[1].strip().lower() for t in rawTags}
IndexError: list index out of range
The following error was occurring:
133902:Error: Traceback (most recent call last):
133903- File "/var/www/production/source/node_modules/authheaders/scripts/authenticate-message.py", line 36, in <module>
133904- main()
133905- File "/var/www/production/source/node_modules/authheaders/scripts/authenticate-message.py", line 25, in main
133906- header = authheaders.authenticate_message(msg=message, authserv_id=authservId, ip=ip, mail_from=mailFrom, helo=helo, spf=True, dkim=True, arc=True)
133907- File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 286, in authenticate_message
133908- dkim_result = check_dkim(msg, dnsfunc=dnsfunc)
133909- File "/home/deploy/.local/lib/python3.6/site-packages/authheaders/__init__.py", line 63, in check_dkim
133910- d = DKIM(msg)
133911- File "/home/deploy/.local/lib/python3.6/site-packages/dkim/__init__.py", line 504, in __init__
133912- self.set_message(message)
133913- File "/home/deploy/.local/lib/python3.6/site-packages/dkim/__init__.py", line 607, in set_message
133914- self.headers, self.body = rfc822_parse(message)
133915- File "/home/deploy/.local/lib/python3.6/site-packages/dkim/__init__.py", line 356, in rfc822_parse
133916- raise MessageFormatError("Unexpected characters in RFC822 header: %s" % lines[i])
133917-dkim.MessageFormatError: Unexpected characters in RFC822 header: b'This is a multi-part message in MIME format.'
133918-
133919- at ChildProcess.<anonymous> (/var/www/production/source/node_modules/authheaders/index.js:61:44)
133920- at ChildProcess.emit (events.js:323:22)
133921- at maybeClose (internal/child_process.js:1021:16)
133922- at Process.ChildProcess._handle.onexit (internal/child_process.js:286:5)
I noticed that this package needed this changed in authheaders/__init__.py
:
def check_dkim(msg, dnsfunc=None):
- d = DKIM(msg)
try:
+ d = DKIM(msg)
if(dnsfunc):
res = d.verify(dnsfunc=dnsfunc) and 'pass' or 'fail'
else:
The reason is because DKIM(msg)
will then call dkimpy
's set_message
function, which will then call rfc822_parse
, which, if it contains an unexpected character, will throw an exception.
For example, you could send across the following headers, and this would cause this lib to throw an exception instead of saying that DKIM failed (which is what my fix properly does).
Received: foobar
Subject: foobar
To: [email protected]
From: [email protected]
Date: Fri, 7 Aug 2020 00:41:34 -0300
MIME-Version: 1.0
This is a multi-part message in MIME format.
Foobar
Here is the link to my commit with the fix in my independently maintained version:
When packaging 0.13.0 I had a closer look at how to devendor/provide the different lists.
While we do package publicsuffix-list on Arch Linux (and I can actually just symlink our version of it in place), I realized, that although setup.py implies, that there is an embedded version of the PSD DMARC registry list, there actually is none in authheaders/psddmarc.csv.
Looking at https://psddmarc.org it's also very intransparent where this list gets generated (if at all), how often it will change, where its upstream is and who is actually responsible for it.
I plan on adding it to python-authheaders for now, but maybe there's a better way and you know more about the list's background?
Traceback (most recent call last):␊
File "/Users/test/Projects/authheaders/scripts/authenticate-message.py", line 3, in <module>␊
import authheaders␊
File "/usr/local/lib/python3.8/site-packages/authheaders/__init__.py", line 23, in <module>␊
from authheaders.dmarc_lookup import dns_query, receiver_record, get_org_domain␊
File "/usr/local/lib/python3.8/site-packages/authheaders/dmarc_lookup.py", line 28, in <module>␊
from dns.resolver import (query, NXDOMAIN, NoAnswer, NoNameservers)␊
ModuleNotFoundError: No module named 'dns'
I have discovered a core bug with this package. Full stack trace below:
ARC signature error message: Traceback (most recent call last):
File "/var/www/production/source/node_modules/dkimpy/scripts/arcsign.py", line 79, in <module>
main()
File "/var/www/production/source/node_modules/dkimpy/scripts/arcsign.py", line 70, in main
srv_id, cv, linesep=dkim.util.get_linesep(message))
File "/home/deploy/.local/lib/python3.6/site-packages/dkim/__init__.py", line 1399, in arc_sign
timestamp=timestamp, standardize=standardize)
File "/home/deploy/.local/lib/python3.6/site-packages/dkim/__init__.py", line 1025, in sign
for res in ar_headers]
File "/home/deploy/.local/lib/python3.6/site-packages/dkim/__init__.py", line 1025, in <listcomp>
for res in ar_headers]
File "/home/deploy/.local/lib/python3.6/site-packages/authres/__init__.py", line 206, in parse
return authres.core.AuthenticationResultsHeader.parse(core_features(), string)
File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 442, in parse
return self.parse_value(feature_context, string)
File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 454, in parse_value
header._parse()
File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 517, in _parse
result = self._parse_resinfo()
File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 550, in _parse_resinfo
method, version, result = self._parse_methodspec()
File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 570, in _parse_methodspec
method, version = self._parse_method()
File "/home/deploy/.local/lib/python3.6/site-packages/authres/core.py", line 583, in _parse_method
raise SyntaxError('Expected method', self._parse_text)
During packaging I realized, that publicsuffix is not supposed to be in use anymore.
I guess a more up-to-date and still maintained solution would be to switch to publicsuffix2 or publicsuffixlist.
What do you think?
<doctest authheaders.dmarc_lookup.answer_to_dict[0]>:1: SyntaxWarning: invalid escape sequence '\;'
answer_to_dict("v=DMARC1\; p=reject\; rua=mailto:[email protected],mailto:[email protected]\; ruf=mailto:[email protected],mailto:[email protected]")
<doctest authheaders.dmarc_lookup.answer_to_dict[1]>:1: SyntaxWarning: invalid escape sequence '\;'
answer_to_dict("v=DMARC1\; p=none\; sp=reject")
Traceback (most recent call last):␊
File "/Users/test/Projects/authheaders/scripts/authenticate-message.py", line 33, in <module>␊
main()␊
File "/Users/test/Projects/authheaders/scripts/authenticate-message.py", line 24, in main␊
header = authheaders.authenticate_message(msg=message, authserv_id=authservId, ip=ip, mail_from=mailFrom, helo=helo, spf=True, dkim=True, arc=True)␊
File "/usr/local/lib/python3.8/site-packages/authheaders-0.13.0-py3.8.egg/authheaders/__init__.py", line 291, in authenticate_message␊
dmarc_result = check_dmarc(msg, spf_result, dkim_result, dnsfunc=dnsfunc, psddmarc=psddmarc)␊
File "/usr/local/lib/python3.8/site-packages/authheaders-0.13.0-py3.8.egg/authheaders/__init__.py", line 239, in check_dmarc␊
from_header = from_headers[0]␊
IndexError: list index out of range
As you can see I submitted a message and omitted the "From:" header line, and thus this error was thrown.
Trying to sign a message with DKIM, I get this error:
TypeError: sign() got an unexpected keyword argument 'timestamp'
Looking at dkimpy
this seems like a valid error -- ARC.sign()
takes a "timestamp" parameter but DKIM.sign()
doesn't.
A message with a From: header like
From: "Txxxxxx Mxxxxxxx de Vxxxxxx, Fxxxxxxxx" <[email protected]>
when flattened as_bytes and passed to check_dmark will have the header folded as
From: "Txxxxxx Mxxxxxxx de Vxxxxxx,
Fxxxxxxxx" <[email protected]>
While this is reported as a bug at python/cpython#114362, it is compliant with RFC 5322 which allows FWS within a quoted string.
In any case the code acting on this does the following:
headers, _ = rfc822_parse(msg)
which returns one of the elements in the headers list as
[b'From', b' "Txxxxxx Mxxxxxxx de Vxxxxxx,\r\n Fxxxxxxxx" <[email protected]>\r\n']
and then
from_headers = [a[1] for a in getaddresses(x[1].decode(errors='ignore').strip() for x in headers if x[0].lower() == b"from")]
yields
['Txxxxxx Mxxxxxxx de Vxxxxxx,']
as from_headers.
One way to fix this is to change
from_headers = [a[1] for a in getaddresses(x[1].decode(errors='ignore').strip() for x in headers if x[0].lower() == b"from")]
to
from_headers = [a[1] for a in getaddresses(x[1].replace(b'\r\n', b'')
.decode(errors='ignore').strip() for x in headers
if x[0].lower() == b"from")]
to unfold the header value before passing it to getaddresses. Normally getaddresses handles folded headers, but I think folding with \r\n
is an issue.
Hi! I'm packaging this project for Arch Linux.
As we are now supporting the use of SPDX license identifiers (https://spdx.org/licenses/), I'm trying to find out what is the license identifier for this license:
authentication-headers/COPYING
Lines 2 to 19 in 05ff686
Maybe you can help me figure this out? :)
Hi! I package this project for Arch Linux.
For 0.15.3 there seem to be no release artifacts (sources, signed sources) yet.
I would expect this method to always return an Authentication-Results header, but for some reason on certain messages (perhaps due to length?) I am not sure, but it does not return a String value for this new header.
Here is the header it fails on:
From: =?UTF-8?B?QmVkIEJhdGggJiBCZXlvbmQ=?=
<BedBath&[email protected]>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.