net-ssh 5.0.2 → 7.0.1

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.
Files changed (122) 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 +3 -0
  9. data/.rubocop.yml +19 -2
  10. data/.rubocop_todo.yml +623 -511
  11. data/CHANGES.txt +76 -0
  12. data/Dockerfile +27 -0
  13. data/Dockerfile.openssl3 +17 -0
  14. data/Gemfile +2 -0
  15. data/Gemfile.noed25519 +2 -0
  16. data/Manifest +0 -1
  17. data/README.md +293 -0
  18. data/Rakefile +6 -2
  19. data/appveyor.yml +4 -2
  20. data/docker-compose.yml +23 -0
  21. data/lib/net/ssh/authentication/agent.rb +36 -14
  22. data/lib/net/ssh/authentication/certificate.rb +19 -7
  23. data/lib/net/ssh/authentication/constants.rb +0 -1
  24. data/lib/net/ssh/authentication/ed25519.rb +83 -50
  25. data/lib/net/ssh/authentication/ed25519_loader.rb +5 -8
  26. data/lib/net/ssh/authentication/key_manager.rb +74 -33
  27. data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
  28. data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
  29. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +5 -3
  30. data/lib/net/ssh/authentication/methods/none.rb +6 -9
  31. data/lib/net/ssh/authentication/methods/password.rb +2 -3
  32. data/lib/net/ssh/authentication/methods/publickey.rb +58 -16
  33. data/lib/net/ssh/authentication/pageant.rb +97 -97
  34. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +2 -3
  35. data/lib/net/ssh/authentication/session.rb +27 -23
  36. data/lib/net/ssh/buffer.rb +91 -40
  37. data/lib/net/ssh/buffered_io.rb +24 -26
  38. data/lib/net/ssh/config.rb +99 -53
  39. data/lib/net/ssh/connection/channel.rb +101 -87
  40. data/lib/net/ssh/connection/constants.rb +0 -4
  41. data/lib/net/ssh/connection/event_loop.rb +30 -25
  42. data/lib/net/ssh/connection/keepalive.rb +12 -12
  43. data/lib/net/ssh/connection/session.rb +115 -111
  44. data/lib/net/ssh/connection/term.rb +56 -58
  45. data/lib/net/ssh/errors.rb +12 -12
  46. data/lib/net/ssh/key_factory.rb +108 -22
  47. data/lib/net/ssh/known_hosts.rb +120 -36
  48. data/lib/net/ssh/loggable.rb +10 -11
  49. data/lib/net/ssh/packet.rb +1 -1
  50. data/lib/net/ssh/prompt.rb +9 -11
  51. data/lib/net/ssh/proxy/command.rb +1 -2
  52. data/lib/net/ssh/proxy/errors.rb +2 -4
  53. data/lib/net/ssh/proxy/http.rb +18 -20
  54. data/lib/net/ssh/proxy/https.rb +8 -10
  55. data/lib/net/ssh/proxy/jump.rb +8 -10
  56. data/lib/net/ssh/proxy/socks4.rb +2 -4
  57. data/lib/net/ssh/proxy/socks5.rb +3 -6
  58. data/lib/net/ssh/service/forward.rb +9 -8
  59. data/lib/net/ssh/test/channel.rb +24 -26
  60. data/lib/net/ssh/test/extensions.rb +37 -35
  61. data/lib/net/ssh/test/kex.rb +6 -8
  62. data/lib/net/ssh/test/local_packet.rb +0 -2
  63. data/lib/net/ssh/test/packet.rb +3 -3
  64. data/lib/net/ssh/test/remote_packet.rb +6 -8
  65. data/lib/net/ssh/test/script.rb +25 -27
  66. data/lib/net/ssh/test/socket.rb +12 -15
  67. data/lib/net/ssh/test.rb +12 -12
  68. data/lib/net/ssh/transport/algorithms.rb +177 -118
  69. data/lib/net/ssh/transport/cipher_factory.rb +34 -50
  70. data/lib/net/ssh/transport/constants.rb +13 -9
  71. data/lib/net/ssh/transport/ctr.rb +8 -14
  72. data/lib/net/ssh/transport/hmac/abstract.rb +20 -5
  73. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  74. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  75. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  76. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  77. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  78. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  79. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  80. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  81. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  82. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  83. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  84. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  85. data/lib/net/ssh/transport/hmac.rb +13 -11
  86. data/lib/net/ssh/transport/identity_cipher.rb +11 -13
  87. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  88. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  89. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  90. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  91. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +5 -19
  92. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  93. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +30 -139
  94. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -8
  95. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  96. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +20 -81
  97. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +5 -4
  98. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +5 -4
  99. data/lib/net/ssh/transport/kex.rb +15 -10
  100. data/lib/net/ssh/transport/key_expander.rb +7 -8
  101. data/lib/net/ssh/transport/openssl.rb +149 -111
  102. data/lib/net/ssh/transport/packet_stream.rb +53 -22
  103. data/lib/net/ssh/transport/server_version.rb +17 -16
  104. data/lib/net/ssh/transport/session.rb +35 -11
  105. data/lib/net/ssh/transport/state.rb +44 -44
  106. data/lib/net/ssh/verifiers/accept_new.rb +7 -2
  107. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  108. data/lib/net/ssh/verifiers/always.rb +10 -4
  109. data/lib/net/ssh/verifiers/never.rb +4 -2
  110. data/lib/net/ssh/version.rb +2 -2
  111. data/lib/net/ssh.rb +17 -9
  112. data/net-ssh-public_cert.pem +18 -19
  113. data/net-ssh.gemspec +9 -7
  114. data/support/ssh_tunnel_bug.rb +3 -3
  115. data.tar.gz.sig +0 -0
  116. metadata +65 -41
  117. metadata.gz.sig +0 -0
  118. data/.travis.yml +0 -52
  119. data/Gemfile.noed25519.lock +0 -41
  120. data/README.rdoc +0 -169
  121. data/lib/net/ssh/ruby_compat.rb +0 -13
  122. data/support/arcfour_check.rb +0 -20
