mail-gpg 0.1.3 → 0.1.4

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.
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  .ruby-version
2
+ .ruby-gemset
2
3
  *.gem
3
4
  *.rbc
4
5
  .bundle
@@ -17,3 +18,5 @@ test/tmp
17
18
  test/version_tmp
18
19
  test/gpghome/random_seed
19
20
  tmp
21
+ *.swp
22
+ tags
@@ -1,7 +1,8 @@
1
1
  language: ruby
2
2
  rvm:
3
+ - 2.1.1
3
4
  - 2.0.0
4
5
  - 1.9.3
5
- gemfile:
6
- - gemfiles/rails3.gemfile
7
- - gemfiles/rails4.gemfile
6
+ env:
7
+ - RAILS=3.2.14
8
+ - RAILS=4.0.0
data/Gemfile CHANGED
@@ -2,3 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in mail-gpg.gemspec
4
4
  gemspec
5
+
6
+ if ENV['RAILS']
7
+ gem 'actionmailer', "~> #{ENV['RAILS']}"
8
+ gem 'shoulda-context', '~> 1.1.5'
9
+ end
@@ -1,3 +1,8 @@
1
+ == 0.1.4 2014-05-26
2
+
3
+ * preserve return path headers and message id
4
+ * fix signature verification
5
+
1
6
  == 0.1.3 2014-02-17
2
7
 
3
8
  * Signature checking implemented, thanks to Morten Andersen
@@ -99,7 +99,7 @@ module Mail
99
99
  def self.construct_mail(cleartext_mail, options, &block)
100
100
  Mail.new do
101
101
  self.perform_deliveries = cleartext_mail.perform_deliveries
102
- %w(from to cc bcc subject reply_to in_reply_to).each do |field|
102
+ %w(from to cc bcc subject reply_to in_reply_to return_path message_id).each do |field|
103
103
  send field, cleartext_mail.send(field)
104
104
  end
105
105
  cleartext_mail.header.fields.each do |field|
@@ -12,12 +12,25 @@ module Mail
12
12
  end
13
13
  end
14
14
 
15
- def self.signature_valid?(plain, signature, options = {})
16
- if !(signature.has_content_type? && ('application/pgp-signature' == signature.mime_type))
15
+ def self.signature_valid?(plain_part, signature_part, options = {})
16
+ if !(signature_part.has_content_type? &&
17
+ ('application/pgp-signature' == signature_part.mime_type))
17
18
  return false
18
19
  end
19
20
 
20
- GpgmeHelper.sign_verify(plain.encoded, signature.body.encoded, options)
21
+ # Work around the problem that plain_part.raw_source prefixes an
22
+ # erronous CRLF, <https://github.com/mikel/mail/issues/702>.
23
+ if ! plain_part.raw_source.empty?
24
+ plaintext = [ plain_part.header.raw_source,
25
+ "\r\n\r\n",
26
+ plain_part.body.raw_source
27
+ ].join
28
+ else
29
+ plaintext = plain_part.encoded
30
+ end
31
+
32
+ signature = signature_part.body.encoded
33
+ GpgmeHelper.sign_verify(plaintext, signature, options)
21
34
  end
22
35
  end
23
36
  end
@@ -1,5 +1,5 @@
1
1
  module Mail
2
2
  module Gpg
3
- VERSION = "0.1.3"
3
+ VERSION = "0.1.4"
4
4
  end
5
5
  end
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.add_dependency "mail", "~> 2.5.3"
22
22
  spec.add_dependency "gpgme", "~> 2.0.2"
23
23
  spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "minitest", "~> 4.0"
24
25
  spec.add_development_dependency "rake"
25
26
  spec.add_development_dependency "actionmailer", ">= 3.2.0"
26
27
  spec.add_development_dependency "pry-nav"
@@ -3,68 +3,122 @@ require 'test_helper'
3
3
  class MyMailer < ActionMailer::Base
4
4
  default from: 'joe@foo.bar', to: 'jane@foo.bar'
5
5
 
6
- def unencrypted
7
- mail subject: 'unencrypted', body: 'unencrypted mail'
6
+ def unencrypted(bouncy=false)
7
+ mail subject: 'unencrypted', body: 'unencrypted mail', return_path: (bouncy && bounce_address)
8
8
  end
