net-ssh 4.0.0.beta3 → 4.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|