net-ssh 6.0.0 → 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/config/rubocop_linter_action.yml +4 -0
  5. data/.github/workflows/ci-with-docker.yml +44 -0
  6. data/.github/workflows/ci.yml +87 -0
  7. data/.github/workflows/rubocop.yml +13 -0
  8. data/.gitignore +2 -0
  9. data/.rubocop.yml +12 -1
  10. data/.rubocop_todo.yml +474 -375
  11. data/CHANGES.txt +39 -2
  12. data/Dockerfile +27 -0
  13. data/Dockerfile.openssl3 +17 -0
  14. data/Gemfile +2 -0
  15. data/Gemfile.noed25519 +2 -0
  16. data/README.md +14 -7
  17. data/Rakefile +5 -0
  18. data/docker-compose.yml +23 -0
  19. data/lib/net/ssh/authentication/agent.rb +29 -13
  20. data/lib/net/ssh/authentication/certificate.rb +12 -9
  21. data/lib/net/ssh/authentication/constants.rb +0 -1
  22. data/lib/net/ssh/authentication/ed25519.rb +11 -7
  23. data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
  24. data/lib/net/ssh/authentication/key_manager.rb +46 -34
  25. data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
  26. data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
  27. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -2
  28. data/lib/net/ssh/authentication/methods/none.rb +6 -9
  29. data/lib/net/ssh/authentication/methods/password.rb +2 -3
  30. data/lib/net/ssh/authentication/methods/publickey.rb +56 -16
  31. data/lib/net/ssh/authentication/pageant.rb +97 -97
  32. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +2 -2
  33. data/lib/net/ssh/authentication/session.rb +18 -17
  34. data/lib/net/ssh/buffer.rb +50 -30
  35. data/lib/net/ssh/buffered_io.rb +24 -25
  36. data/lib/net/ssh/config.rb +33 -20
  37. data/lib/net/ssh/connection/channel.rb +84 -82
  38. data/lib/net/ssh/connection/constants.rb +0 -4
  39. data/lib/net/ssh/connection/event_loop.rb +30 -24
  40. data/lib/net/ssh/connection/keepalive.rb +12 -12
  41. data/lib/net/ssh/connection/session.rb +108 -107
  42. data/lib/net/ssh/connection/term.rb +56 -58
  43. data/lib/net/ssh/errors.rb +12 -12
  44. data/lib/net/ssh/key_factory.rb +7 -8
  45. data/lib/net/ssh/known_hosts.rb +84 -15
  46. data/lib/net/ssh/loggable.rb +8 -9
  47. data/lib/net/ssh/packet.rb +1 -1
  48. data/lib/net/ssh/prompt.rb +9 -11
  49. data/lib/net/ssh/proxy/command.rb +1 -1
  50. data/lib/net/ssh/proxy/errors.rb +2 -4
  51. data/lib/net/ssh/proxy/http.rb +18 -20
  52. data/lib/net/ssh/proxy/https.rb +8 -10
  53. data/lib/net/ssh/proxy/jump.rb +8 -10
  54. data/lib/net/ssh/proxy/socks4.rb +2 -4
  55. data/lib/net/ssh/proxy/socks5.rb +3 -5
  56. data/lib/net/ssh/service/forward.rb +7 -7
  57. data/lib/net/ssh/test/channel.rb +24 -26
  58. data/lib/net/ssh/test/extensions.rb +35 -35
  59. data/lib/net/ssh/test/kex.rb +6 -8
  60. data/lib/net/ssh/test/local_packet.rb +0 -2
  61. data/lib/net/ssh/test/packet.rb +3 -3
  62. data/lib/net/ssh/test/remote_packet.rb +6 -8
  63. data/lib/net/ssh/test/script.rb +25 -27
  64. data/lib/net/ssh/test/socket.rb +12 -15
  65. data/lib/net/ssh/test.rb +4 -5
  66. data/lib/net/ssh/transport/algorithms.rb +34 -17
  67. data/lib/net/ssh/transport/cipher_factory.rb +28 -28
  68. data/lib/net/ssh/transport/constants.rb +3 -3
  69. data/lib/net/ssh/transport/ctr.rb +7 -7
  70. data/lib/net/ssh/transport/hmac/abstract.rb +4 -5
  71. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  72. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  73. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  74. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  75. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  76. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  77. data/lib/net/ssh/transport/hmac.rb +12 -12
  78. data/lib/net/ssh/transport/identity_cipher.rb +11 -13
  79. data/lib/net/ssh/transport/kex/abstract.rb +12 -5
  80. data/lib/net/ssh/transport/kex/abstract5656.rb +1 -1
  81. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +2 -1
  82. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
  83. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  84. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +21 -21
  85. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -2
  86. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +2 -2
  87. data/lib/net/ssh/transport/kex.rb +8 -6
  88. data/lib/net/ssh/transport/key_expander.rb +7 -8
  89. data/lib/net/ssh/transport/openssl.rb +51 -26
  90. data/lib/net/ssh/transport/packet_stream.rb +6 -5
  91. data/lib/net/ssh/transport/server_version.rb +17 -16
  92. data/lib/net/ssh/transport/session.rb +9 -7
  93. data/lib/net/ssh/transport/state.rb +43 -43
  94. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  95. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  96. data/lib/net/ssh/verifiers/always.rb +6 -4
  97. data/lib/net/ssh/verifiers/never.rb +0 -2
  98. data/lib/net/ssh/version.rb +2 -2
  99. data/lib/net/ssh.rb +5 -6
  100. data/net-ssh-public_cert.pem +8 -8
  101. data/net-ssh.gemspec +2 -2
  102. data/support/ssh_tunnel_bug.rb +3 -3
  103. data.tar.gz.sig +0 -0
  104. metadata +23 -15
  105. metadata.gz.sig +0 -0
  106. data/.travis.yml +0 -52