9
9
 
10
- def encrypted
11
- mail subject: 'encrypted', body: 'encrypted mail', gpg: {encrypt: true}
10
+ def encrypted(bouncy=false)
11
+ mail subject: 'encrypted', body: 'encrypted mail', return_path: (bouncy && bounce_address), gpg: {encrypt: true}
12
12
  end
13
13
 
14
- def signed
15
- mail from: 'jane@foo.bar',
16
- to: 'joe@foo.bar',
17
- subject: 'signed',
18
- body: 'signed mail',
19
- gpg: {
20
- sign: true,
21
- password: 'abc'
22
- }
23
- end
14
+ def signed(bouncy=false)
15
+ mail from: 'jane@foo.bar',
16
+ to: 'joe@foo.bar',
17
+ subject: 'signed',
18
+ body: 'signed mail',
19
+ return_path: (bouncy && bounce_address),
20
+ gpg: {
21
+ sign: true,
22
+ password: 'abc'
23
+ }
24
+ end
25
+
26
+ private
27
+
28
+ def bounce_address
29
+ SecureRandom.uuid + "@bounces.example.com"
30
+ end
24
31
 
25
32
  end
26
33
 
27
34
  class ActionMailerTest < Test::Unit::TestCase
28
- context "with action mailer" do
35
+ context 'without return_path' do
29
36
  setup do
30
37
  (@emails = ActionMailer::Base.deliveries).clear
31
38
  end
32
39
 
33
- should "send unencrypted mail" do
34
- MyMailer.unencrypted.deliver
35
- assert_equal 1, @emails.size
36
- assert m = @emails.first
37
- assert_equal 'unencrypted', m.subject
38
- end
40
+ context "with action mailer" do
41
+ should "send unencrypted mail" do
42
+ MyMailer.unencrypted.deliver
43
+ assert_equal 1, @emails.size
44
+ assert m = @emails.first
45
+ assert_equal 'unencrypted', m.subject
46
+ end
47
+
39
48
 
49
+ should "send encrypted mail" do
50
+ assert m = MyMailer.encrypted
51
+ assert true == m.gpg[:encrypt]
52
+ m.deliver
53
+ assert_equal 1, @emails.size
54
+ assert m = @emails.first
55
+ assert_equal 'encrypted', m.subject
56
+ assert_equal 2, m.parts.size
57
+ assert encrypted = m.parts.detect{|p| p.content_type =~ /encrypted\.asc/}
58
+ assert clear = GPGME::Crypto.new.decrypt(encrypted.body.to_s, password: 'abc')
59
+ m = Mail.new clear
60
+ assert_equal 'encrypted mail', m.body.to_s
61
+ end
40
62
 
41
- should "send encrypted mail" do
42
- assert m = MyMailer.encrypted
43
- assert true == m.gpg[:encrypt]
44
- m.deliver
45
- assert_equal 1, @emails.size
46
- assert m = @emails.first
47
- assert_equal 'encrypted', m.subject
48
- assert_equal 2, m.parts.size
49
- assert encrypted = m.parts.detect{|p| p.content_type =~ /encrypted\.asc/}
50
- assert clear = GPGME::Crypto.new.decrypt(encrypted.body.to_s, password: 'abc')
51
- m = Mail.new clear
52
- assert_equal 'encrypted mail', m.body.to_s
63
+ should "send signed mail" do
64
+ assert m = MyMailer.signed
65
+ assert true == m.gpg[:sign]
66
+ m.deliver
67
+ assert_equal 1, @emails.size
68
+ assert delivered = @emails.first
69
+ assert_equal 'signed', delivered.subject
70
+ assert_equal 2, delivered.parts.size
71
+ assert sign_part = delivered.parts.detect{|p| p.content_type =~ /signature\.asc/}
72
+ GPGME::Crypto.new.verify(sign_part.body.to_s, signed_text: m.encoded) do |sig|
73
+ assert true == sig.valid?
74
+ end
75
+ end
53
76
  end
77
+ end
54
78
 
