net-ssh 4.0.0.beta3 → 4.0.0.beta4
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +2 -1
- data/CHANGES.txt +9 -0
- data/Gemfile +9 -1
- data/Gemfile.norbnacl +6 -1
- data/Gemfile.norbnacl.lock +4 -3
- data/ISSUE_TEMPLATE.md +30 -0
- data/README.rdoc +5 -1
- data/Rakefile +4 -0
- data/appveyor.yml +36 -5
- data/lib/net/ssh.rb +5 -5
- data/lib/net/ssh/authentication/agent.rb +174 -14
- data/lib/net/ssh/authentication/key_manager.rb +1 -1
- data/lib/net/ssh/authentication/pageant.rb +116 -19
- data/lib/net/ssh/buffered_io.rb +17 -12
- data/lib/net/ssh/connection/session.rb +29 -7
- data/lib/net/ssh/key_factory.rb +7 -7
- data/lib/net/ssh/proxy/http.rb +7 -4
- data/lib/net/ssh/proxy/https.rb +49 -0
- data/lib/net/ssh/test.rb +2 -2
- data/lib/net/ssh/test/extensions.rb +17 -0
- data/lib/net/ssh/transport/ctr.rb +7 -9
- data/lib/net/ssh/version.rb +2 -2
- data/net-ssh.gemspec +3 -4
- metadata +8 -21
- metadata.gz.sig +0 -0
- data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
- data/lib/net/ssh/authentication/agent/socket.rb +0 -178
@@ -232,7 +232,7 @@ module Net
|
|
232
232
|
identity
|
233
233
|
end
|
234
234
|
|
235
|
-
rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError, ArgumentError => e
|
235
|
+
rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError, OpenSSL::PKey::PKeyError, ArgumentError => e
|
236
236
|
if ignore_decryption_errors
|
237
237
|
identity
|
238
238
|
else
|
@@ -13,7 +13,9 @@ else
|
|
13
13
|
# For now map DL to Fiddler versus updating all the code below
|
14
14
|
module DL
|
15
15
|
CPtr ||= Fiddle::Pointer
|
16
|
-
|
16
|
+
if RUBY_PLATFORM != "java"
|
17
|
+
RUBY_FREE ||= Fiddle::RUBY_FREE
|
18
|
+
end
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
@@ -36,7 +38,7 @@ module Net; module SSH; module Authentication
|
|
36
38
|
|
37
39
|
# The definition of the Windows methods and data structures used in
|
38
40
|
# communicating with the pageant process.
|
39
|
-
module Win
|
41
|
+
module Win # rubocop:disable Metrics/ModuleLength
|
40
42
|
# Compatibility on initialization
|
41
43
|
if RUBY_VERSION < "1.9"
|
42
44
|
extend DL::Importable
|
@@ -59,6 +61,11 @@ module Net; module SSH; module Authentication
|
|
59
61
|
SIZEOF_DWORD = Fiddle::SIZEOF_LONG
|
60
62
|
end
|
61
63
|
|
64
|
+
if RUBY_ENGINE=="jruby"
|
65
|
+
typealias("HANDLE", "void *") # From winnt.h
|
66
|
+
typealias("PHANDLE", "void *") # From winnt.h
|
67
|
+
typealias("ULONG_PTR", "unsigned long*")
|
68
|
+
end
|
62
69
|
typealias("LPCTSTR", "char *") # From winnt.h
|
63
70
|
typealias("LPVOID", "void *") # From winnt.h
|
64
71
|
typealias("LPCVOID", "const void *") # From windef.h
|
@@ -77,16 +84,22 @@ module Net; module SSH; module Authentication
|
|
77
84
|
|
78
85
|
SMTO_NORMAL = 0 # From winuser.h
|
79
86
|
|
87
|
+
SUFFIX = if RUBY_ENGINE == "jruby"
|
88
|
+
"A"
|
89
|
+
else
|
90
|
+
""
|
91
|
+
end
|
92
|
+
|
80
93
|
# args: lpClassName, lpWindowName
|
81
|
-
extern
|
94
|
+
extern "HWND FindWindow#{SUFFIX}(LPCTSTR, LPCTSTR)"
|
82
95
|
|
83
96
|
# args: none
|
84
97
|
extern 'DWORD GetCurrentThreadId()'
|
85
98
|
|
86
99
|
# args: hFile, (ignored), flProtect, dwMaximumSizeHigh,
|
87
100
|
# dwMaximumSizeLow, lpName
|
88
|
-
extern
|
89
|
-
'DWORD, DWORD, LPCTSTR)
|
101
|
+
extern "HANDLE CreateFileMapping#{SUFFIX}(HANDLE, void *, DWORD, ' +
|
102
|
+
'DWORD, DWORD, LPCTSTR)"
|
90
103
|
|
91
104
|
# args: hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh,
|
92
105
|
# dwfileOffsetLow, dwNumberOfBytesToMap
|
@@ -99,8 +112,8 @@ module Net; module SSH; module Authentication
|
|
99
112
|
extern 'BOOL CloseHandle(HANDLE)'
|
100
113
|
|
101
114
|
# args: hWnd, Msg, wParam, lParam, fuFlags, uTimeout, lpdwResult
|
102
|
-
extern
|
103
|
-
'UINT, UINT, PDWORD_PTR)
|
115
|
+
extern "LRESULT SendMessageTimeout#{SUFFIX}(HWND, UINT, WPARAM, LPARAM, ' +
|
116
|
+
'UINT, UINT, PDWORD_PTR)"
|
104
117
|
|
105
118
|
# args: none
|
106
119
|
extern 'DWORD GetLastError()'
|
@@ -154,7 +167,11 @@ module Net; module SSH; module Authentication
|
|
154
167
|
'LPVOID Dacl']
|
155
168
|
|
156
169
|
# The COPYDATASTRUCT is used to send WM_COPYDATA messages
|
157
|
-
COPYDATASTRUCT =
|
170
|
+
COPYDATASTRUCT = if RUBY_ENGINE == "jruby"
|
171
|
+
struct ['ULONG_PTR dwData', 'DWORD cbData', 'LPVOID lpData']
|
172
|
+
else
|
173
|
+
struct ['uintptr_t dwData', 'DWORD cbData', 'LPVOID lpData']
|
174
|
+
end
|
158
175
|
|
159
176
|
# Compatibility for security attribute retrieval.
|
160
177
|
if RUBY_VERSION < "1.9"
|
@@ -189,6 +206,30 @@ module Net; module SSH; module Authentication
|
|
189
206
|
def self.set_ptr_data(ptr, data)
|
190
207
|
ptr[0] = data
|
191
208
|
end
|
209
|
+
elsif RUBY_ENGINE == "jruby"
|
210
|
+
%w(FindWindow CreateFileMapping SendMessageTimeout).each do |name|
|
211
|
+
alias_method name, name+"A"
|
212
|
+
module_function name
|
213
|
+
end
|
214
|
+
# :nodoc:
|
215
|
+
module LibC
|
216
|
+
extend FFI::Library
|
217
|
+
ffi_lib FFI::Library::LIBC
|
218
|
+
attach_function :malloc, [:size_t], :pointer
|
219
|
+
attach_function :free, [:pointer], :void
|
220
|
+
end
|
221
|
+
|
222
|
+
def self.malloc_ptr(size)
|
223
|
+
Fiddle::Pointer.new(LibC.malloc(size), size, LibC.method(:free))
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.get_ptr(ptr)
|
227
|
+
return data.address
|
228
|
+
end
|
229
|
+
|
230
|
+
def self.set_ptr_data(ptr, data)
|
231
|
+
ptr.write_string_length(data, data.size)
|
232
|
+
end
|
192
233
|
else
|
193
234
|
def self.malloc_ptr(size)
|
194
235
|
return DL::CPtr.malloc(size, DL::RUBY_FREE)
|
@@ -211,12 +252,12 @@ module Net; module SSH; module Authentication
|
|
211
252
|
Win.InitializeSecurityDescriptor(psd_information,
|
212
253
|
Win::REVISION))
|
213
254
|
raise_error_if_zero(
|
214
|
-
Win.SetSecurityDescriptorOwner(psd_information, user
|
255
|
+
Win.SetSecurityDescriptorOwner(psd_information, get_sid_ptr(user),
|
215
256
|
0))
|
216
257
|
raise_error_if_zero(
|
217
258
|
Win.IsValidSecurityDescriptor(psd_information))
|
218
259
|
|
219
|
-
sa = Win::SECURITY_ATTRIBUTES.new(malloc_ptr(Win::SECURITY_ATTRIBUTES.size))
|
260
|
+
sa = Win::SECURITY_ATTRIBUTES.new(to_struct_ptr(malloc_ptr(Win::SECURITY_ATTRIBUTES.size)))
|
220
261
|
sa.nLength = Win::SECURITY_ATTRIBUTES.size
|
221
262
|
sa.lpSecurityDescriptor = psd_information.to_i
|
222
263
|
sa.bInheritHandle = 1
|
@@ -224,6 +265,65 @@ module Net; module SSH; module Authentication
|
|
224
265
|
return sa
|
225
266
|
end
|
226
267
|
|
268
|
+
if RUBY_ENGINE == "jruby"
|
269
|
+
def self.ptr_to_s(ptr, size)
|
270
|
+
ret = ptr.to_s(size)
|
271
|
+
ret << "\x00" while ret.size < size
|
272
|
+
ret
|
273
|
+
end
|
274
|
+
|
275
|
+
def self.ptr_to_handle(phandle)
|
276
|
+
phandle.ptr
|
277
|
+
end
|
278
|
+
|
279
|
+
def self.ptr_to_dword(ptr)
|
280
|
+
first = ptr.ptr.to_i
|
281
|
+
second = ptr_to_s(ptr,Win::SIZEOF_DWORD).unpack('L')[0]
|
282
|
+
raise "Error" unless first == second
|
283
|
+
first
|
284
|
+
end
|
285
|
+
|
286
|
+
def self.to_token_user(ptoken_information)
|
287
|
+
TOKEN_USER.new(ptoken_information.to_ptr)
|
288
|
+
end
|
289
|
+
|
290
|
+
def self.to_struct_ptr(ptr)
|
291
|
+
ptr.to_ptr
|
292
|
+
end
|
293
|
+
|
294
|
+
def self.get_sid(user)
|
295
|
+
ptr_to_s(user.to_ptr.ptr,Win::SIZEOF_DWORD).unpack('L')[0]
|
296
|
+
end
|
297
|
+
|
298
|
+
def self.get_sid_ptr(user)
|
299
|
+
user.to_ptr.ptr
|
300
|
+
end
|
301
|
+
else
|
302
|
+
def self.get_sid(user)
|
303
|
+
user.SID
|
304
|
+
end
|
305
|
+
|
306
|
+
def self.ptr_to_handle(phandle)
|
307
|
+
phandle.ptr.to_i
|
308
|
+
end
|
309
|
+
|
310
|
+
def self.to_struct_ptr(ptr)
|
311
|
+
ptr
|
312
|
+
end
|
313
|
+
|
314
|
+
def self.ptr_to_dword(ptr)
|
315
|
+
ptr.to_s(Win::SIZEOF_DWORD).unpack('L')[0]
|
316
|
+
end
|
317
|
+
|
318
|
+
def self.to_token_user(ptoken_information)
|
319
|
+
TOKEN_USER.new(ptoken_information)
|
320
|
+
end
|
321
|
+
|
322
|
+
def self.get_sid_ptr(user)
|
323
|
+
user.SID
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
227
327
|
def self.get_current_user
|
228
328
|
token_handle = open_process_token(Win.GetCurrentProcess,
|
229
329
|
Win::TOKEN_QUERY)
|
@@ -238,8 +338,7 @@ module Net; module SSH; module Authentication
|
|
238
338
|
raise_error_if_zero(
|
239
339
|
Win.OpenProcessToken(process_handle, desired_access,
|
240
340
|
ptoken_handle))
|
241
|
-
token_handle = ptoken_handle
|
242
|
-
|
341
|
+
token_handle = ptr_to_handle(ptoken_handle)
|
243
342
|
return token_handle
|
244
343
|
end
|
245
344
|
|
@@ -254,7 +353,7 @@ module Net; module SSH; module Authentication
|
|
254
353
|
Win.GetTokenInformation(token_handle,
|
255
354
|
token_information_class,
|
256
355
|
Win::NULL, 0, preturn_length)
|
257
|
-
ptoken_information = malloc_ptr(preturn_length
|
356
|
+
ptoken_information = malloc_ptr(ptr_to_dword(preturn_length))
|
258
357
|
|
259
358
|
# This call is going to write the requested information to
|
260
359
|
# the memory location referenced by token_information.
|
@@ -265,7 +364,7 @@ module Net; module SSH; module Authentication
|
|
265
364
|
ptoken_information.size,
|
266
365
|
preturn_length))
|
267
366
|
|
268
|
-
return
|
367
|
+
return to_token_user(ptoken_information)
|
269
368
|
end
|
270
369
|
|
271
370
|
def self.raise_error_if_zero(result)
|
@@ -288,10 +387,8 @@ module Net; module SSH; module Authentication
|
|
288
387
|
|
289
388
|
private_class_method :new
|
290
389
|
|
291
|
-
# The factory method for creating a new Socket instance.
|
292
|
-
|
293
|
-
# the general Socket interface.
|
294
|
-
def self.open(location=nil)
|
390
|
+
# The factory method for creating a new Socket instance.
|
391
|
+
def self.open
|
295
392
|
new
|
296
393
|
end
|
297
394
|
|
@@ -300,7 +397,7 @@ module Net; module SSH; module Authentication
|
|
300
397
|
def initialize
|
301
398
|
@win = Win.FindWindow("Pageant", "Pageant")
|
302
399
|
|
303
|
-
if @win == 0
|
400
|
+
if @win.to_i == 0
|
304
401
|
raise Net::SSH::Exception,
|
305
402
|
"pageant process not running"
|
306
403
|
end
|
data/lib/net/ssh/buffered_io.rb
CHANGED
@@ -66,6 +66,9 @@ module Net; module SSH
|
|
66
66
|
debug { "read #{data.length} bytes" }
|
67
67
|
input.append(data)
|
68
68
|
return data.length
|
69
|
+
rescue EOFError => e
|
70
|
+
@input_errors << e
|
71
|
+
return 0
|
69
72
|
end
|
70
73
|
|
71
74
|
# Read up to +length+ bytes from the input buffer. If +length+ is nil,
|
@@ -143,21 +146,23 @@ module Net; module SSH
|
|
143
146
|
# Module#include to add this module.
|
144
147
|
def initialize_buffered_io
|
145
148
|
@input = Net::SSH::Buffer.new
|
149
|
+
@input_errors = []
|
146
150
|
@output = Net::SSH::Buffer.new
|
151
|
+
@output_errors = []
|
147
152
|
end
|
148
153
|
end
|
149
154
|
|
150
155
|
|
151
|
-
|
156
|
+
|
152
157
|
# Fixes for two issues by Miklós Fazekas:
|
153
158
|
#
|
154
|
-
# * if client closes a forwarded connection, but the server is
|
159
|
+
# * if client closes a forwarded connection, but the server is
|
155
160
|
# reading, net-ssh terminates with IOError socket closed.
|
156
|
-
# * if client force closes (RST) a forwarded connection, but
|
161
|
+
# * if client force closes (RST) a forwarded connection, but
|
157
162
|
# server is reading, net-ssh terminates with [an exception]
|
158
163
|
#
|
159
|
-
# See:
|
160
|
-
#
|
164
|
+
# See:
|
165
|
+
#
|
161
166
|
# http://net-ssh.lighthouseapp.com/projects/36253/tickets/7
|
162
167
|
# http://github.com/net-ssh/net-ssh/tree/portfwfix
|
163
168
|
#
|
@@ -168,24 +173,24 @@ module Net; module SSH
|
|
168
173
|
rescue Errno::ECONNRESET => e
|
169
174
|
debug { "connection was reset => shallowing exception:#{e}" }
|
170
175
|
return 0
|
171
|
-
rescue IOError => e
|
172
|
-
if e.message =~ /closed/ then
|
176
|
+
rescue IOError => e
|
177
|
+
if e.message =~ /closed/ then
|
173
178
|
debug { "connection was reset => shallowing exception:#{e}" }
|
174
179
|
return 0
|
175
180
|
else
|
176
181
|
raise
|
177
|
-
end
|
182
|
+
end
|
178
183
|
end
|
179
184
|
end
|
180
|
-
|
185
|
+
|
181
186
|
def send_pending
|
182
187
|
begin
|
183
|
-
super
|
188
|
+
super
|
184
189
|
rescue Errno::ECONNRESET => e
|
185
190
|
debug { "connection was reset => shallowing exception:#{e}" }
|
186
191
|
return 0
|
187
192
|
rescue IOError => e
|
188
|
-
if e.message =~ /closed/ then
|
193
|
+
if e.message =~ /closed/ then
|
189
194
|
debug { "connection was reset => shallowing exception:#{e}" }
|
190
195
|
return 0
|
191
196
|
else
|
@@ -194,5 +199,5 @@ module Net; module SSH
|
|
194
199
|
end
|
195
200
|
end
|
196
201
|
end
|
197
|
-
|
202
|
+
|
198
203
|
end; end
|
@@ -234,7 +234,7 @@ module Net; module SSH; module Connection
|
|
234
234
|
# Called by event loop to process available data before going to
|
235
235
|
# event multiplexing
|
236
236
|
def ev_preprocess(&block)
|
237
|
-
dispatch_incoming_packets
|
237
|
+
dispatch_incoming_packets(raise_disconnect_errors: false)
|
238
238
|
each_channel { |id, channel| channel.process unless channel.local_closed? }
|
239
239
|
end
|
240
240
|
|
@@ -335,6 +335,15 @@ module Net; module SSH; module Connection
|
|
335
335
|
channels[local_id] = channel
|
336
336
|
end
|
337
337
|
|
338
|
+
class StringWithExitstatus < String
|
339
|
+
def initialize(str, exitstatus)
|
340
|
+
super(str)
|
341
|
+
@exitstatus = exitstatus
|
342
|
+
end
|
343
|
+
|
344
|
+
attr_reader :exitstatus
|
345
|
+
end
|
346
|
+
|
338
347
|
# A convenience method for executing a command and interacting with it. If
|
339
348
|
# no block is given, all output is printed via $stdout and $stderr. Otherwise,
|
340
349
|
# the block is called for each data and extended data packet, with three
|
@@ -355,11 +364,21 @@ module Net; module SSH; module Connection
|
|
355
364
|
# puts data
|
356
365
|
# end
|
357
366
|
# end
|
358
|
-
def exec(command, &block)
|
367
|
+
def exec(command, status: nil, &block)
|
359
368
|
open_channel do |channel|
|
360
369
|
channel.exec(command) do |ch, success|
|
361
370
|
raise "could not execute command: #{command.inspect}" unless success
|
362
371
|
|
372
|
+
if status
|
373
|
+
channel.on_request("exit-status") do |ch2,data|
|
374
|
+
status[:exit_code] = data.read_long
|
375
|
+
end
|
376
|
+
|
377
|
+
channel.on_request("exit-signal") do |ch2, data|
|
378
|
+
status[:exit_signal] = data.read_long
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
363
382
|
channel.on_data do |ch2, data|
|
364
383
|
if block
|
365
384
|
block.call(ch2, :stdout, data)
|
@@ -384,19 +403,22 @@ module Net; module SSH; module Connection
|
|
384
403
|
# as a single string.
|
385
404
|
#
|
386
405
|
# matches = ssh.exec!("grep something /some/files")
|
387
|
-
|
406
|
+
#
|
407
|
+
# the returned string has an exitstatus method to query it's exit satus
|
408
|
+
def exec!(command, status: nil, &block)
|
388
409
|
block_or_concat = block || Proc.new do |ch, type, data|
|
389
410
|
ch[:result] ||= ""
|
390
411
|
ch[:result] << data
|
391
412
|
end
|
392
413
|
|
393
|
-
|
414
|
+
status ||= {}
|
415
|
+
channel = exec(command, status: status, &block_or_concat)
|
394
416
|
channel.wait
|
395
417
|
|
396
418
|
channel[:result] ||= "" unless block
|
397
419
|
channel[:result] &&= channel[:result].force_encoding("UTF-8") unless block
|
398
420
|
|
399
|
-
|
421
|
+
StringWithExitstatus.new(channel[:result], status[:exit_code]) if channel[:result]
|
400
422
|
end
|
401
423
|
|
402
424
|
# Enqueues a message to be sent to the server as soon as the socket is
|
@@ -509,7 +531,7 @@ module Net; module SSH; module Connection
|
|
509
531
|
|
510
532
|
# Read all pending packets from the connection and dispatch them as
|
511
533
|
# appropriate. Returns as soon as there are no more pending packets.
|
512
|
-
def dispatch_incoming_packets
|
534
|
+
def dispatch_incoming_packets(raise_disconnect_errors: true)
|
513
535
|
while packet = transport.poll_message
|
514
536
|
unless MAP.key?(packet.type)
|
515
537
|
raise Net::SSH::Exception, "unexpected response #{packet.type} (#{packet.inspect})"
|
@@ -519,7 +541,7 @@ module Net; module SSH; module Connection
|
|
519
541
|
end
|
520
542
|
rescue
|
521
543
|
force_channel_cleanup_on_close if closed?
|
522
|
-
raise
|
544
|
+
raise if raise_disconnect_errors || !$!.is_a?(Net::SSH::Disconnect)
|
523
545
|
end
|
524
546
|
|
525
547
|
# Returns the next available channel id to be assigned, and increments
|
data/lib/net/ssh/key_factory.rb
CHANGED
@@ -49,7 +49,7 @@ module Net; module SSH
|
|
49
49
|
# encrypted (requiring a passphrase to use), the user will be
|
50
50
|
# prompted to enter their password unless passphrase works.
|
51
51
|
def load_data_private_key(data, passphrase=nil, ask_passphrase=true, filename="", prompt=Prompt.default)
|
52
|
-
key_read,
|
52
|
+
key_read, error_classes = classify_key(data, filename)
|
53
53
|
|
54
54
|
encrypted_key = data.match(/ENCRYPTED/)
|
55
55
|
tries = 0
|
@@ -58,7 +58,7 @@ module Net; module SSH
|
|
58
58
|
result =
|
59
59
|
begin
|
60
60
|
key_read[data, passphrase || 'invalid']
|
61
|
-
rescue
|
61
|
+
rescue *error_classes
|
62
62
|
if encrypted_key && ask_passphrase
|
63
63
|
tries += 1
|
64
64
|
if tries <= 3
|
@@ -110,18 +110,18 @@ module Net; module SSH
|
|
110
110
|
def classify_key(data, filename)
|
111
111
|
if data.match(/-----BEGIN OPENSSH PRIVATE KEY-----/)
|
112
112
|
if defined?(Net::SSH::Authentication::ED25519)
|
113
|
-
return ->(key_data, passphrase) { Net::SSH::Authentication::ED25519::PrivKey.read(key_data, passphrase) }, ArgumentError
|
113
|
+
return ->(key_data, passphrase) { Net::SSH::Authentication::ED25519::PrivKey.read(key_data, passphrase) }, [ArgumentError]
|
114
114
|
else
|
115
115
|
raise OpenSSL::PKey::PKeyError, "OpenSSH keys only supported if ED25519 is available - #{ED25519_LOAD_ERROR}"
|
116
116
|
end
|
117
117
|
elsif OpenSSL::PKey.respond_to?(:read)
|
118
|
-
return ->(key_data, passphrase) { OpenSSL::PKey.read(key_data, passphrase) }, ArgumentError
|
118
|
+
return ->(key_data, passphrase) { OpenSSL::PKey.read(key_data, passphrase) }, [ArgumentError, OpenSSL::PKey::PKeyError]
|
119
119
|
elsif data.match(/-----BEGIN DSA PRIVATE KEY-----/)
|
120
|
-
return ->(key_data, passphrase) { OpenSSL::PKey::DSA.new(key_data, passphrase) }, OpenSSL::PKey::DSAError
|
120
|
+
return ->(key_data, passphrase) { OpenSSL::PKey::DSA.new(key_data, passphrase) }, [OpenSSL::PKey::DSAError]
|
121
121
|
elsif data.match(/-----BEGIN RSA PRIVATE KEY-----/)
|
122
|
-
return ->(key_data, passphrase) { OpenSSL::PKey::RSA.new(key_data, passphrase) }, OpenSSL::PKey::RSAError
|
122
|
+
return ->(key_data, passphrase) { OpenSSL::PKey::RSA.new(key_data, passphrase) }, [OpenSSL::PKey::RSAError]
|
123
123
|
elsif data.match(/-----BEGIN EC PRIVATE KEY-----/) && defined?(OpenSSL::PKey::EC)
|
124
|
-
return ->(key_data, passphrase) { OpenSSL::PKey::EC.new(key_data, passphrase) }, OpenSSL::PKey::ECError
|
124
|
+
return ->(key_data, passphrase) { OpenSSL::PKey::EC.new(key_data, passphrase) }, [OpenSSL::PKey::ECError]
|
125
125
|
elsif data.match(/-----BEGIN (.+) PRIVATE KEY-----/)
|
126
126
|
raise OpenSSL::PKey::PKeyError, "not a supported key type '#{$1}'"
|
127
127
|
else
|