net-ssh 5.0.0.beta1 → 5.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.rubocop_todo.yml +98 -258
  5. data/CHANGES.txt +8 -0
  6. data/Gemfile +1 -3
  7. data/Rakefile +37 -39
  8. data/lib/net/ssh.rb +26 -25
  9. data/lib/net/ssh/authentication/agent.rb +228 -225
  10. data/lib/net/ssh/authentication/certificate.rb +166 -164
  11. data/lib/net/ssh/authentication/constants.rb +17 -14
  12. data/lib/net/ssh/authentication/ed25519.rb +107 -104
  13. data/lib/net/ssh/authentication/ed25519_loader.rb +32 -28
  14. data/lib/net/ssh/authentication/key_manager.rb +5 -3
  15. data/lib/net/ssh/authentication/methods/abstract.rb +53 -47
  16. data/lib/net/ssh/authentication/methods/hostbased.rb +32 -33
  17. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -4
  18. data/lib/net/ssh/authentication/methods/none.rb +10 -10
  19. data/lib/net/ssh/authentication/methods/password.rb +13 -13
  20. data/lib/net/ssh/authentication/methods/publickey.rb +54 -55
  21. data/lib/net/ssh/authentication/pageant.rb +468 -465
  22. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +44 -0
  23. data/lib/net/ssh/authentication/session.rb +127 -123
  24. data/lib/net/ssh/buffer.rb +305 -303
  25. data/lib/net/ssh/buffered_io.rb +163 -162
  26. data/lib/net/ssh/config.rb +230 -227
  27. data/lib/net/ssh/connection/channel.rb +659 -654
  28. data/lib/net/ssh/connection/constants.rb +30 -26
  29. data/lib/net/ssh/connection/event_loop.rb +108 -104
  30. data/lib/net/ssh/connection/keepalive.rb +54 -50
  31. data/lib/net/ssh/connection/session.rb +677 -678
  32. data/lib/net/ssh/connection/term.rb +180 -176
  33. data/lib/net/ssh/errors.rb +101 -99
  34. data/lib/net/ssh/key_factory.rb +108 -108
  35. data/lib/net/ssh/known_hosts.rb +148 -154
  36. data/lib/net/ssh/loggable.rb +56 -54
  37. data/lib/net/ssh/packet.rb +82 -78
  38. data/lib/net/ssh/prompt.rb +55 -53
  39. data/lib/net/ssh/proxy/command.rb +103 -102
  40. data/lib/net/ssh/proxy/errors.rb +12 -8
  41. data/lib/net/ssh/proxy/http.rb +92 -91
  42. data/lib/net/ssh/proxy/https.rb +42 -39
  43. data/lib/net/ssh/proxy/jump.rb +50 -47
  44. data/lib/net/ssh/proxy/socks4.rb +0 -2
  45. data/lib/net/ssh/proxy/socks5.rb +11 -11
  46. data/lib/net/ssh/ruby_compat.rb +1 -0
  47. data/lib/net/ssh/service/forward.rb +364 -362
  48. data/lib/net/ssh/test.rb +85 -83
  49. data/lib/net/ssh/test/channel.rb +146 -142
  50. data/lib/net/ssh/test/extensions.rb +148 -146
  51. data/lib/net/ssh/test/kex.rb +35 -31
  52. data/lib/net/ssh/test/local_packet.rb +48 -44
  53. data/lib/net/ssh/test/packet.rb +87 -84
  54. data/lib/net/ssh/test/remote_packet.rb +35 -31
  55. data/lib/net/ssh/test/script.rb +173 -171
  56. data/lib/net/ssh/test/socket.rb +59 -55
  57. data/lib/net/ssh/transport/algorithms.rb +413 -412
  58. data/lib/net/ssh/transport/cipher_factory.rb +108 -105
  59. data/lib/net/ssh/transport/constants.rb +35 -31
  60. data/lib/net/ssh/transport/ctr.rb +1 -1
  61. data/lib/net/ssh/transport/hmac.rb +1 -1
  62. data/lib/net/ssh/transport/hmac/abstract.rb +67 -64
  63. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +1 -1
  64. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +1 -1
  65. data/lib/net/ssh/transport/identity_cipher.rb +55 -51
  66. data/lib/net/ssh/transport/kex.rb +2 -4
  67. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +47 -40
  68. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +201 -197
  69. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -56
  70. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +94 -87
  71. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +17 -10
  72. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +17 -10
  73. data/lib/net/ssh/transport/key_expander.rb +29 -25
  74. data/lib/net/ssh/transport/openssl.rb +17 -30
  75. data/lib/net/ssh/transport/packet_stream.rb +193 -192
  76. data/lib/net/ssh/transport/server_version.rb +64 -66
  77. data/lib/net/ssh/transport/session.rb +286 -284
  78. data/lib/net/ssh/transport/state.rb +198 -196
  79. data/lib/net/ssh/verifiers/lenient.rb +29 -25
  80. data/lib/net/ssh/verifiers/null.rb +13 -9
  81. data/lib/net/ssh/verifiers/secure.rb +45 -45
  82. data/lib/net/ssh/verifiers/strict.rb +20 -16
  83. data/lib/net/ssh/version.rb +55 -53
  84. data/net-ssh.gemspec +4 -4
  85. data/support/ssh_tunnel_bug.rb +2 -2
  86. metadata +25 -24
  87. metadata.gz.sig +0 -0
