Archive of RubyForge sup-talk mailing list
 help / color / mirror / Atom feed
From: Michael Stapelberg <michael+sup@stapelberg.de>
To: sup-talk <sup-talk@rubyforge.org>
Subject: Re: [sup-talk] PGP INLINE - can't make it work
Date: Wed, 10 Mar 2010 12:14:04 +0100	[thread overview]
Message-ID: <1268219571-sup-3316@midna.zekjur.net> (raw)
In-Reply-To: <1268218067-sup-7683@pk-laptop>

[-- Attachment #1: Type: text/plain, Size: 400 bytes --]

Hi Piotr,

Excerpts from Piotr Kempa's message of Mi Mär 10 11:53:00 +0100 2010:
> Thank you. I just tried the patch and unfortunately sup crashes on me
> now. I patched the 0.11 version and checked that the patches were
> applied successfully (as far as I could at least). 
Thanks for testing. Can you please see if the updated version works
for you (attached to this mail)?

Best regards,
Michael

[-- Attachment #2: 0001-Implement-inline-GPG.patch --]
[-- Type: application/octet-stream, Size: 7925 bytes --]

From 9c3de457828827b0ba9a3d98ca1870325eb6d21d Mon Sep 17 00:00:00 2001
From: Michael Stapelberg <michael@stapelberg.de>
Date: Tue, 9 Mar 2010 17:40:48 +0100
Subject: [PATCH] Implement inline GPG
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The SIG_PATTERN had to be changed because GPG, when clearsigning (which
is what happens when you send inline GPG messages), kind of escapes
lines beginning with dashes (so that the -----BEGIN PGP MESSAGE-----
lines don’t get messed up). Therefore, signatures, starting with "-- "
will be escaped as "- -- ". The manpage of GPG states that the process
of clearsigning is not reversible. Thus, there is no method in GPG to
get the original message.
---
 lib/sup/crypto.rb  |   62 ++++++++++++++++++++++++++++++++-------------------
 lib/sup/message.rb |   42 ++++++++++++++++++++++++++++++++--
 2 files changed, 78 insertions(+), 26 deletions(-)

diff --git a/lib/sup/crypto.rb b/lib/sup/crypto.rb
index 5ece6d9..abbcb98 100644
--- a/lib/sup/crypto.rb
+++ b/lib/sup/crypto.rb
@@ -97,18 +97,24 @@ EOS
     encrypt from, to, payload, true
   end
 
-  def verify payload, signature # both RubyMail::Message objects
+  def verify payload, signature, detached=true # both RubyMail::Message objects
     return unknown_status(cant_find_binary) unless @cmd
 
-    payload_fn = Tempfile.new "redwood.payload"
-    payload_fn.write format_payload(payload)
-    payload_fn.close
+    if detached
+      payload_fn = Tempfile.new "redwood.payload"
+      payload_fn.write format_payload(payload)
+      payload_fn.close
+    end
 
     signature_fn = Tempfile.new "redwood.signature"
     signature_fn.write signature.decode
     signature_fn.close
 
-    output = run_gpg "--verify #{signature_fn.path} #{payload_fn.path}"
+    if detached
+      output = run_gpg "--verify #{signature_fn.path} #{payload_fn.path}"
+    else
+      output = run_gpg "--verify #{signature_fn.path}"
+    end
     output_lines = output.split(/\n/)
 
     if output =~ /^gpg: (.* signature from .*$)/
@@ -123,7 +129,7 @@ EOS
   end
 
   ## returns decrypted_message, status, desc, lines
-  def decrypt payload # a RubyMail::Message object
+  def decrypt payload, armor=false # a RubyMail::Message object
     return unknown_status(cant_find_binary) unless @cmd
 
     payload_fn = Tempfile.new "redwood.payload"
@@ -153,24 +159,34 @@ EOS
       Chunk::CryptoNotice.new :invalid, $1, message.split("\n")
     end
 
-    # This is gross. This decrypted payload could very well be a multipart
-    # element itself, as opposed to a simple payload. For example, a
-    # multipart/signed element, like those generated by Mutt when encrypting
-    # and signing a message (instead of just clearsigning the body).
-    # Supposedly, decrypted_payload being a multipart element ought to work
-    # out nicely because Message::multipart_encrypted_to_chunks() runs the
-    # decrypted message through message_to_chunks() again to get any
-    # children. However, it does not work as intended because these inner
-    # payloads need not carry a MIME-Version header, yet they are fed to
-    # RMail as a top-level message, for which the MIME-Version header is
-    # required. This causes for the part not to be detected as multipart,
-    # hence being shown as an attachment. If we detect this is happening,
-    # we force the decrypted payload to be interpreted as MIME.
-    msg = RMail::Parser.read output
-    if msg.header.content_type =~ %r{^multipart/} && !msg.multipart?
-      output = "MIME-Version: 1.0\n" + output
-      output.force_encoding Encoding::ASCII_8BIT if output.respond_to? :force_encoding
+    if armor
+      msg = RMail::Message.new
+      # Look for Charset, they are put before the base64 crypted part
+      charsets = payload.body.split("\n").grep(/^Charset:/)
+      if !charsets.empty? and charsets[0] =~ /^Charset: (.+)$/
+        output = Iconv.easy_decode($encoding, $1, output)
+      end
+      msg.body = output
+    else
+      # This is gross. This decrypted payload could very well be a multipart
+      # element itself, as opposed to a simple payload. For example, a
+      # multipart/signed element, like those generated by Mutt when encrypting
+      # and signing a message (instead of just clearsigning the body).
+      # Supposedly, decrypted_payload being a multipart element ought to work
+      # out nicely because Message::multipart_encrypted_to_chunks() runs the
+      # decrypted message through message_to_chunks() again to get any
+      # children. However, it does not work as intended because these inner
+      # payloads need not carry a MIME-Version header, yet they are fed to
+      # RMail as a top-level message, for which the MIME-Version header is
+      # required. This causes for the part not to be detected as multipart,
+      # hence being shown as an attachment. If we detect this is happening,
+      # we force the decrypted payload to be interpreted as MIME.
       msg = RMail::Parser.read output
+      if msg.header.content_type =~ %r{^multipart/} && !msg.multipart?
+        output = "MIME-Version: 1.0\n" + output
+        output.force_encoding Encoding::ASCII_8BIT if output.respond_to? :force_encoding
+        msg = RMail::Parser.read output
+      end
     end
     notice = Chunk::CryptoNotice.new :valid, "This message has been decrypted for display"
     [notice, sig, msg]
diff --git a/lib/sup/message.rb b/lib/sup/message.rb
index ebc73fc..7a19f27 100644
--- a/lib/sup/message.rb
+++ b/lib/sup/message.rb
@@ -26,7 +26,7 @@ class Message
 
   QUOTE_PATTERN = /^\s{0,4}[>|\}]/
   BLOCK_QUOTE_PATTERN = /^-----\s*Original Message\s*----+$/
-  SIG_PATTERN = /(^-- ?$)|(^\s*----------+\s*$)|(^\s*_________+\s*$)|(^\s*--~--~-)|(^\s*--\+\+\*\*==)/
+  SIG_PATTERN = /(^(- )*-- ?$)|(^\s*----------+\s*$)|(^\s*_________+\s*$)|(^\s*--~--~-)|(^\s*--\+\+\*\*==)/
 
   MAX_SIG_DISTANCE = 15 # lines from the end
   DEFAULT_SUBJECT = ""
@@ -511,8 +511,44 @@ private
         ## if there's no charset, use the current encoding as the charset.
         ## this ensures that the body is normalized to avoid non-displayable
         ## characters
-        body = Iconv.easy_decode($encoding, m.charset || $encoding, m.decode) if m.body
-        text_to_chunks((body || "").normalize_whitespace.split("\n"), encrypted)
+        if m.body
+          body = Iconv.easy_decode($encoding, m.charset || $encoding, m.decode)
+        else
+          body = ""
+        end
+        lines = body.split("\n")
+
+        ## Check for inline-PGP
+        msg_start = "^-----BEGIN PGP SIGNED MESSAGE-----$"
+        msg_end = "^-----END PGP SIGNED MESSAGE-----$"
+        gpg = lines.select { |l| true if l =~ /#{msg_start}/ .. l =~ /#{msg_end}/ }
+        if !gpg.empty?
+          msg = RMail::Message.new
+          msg.body = gpg.join("\n")
+
+          sig_start = "^-----BEGIN PGP SIGNATURE-----$"
+          sig = lines.select { |l| true if l =~ /#{msg_start}/ .. l =~ /#{sig_start}/ }
+          payload = RMail::Message.new
+          payload.body = sig[1, sig.count-2].join("\n")
+          return [CryptoManager.verify(nil, msg, false), message_to_chunks(payload)].flatten.compact
+        end
+
+        msg_start = "^-----BEGIN PGP MESSAGE-----$"
+        msg_end = "^-----END PGP MESSAGE-----$"
+        gpg = lines.select { |l| true if l =~ /#{msg_start}/ .. l =~ /#{msg_end}/ }
+        if !gpg.empty?
+          msg = RMail::Message.new
+          msg.body = gpg.join("\n")
+          notice, sig, decryptedm = CryptoManager.decrypt msg, true
+          if decryptedm # managed to decrypt
+            children = message_to_chunks(decryptedm, true)
+            return [notice, sig].compact + children
+          else
+            return [notice]
+          end
+        end
+
+        text_to_chunks(body.normalize_whitespace.split("\n"), encrypted)
       end
     end
   end
-- 
1.6.5


[-- Attachment #3: Type: text/plain, Size: 140 bytes --]

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

  reply	other threads:[~2010-03-10 11:14 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-02-26 17:08 kosmici-atakuja
2010-02-26 17:43 ` Sven Schober
2010-03-02 10:49   ` piotr.kempa
2010-03-02 13:59     ` Michael Stapelberg
2010-03-02 14:19       ` piotr.kempa
2010-03-08 10:18         ` piotr.kempa
2010-03-08 10:29           ` piotr.kempa
2010-03-08 10:41             ` Michael Stapelberg
2010-03-08 10:50             ` Sven Moritz Hallberg
2010-03-08 11:20               ` piotr.kempa
2010-03-09 17:06                 ` Michael Stapelberg
2010-03-10 10:53                   ` Piotr Kempa
2010-03-10 11:14                     ` Michael Stapelberg [this message]
2010-03-10 14:41                       ` Piotr Kempa
2010-03-10 21:21                         ` Michael Stapelberg
2010-03-02 14:12     ` Sam Hall

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=1268219571-sup-3316@midna.zekjur.net \
    --to=michael+sup@stapelberg.de \
    --cc=sup-talk@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