sup 0.20.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.travis.yml +1 -1
  4. data/CONTRIBUTORS +15 -12
  5. data/History.txt +16 -0
  6. data/ReleaseNotes +7 -0
  7. data/bin/sup +10 -24
  8. data/bin/sup-sync-back-maildir +1 -1
  9. data/contrib/completion/_sup.bash +102 -0
  10. data/lib/sup.rb +7 -7
  11. data/lib/sup/colormap.rb +5 -2
  12. data/lib/sup/contact.rb +4 -2
  13. data/lib/sup/crypto.rb +34 -2
  14. data/lib/sup/draft.rb +7 -7
  15. data/lib/sup/hook.rb +1 -1
  16. data/lib/sup/index.rb +2 -2
  17. data/lib/sup/label.rb +1 -1
  18. data/lib/sup/maildir.rb +2 -2
  19. data/lib/sup/mbox.rb +2 -2
  20. data/lib/sup/message.rb +6 -0
  21. data/lib/sup/message_chunks.rb +4 -2
  22. data/lib/sup/mode.rb +31 -26
  23. data/lib/sup/modes/edit_message_mode.rb +1 -1
  24. data/lib/sup/modes/forward_mode.rb +22 -3
  25. data/lib/sup/modes/line_cursor_mode.rb +1 -1
  26. data/lib/sup/modes/text_mode.rb +6 -1
  27. data/lib/sup/modes/thread_index_mode.rb +1 -1
  28. data/lib/sup/modes/thread_view_mode.rb +47 -6
  29. data/lib/sup/person.rb +68 -61
  30. data/lib/sup/search.rb +1 -1
  31. data/lib/sup/sent.rb +1 -1
  32. data/lib/sup/util/locale_fiddler.rb +24 -0
  33. data/lib/sup/version.rb +1 -1
  34. data/sup.gemspec +4 -3
  35. data/test/integration/test_maildir.rb +1 -1
  36. data/test/integration/test_mbox.rb +1 -1
  37. data/test/test_crypto.rb +1 -1
  38. data/test/test_header_parsing.rb +1 -1
  39. data/test/test_message.rb +77 -19
  40. data/test/test_messages_dir.rb +1 -19
  41. data/test/test_yaml_regressions.rb +1 -1
  42. data/test/unit/fixtures/contacts.txt +1 -0
  43. data/test/unit/test_contact.rb +33 -0
  44. data/test/unit/test_locale_fiddler.rb +15 -0
  45. data/test/unit/test_person.rb +37 -0
  46. metadata +31 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e7b5ce3c73c1c6d194d8103bb25de84981db2529
4
- data.tar.gz: a5d0868505c66e8c7974025d5131738d2a436ab6
3
+ metadata.gz: 7303df91a168cda15ce5be2bcb280676acafb4bb
4
+ data.tar.gz: 3abfca06f5727c6efd4b179c12304773328a2d84
5
5
  SHA512:
6
- metadata.gz: 8b44f362bd82be161b1d9451d805af1a9d73d962df4c54196703dec1bbca383fb7bd5f2c0bf6479c1fc57bc27b37ec17a65fc2b24abab838e7f2797bfb64687a
7
- data.tar.gz: e3a2eaaebf74bec788b18c28be9d9a2bee2b8fa06487780f3199aa7446ec386ac5ffc731595245e40be6423dfc1708bed14fe74ada70eab06097655ccc4fd47a
6
+ metadata.gz: 521dfa870e7caf37067677814ee4750f8c175fc4ab590e14f67fddab2f19923078b30c1f709c23e2af71cf8711a110b9ed576669f4c1dac30d67035742f53399
7
+ data.tar.gz: 17f73b5cb16135dbd9b1d423a8e899e6c2bca4fd50c52d1107f353f2e7acf52715fda32d4586cf90fc5e6252a9fe6ea761e27d583e14d094bf9f85f1a8fe59c7
data/.gitignore CHANGED
@@ -16,4 +16,7 @@ Gemfile.lock
16
16
  # generated file for gnupg test
17
17
  test/gnupg_test_home/random_seed
18
18
  test/gnupg_test_home/trustdb.gpg
