sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/
commit 11ed9754e0d6e20c81ec522138cd592fd963c94f
parent a8dfda2ebf2404ed93a272cff374fed76baa53db
Author: Dan Callaghan <djc@djc.id.au>
Date:   Mon,  9 May 2022 20:22:06 +1000

restore monkey-patching of RMail::Serialize.calculate_boundaries

The monkey-patch was not applying due to module load ordering. It seems
to still be needed in order to avoid superfluous MIME-Version headers on
nested signed or encrypted parts, although such headers are likely not
harmful.

Includes test cases which attempt to reproduce the original behaviour
and fix that commit 07f0be01 probably intended.

Diffstat:
M lib/sup/util.rb | 1 +
M test/test_crypto.rb | 44 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 0 deletions(-)
diff --git a/lib/sup/util.rb b/lib/sup/util.rb
@@ -4,6 +4,7 @@ require 'thread'
 require 'lockfile'
 require 'mime/types'
 require 'pathname'
+require 'rmail'
 require 'set'
 require 'enumerator'
 require 'benchmark'
diff --git a/test/test_crypto.rb b/test/test_crypto.rb
@@ -69,6 +69,24 @@ class TestCryptoManager < Minitest::Test
         end
     end
 
+    def test_sign_nested_parts
+        if CryptoManager.have_crypto? then
+            body = RMail::Message.new
+            body.header["Content-Disposition"] = "inline"
+            body.body = "ABCDEFG"
+            payload = RMail::Message.new
+            payload.header["MIME-Version"] = "1.0"
+            payload.add_part body
+            payload.add_part RMail::Message.make_attachment "attachment", "text/plain", nil, "attachment.txt"
+            signed = CryptoManager.sign @from_email, @to_email, payload
+            ## The result is a multipart/signed containing a multipart/mixed.
+            ## There should be a MIME-Version header on the top-level
+            ## multipart/signed message, but *not* on the enclosed
+            ## multipart/mixed part.
+            assert_equal 1, signed.to_s.scan(/MIME-Version:/).size
+        end
+    end
+
     def test_encrypt
         if CryptoManager.have_crypto? then
             encrypted = CryptoManager.encrypt @from_email, [@to_email], "ABCDEFG"
@@ -116,6 +134,32 @@ class TestCryptoManager < Minitest::Test
             CryptoManager.verify signed.body[0], signed.body[1], true
         end
     end
+
+    def test_verify_nested_parts
+        if CryptoManager.have_crypto?
+            ## Generate a multipart/signed containing a multipart/mixed.
+            ## We will test verifying the generated signature below.
+            ## Importantly, the inner multipart/mixed does *not* have a
+            ## MIME-Version header because it is not a top-level message.
+            payload = RMail::Parser.read <<EOS
+Content-Type: multipart/mixed; boundary="=-1652088224-7794-561531-1825-1-="
+
+
+--=-1652088224-7794-561531-1825-1-=
+Content-Disposition: inline
+
+ABCDEFG
+--=-1652088224-7794-561531-1825-1-=
+Content-Disposition: attachment; filename="attachment.txt"
+Content-Type: text/plain; name="attachment.txt"
+
+attachment
+--=-1652088224-7794-561531-1825-1-=--
+EOS
+            signed = CryptoManager.sign @from_email_ecc, @to_email, payload
+            CryptoManager.verify payload, signed.body[1], true
+        end
+    end
 end
 
 end