Skip to content

Commit b57d9b9

Browse files
committed
search through all namespaces
The mail providers gmx.net and web.de send dmarc reports with xml dmarc namespaces (https://datatracker.ietf.org/doc/draft-ietf-dmarc-aggregate-reporting/): <?xml version="1.0" encoding="UTF-8"?> <feedback xmlns="urn:ietf:params:xml:ns:dmarc-2.0"> <report_metadata> ... and generate a parsing error Error while parsing files/gmx.net!example.org!1721865600!1721951999!0d5403a6-de18-473b-938e-2bc41d0d271e.xml: File "files/gmx.net!example.org!1721865600!1721951999!0d5403a6-de18-473b-938e-2bc41d0d271e.xml" has no metadata reporting This commit uses the wildcard xpath syntax supported since python 3.8 to correctly parse them.
1 parent 7db680a commit b57d9b9

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

analysis.py

+13-13
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def scan(path):
3333

3434
def parse(domain, filename):
3535
def get(node, name, default=None, expected=False):
36-
child = node.find(name)
36+
child = node.find('{*}' + name)
3737
if child is not None:
3838
if child.text is None:
3939
if expected:
@@ -52,14 +52,14 @@ def convert_timestamp(timestamp):
5252
return datetime.datetime.fromtimestamp(int(timestamp))
5353

5454
e = xml.etree.ElementTree.parse(filename).getroot()
55-
rm = e.find('report_metadata')
55+
rm = e.find('{*}report_metadata')
5656
if rm is None:
5757
raise Exception('File "{0}" has no metadata reporting'.format(filename))
5858
rm_org_name = get(rm, 'org_name', None)
59-
rm_dr = rm.find('date_range')
59+
rm_dr = rm.find('{*}date_range')
6060
rm_start = convert_timestamp(get(rm_dr, 'begin', expected=True))
6161
rm_end = convert_timestamp(get(rm_dr, 'end', expected=True))
62-
pp = e.find('policy_published')
62+
pp = e.find('{*}policy_published')
6363
if pp is None:
6464
raise Exception('File "{0}" has no published policy'.format(filename))
6565
pp_domain = get(pp, 'domain', expected=True)
@@ -69,30 +69,30 @@ def convert_timestamp(timestamp):
6969
pp_sp = get(pp, 'sp', 'none')
7070
pp_pct = int(get(pp, 'pct', '100'))
7171
data = []
72-
for i, r in enumerate(e.findall('record')):
73-
rr = r.find('row')
72+
for i, r in enumerate(e.findall('{*}record')):
73+
rr = r.find('{*}row')
7474
if rr is None:
7575
raise Exception('File "{0}" has no row data in record {1}'.format(filename, i + 1))
7676
rr_source_ip = get(rr, 'source_ip', expected=True)
7777
rr_count = int(get(rr, 'count', 0))
78-
rrpe = rr.find('policy_evaluated')
78+
rrpe = rr.find('{*}policy_evaluated')
7979
if rrpe is None:
8080
raise Exception('File "{0}" has no evaluated policy in record {1}'.format(filename, i + 1))
8181
rrpe_disposition = get(rrpe, 'disposition', expected=True)
8282
rrpe_dkim = get(rrpe, 'dkim', expected=True)
8383
rrpe_spf = get(rrpe, 'spf', expected=True)
84-
ri = r.find('identifiers')
84+
ri = r.find('{*}identifiers')
8585
if ri is None:
8686
raise Exception('File "{0}" has no identifier in record {1}'.format(filename, i + 1))
8787
ri_header_from = get(ri, 'header_from', expected=True)
88-
ra = r.find('auth_results')
88+
ra = r.find('{*}auth_results')
8989
if ra is None:
9090
raise Exception('File "{0}" has no authentication results in record {1}'.format(filename, i + 1))
9191
auth_results = {}
92-
rad = ra.find('dkim')
92+
rad = ra.find('{*}dkim')
9393
if rad is not None:
9494
auth_results['dkim'] = (get(rad, 'domain', None), get(rad, 'result', None))
95-
ras = ra.find('spf')
95+
ras = ra.find('{*}spf')
9696
if ras is not None:
9797
auth_results['spf'] = (get(ras, 'domain', None), get(ras, 'result', None))
9898
data.append((rr_source_ip, rr_count, {'disposition': rrpe_disposition, 'dkim': rrpe_dkim, 'spf': rrpe_spf}, ri_header_from, auth_results))
@@ -172,8 +172,8 @@ def format_result(result):
172172
(policy_evaluated['dkim'], 'green' if (policy_evaluated['dkim'] == 'pass') == is_own else 'red'),
173173
(policy_evaluated['spf'], 'green' if (policy_evaluated['spf'] == 'pass') == is_own else 'red'),
174174
header_from,
175-
format_result(auth_results.get('dkim', None)),
176-
format_result(auth_results.get('spf', None))])
175+
format_result(auth_results.get('{*}dkim', None)),
176+
format_result(auth_results.get('{*}spf', None))])
177177
field = None
178178
if field is not None:
179179
table.append([None, field])

0 commit comments

Comments
 (0)