@@ -21,10 +21,9 @@ end
21
21
 
22
22
  require 'net/ssh/errors'
23
23
 
24
- module Net
25
- module SSH
24
+ module Net
25
+ module SSH
26
26
  module Authentication
27
-
28
27
  # This module encapsulates the implementation of a socket factory that
29
28
  # uses the PuTTY "pageant" utility to obtain information about SSH
30
29
  # identities.
@@ -33,36 +32,35 @@ module Net
33
32
  # by Guillaume Marçais (guillaume.marcais@free.fr). It is used and
34
33
  # relicensed by permission.
35
34
  module Pageant
36
-
37
35
  # From Putty pageant.c
38
36
  AGENT_MAX_MSGLEN = 8192
39
37
  AGENT_COPYDATA_ID = 0x804e50ba
40
-
38
+
41
39
  # The definition of the Windows methods and data structures used in
42
40
  # communicating with the pageant process.
43
41
  module Win # rubocop:disable Metrics/ModuleLength
44
42
  # Compatibility on initialization
45
43
  if RUBY_VERSION < "1.9"
46
44
  extend DL::Importable
47
-
45
+
48
46
  dlload 'user32.dll'
49
47
  dlload 'kernel32.dll'
50
48
  dlload 'advapi32.dll'
51
-
49
+
52
50
  SIZEOF_DWORD = DL.sizeof('L')
53
51
  elsif RUBY_VERSION < "2.1"
54
52
  extend DL::Importer
55
- dlload 'user32.dll','kernel32.dll', 'advapi32.dll'
53
+ dlload 'user32.dll', 'kernel32.dll', 'advapi32.dll'
56
54
  include DL::Win32Types
57
-
55
+
58
56
  SIZEOF_DWORD = DL::SIZEOF_LONG
59
57
  else
60
58
  extend Fiddle::Importer
61
- dlload 'user32.dll','kernel32.dll', 'advapi32.dll'
59
+ dlload 'user32.dll', 'kernel32.dll', 'advapi32.dll'
62
60
  include Fiddle::Win32Types
63
61
  SIZEOF_DWORD = Fiddle::SIZEOF_LONG
64
62
  end
65
-
63
+
66
64
  if RUBY_ENGINE == "jruby"
67
65
  typealias("HANDLE", "void *") # From winnt.h
68
66
  typealias("PHANDLE", "void *") # From winnt.h
@@ -76,105 +74,105 @@ module Net
76
74
  typealias("LPARAM", "long *") # From windef.h
77
75
  typealias("PDWORD_PTR", "long *") # From basetsd.h
78
76
  typealias("USHORT", "unsigned short") # From windef.h
79
-
77
+
80
78
  # From winbase.h, winnt.h
81
79
  INVALID_HANDLE_VALUE = -1
82
80
  NULL = nil