55
- should "send signed mail" do
56
- assert m = MyMailer.signed
57
- assert true == m.gpg[:sign]
58
- m.deliver
59
- assert_equal 1, @emails.size
60
- assert delivered = @emails.first
61
- assert_equal 'signed', delivered.subject
62
- assert_equal 2, delivered.parts.size
63
- assert sign_part = delivered.parts.detect{|p| p.content_type =~ /signature\.asc/}
64
- GPGME::Crypto.new.verify(sign_part.body.to_s, signed_text: m.encoded) do |sig|
65
- assert true == sig.valid?
66
- end
67
- end
79
+ context 'with return_path' do
80
+ setup do
81
+ (@emails = ActionMailer::Base.deliveries).clear
82
+ end
68
83
 
84
+ context "with action mailer" do
85
+ should "send unencrypted mail" do
86
+ MyMailer.unencrypted(true).deliver
87
+ assert_equal 1, @emails.size
88
+ assert m = @emails.first
89
+ assert_match /@bounces\.example\.com\z/, m.return_path
90
+ assert_equal 'unencrypted', m.subject
91
+ end
92
+
93
+ should "send encrypted mail" do
94
+ assert m = MyMailer.encrypted(true)
95
+ assert true == m.gpg[:encrypt]
96
+ m.deliver
97
+ assert_equal 1, @emails.size
98
+ assert m = @emails.first
99
+ assert_match /@bounces\.example\.com\z/, m.return_path
100
+ assert_equal 'encrypted', m.subject
101
+ assert_equal 2, m.parts.size
102
+ assert encrypted = m.parts.detect{|p| p.content_type =~ /encrypted\.asc/}
103
+ assert clear = GPGME::Crypto.new.decrypt(encrypted.body.to_s, password: 'abc')
104
+ m = Mail.new clear
105
+ assert_equal 'encrypted mail', m.body.to_s
106
+ end
107
+
108
+ should "send signed mail" do
109
+ assert m = MyMailer.signed(true)
110
+ assert true == m.gpg[:sign]
111
+ m.deliver
112
+ assert_equal 1, @emails.size
113
+ assert delivered = @emails.first
114
+ assert_match /@bounces\.example\.com\z/, delivered.return_path
115
+ assert_equal 'signed', delivered.subject
116
+ assert_equal 2, delivered.parts.size
117
+ assert sign_part = delivered.parts.detect{|p| p.content_type =~ /signature\.asc/}
118
+ GPGME::Crypto.new.verify(sign_part.body.to_s, signed_text: m.encoded) do |sig|
119
+ assert true == sig.valid?
120
+ end
121
+ end
122
+ end
69
123
  end
70
124
  end
@@ -20,7 +20,6 @@ class GpgTest < Test::Unit::TestCase
20
20
  enc_part.content_type
21
21
  end
22
22
 
23
-
24
23
  def check_content(mail = @mail, encrypted = @encrypted)
25
24
  assert enc = encrypted.parts.last
26
25
  assert clear = GPGME::Crypto.new.decrypt(enc.to_s, password: 'abc').to_s
@@ -50,6 +49,7 @@ class GpgTest < Test::Unit::TestCase
50
49
  assert_equal mail.cc, signed.cc
51
50
  assert_equal mail.bcc, signed.bcc
52
51
  assert_equal mail.subject, signed.subject
52
+ assert_equal mail.return_path, signed.return_path
53
53
  end
54
54
 
55
55
  context "gpg installation" do
@@ -97,6 +97,7 @@ class GpgTest < Test::Unit::TestCase
97
97
  context 'mail with custom header' do
98
98
  setup do
99
99
  @mail.header['X-Custom-Header'] = 'custom value'
100
+ @mail.header['Return-Path'] = 'bounces@example.com'
100
101
  @signed = Mail::Gpg.sign(@mail, password: 'abc')
101
102
  end
102
103
 
@@ -114,6 +115,7 @@ class GpgTest < Test::Unit::TestCase
114
115
 
115
116
  should 'preserve customer header values' do
116
117
  assert_equal 'custom value', @signed.header['X-Custom-Header'].to_s
118
+ assert_equal 'bounces@example.com', @signed.return_path
117
119
  end
118
120
  end
119
121
 
@@ -224,6 +226,7 @@ class GpgTest < Test::Unit::TestCase
224
226
  context 'mail with custom header' do
