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.
Files changed (199) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/FUNDING.yml +1 -0
  5. data/.github/config/rubocop_linter_action.yml +4 -0
  6. data/.github/workflows/ci-with-docker.yml +44 -0
  7. data/.github/workflows/ci.yml +94 -0
  8. data/.github/workflows/rubocop.yml +16 -0
  9. data/.gitignore +15 -0
  10. data/.rubocop.yml +22 -0
  11. data/.rubocop_todo.yml +1081 -0
  12. data/CHANGES.txt +387 -0
  13. data/DEVELOPMENT.md +23 -0
  14. data/Dockerfile +29 -0
  15. data/Dockerfile.openssl3 +17 -0
  16. data/Gemfile +13 -0
  17. data/Gemfile.noed25519 +12 -0
  18. data/Gemfile.norbnacl +12 -0
  19. data/ISSUE_TEMPLATE.md +30 -0
  20. data/Manifest +4 -5
  21. data/README.md +303 -0
  22. data/Rakefile +174 -40
  23. data/SECURITY.md +4 -0
  24. data/THANKS.txt +25 -0
  25. data/appveyor.yml +58 -0
  26. data/docker-compose.yml +25 -0
  27. data/lib/net/ssh/authentication/agent.rb +279 -18
  28. data/lib/net/ssh/authentication/certificate.rb +183 -0
  29. data/lib/net/ssh/authentication/constants.rb +17 -15
  30. data/lib/net/ssh/authentication/ed25519.rb +184 -0
  31. data/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
  32. data/lib/net/ssh/authentication/key_manager.rb +125 -54
  33. data/lib/net/ssh/authentication/methods/abstract.rb +67 -48
  34. data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
  35. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +19 -12
  36. data/lib/net/ssh/authentication/methods/none.rb +16 -19
  37. data/lib/net/ssh/authentication/methods/password.rb +56 -19
  38. data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
  39. data/lib/net/ssh/authentication/pageant.rb +483 -246
  40. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  41. data/lib/net/ssh/authentication/session.rb +138 -120
  42. data/lib/net/ssh/buffer.rb +399 -300
  43. data/lib/net/ssh/buffered_io.rb +154 -150
  44. data/lib/net/ssh/config.rb +361 -166
  45. data/lib/net/ssh/connection/channel.rb +640 -596
  46. data/lib/net/ssh/connection/constants.rb +29 -29
  47. data/lib/net/ssh/connection/event_loop.rb +123 -0
  48. data/lib/net/ssh/connection/keepalive.rb +59 -0
  49. data/lib/net/ssh/connection/session.rb +628 -548
  50. data/lib/net/ssh/connection/term.rb +125 -123
  51. data/lib/net/ssh/errors.rb +101 -95
  52. data/lib/net/ssh/key_factory.rb +198 -100
  53. data/lib/net/ssh/known_hosts.rb +221 -98
  54. data/lib/net/ssh/loggable.rb +50 -49
  55. data/lib/net/ssh/packet.rb +83 -79
  56. data/lib/net/ssh/prompt.rb +50 -81
  57. data/lib/net/ssh/proxy/command.rb +108 -60
  58. data/lib/net/ssh/proxy/errors.rb +12 -10
  59. data/lib/net/ssh/proxy/http.rb +82 -78
  60. data/lib/net/ssh/proxy/https.rb +50 -0
  61. data/lib/net/ssh/proxy/jump.rb +54 -0
  62. data/lib/net/ssh/proxy/socks4.rb +5 -8
  63. data/lib/net/ssh/proxy/socks5.rb +18 -20
  64. data/lib/net/ssh/service/forward.rb +383 -255
  65. data/lib/net/ssh/test/channel.rb +145 -136
  66. data/lib/net/ssh/test/extensions.rb +131 -110
  67. data/lib/net/ssh/test/kex.rb +34 -32
  68. data/lib/net/ssh/test/local_packet.rb +46 -44
  69. data/lib/net/ssh/test/packet.rb +89 -70
  70. data/lib/net/ssh/test/remote_packet.rb +32 -30
  71. data/lib/net/ssh/test/script.rb +156 -142
  72. data/lib/net/ssh/test/socket.rb +49 -48
  73. data/lib/net/ssh/test.rb +82 -77
  74. data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
  75. data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
  76. data/lib/net/ssh/transport/algorithms.rb +472 -348
  77. data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +117 -0
  78. data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +17 -0
  79. data/lib/net/ssh/transport/cipher_factory.rb +124 -100
  80. data/lib/net/ssh/transport/constants.rb +32 -24
  81. data/lib/net/ssh/transport/ctr.rb +42 -22
  82. data/lib/net/ssh/transport/gcm_cipher.rb +207 -0
  83. data/lib/net/ssh/transport/hmac/abstract.rb +97 -63
  84. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  85. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  86. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  87. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  88. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  89. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  90. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  91. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  92. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  93. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  94. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  95. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  96. data/lib/net/ssh/transport/hmac.rb +14 -12
  97. data/lib/net/ssh/transport/identity_cipher.rb +54 -44
  98. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  99. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  100. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  101. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  102. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
  103. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  104. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +119 -213
  105. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -61
  106. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  107. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
  108. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  109. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  110. data/lib/net/ssh/transport/kex.rb +15 -12
  111. data/lib/net/ssh/transport/key_expander.rb +24 -20
  112. data/lib/net/ssh/transport/openssl.rb +161 -124
  113. data/lib/net/ssh/transport/openssl_cipher_extensions.rb +8 -0
  114. data/lib/net/ssh/transport/packet_stream.rb +246 -183
  115. data/lib/net/ssh/transport/server_version.rb +57 -51
  116. data/lib/net/ssh/transport/session.rb +307 -235
  117. data/lib/net/ssh/transport/state.rb +178 -176
  118. data/lib/net/ssh/verifiers/accept_new.rb +33 -0
  119. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  120. data/lib/net/ssh/verifiers/always.rb +58 -0
  121. data/lib/net/ssh/verifiers/never.rb +19 -0
  122. data/lib/net/ssh/version.rb +57 -51
  123. data/lib/net/ssh.rb +140 -40
  124. data/net-ssh-public_cert.pem +21 -0
  125. data/net-ssh.gemspec +39 -184
  126. data/support/ssh_tunnel_bug.rb +5 -5
  127. data.tar.gz.sig +0 -0
  128. metadata +205 -99
  129. metadata.gz.sig +0 -0
  130. data/README.rdoc +0 -219
  131. data/Rudyfile +0 -96
  132. data/gem-public_cert.pem +0 -20
  133. data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
  134. data/lib/net/ssh/authentication/agent/socket.rb +0 -170
  135. data/lib/net/ssh/ruby_compat.rb +0 -51
  136. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  137. data/lib/net/ssh/verifiers/null.rb +0 -12
  138. data/lib/net/ssh/verifiers/secure.rb +0 -54
  139. data/lib/net/ssh/verifiers/strict.rb +0 -24
  140. data/setup.rb +0 -1585
  141. data/support/arcfour_check.rb +0 -20
  142. data/test/README.txt +0 -47
  143. data/test/authentication/methods/common.rb +0 -28
  144. data/test/authentication/methods/test_abstract.rb +0 -51
  145. data/test/authentication/methods/test_hostbased.rb +0 -114
  146. data/test/authentication/methods/test_keyboard_interactive.rb +0 -100
  147. data/test/authentication/methods/test_none.rb +0 -41
  148. data/test/authentication/methods/test_password.rb +0 -52
  149. data/test/authentication/methods/test_publickey.rb +0 -148
  150. data/test/authentication/test_agent.rb +0 -205
  151. data/test/authentication/test_key_manager.rb +0 -218
  152. data/test/authentication/test_session.rb +0 -108
  153. data/test/common.rb +0 -108
  154. data/test/configs/eqsign +0 -3
  155. data/test/configs/exact_match +0 -8
  156. data/test/configs/host_plus +0 -10
  157. data/test/configs/multihost +0 -4
  158. data/test/configs/nohost +0 -19
  159. data/test/configs/numeric_host +0 -4
  160. data/test/configs/send_env +0 -2
  161. data/test/configs/substitutes +0 -8
  162. data/test/configs/wild_cards +0 -14
  163. data/test/connection/test_channel.rb +0 -467
  164. data/test/connection/test_session.rb +0 -526
  165. data/test/known_hosts/github +0 -1
  166. data/test/manual/test_forward.rb +0 -223
  167. data/test/start/test_options.rb +0 -36
  168. data/test/start/test_transport.rb +0 -28
  169. data/test/test_all.rb +0 -11
  170. data/test/test_buffer.rb +0 -433
  171. data/test/test_buffered_io.rb +0 -63
  172. data/test/test_config.rb +0 -151
  173. data/test/test_key_factory.rb +0 -173
  174. data/test/test_known_hosts.rb +0 -13
  175. data/test/transport/hmac/test_md5.rb +0 -41
  176. data/test/transport/hmac/test_md5_96.rb +0 -27
  177. data/test/transport/hmac/test_none.rb +0 -34
  178. data/test/transport/hmac/test_ripemd160.rb +0 -36
  179. data/test/transport/hmac/test_sha1.rb +0 -36
  180. data/test/transport/hmac/test_sha1_96.rb +0 -27
  181. data/test/transport/hmac/test_sha2_256.rb +0 -37
  182. data/test/transport/hmac/test_sha2_256_96.rb +0 -27
  183. data/test/transport/hmac/test_sha2_512.rb +0 -37
  184. data/test/transport/hmac/test_sha2_512_96.rb +0 -27
  185. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +0 -13
  186. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -146
  187. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -92
  188. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +0 -34
  189. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +0 -161
  190. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +0 -38
  191. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +0 -38
  192. data/test/transport/test_algorithms.rb +0 -330
  193. data/test/transport/test_cipher_factory.rb +0 -443
  194. data/test/transport/test_hmac.rb +0 -34
  195. data/test/transport/test_identity_cipher.rb +0 -40
  196. data/test/transport/test_packet_stream.rb +0 -1755
  197. data/test/transport/test_server_version.rb +0 -78
  198. data/test/transport/test_session.rb +0 -319
  199. 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/null'
