Archive of RubyForge sup-devel mailing list
 help / color / mirror / Atom feed
From: Gaudenz Steinlin <gaudenz@soziologie.ch>
To: sup-devel <sup-devel@rubyforge.org>
Subject: [sup-devel] [PATCH] Fix signing of multipart messages
Date: Tue, 12 Oct 2010 23:46:19 +0200	[thread overview]
Message-ID: <1286919925-sup-9064@meteor.durcheinandertal.local> (raw)


[-- Attachment #1.1.1: Type: text/plain, Size: 1157 bytes --]

Hi

Sup currently crashes when you try to sign a multipart message. This
is fixed by the first patch.

Additionally the signatures created for multipart messages are wrong,
because the incorrect MIME-Version header is stripped before signing
but not when actually constructing the message.

RMail automagically adds these MIME-Version headers on serialization.
This also creates problems on signature verification of signed
multipart messages. 

The second patch addresses these two problems by monkey patching RMail
to no longer automagically add MIME-Version headers. This is not
really elegant, but I could not come up with a better way to avoid the
various side effects on signatures of automatically messing with mail
parts on serialization.

For the monkey patch to be applied the require statements had to be
rearranged so that rmail is included before sup/util.

If someone knows a better fix than monkey patching I would be more
than happy...

Gaudenz

P.S.: Do you rather prefer patches as attachments or inline patches?
--
Ever tried. Ever failed. No matter.
Try again. Fail again. Fail better.
~ Samuel Beckett ~

[-- Attachment #1.1.2: 0001-Encode-multipart-messages-for-crypt-operations.patch --]
[-- Type: application/octet-stream, Size: 2178 bytes --]

From ca2511220d1f0198a4e73432e87774a8fe30fba9 Mon Sep 17 00:00:00 2001
From: Gaudenz Steinlin <gaudenz@soziologie.ch>
Date: Tue, 12 Oct 2010 23:20:53 +0200
Subject: [PATCH 1/2] Encode multipart messages for crypt operations

Sup crashed when trying to encode a multipart message for crypto
operations. This encodes each part of the message separately. It also
changes the encoding for text/* parts to quoted-printable.

This only concerns the transfer encoding and does not change the charset
in any way.
---
 lib/sup/modes/edit-message-mode.rb |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb
index f27eb5c..1bf9378 100644
--- a/lib/sup/modes/edit-message-mode.rb
+++ b/lib/sup/modes/edit-message-mode.rb
@@ -403,8 +403,11 @@ protected
     if @crypto_selector && @crypto_selector.val != :none
       from_email = Person.from_address(@header["From"]).email
       to_email = [@header["To"], @header["Cc"], @header["Bcc"]].flatten.compact.map { |p| Person.from_address(p).email }
-      m.header["Content-Transfer-Encoding"] = 'base64'
-      m.body = [m.body].pack('m')
+      if m.multipart?
+        m.each_part {|p| p = transfer_encode p}
+      else
+        m = transfer_encode m
+      end
 
       m = CryptoManager.send @crypto_selector.val, from_email, to_email, m
     end
@@ -520,6 +523,25 @@ private
       []
     end
   end
+
+  def transfer_encode msg_part
+    ## return the message unchanged if it's already encoded
+    if (msg_part.header["Content-Transfer-Encoding"] == "base64" ||
+        msg_part.header["Content-Transfer-Encoding"] == "quoted-printable")
+      return msg_part
+    end
+
+    ## encode to quoted-printable for all text/* MIME types,
+    ## use base64 otherwise
+    if msg_part.header["Content-Type"] =~ /text\/.*/
+      msg_part.header["Content-Transfer-Encoding"] = 'quoted-printable'
+      msg_part.body = [msg_part.body].pack('M')
+    else
+      msg_part.header["Content-Transfer-Encoding"] = 'base64'
+      msg_part.body = [msg_part.body].pack('m')
+    end
+    msg_part
+  end
 end
 
 end
-- 
1.7.1


[-- Attachment #1.1.3: 0002-Monkey-patch-RMails-MIME-Version-header-handling.patch --]
[-- Type: application/octet-stream, Size: 3269 bytes --]

From eb4bbc6054a5d8c63b83d0dc632f880c2b650eb4 Mon Sep 17 00:00:00 2001
From: Gaudenz Steinlin <gaudenz@soziologie.ch>
Date: Tue, 12 Oct 2010 23:25:28 +0200
Subject: [PATCH 2/2] Monkey patch RMails MIME-Version header handling

RMail automagically adds MIME-Version headers to messages on
serialization. Sup uses RMail::Message object to represent parts of
multipart messages. Adding headers to these parts breaks gpg signatures.
The MIME-Version header is only needed in the outermost message. There
it's added manually.
---
 lib/sup.rb                         |    1 +
 lib/sup/crypto.rb                  |    2 +-
 lib/sup/maildir.rb                 |    1 -
 lib/sup/mbox.rb                    |    1 -
 lib/sup/modes/edit-message-mode.rb |    2 +-
 lib/sup/util.rb                    |   13 +++++++++++++
 6 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/lib/sup.rb b/lib/sup.rb
index 0e051be..a1d745c 100644
--- a/lib/sup.rb
+++ b/lib/sup.rb
@@ -5,6 +5,7 @@ require 'thread'
 require 'fileutils'
 require 'gettext'
 require 'curses'
+require 'rmail'
 begin
   require 'fastthread'
 rescue LoadError
diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
index 19983d2..386dbb8 100644
--- a/lib/sup/crypto.rb
+++ b/lib/sup/crypto.rb
@@ -207,7 +207,7 @@ private
   ## here's where we munge rmail output into the format that signed/encrypted
   ## PGP/GPG messages should be
   def format_payload payload
-    payload.to_s.gsub(/(^|[^\r])\n/, "\\1\r\n").gsub(/^MIME-Version: .*\r\n/, "")
+    payload.to_s.gsub(/(^|[^\r])\n/, "\\1\r\n")
   end
 
   # logic is:
diff --git a/lib/sup/maildir.rb b/lib/sup/maildir.rb
index b4e5208..92aaedc 100644
--- a/lib/sup/maildir.rb
+++ b/lib/sup/maildir.rb
@@ -1,4 +1,3 @@
-require 'rmail'
 require 'uri'
 
 module Redwood
diff --git a/lib/sup/mbox.rb b/lib/sup/mbox.rb
index 07b1b67..6b6eff3 100644
--- a/lib/sup/mbox.rb
+++ b/lib/sup/mbox.rb
@@ -1,4 +1,3 @@
-require 'rmail'
 require 'uri'
 require 'set'
 
diff --git a/lib/sup/modes/edit-message-mode.rb b/lib/sup/modes/edit-message-mode.rb
index 1bf9378..86aef4b 100644
--- a/lib/sup/modes/edit-message-mode.rb
+++ b/lib/sup/modes/edit-message-mode.rb
@@ -1,7 +1,6 @@
 require 'tempfile'
 require 'socket' # just for gethostname!
 require 'pathname'
-require 'rmail'
 
 module Redwood
 
@@ -428,6 +427,7 @@ protected
     m.header["Message-Id"] = @message_id
     m.header["User-Agent"] = "Sup/#{Redwood::VERSION}"
     m.header["Content-Transfer-Encoding"] ||= '8bit'
+    m.header["MIME-Version"] = "1.0" if m.multipart?
     m
   end
 
diff --git a/lib/sup/util.rb b/lib/sup/util.rb
index d19caca..2b84c9c 100644
--- a/lib/sup/util.rb
+++ b/lib/sup/util.rb
@@ -98,6 +98,19 @@ module RMail
       a
     end
   end
+
+  class Serialize
+    ## Don't add MIME-Version headers on serialization. Sup sometimes want's to serialize
+    ## message parts where these headers are not needed and messing with the message on
+    ## serialization breaks gpg signatures. The commented section shows the original RMail
+    ## code.
+    def calculate_boundaries(message)
+      calculate_boundaries_low(message, [])
+      # unless message.header['MIME-Version']
+      #   message.header['MIME-Version'] = "1.0"
+      # end
+    end
+  end
 end
 
 class Range
-- 
1.7.1


[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 482 bytes --]

[-- Attachment #2: Type: text/plain, Size: 143 bytes --]

_______________________________________________
Sup-devel mailing list
Sup-devel@rubyforge.org
http://rubyforge.org/mailman/listinfo/sup-devel

             reply	other threads:[~2010-10-12 21:46 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-12 21:46 Gaudenz Steinlin [this message]
2010-10-14  1:09 ` Rich Lane
2010-10-14  1:41   ` Ben Walton

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1286919925-sup-9064@meteor.durcheinandertal.local \
    --to=gaudenz@soziologie.ch \
    --cc=sup-devel@rubyforge.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox