net-ssh 2.7.0 → 7.3.0
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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/.dockerignore +6 -0
- data/.github/FUNDING.yml +1 -0
- data/.github/config/rubocop_linter_action.yml +4 -0
- data/.github/workflows/ci-with-docker.yml +44 -0
- data/.github/workflows/ci.yml +94 -0
- data/.github/workflows/rubocop.yml +16 -0
- data/.gitignore +15 -0
- data/.rubocop.yml +22 -0
- data/.rubocop_todo.yml +1081 -0
- data/CHANGES.txt +387 -0
- data/DEVELOPMENT.md +23 -0
- data/Dockerfile +29 -0
- data/Dockerfile.openssl3 +17 -0
- data/Gemfile +13 -0
- data/Gemfile.noed25519 +12 -0
- data/Gemfile.norbnacl +12 -0
- data/ISSUE_TEMPLATE.md +30 -0
- data/Manifest +4 -5
- data/README.md +303 -0
- data/Rakefile +174 -40
- data/SECURITY.md +4 -0
- data/THANKS.txt +25 -0
- data/appveyor.yml +58 -0
- data/docker-compose.yml +25 -0
- data/lib/net/ssh/authentication/agent.rb +279 -18
- data/lib/net/ssh/authentication/certificate.rb +183 -0
- data/lib/net/ssh/authentication/constants.rb +17 -15
- data/lib/net/ssh/authentication/ed25519.rb +184 -0
- data/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
- data/lib/net/ssh/authentication/key_manager.rb +125 -54
- data/lib/net/ssh/authentication/methods/abstract.rb +67 -48
- data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
- data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +19 -12
- data/lib/net/ssh/authentication/methods/none.rb +16 -19
- data/lib/net/ssh/authentication/methods/password.rb +56 -19
- data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
- data/lib/net/ssh/authentication/pageant.rb +483 -246
- data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
- data/lib/net/ssh/authentication/session.rb +138 -120
- data/lib/net/ssh/buffer.rb +399 -300
- data/lib/net/ssh/buffered_io.rb +154 -150
- data/lib/net/ssh/config.rb +361 -166
- data/lib/net/ssh/connection/channel.rb +640 -596
- data/lib/net/ssh/connection/constants.rb +29 -29
- data/lib/net/ssh/connection/event_loop.rb +123 -0
- data/lib/net/ssh/connection/keepalive.rb +59 -0
- data/lib/net/ssh/connection/session.rb +628 -548
- data/lib/net/ssh/connection/term.rb +125 -123
- data/lib/net/ssh/errors.rb +101 -95
- data/lib/net/ssh/key_factory.rb +198 -100
- data/lib/net/ssh/known_hosts.rb +221 -98
- data/lib/net/ssh/loggable.rb +50 -49
- data/lib/net/ssh/packet.rb +83 -79
- data/lib/net/ssh/prompt.rb +50 -81
- data/lib/net/ssh/proxy/command.rb +108 -60
- data/lib/net/ssh/proxy/errors.rb +12 -10
- data/lib/net/ssh/proxy/http.rb +82 -78
- data/lib/net/ssh/proxy/https.rb +50 -0
- data/lib/net/ssh/proxy/jump.rb +54 -0
- data/lib/net/ssh/proxy/socks4.rb +5 -8
- data/lib/net/ssh/proxy/socks5.rb +18 -20
- data/lib/net/ssh/service/forward.rb +383 -255
- data/lib/net/ssh/test/channel.rb +145 -136
- data/lib/net/ssh/test/extensions.rb +131 -110
- data/lib/net/ssh/test/kex.rb +34 -32
- data/lib/net/ssh/test/local_packet.rb +46 -44
- data/lib/net/ssh/test/packet.rb +89 -70
- data/lib/net/ssh/test/remote_packet.rb +32 -30
- data/lib/net/ssh/test/script.rb +156 -142
- data/lib/net/ssh/test/socket.rb +49 -48
- data/lib/net/ssh/test.rb +82 -77
- data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
- data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
- data/lib/net/ssh/transport/algorithms.rb +472 -348
- data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
- data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
- data/lib/net/ssh/transport/cipher_factory.rb +124 -100
- data/lib/net/ssh/transport/constants.rb +32 -24
- data/lib/net/ssh/transport/ctr.rb +42 -22
- data/lib/net/ssh/transport/gcm_cipher.rb +207 -0
- data/lib/net/ssh/transport/hmac/abstract.rb +97 -63
- 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 +14 -12
- data/lib/net/ssh/transport/identity_cipher.rb +54 -44
- 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 +33 -40
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +119 -213
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -61
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
- data/lib/net/ssh/transport/kex.rb +15 -12
- data/lib/net/ssh/transport/key_expander.rb +24 -20
- data/lib/net/ssh/transport/openssl.rb +161 -124
- data/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
- data/lib/net/ssh/transport/packet_stream.rb +246 -183
- data/lib/net/ssh/transport/server_version.rb +57 -51
- data/lib/net/ssh/transport/session.rb +307 -235
- data/lib/net/ssh/transport/state.rb +178 -176
- data/lib/net/ssh/verifiers/accept_new.rb +33 -0
- data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
- data/lib/net/ssh/verifiers/always.rb +58 -0
- data/lib/net/ssh/verifiers/never.rb +19 -0
- data/lib/net/ssh/version.rb +57 -51
- data/lib/net/ssh.rb +140 -40
- data/net-ssh-public_cert.pem +21 -0
- data/net-ssh.gemspec +39 -184
- data/support/ssh_tunnel_bug.rb +5 -5
- data.tar.gz.sig +0 -0
- metadata +205 -99
- metadata.gz.sig +0 -0
- data/README.rdoc +0 -219
- data/Rudyfile +0 -96
- data/gem-public_cert.pem +0 -20
- data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
- data/lib/net/ssh/authentication/agent/socket.rb +0 -170
- data/lib/net/ssh/ruby_compat.rb +0 -51
- data/lib/net/ssh/verifiers/lenient.rb +0 -30
- data/lib/net/ssh/verifiers/null.rb +0 -12
- data/lib/net/ssh/verifiers/secure.rb +0 -54
- data/lib/net/ssh/verifiers/strict.rb +0 -24
- data/setup.rb +0 -1585
- data/support/arcfour_check.rb +0 -20
- data/test/README.txt +0 -47
- data/test/authentication/methods/common.rb +0 -28
- data/test/authentication/methods/test_abstract.rb +0 -51
- data/test/authentication/methods/test_hostbased.rb +0 -114
- data/test/authentication/methods/test_keyboard_interactive.rb +0 -100
- data/test/authentication/methods/test_none.rb +0 -41
- data/test/authentication/methods/test_password.rb +0 -52
- data/test/authentication/methods/test_publickey.rb +0 -148
- data/test/authentication/test_agent.rb +0 -205
- data/test/authentication/test_key_manager.rb +0 -218
- data/test/authentication/test_session.rb +0 -108
- data/test/common.rb +0 -108
- data/test/configs/eqsign +0 -3
- data/test/configs/exact_match +0 -8
- data/test/configs/host_plus +0 -10
- data/test/configs/multihost +0 -4
- data/test/configs/nohost +0 -19
- data/test/configs/numeric_host +0 -4
- data/test/configs/send_env +0 -2
- data/test/configs/substitutes +0 -8
- data/test/configs/wild_cards +0 -14
- data/test/connection/test_channel.rb +0 -467
- data/test/connection/test_session.rb +0 -526
- data/test/known_hosts/github +0 -1
- data/test/manual/test_forward.rb +0 -223
- data/test/start/test_options.rb +0 -36
- data/test/start/test_transport.rb +0 -28
- data/test/test_all.rb +0 -11
- data/test/test_buffer.rb +0 -433
- data/test/test_buffered_io.rb +0 -63
- data/test/test_config.rb +0 -151
- data/test/test_key_factory.rb +0 -173
- data/test/test_known_hosts.rb +0 -13
- data/test/transport/hmac/test_md5.rb +0 -41
- data/test/transport/hmac/test_md5_96.rb +0 -27
- data/test/transport/hmac/test_none.rb +0 -34
- data/test/transport/hmac/test_ripemd160.rb +0 -36
- data/test/transport/hmac/test_sha1.rb +0 -36
- data/test/transport/hmac/test_sha1_96.rb +0 -27
- data/test/transport/hmac/test_sha2_256.rb +0 -37
- data/test/transport/hmac/test_sha2_256_96.rb +0 -27
- data/test/transport/hmac/test_sha2_512.rb +0 -37
- data/test/transport/hmac/test_sha2_512_96.rb +0 -27
- data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +0 -13
- data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -146
- data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -92
- data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +0 -34
- data/test/transport/kex/test_ecdh_sha2_nistp256.rb +0 -161
- data/test/transport/kex/test_ecdh_sha2_nistp384.rb +0 -38
- data/test/transport/kex/test_ecdh_sha2_nistp521.rb +0 -38
- data/test/transport/test_algorithms.rb +0 -330
- data/test/transport/test_cipher_factory.rb +0 -443
- data/test/transport/test_hmac.rb +0 -34
- data/test/transport/test_identity_cipher.rb +0 -40
- data/test/transport/test_packet_stream.rb +0 -1755
- data/test/transport/test_server_version.rb +0 -78
- data/test/transport/test_session.rb +0 -319
- data/test/transport/test_state.rb +0 -181
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'socket'
|
2
|
-
require 'timeout'
|
3
2
|
|
4
3
|
require 'net/ssh/errors'
|
5
4
|
require 'net/ssh/loggable'
|
@@ -8,275 +7,348 @@ require 'net/ssh/transport/algorithms'
|
|
8
7
|
require 'net/ssh/transport/constants'
|
9
8
|
require 'net/ssh/transport/packet_stream'
|
10
9
|
require 'net/ssh/transport/server_version'
|
11
|
-
require 'net/ssh/verifiers/
|
12
|
-
require 'net/ssh/verifiers/
|
13
|
-
require 'net/ssh/verifiers/
|
14
|
-
require 'net/ssh/verifiers/
|
15
|
-
|
16
|
-
module Net
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
10
|
+
require 'net/ssh/verifiers/accept_new_or_local_tunnel'
|
11
|
+
require 'net/ssh/verifiers/accept_new'
|
12
|
+
require 'net/ssh/verifiers/always'
|
13
|
+
require 'net/ssh/verifiers/never'
|
14
|
+
|
15
|
+
module Net
|
16
|
+
module SSH
|
17
|
+
module Transport
|
18
|
+
# The transport layer represents the lowest level of the SSH protocol, and
|
19
|
+
# implements basic message exchanging and protocol initialization. It will
|
20
|
+
# never be instantiated directly (unless you really know what you're about),
|
21
|
+
# but will instead be created for you automatically when you create a new
|
22
|
+
# SSH session via Net::SSH.start.
|
23
|
+
class Session
|
24
|
+
include Loggable
|
25
|
+
include Constants
|
26
|
+
|
27
|
+
# The standard port for the SSH protocol.
|
28
|
+
DEFAULT_PORT = 22
|
29
|
+
|
30
|
+
# The host to connect to, as given to the constructor.
|
31
|
+
attr_reader :host
|
32
|
+
|
33
|
+
# The port number to connect to, as given in the options to the constructor.
|
34
|
+
# If no port number was given, this will default to DEFAULT_PORT.
|
35
|
+
attr_reader :port
|
36
|
+
|
37
|
+
# The underlying socket object being used to communicate with the remote
|
38
|
+
# host.
|
39
|
+
attr_reader :socket
|
40
|
+
|
41
|
+
# The ServerVersion instance that encapsulates the negotiated protocol
|
42
|
+
# version.
|
43
|
+
attr_reader :server_version
|
44
|
+
|
45
|
+
# The Algorithms instance used to perform key exchanges.
|
46
|
+
attr_reader :algorithms
|
47
|
+
|
48
|
+
# The host-key verifier object used to verify host keys, to ensure that
|
49
|
+
# the connection is not being spoofed.
|
50
|
+
attr_reader :host_key_verifier
|
51
|
+
|
52
|
+
# The hash of options that were given to the object at initialization.
|
53
|
+
attr_reader :options
|
54
|
+
|
55
|
+
# Instantiates a new transport layer abstraction. This will block until
|
56
|
+
# the initial key exchange completes, leaving you with a ready-to-use
|
57
|
+
# transport session.
|
58
|
+
def initialize(host, options = {})
|
59
|
+
self.logger = options[:logger]
|
60
|
+
|
61
|
+
@host = host
|
62
|
+
@port = options[:port] || DEFAULT_PORT
|
63
|
+
@bind_address = options[:bind_address] || nil
|
64
|
+
@options = options
|
65
|
+
|
66
|
+
@socket =
|
67
|
+
if (factory = options[:proxy])
|
68
|
+
debug { "establishing connection to #{@host}:#{@port} through proxy" }
|
69
|
+
factory.open(@host, @port, options)
|
70
|
+
else
|
71
|
+
debug { "establishing connection to #{@host}:#{@port}" }
|
72
|
+
Socket.tcp(@host, @port, @bind_address, nil,
|
73
|
+
connect_timeout: options[:timeout])
|
74
|
+
end
|
75
|
+
|
76
|
+
@socket.extend(PacketStream)
|
77
|
+
@socket.logger = @logger
|
78
|
+
|
79
|
+
debug { "connection established" }
|
80
|
+
|
81
|
+
@queue = []
|
82
|
+
|
83
|
+
@host_key_verifier = select_host_key_verifier(options[:verify_host_key])
|
84
|
+
|
85
|
+
@server_version = ServerVersion.new(socket, logger, options[:timeout])
|
86
|
+
|
87
|
+
@algorithms = Algorithms.new(self, options)
|
88
|
+
@algorithms.start
|
89
|
+
wait { algorithms.initialized? }
|
90
|
+
rescue Errno::ETIMEDOUT
|
91
|
+
raise Net::SSH::ConnectionTimeout
|
92
|
+
end
|
72
93
|
|
73
|
-
|
94
|
+
def host_keys
|
95
|
+
@host_keys ||= begin
|
96
|
+
known_hosts = options.fetch(:known_hosts, KnownHosts)
|
97
|
+
known_hosts.search_for(options[:host_key_alias] || host_as_string, options)
|
98
|
+
end
|
99
|
+
end
|
74
100
|
|
75
|
-
|
101
|
+
# Returns the host (and possibly IP address) in a format compatible with
|
102
|
+
# SSH known-host files.
|
103
|
+
def host_as_string
|
104
|
+
@host_as_string ||= begin
|
105
|
+
string = "#{host}"
|
106
|
+
string = "[#{string}]:#{port}" if port != DEFAULT_PORT
|
76
107
|
|
108
|
+
peer_ip = socket.peer_ip
|
77
109
|
|
78
|
-
|
110
|
+
if peer_ip != Net::SSH::Transport::PacketStream::PROXY_COMMAND_HOST_IP &&
|
111
|
+
peer_ip != host
|
112
|
+
string2 = peer_ip
|
113
|
+
string2 = "[#{string2}]:#{port}" if port != DEFAULT_PORT
|
114
|
+
string << "," << string2
|
115
|
+
end
|
79
116
|
|
80
|
-
|
81
|
-
|
82
|
-
|
117
|
+
string
|
118
|
+
end
|
119
|
+
end
|
83
120
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
@host_as_string ||= begin
|
88
|
-
string = "#{host}"
|
89
|
-
string = "[#{string}]:#{port}" if port != DEFAULT_PORT
|
90
|
-
if socket.peer_ip != host
|
91
|
-
string2 = socket.peer_ip
|
92
|
-
string2 = "[#{string2}]:#{port}" if port != DEFAULT_PORT
|
93
|
-
string << "," << string2
|
121
|
+
# Returns true if the underlying socket has been closed.
|
122
|
+
def closed?
|
123
|
+
socket.closed?
|
94
124
|
end
|
95
|
-
string
|
96
|
-
end
|
97
|
-
end
|
98
125
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
126
|
+
# Cleans up (see PacketStream#cleanup) and closes the underlying socket.
|
127
|
+
def close
|
128
|
+
socket.cleanup
|
129
|
+
socket.close
|
130
|
+
end
|
103
131
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
132
|
+
# Performs a "hard" shutdown of the connection. In general, this should
|
133
|
+
# never be done, but it might be necessary (in a rescue clause, for instance,
|
134
|
+
# when the connection needs to close but you don't know the status of the
|
135
|
+
# underlying protocol's state).
|
136
|
+
def shutdown!
|
137
|
+
error { "forcing connection closed" }
|
138
|
+
socket.close
|
139
|
+
end
|
109
140
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
error { "forcing connection closed" }
|
116
|
-
socket.close
|
117
|
-
end
|
141
|
+
# Returns a new service_request packet for the given service name, ready
|
142
|
+
# for sending to the server.
|
143
|
+
def service_request(service)
|
144
|
+
Net::SSH::Buffer.from(:byte, SERVICE_REQUEST, :string, service)
|
145
|
+
end
|
118
146
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
147
|
+
# Requests a rekey operation, and blocks until the operation completes.
|
148
|
+
# If a rekey is already pending, this returns immediately, having no
|
149
|
+
# effect.
|
150
|
+
def rekey!
|
151
|
+
if !algorithms.pending?
|
152
|
+
algorithms.rekey!
|
153
|
+
wait { algorithms.initialized? }
|
154
|
+
end
|
155
|
+
end
|
124
156
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
algorithms.rekey!
|
131
|
-
wait { algorithms.initialized? }
|
132
|
-
end
|
133
|
-
end
|
157
|
+
# Returns immediately if a rekey is already in process. Otherwise, if a
|
158
|
+
# rekey is needed (as indicated by the socket, see PacketStream#if_needs_rekey?)
|
159
|
+
# one is performed, causing this method to block until it completes.
|
160
|
+
def rekey_as_needed
|
161
|
+
return if algorithms.pending?
|
134
162
|
|
135
|
-
|
136
|
-
|
137
|
-
# one is performed, causing this method to block until it completes.
|
138
|
-
def rekey_as_needed
|
139
|
-
return if algorithms.pending?
|
140
|
-
socket.if_needs_rekey? { rekey! }
|
141
|
-
end
|
163
|
+
socket.if_needs_rekey? { rekey! }
|
164
|
+
end
|
142
165
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
166
|
+
# Returns a hash of information about the peer (remote) side of the socket,
|
167
|
+
# including :ip, :port, :host, and :canonized (see #host_as_string).
|
168
|
+
def peer
|
169
|
+
@peer ||= { ip: socket.peer_ip, port: @port.to_i, host: @host, canonized: host_as_string }
|
170
|
+
end
|
148
171
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
172
|
+
# Blocks until a new packet is available to be read, and returns that
|
173
|
+
# packet. See #poll_message.
|
174
|
+
def next_message
|
175
|
+
poll_message(:block)
|
176
|
+
end
|
154
177
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
178
|
+
# Tries to read the next packet from the socket. If mode is :nonblock (the
|
179
|
+
# default), this will not block and will return nil if there are no packets
|
180
|
+
# waiting to be read. Otherwise, this will block until a packet is
|
181
|
+
# available. Note that some packet types (DISCONNECT, IGNORE, UNIMPLEMENTED,
|
182
|
+
# DEBUG, and KEXINIT) are handled silently by this method, and will never
|
183
|
+
# be returned.
|
184
|
+
#
|
185
|
+
# If a key-exchange is in process and a disallowed packet type is
|
186
|
+
# received, it will be enqueued and otherwise ignored. When a key-exchange
|
187
|
+
# is not in process, and consume_queue is true, packets will be first
|
188
|
+
# read from the queue before the socket is queried.
|
189
|
+
def poll_message(mode = :nonblock, consume_queue = true)
|
190
|
+
loop do
|
191
|
+
return @queue.shift if consume_queue && @queue.any? && algorithms.allow?(@queue.first)
|
192
|
+
|
193
|
+
packet = socket.next_packet(mode, options[:timeout])
|
194
|
+
return nil if packet.nil?
|
195
|
+
|
196
|
+
case packet.type
|
197
|
+
when DISCONNECT
|
198
|
+
raise Net::SSH::Disconnect, "disconnected: #{packet[:description]} (#{packet[:reason_code]})"
|
199
|
+
|
200
|
+
when IGNORE
|
201
|
+
debug { "IGNORE packet received: #{packet[:data].inspect}" }
|
202
|
+
|
203
|
+
when UNIMPLEMENTED
|
204
|
+
lwarn { "UNIMPLEMENTED: #{packet[:number]}" }
|
205
|
+
|
206
|
+
when DEBUG
|
207
|
+
send(packet[:always_display] ? :fatal : :debug) { packet[:message] }
|
208
|
+
|
209
|
+
when KEXINIT
|
210
|
+
algorithms.accept_kexinit(packet)
|
211
|
+
|
212
|
+
else
|
213
|
+
return packet if algorithms.allow?(packet)
|
214
|
+
|
215
|
+
push(packet)
|
216
|
+
end
|
217
|
+
end
|
170
218
|
end
|
171
219
|
|
172
|
-
|
173
|
-
|
220
|
+
# Waits (blocks) until the given block returns true. If no block is given,
|
221
|
+
# this just waits long enough to see if there are any pending packets. Any
|
222
|
+
# packets read are enqueued (see #push).
|
223
|
+
def wait
|
224
|
+
loop do
|
225
|
+
break if block_given? && yield
|
174
226
|
|
175
|
-
|
176
|
-
|
177
|
-
|
227
|
+
message = poll_message(:nonblock, false)
|
228
|
+
push(message) if message
|
229
|
+
break if !block_given?
|
230
|
+
end
|
231
|
+
end
|
178
232
|
|
179
|
-
|
180
|
-
|
233
|
+
# Adds the given packet to the packet queue. If the queue is non-empty,
|
234
|
+
# #poll_message will return packets from the queue in the order they
|
235
|
+
# were received.
|
236
|
+
def push(packet)
|
237
|
+
@queue.push(packet)
|
238
|
+
end
|
181
239
|
|
182
|
-
|
183
|
-
|
240
|
+
# Sends the given message via the packet stream, blocking until the
|
241
|
+
# entire message has been sent.
|
242
|
+
def send_message(message)
|
243
|
+
socket.send_packet(message)
|
244
|
+
end
|
184
245
|
|
185
|
-
|
186
|
-
|
246
|
+
# Enqueues the given message, such that it will be sent at the earliest
|
247
|
+
# opportunity. This does not block, but returns immediately.
|
248
|
+
def enqueue_message(message)
|
249
|
+
socket.enqueue_packet(message)
|
250
|
+
end
|
187
251
|
|
188
|
-
|
189
|
-
|
252
|
+
# Configure's the packet stream's client state with the given set of
|
253
|
+
# options. This is typically used to define the cipher, compression, and
|
254
|
+
# hmac algorithms to use when sending packets to the server.
|
255
|
+
def configure_client(options = {})
|
256
|
+
socket.client.set(options)
|
257
|
+
end
|
190
258
|
|
191
|
-
|
192
|
-
|
193
|
-
|
259
|
+
# Configure's the packet stream's server state with the given set of
|
260
|
+
# options. This is typically used to define the cipher, compression, and
|
261
|
+
# hmac algorithms to use when reading packets from the server.
|
262
|
+
def configure_server(options = {})
|
263
|
+
socket.server.set(options)
|
194
264
|
end
|
195
|
-
end
|
196
|
-
end
|
197
265
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
break if block_given? && yield
|
204
|
-
message = poll_message(:nonblock, false)
|
205
|
-
push(message) if message
|
206
|
-
break if !block_given?
|
207
|
-
end
|
208
|
-
end
|
266
|
+
# Sets a new hint for the packet stream, which the packet stream may use
|
267
|
+
# to change its behavior. (See PacketStream#hints).
|
268
|
+
def hint(which, value = true)
|
269
|
+
socket.hints[which] = value
|
270
|
+
end
|
209
271
|
|
210
|
-
|
211
|
-
# #poll_message will return packets from the queue in the order they
|
212
|
-
# were received.
|
213
|
-
def push(packet)
|
214
|
-
@queue.push(packet)
|
215
|
-
end
|
272
|
+
public
|
216
273
|
|
217
|
-
|
218
|
-
|
219
|
-
def send_message(message)
|
220
|
-
socket.send_packet(message)
|
221
|
-
end
|
274
|
+
# this method is primarily for use in tests
|
275
|
+
attr_reader :queue # :nodoc:
|
222
276
|
|
223
|
-
|
224
|
-
# opportunity. This does not block, but returns immediately.
|
225
|
-
def enqueue_message(message)
|
226
|
-
socket.enqueue_packet(message)
|
227
|
-
end
|
277
|
+
private
|
228
278
|
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
279
|
+
# Compatibility verifier which allows users to keep using
|
280
|
+
# custom verifier code without adding new :verify_signature
|
281
|
+
# method.
|
282
|
+
class CompatibleVerifier
|
283
|
+
def initialize(verifier)
|
284
|
+
@verifier = verifier
|
285
|
+
end
|
235
286
|
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
def configure_server(options={})
|
240
|
-
socket.server.set(options)
|
241
|
-
end
|
287
|
+
def verify(arguments)
|
288
|
+
@verifier.verify(arguments)
|
289
|
+
end
|
242
290
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
end
|
291
|
+
def verify_signature(&block)
|
292
|
+
yield
|
293
|
+
end
|
294
|
+
end
|
248
295
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
296
|
+
# Instantiates a new host-key verification class, based on the value of
|
297
|
+
# the parameter.
|
298
|
+
#
|
299
|
+
# Usually, the argument is a symbol like `:never` which corresponds to
|
300
|
+
# a verifier, like `::Net::SSH::Verifiers::Never`.
|
301
|
+
#
|
302
|
+
# - :never (very insecure)
|
303
|
+
# - :accept_new_or_local_tunnel (insecure)
|
304
|
+
# - :accept_new (insecure)
|
305
|
+
# - :always (secure)
|
306
|
+
#
|
307
|
+
# If the argument happens to respond to :verify and :verify_signature,
|
308
|
+
# it is returned directly. Otherwise, an exception is raised.
|
309
|
+
#
|
310
|
+
# Values false, true, and :very were deprecated in
|
311
|
+
# [#595](https://github.com/net-ssh/net-ssh/pull/595)
|
312
|
+
def select_host_key_verifier(verifier)
|
313
|
+
case verifier
|
314
|
+
when false
|
315
|
+
Kernel.warn('verify_host_key: false is deprecated, use :never')
|
316
|
+
Net::SSH::Verifiers::Never.new
|
317
|
+
when :never then
|
318
|
+
Net::SSH::Verifiers::Never.new
|
319
|
+
when true
|
320
|
+
Kernel.warn('verify_host_key: true is deprecated, use :accept_new_or_local_tunnel')
|
321
|
+
Net::SSH::Verifiers::AcceptNewOrLocalTunnel.new
|
322
|
+
when :accept_new_or_local_tunnel, nil then
|
323
|
+
Net::SSH::Verifiers::AcceptNewOrLocalTunnel.new
|
324
|
+
when :very
|
325
|
+
Kernel.warn('verify_host_key: :very is deprecated, use :accept_new')
|
326
|
+
Net::SSH::Verifiers::AcceptNew.new
|
327
|
+
when :accept_new then
|
328
|
+
Net::SSH::Verifiers::AcceptNew.new
|
329
|
+
when :secure then
|
330
|
+
Kernel.warn('verify_host_key: :secure is deprecated, use :always')
|
331
|
+
Net::SSH::Verifiers::Always.new
|
332
|
+
when :always then
|
333
|
+
Net::SSH::Verifiers::Always.new
|
276
334
|
else
|
277
|
-
|
335
|
+
if verifier.respond_to?(:verify)
|
336
|
+
if verifier.respond_to?(:verify_signature)
|
337
|
+
verifier
|
338
|
+
else
|
339
|
+
Kernel.warn("Warning: verifier without :verify_signature is deprecated")
|
340
|
+
CompatibleVerifier.new(verifier)
|
341
|
+
end
|
342
|
+
else
|
343
|
+
raise(
|
344
|
+
ArgumentError,
|
345
|
+
"Invalid argument to :verify_host_key (or deprecated " \
|
346
|
+
":paranoid): #{verifier.inspect}"
|
347
|
+
)
|
348
|
+
end
|
278
349
|
end
|
279
350
|
end
|
280
351
|
end
|
352
|
+
end
|
281
353
|
end
|
282
|
-
end
|
354
|
+
end
|