12
- require 'net/ssh/verifiers/secure'
13
- require 'net/ssh/verifiers/strict'
14
- require 'net/ssh/verifiers/lenient'
15
-
16
- module Net; module SSH; module Transport
17
-
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 Constants, Loggable
25
-
26
- # The standard port for the SSH protocol.
27
- DEFAULT_PORT = 22
28
-
29
- # The host to connect to, as given to the constructor.
30
- attr_reader :host
31
-
32
- # The port number to connect to, as given in the options to the constructor.
33
- # If no port number was given, this will default to DEFAULT_PORT.
34
- attr_reader :port
35
-
36
- # The underlying socket object being used to communicate with the remote
37
- # host.
38
- attr_reader :socket
39
-
40
- # The ServerVersion instance that encapsulates the negotiated protocol
41
- # version.
42
- attr_reader :server_version
43
-
44
- # The Algorithms instance used to perform key exchanges.
45
- attr_reader :algorithms
46
-
47
- # The host-key verifier object used to verify host keys, to ensure that
48
- # the connection is not being spoofed.
49
- attr_reader :host_key_verifier
50
-
51
- # The hash of options that were given to the object at initialization.
52
- attr_reader :options
53
-
54
- # Instantiates a new transport layer abstraction. This will block until
55
- # the initial key exchange completes, leaving you with a ready-to-use
56
- # transport session.
57
- def initialize(host, options={})
58
- self.logger = options[:logger]
59
-
60
- @host = host
61
- @port = options[:port] || DEFAULT_PORT
62
- @bind_address = options[:bind_address] || nil
63
- @options = options
64
-
65
- debug { "establishing connection to #{@host}:#{@port}" }
66
- factory = options[:proxy] || TCPSocket
67
- @socket = timeout(options[:timeout] || 0) { @bind_address.nil? || options[:proxy] ? factory.open(@host, @port) : factory.open(@host,@port,@bind_address) }
68
- @socket.extend(PacketStream)
69
- @socket.logger = @logger
70
-
71
- debug { "connection established" }
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
- @queue = []
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
- @host_key_verifier = select_host_key_verifier(options[:paranoid])
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
- @server_version = timeout(options[:timeout] || 0) { ServerVersion.new(socket, logger) }
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
- @algorithms = Algorithms.new(self, options)
81
- wait { algorithms.initialized? }
82
- end
117
+ string
118
+ end
119
+ end
83
120
 
