-
Notifications
You must be signed in to change notification settings - Fork 38
Authenticated Received Chain - ARC sealing #33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
agrinchenko
wants to merge
40
commits into
apache:master
Choose a base branch
from
agrinchenko:arc-sealing-clean
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
7e0004d
First commit
agrinchenko 508fbc2
Update arc/src/main/java/org/apache/james/arc/ArcSealVerifyData.java
agrinchenko 0718f68
Update arc/src/main/java/org/apache/james/arc/ARCChainValidator.java
agrinchenko 353434e
Update arc/src/main/java/org/apache/james/arc/ARCChainValidator.java
agrinchenko 2bdeeca
Update arc/src/main/java/org/apache/james/arc/ARCChainValidator.java
agrinchenko ce7b5ba
Refactor ARC to minimize dependencies and address some initial PR fee…
agrinchenko 28386ff
Rework DMARK and reduce dependencies
agrinchenko 471e608
Adding DMARC pom.xml that was missing in the previous commit
agrinchenko 620e388
Remove maven compiler plugin in DMARC pom.xml causing build to fail
agrinchenko 9714b4e
Add to the maven-compiler-plugin in DMARC pom.xml to fix the auto bu…
agrinchenko 016bed6
Add to the maven-compiler-plugin in ARC pom.xml to fix the auto buil…
agrinchenko 16c1fdf
Updating ARC pom to make sure it can see DMARC test dependencies on J…
agrinchenko dbe3301
Fixing the Jenkins build. Realigning to JDK 11
agrinchenko c8a688b
Add missing license info. Reorder 'dmarc' and 'arc' modules in the pa…
agrinchenko 3d75e62
Rewrote PSL matching to handle exceptions/wildcards plus:
agrinchenko 3bddd76
Updated README to reflect the purpose of the fork
agrinchenko bdca306
Update README.adoc
agrinchenko 6e69d2a
Fix site build and ARC/DMARC test support
agrinchenko 2fa964f
Add cv_fail_i1_ams_invalid test: assert cv=fail when ARC-Message-Sign…
agrinchenko 399e245
Add cv_fail_i1_as_invalid test: assert cv=fail when ARC-Seal b= is cr…
agrinchenko 101c79c
Fix ARCChainValidator to return cv=fail instead of throwing when ARC …
agrinchenko aa008e5
Add 10 cv_fail_i2_* tests: assert cv=fail for all structural and sign…
agrinchenko db78f24
Fix a bug in ARC-Seal to cover all prior hop headers as per RFC 8617;…
agrinchenko d2eba43
Add AMS structural validation tests and fix uncaught exceptions for m…
agrinchenko af9ee17
Add AMS tag format validation tests and fix null-safe DNS result hand…
agrinchenko 0f048c2
Add canonicalization tests for body whitespace and header normalization
agrinchenko e3d8df4
Add ARC AMS formatting and duplicate instance tests:
agrinchenko c9fd4d1
Expand ARC validation coverage and fix header parsing:
agrinchenko 813fe12
Add ARC-Seal field validation tests:
agrinchenko a158e3c
Add ARC-Seal b= validation test coverage:
agrinchenko 520d504
Add the ARC-Seal b= group test cases:
agrinchenko 280356f
Added more AMS field validation coverage:
agrinchenko 8be878e
Add ARC body hash and key fixture coverage:
agrinchenko b6baca4
Added ValiMail coverage tests in ARCTest for "c=" edge cases:
agrinchenko 99d1325
Added AMS tag validation in ARCVerifier:
agrinchenko 02bef53
Add remaining ARC h= and first-hop signing test coverage:
agrinchenko 3fa047f
Harden ARC validation and replace bundled PSL:
agrinchenko 510f6be
Address ARC and DMARC review hardening
agrinchenko 7723098
Update dmarc/src/main/java/org/apache/james/dmarc/DMARCVerifier.java
agrinchenko 39a6531
Harden ARC timestamp and instance validation:
agrinchenko File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,7 +1,9 @@ | ||||||||||||||||||||||||||||||||||||||
| = JAMES jDKIM library | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Library dealing with parsing and crytography to sign and verify DKIM signatures. | ||||||||||||||||||||||||||||||||||||||
| Library dealing with parsing and cryptography to sign and verify DKIM signatures. | ||||||||||||||||||||||||||||||||||||||
| It also provides DMARC verification and ARC (Authenticated Received Chain) | ||||||||||||||||||||||||||||||||||||||
| support for Java-based mail processing workflows. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| The mailet has been moved to James project: https://github.com/apache/james-project/tree/master/server/mailet/dkim | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
@@ -56,33 +58,154 @@ List<SignatureRecord> verifiedSignatures = verifier.verify(stream); | |||||||||||||||||||||||||||||||||||||
| List<Result> results = verifier.getResults(); | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| === Checking DMARC | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| DMARC verification combines SPF and DKIM results with the RFC5322 `From` | ||||||||||||||||||||||||||||||||||||||
| domain and the domain DMARC policy. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| [source,java] | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.dmarc.DMARCVerifier; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.dmarc.DmarcValidationResult; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.dmarc.PublicKeyRecordRetrieverDmarc; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.mime4j.dom.Message; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| PublicKeyRecordRetrieverDmarc recordRetriever = null; | ||||||||||||||||||||||||||||||||||||||
| Message message = null; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| DMARCVerifier dmarcVerifier = new DMARCVerifier(recordRetriever); | ||||||||||||||||||||||||||||||||||||||
| DmarcValidationResult dmarcResult = dmarcVerifier.runDmarcCheck( | ||||||||||||||||||||||||||||||||||||||
| message, | ||||||||||||||||||||||||||||||||||||||
| "pass client-ip=192.0.2.1; envelope-from=sender@example.org", | ||||||||||||||||||||||||||||||||||||||
| "example.org", | ||||||||||||||||||||||||||||||||||||||
| "pass", | ||||||||||||||||||||||||||||||||||||||
| "example.org"); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| String authenticationResult = dmarcResult.toString(); | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| More complete DMARC examples can be found in | ||||||||||||||||||||||||||||||||||||||
| https://github.com/apache/james-jdkim/blob/master/dmarc/src/main/test/java/org/apache/james/dmarc/DMARCTest.java[DMARCTest]. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| == ARC Support | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| ARC support adds RFC 8617 signing and validation for intermediaries that need to | ||||||||||||||||||||||||||||||||||||||
| preserve authentication results across forwarding hops. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| === Building An ARC Set | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Generating ARC headers for a MIME message can be achieved using the following | ||||||||||||||||||||||||||||||||||||||
| snippet. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| [source,java] | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
| import java.io.InputStream; | ||||||||||||||||||||||||||||||||||||||
| import java.security.PrivateKey; | ||||||||||||||||||||||||||||||||||||||
| import java.util.Map; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| import org.apache.james.arc.ArcSetBuilder; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.arc.PublicKeyRetrieverArc; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.mime4j.dom.Message; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.mime4j.message.DefaultMessageBuilder; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| String amsTemplate = "i=; a=rsa-sha256; c=relaxed/relaxed; d=example.org; s=arc; t=; h=Subject:From:To; bh=; b="; | ||||||||||||||||||||||||||||||||||||||
| String sealTemplate = "i=; cv=; a=rsa-sha256; d=example.org; s=arc; t=; b="; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| PrivateKey privateKey = null; | ||||||||||||||||||||||||||||||||||||||
| InputStream stream = null; | ||||||||||||||||||||||||||||||||||||||
| Message message = new DefaultMessageBuilder().parseMessage(stream); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| ArcSetBuilder arcSetBuilder = new ArcSetBuilder( | ||||||||||||||||||||||||||||||||||||||
| privateKey, | ||||||||||||||||||||||||||||||||||||||
| amsTemplate, | ||||||||||||||||||||||||||||||||||||||
| sealTemplate, | ||||||||||||||||||||||||||||||||||||||
| "mx.example.org", | ||||||||||||||||||||||||||||||||||||||
| System.currentTimeMillis() / 1000); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| PublicKeyRetrieverArc keyRecordRetriever = null; | ||||||||||||||||||||||||||||||||||||||
| Map<String, String> arcSet = arcSetBuilder.buildArcSet( | ||||||||||||||||||||||||||||||||||||||
| message, | ||||||||||||||||||||||||||||||||||||||
| "mail.example.org", | ||||||||||||||||||||||||||||||||||||||
| "sender@example.org", | ||||||||||||||||||||||||||||||||||||||
| "192.0.2.1", | ||||||||||||||||||||||||||||||||||||||
| keyRecordRetriever); | ||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here again some interface cosmetic fixes would go a long way. Same principal: builders, and POJO extracted...
Suggested change
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| String authenticationResults = arcSet.get("Authentication-Results"); | ||||||||||||||||||||||||||||||||||||||
| String arcAuthenticationResults = arcSet.get("ARC-Authentication-Results"); | ||||||||||||||||||||||||||||||||||||||
| String arcMessageSignature = arcSet.get("ARC-Message-Signature"); | ||||||||||||||||||||||||||||||||||||||
| String arcSeal = arcSet.get("ARC-Seal"); | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| The generated map contains the ARC headers for the current hop, ready to be | ||||||||||||||||||||||||||||||||||||||
| added to the message. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| === Validating An ARC Chain | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Validating ARC headers on a MIME message can be achieved using the following | ||||||||||||||||||||||||||||||||||||||
| snippet. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| [source,java] | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
| import java.io.InputStream; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| import org.apache.james.arc.ARCChainValidator; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.arc.ArcValidationOutcome; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.arc.PublicKeyRetrieverArc; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.mime4j.dom.Message; | ||||||||||||||||||||||||||||||||||||||
| import org.apache.james.mime4j.message.DefaultMessageBuilder; | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| PublicKeyRetrieverArc keyRecordRetriever = null; | ||||||||||||||||||||||||||||||||||||||
| InputStream stream = null; | ||||||||||||||||||||||||||||||||||||||
| Message message = new DefaultMessageBuilder().parseMessage(stream); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| ARCChainValidator arcChainValidator = new ARCChainValidator(keyRecordRetriever); | ||||||||||||||||||||||||||||||||||||||
| ArcValidationOutcome validation = arcChainValidator.validateArcChain(message); | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| String chainValidation = validation.getResult().toString(); | ||||||||||||||||||||||||||||||||||||||
| String description = validation.getDescription(); | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| More complete ARC usage can be found in | ||||||||||||||||||||||||||||||||||||||
| https://github.com/apache/james-jdkim/blob/master/arc/src/test/java/org/apache/james/arc/ARCTest.java[ARCTest]. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| == Test Coverage | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| ARC functionality is covered by tests in | ||||||||||||||||||||||||||||||||||||||
| https://github.com/apache/james-jdkim/blob/master/arc/src/test/java/org/apache/james/arc/ARCTest.java[ARCTest]. | ||||||||||||||||||||||||||||||||||||||
| The coverage is based on the ARC protocol requirements from | ||||||||||||||||||||||||||||||||||||||
| https://datatracker.ietf.org/doc/html/rfc8617[RFC 8617] and on the public | ||||||||||||||||||||||||||||||||||||||
| https://github.com/ValiMail/arc_test_suite[ValiMail ARC test suite]. The tests | ||||||||||||||||||||||||||||||||||||||
| exercise ARC set creation, chain validation, ARC-Seal verification, | ||||||||||||||||||||||||||||||||||||||
| ARC-Message-Signature canonicalization, body hash handling, required tag | ||||||||||||||||||||||||||||||||||||||
| validation, and malformed or tampered ARC header cases. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| == Cryptography Notice | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
| This distribution includes cryptographic software. The country in | ||||||||||||||||||||||||||||||||||||||
| which you currently reside may have restrictions on the import, | ||||||||||||||||||||||||||||||||||||||
| possession, use, and/or re-export to another country, of | ||||||||||||||||||||||||||||||||||||||
| encryption software. BEFORE using any encryption software, please | ||||||||||||||||||||||||||||||||||||||
| This distribution includes cryptographic software. The country in | ||||||||||||||||||||||||||||||||||||||
| which you currently reside may have restrictions on the import, | ||||||||||||||||||||||||||||||||||||||
| possession, use, and/or re-export to another country, of | ||||||||||||||||||||||||||||||||||||||
| encryption software. BEFORE using any encryption software, please | ||||||||||||||||||||||||||||||||||||||
| check your country's laws, regulations and policies concerning the | ||||||||||||||||||||||||||||||||||||||
| import, possession, or use, and re-export of encryption software, to | ||||||||||||||||||||||||||||||||||||||
| import, possession, or use, and re-export of encryption software, to | ||||||||||||||||||||||||||||||||||||||
| see if this is permitted. See http://www.wassenaar.org for more | ||||||||||||||||||||||||||||||||||||||
| information. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| The U.S. Government Department of Commerce, Bureau of Industry and | ||||||||||||||||||||||||||||||||||||||
| Security (BIS), has classified this software as Export Commodity | ||||||||||||||||||||||||||||||||||||||
| Security (BIS), has classified this software as Export Commodity | ||||||||||||||||||||||||||||||||||||||
| Control Number (ECCN) 5D002.C.1, which includes information security | ||||||||||||||||||||||||||||||||||||||
| software using or performing cryptographic functions with asymmetric | ||||||||||||||||||||||||||||||||||||||
| algorithms. The form and manner of this Apache Software Foundation | ||||||||||||||||||||||||||||||||||||||
| distribution makes it eligible for export under the License Exception | ||||||||||||||||||||||||||||||||||||||
| ENC Technology Software Unrestricted (TSU) exception (see the BIS | ||||||||||||||||||||||||||||||||||||||
| Export Administration Regulations, Section 740.13) for both object | ||||||||||||||||||||||||||||||||||||||
| ENC Technology Software Unrestricted (TSU) exception (see the BIS | ||||||||||||||||||||||||||||||||||||||
| Export Administration Regulations, Section 740.13) for both object | ||||||||||||||||||||||||||||||||||||||
| code and source code. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| The following provides more details on the included cryptographic | ||||||||||||||||||||||||||||||||||||||
| software: | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| - jDKIM includes code designed to work with Java SE Security | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Export classifications and source links can be found | ||||||||||||||||||||||||||||||||||||||
| at http://www.apache.org/licenses/exports/. | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
| ---- | ||||||||||||||||||||||||||||||||||||||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!-- | ||
| Licensed to the Apache Software Foundation (ASF) under one | ||
| or more contributor license agreements. See the NOTICE file | ||
| distributed with this work for additional information | ||
| regarding copyright ownership. The ASF licenses this file | ||
| to you under the Apache License, Version 2.0 (the | ||
| "License"); you may not use this file except in compliance | ||
| with the License. You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, | ||
| software distributed under the License is distributed on an | ||
| "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| KIND, either express or implied. See the License for the | ||
| specific language governing permissions and limitations | ||
| under the License. | ||
| --> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <parent> | ||
| <artifactId>apache-jdkim-project</artifactId> | ||
| <groupId>org.apache.james.jdkim</groupId> | ||
| <version>0.6-SNAPSHOT</version> | ||
| <relativePath>../pom.xml</relativePath> | ||
| </parent> | ||
|
|
||
| <artifactId>apache-arc-library</artifactId> | ||
|
|
||
| <name>Apache James :: ARC</name> | ||
| <description>A Java implementation for the ARC specification.</description> | ||
| <url>http://james.apache.org/jdkim/main/</url> | ||
| <inceptionYear>2008</inceptionYear> | ||
|
|
||
| <dependencies> | ||
| <dependency> | ||
| <groupId>org.apache.james.jdkim</groupId> | ||
| <artifactId>apache-dmarc-library</artifactId> | ||
| <version>${project.version}</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.james.jdkim</groupId> | ||
| <artifactId>apache-dmarc-library</artifactId> | ||
| <version>${project.version}</version> | ||
| <type>test-jar</type> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.james.jdkim</groupId> | ||
| <artifactId>apache-jdkim-library</artifactId> | ||
| <version>${project.version}</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.james.jdkim</groupId> | ||
| <artifactId>apache-jdkim-library</artifactId> | ||
| <version>${project.version}</version> | ||
| <type>test-jar</type> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.james.jspf</groupId> | ||
| <artifactId>apache-jspf-resolver</artifactId> | ||
| <version>${jspf-resolver.version}</version> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>junit</groupId> | ||
| <artifactId>junit</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.james</groupId> | ||
| <artifactId>apache-mime4j-core</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.apache.james</groupId> | ||
| <artifactId>apache-mime4j-dom</artifactId> | ||
| </dependency> | ||
| <dependency> | ||
| <groupId>org.assertj</groupId> | ||
| <artifactId>assertj-core</artifactId> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| </project> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is a lot of string arguments that I would be annoyend to distinguish from each other and to actually come up with. Suggestion: syntactic sugar
Would already be a nice enhancement.
We could have a typed alternative for SPF. Also We likely should offer a wauy to work directly with DKIM signature records.
To be honnest I do not care (here) about the internal, just about the outer layers. IMO we can easily do the last kilometer to make it easy to use.
Does this make sense?