@@ -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,41 +21,41 @@ 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.
34
33
  #
35
34
  # A new Net::SSH::Test::Channel instance is returned, which can be used
36
35
  # to script additional channel operations.
37
- def opens_channel(confirm=true)
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
@@ -71,7 +70,7 @@ module Net
71
70
  #
72
71
  # This will typically be called via Net::SSH::Test::Channel#sends_exec or
73
72
  # Net::SSH::Test::Channel#sends_subsystem.
74
- def sends_channel_request(channel, request, reply, data, success=true)
73
+ def sends_channel_request(channel, request, reply, data, success = true)
75
74
  if data.is_a? Array
76
75
  events << LocalPacket.new(:channel_request, channel.remote_id, request, reply, *data)
77
76
  else
@@ -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.
@@ -164,10 +163,10 @@ module Net
164
163
  #
165
164
  # # peek at the next event
166
165
  # event = script.next(:first)
167
- def next(mode=:shift)
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
- end
180
+ end
@@ -3,66 +3,63 @@ require 'stringio'
3
3
  require 'net/ssh/test/extensions'
4
4
  require 'net/ssh/test/script'
5
5
 
6
- module Net
7
- module SSH
6
+ module Net
7
+ module SSH
8
8
  module Test
9
-
10
9
  # A mock socket implementation for use in testing. It implements the minimum
11
10
  # necessary interface for interacting with the rest of the Net::SSH::Test
12
11
  # system.
13
12
  class Socket < StringIO
14
13
  attr_reader :host, :port
15
-
14
+
16
15
  # The Net::SSH::Test::Script object in use by this socket. This is the
17
16
  # canonical script instance that should be used for any test depending on
18
17
  # this socket instance.
19
18
  attr_reader :script
20
-
19
+
21
20
  # Create a new test socket. This will also instantiate a new Net::SSH::Test::Script
22
21
  # and seed it with the necessary events to power the initialization of the
23
22
  # connection.
24
23
  def initialize
25
24
  extend(Net::SSH::Transport::PacketStream)
26
25
  super "SSH-2.0-Test\r\n"
27
-
26
+
28
27
  @script = Script.new
29
-
28
+
30
29
  script.sends(:kexinit)
