net-ssh 6.2.0.rc2 → 6.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.github/workflows/ci.yml +27 -10
  5. data/.rubocop.yml +11 -1
  6. data/.rubocop_todo.yml +374 -173
  7. data/.travis.yml +10 -11
  8. data/CHANGES.txt +6 -0
  9. data/Gemfile +2 -0
  10. data/Gemfile.noed25519 +2 -0
  11. data/README.md +2 -2
  12. data/Rakefile +1 -0
  13. data/lib/net/ssh.rb +1 -2
  14. data/lib/net/ssh/authentication/agent.rb +4 -2
  15. data/lib/net/ssh/authentication/certificate.rb +3 -1
  16. data/lib/net/ssh/authentication/constants.rb +0 -1
  17. data/lib/net/ssh/authentication/ed25519.rb +6 -2
  18. data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
  19. data/lib/net/ssh/authentication/key_manager.rb +28 -29
  20. data/lib/net/ssh/authentication/methods/abstract.rb +0 -1
  21. data/lib/net/ssh/authentication/methods/hostbased.rb +0 -2
  22. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +1 -1
  23. data/lib/net/ssh/authentication/methods/none.rb +5 -8
  24. data/lib/net/ssh/authentication/methods/password.rb +1 -2
  25. data/lib/net/ssh/authentication/methods/publickey.rb +0 -2
  26. data/lib/net/ssh/authentication/pageant.rb +89 -89
  27. data/lib/net/ssh/authentication/session.rb +14 -15
  28. data/lib/net/ssh/buffer.rb +10 -5
  29. data/lib/net/ssh/buffered_io.rb +18 -19
  30. data/lib/net/ssh/config.rb +29 -16
  31. data/lib/net/ssh/connection/channel.rb +71 -69
  32. data/lib/net/ssh/connection/constants.rb +0 -4
  33. data/lib/net/ssh/connection/event_loop.rb +22 -16
  34. data/lib/net/ssh/connection/keepalive.rb +12 -12
  35. data/lib/net/ssh/connection/session.rb +95 -94
  36. data/lib/net/ssh/connection/term.rb +56 -58
  37. data/lib/net/ssh/errors.rb +10 -10
  38. data/lib/net/ssh/key_factory.rb +0 -1
  39. data/lib/net/ssh/known_hosts.rb +79 -11
  40. data/lib/net/ssh/loggable.rb +8 -9
  41. data/lib/net/ssh/packet.rb +1 -1
  42. data/lib/net/ssh/prompt.rb +8 -10
  43. data/lib/net/ssh/proxy/command.rb +1 -1
  44. data/lib/net/ssh/proxy/errors.rb +2 -4
  45. data/lib/net/ssh/proxy/http.rb +17 -19
  46. data/lib/net/ssh/proxy/https.rb +6 -8
  47. data/lib/net/ssh/proxy/jump.rb +8 -10
  48. data/lib/net/ssh/proxy/socks4.rb +1 -3
  49. data/lib/net/ssh/proxy/socks5.rb +2 -4
  50. data/lib/net/ssh/service/forward.rb +3 -3
  51. data/lib/net/ssh/test.rb +1 -2
  52. data/lib/net/ssh/test/channel.rb +20 -22
  53. data/lib/net/ssh/test/extensions.rb +29 -29
  54. data/lib/net/ssh/test/kex.rb +6 -8
  55. data/lib/net/ssh/test/local_packet.rb +0 -2
  56. data/lib/net/ssh/test/packet.rb +2 -2
  57. data/lib/net/ssh/test/remote_packet.rb +5 -7
  58. data/lib/net/ssh/test/script.rb +21 -23
  59. data/lib/net/ssh/test/socket.rb +11 -14
  60. data/lib/net/ssh/transport/algorithms.rb +2 -1
  61. data/lib/net/ssh/transport/cipher_factory.rb +13 -13
  62. data/lib/net/ssh/transport/constants.rb +3 -3
  63. data/lib/net/ssh/transport/ctr.rb +4 -4
  64. data/lib/net/ssh/transport/hmac/abstract.rb +0 -1
  65. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  66. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  67. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  68. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  69. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  70. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  71. data/lib/net/ssh/transport/identity_cipher.rb +10 -12
  72. data/lib/net/ssh/transport/kex.rb +2 -0
  73. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +1 -0
  74. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
  75. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  76. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +0 -1
  77. data/lib/net/ssh/transport/key_expander.rb +6 -7
  78. data/lib/net/ssh/transport/openssl.rb +6 -11
  79. data/lib/net/ssh/transport/packet_stream.rb +1 -2
  80. data/lib/net/ssh/transport/server_version.rb +17 -16
  81. data/lib/net/ssh/transport/session.rb +3 -1
  82. data/lib/net/ssh/transport/state.rb +42 -42
  83. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  84. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  85. data/lib/net/ssh/verifiers/always.rb +6 -4
  86. data/lib/net/ssh/verifiers/never.rb +0 -2
  87. data/lib/net/ssh/version.rb +2 -2
  88. data/net-ssh-public_cert.pem +8 -8
  89. data/net-ssh.gemspec +2 -2
  90. data/support/ssh_tunnel_bug.rb +3 -3
  91. metadata +14 -13
  92. metadata.gz.sig +0 -0
