Skip to content

Commit 858c920

Browse files
authored
Rewrite of the SPF module (#190)
* First phase of the rewrite * Fix exp * Fix calculation DNS lookup of include records * Include void includes in output * Update changelog and bump the version * Reformatting * Pass tests --------- Co-authored-by: Sean Whalen <seanthegeek@users.noreply.github.com>
1 parent 336ae2d commit 858c920

File tree

4 files changed

+282
-95
lines changed

4 files changed

+282
-95
lines changed

CHANGELOG.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,127 @@
11
# Changelog
22

3+
## 5.12.0
4+
5+
### ⚠️ Breaking Changes
6+
7+
#### 1. SPF Record Parsing Structure
8+
9+
- **Before**: The `parse_spf_record()` function returned a `parsed` dictionary with top-level keys like `"pass"`, `"neutral"`, `"softfail"`, `"fail"`, along with `"include"`, `"redirect"`, `"exp"`, and `"all"`.
10+
- **After**: The `parsed` structure now contains a list of dictionaries under the `"mechanisms"` key. Each entry describes a mechanism (e.g., `mx`, `a`, `include`), and includes additional data such as DNS lookup counts and associated addresses.
11+
12+
**Example:**
13+
14+
- Before:
15+
16+
```json
17+
"pass": [...]
18+
```
19+
20+
- After:
21+
22+
```json
23+
"mechanisms": [
24+
{
25+
"mechanism": "mx",
26+
"value": "example.com",
27+
"dns_lookups": 3,
28+
"void_dns_lookups": 0,
29+
"action": "pass",
30+
"hosts": {
31+
"mx1.example.com": ["203.0.113.10"]
32+
}
33+
}
34+
]
35+
```
36+
37+
#### 2. DNS Lookup Counting Changes
38+
39+
- DNS lookup counts are now tracked per mechanism and globally. The total number of DNS lookups is counted and limited (including `mx` lookups).
40+
- An exception is raised for DNS lookups if more than **9 MX records** are found (reduced from **10** in `5.11.0`), ensuring that the overall limit of 10 DNS queries per SPF evaluation is respected.
41+
42+
#### 3. DNS void fields
43+
44+
- The field for void DNS lookups in exceptions is now `void_dns_lookups`, as opposed to `dns_void_lookups` in the master branch. Code reading exception data should be updated to reflect this change.
45+
46+
**Example:**
47+
48+
- Before:
49+
50+
```python
51+
e.data["dns_void_lookups"]
52+
```
53+
54+
- After:
55+
56+
```python
57+
e.data["void_dns_lookups"]
58+
```
59+
60+
#### 4. Redirect Handling
61+
62+
- The `redirect` mechanism now propagates the terminal policy (i.e., `all`) from the redirected SPF record. The effective `all` policy is now available directly under `parsed["all"]` after resolving redirects.
63+
64+
---
65+
66+
### 🛠️ Improvements
67+
68+
#### Enhanced Output Data for Mechanisms
69+
70+
- Each mechanism entry that uses DNS lookups now includes detailed information such as DNS lookup counts (`dns_lookups`), void DNS lookups (`void_dns_lookups`), and resolved addresses (`hosts` for `mx` mechanisms).
71+
72+
---
73+
74+
### 🧰 Migration Notes
75+
76+
#### 1. Handling SPF Parsing Results
77+
78+
- Update how you iterate over SPF record results. Previously, you could directly access the `"pass"`, `"neutral"`, etc., keys. In the new structure, you must filter the `"mechanisms"` list based on the `action` key.
79+
80+
**Before**:
81+
82+
```python
83+
for item in parsed["pass"]:
84+
...
85+
```
86+
87+
**After**:
88+
89+
```python
90+
for m in parsed["mechanisms"]:
91+
if m["action"] == "pass":
92+
...
93+
```
94+
95+
#### 2. Error Payload Field Updates
96+
97+
- Code that references `e.data["dns_void_lookups"]` must update to `e.data["void_dns_lookups"]`.
98+
99+
---
100+
101+
### 🚨 Potential Compatibility Breaks for Consumers
102+
103+
- If you are consuming SPF evaluation results in JSON format (via `--json` flag or other means), note that the structure of the output has changed. The old format with top-level `pass`, `fail`, and other categories has been replaced with a list of mechanisms.
104+
- Consumers should update to handle the new format, which organizes data by individual mechanisms and includes detailed DNS lookup statistics.
105+
106+
---
107+
108+
### 🧑‍💻 For CLI Users
109+
110+
- **SPF Record Parsing**: The output format has changed. You will now see a list of mechanisms under `mechanisms`, each containing information like DNS lookups, void lookups, and resolved addresses.
111+
- **Lookup Limits**: If your SPF record exceeds the DNS lookup limit (especially with MX records), you'll see an error message when more than **9 MX records** are found.
112+
- **Warnings**: Expect warnings for oversized TXT records or overly large SPF records (exceeding RFC limits).
113+
114+
---
115+
116+
### ✨ Summary of Changes
117+
118+
- The **SPF parsing structure** has been overhauled for more detailed reporting.
119+
- **DNS lookup counting** has been improved with more granular tracking of DNS queries per mechanism.
120+
- **Exceptions** and error data formats have been streamlined.
121+
- **Redirect handling** has been enhanced, making the terminal policy easier to trace after redirects.
122+
123+
This release introduces significant changes that improve the clarity, flexibility, and robustness of SPF record evaluation. Please ensure your codebase is compatible with these new structures and exception formats.
124+
3125
## 5.11.6
4126

5127
- Remove inaccurate warning about SMTP-STS policy line endings

checkdmarc/_constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
See the License for the specific language governing permissions and
2020
limitations under the License."""
2121

22-
__version__ = "5.11.6"
22+
__version__ = "5.12.0"
2323

2424
OS = platform.system()
2525
OS_RELEASE = platform.release()

0 commit comments

Comments
 (0)