sup 0.13.2.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sup might be problematic. Click here for more details.

@@ -11,13 +11,14 @@ Eric Sherman <hyperbolist at the gmail dot coms>
11
11
  Tero Tilus <tero at the tilus dot nets>
12
12
  Ben Walton <bwalton at the artsci.utoronto dot cas>
13
13
  Mike Stipicevic <stipim at the rpi dot edus>
14
+ Clint Byrum <clint at the ubuntu dot coms>
14
15
  Marcus Williams <marcus-sup at the bar-coded dot nets>
15
16
  Lionel Ott <white.magic at the gmx dot des>
16
17
  Gaudenz Steinlin <gaudenz at the soziologie dot chs>
17
18
  Damien Leone <damien.leone at the fensalir dot frs>
18
19
  Ingmar Vanhassel <ingmar at the exherbo dot orgs>
19
20
  Mark Alexander <marka at the pobox dot coms>
20
- Eric Weikl <eric.weikl at the tngtech dot coms>
21
+ Eric Weikl <eric.weikl at the gmx dot nets>
21
22
  Christopher Warrington <chrisw at the rice dot edus>
22
23
  W. Trevor King <wking at the drexel dot edus>
23
24
  Richard Brown <rbrown at the exherbo dot orgs>
@@ -26,9 +27,11 @@ Marc Hartstein <marc.hartstein at the alum.vassar dot edus>
26
27
  Israel Herraiz <israel.herraiz at the gmail dot coms>
27
28
  Bo Borgerson <gigabo at the gmail dot coms>
28
29
  Michael Hamann <michael at the content-space dot des>
30
+ Jonathan Lassoff <jof at the thejof dot coms>
29
31
  William Erik Baxter <web at the superscript dot coms>
30
32
  Grant Hollingworth <grant at the antiflux dot orgs>
31
33
  Markus Klinik <markus.klinik at the gmx dot des>
34
+ Ico Doornekamp <ico at the pruts dot nls>
32
35
  Adeodato Simó <dato at the net.com.org dot ess>
33
36
  Daniel Schoepe <daniel.schoepe at the googlemail dot coms>
34
37
  Jason Petsod <jason at the petsod dot orgs>
@@ -44,21 +47,22 @@ Andrew Pimlott <andrew at the pimlott dot nets>
44
47
  Jeff Balogh <its.jeff.balogh at the gmail dot coms>
45
48
  Matías Aguirre <matiasaguirre at the gmail dot coms>
46
49
  Kornilios Kourtis <kkourt at the cslab.ece.ntua dot grs>
47
- Giorgio Lando <patroclo7 at the gmail dot coms>
48
50
  Kevin Riggle <kevinr at the free-dissociation dot coms>
51
+ Giorgio Lando <patroclo7 at the gmail dot coms>
49
52
  Benoît PIERRE <benoit.pierre at the gmail dot coms>
53
+ Matthieu Rakotojaona <matthieu.rakotojaona at the gmail dot coms>
50
54
  Alvaro Herrera <alvherre at the alvh.no-ip dot orgs>
51
55
  Steven Lawrance <stl at the koffein dot nets>
52
56
  Jonah <Jonah at the GoodCoffee dot cas>
53
57
  ian <itaylor at the uark dot edus>
58
+ Todd Eisenberger <teisenbe at the andrew.cmu dot edus>
54
59
  Adam Lloyd <adam at the alloy-d dot nets>
55
- Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
56
60
  MichaelRevell <mikearevell at the gmail dot coms>
57
- Todd Eisenberger <teisenbe at the andrew.cmu dot edus>
61
+ Per Andersson <avtobiff at the gmail dot coms>
62
+ Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
58
63
  Steven Walter <swalter at the monarch.(none)>
59
64
  Jon M. Dugan <jdugan at the es dot nets>
60
- Jonathan Lassoff <jof at the thejof dot coms>
61
- Matthieu Rakotojaona <matthieu.rakotojaona at the gmail dot coms>
62
- Stefan Lundström <lundst at the snabb.(none)>
63
65
  Matthias Vallentin <vallentin at the icir dot orgs>