@@ -6,16 +6,14 @@ require 'net/ssh/connection/constants'
6
6
  require 'net/ssh/transport/constants'
7
7
  require 'net/ssh/transport/packet_stream'
8
8
 
9
- module Net
10
- module SSH
9
+ module Net
10
+ module SSH
11
11
  module Test
12
-
13
12
  # A collection of modules used to extend/override the default behavior of
14
13
  # Net::SSH internals for ease of testing. As a consumer of Net::SSH, you'll
15
14
  # never need to use this directly--they're all used under the covers by
16
15
  # the Net::SSH::Test system.
17
16
  module Extensions
18
-
19
17
  # An extension to Net::SSH::BufferedIo (assumes that the underlying IO
20
18
  # is actually a StringIO). Facilitates unit testing.
21
19
  module BufferedIo
@@ -24,80 +22,82 @@ module Net
24
22
  def select_for_read?
25
23
  pos < size
26
24
  end
27
-
25
+
28
26
  # Set this to +true+ if you want the IO to pretend to be available for writing
29
27
  attr_accessor :select_for_write
30
-
28
+
31
29
  # Set this to +true+ if you want the IO to pretend to be in an error state
32
30
  attr_accessor :select_for_error
33
-
31
+
34
32
  alias select_for_write? select_for_write
35
33
  alias select_for_error? select_for_error
36
34
  end
37
-
35
+
38
36
  # An extension to Net::SSH::Transport::PacketStream (assumes that the
39
37
  # underlying IO is actually a StringIO). Facilitates unit testing.
40
38
  module PacketStream
41
39
  include BufferedIo # make sure we get the extensions here, too
42
-
40
+
43
41
  def self.included(base) #:nodoc:
44
42
  base.send :alias_method, :real_available_for_read?, :available_for_read?
45
43
  base.send :alias_method, :available_for_read?, :test_available_for_read?
46
-
44
+
47
45
  base.send :alias_method, :real_enqueue_packet, :enqueue_packet
48
46
  base.send :alias_method, :enqueue_packet, :test_enqueue_packet
49
-
47
+
50
48
  base.send :alias_method, :real_poll_next_packet, :poll_next_packet
51
49
  base.send :alias_method, :poll_next_packet, :test_poll_next_packet
52
50
  end
53
-
51
+
54
52
  # Called when another packet should be inspected from the current
55
53
  # script. If the next packet is a remote packet, it pops it off the
56
54
  # script and shoves it onto this IO object, making it available to
57
55
  # be read.
58
56
  def idle!
59
57
  return false unless script.next(:first)
60
-
58
+
61
59
  if script.next(:first).remote?
62
60
  self.string << script.next.to_s
63
61
  self.pos = pos
64
62
  end
65
-
63
+
66
64
  return true
67
65
  end
