net-ssh 5.0.2 → 7.0.1
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/.dockerignore +6 -0
- data/.github/config/rubocop_linter_action.yml +4 -0
- data/.github/workflows/ci-with-docker.yml +44 -0
- data/.github/workflows/ci.yml +87 -0
- data/.github/workflows/rubocop.yml +13 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +19 -2
- data/.rubocop_todo.yml +623 -511
- data/CHANGES.txt +76 -0
- data/Dockerfile +27 -0
- data/Dockerfile.openssl3 +17 -0
- data/Gemfile +2 -0
- data/Gemfile.noed25519 +2 -0
- data/Manifest +0 -1
- data/README.md +293 -0
- data/Rakefile +6 -2
- data/appveyor.yml +4 -2
- data/docker-compose.yml +23 -0
- data/lib/net/ssh/authentication/agent.rb +36 -14
- data/lib/net/ssh/authentication/certificate.rb +19 -7
- data/lib/net/ssh/authentication/constants.rb +0 -1
- data/lib/net/ssh/authentication/ed25519.rb +83 -50
- data/lib/net/ssh/authentication/ed25519_loader.rb +5 -8
- data/lib/net/ssh/authentication/key_manager.rb +74 -33
- data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
- data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
- data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +5 -3
- data/lib/net/ssh/authentication/methods/none.rb +6 -9
- data/lib/net/ssh/authentication/methods/password.rb +2 -3
- data/lib/net/ssh/authentication/methods/publickey.rb +58 -16
- data/lib/net/ssh/authentication/pageant.rb +97 -97
- data/lib/net/ssh/authentication/pub_key_fingerprint.rb +2 -3
- data/lib/net/ssh/authentication/session.rb +27 -23
- data/lib/net/ssh/buffer.rb +91 -40
- data/lib/net/ssh/buffered_io.rb +24 -26
- data/lib/net/ssh/config.rb +99 -53
- data/lib/net/ssh/connection/channel.rb +101 -87
- data/lib/net/ssh/connection/constants.rb +0 -4
- data/lib/net/ssh/connection/event_loop.rb +30 -25
- data/lib/net/ssh/connection/keepalive.rb +12 -12
- data/lib/net/ssh/connection/session.rb +115 -111
- data/lib/net/ssh/connection/term.rb +56 -58
- data/lib/net/ssh/errors.rb +12 -12
- data/lib/net/ssh/key_factory.rb +108 -22
- data/lib/net/ssh/known_hosts.rb +120 -36
- data/lib/net/ssh/loggable.rb +10 -11
- data/lib/net/ssh/packet.rb +1 -1
- data/lib/net/ssh/prompt.rb +9 -11
- data/lib/net/ssh/proxy/command.rb +1 -2
- data/lib/net/ssh/proxy/errors.rb +2 -4
- data/lib/net/ssh/proxy/http.rb +18 -20
- data/lib/net/ssh/proxy/https.rb +8 -10
- data/lib/net/ssh/proxy/jump.rb +8 -10
- data/lib/net/ssh/proxy/socks4.rb +2 -4
- data/lib/net/ssh/proxy/socks5.rb +3 -6
- data/lib/net/ssh/service/forward.rb +9 -8
- data/lib/net/ssh/test/channel.rb +24 -26
- data/lib/net/ssh/test/extensions.rb +37 -35
- data/lib/net/ssh/test/kex.rb +6 -8
- data/lib/net/ssh/test/local_packet.rb +0 -2
- data/lib/net/ssh/test/packet.rb +3 -3
- data/lib/net/ssh/test/remote_packet.rb +6 -8
- data/lib/net/ssh/test/script.rb +25 -27
- data/lib/net/ssh/test/socket.rb +12 -15
- data/lib/net/ssh/test.rb +12 -12
- data/lib/net/ssh/transport/algorithms.rb +177 -118
- data/lib/net/ssh/transport/cipher_factory.rb +34 -50
- data/lib/net/ssh/transport/constants.rb +13 -9
- data/lib/net/ssh/transport/ctr.rb +8 -14
- data/lib/net/ssh/transport/hmac/abstract.rb +20 -5
- data/lib/net/ssh/transport/hmac/md5.rb +0 -2
- data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
- data/lib/net/ssh/transport/hmac/none.rb +0 -2
- data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
- data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
- data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
- data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
- data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
- data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
- data/lib/net/ssh/transport/hmac.rb +13 -11
- data/lib/net/ssh/transport/identity_cipher.rb +11 -13
- data/lib/net/ssh/transport/kex/abstract.rb +130 -0
- data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
- data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
- data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +5 -19
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +30 -139
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -8
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +20 -81
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +5 -4
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +5 -4
- data/lib/net/ssh/transport/kex.rb +15 -10
- data/lib/net/ssh/transport/key_expander.rb +7 -8
- data/lib/net/ssh/transport/openssl.rb +149 -111
- data/lib/net/ssh/transport/packet_stream.rb +53 -22
- data/lib/net/ssh/transport/server_version.rb +17 -16
- data/lib/net/ssh/transport/session.rb +35 -11
- data/lib/net/ssh/transport/state.rb +44 -44
- data/lib/net/ssh/verifiers/accept_new.rb +7 -2
- data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
- data/lib/net/ssh/verifiers/always.rb +10 -4
- data/lib/net/ssh/verifiers/never.rb +4 -2
- data/lib/net/ssh/version.rb +2 -2
- data/lib/net/ssh.rb +17 -9
- data/net-ssh-public_cert.pem +18 -19
- data/net-ssh.gemspec +9 -7
- data/support/ssh_tunnel_bug.rb +3 -3
- data.tar.gz.sig +0 -0
- metadata +65 -41
- metadata.gz.sig +0 -0
- data/.travis.yml +0 -52
- data/Gemfile.noed25519.lock +0 -41
- data/README.rdoc +0 -169
- data/lib/net/ssh/ruby_compat.rb +0 -13
- data/support/arcfour_check.rb +0 -20
data/lib/net/ssh/test/script.rb
CHANGED
@@ -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
|
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
|
data/lib/net/ssh/test/socket.rb
CHANGED
@@ -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:
|
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
|
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
|