83
81
  PAGE_READWRITE = 0x0004
84
82
  FILE_MAP_WRITE = 2
85
83
  WM_COPYDATA = 74
86
-
84
+
87
85
  SMTO_NORMAL = 0 # From winuser.h
88
-
86
+
89
87
  SUFFIX = if RUBY_ENGINE == "jruby"
90
88
  "A"
91
89
  else
92
90
  ""
93
91
  end
94
-
92
+
95
93
  # args: lpClassName, lpWindowName
96
94
  extern "HWND FindWindow#{SUFFIX}(LPCTSTR, LPCTSTR)"
97
-
95
+
98
96
  # args: none
99
97
  extern 'DWORD GetCurrentThreadId()'
100
-
98
+
101
99
  # args: hFile, (ignored), flProtect, dwMaximumSizeHigh,
102
100
  # dwMaximumSizeLow, lpName
103
101
  extern "HANDLE CreateFileMapping#{SUFFIX}(HANDLE, void *, DWORD, " +
104
102
  "DWORD, DWORD, LPCTSTR)"
105
-
103
+
106
104
  # args: hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh,
107
105
  # dwfileOffsetLow, dwNumberOfBytesToMap
108
106
  extern 'LPVOID MapViewOfFile(HANDLE, DWORD, DWORD, DWORD, DWORD)'
109
-
107
+
110
108
  # args: lpBaseAddress
111
109
  extern 'BOOL UnmapViewOfFile(LPCVOID)'
112
-
110
+
113
111
  # args: hObject
114
112
  extern 'BOOL CloseHandle(HANDLE)'
115
-
113
+
116
114
  # args: hWnd, Msg, wParam, lParam, fuFlags, uTimeout, lpdwResult
117
115
  extern "LRESULT SendMessageTimeout#{SUFFIX}(HWND, UINT, WPARAM, LPARAM, " +
118
116
  "UINT, UINT, PDWORD_PTR)"
119
-
117
+
120
118
  # args: none
121
119
  extern 'DWORD GetLastError()'
122
-
120
+
123
121
  # args: none
124
122
  extern 'HANDLE GetCurrentProcess()'
125
-
123
+
126
124
  # args: hProcessHandle, dwDesiredAccess, (out) phNewTokenHandle
127
125
  extern 'BOOL OpenProcessToken(HANDLE, DWORD, PHANDLE)'
128
-
126
+
129
127
  # args: hTokenHandle, uTokenInformationClass,
130
128
  # (out) lpTokenInformation, dwTokenInformationLength
131
129
  # (out) pdwInfoReturnLength
132
130
  extern 'BOOL GetTokenInformation(HANDLE, UINT, LPVOID, DWORD, ' +
133
131
  'PDWORD)'
134
-
132
+
135
133
  # args: (out) lpSecurityDescriptor, dwRevisionLevel
136
134
  extern 'BOOL InitializeSecurityDescriptor(LPVOID, DWORD)'
137
-
135
+
138
136
  # args: (out) lpSecurityDescriptor, lpOwnerSid, bOwnerDefaulted
139
137
  extern 'BOOL SetSecurityDescriptorOwner(LPVOID, LPVOID, BOOL)'
140
-
138
+
141
139
  # args: pSecurityDescriptor
142
140
  extern 'BOOL IsValidSecurityDescriptor(LPVOID)'
143
-
141
+
144
142
  # Constants needed for security attribute retrieval.
145
143
  # Specifies the access mask corresponding to the desired access
146
144
  # rights.
147
145
  TOKEN_QUERY = 0x8
148
-
146
+
149
147
  # The value of TOKEN_USER from the TOKEN_INFORMATION_CLASS enum.
150
148
  TOKEN_USER_INFORMATION_CLASS = 1
151
-
149
+
152
150
  # The initial revision level assigned to the security descriptor.
153
151
  REVISION = 1
154
-
152
+
155
153
  # Structs for security attribute functions.
156
154
  # Holds the retrieved user access token.
157
155
  TOKEN_USER = struct ['void * SID', 'DWORD ATTRIBUTES']
158
-
156
+
159
157
  # Contains the security descriptor, this gets passed to the
160
158
  # function that constructs the shared memory map.
161
159
  SECURITY_ATTRIBUTES = struct ['DWORD nLength',
162
160
  'LPVOID lpSecurityDescriptor',
163
161
  'BOOL bInheritHandle']