225
227
  setup do
226
228
  @mail.header['X-Custom-Header'] = 'custom value'
229
+ @mail.header['Return-Path'] = 'bounces@example.com'
227
230
  @encrypted = Mail::Gpg.encrypt(@mail)
228
231
  @encrypted.header['X-Another-Header'] = 'another value'
229
232
  end
@@ -242,6 +245,7 @@ class GpgTest < Test::Unit::TestCase
242
245
 
243
246
  should 'preserve customer header values' do
244
247
  assert_equal 'custom value', @encrypted.header['X-Custom-Header'].to_s
248
+ assert_equal 'bounces@example.com', @encrypted.return_path
245
249
  end
246
250
 
247
251
  context 'when decrypted' do
@@ -2,19 +2,19 @@ require 'test_helper'
2
2
  require 'mail/gpg/sign_part'
3
3
 
4
4
  class SignPartTest < Test::Unit::TestCase
5
- context 'SignPart' do
6
- setup do
7
- @mail = Mail.new do
8
- to 'jane@foo.bar'
9
- from 'joe@foo.bar'
10
- subject 'test'
11
- body 'i am unsigned'
12
- end
13
- end
5
+ context 'SignPart' do
6
+ setup do
7
+ @mail = Mail.new do
8
+ to 'jane@foo.bar'
9
+ from 'joe@foo.bar'
10
+ subject 'test'
11
+ body 'i am unsigned'
12
+ end
13
+ end
14
14
 
15
- should 'roundtrip successfully' do
16
- signature_part = Mail::Gpg::SignPart.new(@mail, password: 'abc')
17
- assert Mail::Gpg::SignPart.signature_valid?(@mail, signature_part)
18
- end
19
- end
15
+ should 'roundtrip successfully' do
16
+ signature_part = Mail::Gpg::SignPart.new(@mail, password: 'abc')
17
+ assert Mail::Gpg::SignPart.signature_valid?(@mail, signature_part)
18
+ end
19
+ end
20
20
  end
@@ -2,6 +2,7 @@ require 'test/unit'
2
2
  require 'shoulda/context'
3
3
  require 'mail-gpg'
4
4
  require 'action_mailer'
5
+ require 'securerandom'
5
6
 
6
7
  begin
7
8
  require 'pry-nav'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail-gpg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-02-17 00:00:00.000000000 Z
12
+ date: 2014-05-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: mail
@@ -59,6 +59,22 @@ dependencies:
59
59
  - - ~>
60
60
  - !ruby/object:Gem::Version
61
61
  version: '1.3'
62
+ - !ruby/object:Gem::Dependency
63
+ name: minitest
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: '4.0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: '4.0'
62
78
  - !ruby/object:Gem::Dependency
63
79
  name: rake
64
80
  requirement: !ruby/object:Gem::Requirement
@@ -140,8 +156,6 @@ files:
140
156
  - LICENSE.txt
141
157
  - README.md
142
158
  - Rakefile
143
- - gemfiles/rails3.gemfile
144
- - gemfiles/rails4.gemfile
145
159
  - lib/hkp.rb
146
160
  - lib/mail-gpg.rb
147
161
  - lib/mail/gpg.rb
@@ -193,7 +207,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
193
207
  version: '0'
194
208
  requirements: []
195
209
  rubyforge_project:
196
- rubygems_version: 1.8.23
210
+ rubygems_version: 1.8.23.2
197
211
  signing_key:
198
212
  specification_version: 3
199
213
  summary: GPG/MIME encryption plugin for the Ruby Mail Library
@@ -1,10 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rake'
4
-
5
- gem 'mail', '~> 2.5.3'
6
- gem 'gpgme', '~> 2.0.2'
7
- gem 'actionmailer', '~> 3.2.14'
8
-
9
- gem 'shoulda-context', '~> 1.1.5'
10
-
@@ -1,11 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rake'
4
-
5
- gem 'mail', '~> 2.5.3'
6
- gem 'gpgme', '~> 2.0.2'
7
- gem 'actionmailer', '~> 4.0.0'
8
-
9
- gem 'shoulda-context', '~> 1.1.5'
10
-
11
-