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