84
- # Returns the host (and possibly IP address) in a format compatible with
85
- # SSH known-host files.
86
- def host_as_string
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
- # Returns true if the underlying socket has been closed.
100
- def closed?
101
- socket.closed?
102
- end
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
- # Cleans up (see PacketStream#cleanup) and closes the underlying socket.
105
- def close
106
- socket.cleanup
107
- socket.close
108
- 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
109
140
 
110
- # Performs a "hard" shutdown of the connection. In general, this should
111
- # never be done, but it might be necessary (in a rescue clause, for instance,
112
- # when the connection needs to close but you don't know the status of the
113
- # underlying protocol's state).
114
- def shutdown!
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
- # Returns a new service_request packet for the given service name, ready
120
- # for sending to the server.
121
- def service_request(service)
122
- Net::SSH::Buffer.from(:byte, SERVICE_REQUEST, :string, service)
123
- 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
124
156
 
125
- # Requests a rekey operation, and blocks until the operation completes.
126
- # If a rekey is already pending, this returns immediately, having no
127
- # effect.
128
- def rekey!
129
- if !algorithms.pending?
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
- # Returns immediately if a rekey is already in process. Otherwise, if a
136
- # rekey is needed (as indicated by the socket, see PacketStream#if_needs_rekey?)
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
- # Returns a hash of information about the peer (remote) side of the socket,
144
- # including :ip, :port, :host, and :canonized (see #host_as_string).
145
- def peer
146
- @peer ||= { :ip => socket.peer_ip, :port => @port.to_i, :host => @host, :canonized => host_as_string }
147
- 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
148
171
 
