iostreams 0.12.0 → 0.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/io_streams/pgp.rb +49 -25
- data/lib/io_streams/version.rb +1 -1
- data/test/pgp_test.rb +7 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0d18dafc30b8314925e4bc352ff146bcf39ec0c6
|
4
|
+
data.tar.gz: 8fc00eda8c6a850f5e8abe6386718a483b04884c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d0c13bb7daa4480884ce323b229a0018ec37ded48aad8ad2c10502a085e14970d354de06306898fd989225b6aaaf3a2fc0fdee563c7bb3a7e7bf84413ab74ce
|
7
|
+
data.tar.gz: 7b70b19a019542d1c400d7ef1e99622acc73342a07444402f7326c341496b6a92e5985e807dd811004135b5f30c806aaf9ccdbaadf80394a14a764e6fadfd862
|
data/lib/io_streams/pgp.rb
CHANGED
@@ -26,7 +26,7 @@ module IOStreams
|
|
26
26
|
# # Recipient must also have the senders public key to verify the signature
|
27
27
|
# IOStreams::Pgp::Reader.open('secure.gpg', passphrase: 'receiver_passphrase') do |stream|
|
28
28
|
# while !stream.eof?
|
29
|
-
#
|
29
|
+
# p stream.read(10)
|
30
30
|
# puts
|
31
31
|
# end
|
32
32
|
# end
|
@@ -52,7 +52,7 @@ module IOStreams
|
|
52
52
|
# # Recipient must also have the senders public key to verify the signature
|
53
53
|
# IOStreams.reader('secure.gpg') do |stream|
|
54
54
|
# while data = stream.read(10)
|
55
|
-
#
|
55
|
+
# p data
|
56
56
|
# end
|
57
57
|
# end
|
58
58
|
#
|
@@ -77,6 +77,10 @@ module IOStreams
|
|
77
77
|
# :zip: size: 411MB write: 75s read: 31s
|
78
78
|
# :zlib: size: 241MB write: 66s read: 23s ( 756KB Memory )
|
79
79
|
# :bzip2: size: 129MB write: 430s read: 130s ( 5MB Memory )
|
80
|
+
#
|
81
|
+
# Notes:
|
82
|
+
# - Tested against gnupg v1.4.21 and v2.0.30
|
83
|
+
# - Does not work yet with gnupg v2.1. Pull Requests welcome.
|
80
84
|
module Pgp
|
81
85
|
autoload :Reader, 'io_streams/pgp/reader'
|
82
86
|
autoload :Writer, 'io_streams/pgp/writer'
|
@@ -87,6 +91,16 @@ module IOStreams
|
|
87
91
|
class UnsupportedVersion < Failure
|
88
92
|
end
|
89
93
|
|
94
|
+
def self.executable
|
95
|
+
@executable
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.executable=(executable)
|
99
|
+
@executable = executable
|
100
|
+
end
|
101
|
+
|
102
|
+
@executable = 'gpg'
|
103
|
+
|
90
104
|
# Generate a new ultimate trusted local public and private key.
|
91
105
|
#
|
92
106
|
# Returns [String] the key id for the generated key.
|
@@ -121,7 +135,7 @@ module IOStreams
|
|
121
135
|
params << "Expire-Date: #{expire_date}\n" if expire_date
|
122
136
|
params << "Passphrase: #{passphrase}\n" if passphrase
|
123
137
|
params << '%commit'
|
124
|
-
out, err, status = Open3.capture3(
|
138
|
+
out, err, status = Open3.capture3("#{executable} --batch --gen-key", binmode: true, stdin_data: params)
|
125
139
|
logger.debug { "IOStreams::Pgp.generate_key output:\n#{out}#{err}" } if logger
|
126
140
|
if status.success?
|
127
141
|
if match = err.match(/gpg: key ([0-9A-F]+)\s+/)
|
@@ -149,8 +163,8 @@ module IOStreams
|
|
149
163
|
def self.delete_keys(email:, public: true, private: false)
|
150
164
|
version_check
|
151
165
|
cmd = "for i in `gpg --with-colons --fingerprint #{email} | grep \"^fpr\" | cut -d: -f10`; do\n"
|
152
|
-
cmd << "
|
153
|
-
cmd << "
|
166
|
+
cmd << "#{executable} --batch --delete-secret-keys \"$i\" ;\n" if private
|
167
|
+
cmd << "#{executable} --batch --delete-keys \"$i\" ;\n" if public
|
154
168
|
cmd << 'done'
|
155
169
|
|
156
170
|
out, err, status = Open3.capture3(cmd, binmode: true)
|
@@ -184,16 +198,20 @@ module IOStreams
|
|
184
198
|
def self.list_keys(email: nil, key_id: nil, private: false)
|
185
199
|
version_check
|
186
200
|
cmd = private ? '--list-secret-keys' : '--list-keys'
|
187
|
-
out, err, status = Open3.capture3("
|
201
|
+
out, err, status = Open3.capture3("#{executable} #{cmd} #{email || key_id}", binmode: true)
|
188
202
|
logger.debug { "IOStreams::Pgp.list_keys output:\n#{err}#{out}" } if logger
|
189
203
|
if status.success? && out.length > 0
|
190
|
-
#
|
204
|
+
# v2.0.30 output:
|
191
205
|
# pub 4096R/3A5456F5 2017-06-07
|
192
206
|
# uid [ unknown] Joe Bloggs <j@bloggs.net>
|
193
207
|
# sub 4096R/2C9B240B 2017-06-07
|
208
|
+
# v1.4 output:
|
209
|
+
# sec 2048R/27D2E7FA 2016-10-05
|
210
|
+
# uid Receiver <receiver@example.org>
|
211
|
+
# ssb 2048R/893749EA 2016-10-05
|
194
212
|
parse_list_output(out)
|
195
213
|
else
|
196
|
-
return [] if err =~ /(key not found|No (public|secret) key)/i
|
214
|
+
return [] if err =~ /(key not found|No (public|secret) key|key not available)/i
|
197
215
|
raise(Pgp::Failure, "GPG Failed calling gpg to list keys for #{email || key_id}: #{err}#{out}")
|
198
216
|
end
|
199
217
|
end
|
@@ -212,7 +230,7 @@ module IOStreams
|
|
212
230
|
# email: [String]
|
213
231
|
def self.key_info(key:)
|
214
232
|
version_check
|
215
|
-
out, err, status = Open3.capture3(
|
233
|
+
out, err, status = Open3.capture3(executable, binmode: true, stdin_data: key)
|
216
234
|
logger.debug { "IOStreams::Pgp.key_info output:\n#{err}#{out}" } if logger
|
217
235
|
if status.success? && out.length > 0
|
218
236
|
# Sample Output:
|
@@ -239,9 +257,9 @@ module IOStreams
|
|
239
257
|
# Default: false
|
240
258
|
def self.export(email:, ascii: true, private: false)
|
241
259
|
version_check
|
242
|
-
armor = ascii ? '
|
260
|
+
armor = ascii ? '--armor' : nil
|
243
261
|
cmd = private ? '--export-secret-keys' : '--export'
|
244
|
-
out, err, status = Open3.capture3("
|
262
|
+
out, err, status = Open3.capture3("#{executable} #{armor} #{cmd} #{email}", binmode: true)
|
245
263
|
logger.debug { "IOStreams::Pgp.export output:\n#{err}" } if logger
|
246
264
|
if status.success? && out.length > 0
|
247
265
|
out
|
@@ -267,7 +285,7 @@ module IOStreams
|
|
267
285
|
# * Invalidated keys must be removed manually.
|
268
286
|
def self.import(key:)
|
269
287
|
version_check
|
270
|
-
out, err, status = Open3.capture3(
|
288
|
+
out, err, status = Open3.capture3("#{executable} --import", binmode: true, stdin_data: key)
|
271
289
|
logger.debug { "IOStreams::Pgp.import output:\n#{err}#{out}" } if logger
|
272
290
|
if status.success? && err.length > 0
|
273
291
|
# Sample output
|
@@ -316,7 +334,7 @@ module IOStreams
|
|
316
334
|
return unless fingerprint
|
317
335
|
|
318
336
|
trust = "#{fingerprint}:#{level + 1}:\n"
|
319
|
-
out, err, status = Open3.capture3(
|
337
|
+
out, err, status = Open3.capture3("#{executable} --import-ownertrust", stdin_data: trust)
|
320
338
|
logger.debug { "IOStreams::Pgp.set_trust output:\n#{err}#{out}" } if logger
|
321
339
|
if status.success?
|
322
340
|
err
|
@@ -328,7 +346,7 @@ module IOStreams
|
|
328
346
|
# DEPRECATED - Use key_ids instead of fingerprints
|
329
347
|
def self.fingerprint(email:)
|
330
348
|
version_check
|
331
|
-
Open3.popen2e("
|
349
|
+
Open3.popen2e("#{executable} --list-keys --fingerprint --with-colons #{email}") do |stdin, out, waith_thr|
|
332
350
|
output = out.read.chomp
|
333
351
|
if waith_thr.value.success?
|
334
352
|
output.each_line do |line|
|
@@ -351,7 +369,7 @@ module IOStreams
|
|
351
369
|
# Returns [String] the version of pgp currently installed
|
352
370
|
def self.pgp_version
|
353
371
|
@pgp_version ||= begin
|
354
|
-
out, err, status = Open3.capture3("
|
372
|
+
out, err, status = Open3.capture3("#{executable} --version")
|
355
373
|
logger.debug { "IOStreams::Pgp.version output:\n#{err}#{out}" } if logger
|
356
374
|
if status.success?
|
357
375
|
# Sample output
|
@@ -395,7 +413,9 @@ module IOStreams
|
|
395
413
|
results = []
|
396
414
|
hash = {}
|
397
415
|
out.each_line do |line|
|
398
|
-
if match = line.match(/(pub|sec)\s+(\d+)(.*)\/(\w+)\s+(\
|
416
|
+
if match = line.match(/(pub|sec)\s+(\d+)(.*)\/(\w+)\s+(\d+-\d+-\d+)(\s+(.+)<(.+)>)?/)
|
417
|
+
# Matches: pub 2048R/C7F9D9CB 2016-10-26
|
418
|
+
# Or: pub 2048R/C7F9D9CB 2016-10-26 Receiver <receiver@example.org>
|
399
419
|
hash = {
|
400
420
|
private: match[1] == 'sec',
|
401
421
|
key_length: match[2].to_s.to_i,
|
@@ -403,19 +423,23 @@ module IOStreams
|
|
403
423
|
key_id: match[4],
|
404
424
|
date: (Date.parse(match[5].to_s) rescue match[5])
|
405
425
|
}
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
hash
|
412
|
-
hash[:name] = match[3].to_s.strip
|
413
|
-
else
|
414
|
-
hash[:name] = name
|
426
|
+
# Prior to gpg v2.0.30
|
427
|
+
if match[7]
|
428
|
+
hash[:name] = match[7].strip
|
429
|
+
hash[:email] = match[8].strip
|
430
|
+
results << hash
|
431
|
+
hash = {}
|
415
432
|
end
|
433
|
+
elsif match = line.match(/uid\s+(\[(.+)\]\s+)?(.+)<(.+)>/)
|
434
|
+
# Matches: uid [ unknown] Joe Bloggs <j@bloggs.net>
|
435
|
+
# Or: uid Joe Bloggs <j@bloggs.net>
|
436
|
+
hash[:email] = match[4].strip
|
437
|
+
hash[:name] = match[3].to_s.strip
|
438
|
+
hash[:trust] = match[2].to_s.strip if match[1]
|
416
439
|
results << hash
|
417
440
|
hash = {}
|
418
441
|
end
|
442
|
+
|
419
443
|
end
|
420
444
|
results
|
421
445
|
end
|
data/lib/io_streams/version.rb
CHANGED
data/test/pgp_test.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
|
-
#IOStreams::Pgp.logger =
|
3
|
+
#IOStreams::Pgp.logger = Logger.new(STDOUT)
|
4
4
|
|
5
5
|
module Streams
|
6
6
|
class PgpTest < Minitest::Test
|
@@ -118,7 +118,12 @@ module Streams
|
|
118
118
|
assert_equal 'R', key[:key_type]
|
119
119
|
assert_equal user_name, key[:name]
|
120
120
|
refute key[:private], key
|
121
|
-
|
121
|
+
ver = IOStreams::Pgp.pgp_version
|
122
|
+
ap "Running PGP tests with #{IOStreams::Pgp.executable} v#{ver}"
|
123
|
+
maint = ver.split('.').last.to_i
|
124
|
+
if (ver.to_f >= 2) && (maint >= 30)
|
125
|
+
assert_equal 'ultimate', key[:trust]
|
126
|
+
end
|
122
127
|
end
|
123
128
|
|
124
129
|
it 'lists private keys' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iostreams
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.12.
|
4
|
+
version: 0.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reid Morrison
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-06-
|
11
|
+
date: 2017-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|