164
-
162
+
165
163
  # The security descriptor holds security information.
166
164
  SECURITY_DESCRIPTOR = struct ['UCHAR Revision', 'UCHAR Sbz1',
167
165
  'USHORT Control', 'LPVOID Owner',
168
166
  'LPVOID Group', 'LPVOID Sacl',
169
167
  'LPVOID Dacl']
170
-
168
+
171
169
  # The COPYDATASTRUCT is used to send WM_COPYDATA messages
172
170
  COPYDATASTRUCT = if RUBY_ENGINE == "jruby"
173
171
  struct ['ULONG_PTR dwData', 'DWORD cbData', 'LPVOID lpData']
174
172
  else
175
173
  struct ['uintptr_t dwData', 'DWORD cbData', 'LPVOID lpData']
176
174
  end
177
-
175
+
178
176
  # Compatibility for security attribute retrieval.
179
177
  if RUBY_VERSION < "1.9"
180
178
  # Alias functions to > 1.9 capitalization
@@ -196,15 +194,15 @@ module Net
196
194
  alias_method new_name, name
197
195
  module_function new_name
198
196
  end
199
-
197
+
200
198
  def self.malloc_ptr(size)
201
199
  return DL.malloc(size)
202
200
  end
203
-
201
+
204
202
  def self.get_ptr(data)
205
203
  return data.to_ptr
206
204
  end
207
-
205
+
208
206
  def self.set_ptr_data(ptr, data)
209
207
  ptr[0] = data
210
208
  end
@@ -220,15 +218,15 @@ module Net
220
218
  attach_function :malloc, [:size_t], :pointer
221
219
  attach_function :free, [:pointer], :void
222
220
  end
223
-
221
+
224
222
  def self.malloc_ptr(size)
225
223
  Fiddle::Pointer.new(LibC.malloc(size), size, LibC.method(:free))
226
224
  end
227
-
225
+
228
226
  def self.get_ptr(ptr)
229
227
  return data.address
230
228
  end
231
-
229
+
232
230
  def self.set_ptr_data(ptr, data)
233
231
  ptr.write_string_length(data, data.size)
234
232
  end
@@ -236,19 +234,19 @@ module Net
236
234
  def self.malloc_ptr(size)
237
235
  return DL::CPtr.malloc(size, DL::RUBY_FREE)
238
236
  end
239
-
237
+
240
238
  def self.get_ptr(data)
241
239
  return DL::CPtr.to_ptr data
242
240
  end
243
-
241
+
244
242
  def self.set_ptr_data(ptr, data)
245
- DL::CPtr.new(ptr)[0,data.size] = data
243
+ DL::CPtr.new(ptr)[0, data.size] = data
246
244
  end
247
245
  end
248
-
246
+
249
247
  def self.get_security_attributes_for_user
250
248
  user = get_current_user
251
-
249
+
252
250
  psd_information = malloc_ptr(Win::SECURITY_DESCRIPTOR.size)