66
+ Stefan Lundström <lundst at the snabb.(none)>
67
+ Horacio Sanson <horacio at the skillupjapan.co dot jps>
64
68
  Kirill Smelkov <kirr at the landau.phys.spbu dot rus>
@@ -1,6 +1,12 @@
1
- == 0.13.2.1 / 2013-10-29
2
-
3
- * SBU1: security release
1
+ == 0.14.0 / 2013-08-15
2
+
3
+ * CJK compatability
4
+ * Psych over Syck
5
+ * Ruby 1.8 deprecated
6
+ * Thread safety
7
+ * No more Iconv, but using built in Ruby encodings. Better UTF-8
8
+ handling.
9
+ * GPGME 2.0 support
4
10
 
5
11
  == 0.13.2 / 2013-06-26
6
12
 
@@ -1,24 +1,21 @@
1
- Release 0.13.2.1:
1
+ Release 0.14.0:
2
2
 
3
- Security advisory (#SBU1) for Sup
3
+ CJK-compatability, Psych usage, thread safety, GPGME 2.0 support. Sup is now
4
+ Ruby 1.9 based, and apart from RMail - ready for Ruby 2.0.0.
4
5
 
5
- We have been notified of an potential exploit in the somewhat careless
6
- way Sup treats attachment metadata in received e-mails. The issues
7
- should now be fixed and I have released Sup 0.13.2.1 and 0.14.1.1 which
8
- incorporates these fixes. Please upgrade immediately and also ensure
9
- that your mime-decode or mime-view hooks are secure [0], [1].
6
+ Sup now uses Psych as a YAML parser (default by Ruby) and your previous
7
+ configuration files (~/.sup/*.yaml) may need to be migrated or re-created for
8
+ them to work with the new sup. A migration script is included for this.
10
9
 
11
- This is specifically related to using quotes (',") around filename or
12
- content_type which is already escaped using Ruby Shellwords.escape -
13
- this means that the string (content_type, filename) is intended to be
14
- used _without_ any further quotes. Please make sure that if you use
15
- .mailcap (non OSX systems), you do not quote the string.
10
+ Check https://github.com/sup-heliotrope/sup/wiki/Migration-0.13-to-0.14 for
11
+ the latest instructions.
16
12
 
17
- Credit goes to: joernchen of Phenoelit (http://phenoelit.de) who
18
- discovered and suggested fixes for these issues.
13
+ First back up your ~/.sup directory and index, after installing the new sup
14
+ run:
19
15
 
20
- [0] https://github.com/sup-heliotrope/sup/wiki/Viewing-Attachments
21
- [1] https://github.com/sup-heliotrope/sup/wiki/Secure-usage-of-Sup
16
+ $ sup-psych-ify-config-files
17
+
18
+ to migrate your files. You should now be all set for buisness.
22
19
 
23
20
 
24
21
  Release 0.13.2:
data/bin/sup CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
+ # encoding: utf-8
2
3
 
3
4
  $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
5
 
@@ -8,8 +9,6 @@ require 'ncursesw'
8
9
 
9
10
  no_gpgme = false
10
11
  begin
11
- # gpgme broke its API in 2.0, so make sure we have the old version for now.
12
- gem 'gpgme', '=1.0.8'
13
12
  require 'gpgme'
14
13
  rescue LoadError
15
14
  no_gpgme = true
@@ -158,7 +157,11 @@ begin
158
157
 
159
158
  $die = false
160
159
  trap("TERM") { |x| $die = true }
161
- trap("WINCH") { |x| BufferManager.sigwinch_happened! }
160
+ trap("WINCH") do |x|
161
+ ::Thread.new do
162
+ BufferManager.sigwinch_happened!
163
+ end
164
+ end
162
165
 
163
166
  if(s = Redwood::SourceManager.source_for DraftManager.source_name)
164
167
  DraftManager.source = s
@@ -290,8 +293,8 @@ begin
290
293
  b.mode.load_in_background if new
291
294
  when :search
292
295
  completions = LabelManager.all_labels.map { |l| "label:#{LabelManager.string_for l}" }
293
- completions = completions.each { |l| l.force_encoding 'UTF-8' if l.methods.include?(:encoding) }
294
- completions += ["from:", "to:", "after:", "before:", "date:", "limit:", "AND", "OR", "NOT"]
296
+ completions = completions.each { |l| l.fix_encoding }
297
+ completions += Index::COMPL_PREFIXES
295
298
  query = BufferManager.ask_many_with_completions :search, "Search all messages (enter for saved searches): ", completions
296
299
  unless query.nil?
297
300
  if query.empty?
@@ -304,7 +307,7 @@ begin
304
307
  SearchResultsMode.spawn_from_query "is:unread"
305
308
  when :list_labels
306
309
  labels = LabelManager.all_labels.map { |l| LabelManager.string_for l }
307
- labels = labels.each { |l| l.force_encoding 'UTF-8' if l.methods.include?(:encoding) }
310
+ labels = labels.each { |l| l.fix_encoding }
308
311
 
309
312
  user_label = bm.ask_with_completions :label, "Show threads with label (enter for listing): ", labels
310
313
  unless user_label.nil?
@@ -412,7 +415,7 @@ unless Redwood::exceptions.empty?
412
415
  We are very sorry. It seems that an error occurred in Sup. Please
413
416
  accept our sincere apologies. Please submit the contents of
414
417
  #{BASE_DIR}/exception-log.txt and a brief report of the
415
- circumstances to https://github.com/sup-heliotrope/sup/issues so that
418
+ circumstances to https://github.com/sup-heliotrope/sup/issues so that
416
419
  we might address this problem. Thank you!
417
420
 
418
421
  Sincerely,
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
4
+
5
+ require "sup"
6
+ require "fileutils"
7
+
8
+ Redwood.start
9
+
10
+ fn = Redwood::SOURCE_FN
11
+ FileUtils.cp fn, "#{fn}.syck_bak"
12
+
13
+ Redwood::SourceManager.load_sources fn
14
+ Redwood::SourceManager.save_sources fn, true
15
+
16
+ Redwood.finish
data/lib/sup.rb CHANGED
@@ -1,11 +1,8 @@
1
- require 'rubygems'
1
+ # encoding: utf-8
2
2
 
3
- require 'syck'
3
+ require 'rubygems'
4
4
  require 'yaml'
5
- if YAML.const_defined? :ENGINE
6
- YAML::ENGINE.yamler = 'syck'
7
- end
8
-
5
+ YAML::ENGINE.yamler = 'psych'
9
6
  require 'zlib'
10
7
  require 'thread'
11
8
  require 'fileutils'
@@ -28,18 +25,23 @@ end
28
25
  class Module
29
26
  def yaml_properties *props
30
27
  props = props.map { |p| p.to_s }
31
- vars = props.map { |p| "@#{p}" }
32
- klass = self
33
- path = klass.name.gsub(/::/, "/")
34
28
 
35
- klass.instance_eval do
36
- define_method(:to_yaml_properties) { vars }
37
- define_method(:to_yaml_type) { "!#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}" }
29
+ path = name.gsub(/::/, "/")
30
+ yaml_tag "!#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}"
31
+
32
+ define_method :init_with do |coder|
33
+ initialize(*coder.map.values_at(*props))
38
34
  end
39
35
 
40
- YAML.add_domain_type("#{Redwood::YAML_DOMAIN},#{Redwood::YAML_DATE}", path) do |type, val|
41
- klass.new(*props.map { |p| val[p] })
36
+ define_method :encode_with do |coder|
37
+ coder.map = props.inject({}) do |hash, key|
38
+ hash[key] = instance_variable_get("@#{key}")
39
+ hash
40
+ end
42
41
  end
42
+
43
+ # Legacy
44
+ Psych.load_tags["!#{Redwood::LEGACY_YAML_DOMAIN},#{Redwood::YAML_DATE}/#{path}"] = self
43
45
  end
44
46
  end
45
47
 
@@ -58,7 +60,8 @@ module Redwood
58
60
  SEARCH_FN = File.join(BASE_DIR, "searches.txt")
59
61
  LOG_FN = File.join(BASE_DIR, "log")
60
62
 
61
- YAML_DOMAIN = "masanjin.net"
63
+ YAML_DOMAIN = "supmua.org"
64
+ LEGACY_YAML_DOMAIN = "masanjin.net"
62
65
  YAML_DATE = "2006-10-01"
63
66
 
64
67
  ## record exceptions thrown in threads nicely
@@ -268,7 +271,7 @@ EOM
268
271
  else
269
272
  require 'etc'
270
273
  require 'socket'
271
- name = Etc.getpwnam(ENV["USER"]).gecos.split(/,/).first rescue nil
274
+ name = Etc.getpwnam(ENV["USER"]).gecos.split(/,/).first.force_encoding($encoding).fix_encoding rescue nil
272
275
  name ||= ENV["USER"]
273
276
  email = ENV["USER"] + "@" +
274
277
  begin
@@ -280,8 +283,8 @@ EOM
280
283
  config = {
281
284
  :accounts => {
282
285
  :default => {
283
- :name => name,
284
- :email => email,
286
+ :name => name.fix_encoding,
287
+ :email => email.fix_encoding,
285
288
  :alternates => [],
286
289
  :sendmail => "/usr/sbin/sendmail -oem -ti",
287
290
  :signature => File.join(ENV["HOME"], ".signature"),
@@ -314,6 +317,7 @@ require "sup/logger/singleton"
314
317
  ## determine encoding and character set
315
318
  $encoding = Locale.current.charset
316
319
  $encoding = "UTF-8" if $encoding == "utf8"
320
+ $encoding = "UTF-8" if $encoding == "UTF8"
317
321
  if $encoding
318
322
  debug "using character set encoding #{$encoding.inspect}"
319
323
  else
@@ -321,6 +325,16 @@ else
321
325
  $encoding = "UTF-8"
322
326
  end
323
327
 
328
+ # test encoding
329
+ teststr = "test"
330
+ teststr.encode('UTF-8')
331
+ begin
332
+ teststr.encode($encoding)
333
+ rescue Encoding::ConverterNotFoundError
334
+ warn "locale encoding is invalid, defaulting to utf-8"
335
+ $encoding = "UTF-8"
336
+ end
337
+
324
338
  require "sup/buffer"
325
339
  require "sup/keymap"
326
340
  require "sup/mode"
@@ -50,8 +50,9 @@ class AccountManager
50
50
  [:name, :sendmail, :signature, :gpgkey].each { |k| hash[k] ||= @default_account.send(k) }
51
51
  end
52
52
  hash[:alternates] ||= []
53
+ fail "alternative emails are not an array: #{hash[:alternates]}" unless hash[:alternates].kind_of? Array
53
54
 
54
- [:name, :signature].each { |x| hash[x].force_encoding Encoding::UTF_8 if hash[x].respond_to? :encoding }
55
+ [:name, :signature].each { |x| hash[x] ? hash[x].fix_encoding : nil }
55
56
 
56
57
  a = Account.new hash
57
58
  @accounts[a] = true
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  require 'etc'
2
4
  require 'thread'
3
5
 
@@ -126,14 +128,11 @@ class Buffer
126
128
  @w.attrset Colormap.color_for(opts[:color] || :none, opts[:highlight])
127
129
  s ||= ""
128
130
  maxl = @width - x # maximum display width width
129
- stringl = maxl # string "length"
130
131
 
131
132
  # fill up the line with blanks to overwrite old screen contents
132
133
  @w.mvaddstr y, x, " " * maxl unless opts[:no_fill]
133
134
 
134
- ## the next horribleness is thanks to ruby's lack of widechar support
135
- stringl += 1 while stringl < s.length && s[0 ... stringl].display_length < maxl
136
- @w.mvaddstr y, x, s[0 ... stringl]
135
+ @w.mvaddstr y, x, s.slice_by_display_length(maxl)
137
136
  end
138
137
 
139
138
  def clear
@@ -450,7 +449,7 @@ EOS
450
449
 
451
450
  def ask_with_completions domain, question, completions, default=nil
452
451
  ask domain, question, default do |s|
453
- s.force_encoding 'UTF-8' if s.methods.include?(:encoding)
452
+ s.fix_encoding
454
453
  completions.select { |x| x =~ /^#{Regexp::escape s}/iu }.map { |x| [x, x] }
455
454
  end
456
455
  end
@@ -467,9 +466,9 @@ EOS
467
466
  raise "william screwed up completion: #{partial.inspect}"
468
467
  end
469
468
 
470
- prefix.force_encoding 'UTF-8' if prefix.methods.include?(:encoding)
471
- target.force_encoding 'UTF-8' if target.methods.include?(:encoding)
472
- completions.select { |x| x =~ /^#{Regexp::escape target}/i }.map { |x| [prefix + x, x] }
469
+ prefix.fix_encoding
470
+ target.fix_encoding
471
+ completions.select { |x| x =~ /^#{Regexp::escape target}/iu }.map { |x| [prefix + x, x] }
473
472
  end
474
473
  end
475
474
 
@@ -477,12 +476,12 @@ EOS
477
476
  ask domain, question, default do |partial|
478
477
  prefix, target = partial.split_on_commas_with_remainder
479
478
  target ||= prefix.pop || ""
480
- target.force_encoding 'UTF-8' if target.methods.include?(:encoding)
479
+ target.fix_encoding
481
480
 
482
481
  prefix = prefix.join(", ") + (prefix.empty? ? "" : ", ")
483
- prefix.force_encoding 'UTF-8' if prefix.methods.include?(:encoding)
482
+ prefix.fix_encoding
484
483
 
485
- completions.select { |x| x =~ /^#{Regexp::escape target}/i }.sort_by { |c| [ContactManager.contact_for(c) ? 0 : 1, c] }.map { |x| [prefix + x, x] }
484
+ completions.select { |x| x =~ /^#{Regexp::escape target}/iu }.sort_by { |c| [ContactManager.contact_for(c) ? 0 : 1, c] }.map { |x| [prefix + x, x] }
486
485
  end
487
486
  end
488
487
 
@@ -495,7 +494,7 @@ EOS
495
494
  if dir
496
495
  [[s.sub(full, dir), "~#{name}"]]
497
496
  else
498
- users.select { |u| u =~ /^#{Regexp::escape name}/ }.map do |u|
497
+ users.select { |u| u =~ /^#{Regexp::escape name}/u }.map do |u|
499
498
  [s.sub("~#{name}", "~#{u}"), "~#{u}"]
500
499
  end
501
500
  end
@@ -554,6 +553,7 @@ EOS
554
553
 
555
554
  completions = (recent + contacts).flatten.uniq
556
555
  completions += HookManager.run("extra-contact-addresses") || []
556
+
557
557
  answer = BufferManager.ask_many_emails_with_completions domain, question, completions, default
558
558
 
559
559
  if answer
@@ -622,7 +622,7 @@ EOS
622
622
  tf.deactivate
623
623
  draw_screen :sync => false, :status => status, :title => title
624
624
  end
625
- tf.value.tap { |x| x.force_encoding Encoding::UTF_8 if x && x.respond_to?(:encoding) }
625
+ tf.value.tap { |x| x }
626
626
  end
627
627
 
628
628
  def ask_getch question, accept=nil
@@ -1,3 +1,5 @@
1
+ # encoding: utf-8
2
+
1
3
  module Redwood
2
4
 
3
5
  class ContactManager
@@ -54,7 +56,7 @@ class ContactManager
54
56
  def is_aliased_contact? person; !@p2a[person].nil? end
55
57
 
56
58
  def save
57
- File.open(@fn, "w") do |f|
59
+ File.open(@fn, "w:UTF-8") do |f|
58
60
  @p2a.sort_by { |(p, a)| [p.full_address, a] }.each do |(p, a)|
59
61
  f.puts "#{a || ''}: #{p.full_address}"
60
62
  end
@@ -1,6 +1,4 @@
1
1
  begin
2
- # gpgme broke its API in 2.0, so make sure we have the old version for now.
3
- gem 'gpgme', '=1.0.8'
4
2
  require 'gpgme'
5
3
  rescue LoadError
6
4
  end
@@ -64,28 +62,39 @@ EOS
64
62
  @gpgme_present =
65
63
  begin
66
64
  begin
67
- GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
65
+ begin
66
+ GPGME.check_version({:protocol => GPGME::PROTOCOL_OpenPGP})
67
+ rescue TypeError
68
+ GPGME.check_version(nil)
69
+ end
68
70
  true
69
71
  rescue GPGME::Error
70
72
  false
73
+ rescue ArgumentError
74
+ # gpgme 2.0.0 raises this due to the hash->string conversion
75
+ false
71
76
  end
72
77
  rescue NameError
73
78
  false
74
79
  end
75
80
 
76
81
  unless @gpgme_present
77
- @not_working_reason = ['gpgme gem not present',
82
+ @not_working_reason = ['gpgme gem not present',
78
83
  'Install the gpgme gem in order to use signed and encrypted emails']
79
84
  return
80
85
  end
81
86
 
82
87
  # if gpg2 is available, it will start gpg-agent if required
83
88
  if (bin = `which gpg2`.chomp) =~ /\S/
84
- GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
89
+ if GPGME.respond_to?('set_engine_info')
90
+ GPGME.set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
91
+ else
92
+ GPGME.gpgme_set_engine_info GPGME::PROTOCOL_OpenPGP, bin, nil
93
+ end
85
94
  else
86
95
  # check if the gpg-options hook uses the passphrase_callback
87
96
  # if it doesn't then check if gpg agent is present
88
- gpg_opts = HookManager.run("gpg-options",
97
+ gpg_opts = HookManager.run("gpg-options",
89
98
  {:operation => "sign", :options => {}}) || {}
90
99
  if gpg_opts[:passphrase_callback].nil?
91
100
  if ENV['GPG_AGENT_INFO'].nil?
@@ -110,22 +119,29 @@ EOS
110
119
  end
111
120
 
112
121
  def have_crypto?; @not_working_reason.nil? end
122
+ def not_working_reason; @not_working_reason end
113
123
 
114
124
  def sign from, to, payload
115
125
  return unknown_status(@not_working_reason) unless @not_working_reason.nil?
116
126
 
117
127
  gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true}
118
128
  gpg_opts.merge!(gen_sign_user_opts(from))
119
- gpg_opts = HookManager.run("gpg-options",
129
+ gpg_opts = HookManager.run("gpg-options",
120
130
  {:operation => "sign", :options => gpg_opts}) || gpg_opts
121
131
 
122
132
  begin
123
- sig = GPGME.detach_sign(format_payload(payload), gpg_opts)
133
+ if GPGME.respond_to?('detach_sign')
134
+ sig = GPGME.detach_sign(format_payload(payload), gpg_opts)
135
+ else
136
+ crypto = GPGME::Crypto.new
137
+ gpg_opts[:mode] = GPGME::SIG_MODE_DETACH
138
+ sig = crypto.sign(format_payload(payload), gpg_opts).read
139
+ end
124
140
  rescue GPGME::Error => exc
125
141
  raise Error, gpgme_exc_msg(exc.message)
126
142
  end
127
143
 
128
- # if the key (or gpg-agent) is not available GPGME does not complain
144
+ # if the key (or gpg-agent) is not available GPGME does not complain
129
145
  # but just returns a zero length string. Let's catch that
130
146
  if sig.length == 0
131
147
  raise Error, gpgme_exc_msg("GPG failed to generate signature: check that gpg-agent is running and your key is available.")
@@ -145,7 +161,7 @@ EOS
145
161
 
146
162
  gpg_opts = {:protocol => GPGME::PROTOCOL_OpenPGP, :armor => true, :textmode => true}
147
163
  if sign
148
- gpg_opts.merge!(gen_sign_user_opts(from))
164
+ gpg_opts.merge!(gen_sign_user_opts(from))
149
165
  gpg_opts.merge!({:sign => true})
150
166
  end
151
167
  gpg_opts = HookManager.run("gpg-options",
@@ -153,12 +169,18 @@ EOS
153
169
  recipients = to + [from]
154
170
  recipients = HookManager.run("gpg-expand-keys", { :recipients => recipients }) || recipients
155
171
  begin
156
- cipher = GPGME.encrypt(recipients, format_payload(payload), gpg_opts)
172
+ if GPGME.respond_to?('encrypt')
173
+ cipher = GPGME.encrypt(recipients, format_payload(payload), gpg_opts)
174
+ else
175
+ crypto = GPGME::Crypto.new
176
+ gpg_opts[:recipients] = recipients
177
+ cipher = crypto.encrypt(format_payload(payload), gpg_opts).read
178
+ end
157
179
  rescue GPGME::Error => exc
158
180
  raise Error, gpgme_exc_msg(exc.message)
159
181
  end
160
182
 
161
- # if the key (or gpg-agent) is not available GPGME does not complain
183
+ # if the key (or gpg-agent) is not available GPGME does not complain
162
184
  # but just returns a zero length string. Let's catch that
163
185
  if cipher.length == 0
164
186
  raise Error, gpgme_exc_msg("GPG failed to generate cipher text: check that gpg-agent is running and your key is available.")
@@ -262,7 +284,11 @@ EOS
262
284
  {:operation => "decrypt", :options => gpg_opts}) || gpg_opts
263
285
  ctx = GPGME::Ctx.new(gpg_opts)
264
286
  cipher_data = GPGME::Data.from_str(format_payload(payload))
265
- plain_data = GPGME::Data.empty
287
+ if GPGME::Data.respond_to?('empty')
288
+ plain_data = GPGME::Data.empty
289
+ else
290
+ plain_data = GPGME::Data.empty!
291
+ end
266
292
  begin
267
293
  ctx.decrypt_verify(cipher_data, plain_data)
268
294
  rescue GPGME::Error => exc
@@ -275,7 +301,7 @@ EOS
275
301
  end
276
302
  plain_data.seek(0, IO::SEEK_SET)
277
303
  output = plain_data.read
278
- output.force_encoding Encoding::ASCII_8BIT if output.respond_to? :force_encoding
304
+ output.transcode(Encoding::ASCII_8BIT, output.encoding)
279
305
 
280
306
  ## TODO: test to see if it is still necessary to do a 2nd run if verify
281
307
  ## fails.
@@ -290,7 +316,7 @@ EOS
290
316
  # Look for Charset, they are put before the base64 crypted part
291
317
  charsets = payload.body.split("\n").grep(/^Charset:/)
292
318
  if !charsets.empty? and charsets[0] =~ /^Charset: (.+)$/
293
- output = Iconv.easy_decode($encoding, $1, output)
319
+ output.transcode($encoding, $1)
294
320
  end
295
321
  msg.body = output
296
322
  else
@@ -314,7 +340,7 @@ EOS
314
340
  msg = RMail::Parser.read output
315
341
  if msg.header.content_type =~ %r{^multipart/} && !msg.multipart?
316
342
  output = "MIME-Version: 1.0\n" + output
317
- output.force_encoding Encoding::ASCII_8BIT if output.respond_to? :force_encoding
343
+ output.fix_encoding
318
344
  msg = RMail::Parser.read output
319
345
  end
320
346
  end
@@ -330,7 +356,7 @@ private
330
356
 
331
357
  def gpgme_exc_msg msg
332
358
  err_msg = "Exception in GPGME call: #{msg}"
333
- info err_msg
359
+ #info err_msg
334
360
  err_msg
335
361
  end
336
362
 
@@ -362,7 +388,7 @@ private
362
388
  else
363
389
  first_sig = "Unknown error or empty signature"
364
390
  end
365
- rescue EOFError
391
+ rescue EOFError
366
392
  from_key = nil
367
393
  first_sig = "No public key available for #{signature.fingerprint}"
368
394
  end