19
+ test/gnupg_test_home/.gpg-v21-migrated
20
+ test/gnupg_test_home/private-keys-v1.d
21
+
19
22
 
@@ -3,7 +3,7 @@ language: ruby
3
3
  rvm:
4
4
  - 2.1.1
5
5
  - 2.0.0
6
- - 1.9.3
6
+ - 2.2.0
7
7
 
8
8
  before_install:
9
9
  - sudo apt-get update -qq
@@ -9,23 +9,25 @@ Eric Weikl <eric.weikl at the gmx dot nets>
9
9
  Paweł Wilk <siefca at the gnu dot orgs>
10
10
  Ismo Puustinen <ismo at the iki dot fis>
11
11
  Nicolas Pouillard <nicolas.pouillard at the gmail dot coms>
12
+ Matthieu Rakotojaona <matthieu.rakotojaona at the gmail dot coms>
12
13
  Michael Stapelberg <michael at the stapelberg dot des>
13
14
  Eric Sherman <hyperbolist at the gmail dot coms>
15
+ Zeger-Jan van de Weg <mail at the zjvandeweg dot nls>
14
16
  Tero Tilus <tero at the tilus dot nets>
15
17
  Ben Walton <bwalton at the artsci.utoronto dot cas>
16
18
  Scott Bonds <scott at the ggr dot coms>
17
19
  Mike Stipicevic <stipim at the rpi dot edus>
18
20
  Martin Bähr <mbaehr at the societyserver dot orgs>
19
- Matthieu Rakotojaona <matthieu.rakotojaona at the gmail dot coms>
21
+ Timon Vonk <timonv at the gmail dot coms>
20
22
  Clint Byrum <clint at the ubuntu dot coms>
21
23
  Wael M. Nasreddine <wael.nasreddine at the gmail dot coms>
22
24
  Marcus Williams <marcus-sup at the bar-coded dot nets>
23
25
  Lionel Ott <white.magic at the gmx dot des>
24
26
  Gaudenz Steinlin <gaudenz at the soziologie dot chs>
27
+ Per Andersson <avtobiff at the gmail dot coms>
25
28
  Ingmar Vanhassel <ingmar at the exherbo dot orgs>
26
29
  Mark Alexander <marka at the pobox dot coms>
27
30
  Edward Z. Yang <ezyang at the mit dot edus>
28
- Timon Vonk <timonv at the gmail dot coms>
29
31
  julien@macbook <julien.stechele at the gmail dot coms>
30
32
  Christopher Warrington <chrisw at the rice dot edus>
31
33
  W. Trevor King <wking at the drexel dot edus>
@@ -38,49 +40,50 @@ Markus Klinik <mkl at the lambdanaut dot nets>
38
40
  Bo Borgerson <gigabo at the gmail dot coms>
39
41
  Atte Kojo <atte.kojo at the reaktor dot fis>
40
42
  Michael Hamann <michael at the content-space dot des>
41
- Jonathan Lassoff <jof at the thejof dot coms>
42
43
  William Erik Baxter <web at the superscript dot coms>
44
+ Jonathan Lassoff <jof at the thejof dot coms>
43
45
  Grant Hollingworth <grant at the antiflux dot orgs>
44
46
  Ico Doornekamp <ico at the pruts dot nls>
45
47
  Adeodato Simó <dato at the net.com.org dot ess>
46
48
  Daniel Schoepe <daniel.schoepe at the googlemail dot coms>
47
- James Taylor <james at the jamestaylor dot orgs>
48
49
  Jason Petsod <jason at the petsod dot orgs>
50
+ James Taylor <james at the jamestaylor dot orgs>
49
51
  Steve Goldman <sgoldman at the tower-research dot coms>
50
52
  Robin Burchell <viroteck at the viroteck dot nets>
51
53
  Peter Harkins <ph at the malaprop dot orgs>
52
54
  Decklin Foster <decklin at the red-bean dot coms>
55
+ rjg-vB <rthrd at the web dot des>
53
56
  Cameron Matheson <cam+sup at the cammunism dot orgs>
54
- Carl Worth <cworth at the cworth dot orgs>
55
57
  Alex Vandiver <alex at the chmrr dot nets>
58
+ Carl Worth <cworth at the cworth dot orgs>
56
59
  Jeff Balogh <its.jeff.balogh at the gmail dot coms>
57
60
  Andrew Pimlott <andrew at the pimlott dot nets>
58
61
  Matías Aguirre <matiasaguirre at the gmail dot coms>
59
62
  PaulSmecker <paul.smecker at the gmail dot coms>
60
- Per Andersson <avtobiff at the gmail dot coms>
61
63
  Ruthard Baudach <rthrd at the web dot des>
62
64
  Kornilios Kourtis <kkourt at the cslab.ece.ntua dot grs>
63
65
  Lars Fischer <fischer at the wiwi.uni-siegen dot des>
64
66
  madhat2r <MaDhAt2r at the dukefoo dot coms>
65
- Giorgio Lando <patroclo7 at the gmail dot coms>
66
67
  Kevin Riggle <kevinr at the free-dissociation dot coms>
68
+ Giorgio Lando <patroclo7 at the gmail dot coms>
67
69
  Benoît PIERRE <benoit.pierre at the gmail dot coms>
68
70
  Alvaro Herrera <alvherre at the alvh.no-ip dot orgs>
69
71
  Steven Lawrance <stl at the koffein dot nets>
70
72
  Jonah <Jonah at the GoodCoffee dot cas>
71
73
  ian <itaylor at the uark dot edus>
72
- Adam Lloyd <adam at the alloy-d dot nets>
73
74
  Todd Eisenberger <teisenbe at the andrew.cmu dot edus>
74
- 0xACE <0xACE at the users.noreply.github dot coms>
75
75
  MichaelRevell <mikearevell at the gmail dot coms>
76
+ Adam Lloyd <adam at the alloy-d dot nets>
77
+ 0xACE <0xACE at the users.noreply.github dot coms>
76
78
  Gregor Hoffleit <gregor at the sam.mediasupervision dot des>
77
- Steven Schmeiser <steven at the schmeiser dot orgs>
79
+ Sharif Olorin <sio at the tesser dot orgs>
78
80
  Steven Walter <swalter at the monarch.(none)>
79
- Jon M. Dugan <jdugan at the es dot nets>
80
- Horacio Sanson <horacio at the skillupjapan.co dot jps>
81
+ Steven Schmeiser <steven at the schmeiser dot orgs>
81
82
  Stefan Lundström <lundst at the snabb.(none)>
82
83
  William A. Kennington III <william at the wkennington dot coms>
83
84
  akojo <atte.kojo at the gmail dot coms>
85
+ Horacio Sanson <horacio at the skillupjapan.co dot jps>
86
+ Jon M. Dugan <jdugan at the es dot nets>
84
87
  Matthias Vallentin <vallentin at the icir dot orgs>
85
88
  Johannes Larsen <johs.a.larsen at the gmail dot coms>
86
89
  Kirill Smelkov <kirr at the landau.phys.spbu dot rus>
@@ -1,3 +1,19 @@
1
+ == 0.21.0 / 2015-02-12
2
+
3
+ * Key binding to fetch GPG key from keyserver (Matthieu Rakotojaona)
4
+ * Replace occurences of File.exists? with File.exist? (Zeger-Jan van de
5
+ Weg)
6
+ * You can now unsubscribe from mailinglists using an url, if you have a
7
+ goto-hook setup (Timon Vonk).
8
+ * Forward attribution can be customized using the forward-attribution
9
+ hook (Ruthard Baudach)
10
+ * Do a few more checks for buffer not nil in the hope to fix a few
11
+ random crashes
12
+ * Add bash completion (Per Andersson)
13
+ * Replace dl/import with Fiddle (Timon Vonk)
14
+ * Drop support for ruby 1.9.3
15
+ * Add tests for contact manager and persons (Zeger-Jan van de Weg)
16
+
1
17
  == 0.20.0 / 2014-10-06
2
18
 
3
19
  * add man-pages (generated from wiki) (Per Andersson)!
