[DRE-commits] [sup-mail] 22/26: Imported Upstream version 0.14.1.1

Per Andersson avtobiff at moszumanska.debian.org
Wed Oct 1 19:02:21 UTC 2014


This is an automated email from the git hooks/post-receive script.

avtobiff pushed a commit to branch next-0.14.1.1
in repository sup-mail.

commit df82dc933ca392648c7ad18c0e5b6a03c73f2abb
Author: Per Andersson <avtobiff at gmail.com>
Date:   Sun Nov 3 20:52:33 2013 +0100

    Imported Upstream version 0.14.1.1
---
 CONTRIBUTORS                         | 14 ++++----
 History.txt                          | 15 ++++++++
 ReleaseNotes                         | 30 ++++++++++++++++
 doc/FAQ.txt                          |  6 +++-
 doc/Hooks.txt                        |  7 +++-
 lib/sup.rb                           |  2 +-
 lib/sup/logger.rb                    |  5 ++-
 lib/sup/message.rb                   |  2 +-
 lib/sup/message_chunks.rb            | 66 +++++++++++++++++++++++++++++-------
 lib/sup/modes/edit_message_mode.rb   | 12 ++++---
 lib/sup/modes/search_list_mode.rb    |  6 +++-
 lib/sup/modes/search_results_mode.rb |  6 +++-
 lib/sup/search.rb                    | 23 +++++++++++--
 lib/sup/version.rb                   |  2 +-
 sup.gemspec                          |  7 ++--
 15 files changed, 166 insertions(+), 37 deletions(-)

diff --git a/CONTRIBUTORS b/CONTRIBUTORS
index 9b60058..fb6325d 100644
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -25,44 +25,44 @@ Richard Brown <rbrown at the exherbo dot orgs>
 Anthony Martinez <pi+sup at the pihost dot uss>
 Marc Hartstein <marc.hartstein at the alum.vassar dot edus>
 Israel Herraiz <israel.herraiz at the gmail dot coms>
+Matthieu Rakotojaona <matthieu.rakotojaona at the gmail dot coms>
 Bo Borgerson <gigabo at the gmail dot coms>
 Michael Hamann <michael at the content-space dot des>
 Jonathan Lassoff <jof at the thejof dot coms>
 William Erik Baxter <web at the superscript dot coms>
 Grant Hollingworth <grant at the antiflux dot orgs>
-Markus Klinik <markus.klinik at the gmx dot des>
 Ico Doornekamp <ico at the pruts dot nls>
+Markus Klinik <markus.klinik at the gmx dot des>
 Adeodato Simó <dato at the net.com.org dot ess>
 Daniel Schoepe <daniel.schoepe at the googlemail dot coms>
 Jason Petsod <jason at the petsod dot orgs>
 Edward Z. Yang <edwardzyang at the thewritingpot dot coms>
-Robin Burchell <viroteck at the viroteck dot nets>
 Steve Goldman <sgoldman at the tower-research dot coms>
+Robin Burchell <viroteck at the viroteck dot nets>
 Peter Harkins <ph at the malaprop dot orgs>
 Decklin Foster <decklin at the red-bean dot coms>
 Cameron Matheson <cam+sup at the cammunism dot orgs>
 Carl Worth <cworth at the cworth dot orgs>
 Alex Vandiver <alex at the chmrr dot nets>
-Andrew Pimlott <andrew at the pimlott dot nets>
 Jeff Balogh <its.jeff.balogh at the gmail dot coms>
+Andrew Pimlott <andrew at the pimlott dot nets>
 Matías Aguirre <matiasaguirre at the gmail dot coms>
 Kornilios Kourtis <kkourt at the cslab.ece.ntua dot grs>
 Kevin Riggle <kevinr at the free-dissociation dot coms>
 Giorgio Lando <patroclo7 at the gmail dot coms>
 Benoît PIERRE <benoit.pierre at the gmail dot coms>
-Matthieu Rakotojaona <matthieu.rakotojaona at the gmail dot coms>
 Alvaro Herrera <alvherre at the alvh.no-ip dot orgs>
 Steven Lawrance <stl at the koffein dot nets>
 Jonah <Jonah at the GoodCoffee dot cas>
 ian <itaylor at the uark dot edus>
-Todd Eisenberger <teisenbe at the andrew.cmu dot edus>
 Adam Lloyd <adam at the alloy-d dot nets>
+Todd Eisenberger <teisenbe at the andrew.cmu dot edus>
+Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
 MichaelRevell <mikearevell at the gmail dot coms>
 Per Andersson <avtobiff at the gmail dot coms>
-Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
 Steven Walter <swalter at the monarch.(none)>
-Jon M. Dugan <jdugan at the es dot nets>
 Matthias Vallentin <vallentin at the icir dot orgs>
+Jon M. Dugan <jdugan at the es dot nets>
 Stefan Lundström <lundst at the snabb.(none)>
 Horacio Sanson <horacio at the skillupjapan.co dot jps>
 Kirill Smelkov <kirr at the landau.phys.spbu dot rus>
diff --git a/History.txt b/History.txt
index 59b5a90..1f5417c 100644
--- a/History.txt
+++ b/History.txt
@@ -1,3 +1,18 @@
+== 0.14.1.1 / 2013-10-29
+
+* SBU1: security release
+* Tempfiles for attachments are persistent through the sup process to
+  ensure that spawned processes have access to them.
+
+== 0.13.2.1 / 2013-10-29
+
+* SBU1: security release
+
+== 0.14.1 / 2013-08-31
+
+* Various bugfixes.
+* Predefined 'All mail' search.
+
 == 0.14.0 / 2013-08-15
 
 * CJK compatability
diff --git a/ReleaseNotes b/ReleaseNotes
index 736dad2..b0bf93b 100644
--- a/ReleaseNotes
+++ b/ReleaseNotes
@@ -1,3 +1,33 @@
+Release 0.14.1.1:
+
+See 0.13.2.1.
+
+Release 0.13.2.1:
+
+Security advisory (#SBU1) for Sup
+
+We have been notified of an potential exploit in the somewhat careless
+way Sup treats attachment metadata in received e-mails. The issues
+should now be fixed and I have released Sup 0.13.2.1 and 0.14.1.1 which
+incorporates these fixes. Please upgrade immediately and also ensure
+that your mime-decode or mime-view hooks are secure [0], [1].
+
+This is specifically related to using quotes (',") around filename or
+content_type which is already escaped using Ruby Shellwords.escape -
+this means that the string (content_type, filename) is intended to be
+used _without_ any further quotes. Please make sure that if you use
+.mailcap (non OSX systems), you do not quote the string.
+
+Credit goes to: joernchen of Phenoelit (http://phenoelit.de) who
+discovered and suggested fixes for these issues.
+
+[0] https://github.com/sup-heliotrope/sup/wiki/Viewing-Attachments
+[1] https://github.com/sup-heliotrope/sup/wiki/Secure-usage-of-Sup
+
+Release 0.14.1:
+
+Service release to 0.14.0 plus a predefined 'All mail' search.
+
 Release 0.14.0:
 
 CJK-compatability, Psych usage, thread safety, GPGME 2.0 support. Sup is now
diff --git a/doc/FAQ.txt b/doc/FAQ.txt
index be19399..16c9a59 100644
--- a/doc/FAQ.txt
+++ b/doc/FAQ.txt
@@ -112,4 +112,8 @@ P: When I run Sup remotely and view an HTML attachment, an existing
    file, which it can't find (since it's on the remote machine). How do
    I view HTML attachments in this environment?
 S: Put this in your ~/.mailcap on the machine you run Sup on:
-      text/html; /usr/bin/firefox -a sup '%s'; description=HTML Text; test=test -n "$DISPLAY";  nametemplate=%s.html
+      text/html; /usr/bin/firefox -a sup %s; description=HTML Text; test=test -n "$DISPLAY";  nametemplate=%s.html
+
+   Please read
+   https://github.com/sup-heliotrope/sup/wiki/Viewing-Attachments for
+   some security concerns on opening attachments.
diff --git a/doc/Hooks.txt b/doc/Hooks.txt
index 21b1e5e..6c33971 100644
--- a/doc/Hooks.txt
+++ b/doc/Hooks.txt
@@ -48,12 +48,17 @@ before-poll:
 
 
 mime-decode:
+  ## Please read:
+  https://github.com/sup-heliotrope/sup/wiki/Viewing-Attachments for
+  some security concerns on opening attachments.
+
   ## turn text/html attachments into plain text, unless they are part
   ## of a multipart/alternative pair
+  require 'shellwords'
   unless sibling_types.member? "text/plain"
     case content_type
     when "text/html"
-      `/usr/bin/w3m -dump -T #{content_type} '#{filename}'`
+      `/usr/bin/w3m -dump -T #{content_type} #{Shellwords.escape filename}`
     end
   end
 
diff --git a/lib/sup.rb b/lib/sup.rb
index 0748ccb..65413a1 100644
--- a/lib/sup.rb
+++ b/lib/sup.rb
@@ -284,7 +284,7 @@ EOM
         :accounts => {
           :default => {
             :name => name.dup.fix_encoding!,
-            :email => email.fix_encoding!,
+            :email => email.dup.fix_encoding!,
             :alternates => [],
             :sendmail => "/usr/sbin/sendmail -oem -ti",
             :signature => File.join(ENV["HOME"], ".signature"),
diff --git a/lib/sup/logger.rb b/lib/sup/logger.rb
index 7dd296a..514b78e 100644
--- a/lib/sup/logger.rb
+++ b/lib/sup/logger.rb
@@ -60,7 +60,10 @@ private
   ## actually distribute the message
   def send_message m
     @mutex.synchronize do
-      @sinks.each { |sink| sink << m }
+      @sinks.each do |sink|
+        sink << m
+        sink.flush if sink.respond_to?(:flush) and level == "debug"
+      end
       @buf << m
     end
   end
diff --git a/lib/sup/message.rb b/lib/sup/message.rb
index 9cdcea2..480ab6c 100644
--- a/lib/sup/message.rb
+++ b/lib/sup/message.rb
@@ -309,7 +309,7 @@ EOS
   end
 
   def indexable_chunks
-    chunks ? chunks.select { |c| c.is_a? Chunk::Text } : []
+    chunks.select { |c| c.is_a? Chunk::Text } || []
   end
 
   def indexable_subject
diff --git a/lib/sup/message_chunks.rb b/lib/sup/message_chunks.rb
index f3f807b..e091e0b 100644
--- a/lib/sup/message_chunks.rb
+++ b/lib/sup/message_chunks.rb
@@ -1,5 +1,6 @@
 require 'tempfile'
 require 'rbconfig'
+require 'shellwords'
 
 ## Here we define all the "chunks" that a message is parsed
 ## into. Chunks are used by ThreadViewMode to render a message. Chunks
@@ -59,6 +60,8 @@ end
 module Redwood
 module Chunk
   class Attachment
+    ## please see note in write_to_disk on important usage
+    ## of quotes to avoid remote command injection.
     HookManager.register "mime-decode", <<EOS
 Decodes a MIME attachment into text form. The text will be displayed
 directly in Sup. For attachments that you wish to use a separate program
@@ -75,6 +78,9 @@ Return value:
   The decoded text of the attachment, or nil if not decoded.
 EOS
 
+
+    ## please see note in write_to_disk on important usage
+    ## of quotes to avoid remote command injection.
     HookManager.register "mime-view", <<EOS
 Views a non-text MIME attachment. This hook allows you to run
 third-party programs for attachments that require such a thing (e.g.
@@ -100,8 +106,18 @@ EOS
     attr_reader :content_type, :filename, :lines, :raw_content
     bool_reader :quotable
 
+    ## store tempfile objects as class variables so that they
+    ## are not removed when the viewing process returns. they
+    ## should be garbage collected when the class variable is removed.
+    @@view_tempfiles = []
+
     def initialize content_type, filename, encoded_content, sibling_types
       @content_type = content_type.downcase
+      if Shellwords.escape(@content_type) != @content_type
+        warn "content_type #{@content_type} is not safe, changed to application/octet-stream"
+        @content_type = 'application/octet-stream'
+      end
+
       @filename = filename
       @quotable = false # changed to true if we can parse it through the
                         # mime-decode hook, or if it's plain text
@@ -116,7 +132,9 @@ EOS
       when /^text\/plain\b/
         @raw_content
       else
-        HookManager.run "mime-decode", :content_type => content_type,
+        ## please see note in write_to_disk on important usage
+        ## of quotes to avoid remote command injection.
+        HookManager.run "mime-decode", :content_type => @content_type,
                         :filename => lambda { write_to_disk },
                         :charset => encoded_content.charset,
                         :sibling_types => sibling_types
@@ -125,7 +143,13 @@ EOS
       @lines = nil
       if text
         text = text.transcode(encoded_content.charset || $encoding, text.encoding)
-        @lines = text.gsub("\r\n", "\n").gsub(/\t/, "        ").gsub(/\r/, "").split("\n")
+        begin
+          @lines = text.gsub("\r\n", "\n").gsub(/\t/, "        ").gsub(/\r/, "").split("\n")
+        rescue Encoding::CompatibilityError
+          @lines = text.fix_encoding!.gsub("\r\n", "\n").gsub(/\t/, "        ").gsub(/\r/, "").split("\n")
+          debug "error while decoding message text, falling back to default encoding, expect errors in encoding: #{text.fix_encoding!}"
+        end
+
         @quotable = true
       end
     end
@@ -147,11 +171,13 @@ EOS
     def initial_state; :open end
     def viewable?; @lines.nil? end
     def view_default! path
+      ## please see note in write_to_disk on important usage
+      ## of quotes to avoid remote command injection.
       case RbConfig::CONFIG['arch']
         when /darwin/
-          cmd = "open '#{path}'"
+          cmd = "open #{path}"
         else
-          cmd = "/usr/bin/run-mailcap --action=view '#{@content_type}:#{path}'"
+          cmd = "/usr/bin/run-mailcap --action=view #{@content_type}:#{path}"
       end
       debug "running: #{cmd.inspect}"
       BufferManager.shell_out(cmd)
@@ -159,17 +185,31 @@ EOS
     end
 
     def view!
-      path = write_to_disk
-      ret = HookManager.run "mime-view", :content_type => @content_type,
-                                         :filename => path
-      ret || view_default!(path)
+      ## please see note in write_to_disk on important usage
+      ## of quotes to avoid remote command injection.
+      write_to_disk do |file|
+
+        @@view_tempfiles.push file # make sure the tempfile is not garbage collected before sup stops
+
+        ret = HookManager.run "mime-view", :content_type => @content_type,
+                                           :filename => file.path
+        ret || view_default!(file.path)
+      end
     end
 
+    ## note that the path returned from write_to_disk is
+    ## Shellwords.escaped and is intended to be used without single
+    ## or double quotes. the use of either opens sup up for remote
+    ## code injection through the file name.
     def write_to_disk
-      file = Tempfile.new(["sup", @filename.gsub("/", "_") || "sup-attachment"])
-      file.print @raw_content
-      file.close
-      file.path
+      begin
+        file = Tempfile.new(["sup", Shellwords.escape(@filename.gsub("/", "_")) || "sup-attachment"])
+        file.print @raw_content
+        yield file if block_given?
+        return file.path
+      ensure
+        file.close
+      end
     end
 
     ## used when viewing the attachment as text
@@ -229,7 +269,7 @@ EOS
   class EnclosedMessage
     attr_reader :lines
     def initialize from, to, cc, date, subj
-      @from = from ? "unknown sender" : from.full_adress
+      @from = from ? "unknown sender" : from.full_address
       @to = to ? "" : to.map { |p| p.full_address }.join(", ")
       @cc = cc ? "" : cc.map { |p| p.full_address }.join(", ")
       if date
diff --git a/lib/sup/modes/edit_message_mode.rb b/lib/sup/modes/edit_message_mode.rb
index 9a924a4..473f14c 100644
--- a/lib/sup/modes/edit_message_mode.rb
+++ b/lib/sup/modes/edit_message_mode.rb
@@ -489,7 +489,7 @@ protected
               return false
         end
       else
-        IO.popen(acct.sendmail, "w") { |p| p.puts m }
+        IO.popen(acct.sendmail, "w:UTF-8") { |p| p.puts m }
         raise SendmailCommandFailed, "Couldn't execute #{acct.sendmail}" unless $? == 0
       end
 
@@ -517,6 +517,7 @@ protected
     m.body += "\n" + sig_lines.join("\n") unless @sig_edited
     ## body must end in a newline or GPG signatures will be WRONG!
     m.body += "\n" unless m.body =~ /\n\Z/
+    m.body = m.body.fix_encoding!
 
     ## there are attachments, so wrap body in an attachment of its own
     unless @attachments.empty?
@@ -525,7 +526,10 @@ protected
       m = RMail::Message.new
 
       m.add_part body_m
-      @attachments.each { |a| m.add_part a }
+      @attachments.each do |a|
+        a.body = a.body.fix_encoding! if a.body.kind_of? String
+        m.add_part a
+      end
     end
 
     ## do whatever crypto transformation is necessary
@@ -547,9 +551,9 @@ protected
       m.header[k] =
         case v
         when String
-          k.match(/subject/i) ? mime_encode_subject(v) : mime_encode_address(v)
+          (k.match(/subject/i) ? mime_encode_subject(v) : mime_encode_address(v)).fix_encoding!
         when Array
-          v.map { |v| mime_encode_address v }.join ", "
+          (v.map { |v| mime_encode_address v }.join ", ").fix_encoding!
         end
     end
 
diff --git a/lib/sup/modes/search_list_mode.rb b/lib/sup/modes/search_list_mode.rb
index 8f73659..955bd1b 100644
--- a/lib/sup/modes/search_list_mode.rb
+++ b/lib/sup/modes/search_list_mode.rb
@@ -86,7 +86,11 @@ protected
     counted = searches.map do |name|
       search_string = SearchManager.search_string_for name
       begin
-        query = Index.parse_query search_string
+        if SearchManager.predefined_queries.has_key? search_string
+          query = SearchManager.predefined_queries[search_string]
+        else
+          query = Index.parse_query search_string
+        end
         total = Index.num_results_for :qobj => query[:qobj]
         unread = Index.num_results_for :qobj => query[:qobj], :label => :unread
       rescue Index::ParseError => e
diff --git a/lib/sup/modes/search_results_mode.rb b/lib/sup/modes/search_results_mode.rb
index f346e97..7bcb35a 100644
--- a/lib/sup/modes/search_results_mode.rb
+++ b/lib/sup/modes/search_results_mode.rb
@@ -40,7 +40,11 @@ class SearchResultsMode < ThreadIndexMode
 
   def self.spawn_from_query text
     begin
-      query = Index.parse_query(text)
+      if SearchManager.predefined_queries.has_key? text
+        query = SearchManager.predefined_queries[text]
+      else
+        query = Index.parse_query(text)
+      end
       return unless query
       short_text = text.length < 20 ? text : text[0 ... 20] + "..."
       mode = SearchResultsMode.new query
diff --git a/lib/sup/search.rb b/lib/sup/search.rb
index 0c63b06..0e2423d 100644
--- a/lib/sup/search.rb
+++ b/lib/sup/search.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
 module Redwood
 
 class SearchManager
@@ -15,10 +17,27 @@ class SearchManager
       end
     end
     @modified = false
+
+    @predefined_searches = { 'All mail' => 'Search all mail.' }
+    @predefined_queries  = { 'All mail'.to_sym => { :qobj => Xapian::Query.new('Kmail'),
+                                                    :load_spam => false,
+                                                    :load_deleted => false,
+                                                    :load_killed => false,
+                                                    :text => 'Search all mail.'}
+    }
+    @predefined_searches.each do |k,v|
+      @searches[k] = v
+    end
   end
 
+  def predefined_queries; return @predefined_queries; end
   def all_searches; return @searches.keys.sort; end
-  def search_string_for name; return @searches[name]; end
+  def search_string_for name;
+    if @predefined_searches.keys.member? name
+      return name.to_sym
+    end
+    return @searches[name];
+  end
   def valid_name? name; name =~ /^[\w-]+$/; end
   def name_format_hint; "letters, numbers, underscores and dashes only"; end
 
@@ -65,7 +84,7 @@ class SearchManager
 
   def save
     return unless @modified
-    File.open(@fn, "w") { |f| @searches.sort.each { |(n, s)| f.puts "#{n}: #{s}" } }
+    File.open(@fn, "w:UTF-8") { |f| (@searches - @predefined_searches.keys).sort.each { |(n, s)| f.puts "#{n}: #{s}" } }
     @modified = false
   end
 end
diff --git a/lib/sup/version.rb b/lib/sup/version.rb
index cdff2dd..99c29be 100644
--- a/lib/sup/version.rb
+++ b/lib/sup/version.rb
@@ -1,3 +1,3 @@
 module Redwood
-  VERSION = "git"
+  VERSION = "0.14.1.1"
 end
diff --git a/sup.gemspec b/sup.gemspec
index 130e1aa..ba2a0eb 100644
--- a/sup.gemspec
+++ b/sup.gemspec
@@ -36,10 +36,11 @@ DESC
     s.license = 'GPL-2'
     # TODO: might want to add index migrating script here, too
     s.post_install_message = <<-EOF
-SUP: Please run `sup-psych-ify-config-files` to migrate from 0.13 to 0.14.
+SUP: If you are upgrading Sup from before version 0.14.0: Please
+     run `sup-psych-ify-config-files` to migrate from 0.13 to 0.14.
 
-SUP: Check https://github.com/sup-heliotrope/sup/wiki/Migration-0.13-to-0.14
-     for more detailed up-to-date instructions.
+     Check https://github.com/sup-heliotrope/sup/wiki/Migration-0.13-to-0.14
+     for more detailed and up-to-date instructions.
     EOF
     s.files = SUP_FILES
     s.executables = SUP_EXECUTABLES

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/sup-mail.git



More information about the Pkg-ruby-extras-commits mailing list