From: wmorgan Date: Fri, 14 Sep 2007 07:40:30 +0000 (+0000) Subject: very preliminary gpg signature verification X-Git-Url: https://git.cworth.org/git?a=commitdiff_plain;h=0603c0203f6b7c52b49d5154c23eff9f3459035f;p=sup very preliminary gpg signature verification git-svn-id: svn://rubyforge.org/var/svn/sup/trunk@574 5c8cc53c-5e98-4d25-b20a-d8db53a31250 --- diff --git a/bin/sup b/bin/sup index 6ffbac5..9180f76 100644 --- a/bin/sup +++ b/bin/sup @@ -126,6 +126,8 @@ begin c.add :alternate_patina_color, Ncurses::COLOR_BLACK, Ncurses::COLOR_BLUE c.add :missing_message_color, Ncurses::COLOR_BLACK, Ncurses::COLOR_RED c.add :attachment_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK + c.add :valid_cryptosig_color, Ncurses::COLOR_CYAN, Ncurses::COLOR_BLACK + c.add :invalid_cryptosig_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_RED, Ncurses::A_BOLD c.add :quote_patina_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK c.add :sig_patina_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK c.add :quote_color, Ncurses::COLOR_YELLOW, Ncurses::COLOR_BLACK diff --git a/lib/sup/message.rb b/lib/sup/message.rb index 744485a..42ec88a 100644 --- a/lib/sup/message.rb +++ b/lib/sup/message.rb @@ -112,6 +112,47 @@ EOS end end + class CryptoSignature + attr_reader :lines, :description + + def initialize payload, signature + @payload = payload + @signature = signature + @status = nil + @description = nil + @lines = [] + end + + def valid?; status == :valid end + + def status + return @status if @status + payload = Tempfile.new "redwood.payload" + signature = Tempfile.new "redwood.signature" + + payload.write @payload.to_s.gsub(/(^|[^\r])\n/, "\\1\r\n") + payload.close + + signature.write @signature.decode + signature.close + + cmd = "gpg --quiet --batch --no-verbose --verify --logger-fd 1 #{signature.path} #{payload.path}" + #Redwood::log "gpg: running: #{cmd}" + gpg_output = `#{cmd}` + #Redwood::log "got output: #{gpg_output.inspect}" + @lines = gpg_output.split(/\n/) + + @description = + if gpg_output =~ /^gpg: (.* signature from .*$)/ + $1 + else + "Unable to determine signature validity" + end + + @status = ($? == 0 ? :valid : :invalid) + end + end + QUOTE_PATTERN = /^\s{0,4}[>|\}]/ BLOCK_QUOTE_PATTERN = /^-----\s*Original Message\s*----+$/ QUOTE_START_PATTERN = /(^\s*Excerpts from)|(^\s*In message )|(^\s*In article )|(^\s*Quoting )|((wrote|writes|said|says)\s*:\s*$)/ @@ -338,10 +379,41 @@ private ## of the gruesome slaughterhouse and sausage factory that is a ## mime-encoded message, but need only see the delicious end ## product. + + def multipart_signed_to_chunks m +# Redwood::log ">> multipart SIGNED: #{m.header['Content-Type']}: #{m.body.size}" + if m.body.size != 2 + Redwood::log "warning: multipart/signed with #{m.body.size} parts (expecting 2)" + return + end + + payload, signature = m.body + if payload.multipart? || signature.multipart? + Redwood::log "warning: multipart/signed with payload multipart #{payload.multipart?} and signature multipart #{signature.multipart?}" + return + end + + if payload.header.content_type == "application/pgp-signature" + Redwood::log "warning: multipart/signed with payload content type #{payload.header.content_type}" + return + end + + if signature.header.content_type != "application/pgp-signature" + Redwood::log "warning: multipart/signed with signature content type #{signature.header.content_type}" + return + end + + [CryptoSignature.new(payload, signature), message_to_chunks(payload)].flatten + end + def message_to_chunks m, sibling_types=[] if m.multipart? - sibling_types = m.body.map { |p| p.header.content_type } - m.body.map { |p| message_to_chunks p, sibling_types }.flatten.compact # recurse + chunks = multipart_signed_to_chunks(m) if m.header.content_type == "multipart/signed" + unless chunks + sibling_types = m.body.map { |p| p.header.content_type } + chunks = m.body.map { |p| message_to_chunks p, sibling_types }.flatten.compact + end + chunks else filename = ## first, paw through the headers looking for a filename diff --git a/lib/sup/modes/thread-view-mode.rb b/lib/sup/modes/thread-view-mode.rb index 643f6e2..b172779 100644 --- a/lib/sup/modes/thread-view-mode.rb +++ b/lib/sup/modes/thread-view-mode.rb @@ -179,7 +179,7 @@ class ThreadViewMode < LineCursorMode l = @layout[chunk] l.state = (l.state != :closed ? :closed : :open) cursor_down if l.state == :closed - when Message::Quote, Message::Signature + when Message::Quote, Message::Signature, Message::CryptoSignature return if chunk.lines.length == 1 toggle_chunk_expansion chunk when Message::Attachment @@ -510,6 +510,15 @@ private when :open [[[:sig_patina_color, "#{prefix}- (#{chunk.lines.length}-line signature)"]]] + chunk.lines.map { |line| [[:sig_color, "#{prefix}#{line}"]] } end + when Message::CryptoSignature + color = chunk.valid? ? :valid_cryptosig_color : :invalid_cryptosig_color + case state + when :closed + [[[color, "#{prefix}+ Cryptographic signature: #{chunk.description}"]]] + when :open + [[[color, "#{prefix}- Cryptographic signature: #{chunk.description}"]]] + + chunk.lines.map { |line| [[color, "#{prefix}#{line}"]] } + end else raise "unknown chunk type #{chunk.class.name}" end