@@ -1,3 +1,10 @@
1
+ Release 0.21.0:
2
+
3
+ Several small features as well as polishing (including fetching a GPG key with
4
+ a shortcut and unsubscribing from mailinglist using an url). Several old
5
+ deprecated parts of sup have been modernized. Support for Ruby 1.9.3 has been
6
+ dropped. Have a look in History.txt for the details.
7
+
1
8
  Release 0.20.0:
2
9
 
3
10
  We've got man pages (Mr. Andersson)! We've got OpenBSD support (Scott Bonds)!
data/bin/sup CHANGED
@@ -7,6 +7,7 @@ require 'rubygems'
7
7
  require 'ncursesw'
8
8
 
9
9
  require 'sup/util/ncurses'
10
+ require 'sup/util/locale_fiddler'
10
11
 
11
12
  no_gpgme = false
12
13
  begin
@@ -102,32 +103,17 @@ global_keymap = Keymap.new do |k|
102
103
  end
103
104
  end
104
105
 
105
- ## the following magic enables wide characters when used with a ruby
106
- ## ncurses.so that's been compiled against libncursesw. (note the w.) why
107
- ## this works, i have no idea. much like pretty much every aspect of
108
- ## dealing with curses. cargo cult programming at its best.
109
106
  require 'rbconfig'
110
- unless RbConfig::CONFIG['arch'] =~ /openbsd/
111
- require 'dl/import'
112
- module LibC
113
- extend DL.const_defined?(:Importer) ? DL::Importer : DL::Importable
114
- setlocale_lib = case RbConfig::CONFIG['arch']
115
- when /darwin/; "libc.dylib"
116
- when /cygwin/; "cygwin1.dll"
117
- when /freebsd/; "libc.so.7"
118
- else; "libc.so.6"
119
- end
120
107
 
121
- debug "dynamically loading setlocale() from #{setlocale_lib}"
122
- begin
123
- dlload setlocale_lib
124
- extern "void setlocale(int, const char *)"
125
- debug "setting locale..."
126
- LibC.setlocale(6, "") # LC_ALL == 6
127
- rescue RuntimeError => e
128
- warn "cannot dlload setlocale(); ncurses wide character support probably broken."
129
- warn "dlload error was #{e.class}: #{e.message}"
130
- end
108
+ unless RbConfig::CONFIG['arch'] =~ /openbsd/
109
+ debug "dynamically loading setlocale()"
110
+ begin
111
+ class LibC; extend LocaleFiddler; end
112
+ debug "setting locale..."
113
+ LibC.setlocale(6, "")
114
+ rescue RuntimeError => e
115
+ warn "cannot dlload setlocale(); ncurses wide character support probably broken."
116
+ warn "dlload error was #{e.class}: #{e.message}"
131
117
  end
132
118
  end
133
119
 
@@ -60,7 +60,7 @@ $config[:sync_back_to_maildir] = true
60
60
 
61
61
  begin
62
62
  sync_performed = []
63
- sync_performed = File.readlines(Redwood::SYNC_OK_FN).collect { |e| e.strip }.find_all { |e| not e.empty? } if File.exists? Redwood::SYNC_OK_FN
63
+ sync_performed = File.readlines(Redwood::SYNC_OK_FN).collect { |e| e.strip }.find_all { |e| not e.empty? } if File.exist? Redwood::SYNC_OK_FN
64
64
  sources = []
65
65
 
66
66
  ## Try to find out sources given in parameters
