mail-gpg 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5372354dbe32dbf5c05196f257b8172582e5ffcc
4
- data.tar.gz: 983703ee19cac1078e36c37bfde1b13906fd0ffa
3
+ metadata.gz: 0fa28ac570f95bf31e58025d3e29c4d8fe15c43a
4
+ data.tar.gz: 3a4afd5b7c7847333c364135aba9acb20fc9762d
5
5
  SHA512:
6
- metadata.gz: aeb9b25b2c04e4c0a71b1eea09631e399a82dbcef6b707b75a4053bca637e66dbdd1d3eabf88673c16a75b8ffd623fabdbdc1e9fe906c10b0ceee4debe452c75
7
- data.tar.gz: 241a812c8341db86deae1bf48927e5a1c5e92491c505ab67706a9c3e83768c341207dc4d00dcc434d4fbff29252c6625ea5a55110a91a9d033bfb2a534701de6
6
+ metadata.gz: d96da3558cb0b0ed814dce389d0e969e19edf718712adcecc0dc5bad04c6d1a35ed8da20acbf9427212072daf1c462e48a9391d5fc0c6d5b63c4e6a9e3593052
7
+ data.tar.gz: 3a8e23f13198857aa5fe9f533a08d7209d55ee0ba9839d913b977fbea59841315c211c1f87f3440e0c7a1d3a239419ed84dcb0b593efa6590aa85aadfce129cd
@@ -1,3 +1,11 @@
1
+ == 0.3.2 2018-03-30
2
+
3
+ * do not attempt to decrypt inline-encrypted HTML parts #52
4
+ * fixes possible double decoding of quoted printable bodies #57
5
+ * fixes a bug which occured in some environments that led to encryption with
6
+ all available public keys (#31, #55)
7
+
8
+
1
9
  == 0.3.1 2017-04-13
2
10
 
3
11
  * fixes a bug with signature verification that only surfaced in environments
data/README.md CHANGED
@@ -14,7 +14,9 @@ wild as described in this [Know your PGP implementation](http://binblog.info/200
14
14
 
15
15
  Add this line to your application's Gemfile:
16
16
 
17
- gem 'mail-gpg'
17
+ ```ruby
18
+ gem 'mail-gpg'
19
+ ```
18
20
 
19
21
  And then execute:
20
22
 
@@ -31,48 +33,51 @@ Or install it yourself as:
31
33
  Construct your Mail object as usual and specify you want it to be encrypted
32
34
  with the gpg method:
33
35
 
34
- Mail.new do
35
- to 'jane@doe.net'
36
- from 'john@doe.net'
37
- subject 'gpg test'
38
- body "encrypt me!"
39
- add_file "some_attachment.zip"
40
-
41
- # encrypt message, no signing
42
- gpg encrypt: true
36
+ ```ruby
37
+ Mail.new do
38
+ to 'jane@doe.net'
39
+ from 'john@doe.net'
40
+ subject 'gpg test'
41
+ body "encrypt me!"
42
+ add_file "some_attachment.zip"
43
43
 
44
- # encrypt and sign message with sender's private key, using the given
45
- # passphrase to decrypt the key
46
- gpg encrypt: true, sign: true, password: 'secret'
44
+ # encrypt message, no signing
45
+ gpg encrypt: true
47
46
 
48
- # encrypt and sign message using a different key
49
- gpg encrypt: true, sign_as: 'joe@otherdomain.com', password: 'secret'
47
+ # encrypt and sign message with sender's private key, using the given
48
+ # passphrase to decrypt the key
49
+ gpg encrypt: true, sign: true, password: 'secret'
50
50
 
51
+ # encrypt and sign message using a different key
52
+ gpg encrypt: true, sign_as: 'joe@otherdomain.com', password: 'secret'
51
53
 
52
- # encrypt and sign message and use a callback function to provide the
53
- # passphrase.
54
- gpg encrypt: true, sign_as: 'joe@otherdomain.com',
55
- passphrase_callback: ->(obj, uid_hint, passphrase_info, prev_was_bad, fd){puts "Enter passphrase for #{passphrase_info}: "; (IO.for_fd(fd, 'w') << readline.chomp).flush }
56
- end.deliver
57
54
 
55
+ # encrypt and sign message and use a callback function to provide the
56
+ # passphrase.
57
+ gpg encrypt: true, sign_as: 'joe@otherdomain.com',
58
+ passphrase_callback: ->(obj, uid_hint, passphrase_info, prev_was_bad, fd){puts "Enter passphrase for #{passphrase_info}: "; (IO.for_fd(fd, 'w') << readline.chomp).flush }
59
+ end.deliver
60
+ ```
58
61
 
59
62
  Make sure all recipients' public keys are present in your local gpg keychain.
60
63
  You will get errors in case encryption is not possible due to missing keys.
61
64
  If you collect public key data from your users, you can specify the ascii
62
65
  armored key data for recipients using the `:keys` option like this:
63
66
 
64
- johns_key = <<-END
65
- -----BEGIN PGP PUBLIC KEY BLOCK-----
66
- Version: GnuPG v1.4.12 (GNU/Linux)
67
+ ```ruby
68
+ johns_key = <<-END
69
+ -----BEGIN PGP PUBLIC KEY BLOCK-----
70
+ Version: GnuPG v1.4.12 (GNU/Linux)
67
71
 
68
- mQGiBEk39msRBADw1ExmrLD1OUMdfvA7cnVVYTC7CyqfNvHUVuuBDhV7azs
69
- ....
70
- END
72
+ mQGiBEk39msRBADw1ExmrLD1OUMdfvA7cnVVYTC7CyqfNvHUVuuBDhV7azs
73
+ ....
74
+ END
71
75
 
72
- Mail.new do
73
- to 'john@foo.bar'
74
- gpg encrypt: true, keys: { 'john@foo.bar' => johns_key }
75
- end
76
+ Mail.new do
77
+ to 'john@foo.bar'
78
+ gpg encrypt: true, keys: { 'john@foo.bar' => johns_key }
79
+ end
80
+ ```
76
81
 
77
82
  The key will then be imported before actually trying to encrypt/send the mail.
78
83
  In theory you only need to specify the key once like that, however doing it
@@ -101,16 +106,18 @@ Set the `:verify` option to `true` when calling `decrypt` to decrypt *and* verif
101
106
  A `GPGME::Error::BadPassphrase` will be raised if the password for the private key is incorrect.
102
107
  A `EncodingError` will be raised if the encrypted mails is not encoded correctly as a [RFC 3156](http://www.ietf.org/rfc/rfc3156.txt) message.
103
108
 
109
+ Please note that in case of a multipart/alternative-message where both parts are inline-encrypted, the HTML-part will be dropped during decryption. Handling the HTML-part would require parsing HTML and guessing about the decrypted contents, which is brittle and out of the scope of this library. If you need the HTML-part of multipart/alternative-messages, use pgp/mime-encryption.
104
110
 
105
111
  ### Signing only
106
112
 
107
113
  Just leave the `:encrypt` option out or pass `encrypt: false`, i.e.
108
114
 
109
-
110
- Mail.new do
111
- to 'jane@doe.net'
112
- gpg sign: true
113
- end.deliver
115
+ ```ruby
116
+ Mail.new do
117
+ to 'jane@doe.net'
118
+ gpg sign: true
119
+ end.deliver
120
+ ```
114
121
 
115
122
  ### Verify signature(s)
116
123
 
@@ -147,14 +154,14 @@ signature with the key id of the expected sender.
147
154
  The Hkp class can be used to lookup and import public keys from public key servers.
148
155
  You can specify the keyserver url when initializing the class:
149
156
 
150
- ```
157
+ ```ruby
151
158
  hkp = Hkp.new("hkp://my-key-server.de")
152
159
  ```
153
160
 
154
161
  Or, if you want to override how ssl certificates should be treated in case of
155
162
  TLS-secured keyservers (the default is `VERIFY_PEER`):
156
163
 
157
- ```
164
+ ```ruby
158
165
  hkp = Hkp.new(keyserver: "hkps://another.key-server.com",
159
166
  ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE)
160
167
  ```
@@ -170,13 +177,13 @@ parsing the `gpg.conf` file). As a last resort, the server-pool at
170
177
 
171
178
  Lookup key ids by searching the keyserver for an email address
172
179
 
173
- ```
180
+ ```ruby
174
181
  hkp.search('jane@doe.net')
175
182
  ```
176
183
 
177
184
  You can lookup (and import) a specific key by its id:
178
185
 
179
- ```
186
+ ```ruby
180
187
  key = hkp.fetch(id)
181
188
  GPGME::Key.import(key)
182
189
 
@@ -186,12 +193,14 @@ hkp.fetch_and_import(id)
186
193
 
187
194
  ## Rails / ActionMailer integration
188
195
 
189
- class MyMailer < ActionMailer::Base
190
- default from: 'baz@bar.com'
191
- def some_mail
192
- mail to: 'foo@bar.com', subject: 'subject!', gpg: { encrypt: true }
193
- end
194
- end
196
+ ```ruby
197
+ class MyMailer < ActionMailer::Base
198
+ default from: 'baz@bar.com'
199
+ def some_mail
200
+ mail to: 'foo@bar.com', subject: 'subject!', gpg: { encrypt: true }
201
+ end
202
+ end
203
+ ```
195
204
 
196
205
  The gpg option takes the same arguments as outlined above for the
197
206
  Mail::Message#gpg method.
@@ -228,7 +237,6 @@ Open3.popen3(gppbin, '--preset', fpr) do |stdin, stdout, stderr|
228
237
  end
229
238
  # Hook to kill our gpg-agent when script finishes.
230
239
  Signal.trap(0, proc { Process.kill('TERM', ENV['GPG_AGENT_INFO'].split(':')[1]) })
231
-
232
240
  ```
233
241
 
234
242
 
@@ -23,7 +23,7 @@ module Mail
23
23
  GPGME::Ctx.new(options) do |ctx|
24
24
  begin
25
25
  if options[:sign]
26
- if options[:signers]
26
+ if options[:signers] && options[:signers].size > 0
27
27
  signers = GPGME::Key.find(:secret, options[:signers], :sign)
28
28
  ctx.add_signer(*signers)
29
29
  end
@@ -122,12 +122,19 @@ module Mail
122
122
  k = key_data[r]
123
123
  if k and k =~ /-----BEGIN PGP/
124
124
  k = GPGME::Key.import(k).imports.map(&:fpr)
125
+ k = nil if k.size == 0
126
+ end
127
+ key_id = k || r
128
+ unless key_id.nil? || key_id.empty?
129
+ GPGME::Key.find(:public, key_id, :encrypt)
125
130
  end
126
- GPGME::Key.find(:public, k || r, :encrypt)
127
131
  end.flatten
128
- else
132
+ elsif emails_or_shas_or_keys.size > 0
129
133
  # key lookup in keychain for all receivers
130
134
  GPGME::Key.find :public, emails_or_shas_or_keys, :encrypt
135
+ else
136
+ # empty array given
137
+ []
131
138
  end
132
139
  end
133
140
  end
@@ -16,6 +16,28 @@ module Mail
16
16
  if cipher_mail.multipart?
17
17
  self.new do
18
18
  Mail::Gpg.copy_headers cipher_mail, self
19
+
20
+ # Drop the HTML-part of a multipart/alternative-message if it is
21
+ # inline-encrypted: that ciphertext is probably wrapped in HTML,
22
+ # which GnuPG chokes upon, so we would have to parse the HTML to
23
+ # handle the message-part properly.
24
+ # Also it's not clear how to handle the resulting plain-text: is
25
+ # it HTML or simple text? That depends on the sending MUA and
26
+ # the original input.
27
+ # In summary, that's too much complications.
28
+ if cipher_mail.mime_type == 'multipart/alternative' &&
29
+ cipher_mail.html_part.present? &&
30
+ cipher_mail.html_part.body.decoded.include?('-----BEGIN PGP MESSAGE-----')
31
+ cipher_mail.parts.delete_if do |part|
32
+ part[:content_type].content_type == 'text/html'
33
+ end
34
+ # Set the content-type of the newly generated message to
35
+ # something less confusing.
36
+ content_type 'multipart/mixed'
37
+ # Leave a marker for other code.
38
+ header['X-MailGpg-Deleted-Html-Part'] = 'true'
39
+ end
40
+
19
41
  cipher_mail.parts.each do |part|
20
42
  p = VerifiedPart.new do |p|
21
43
  if part.has_content_type? && /application\/(?:octet-stream|pgp-encrypted)/ =~ part.mime_type
@@ -18,7 +18,7 @@ module Mail
18
18
  if content_part.multipart?
19
19
  content_part.parts.each{|part| add_part part}
20
20
  else
21
- body content_part.body.to_s
21
+ body content_part.body.raw_source
22
22
  end
23
23
  end
24
24
  end
@@ -26,5 +26,3 @@ module Mail
26
26
  end
27
27
  end
28
28
 
29
-
30
-
@@ -25,7 +25,7 @@ module Mail
25
25
  end
26
26
 
27
27
  # Work around the problem that plain_part.raw_source prefixes an
28
- # erronous CRLF, <https://github.com/mikel/mail/issues/702>.
28
+ # erroneous CRLF, <https://github.com/mikel/mail/issues/702>.
29
29
  if ! plain_part.raw_source.empty?
30
30
  plaintext = [ plain_part.header.raw_source,
31
31
  "\r\n\r\n",
@@ -1,5 +1,5 @@
1
1
  module Mail
2
2
  module Gpg
3
- VERSION = "0.3.1"
3
+ VERSION = "0.3.2"
4
4
  end
5
5
  end
@@ -33,6 +33,25 @@ class InlineDecryptedMessageTest < Test::Unit::TestCase
33
33
  end
34
34
  end
35
35
 
36
+ context "multipart/alternative message" do
37
+ should "have dropped HTML-part" do
38
+ mail = Mail.new(@mail)
39
+ mail.body = InlineDecryptedMessageTest.encrypt(mail, mail.body.to_s)
40
+ mail.html_part do |p|
41
+ p.body "<pre>#{InlineDecryptedMessageTest.encrypt(mail, mail.body.to_s)}</pre>"
42
+ end
43
+
44
+ assert mail.multipart?
45
+ assert mail.encrypted?
46
+ assert decrypted = mail.decrypt(:password => 'abc', verify: true)
47
+ assert !decrypted.encrypted?
48
+ assert decrypted.mime_type == 'multipart/mixed'
49
+ assert decrypted.parts.size == 1
50
+ assert decrypted.parts.first.mime_type == 'text/plain'
51
+ assert decrypted.header['X-MailGpg-Deleted-Html-Part'].value == 'true'
52
+ end
53
+ end
54
+
36
55
  context "attachment message" do
37
56
  should "decrypt attachment" do
38
57
  rakefile = File.open('Rakefile') { |file| file.read }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mail-gpg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Kraemer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-13 00:00:00.000000000 Z
11
+ date: 2018-03-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mail