You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@james.apache.org by rc...@apache.org on 2023/11/10 07:22:19 UTC

(james-project) branch master updated: JAMES-3958 Be resilient when updating mails with invalid headers (#1783)

This is an automated email from the ASF dual-hosted git repository.

rcordier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git


The following commit(s) were added to refs/heads/master by this push:
     new ec9ad67d5a JAMES-3958 Be resilient when updating mails with invalid headers (#1783)
ec9ad67d5a is described below

commit ec9ad67d5a4e556912ac4517ab5c7ffae63c4d6e
Author: Benoit TELLIER <bt...@linagora.com>
AuthorDate: Fri Nov 10 08:22:13 2023 +0100

    JAMES-3958 Be resilient when updating mails with invalid headers (#1783)
---
 server/mailet/dkim/pom.xml                         |  4 ++
 .../org/apache/james/jdkim/mailets/DKIMSign.java   |  5 +-
 .../apache/james/jdkim/mailets/DKIMVerifier.java   |  3 +-
 .../org/apache/james/jdkim/mailets/DKIMVerify.java |  2 +-
 .../apache/james/mailets/DKIMIntegrationTest.java  | 77 ++++++++++++++++++++--
 5 files changed, 84 insertions(+), 7 deletions(-)

diff --git a/server/mailet/dkim/pom.xml b/server/mailet/dkim/pom.xml
index 7bdd851958..8d1aaf615f 100644
--- a/server/mailet/dkim/pom.xml
+++ b/server/mailet/dkim/pom.xml
@@ -50,6 +50,10 @@
             <artifactId>apache-mailet-test</artifactId>
             <scope>test</scope>
         </dependency>
+        <dependency>
+            <groupId>${james.groupId}</groupId>
+            <artifactId>james-server-core</artifactId>
+        </dependency>
         <dependency>
             <groupId>${james.groupId}</groupId>
             <artifactId>testing-base</artifactId>
diff --git a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMSign.java b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMSign.java
index d3fd4716d6..b5e5d18c9f 100644
--- a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMSign.java
+++ b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMSign.java
@@ -44,6 +44,7 @@ import org.apache.james.jdkim.api.BodyHasher;
 import org.apache.james.jdkim.api.Headers;
 import org.apache.james.jdkim.api.SignatureRecord;
 import org.apache.james.jdkim.exceptions.PermFailException;
+import org.apache.james.server.core.MimeMessageInputStream;
 import org.apache.mailet.Mail;
 import org.apache.mailet.base.GenericMailet;
 import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
@@ -155,7 +156,9 @@ public class DKIMSign extends GenericMailet {
                 if (forceCRLF) {
                     os = new CRLFOutputStream(os);
                 }
-                message.writeTo(os);
+                try (MimeMessageInputStream stream = new MimeMessageInputStream(message)) {
+                    stream.transferTo(os);
+                }
             } catch (IOException e) {
                 throw new MessagingException("Exception calculating bodyhash: " + e.getMessage(), e);
             } finally {
diff --git a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerifier.java b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerifier.java
index 06994021bf..8117f48a7c 100644
--- a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerifier.java
+++ b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerifier.java
@@ -31,6 +31,7 @@ import org.apache.james.jdkim.api.Headers;
 import org.apache.james.jdkim.api.PublicKeyRecordRetriever;
 import org.apache.james.jdkim.api.SignatureRecord;
 import org.apache.james.jdkim.exceptions.FailException;
+import org.apache.james.server.core.MimeMessageInputStream;
 
 public class DKIMVerifier {
     private final org.apache.james.jdkim.DKIMVerifier originalVerifier;
@@ -53,7 +54,7 @@ public class DKIMVerifier {
                 if (forceCRLF) {
                     os = new CRLFOutputStream(os);
                 }
-                message.writeTo(os);
+                new MimeMessageInputStream(message).transferTo(os);
             }
 
         } catch (IOException e) {
diff --git a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerify.java b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerify.java
index 37eee98980..242e873a79 100644
--- a/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerify.java
+++ b/server/mailet/dkim/src/main/java/org/apache/james/jdkim/mailets/DKIMVerify.java
@@ -71,7 +71,7 @@ public class DKIMVerify extends GenericMailet {
 
     public void service(Mail mail) throws MessagingException {
         try {
-            MimeMessage message = mail.getMessage();
+            MimeMessage message =  mail.getMessage();
             List<SignatureRecord> res = verifier.verify(message, forceCRLF);
             if (res == null || res.isEmpty()) {
                 // neutral
diff --git a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/DKIMIntegrationTest.java b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/DKIMIntegrationTest.java
index 8a38348e01..26d098b93e 100644
--- a/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/DKIMIntegrationTest.java
+++ b/server/mailet/integration-testing/src/test/java/org/apache/james/mailets/DKIMIntegrationTest.java
@@ -53,6 +53,7 @@ import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.RegisterExtension;
 import org.junit.jupiter.api.io.TempDir;
 
+import com.google.common.collect.ImmutableList;
 import com.google.inject.Module;
 
 class DKIMIntegrationTest {
@@ -128,7 +129,30 @@ class DKIMIntegrationTest {
 
         messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
             .authenticate(FROM, PASSWORD)
-            .sendMessage(FROM, RECIPIENT);
+            .sendMessageWithHeaders(FROM, ImmutableList.of(RECIPIENT), "Return-Path: <bt...@linagora.com>\n" +
+                "Content-Type: multipart/mixed; boundary=\"------------dsVZbfyUhMRjfuWnqQ80tHvc\"\n" +
+                "Message-ID: <a7...@linagora.com>\n" +
+                "Date: Tue, 7 Nov 2023 12:14:47 +0100\n" +
+                "MIME-Version: 1.0\n" +
+                "User-Agent: Mozilla Thunderbird\n" +
+                "Content-Language: en-US\n" +
+                "To: btellier@linagora.com\n" +
+                "From: \"btellier@linagora.com\" <bt...@linagora.com>\n" +
+                "Subject: Simple message\n" +
+                "\n" +
+                "This is a multi-part message in MIME format.\n" +
+                "--------------dsVZbfyUhMRjfuWnqQ80tHvc\n" +
+                "Content-Type: text/plain; charset=UTF-8; format=flowed\n" +
+                "Content-Transfer-Encoding: 7bit\n" +
+                "\n" +
+                "Simple body\n" +
+                "\n" +
+                "--------------dsVZbfyUhMRjfuWnqQ80tHvc\n" +
+                "Content-Type: message/rfc822; name=BNPP ADVICE LOLO.eml\n" +
+                "Content-Disposition: attachment; filename=\"BNPP.eml\"\n" +
+                "\n" +
+                "\n" +
+                "--------------dsVZbfyUhMRjfuWnqQ80tHvc--");
 
         testIMAPClient.connect(LOCALHOST_IP, jamesServer.getProbe(ImapGuiceProbe.class).getImapPort())
             .login(RECIPIENT, PASSWORD)
@@ -136,12 +160,57 @@ class DKIMIntegrationTest {
             .awaitMessage(awaitAtMostOneMinute);
 
         assertThat(dkimAuthResults)
-                .hasSize(1);
+            .hasSize(1);
+        assertThat(dkimAuthResults.get(0))
+            .hasValueSatisfying(result -> assertThat(result).startsWith("pass"));
+
+        assertThat(testIMAPClient.readFirstMessageHeaders())
+            .contains("DKIM-Signature");
+    }
+
+    @Test
+    void dkimShouldBeResilientWhenFacedWithInvalidHeaders(@TempDir File temporaryFolder) throws Exception {
+        initJamesServer(temporaryFolder, binder -> binder.bind(PublicKeyRecordRetriever.class).toInstance(MOCK_PUBLIC_KEY_RECORD_RETRIEVER));
+
+        messageSender.connect(LOCALHOST_IP, jamesServer.getProbe(SmtpGuiceProbe.class).getSmtpPort())
+            .authenticate(FROM, PASSWORD)
+            .sendMessageWithHeaders(FROM, ImmutableList.of(RECIPIENT), "Return-Path: <bt...@linagora.com>\n" +
+                "Content-Type: multipart/mixed; boundary=\"------------dsVZbfyUhMRjfuWnqQ80tHvc\"\n" +
+                "Message-ID: <a7...@linagora.com>\n" +
+                "Date: Tue, 7 Nov 2023 12:14:47 +0100\n" +
+                "MIME-Version: 1.0\n" +
+                "User-Agent: Mozilla Thunderbird\n" +
+                "Content-Language: en-US\n" +
+                "To: btellier@linagora.com\n" +
+                "From: \"btellier@linagora.com\" <bt...@linagora.com>\n" +
+                "Subject: Simple message\n" +
+                "\n" +
+                "This is a multi-part message in MIME format.\n" +
+                "--------------dsVZbfyUhMRjfuWnqQ80tHvc\n" +
+                "Content-Type: text/plain; charset=UTF-8; format=flowed\n" +
+                "Content-Transfer-Encoding: 7bit\n" +
+                "\n" +
+                "Simple body\n" +
+                "\n" +
+                "--------------dsVZbfyUhMRjfuWnqQ80tHvc\n" +
+                "Content-Type: message/rfc822; name=BNPP ADVICE LOLO.eml\n" +
+                "Content-Disposition: attachment; filename=\"BNPP.eml\"\n" +
+                "\n" +
+                "\n" +
+                "--------------dsVZbfyUhMRjfuWnqQ80tHvc--");
+
+        testIMAPClient.connect(LOCALHOST_IP, jamesServer.getProbe(ImapGuiceProbe.class).getImapPort())
+            .login(RECIPIENT, PASSWORD)
+            .select(TestIMAPClient.INBOX)
+            .awaitMessage(awaitAtMostOneMinute);
+
+        assertThat(dkimAuthResults)
+            .hasSize(1);
         assertThat(dkimAuthResults.get(0))
-                .hasValueSatisfying(result -> assertThat(result).startsWith("pass"));
+            .hasValueSatisfying(result -> assertThat(result).startsWith("pass"));
 
         assertThat(testIMAPClient.readFirstMessageHeaders())
-                .contains("DKIM-Signature");
+            .contains("DKIM-Signature");
     }
 
     @Test


---------------------------------------------------------------------
To unsubscribe, e-mail: notifications-unsubscribe@james.apache.org
For additional commands, e-mail: notifications-help@james.apache.org