@@ -0,0 +1,102 @@
1
+ # Sup Bash completion
2
+ #
3
+ # * Complete options for all Sup commands.
4
+ # * Disable completion for next option when current option takes an argument.
5
+ # * Complete sources, directories, and files, where applicable.
6
+
7
+ _sup_cmds() {
8
+ local cur prev opts sources
9
+ COMPREPLY=()
10
+ cur="${COMP_WORDS[COMP_CWORD]}"
11
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
12
+ sources="$(sed -n '/uri:/ {s/.*uri:\s*//p}' $HOME/.sup/sources.yaml)"
13
+
14
+ case "${1##/*}" in
15
+ sup-add)
16
+ opts="--archive -a --unusual -u --sync-back --no-sync-back -s
17
+ --labels -l --force-new -f --force-account -o --version -v
18
+ --help -h mbox: maildir:"
19
+
20
+ case $prev in
21
+ --labels|-l|--force-account|-o)
22
+ COMPREPLY=()
23
+ return 0
24
+ ;;
25
+ esac
26
+ ;;
27
+ sup-config|sup-dump)
28
+ opts="--version -v --help -h"
29
+ ;;
30
+ sup-import-dump)
31
+ opts="--verbose -v --ignore-missing -i --warn-missing -w
32
+ --abort-missing -a --atomic -t --dry-run -n --version --help
33
+ -h"
34
+ ;;
35
+ sup)
36
+ opts="--list-hooks -l --no-threads -n --no-initial-poll -o --search
37
+ -s --compose -c --subject -j --version -v --help -h"
38
+
39
+ case $prev in
40
+ --search|-s|--compose|-c|--subject|-j)
41
+ COMPREPLY=()
42
+ return 0
43
+ ;;
44
+ esac
45
+ ;;
46
+ sup-recover-sources)
47
+ opts="--unusual --archive --scan-num --help -h $sources"
48
+
49
+ case $prev in
50
+ --scan-num)
51
+ COMPREPLY=()
52
+ return 0
53
+ ;;
54
+ esac
55
+ ;;
56
+ sup-sync)
57
+ opts="--asis --restore --discard --archive -x --read -r
58
+ --extra-labels --verbose -v --optimize -o --all-sources
59
+ --dry-run -n --version --help -h ${sources}"
60
+
61
+
62
+ case $prev in
63
+ --restore|--extra-labels)
64
+ COMPREPLY=()
65
+ return 0
66
+ ;;
67
+ esac
68
+ ;;
69
+ sup-sync-back-maildir)
70
+ maildir_sources="$(echo $sources | tr ' ' '\n' | grep maildir)"
71
+ opts="--no-confirm -n --no-merge -m --list-sources -l
72
+ --unusual-sources-too -u --version -v --help -h
73
+ $maildir_sources"
74
+ ;;
75
+ sup-tweak-labels)
76
+ opts="--add -a --remove -r --query -q --verbose -v --very-verbose
77
+ -e --all-sources --dry-run -n --no-sync-back -o --version
78
+ --help -h $sources"
79
+
80
+ case $prev in
81
+ --add|-a|--remove|-r|--query|-q)
82
+ COMPREPLY=()
83
+ return 0
84
+ ;;
85
+ esac
86
+ ;;
87
+ esac
88
+
89
+ COMPREPLY=( $(compgen -W "$opts" -- ${cur}) )
90
+ return 0
91
+ }
92
+
93
+ complete -F _sup_cmds sup \
94
+ sup-add \
95
+ sup-config \
96
+ sup-dump \
97
+ sup-recover-sources \
98
+ sup-sync \
99
+ sup-sync-back-maildir \
100
+ sup-tweak-labels
101
+
102
+ complete -F _sup_cmds -o filenames -o plusdirs sup-import-dump
data/lib/sup.rb CHANGED
@@ -105,7 +105,7 @@ module Redwood
105
105
  o
106
106
  end
107
107
 
108
- mode = if File.exists? fn
108
+ mode = if File.exist? fn
109
109
  File.stat(fn).mode
110
110
  else
111
111
  0600
@@ -113,7 +113,7 @@ module Redwood
113
113
 
114
114
  if backup
115
115
  backup_fn = fn + '.bak'
116
- if File.exists?(fn) && File.size(fn) > 0
116
+ if File.exist?(fn) && File.size(fn) > 0
117
117
  File.open(backup_fn, "w", mode) do |f|
118
118
  File.open(fn, "r") { |old_f| FileUtils.copy_stream old_f, f }
119
119
  f.fsync
@@ -139,7 +139,7 @@ module Redwood
139
139
  end
140
140
 
141
141
  def load_yaml_obj fn, compress=false
142
- o = if File.exists? fn
142
+ o = if File.exist? fn
143
143
  if compress