253
251
  raise_error_if_zero(
254
252
  Win.InitializeSecurityDescriptor(psd_information,
@@ -261,45 +259,46 @@ module Net
261
259
  raise_error_if_zero(
262
260
  Win.IsValidSecurityDescriptor(psd_information)
263
261
  )
264
-
262
+
265
263
  sa = Win::SECURITY_ATTRIBUTES.new(to_struct_ptr(malloc_ptr(Win::SECURITY_ATTRIBUTES.size)))
266
264
  sa.nLength = Win::SECURITY_ATTRIBUTES.size
267
265
  sa.lpSecurityDescriptor = psd_information.to_i
268
266
  sa.bInheritHandle = 1
269
-
267
+
270
268
  return sa
271
269
  end
272
-
270
+
273
271
  if RUBY_ENGINE == "jruby"
274
272
  def self.ptr_to_s(ptr, size)
275
273
  ret = ptr.to_s(size)
276
274
  ret << "\x00" while ret.size < size
277
275
  ret
278
276
  end
279
-
277
+
280
278
  def self.ptr_to_handle(phandle)
281
279
  phandle.ptr
282
280
  end
283
-
281
+
284
282
  def self.ptr_to_dword(ptr)
285
283
  first = ptr.ptr.to_i
286
- second = ptr_to_s(ptr,Win::SIZEOF_DWORD).unpack('L')[0]
284
+ second = ptr_to_s(ptr, Win::SIZEOF_DWORD).unpack('L')[0]
287
285
  raise "Error" unless first == second
286
+
288
287
  first
289
288
  end
290
-
289
+
291
290
  def self.to_token_user(ptoken_information)
292
291
  TOKEN_USER.new(ptoken_information.to_ptr)
293
292
  end
294
-
293
+
295
294
  def self.to_struct_ptr(ptr)
296
295
  ptr.to_ptr
297
296
  end
298
-
297
+
299
298
  def self.get_sid(user)
300
- ptr_to_s(user.to_ptr.ptr,Win::SIZEOF_DWORD).unpack('L')[0]
299
+ ptr_to_s(user.to_ptr.ptr, Win::SIZEOF_DWORD).unpack('L')[0]
301
300
  end
302
-
301
+
303
302
  def self.get_sid_ptr(user)
304
303
  user.to_ptr.ptr
305
304
  end
@@ -307,39 +306,39 @@ module Net
307
306
  def self.get_sid(user)
308
307
  user.SID
309
308
  end
310
-
309
+
311
310
  def self.ptr_to_handle(phandle)
312
311
  phandle.ptr.to_i
313
312
  end
314
-
313
+
315
314
  def self.to_struct_ptr(ptr)
316
315
  ptr
317
316
  end
318
-
317
+
319
318
  def self.ptr_to_dword(ptr)
320
319
  ptr.to_s(Win::SIZEOF_DWORD).unpack('L')[0]
321
320
  end
322
-
321
+
323
322
  def self.to_token_user(ptoken_information)
324
323
  TOKEN_USER.new(ptoken_information)
325
324
  end
326
-
325
+
327
326
  def self.get_sid_ptr(user)
328
327
  user.SID
329
328
  end
330
329
  end
331
-
330
+
332
331
  def self.get_current_user
333
332
  token_handle = open_process_token(Win.GetCurrentProcess,
334
333
  Win::TOKEN_QUERY)
335
334
  token_user = get_token_information(token_handle,
336
- Win::TOKEN_USER_INFORMATION_CLASS)
335
+ Win::TOKEN_USER_INFORMATION_CLASS)
337
336
  return token_user
338
337
  end
339
-
338
+
340
339
  def self.open_process_token(process_handle, desired_access)
341
340
  ptoken_handle = malloc_ptr(Win::SIZEOF_DWORD)
342
-
341
+
343
342
  raise_error_if_zero(
344
343
  Win.OpenProcessToken(process_handle, desired_access,
345
344
  ptoken_handle)
@@ -347,12 +346,12 @@ module Net
347
346
  token_handle = ptr_to_handle(ptoken_handle)
348
347
  return token_handle
349
348
  end
350
-
349
+
351
350
  def self.get_token_information(token_handle,
352
351
  token_information_class)
353
352
  # Hold the size of the information to be returned
354
353
  preturn_length = malloc_ptr(Win::SIZEOF_DWORD)
355
-
354
+
356
355
  # Going to throw an INSUFFICIENT_BUFFER_ERROR, but that is ok
357
356
  # here. This is retrieving the size of the information to be
358
357
  # returned.
@@ -360,7 +359,7 @@ module Net
360
359
  token_information_class,
361
360
  Win::NULL, 0, preturn_length)
362
361
  ptoken_information = malloc_ptr(ptr_to_dword(preturn_length))
363
-
362
+
364
363
  # This call is going to write the requested information to
365
364
  # the memory location referenced by token_information.
366
365
  raise_error_if_zero(
@@ -370,74 +369,76 @@ module Net
370
369
  ptoken_information.size,
371
370
  preturn_length)
372
371
  )
373
-
372
+
374
373
  return to_token_user(ptoken_information)
375
374
  end
376
-
375
+
377
376
  def self.raise_error_if_zero(result)
378
377
  if result == 0
379
378
  raise "Windows error: #{Win.GetLastError}"
380
379
  end
381
380
  end
382
-
381
+
383
382
  # Get a null-terminated string given a string.
384
383
  def self.get_cstr(str)
385
384
  return str + "\000"
386
385
  end
387
386
  end
388
-
387
+
389
388
  # This is the pseudo-socket implementation that mimics the interface of
390
389
  # a socket, translating each request into a Windows messaging call to