68
-
66
+
69
67
  # The testing version of Net::SSH::Transport::PacketStream#available_for_read?.
70
68
  # Returns true if there is data pending to be read. Otherwise calls #idle!.
71
69
  def test_available_for_read?
72
70
  return true if select_for_read?
71
+
73
72
  idle!
74
73
  false
75
74
  end
76
-
75
+
77
76
  # The testing version of Net::SSH::Transport::PacketStream#enqueued_packet.
78
77
  # Simply calls Net::SSH::Test::Script#process on the packet.
79
78
  def test_enqueue_packet(payload)
80
79
  packet = Net::SSH::Buffer.new(payload.to_s)
81
80
  script.process(packet)
82
81
  end
83
-
82
+
84
83
  # The testing version of Net::SSH::Transport::PacketStream#poll_next_packet.
85
84
  # Reads the next available packet from the IO object and returns it.
86
85
  def test_poll_next_packet
87
86
  return nil if available <= 0
87
+
88
88
  packet = Net::SSH::Buffer.new(read_available(4))
89
89
  length = packet.read_long
90
90
  Net::SSH::Packet.new(read_available(length))
91
91
  end
92
92
  end
93
-
93
+
94
94
  # An extension to Net::SSH::Connection::Channel. Facilitates unit testing.
95
95
  module Channel
96
96
  def self.included(base) #:nodoc:
97
97
  base.send :alias_method, :send_data_for_real, :send_data
98
98
  base.send :alias_method, :send_data, :send_data_for_test
99
99
  end
100
-
100
+
101
101
  # The testing version of Net::SSH::Connection::Channel#send_data. Calls
102
102
  # the original implementation, and then immediately enqueues the data for
103
103
  # output so that scripted sends are properly interpreted as discrete
@@ -107,16 +107,16 @@ module Net
107
107
  enqueue_pending_output
108
108
  end
109
109
  end
110
-
110
+
111
111
  # An extension to the built-in ::IO class. Simply redefines IO.select
112
112
  # so that it can be scripted in Net::SSH unit tests.
113
113
  module IO
114
114
  def self.included(base) #:nodoc:
115
115
  base.extend(ClassMethods)
116
116
  end
117
-
117
+
118
118
  @extension_enabled = false
119
-
119
+
120
120
  def self.with_test_extension(&block)
121
121
  orig_value = @extension_enabled
122
122
  @extension_enabled = true
@@ -126,11 +126,11 @@ module Net
126
126
  @extension_enabled = orig_value
127
127
  end
128
128
  end
129
-
129
+
130
130
  def self.extension_enabled?
131
131
  @extension_enabled
132
132
  end
133
-
133
+
134
134
  module ClassMethods
135
135
  def self.extended(obj) #:nodoc:
136
136
  class <<obj
@@ -138,23 +138,24 @@ module Net
138
138
  alias_method :select, :select_for_test
139
139
  end
140
140
  end
141
-
141
+
142
142
  # The testing version of ::IO.select. Assumes that all readers,
143
143
  # writers, and errors arrays are either nil, or contain only objects
144
144
  # that mix in Net::SSH::Test::Extensions::BufferedIo.
145
145
  def select_for_test(readers=nil, writers=nil, errors=nil, wait=nil)
146
146
  return select_for_real(readers, writers, errors, wait) unless Net::SSH::Test::Extensions::IO.extension_enabled?
147
+
147
148
  ready_readers = Array(readers).select { |r| r.select_for_read? }
148
149
  ready_writers = Array(writers).select { |r| r.select_for_write? }
149
150
  ready_errors = Array(errors).select { |r| r.select_for_error? }
150
-
151
+
151
152
  return [ready_readers, ready_writers, ready_errors] if ready_readers.any? || ready_writers.any? || ready_errors.any?
152
-
153
+
153
154
  processed = 0
154
155
  Array(readers).each do |reader|
155
156
  processed += 1 if reader.idle!
156
157
  end
157
-
158
+
158
159
  raise "no readers were ready for reading, and none had any incoming packets" if processed == 0 && wait != 0