144
144
  Zlib::GzipReader.open(fn) { |f| YAML::load f }
145
145
  else
@@ -180,7 +180,7 @@ module Redwood
180
180
  return if bypass_sync_check
181
181
 
182
182
  if $config[:sync_back_to_maildir]
183
- if not File.exists? Redwood::SYNC_OK_FN
183
+ if not File.exist? Redwood::SYNC_OK_FN
184
184
  Redwood.warn_syncback <<EOS
185
185
  It appears that the "sync_back_to_maildir" option has been changed
186
186
  from false to true since the last execution of sup.
@@ -191,14 +191,14 @@ Should I complain about this again? (Y/n)
191
191
  EOS
192
192
  File.open(Redwood::SYNC_OK_FN, 'w') {|f| f.write(Redwood::MAILDIR_SYNC_CHECK_SKIPPED) } if STDIN.gets.chomp.downcase == 'n'
193
193
  end
194
- elsif not $config[:sync_back_to_maildir] and File.exists? Redwood::SYNC_OK_FN
194
+ elsif not $config[:sync_back_to_maildir] and File.exist? Redwood::SYNC_OK_FN
195
195
  File.delete(Redwood::SYNC_OK_FN)
196
196
  end
197
197
  end
198
198
 
199
199
  def check_syncback_settings
200
200
  # don't check if syncback was never performed
201
- return unless File.exists? Redwood::SYNC_OK_FN
201
+ return unless File.exist? Redwood::SYNC_OK_FN
202
202
  active_sync_sources = File.readlines(Redwood::SYNC_OK_FN).collect { |e| e.strip }.find_all { |e| not e.empty? }
203
203
  return if active_sync_sources.length == 1 and active_sync_sources[0] == Redwood::MAILDIR_SYNC_CHECK_SKIPPED
204
204
  sources = SourceManager.sources
@@ -338,7 +338,7 @@ EOM
338
338
  :continuous_scroll => false,
339
339
  :always_edit_async => false,
340
340
  }
341
- if File.exists? filename
341
+ if File.exist? filename
342
342
  config = Redwood::load_yaml_obj filename
343
343
  abort "#{filename} is not a valid configuration file (it's a #{config.class}, not a hash)" unless config.is_a?(Hash)
344
344
  default_config.merge config
@@ -17,6 +17,9 @@ module Ncurses
17
17
 
18
18
  ## xterm 24-shade grayscale
19
19
  24.times { |x| color! "g#{x}", (16+6*6*6) + x }
20
+ elsif Ncurses::NUM_COLORS == -1
21
+ ## Terminal emulator doesn't appear to support colors
22
+ fail "sup must be run in a terminal with color support, please check your TERM variable."
20
23
  end
21
24
  end
22
25
 
@@ -186,13 +189,13 @@ class Colormap
186
189
  ## Try to use the user defined colors, in case of an error fall back
187
190
  ## to the default ones.
188
191
  def populate_colormap
189
- user_colors = if File.exists? Redwood::COLOR_FN
192
+ user_colors = if File.exist? Redwood::COLOR_FN
190
193
  debug "loading user colors from #{Redwood::COLOR_FN}"
191
194
  Redwood::load_yaml_obj Redwood::COLOR_FN
192
195
  end
193
196
 
194
197
  ## Set attachment sybmol to sane default for existing colorschemes
195
- if user_colors and user_colors.has_key? :to_me
198
+ if user_colors and user_colors.has_key? :to_me
196
199
  user_colors[:with_attachment] = user_colors[:to_me] unless user_colors.has_key? :with_attachment
197
200
  end
198
201
 
@@ -16,7 +16,7 @@ class ContactManager
16
16
  @a2p = {} # alias to person
17
17
  @e2p = {} # email to person
18
18
 
19
- if File.exists? fn
19
+ if File.exist? fn
20
20
  IO.foreach(fn) do |l|
21
21
  l =~ /^([^:]*): (.*)$/ or raise "can't parse #{fn} line #{l.inspect}"
22
22
  aalias, addr = $1, $2
@@ -29,11 +29,13 @@ class ContactManager
29
29
  def contacts_with_aliases; @a2p.values.uniq end
