net-ssh 8.0.0.rc2 → 8.0.0.rc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd6a3f2cc54c2b16873c1bcd92038d6c70e09581fd29c5a6674b708a76c9fec9
4
- data.tar.gz: 80fd4270605a25552b4cf7c0ca0c73b358f3806bd3a6654d15b94682fce0ff81
3
+ metadata.gz: 03f0ed4c48532bcfa337a176d655407155043de284d1428cd51a4bf2b7cb2f58
4
+ data.tar.gz: 49e8bbef56ac3139f5bb05cfad70afb33dda44227e9ce17f4424bd5aed749b95
5
5
  SHA512:
6
- metadata.gz: 0cd7d51126432199154b9aeeaf28dd6f0df05c6673c4ccf580b27a84c54d6865500b6ff4e2814e9242cc7dc882d3eec7d95000856b5b732dab97d493d1eabe83
7
- data.tar.gz: abce0bd3fcd5b47f74cc9fae9e684282e927b3af17c424e265f87aaf41fb85afbda631a588f080687804102a75692fa2086b8e82bda4af2d99ae824f2251b33d
6
+ metadata.gz: 56ec747abdff1eb6a0cbfb03adb3f880246372afe864f421c4241881671b9ce49dc1dc37a30c9e75e52526284b7c05caab1f14d367f94a1cdd422e1cf4aea93d
7
+ data.tar.gz: df092fc1f9da4c85eaf3b305890e0635b9d16d72b3bf05711180a9c28652d97a987be3011bbf7610363d0a9412dafa056c527172519a92c2bf77e7f228bcade8
checksums.yaml.gz.sig CHANGED
Binary file
@@ -1,6 +1,8 @@
1
1
  name: Rubocop
2
2
 
3
- on: [push]
3
+ on:
4
+ pull_request:
5
+ push: { branches: master }
4
6
 
5
7
  jobs:
6
8
  build:
data/CHANGES.txt CHANGED
@@ -1,3 +1,11 @@
1
+ === 8.0.0 rc3
2
+
3
+ * Fix "Calling Net::SSH::Buffer methods on HostKeyEntries PubKey is deprecated" warnings printed on every connection to a host in known_hosts [#1026, #1027]
4
+ * `ProxyJump none` now means no proxy instead of jumping through a host named "none", and `ProxyCommand none` is matched case-insensitively, as in OpenSSH [#893, #972, #1030]
5
+ * Send SIGHUP to the ProxyCommand process on close, as OpenSSH does, so tunnels such as EC2 Instance Connect Endpoint no longer hang at exit [#947]
6
+ * Reconnect when the ssh-agent closes the connection on the legacy version request (e.g. older Proton Pass) instead of raising FrozenError [#1008]
7
+ * ssh_config: parse `Key = value` lines like OpenSSH (the value no longer keeps the leading space, and the keyword ends at the first `=`), and honor ProxyJump/ProxyCommand before the first Host [#1034]
8
+
1
9
  === 8.0.0 rc2
2
10
 
3
11
  * Security: refuse agent channels opened by the server unless agent forwarding was requested (`forward_agent`, ForwardAgent, or `Forward#agent`); any use of port forwarding let a malicious server use the local ssh-agent [GHSA-qpg5-fx6p-8cq3]
@@ -17,6 +17,9 @@ module Net
17
17
  # An exception for indicating that the SSH agent is not available.
18
18
  class AgentNotAvailable < AgentError; end
19
19
 
20
+ # Raised when the agent closes the connection before replying.
21
+ class AgentClosedConnection < AgentError; end
22
+
20
23
  # This class implements a simple client for the ssh-agent protocol. It
21
24
  # does not implement any specific protocol, but instead copies the
22
25
  # behavior of the ssh-agent functions in the OpenSSH library (3.8).
@@ -83,12 +86,18 @@ module Net
83
86
  # socket reports that it is an SSH2-compatible agent, this will fail
84
87
  # (it only supports the ssh-agent distributed by OpenSSH).
85
88
  def connect!(agent_socket_factory = nil, identity_agent = nil)
89
+ @agent_socket_factory = agent_socket_factory
90
+ @identity_agent = identity_agent
91
+ open_agent_socket!
92
+ end
93
+
94
+ def open_agent_socket!
86
95
  debug { "connecting to ssh-agent" }
87
96
  @socket =
88
- if agent_socket_factory
89
- agent_socket_factory.call
90
- elsif identity_agent
91
- unix_socket_class.open(File.expand_path(identity_agent))
97
+ if @agent_socket_factory
98
+ @agent_socket_factory.call
99
+ elsif @identity_agent
100
+ unix_socket_class.open(File.expand_path(@identity_agent))
92
101
  elsif ENV['SSH_AUTH_SOCK'] && unix_socket_class
93
102
  unix_socket_class.open(File.expand_path(ENV['SSH_AUTH_SOCK']))
94
103
  elsif Gem.win_platform? && RUBY_ENGINE != "jruby"
@@ -100,6 +109,7 @@ module Net
100
109
  error { "could not connect to ssh-agent: #{e.message}" }
101
110
  raise AgentNotAvailable, $!.message
102
111
  end
112
+ private :open_agent_socket!
103
113
 
104
114
  # Attempts to negotiate the SSH agent protocol version. Raises an error
105
115
  # if the version could not be negotiated successfully.
@@ -114,6 +124,11 @@ module Net
114
124
  elsif type != SSH_AGENT_RSA_IDENTITIES_ANSWER1 && type != SSH_AGENT_RSA_IDENTITIES_ANSWER2
115
125
  raise AgentNotAvailable, "unknown response from agent: #{type}, #{body.to_s.inspect}"
116
126
  end
127
+ rescue AgentClosedConnection
128
+ # Agents built on ssh-agent-lib <= 0.6.0 (e.g. older Proton Pass) drop the connection on
129
+ # this legacy request but handle the rest of the protocol (#1008).
130
+ debug { "ssh-agent closed the connection on the version request; assuming a modern agent and reconnecting" }
131
+ open_agent_socket!
117
132
  end
118
133
 
119
134
  # Return an array of all identities (public keys) known to the agent.
@@ -223,8 +238,14 @@ module Net
223
238
  # tuple consisting of the packet type, and the packet's body (which
224
239
  # is returned as a Net::SSH::Buffer).
225
240
  def read_packet
226
- buffer = Net::SSH::Buffer.new(@socket.read(4))
227
- buffer.append(@socket.read(buffer.read_long))
241
+ header = @socket.read(4)
242
+ raise AgentClosedConnection, "agent closed the connection" if header.nil?
243
+
244
+ buffer = Net::SSH::Buffer.new(header)
245
+ body = @socket.read(buffer.read_long)
246
+ raise AgentClosedConnection, "agent closed the connection" if body.nil?
247
+
248
+ buffer.append(body)
228
249
  type = buffer.read_byte
229
250
  debug { "received agent packet #{type} len #{buffer.length - 4}" }
230
251
  return type, buffer
@@ -88,11 +88,8 @@ module Net
88
88
  IO.foreach(file) do |line|
89
89
  next if line =~ /^\s*(?:#.*)?$/
90
90
 
91
- if line =~ /^\s*(\S+)\s*=(.*)$/
92
- key, value = $1, $2
93
- else
94
- key, value = line.strip.split(/\s+/, 2)
95
- end
91
+ # As in OpenSSH, the keyword ends at the first whitespace or "=".
92
+ key, value = line.strip.split(/\s*=\s*|\s+/, 2)
96
93
 
97
94
  # silently ignore malformed entries
98
95
  next if value.nil?
@@ -152,9 +149,11 @@ module Net
152
149
  end
153
150
 
154
151
  # ProxyCommand and ProxyJump override each other so they need to be tracked togeather
155
- %w[proxyjump proxycommand].each do |proxy_key|
156
- if (proxy_value = settings.delete(proxy_key))
157
- settings['proxy'] ||= [proxy_key, proxy_value]
152
+ [globals, settings].each do |hash|
153
+ %w[proxyjump proxycommand].each do |proxy_key|
154
+ if (proxy_value = hash.delete(proxy_key))
155
+ hash['proxy'] ||= [proxy_key, proxy_value]
156
+ end
158
157
  end
159
158
  end
160
159
  end
@@ -302,13 +301,15 @@ module Net
302
301
  def setup_proxy(type, value)
303
302
  case type
304
303
  when 'proxycommand'
305
- if value !~ /^none$/
304
+ if value !~ /^none$/i
306
305
  require 'net/ssh/proxy/command'
307
306
  Net::SSH::Proxy::Command.new(value)
308
307
  end
309
308
  when 'proxyjump'
310
- require 'net/ssh/proxy/jump'
311
- Net::SSH::Proxy::Jump.new(value)
309
+ if value !~ /^none$/i
310
+ require 'net/ssh/proxy/jump'
311
+ Net::SSH::Proxy::Jump.new(value)
312
+ end
312
313
  end
313
314
  end
314
315
 
@@ -190,6 +190,7 @@ module Net
190
190
  def cleanup
191
191
  client.cleanup
192
192
  server.cleanup
193
+ hang_up_proxy_command
193
194
  end
194
195
 
195
196
  # If the IO object requires a rekey operation (as indicated by either its
@@ -205,6 +206,17 @@ module Net
205
206
 
206
207
  protected
207
208
 
209
+ # Like OpenSSH, hang up a ProxyCommand child: tunnels such as EC2 Instance
210
+ # Connect don't exit on their own, and IO#close waits for them.
211
+ def hang_up_proxy_command
212
+ return unless respond_to?(:pid)
213
+
214
+ child = pid
215
+ Process.kill('HUP', child) if child
216
+ rescue IOError, Errno::ESRCH
217
+ # already closed, or the child has already been reaped
218
+ end
219
+
208
220
  # Called when this module is used to extend an object. It initializes
209
221
  # the states and generally prepares the object for use as a packet stream.
210
222
  def initialize_ssh
@@ -51,6 +51,9 @@ module Net
51
51
  # implement them (Net::SSH::HostKeyEntries::CertAuthority). Non-certificate
52
52
  # entries do not respond to these predicates and are left untouched.
53
53
  def verify_certificate!(entry, host_keys, arguments)
54
+ # Plain keys carry no certificate constraints, and respond_to? on this delegator prints a deprecation warning (#1026).
55
+ return if entry.is_a?(Net::SSH::HostKeyEntries::PubKey)
56
+
54
57
  cert = arguments[:key]
55
58
 
56
59
  if entry.respond_to?(:matches_validity?) && !entry.matches_validity?(cert)
@@ -56,7 +56,7 @@ module Net
56
56
 
57
57
  # The prerelease component of this version of the Net::SSH library
58
58
  # nil allowed
59
- PRE = "rc2"
59
+ PRE = "rc3"
60
60
 
61
61
  # The current version of the Net::SSH library as a Version instance
62
62
  CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.0.0.rc2
4
+ version: 8.0.0.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
@@ -32,7 +32,7 @@ cert_chain:
32
32
  ufHf4AX2UIkJbh7zCPkiNCqIr7MSWLNFG/9lOlHYsEJM8XujT1ofPobYx6YSFx/C
33
33
  7HBrI7UX7awt6UvBZebhcHzyMHxg/B5PVQllPA==
34
34
  -----END CERTIFICATE-----
35
- date: 2026-10-05 00:00:00.000000000 Z
35
+ date: 2026-10-11 00:00:00.000000000 Z
36
36
  dependencies:
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: logger
metadata.gz.sig CHANGED
Binary file