159
160
 
160
161
  [[], [], []]
@@ -162,7 +163,6 @@ module Net
162
163
  end
163
164
  end
164
165
  end
165
-
166
166
  end
167
167
  end
168
168
  end
@@ -5,10 +5,9 @@ require 'net/ssh/transport/algorithms'
5
5
  require 'net/ssh/transport/constants'
6
6
  require 'net/ssh/transport/kex'
7
7
 
8
- module Net
9
- module SSH
8
+ module Net
9
+ module SSH
10
10
  module Test
11
-
12
11
  # An implementation of a key-exchange strategy specifically for unit tests.
13
12
  # (This strategy would never really work against a real SSH server--it makes
14
13
  # too many assumptions about the server's response.)
@@ -17,29 +16,28 @@ module Net
17
16
  # "test" algorithm.
18
17
  class Kex
19
18
  include Net::SSH::Transport::Constants
20
-
19
+
21
20
  # Creates a new instance of the testing key-exchange algorithm with the
22
21
  # given arguments.
23
22
  def initialize(algorithms, connection, data)
24
23
  @connection = connection
25
24
  end
26
-
25
+
27
26
  # Exchange keys with the server. This returns a hash of constant values,
28
27
  # and does not actually exchange keys.
29
28
  def exchange_keys
30
29
  result = Net::SSH::Buffer.from(:byte, NEWKEYS)
31
30
  @connection.send_message(result)
32
-
31
+
33
32
  buffer = @connection.next_message
34
33
  raise Net::SSH::Exception, "expected NEWKEYS" unless buffer.type == NEWKEYS
35
-
34
+
36
35
  { session_id: "abc-xyz",
37
36
  server_key: OpenSSL::PKey::RSA.new(512),
38
37
  shared_secret: OpenSSL::BN.new("1234567890", 10),
39
38
  hashing_algorithm: OpenSSL::Digest::SHA1 }
40
39
  end
41
40
  end
42
-
43
41
  end
44
42
  end
45
43
  end
@@ -4,7 +4,6 @@ require 'net/ssh/test/packet'
4
4
  module Net
5
5
  module SSH
6
6
  module Test
7
-
8
7
  # This is a specialization of Net::SSH::Test::Packet for representing mock
9
8
  # packets that are sent from the local (client) host. These are created
10
9
  # automatically by Net::SSH::Test::Script and Net::SSH::Test::Channel by any
@@ -49,7 +48,6 @@ module Net
49
48
  end
50
49
  end
51
50
  end
52
-
53
51
  end
54
52
  end
55
53
  end
@@ -4,7 +4,6 @@ require 'net/ssh/transport/constants'
4
4
  module Net
5
5
  module SSH
6
6
  module Test
7
-
8
7
  # This is an abstract class, not to be instantiated directly, subclassed by
9
8
  # Net::SSH::Test::LocalPacket and Net::SSH::Test::RemotePacket. It implements
10
9
  # functionality common to those subclasses.
@@ -70,7 +69,7 @@ module Net
70
69
  # added. Unsupported packet types will otherwise raise an exception.
71
70
  def types
72
71
  @types ||= case @type
73
- when KEXINIT then
72
+ when KEXINIT
74
73
  %i[long long long long
75
74
  string string string string string string string string string string
76
75
  bool]
@@ -90,6 +89,7 @@ module Net
90
89
  else
91
90
  request = Packet.registered_channel_requests(@data[1])
92
91
  raise "don't know what to do about #{@data[1]} channel request" unless request
92
+
93
93
  parts.concat(request[:extra_parts])
94
94
  end
95
95
  else raise "don't know how to parse packet type #{@type}"
@@ -1,10 +1,9 @@
1
1
  require 'net/ssh/buffer'
2
2
  require 'net/ssh/test/packet'
3
3
 
4
- module Net
5
- module SSH
4
+ module Net
5
+ module SSH
6
6
  module Test
7
-
8
7
  # This is a specialization of Net::SSH::Test::Packet for representing mock
9
8
  # packets that are received by the local (client) host. These are created
