net-ssh 3.2.0.rc2 → 7.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +2 -2
  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 +16 -0
  8. data/.gitignore +13 -0
  9. data/.rubocop.yml +22 -0
  10. data/.rubocop_todo.yml +1081 -0
  11. data/CHANGES.txt +228 -7
  12. data/Dockerfile +27 -0
  13. data/Dockerfile.openssl3 +17 -0
  14. data/Gemfile +13 -0
  15. data/Gemfile.noed25519 +12 -0
  16. data/ISSUE_TEMPLATE.md +30 -0
  17. data/Manifest +4 -5
  18. data/README.md +297 -0
  19. data/Rakefile +125 -74
  20. data/SECURITY.md +4 -0
  21. data/appveyor.yml +58 -0
  22. data/docker-compose.yml +23 -0
  23. data/lib/net/ssh/authentication/agent.rb +279 -18
  24. data/lib/net/ssh/authentication/certificate.rb +183 -0
  25. data/lib/net/ssh/authentication/constants.rb +17 -15
  26. data/lib/net/ssh/authentication/ed25519.rb +186 -0
  27. data/lib/net/ssh/authentication/ed25519_loader.rb +31 -0
  28. data/lib/net/ssh/authentication/key_manager.rb +86 -39
  29. data/lib/net/ssh/authentication/methods/abstract.rb +67 -48
  30. data/lib/net/ssh/authentication/methods/hostbased.rb +34 -37
  31. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +13 -13
  32. data/lib/net/ssh/authentication/methods/none.rb +16 -19
  33. data/lib/net/ssh/authentication/methods/password.rb +27 -17
  34. data/lib/net/ssh/authentication/methods/publickey.rb +96 -55
  35. data/lib/net/ssh/authentication/pageant.rb +471 -367
  36. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +43 -0
  37. data/lib/net/ssh/authentication/session.rb +131 -121
  38. data/lib/net/ssh/buffer.rb +399 -300
  39. data/lib/net/ssh/buffered_io.rb +154 -150
  40. data/lib/net/ssh/config.rb +308 -185
  41. data/lib/net/ssh/connection/channel.rb +635 -613
  42. data/lib/net/ssh/connection/constants.rb +29 -29
  43. data/lib/net/ssh/connection/event_loop.rb +123 -0
  44. data/lib/net/ssh/connection/keepalive.rb +55 -51
  45. data/lib/net/ssh/connection/session.rb +620 -551
  46. data/lib/net/ssh/connection/term.rb +125 -123
  47. data/lib/net/ssh/errors.rb +101 -99
  48. data/lib/net/ssh/key_factory.rb +197 -105
  49. data/lib/net/ssh/known_hosts.rb +214 -127
  50. data/lib/net/ssh/loggable.rb +50 -49
  51. data/lib/net/ssh/packet.rb +83 -79
  52. data/lib/net/ssh/prompt.rb +50 -81
  53. data/lib/net/ssh/proxy/command.rb +105 -90
  54. data/lib/net/ssh/proxy/errors.rb +12 -10
  55. data/lib/net/ssh/proxy/http.rb +82 -79
  56. data/lib/net/ssh/proxy/https.rb +50 -0
  57. data/lib/net/ssh/proxy/jump.rb +54 -0
  58. data/lib/net/ssh/proxy/socks4.rb +2 -6
  59. data/lib/net/ssh/proxy/socks5.rb +14 -17
  60. data/lib/net/ssh/service/forward.rb +370 -317
  61. data/lib/net/ssh/test/channel.rb +145 -136
  62. data/lib/net/ssh/test/extensions.rb +131 -110
  63. data/lib/net/ssh/test/kex.rb +34 -32
  64. data/lib/net/ssh/test/local_packet.rb +46 -44
  65. data/lib/net/ssh/test/packet.rb +89 -70
  66. data/lib/net/ssh/test/remote_packet.rb +32 -30
  67. data/lib/net/ssh/test/script.rb +156 -142
  68. data/lib/net/ssh/test/socket.rb +49 -48
  69. data/lib/net/ssh/test.rb +82 -77
  70. data/lib/net/ssh/transport/algorithms.rb +441 -360
  71. data/lib/net/ssh/transport/cipher_factory.rb +96 -98
  72. data/lib/net/ssh/transport/constants.rb +32 -24
  73. data/lib/net/ssh/transport/ctr.rb +42 -22
  74. data/lib/net/ssh/transport/hmac/abstract.rb +81 -63
  75. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  76. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  77. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  78. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  79. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  80. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  81. data/lib/net/ssh/transport/hmac/sha2_256.rb +7 -11
  82. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +4 -8
  83. data/lib/net/ssh/transport/hmac/sha2_256_etm.rb +12 -0
  84. data/lib/net/ssh/transport/hmac/sha2_512.rb +6 -9
  85. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +4 -8
  86. data/lib/net/ssh/transport/hmac/sha2_512_etm.rb +12 -0
  87. data/lib/net/ssh/transport/hmac.rb +14 -12
  88. data/lib/net/ssh/transport/identity_cipher.rb +54 -52
  89. data/lib/net/ssh/transport/kex/abstract.rb +130 -0
  90. data/lib/net/ssh/transport/kex/abstract5656.rb +72 -0
  91. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +39 -0
  92. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +30 -0
  93. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +33 -40
  94. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  95. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +119 -213
  96. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -61
  97. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha256.rb +5 -9
  98. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +36 -90
  99. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +18 -10
  100. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +18 -10
  101. data/lib/net/ssh/transport/kex.rb +15 -12
  102. data/lib/net/ssh/transport/key_expander.rb +24 -20
  103. data/lib/net/ssh/transport/openssl.rb +161 -124
  104. data/lib/net/ssh/transport/packet_stream.rb +225 -185
  105. data/lib/net/ssh/transport/server_version.rb +55 -56
  106. data/lib/net/ssh/transport/session.rb +306 -255
  107. data/lib/net/ssh/transport/state.rb +178 -176
  108. data/lib/net/ssh/verifiers/accept_new.rb +33 -0
  109. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +33 -0
  110. data/lib/net/ssh/verifiers/always.rb +58 -0
  111. data/lib/net/ssh/verifiers/never.rb +19 -0
  112. data/lib/net/ssh/version.rb +55 -53
  113. data/lib/net/ssh.rb +110 -47
  114. data/net-ssh-public_cert.pem +18 -18
  115. data/net-ssh.gemspec +36 -205
  116. data/support/ssh_tunnel_bug.rb +5 -5
  117. data.tar.gz.sig +0 -0
  118. metadata +153 -118
  119. metadata.gz.sig +0 -0
  120. data/.travis.yml +0 -18
  121. data/README.rdoc +0 -182
  122. data/lib/net/ssh/authentication/agent/java_pageant.rb +0 -85
  123. data/lib/net/ssh/authentication/agent/socket.rb +0 -178
  124. data/lib/net/ssh/ruby_compat.rb +0 -46
  125. data/lib/net/ssh/verifiers/lenient.rb +0 -30
  126. data/lib/net/ssh/verifiers/null.rb +0 -12
  127. data/lib/net/ssh/verifiers/secure.rb +0 -52
  128. data/lib/net/ssh/verifiers/strict.rb +0 -24
  129. data/setup.rb +0 -1585
  130. data/support/arcfour_check.rb +0 -20
  131. data/test/README.txt +0 -18
  132. data/test/authentication/methods/common.rb +0 -28
  133. data/test/authentication/methods/test_abstract.rb +0 -51
  134. data/test/authentication/methods/test_hostbased.rb +0 -114
  135. data/test/authentication/methods/test_keyboard_interactive.rb +0 -121
  136. data/test/authentication/methods/test_none.rb +0 -41
  137. data/test/authentication/methods/test_password.rb +0 -95
  138. data/test/authentication/methods/test_publickey.rb +0 -148
  139. data/test/authentication/test_agent.rb +0 -232
  140. data/test/authentication/test_key_manager.rb +0 -240
  141. data/test/authentication/test_session.rb +0 -107
  142. data/test/common.rb +0 -125
  143. data/test/configs/auth_off +0 -5
  144. data/test/configs/auth_on +0 -4
  145. data/test/configs/empty +0 -0
  146. data/test/configs/eqsign +0 -3
  147. data/test/configs/exact_match +0 -8
  148. data/test/configs/host_plus +0 -10
  149. data/test/configs/multihost +0 -4
  150. data/test/configs/negative_match +0 -6
  151. data/test/configs/nohost +0 -19
  152. data/test/configs/numeric_host +0 -4
  153. data/test/configs/proxy_remote_user +0 -2
  154. data/test/configs/send_env +0 -2
  155. data/test/configs/substitutes +0 -8
  156. data/test/configs/wild_cards +0 -14
  157. data/test/connection/test_channel.rb +0 -487
  158. data/test/connection/test_session.rb +0 -564
  159. data/test/integration/README.txt +0 -17
  160. data/test/integration/Vagrantfile +0 -12
  161. data/test/integration/common.rb +0 -63
  162. data/test/integration/playbook.yml +0 -56
  163. data/test/integration/test_forward.rb +0 -637
  164. data/test/integration/test_id_rsa_keys.rb +0 -96
  165. data/test/integration/test_proxy.rb +0 -93
  166. data/test/known_hosts/github +0 -1
  167. data/test/known_hosts/github_hash +0 -1
  168. data/test/manual/test_pageant.rb +0 -37
  169. data/test/start/test_connection.rb +0 -53
  170. data/test/start/test_options.rb +0 -57
  171. data/test/start/test_transport.rb +0 -28
  172. data/test/start/test_user_nil.rb +0 -27
  173. data/test/test_all.rb +0 -12
  174. data/test/test_buffer.rb +0 -433
  175. data/test/test_buffered_io.rb +0 -63
  176. data/test/test_config.rb +0 -268
  177. data/test/test_key_factory.rb +0 -191
  178. data/test/test_known_hosts.rb +0 -66
  179. data/test/transport/hmac/test_md5.rb +0 -41
  180. data/test/transport/hmac/test_md5_96.rb +0 -27
  181. data/test/transport/hmac/test_none.rb +0 -34
  182. data/test/transport/hmac/test_ripemd160.rb +0 -36
  183. data/test/transport/hmac/test_sha1.rb +0 -36
  184. data/test/transport/hmac/test_sha1_96.rb +0 -27
  185. data/test/transport/hmac/test_sha2_256.rb +0 -37
  186. data/test/transport/hmac/test_sha2_256_96.rb +0 -27
  187. data/test/transport/hmac/test_sha2_512.rb +0 -37
  188. data/test/transport/hmac/test_sha2_512_96.rb +0 -27
  189. data/test/transport/kex/test_diffie_hellman_group14_sha1.rb +0 -13
  190. data/test/transport/kex/test_diffie_hellman_group1_sha1.rb +0 -150
  191. data/test/transport/kex/test_diffie_hellman_group_exchange_sha1.rb +0 -96
  192. data/test/transport/kex/test_diffie_hellman_group_exchange_sha256.rb +0 -19
  193. data/test/transport/kex/test_ecdh_sha2_nistp256.rb +0 -161
  194. data/test/transport/kex/test_ecdh_sha2_nistp384.rb +0 -38
  195. data/test/transport/kex/test_ecdh_sha2_nistp521.rb +0 -38
  196. data/test/transport/test_algorithms.rb +0 -328
  197. data/test/transport/test_cipher_factory.rb +0 -443
  198. data/test/transport/test_hmac.rb +0 -34
  199. data/test/transport/test_identity_cipher.rb +0 -40
  200. data/test/transport/test_packet_stream.rb +0 -1762
  201. data/test/transport/test_server_version.rb +0 -74
  202. data/test/transport/test_session.rb +0 -331
  203. data/test/transport/test_state.rb +0 -181
  204. data/test/verifiers/test_secure.rb +0 -40
@@ -7,297 +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
- debug { "establishing connection to #{@host}:#{@port}" }
65
-
66
- @socket =
67
- if (factory = options[:proxy])
68
- factory.open(@host, @port, options)
69
- else
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[:paranoid])
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 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
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(paranoid)
285
- case paranoid
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 paranoid.respond_to?(:verify)
296
- 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
297
334
  else
298
- 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
299
349
  end
300
350
  end
301
351
  end
352
+ end
302
353
  end
303
- end; end; end
354
+ end