149
- # Blocks until a new packet is available to be read, and returns that
150
- # packet. See #poll_message.
151
- def next_message
152
- poll_message(:block)
153
- 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
154
177
 
155
- # Tries to read the next packet from the socket. If mode is :nonblock (the
156
- # default), this will not block and will return nil if there are no packets
157
- # waiting to be read. Otherwise, this will block until a packet is
158
- # available. Note that some packet types (DISCONNECT, IGNORE, UNIMPLEMENTED,
159
- # DEBUG, and KEXINIT) are handled silently by this method, and will never
160
- # be returned.
161
- #
162
- # If a key-exchange is in process and a disallowed packet type is
163
- # received, it will be enqueued and otherwise ignored. When a key-exchange
164
- # is not in process, and consume_queue is true, packets will be first
165
- # read from the queue before the socket is queried.
166
- def poll_message(mode=:nonblock, consume_queue=true)
167
- loop do
168
- if consume_queue && @queue.any? && algorithms.allow?(@queue.first)
169
- 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
170
218
  end
171
219
 
172
- packet = socket.next_packet(mode)
173
- 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
174
226
 
175
- case packet.type
176
- when DISCONNECT
177
- 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
178
232
 
179
- when IGNORE
180
- debug { "IGNORE packet recieved: #{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
181
239
 
182
- when UNIMPLEMENTED
183
- 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
184
245
 
185
- when DEBUG
186
- 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
187
251
 
188
- when KEXINIT
189
- 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
190
258
 
191
- else
192
- return packet if algorithms.allow?(packet)
193
- 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)
194
264
  end
195
- end
196
- end
197
265
 
198
- # Waits (blocks) until the given block returns true. If no block is given,
199
- # this just waits long enough to see if there are any pending packets. Any
200
- # packets read are enqueued (see #push).
201
- def wait
202
- loop do
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
- # Adds the given packet to the packet queue. If the queue is non-empty,
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
- # Sends the given message via the packet stream, blocking until the
218
- # entire message has been sent.
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
- # Enqueues the given message, such that it will be sent at the earliest
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
- # Configure's the packet stream's client state with the given set of
230
- # options. This is typically used to define the cipher, compression, and
231
- # hmac algorithms to use when sending packets to the server.
232
- def configure_client(options={})
233
- socket.client.set(options)
234
- 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
235
286
 
236
- # Configure's the packet stream's server state with the given set of
237
- # options. This is typically used to define the cipher, compression, and
238
- # hmac algorithms to use when reading packets from the server.
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
- # Sets a new hint for the packet stream, which the packet stream may use
244
- # to change its behavior. (See PacketStream#hints).
245
- def hint(which, value=true)
246
- socket.hints[which] = value
247
- end
291
+ def verify_signature(&block)
292
+ yield
293
+ end
294
+ end
248
295
 
249
- public
250
-
251
- # this method is primarily for use in tests
252
- attr_reader :queue #:nodoc:
253
-
254
- private
255
-
256
- # Instantiates a new host-key verification class, based on the value of
257
- # the parameter. When true or nil, the default Lenient verifier is
258
- # returned. If it is false, the Null verifier is returned, and if it is
259
- # :very, the Strict verifier is returned. If it is :secure, the even more
260
- # strict Secure verifier is returned. If the argument happens to respond
261
- # to :verify, it is returned directly. Otherwise, an exception
262
- # is raised.
263
- def select_host_key_verifier(paranoid)
264
- case paranoid
265
- when true, nil then
266
- Net::SSH::Verifiers::Lenient.new
267
- when false then
268
- Net::SSH::Verifiers::Null.new
269
- when :very then
270
- Net::SSH::Verifiers::Strict.new
271
- when :secure then
272
- Net::SSH::Verifiers::Secure.new
273
- else
274
- if paranoid.respond_to?(:verify)
275
- paranoid
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
- raise ArgumentError, "argument to :paranoid is not valid: #{paranoid.inspect}"
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; end; end
354
+ end