10
9
  # automatically by Net::SSH::Test::Script and Net::SSH::Test::Channel by any
@@ -14,7 +13,7 @@ module Net
14
13
  def remote?
15
14
  true
16
15
  end
17
-
16
+
18
17
  # The #process method should only be called on Net::SSH::Test::LocalPacket
19
18
  # packets; if it is attempted on a remote packet, then it is an expectation
20
19
  # mismatch (a remote packet was received when a local packet was expected
@@ -23,8 +22,8 @@ module Net
23
22
  def process(packet)
24
23
  raise "received packet type #{packet.read_byte} and was not expecting any packet"
25
24
  end
26
-
27
- # Returns this remote packet as a string, suitable for parsing by
25
+
26
+ # Returns this remote packet as a string, suitable for parsing by
28
27
  # Net::SSH::Transport::PacketStream and friends. When a remote packet is
29
28
  # received, this method is called and the result concatenated onto the
30
29
  # input buffer for the packet stream.
@@ -36,7 +35,6 @@ module Net
36
35
  end
37
36
  end
38
37
  end
39
-
40
38
  end
41
39
  end
42
40
  end
@@ -2,10 +2,9 @@ require 'net/ssh/test/channel'
2
2
  require 'net/ssh/test/local_packet'
3
3
  require 'net/ssh/test/remote_packet'
4
4
 
5
- module Net
6
- module SSH
5
+ module Net
6
+ module SSH
7
7
  module Test
8
-
9
8
  # Represents a sequence of scripted events that identify the behavior that
10
9
  # a test expects. Methods named "sends_*" create events for packets being
11
10
  # sent from the local to the remote host, and methods named "gets_*" create
@@ -22,12 +21,12 @@ module Net
22
21
  # The list of scripted events. These will be Net::SSH::Test::LocalPacket
23
22
  # and Net::SSH::Test::RemotePacket instances.
24
23
  attr_reader :events
25
-
24
+
26
25
  # Create a new, empty script.
27
26
  def initialize
28
27
  @events = []
29
28
  end
30
-
29
+
31
30
  # Scripts the opening of a channel by adding a local packet sending the
32
31
  # channel open request, and if +confirm+ is true (the default), also
33
32
  # adding a remote packet confirming the new channel.
@@ -37,26 +36,26 @@ module Net
37
36
  def opens_channel(confirm=true)
38
37
  channel = Channel.new(self)
39
38
  channel.remote_id = 5555
40
-
39
+
41
40
  events << LocalPacket.new(:channel_open) { |p| channel.local_id = p[:remote_id] }
42
-
41
+
43
42
  events << RemotePacket.new(:channel_open_confirmation, channel.local_id, channel.remote_id, 0x20000, 0x10000) if confirm
44
-
43
+
45
44
  channel
46
45
  end
47
-
46
+
48
47
  # A convenience method for adding an arbitrary local packet to the events
49
48
  # list.
50
49
  def sends(type, *args, &block)
51
50
  events << LocalPacket.new(type, *args, &block)
52
51
  end
53
-
52
+
54
53
  # A convenience method for adding an arbitrary remote packet to the events
55
54
  # list.
56
55
  def gets(type, *args)
57
56
  events << RemotePacket.new(type, *args)
58
57
  end
59
-
58
+
60
59
  # Scripts the sending of a new channel request packet to the remote host.
61
60
  # +channel+ should be an instance of Net::SSH::Test::Channel. +request+
62
61
  # is a string naming the request type to send, +reply+ is a boolean
@@ -85,7 +84,7 @@ module Net
85
84
  end
86
85
  end
87
86
  end
88
-
87
+
89
88
  # Scripts the sending of a channel data packet. +channel+ must be a
90
89
  # Net::SSH::Test::Channel object, and +data+ is the (string) data to
91
90
  # expect will be sent.
@@ -94,21 +93,21 @@ module Net
94
93
  def sends_channel_data(channel, data)
95
94
  events << LocalPacket.new(:channel_data, channel.remote_id, data)
96
95
  end