30
30
 
31
31
  def update_alias person, aalias=nil
32
+ ## Deleting old data if it exists
32
33
  old_aalias = @p2a[person]
33
- if(old_aalias != nil and old_aalias != "") # remove old alias
34
+ if old_aalias
34
35
  @a2p.delete old_aalias
35
36
  @e2p.delete person.email
36
37
  end
38
+ ## Update with new data
37
39
  @p2a[person] = aalias
38
40
  unless aalias.nil? || aalias.empty?
39
41
  @a2p[aalias] = person
@@ -16,6 +16,9 @@ class CryptoManager
16
16
  [:encrypt, "Encrypt only"]
17
17
  )
18
18
 
19
+ KEY_PATTERN = /(-----BEGIN PGP PUBLIC KEY BLOCK.*-----END PGP PUBLIC KEY BLOCK)/m
20
+ KEYSERVER_URL = "http://pool.sks-keyservers.net:11371/pks/lookup"
21
+
19
22
  HookManager.register "gpg-options", <<EOS
20
23
  Runs before gpg is called, allowing you to modify the options (most
21
24
  likely you would want to add something to certain commands, like
@@ -212,9 +215,10 @@ EOS
212
215
  unknown = false
213
216
  all_output_lines = []
214
217
  all_trusted = true
218
+ unknown_fingerprint = nil
215
219
 
216
220
  verify_result.signatures.each do |signature|
217
- output_lines, trusted = sig_output_lines signature
221
+ output_lines, trusted, unknown_fingerprint = sig_output_lines signature
218
222
  all_output_lines << output_lines
219
223
  all_output_lines.flatten!
220
224
  all_trusted &&= trusted
@@ -242,6 +246,8 @@ EOS
242
246
  end
243
247
  elsif !unknown
244
248
  Chunk::CryptoNotice.new(:invalid, summary_line, all_output_lines)
249
+ elsif unknown_fingerprint
250
+ Chunk::CryptoNotice.new(:unknown_key, "Unable to determine validity of cryptographic signature", all_output_lines, unknown_fingerprint)
245
251
  else
246
252
  unknown_status all_output_lines
247
253
  end
@@ -351,6 +357,31 @@ EOS
351
357
  [notice, sig, msg]
352
358
  end
353
359
 
360
+ def retrieve fingerprint
361
+ require 'net/http'
362
+ uri = URI($config[:keyserver_url] || KEYSERVER_URL)
363
+ unless uri.scheme == "http" and not uri.host.nil?
364
+ return "Invalid url: #{uri}"
365
+ end
366
+
367
+ fingerprint = "0x" + fingerprint unless fingerprint[0..1] == "0x"
368
+ params = {op: "get", search: fingerprint}
369
+ uri.query = URI.encode_www_form(params)
370
+
371
+ begin
372
+ res = Net::HTTP.get_response(uri)
373
+ rescue SocketError # Host doesn't exist or we couldn't connect
374
+ end
375
+ return "Couldn't get key from keyserver at this address: #{uri}" unless res.is_a?(Net::HTTPSuccess)
376
+
377
+ match = KEY_PATTERN.match(res.body)
378
+ return "No key found" unless match && match.length > 0
379
+
380
+ GPGME::Key.import(match[0])
381
+
382
+ return nil
383
+ end
384
+
354
385
  private
355
386
 
356
387
  def unknown_status lines=[]
@@ -394,6 +425,7 @@ private
394
425
  rescue EOFError
395
426
  from_key = nil
396
427
  first_sig = "No public key available for #{signature.fingerprint}"
428
+ unknown_fpr = signature.fingerprint
397
429
  end
398
430
 
399
431
  time_line = "Signature made " + signature.timestamp.strftime("%a %d %b %Y %H:%M:%S %Z") +
@@ -422,7 +454,7 @@ private
422
454
  output_lines << HookManager.run("sig-output",
423
455
  {:signature => signature, :from_key => from_key})
424
456
  end
425
- return output_lines, trusted
457
+ return output_lines, trusted, unknown_fpr
426
458
  end
427
459
 
428
460
  def key_type key, fpr