net-ssh 5.2.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +7 -4
- data/.rubocop_todo.yml +392 -379
- data/.travis.yml +16 -17
- data/CHANGES.txt +11 -0
- data/Manifest +0 -1
- data/README.md +286 -0
- data/Rakefile +1 -2
- data/appveyor.yml +4 -2
- data/lib/net/ssh.rb +7 -2
- data/lib/net/ssh/authentication/certificate.rb +10 -1
- data/lib/net/ssh/authentication/ed25519.rb +2 -1
- data/lib/net/ssh/authentication/ed25519_loader.rb +1 -1
- data/lib/net/ssh/authentication/key_manager.rb +34 -5
- data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +3 -1
- data/lib/net/ssh/authentication/pub_key_fingerprint.rb +0 -1
- data/lib/net/ssh/authentication/session.rb +9 -6
- data/lib/net/ssh/buffer.rb +1 -10
- data/lib/net/ssh/buffered_io.rb +0 -1
- data/lib/net/ssh/config.rb +51 -32
- data/lib/net/ssh/connection/channel.rb +17 -5
- data/lib/net/ssh/connection/event_loop.rb +0 -1
- data/lib/net/ssh/connection/session.rb +7 -4
- data/lib/net/ssh/key_factory.rb +6 -8
- data/lib/net/ssh/known_hosts.rb +27 -29
- data/lib/net/ssh/loggable.rb +2 -2
- data/lib/net/ssh/proxy/command.rb +0 -1
- data/lib/net/ssh/proxy/socks5.rb +0 -1
- data/lib/net/ssh/service/forward.rb +2 -1
- data/lib/net/ssh/test.rb +3 -2
- data/lib/net/ssh/transport/algorithms.rb +67 -42
- data/lib/net/ssh/transport/cipher_factory.rb +11 -27
- data/lib/net/ssh/transport/constants.rb +10 -6
- data/lib/net/ssh/transport/ctr.rb +1 -7
- data/lib/net/ssh/transport/hmac.rb +15 -13
- data/lib/net/ssh/transport/hmac/abstract.rb +16 -0
- 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/kex.rb +14 -11
- data/lib/net/ssh/transport/kex/abstract.rb +123 -0
- data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
- data/lib/net/ssh/transport/kex/curve25519_sha256.rb +38 -0
- data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +1 -15
- data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +9 -118
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +0 -6
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +18 -79
- 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/openssl.rb +104 -107
- data/lib/net/ssh/transport/packet_stream.rb +44 -11
- data/lib/net/ssh/transport/state.rb +1 -1
- data/lib/net/ssh/version.rb +2 -2
- data/net-ssh-public_cert.pem +8 -8
- data/net-ssh.gemspec +9 -7
- metadata +46 -29
- metadata.gz.sig +2 -3
- data/Gemfile.noed25519.lock +0 -41
- data/README.rdoc +0 -194
- data/lib/net/ssh/ruby_compat.rb +0 -13
- data/support/arcfour_check.rb +0 -20
data/lib/net/ssh/known_hosts.rb
CHANGED
@@ -41,14 +41,11 @@ module Net
|
|
41
41
|
# This is used internally by Net::SSH, and will never need to be used directly
|
42
42
|
# by consumers of the library.
|
43
43
|
class KnownHosts
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
else
|
50
|
-
SUPPORTED_TYPE = %w[ssh-rsa ssh-dss]
|
51
|
-
end
|
44
|
+
SUPPORTED_TYPE = %w[ssh-rsa ssh-dss
|
45
|
+
ecdsa-sha2-nistp256
|
46
|
+
ecdsa-sha2-nistp384
|
47
|
+
ecdsa-sha2-nistp521]
|
48
|
+
|
52
49
|
SUPPORTED_TYPE.push('ssh-ed25519') if Net::SSH::Authentication::ED25519Loader::LOADED
|
53
50
|
|
54
51
|
class <<self
|
@@ -78,7 +75,9 @@ module Net
|
|
78
75
|
|
79
76
|
files += Array(options[:user_known_hosts_file] || %w[~/.ssh/known_hosts ~/.ssh/known_hosts2]) if which == :all || which == :user
|
80
77
|
|
81
|
-
|
78
|
+
if which == :all || which == :global
|
79
|
+
files += Array(options[:global_known_hosts_file] || %w[/etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2])
|
80
|
+
end
|
82
81
|
|
83
82
|
return files
|
84
83
|
end
|
@@ -130,27 +129,22 @@ module Net
|
|
130
129
|
host_ip = entries[1]
|
131
130
|
|
132
131
|
File.open(source) do |file|
|
133
|
-
scanner = StringScanner.new("")
|
134
132
|
file.each_line do |line|
|
135
|
-
|
133
|
+
hosts, type, key_content = line.split(' ')
|
134
|
+
# Skip empty line or one that is commented
|
135
|
+
next if hosts.nil? || hosts.start_with?('#')
|
136
136
|
|
137
|
-
|
138
|
-
|
137
|
+
hostlist = hosts.split(',')
|
138
|
+
|
139
|
+
next unless SUPPORTED_TYPE.include?(type)
|
139
140
|
|
140
|
-
hostlist = scanner.scan(/\S+/).split(/,/)
|
141
141
|
found = hostlist.any? { |pattern| match(host_name, pattern) } || known_host_hash?(hostlist, entries)
|
142
142
|
next unless found
|
143
143
|
|
144
144
|
found = hostlist.include?(host_ip) if options[:check_host_ip] && entries.size > 1 && hostlist.size > 1
|
145
145
|
next unless found
|
146
146
|
|
147
|
-
|
148
|
-
type = scanner.scan(/\S+/)
|
149
|
-
|
150
|
-
next unless SUPPORTED_TYPE.include?(type)
|
151
|
-
|
152
|
-
scanner.skip(/\s*/)
|
153
|
-
blob = scanner.rest.unpack("m*").first
|
147
|
+
blob = key_content.unpack("m*").first
|
154
148
|
keys << Net::SSH::Buffer.new(blob).read_key
|
155
149
|
end
|
156
150
|
end
|
@@ -159,14 +153,18 @@ module Net
|
|
159
153
|
end
|
160
154
|
|
161
155
|
def match(host, pattern)
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
156
|
+
if pattern.include?('*') || pattern.include?('?')
|
157
|
+
# see man 8 sshd for pattern details
|
158
|
+
pattern_regexp = pattern.split('*').map do |x|
|
159
|
+
x.split('?').map do |y|
|
160
|
+
Regexp.escape(y)
|
161
|
+
end.join('.')
|
162
|
+
end.join('[^.]*')
|
163
|
+
|
164
|
+
host =~ Regexp.new("\\A#{pattern_regexp}\\z")
|
165
|
+
else
|
166
|
+
host == pattern
|
167
|
+
end
|
170
168
|
end
|
171
169
|
|
172
170
|
# Indicates whether one of the entries matches an hostname that has been
|
data/lib/net/ssh/loggable.rb
CHANGED
@@ -56,8 +56,8 @@ module Net
|
|
56
56
|
# originates. It defaults to the name of class with the object_id
|
57
57
|
# appended.
|
58
58
|
def facility
|
59
|
-
@facility ||= self.class.
|
59
|
+
@facility ||= self.class.to_s.gsub(/::/, ".").gsub(/([a-z])([A-Z])/, "\\1_\\2").downcase + "[%x]" % object_id
|
60
60
|
end
|
61
61
|
end
|
62
62
|
end
|
63
|
-
end
|
63
|
+
end
|
data/lib/net/ssh/proxy/socks5.rb
CHANGED
@@ -85,7 +85,8 @@ module Net
|
|
85
85
|
client = server.accept
|
86
86
|
debug { "received connection on #{socket}" }
|
87
87
|
|
88
|
-
channel = session.open_channel("direct-tcpip", :string, remote_host, :long,
|
88
|
+
channel = session.open_channel("direct-tcpip", :string, remote_host, :long,
|
89
|
+
remote_port, :string, bind_address, local_port_type, local_port) do |achannel|
|
89
90
|
achannel.info { "direct channel established" }
|
90
91
|
end
|
91
92
|
|
data/lib/net/ssh/test.rb
CHANGED
@@ -74,7 +74,7 @@ module Net
|
|
74
74
|
def transport(options={})
|
75
75
|
@transport ||= Net::SSH::Transport::Session.new(
|
76
76
|
options[:host] || "localhost",
|
77
|
-
options.merge(kex: "test", host_key: "ssh-rsa", verify_host_key: :never, proxy: socket(options))
|
77
|
+
options.merge(kex: "test", host_key: "ssh-rsa", append_all_supported_algorithms: true, verify_host_key: :never, proxy: socket(options))
|
78
78
|
)
|
79
79
|
end
|
80
80
|
|
@@ -86,7 +86,8 @@ module Net
|
|
86
86
|
def assert_scripted
|
87
87
|
raise "there is no script to be processed" if socket.script.events.empty?
|
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
|
|
@@ -5,13 +5,13 @@ require 'net/ssh/transport/cipher_factory'
|
|
5
5
|
require 'net/ssh/transport/constants'
|
6
6
|
require 'net/ssh/transport/hmac'
|
7
7
|
require 'net/ssh/transport/kex'
|
8
|
+
require 'net/ssh/transport/kex/curve25519_sha256_loader'
|
8
9
|
require 'net/ssh/transport/server_version'
|
9
10
|
require 'net/ssh/authentication/ed25519_loader'
|
10
11
|
|
11
12
|
module Net
|
12
13
|
module SSH
|
13
14
|
module Transport
|
14
|
-
|
15
15
|
# Implements the higher-level logic behind an SSH key-exchange. It handles
|
16
16
|
# both the initial exchange, as well as subsequent re-exchanges (as needed).
|
17
17
|
# It also encapsulates the negotiation of the algorithms, and provides a
|
@@ -23,56 +23,72 @@ module Net
|
|
23
23
|
include Loggable
|
24
24
|
include Constants
|
25
25
|
|
26
|
-
# Define the default algorithms, in order of preference, supported by
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
# Define the default algorithms, in order of preference, supported by Net::SSH.
|
27
|
+
DEFAULT_ALGORITHMS = {
|
28
|
+
host_key: %w[ecdsa-sha2-nistp521-cert-v01@openssh.com
|
29
|
+
ecdsa-sha2-nistp384-cert-v01@openssh.com
|
30
|
+
ecdsa-sha2-nistp256-cert-v01@openssh.com
|
31
|
+
ecdsa-sha2-nistp521
|
32
|
+
ecdsa-sha2-nistp384
|
33
|
+
ecdsa-sha2-nistp256
|
34
|
+
ssh-rsa-cert-v01@openssh.com
|
30
35
|
ssh-rsa-cert-v00@openssh.com
|
31
|
-
ssh-rsa
|
32
|
-
|
33
|
-
|
34
|
-
|
36
|
+
ssh-rsa],
|
37
|
+
|
38
|
+
kex: %w[ecdh-sha2-nistp521
|
39
|
+
ecdh-sha2-nistp384
|
40
|
+
ecdh-sha2-nistp256
|
41
|
+
diffie-hellman-group-exchange-sha256
|
42
|
+
diffie-hellman-group14-sha1],
|
43
|
+
|
44
|
+
encryption: %w[aes256-ctr aes192-ctr aes128-ctr],
|
45
|
+
|
46
|
+
hmac: %w[hmac-sha2-512-etm@openssh.com hmac-sha2-256-etm@openssh.com
|
47
|
+
hmac-sha2-512 hmac-sha2-256
|
48
|
+
hmac-sha1]
|
49
|
+
}.freeze
|
50
|
+
|
51
|
+
if Net::SSH::Authentication::ED25519Loader::LOADED
|
52
|
+
DEFAULT_ALGORITHMS[:host_key].unshift(
|
53
|
+
'ssh-ed25519-cert-v01@openssh.com',
|
54
|
+
'ssh-ed25519'
|
55
|
+
)
|
56
|
+
end
|
57
|
+
|
58
|
+
if Net::SSH::Transport::Kex::Curve25519Sha256Loader::LOADED
|
59
|
+
DEFAULT_ALGORITHMS[:kex].unshift(
|
60
|
+
'curve25519-sha256',
|
61
|
+
'curve25519-sha256@libssh.org'
|
62
|
+
)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Define all algorithms, with the deprecated, supported by Net::SSH.
|
66
|
+
ALGORITHMS = {
|
67
|
+
host_key: DEFAULT_ALGORITHMS[:host_key] + %w[ssh-dss],
|
68
|
+
|
69
|
+
kex: DEFAULT_ALGORITHMS[:kex] +
|
70
|
+
%w[diffie-hellman-group-exchange-sha1
|
35
71
|
diffie-hellman-group1-sha1],
|
36
|
-
|
37
|
-
|
72
|
+
|
73
|
+
encryption: DEFAULT_ALGORITHMS[:encryption] +
|
74
|
+
%w[aes256-cbc aes192-cbc aes128-cbc
|
38
75
|
rijndael-cbc@lysator.liu.se
|
39
76
|
blowfish-ctr blowfish-cbc
|
40
77
|
cast128-ctr cast128-cbc
|
41
78
|
3des-ctr 3des-cbc
|
42
|
-
idea-cbc
|
79
|
+
idea-cbc
|
43
80
|
none],
|
44
81
|
|
45
|
-
hmac:
|
46
|
-
|
47
|
-
hmac-sha1
|
82
|
+
hmac: DEFAULT_ALGORITHMS[:hmac] +
|
83
|
+
%w[hmac-sha2-512-96 hmac-sha2-256-96
|
84
|
+
hmac-sha1-96
|
48
85
|
hmac-ripemd160 hmac-ripemd160@openssh.com
|
49
86
|
hmac-md5 hmac-md5-96
|
50
87
|
none],
|
51
88
|
|
52
89
|
compression: %w[none zlib@openssh.com zlib],
|
53
90
|
language: %w[]
|
54
|
-
}
|
55
|
-
if defined?(OpenSSL::PKey::EC)
|
56
|
-
ALGORITHMS[:host_key].unshift(
|
57
|
-
"ecdsa-sha2-nistp521-cert-v01@openssh.com",
|
58
|
-
"ecdsa-sha2-nistp384-cert-v01@openssh.com",
|
59
|
-
"ecdsa-sha2-nistp256-cert-v01@openssh.com",
|
60
|
-
"ecdsa-sha2-nistp521",
|
61
|
-
"ecdsa-sha2-nistp384",
|
62
|
-
"ecdsa-sha2-nistp256"
|
63
|
-
)
|
64
|
-
if Net::SSH::Authentication::ED25519Loader::LOADED
|
65
|
-
ALGORITHMS[:host_key].unshift(
|
66
|
-
"ssh-ed25519-cert-v01@openssh.com",
|
67
|
-
"ssh-ed25519"
|
68
|
-
)
|
69
|
-
end
|
70
|
-
ALGORITHMS[:kex].unshift(
|
71
|
-
"ecdh-sha2-nistp521",
|
72
|
-
"ecdh-sha2-nistp384",
|
73
|
-
"ecdh-sha2-nistp256"
|
74
|
-
)
|
75
|
-
end
|
91
|
+
}.freeze
|
76
92
|
|
77
93
|
# The underlying transport layer session that supports this object
|
78
94
|
attr_reader :session
|
@@ -140,6 +156,7 @@ module Net
|
|
140
156
|
# Start the algorithm negotation
|
141
157
|
def start
|
142
158
|
raise ArgumentError, "Cannot call start if it's negotiation started or done" if @pending || @initialized
|
159
|
+
|
143
160
|
send_kexinit
|
144
161
|
end
|
145
162
|
|
@@ -197,8 +214,8 @@ module Net
|
|
197
214
|
|
198
215
|
def host_key_format
|
199
216
|
case host_key
|
200
|
-
when
|
201
|
-
|
217
|
+
when /^([a-z0-9-]+)-cert-v\d{2}@openssh.com$/
|
218
|
+
Regexp.last_match[1]
|
202
219
|
else
|
203
220
|
host_key
|
204
221
|
end
|
@@ -239,7 +256,10 @@ module Net
|
|
239
256
|
options[:compression] = %w[zlib@openssh.com zlib] if options[:compression] == true
|
240
257
|
|
241
258
|
ALGORITHMS.each do |algorithm, supported|
|
242
|
-
algorithms[algorithm] = compose_algorithm_list(
|
259
|
+
algorithms[algorithm] = compose_algorithm_list(
|
260
|
+
supported, options[algorithm] || DEFAULT_ALGORITHMS[algorithm],
|
261
|
+
options[:append_all_supported_algorithms]
|
262
|
+
)
|
243
263
|
end
|
244
264
|
|
245
265
|
# for convention, make sure our list has the same keys as the server
|
@@ -356,7 +376,8 @@ module Net
|
|
356
376
|
|
357
377
|
debug do
|
358
378
|
"negotiated:\n" +
|
359
|
-
%i[kex host_key encryption_server encryption_client hmac_client hmac_server
|
379
|
+
%i[kex host_key encryption_server encryption_client hmac_client hmac_server
|
380
|
+
compression_client compression_server language_client language_server].map do |key|
|
360
381
|
"* #{key}: #{instance_variable_get("@#{key}")}"
|
361
382
|
end.join("\n")
|
362
383
|
end
|
@@ -368,7 +389,11 @@ module Net
|
|
368
389
|
def negotiate(algorithm)
|
369
390
|
match = self[algorithm].find { |item| @server_data[algorithm].include?(item) }
|
370
391
|
|
371
|
-
|
392
|
+
if match.nil?
|
393
|
+
raise Net::SSH::Exception, "could not settle on #{algorithm} algorithm\n"\
|
394
|
+
"Server #{algorithm} preferences: #{@server_data[algorithm].join(',')}\n"\
|
395
|
+
"Client #{algorithm} preferences: #{self[algorithm].join(',')}"
|
396
|
+
end
|
372
397
|
|
373
398
|
return match
|
374
399
|
end
|
@@ -19,30 +19,17 @@ module Net
|
|
19
19
|
"idea-cbc" => "idea-cbc",
|
20
20
|
"cast128-cbc" => "cast-cbc",
|
21
21
|
"rijndael-cbc@lysator.liu.se" => "aes-256-cbc",
|
22
|
-
"arcfour128" => "rc4",
|
23
|
-
"arcfour256" => "rc4",
|
24
|
-
"arcfour512" => "rc4",
|
25
|
-
"arcfour" => "rc4",
|
26
|
-
|
27
22
|
"3des-ctr" => "des-ede3",
|
28
23
|
"blowfish-ctr" => "bf-ecb",
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
}
|
37
|
-
|
38
|
-
# Ruby's OpenSSL bindings always return a key length of 16 for RC4 ciphers
|
39
|
-
# resulting in the error: OpenSSL::CipherError: key length too short.
|
40
|
-
# The following ciphers will override this key length.
|
41
|
-
KEY_LEN_OVERRIDE = {
|
42
|
-
"arcfour256" => 32,
|
43
|
-
"arcfour512" => 64
|
24
|
+
|
25
|
+
'aes256-ctr' => 'aes-256-ctr',
|
26
|
+
'aes192-ctr' => 'aes-192-ctr',
|
27
|
+
'aes128-ctr' => 'aes-128-ctr',
|
28
|
+
'cast128-ctr' => 'cast5-ecb',
|
29
|
+
|
30
|
+
'none' => 'none'
|
44
31
|
}
|
45
|
-
|
32
|
+
|
46
33
|
# Returns true if the underlying OpenSSL library supports the given cipher,
|
47
34
|
# and false otherwise.
|
48
35
|
def self.supported?(name)
|
@@ -72,12 +59,11 @@ module Net
|
|
72
59
|
cipher = Net::SSH::Transport::OpenSSLAESCTR.new(cipher)
|
73
60
|
end
|
74
61
|
end
|
75
|
-
cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options)
|
62
|
+
cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options)
|
76
63
|
|
77
|
-
key_len =
|
64
|
+
key_len = cipher.key_len
|
78
65
|
cipher.key_len = key_len
|
79
66
|
cipher.key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
|
80
|
-
cipher.update(" " * 1536) if (ossl_name == "rc4" && name != "arcfour")
|
81
67
|
|
82
68
|
return cipher
|
83
69
|
end
|
@@ -94,13 +80,11 @@ module Net
|
|
94
80
|
result << 0 if options[:iv_len]
|
95
81
|
else
|
96
82
|
cipher = OpenSSL::Cipher.new(ossl_name)
|
97
|
-
key_len =
|
83
|
+
key_len = cipher.key_len
|
98
84
|
cipher.key_len = key_len
|
99
85
|
|
100
86
|
block_size =
|
101
87
|
case ossl_name
|
102
|
-
when "rc4"
|
103
|
-
8
|
104
88
|
when /\-ctr/
|
105
89
|
Net::SSH::Transport::OpenSSLAESCTR.block_size
|
106
90
|
else
|
@@ -2,11 +2,10 @@ module Net
|
|
2
2
|
module SSH
|
3
3
|
module Transport
|
4
4
|
module Constants
|
5
|
-
|
6
5
|
#--
|
7
6
|
# Transport layer generic messages
|
8
7
|
#++
|
9
|
-
|
8
|
+
|
10
9
|
DISCONNECT = 1
|
11
10
|
IGNORE = 2
|
12
11
|
UNIMPLEMENTED = 3
|
@@ -17,19 +16,24 @@ module Net
|
|
17
16
|
#--
|
18
17
|
# Algorithm negotiation messages
|
19
18
|
#++
|
20
|
-
|
19
|
+
|
21
20
|
KEXINIT = 20
|
22
21
|
NEWKEYS = 21
|
23
|
-
|
22
|
+
|
24
23
|
#--
|
25
24
|
# Key exchange method specific messages
|
26
25
|
#++
|
27
|
-
|
26
|
+
|
28
27
|
KEXDH_INIT = 30
|
29
28
|
KEXDH_REPLY = 31
|
30
|
-
|
29
|
+
|
31
30
|
KEXECDH_INIT = 30
|
32
31
|
KEXECDH_REPLY = 31
|
32
|
+
|
33
|
+
KEXDH_GEX_GROUP = 31
|
34
|
+
KEXDH_GEX_INIT = 32
|
35
|
+
KEXDH_GEX_REPLY = 33
|
36
|
+
KEXDH_GEX_REQUEST = 34
|
33
37
|
end
|
34
38
|
end
|
35
39
|
end
|
@@ -88,14 +88,8 @@ module Net::SSH::Transport
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def final
|
91
|
-
|
92
|
-
s = xor!(@remaining, _update(@counter))
|
93
|
-
else
|
94
|
-
s = ""
|
95
|
-
end
|
96
|
-
|
91
|
+
s = @remaining.empty? ? '' : xor!(@remaining, _update(@counter))
|
97
92
|
@remaining = ""
|
98
|
-
|
99
93
|
s
|
100
94
|
end
|
101
95
|
|