97
-
96
+
98
97
  # Scripts the sending of a channel EOF packet from the given
99
98
  # Net::SSH::Test::Channel +channel+. This will typically be called via
100
99
  # Net::SSH::Test::Channel#sends_eof.
101
100
  def sends_channel_eof(channel)
102
101
  events << LocalPacket.new(:channel_eof, channel.remote_id)
103
102
  end
104
-
103
+
105
104
  # Scripts the sending of a channel close packet from the given
106
105
  # Net::SSH::Test::Channel +channel+. This will typically be called via
107
106
  # Net::SSH::Test::Channel#sends_close.
108
107
  def sends_channel_close(channel)
109
108
  events << LocalPacket.new(:channel_close, channel.remote_id)
110
109
  end
111
-
110
+
112
111
  # Scripts the sending of a channel request pty packets from the given
113
112
  # Net::SSH::Test::Channel +channel+. This will typically be called via
114
113
  # Net::SSH::Test::Channel#sends_request_pty.
@@ -117,14 +116,14 @@ module Net
117
116
  data += Net::SSH::Connection::Channel::VALID_PTY_OPTIONS.merge(modes: "\0").values
118
117
  events << LocalPacket.new(:channel_request, channel.remote_id, *data)
119
118
  end
120
-
119
+
121
120
  # Scripts the reception of a channel data packet from the remote host by
122
121
  # the given Net::SSH::Test::Channel +channel+. This will typically be
123
122
  # called via Net::SSH::Test::Channel#gets_data.
124
123
  def gets_channel_data(channel, data)
125
124
  events << RemotePacket.new(:channel_data, channel.local_id, data)
126
125
  end
127
-
126
+
128
127
  # Scripts the reception of a channel extended data packet from the remote
129
128
  # host by the given Net::SSH::Test::Channel +channel+. This will typically
130
129
  # be called via Net::SSH::Test::Channel#gets_extended_data.
@@ -133,28 +132,28 @@ module Net
133
132
  def gets_channel_extended_data(channel, data)
134
133
  events << RemotePacket.new(:channel_extended_data, channel.local_id, 1, data)
135
134
  end
136
-
135
+
137
136
  # Scripts the reception of a channel request packet from the remote host by
138
137
  # the given Net::SSH::Test::Channel +channel+. This will typically be
139
138
  # called via Net::SSH::Test::Channel#gets_exit_status.
140
139
  def gets_channel_request(channel, request, reply, data)
141
140
  events << RemotePacket.new(:channel_request, channel.local_id, request, reply, data)
142
141
  end
143
-
142
+
144
143
  # Scripts the reception of a channel EOF packet from the remote host by
145
144
  # the given Net::SSH::Test::Channel +channel+. This will typically be
146
145
  # called via Net::SSH::Test::Channel#gets_eof.
147
146
  def gets_channel_eof(channel)
148
147
  events << RemotePacket.new(:channel_eof, channel.local_id)
149
148
  end
150
-
149
+
151
150
  # Scripts the reception of a channel close packet from the remote host by
152
151
  # the given Net::SSH::Test::Channel +channel+. This will typically be
153
152
  # called via Net::SSH::Test::Channel#gets_close.
154
153
  def gets_channel_close(channel)
155
154
  events << RemotePacket.new(:channel_close, channel.local_id)
156
155
  end
157
-
156
+
158
157
  # By default, removes the next event in the list and returns it. However,
159
158
  # this can also be used to non-destructively peek at the next event in the
160
159
  # list, by passing :first as the argument.
@@ -167,7 +166,7 @@ module Net
167
166
  def next(mode=:shift)
168
167
  events.send(mode)
169
168
  end
170
-
169
+
171
170
  # Compare the given packet against the next event in the list. If there is
172
171
  # no next event, an exception will be raised. This is called by
173
172
  # Net::SSH::Test::Extensions::PacketStream#test_enqueue_packet.
@@ -176,7 +175,6 @@ module Net
176
175
  event.process(packet)
177
176
  end
178
177
  end
179
-
180
178
  end
181
179
  end
182
180
  end