391
390
  # the pageant daemon. This allows pageant support to be implemented
392
391
  # simply by replacing the socket factory used by the Agent class.
393
392
  class Socket
394
393
  private_class_method :new
395
-
394
+
396
395
  # The factory method for creating a new Socket instance.
397
396
  def self.open
398
397
  new
399
398
  end
400
-
399
+
401
400
  # Create a new instance that communicates with the running pageant
402
401
  # instance. If no such instance is running, this will cause an error.
403
402
  def initialize
404
403
  @win = Win.FindWindow("Pageant", "Pageant")
405
-
404
+
406
405
  if @win.to_i == 0
407
406
  raise Net::SSH::Exception,
408
- "pageant process not running"
407
+ "pageant process not running"
409
408
  end
410
-
409
+
411
410
  @input_buffer = Net::SSH::Buffer.new
412
411
  @output_buffer = Net::SSH::Buffer.new
413
412
  end
414
-
413
+
415
414
  # Forwards the data to #send_query, ignoring any arguments after
416
415
  # the first.
417
416
  def send(data, *args)
418
417
  @input_buffer.append(data)
419
-
418
+
420
419
  ret = data.length
421
-
420
+
422
421
  while true
423
422
  return ret if @input_buffer.length < 4
423
+
424
424
  msg_length = @input_buffer.read_long + 4
425
425
  @input_buffer.reset!
426
-
426
+
427
427
  return ret if @input_buffer.length < msg_length
428
+
428
429
  msg = @input_buffer.read!(msg_length)
429
430
  @output_buffer.append(send_query(msg))
430
431
  end
431
432
  end
432
-
433
+
433
434
  # Reads +n+ bytes from the cached result of the last query. If +n+
434
435
  # is +nil+, returns all remaining data from the last query.
435
436
  def read(n = nil)
436
437
  @output_buffer.read(n)
437
438
  end
438
-
439
+
439
440
  def close; end
440
-
441
+
441
442
  # Packages the given query string and sends it to the pageant
442
443
  # process via the Windows messaging subsystem. The result is
443
444
  # cached, to be returned piece-wise when #read is called.
@@ -446,29 +447,29 @@ module Net
446
447
  filemap = 0
447
448
  ptr = nil
448
449
  id = Win.malloc_ptr(Win::SIZEOF_DWORD)
449
-
450
+
450
451
  mapname = "PageantRequest%08x" % Win.GetCurrentThreadId()
451
452
  security_attributes = Win.get_ptr Win.get_security_attributes_for_user
452
-
453
+
453
454
  filemap = Win.CreateFileMapping(Win::INVALID_HANDLE_VALUE,
454
455
  security_attributes,
455
456
  Win::PAGE_READWRITE, 0,
456
457
  AGENT_MAX_MSGLEN, mapname)
457
-
458
+
458
459
  if filemap == 0 || filemap == Win::INVALID_HANDLE_VALUE
459
460
  raise Net::SSH::Exception,
460
- "Creation of file mapping failed with error: #{Win.GetLastError}"
461
+ "Creation of file mapping failed with error: #{Win.GetLastError}"
461
462
  end
462
-
463
+
463
464
  ptr = Win.MapViewOfFile(filemap, Win::FILE_MAP_WRITE, 0, 0,
464
465
  0)
465
-
466
+
466
467
  if ptr.nil? || ptr.null?
467
468
  raise Net::SSH::Exception, "Mapping of file failed"
468
469
  end
469
-
470
+
470
471
  Win.set_ptr_data(ptr, query)
471
-
472
+
472
473
  # using struct to achieve proper alignment and field size on 64-bit platform
473
474
  cds = Win::COPYDATASTRUCT.new(Win.malloc_ptr(Win::COPYDATASTRUCT.size))
474
475
  cds.dwData = AGENT_COPYDATA_ID
@@ -476,14 +477,14 @@ module Net
476
477
  cds.lpData = Win.get_cstr(mapname)
477
478
  succ = Win.SendMessageTimeout(@win, Win::WM_COPYDATA, Win::NULL,
478
479
  cds.to_ptr, Win::SMTO_NORMAL, 5000, id)
479
-
480
+
480
481
  if succ > 0
481
482
  retlen = 4 + ptr.to_s(4).unpack("N")[0]
482
483
  res = ptr.to_s(retlen)
