mail-gpg 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
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
-