@@ -12,296 +12,298 @@ require 'net/ssh/verifiers/secure'
12
12
  require 'net/ssh/verifiers/strict'
13
13
  require 'net/ssh/verifiers/lenient'
14
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])
15
+ module Net
16
+ module SSH
17
+ module Transport
18
+
19
+ # The transport layer represents the lowest level of the SSH protocol, and
20
+ # implements basic message exchanging and protocol initialization. It will
21
+ # never be instantiated directly (unless you really know what you're about),
22
+ # but will instead be created for you automatically when you create a new
23
+ # SSH session via Net::SSH.start.
24
+ class Session
25
+ include Loggable
26
+ include Constants
27
+
28
+ # The standard port for the SSH protocol.
29
+ DEFAULT_PORT = 22
30
+
31
+ # The host to connect to, as given to the constructor.
32
+ attr_reader :host
33
+
34
+ # The port number to connect to, as given in the options to the constructor.
35
+ # If no port number was given, this will default to DEFAULT_PORT.
36
+ attr_reader :port
37
+
38
+ # The underlying socket object being used to communicate with the remote
39
+ # host.
40
+ attr_reader :socket
41
+
42
+ # The ServerVersion instance that encapsulates the negotiated protocol
43
+ # version.
44
+ attr_reader :server_version
45
+
46
+ # The Algorithms instance used to perform key exchanges.
47
+ attr_reader :algorithms
48
+
49
+ # The host-key verifier object used to verify host keys, to ensure that
50
+ # the connection is not being spoofed.
51
+ attr_reader :host_key_verifier
52
+
53
+ # The hash of options that were given to the object at initialization.
54
+ attr_reader :options
55
+
56
+ # Instantiates a new transport layer abstraction. This will block until
57
+ # the initial key exchange completes, leaving you with a ready-to-use
58
+ # transport session.
59
+ def initialize(host, options={})
60
+ self.logger = options[:logger]
61
+
62
+ @host = host
63
+ @port = options[:port] || DEFAULT_PORT
64
+ @bind_address = options[:bind_address] || nil
65
+ @options = options
66
+
67
+ @socket =
68
+ if (factory = options[:proxy])
69
+ debug { "establishing connection to #{@host}:#{@port} through proxy" }
70
+ factory.open(@host, @port, options)
71
+ else
72
+ debug { "establishing connection to #{@host}:#{@port}" }
73
+ Socket.tcp(@host, @port, @bind_address, nil,
74
+ connect_timeout: options[:timeout])
75
+ end
76
+
77
+ @socket.extend(PacketStream)
78
+ @socket.logger = @logger
79
+
80
+ debug { "connection established" }
81
+
82
+ @queue = []
83
+
84
+ @host_key_verifier = select_host_key_verifier(options[:verify_host_key])
85
+
86
+ @server_version = ServerVersion.new(socket, logger, options[:timeout])
87
+
88
+ @algorithms = Algorithms.new(self, options)
89
+ @algorithms.start
90
+ wait { algorithms.initialized? }
91
+ rescue Errno::ETIMEDOUT
92
+ raise Net::SSH::ConnectionTimeout
72
93
  end