483
484
  else
484
485
  raise Net::SSH::Exception, "Message failed with error: #{Win.GetLastError}"
485
486
  end
486
-
487
+
487
488
  return res
488
489
  ensure
489
490
  Win.UnmapViewOfFile(ptr) unless ptr.nil? || ptr.null?
@@ -491,7 +492,6 @@ module Net
491
492
  end
492
493
  end
493
494
  end
494
-
495
495
  end
496
496
  end
497
497
  end
@@ -22,12 +22,12 @@ module Net
22
22
  # returned by OpenSSH's <tt>`ssh-add -l -E SHA256`</tt>, i.e.,
23
23
  # trailing base64 padding '=' characters are stripped and the
24
24
  # literal string +SHA256:+ is prepended.
25
- def fingerprint(algorithm='MD5')
25
+ def fingerprint(algorithm = 'MD5')
26
26
  @fingerprint ||= {}
27
27
  @fingerprint[algorithm] ||= PubKeyFingerprint.fingerprint(to_blob, algorithm)
28
28
  end
29
29
 
30
- def self.fingerprint(blob, algorithm='MD5')
30
+ def self.fingerprint(blob, algorithm = 'MD5')
31
31
  case algorithm.to_s.upcase
32
32
  when 'MD5'
33
33
  OpenSSL::Digest.hexdigest(algorithm, blob).scan(/../).join(":")
@@ -11,7 +11,6 @@ require 'net/ssh/authentication/methods/keyboard_interactive'
11
11
  module Net
12
12
  module SSH
13
13
  module Authentication
14
-
15
14
  # Raised if the current authentication method is not allowed
16
15
  class DisallowedMethod < Net::SSH::Exception
17
16
  end
@@ -42,7 +41,7 @@ module Net
42
41
 
43
42
  # Instantiates a new Authentication::Session object over the given
44
43
  # transport layer abstraction.
45
- def initialize(transport, options={})
44
+ def initialize(transport, options = {})
46
45
  self.logger = transport.logger
47
46
  @transport = transport
48
47
 
@@ -55,7 +54,7 @@ module Net
55
54
  # Attempts to authenticate the given user, in preparation for the next
56
55
  # service request. Returns true if an authentication method succeeds in
57
56
  # authenticating the user, and false otherwise.
58
- def authenticate(next_service, username, password=nil)
57
+ def authenticate(next_service, username, password = nil)
59
58
  debug { "beginning authentication of `#{username}'" }
60
59
 
61
60
  transport.send_message(transport.service_request("ssh-userauth"))
@@ -70,22 +69,23 @@ module Net
70
69
  attempted = []
71
70
 
72
71
  @auth_methods.each do |name|
72
+ next unless @allowed_auth_methods.include?(name)
73
+
74
+ attempted << name
75
+
76
+ debug { "trying #{name}" }
73
77
  begin
74
- next unless @allowed_auth_methods.include?(name)
75
- attempted << name
76
-
77
- debug { "trying #{name}" }
78
- begin
79
- auth_class = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join)
80
- method = auth_class.new(self, key_manager: key_manager, password_prompt: options[:password_prompt])
81
- rescue NameError
82
- debug {"Mechanism #{name} was requested, but isn't a known type. Ignoring it."}
83
- next
84
- end
85
-
86
- return true if method.authenticate(next_service, username, password)
87
- rescue Net::SSH::Authentication::DisallowedMethod
78
+ auth_class = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join)
79
+ method = auth_class.new(self,
80
+ key_manager: key_manager, password_prompt: options[:password_prompt],
81
+ pubkey_algorithms: options[:pubkey_algorithms] || nil)
82
+ rescue NameError
83
+ debug {"Mechanism #{name} was requested, but isn't a known type. Ignoring it."}
84
+ next
88
85
  end
86
+
87
+ return true if method.authenticate(next_service, username, password)
88
+ rescue Net::SSH::Authentication::DisallowedMethod
89
89
  end
90
90
 
91
91
  error { "all authorization methods failed (tried #{attempted.join(', ')})" }
@@ -129,6 +129,7 @@ module Net
129
129
  def expect_message(type)
130
130
  message = next_message
131
131
  raise Net::SSH::Exception, "expected #{type}, got #{message.type} (#{message})" unless message.type == type
132
+
132
133
  message
133
134
  end
134
135