31
30
  script.gets(:kexinit, 1, 2, 3, 4, "test", "ssh-rsa", "none", "none", "none", "none", "none", "none", "", "", false)
32
31
  script.sends(:newkeys)
33
32
  script.gets(:newkeys)
34
33
  end
35
-
34
+
36
35
  # This doesn't actually do anything, since we don't really care what gets
37
36
  # written.
38
37
  def write(data)
39
38
  # black hole, because we don't actually care about what gets written
40
39
  end
41
-
40
+
42
41
  # Allows the socket to also mimic a socket factory, simply returning
43
42
  # +self+.
44
- def open(host, port, options={})
43
+ def open(host, port, options = {})
45
44
  @host, @port = host, port
46
45
  self
47
46
  end
48
-
47
+
49
48
  # Returns a sockaddr struct for the port and host that were used when the
50
49
  # socket was instantiated.
51
50
  def getpeername
52
51
  ::Socket.sockaddr_in(port, host)
53
52
  end
54
-
53
+
55
54
  # Alias to #read, but never returns nil (returns an empty string instead).
56
55
  def recv(n)
57
56
  read(n) || ""
58
57
  end
59
-
58
+
60
59
  def readpartial(n)
61
60
  recv(n)
62
61
  end
63
-
64
62
  end
65
-
66
63
  end
67
64
  end
68
65
  end
data/lib/net/ssh/test.rb CHANGED
@@ -3,9 +3,8 @@ require 'net/ssh/connection/session'
3
3
  require 'net/ssh/test/kex'
4
4
  require 'net/ssh/test/socket'
5
5
 
6
- module Net
6
+ module Net
7
7
  module SSH
8
-
9
8
  # This module may be used in unit tests, for when you want to test that your
10
9
  # SSH state machines are really doing what you expect they are doing. You will
11
10
  # typically include this module in your unit test class, and then build a
@@ -54,30 +53,30 @@ module Net
54
53
  Net::SSH::Test::Extensions::IO.with_test_extension { yield socket.script if block_given? }
55
54
  return socket.script
56
55
  end
57
-
56
+
58
57
  # Returns the test socket instance to use for these tests (see
59
58
  # Net::SSH::Test::Socket).
60
- def socket(options={})
59
+ def socket(options = {})
61
60
  @socket ||= Net::SSH::Test::Socket.new
62
61
  end
63
-
62
+
64
63
  # Returns the connection session (Net::SSH::Connection::Session) for use
65
64
  # in these tests. It is a fully functional SSH session, operating over
66
65
  # a mock socket (#socket).
67
- def connection(options={})
66
+ def connection(options = {})
68
67
  @connection ||= Net::SSH::Connection::Session.new(transport(options), options)
69
68
  end
70
-
69
+
71
70
  # Returns the transport session (Net::SSH::Transport::Session) for use
72
71
  # in these tests. It is a fully functional SSH transport session, operating
73
72
  # over a mock socket (#socket).
74
- def transport(options={})
73
+ def transport(options = {})
75
74
  @transport ||= Net::SSH::Transport::Session.new(
76
75
  options[:host] || "localhost",
77
- options.merge(kex: "test", host_key: "ssh-rsa", verify_host_key: false, proxy: socket(options))
76
+ options.merge(kex: "test", host_key: "ssh-rsa", append_all_supported_algorithms: true, verify_host_key: :never, proxy: socket(options))
78
77
  )
79
78
  end
80
-
79
+
81
80
  # First asserts that a story has been described (see #story). Then yields,
82
81
  # and then asserts that all items described in the script have been
83
82
  # processed. Typically, this is called immediately after a story has
@@ -85,10 +84,11 @@ module Net
85
84
  # the block passed to this assertion.
86
85
  def assert_scripted
87
86
  raise "there is no script to be processed" if socket.script.events.empty?
87
+
88
88
  Net::SSH::Test::Extensions::IO.with_test_extension { yield }
89
- assert socket.script.events.empty?, "there should not be any remaining scripted events, but there are still #{socket.script.events.length} pending"
89
+ assert socket.script.events.empty?, "there should not be any remaining scripted events, but there are still" \
90
+ "#{socket.script.events.length} pending"
90
91
  end
91
92
  end
92
-
93
93
  end
94
94
  end