73
-
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
92
-
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
99
-
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
106
-
107
- peer_ip = socket.peer_ip
108
-
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
94
+
95
+ def host_keys
96
+ @host_keys ||= begin
97
+ known_hosts = options.fetch(:known_hosts, KnownHosts)
98
+ known_hosts.search_for(options[:host_key_alias] || host_as_string, options)
99
+ end
114
100
  end
115
-
116
- string
117
- end
118
- end
119
-
120
- # Returns true if the underlying socket has been closed.
121
- def closed?
122
- socket.closed?
123
- end
124
-
125
- # Cleans up (see PacketStream#cleanup) and closes the underlying socket.
126
- def close
127
- socket.cleanup
128
- socket.close
129
- end
130
-
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
139
-
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
145
-
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
155
-
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
-
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
169
-
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
175
-
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
101
+
102
+ # Returns the host (and possibly IP address) in a format compatible with
103
+ # SSH known-host files.
104
+ def host_as_string
105
+ @host_as_string ||= begin
106
+ string = "#{host}"
107
+ string = "[#{string}]:#{port}" if port != DEFAULT_PORT
108
+
109
+ peer_ip = socket.peer_ip
110
+
111
+ if peer_ip != Net::SSH::Transport::PacketStream::PROXY_COMMAND_HOST_IP &&
112
+ peer_ip != host
113
+ string2 = peer_ip
114
+ string2 = "[#{string2}]:#{port}" if port != DEFAULT_PORT
115
+ string << "," << string2
116
+ end
117
+
118
+ string
119
+ end
191
120
  end
192
-
193
- packet = socket.next_packet(mode)
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
- push(packet)
121
+
122
+ # Returns true if the underlying socket has been closed.
123
+ def closed?
124
+ socket.closed?
215
125
  end
216
- end
217
- end
218
-
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
230
-
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
237
-
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
243
-
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
249
-
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
256
-
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
263
-
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
269
-
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
126
+
127
+ # Cleans up (see PacketStream#cleanup) and closes the underlying socket.
128
+ def close
129
+ socket.cleanup
130
+ socket.close
131
+ end
132
+
133
+ # Performs a "hard" shutdown of the connection. In general, this should
134
+ # never be done, but it might be necessary (in a rescue clause, for instance,
135
+ # when the connection needs to close but you don't know the status of the
136
+ # underlying protocol's state).
137
+ def shutdown!
138
+ error { "forcing connection closed" }
139
+ socket.close
140
+ end
141
+
142
+ # Returns a new service_request packet for the given service name, ready
143
+ # for sending to the server.
144
+ def service_request(service)
145
+ Net::SSH::Buffer.from(:byte, SERVICE_REQUEST, :string, service)
146
+ end
147
+
148
+ # Requests a rekey operation, and blocks until the operation completes.
149
+ # If a rekey is already pending, this returns immediately, having no
150
+ # effect.
151
+ def rekey!
152
+ if !algorithms.pending?
153
+ algorithms.rekey!
154
+ wait { algorithms.initialized? }
155
+ end
156
+ end
157
+
158
+ # Returns immediately if a rekey is already in process. Otherwise, if a
159
+ # rekey is needed (as indicated by the socket, see PacketStream#if_needs_rekey?)
160
+ # one is performed, causing this method to block until it completes.
161
+ def rekey_as_needed
162
+ return if algorithms.pending?
163
+ socket.if_needs_rekey? { rekey! }
164
+ end
165
+
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
171
+
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
177
+
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)
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
+ push(packet)
215
+ end
216
+ end
217
+ end
218
+
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
230
+
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
237
+
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
243
+
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
249
+
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
256
+
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
263
+
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
269
+
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
297
294
  else
298
- raise(
299
- ArgumentError,
300
- "Invalid argument to :verify_host_key (or deprecated " \
301
- ":paranoid): #{verify_host_key.inspect}"
302
- )
295
+ if verify_host_key.respond_to?(:verify)
296
+ verify_host_key
297
+ else
298
+ raise(
299
+ ArgumentError,
300
+ "Invalid argument to :verify_host_key (or deprecated " \
301
+ ":paranoid): #{verify_host_key.inspect}"
302
+ )
303
+ end
303
304
  end
304
305
  end
305
306
  end
307
+ end
306
308
  end
307
- end; end; end
309
+ end