net-ssh 7.2.0 → 8.0.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 (81) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +3 -0
  4. data/.github/pull_request_template.md +1 -0
  5. data/.github/workflows/changelog.yml +43 -0
  6. data/.github/workflows/ci-with-docker.yml +20 -9
  7. data/.github/workflows/ci.yml +11 -20
  8. data/.github/workflows/rubocop.yml +3 -1
  9. data/.gitignore +2 -0
  10. data/.rubocop.yml +1 -1
  11. data/.rubocop_todo.yml +4 -1
  12. data/CHANGES.txt +114 -0
  13. data/CONTRIBUTING.md +35 -0
  14. data/Dockerfile +7 -2
  15. data/Dockerfile.openssl3 +1 -1
  16. data/Dockerfile.zlib_ng +29 -0
  17. data/README.md +76 -57
  18. data/Rakefile +117 -30
  19. data/appveyor.yml +4 -16
  20. data/changelog.d/README.md +1 -0
  21. data/docker-compose.yml +2 -8
  22. data/lib/net/ssh/authentication/agent.rb +35 -11
  23. data/lib/net/ssh/authentication/ed25519.rb +141 -40
  24. data/lib/net/ssh/authentication/ed25519_loader.rb +14 -9
  25. data/lib/net/ssh/authentication/key_manager.rb +61 -18
  26. data/lib/net/ssh/authentication/methods/abstract.rb +2 -8
  27. data/lib/net/ssh/authentication/methods/publickey.rb +3 -1
  28. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +1 -1
  29. data/lib/net/ssh/authentication/security_key.rb +71 -0
  30. data/lib/net/ssh/authentication/session.rb +34 -15
  31. data/lib/net/ssh/buffer.rb +6 -1
  32. data/lib/net/ssh/buffered_io.rb +41 -4
  33. data/lib/net/ssh/config.rb +30 -13
  34. data/lib/net/ssh/connection/channel.rb +49 -2
  35. data/lib/net/ssh/connection/session.rb +58 -8
  36. data/lib/net/ssh/errors.rb +24 -6
  37. data/lib/net/ssh/key_factory.rb +11 -4
  38. data/lib/net/ssh/known_hosts.rb +64 -11
  39. data/lib/net/ssh/multiplex/client.rb +162 -0
  40. data/lib/net/ssh/multiplex/control_path.rb +120 -0
  41. data/lib/net/ssh/multiplex/proxy_transport.rb +218 -0
  42. data/lib/net/ssh/multiplex.rb +130 -0
  43. data/lib/net/ssh/prompt.rb +3 -3
  44. data/lib/net/ssh/proxy/command.rb +28 -3
  45. data/lib/net/ssh/proxy/jump.rb +52 -4
  46. data/lib/net/ssh/service/forward.rb +38 -27
  47. data/lib/net/ssh/test/extensions.rb +3 -2
  48. data/lib/net/ssh/test/socket.rb +1 -1
  49. data/lib/net/ssh/test.rb +2 -1
  50. data/lib/net/ssh/transport/aes128_gcm.rb +40 -0
  51. data/lib/net/ssh/transport/aes256_gcm.rb +40 -0
  52. data/lib/net/ssh/transport/algorithms.rb +96 -34
  53. data/lib/net/ssh/transport/chacha20_poly1305_cipher.rb +89 -16
  54. data/lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb +20 -1
  55. data/lib/net/ssh/transport/cipher_factory.rb +32 -8
  56. data/lib/net/ssh/transport/constants.rb +1 -0
  57. data/lib/net/ssh/transport/gcm_cipher.rb +228 -0
  58. data/lib/net/ssh/transport/hmac/abstract.rb +16 -0
  59. data/lib/net/ssh/transport/hmac/sha1_etm.rb +12 -0
  60. data/lib/net/ssh/transport/hmac.rb +2 -0
  61. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +41 -9
  62. data/lib/net/ssh/transport/kex/curve25519_sha256_loader.rb +14 -6
  63. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +8 -0
  64. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +45 -15
  65. data/lib/net/ssh/transport/openssl.rb +2 -1
  66. data/lib/net/ssh/transport/packet_stream.rb +19 -3
  67. data/lib/net/ssh/transport/server_version.rb +33 -13
  68. data/lib/net/ssh/transport/session.rb +60 -46
  69. data/lib/net/ssh/transport/state.rb +1 -1
  70. data/lib/net/ssh/verifiers/always.rb +43 -8
  71. data/lib/net/ssh/version.rb +2 -2
  72. data/lib/net/ssh.rb +142 -62
  73. data/net-ssh-public_cert.pem +19 -18
  74. data/net-ssh.gemspec +7 -8
  75. data/rakelib/changelog.rb +229 -0
  76. data.tar.gz.sig +0 -0
  77. metadata +86 -53
  78. metadata.gz.sig +1 -1
  79. data/Gemfile.noed25519 +0 -12
  80. data/Gemfile.norbnacl +0 -12
  81. data/lib/net/ssh/version.rb.old +0 -68
@@ -1,20 +1,21 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIIDQDCCAiigAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpuZXRz
3
- c2gvREM9c29sdXRpb3VzL0RDPWNvbTAeFw0yMzAxMjQwMzE3NTVaFw0yNDAxMjQw
4
- MzE3NTVaMCUxIzAhBgNVBAMMGm5ldHNzaC9EQz1zb2x1dGlvdXMvREM9Y29tMIIB
5
- IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxieE22fR/qmdPKUHyYTyUx2g
6
- wskLwrCkxay+Tvc97ZZUOwf85LDDDPqhQaTWLvRwnIOMgQE2nBPzwalVclK6a+pW
7
- x/18KDeZY15vm3Qn5p42b0wi9hUxOqPm3J2hdCLCcgtENgdX21nVzejn39WVqFJO
8
- lntgSDNW5+kCS8QaRsmIbzj17GKKkrsw39kiQw7FhWfJFeTjddzoZiWwc59KA/Bx
9
- fBbmDnsMLAtAtauMOxORrbx3EOY7sHku/kSrMg3FXFay7jc6BkbbUij+MjJ/k82l
10
- 4o8o0YO4BAnya90xgEmgOG0LCCxRhuXQFnMDuDjK2XnUe0h4/6NCn94C+z9GsQID
11
- AQABo3sweTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUBfKiwO2e
12
- M4NEiRrVG793qEPLYyMwHwYDVR0RBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20w
13
- HwYDVR0SBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20wDQYJKoZIhvcNAQELBQAD
14
- ggEBAHyOSaOUji+EJFWZ46g+2EZ/kG7EFloFtIQUz8jDJIWGE+3NV5po1M0Z6EqH
15
- XmG3BtMLfgOV9NwMQRqIdKnZDfKsqM/FOu+9IqrP+OieAde5OrXR2pzQls60Xft7
16
- 3qNVaQS99woQRqiUiDQQ7WagOYrZjuVANqTDNt4myzGSjS5sHcKlz3PRn0LJRMe5
17
- ouuLwQ7BCXityv5RRXex2ibCOyY7pB5ris6xDnPe1WdlyCfUf1Fb+Yqxpy6a8QmH
18
- v84waVXQ2i5M7pJaHVBF7DxxeW/q8W3VCnsq8vmmvULSThD18QqYGaFDJeN8sTR4
19
- 6tfjgZ6OvGSScvbCMHkCE9XjonE=
2
+ MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQ8wDQYDVQQDDAZuZXRz
3
+ c2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
4
+ b20wHhcNMjYwMjE1MTAxNzUyWhcNMjcwMjE1MTAxNzUyWjBBMQ8wDQYDVQQDDAZu
5
+ ZXRzc2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
6
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGJ4TbZ9H+qZ08
7
+ pQfJhPJTHaDCyQvCsKTFrL5O9z3tllQ7B/zksMMM+qFBpNYu9HCcg4yBATacE/PB
8
+ qVVyUrpr6lbH/XwoN5ljXm+bdCfmnjZvTCL2FTE6o+bcnaF0IsJyC0Q2B1fbWdXN
9
+ 6Off1ZWoUk6We2BIM1bn6QJLxBpGyYhvOPXsYoqSuzDf2SJDDsWFZ8kV5ON13Ohm
10
+ JbBzn0oD8HF8FuYOewwsC0C1q4w7E5GtvHcQ5juweS7+RKsyDcVcVrLuNzoGRttS
11
+ KP4yMn+TzaXijyjRg7gECfJr3TGASaA4bQsILFGG5dAWcwO4OMrZedR7SHj/o0Kf
12
+ 3gL7P0axAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
13
+ BBQF8qLA7Z4zg0SJGtUbv3eoQ8tjIzAfBgNVHREEGDAWgRRuZXRzc2hAc29sdXRp
14
+ b3VzLmNvbTAfBgNVHRIEGDAWgRRuZXRzc2hAc29sdXRpb3VzLmNvbTANBgkqhkiG
15
+ 9w0BAQsFAAOCAQEASsiVybehJLRPztFeFV8+SKa2BwbBSNJoAkhARVJKhpJxCfeY
16
+ gO7Kqb7JCykzb0anb1s6xTrzD03cWRNGE2YaoBLqnzeUqW1LPqVwmcySmnSIGH9F
17
+ DlFYlHaAn3oSqglyDxQx9bLngKatetx+tSfB3bLAb7Tr9PO8/lhBENbjlD4+UUwD
18
+ gApoZuD9pknWDH3KsITgzphswETBdo0hd9aLnRNR3EifD0lUIEit/0Yx6euSxWtI
19
+ ufHf4AX2UIkJbh7zCPkiNCqIr7MSWLNFG/9lOlHYsEJM8XujT1ofPobYx6YSFx/C
20
+ 7HBrI7UX7awt6UvBZebhcHzyMHxg/B5PVQllPA==
20
21
  -----END CERTIFICATE-----
data/net-ssh.gemspec CHANGED
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.description = %q{Net::SSH: a pure-Ruby implementation of the SSH2 client protocol. It allows you to write programs that invoke and interact with processes on remote servers, via SSH2.}
16
16
  spec.homepage = "https://github.com/net-ssh/net-ssh"
17
17
  spec.license = "MIT"
18
- spec.required_ruby_version = Gem::Requirement.new(">= 2.6")
18
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.7")
19
19
  spec.metadata = {
20
20
  "changelog_uri" => "https://github.com/net-ssh/net-ssh/blob/master/CHANGES.txt"
21
21
  }
@@ -30,17 +30,16 @@ Gem::Specification.new do |spec|
30
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ["lib"]
32
32
 
33
- unless ENV['NET_SSH_NO_ED25519']
34
- spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0") unless RUBY_PLATFORM == "java"
35
- spec.add_development_dependency("ed25519", "~> 1.2")
36
- spec.add_development_dependency('x25519') unless RUBY_PLATFORM == 'java'
37
- end
33
+ spec.add_dependency("logger")
34
+ spec.add_dependency("openssl", ">= 3.2.0")
38
35
 
39
- spec.add_development_dependency('rbnacl', '~> 7.1') unless ENV['NET_SSH_NO_RBNACL']
36
+ spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0") unless RUBY_PLATFORM == "java"
40
37
 
38
+ spec.add_development_dependency "base64"
41
39
  spec.add_development_dependency "bundler", ">= 1.17"
42
40
  spec.add_development_dependency "minitest", "~> 5.19"
43
- spec.add_development_dependency "mocha", "~> 2.1.0"
41
+ spec.add_development_dependency "mocha", ">= 2.1", "< 4"
42
+ spec.add_development_dependency "ostruct"
44
43
  spec.add_development_dependency "rake", "~> 12.0"
45
44
  spec.add_development_dependency "rubocop", "~> 1.28.0"
46
45
  end
@@ -0,0 +1,229 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'open3'
5
+
6
+ # Builds CHANGES.txt sections from the fragment files in changelog.d/ (see CONTRIBUTING.md).
7
+ class Changelog
8
+ class Error < StandardError; end
9
+
10
+ # Output order of the groups in a release section; `none` fragments are never emitted.
11
+ TYPES = {
12
+ 'breaking-security' => 'BREAKING: Security: ',
13
+ 'breaking' => 'BREAKING: ',
14
+ 'security' => 'Security: ',
15
+ 'change' => '',
16
+ 'none' => nil
17
+ }.freeze
18
+
19
+ FILENAME = /\A(?<number>[1-9]\d*)\.(?<type>[a-z-]+)(?:\.(?<seq>[1-9]\d*))?\.txt\z/.freeze
20
+ REF = /#\d+|GHSA(?:-[a-z0-9]{4}){3}|CVE-\d{4}-\d+/i.freeze
21
+ REF_LIST = /\[(?:#{REF})(?:,\s*(?:#{REF}))*\]\z/.freeze
22
+ UNRELEASED = '=== Unreleased'
23
+ PLACEHOLDER = 'TODO: describe the change as it should read in CHANGES.txt'
24
+
25
+ Fragment = Struct.new(:path, :number, :type, :seq, :text) do
26
+ def entry
27
+ "#{TYPES.fetch(type)}#{text}"
28
+ end
29
+
30
+ def sort_key
31
+ [-number, seq]
32
+ end
33
+ end
34
+
35
+ attr_reader :dir, :changes_path
36
+
37
+ def initialize(root)
38
+ @root = root
39
+ @dir = File.join(root, 'changelog.d')
40
+ @changes_path = File.join(root, 'CHANGES.txt')
41
+ end
42
+
43
+ # Raises Error listing every invalid fragment; returns all fragments, including `none` ones.
44
+ def fragments
45
+ errors = []
46
+ fragments = []
47
+ entries_in_dir.each do |name|
48
+ result = parse_fragment(name)
49
+ result.is_a?(Fragment) ? fragments << result : errors << "changelog.d/#{name}: #{result}"
50
+ end
51
+ raise Error, "Invalid changelog fragments:\n #{errors.join("\n ")}" unless errors.empty?
52
+
53
+ fragments.sort_by(&:sort_key)
54
+ end
55
+
56
+ # Validates the fragments and the `=== Unreleased` section of CHANGES.txt; returns the fragments.
57
+ def check
58
+ all = fragments
59
+ split_changes(read_changes)
60
+ all
61
+ end
62
+
63
+ # The text of the section for +heading+, or nil for a pre-release with nothing to release.
64
+ def section(heading)
65
+ assemble(heading, fragments, split_changes(read_changes))
66
+ end
67
+
68
+ # Writes the section for +heading+ to the top of CHANGES.txt, folding in any `=== Unreleased`
69
+ # entries, and removes all fragments; returns the section, or nil when CHANGES.txt was left unchanged.
70
+ def release(heading)
71
+ all = fragments
72
+ content = read_changes
73
+ raise Error, "CHANGES.txt already has a '=== #{heading}' section" if content.lines.any? { |l| l.chomp == "=== #{heading}" }
74
+
75
+ parts = split_changes(content)
76
+ section = assemble(heading, all, parts)
77
+ if section
78
+ rest = parts[:rest].empty? ? '' : "\n#{parts[:rest]}"
79
+ File.write(changes_path, "#{parts[:preamble]}#{section}#{rest}")
80
+ end
81
+ remove(all.map(&:path))
82
+ section
83
+ end
84
+
85
+ # Creates a fragment for PR +number+ and returns its path; picks the next free `.N` suffix if needed.
86
+ def new_fragment(number, type, text = nil)
87
+ path = (1..).lazy.map { |seq| File.join(dir, fragment_name(number, type, seq)) }.find { |p| !File.exist?(p) }
88
+ error = validate_name(File.basename(path))
89
+ raise Error, error if error
90
+
91
+ FileUtils.mkdir_p(dir)
92
+ text = PLACEHOLDER if (text.nil? || text.strip.empty?) && type != 'none'
93
+ File.write(path, "#{text}\n")
94
+ path
95
+ end
96
+
97
+ def self.heading(major, minor, tiny, pre)
98
+ ["#{major}.#{minor}.#{tiny}", pre].compact.join(' ')
99
+ end
100
+
101
+ private
102
+
103
+ def entries_in_dir
104
+ return [] unless Dir.exist?(dir)
105
+
106
+ Dir.children(dir).sort.reject { |name| name == 'README.md' || name.start_with?('.') }
107
+ end
108
+
109
+ def fragment_name(number, type, seq)
110
+ seq == 1 ? "#{number}.#{type}.txt" : "#{number}.#{type}.#{seq}.txt"
111
+ end
112
+
113
+ def validate_name(name)
114
+ match = FILENAME.match(name)
115
+ return "file name must be <PR number>.<type>[.<n>].txt, types: #{TYPES.keys.join(', ')}" unless match
116
+ return "unknown type '#{match[:type]}', expected one of: #{TYPES.keys.join(', ')}" unless TYPES.key?(match[:type])
117
+
118
+ nil
119
+ end
120
+
121
+ # Returns a Fragment, or an error message.
122
+ def parse_fragment(name)
123
+ path = File.join(dir, name)
124
+ return 'is not a file' unless File.file?(path)
125
+
126
+ error = validate_name(name)
127
+ return error if error
128
+
129
+ match = FILENAME.match(name)
130
+ fragment = Fragment.new(path, match[:number].to_i, match[:type], (match[:seq] || 1).to_i, nil)
131
+ return fragment if fragment.type == 'none'
132
+
133
+ text = parse_text(read_utf8(path))
134
+ return text[:error] if text[:error]
135
+
136
+ fragment.text = text[:text]
137
+ fragment.text = "#{fragment.text} [##{fragment.number}]" unless fragment.text.match?(REF_LIST)
138
+ fragment
139
+ end
140
+
141
+ def parse_text(raw)
142
+ return { error: 'is not valid UTF-8' } unless raw.valid_encoding?
143
+
144
+ lines = raw.strip.lines.map(&:strip)
145
+ return { error: 'is empty' } if lines.empty?
146
+ return { error: 'must be a single paragraph (no blank lines)' } if lines.include?('')
147
+
148
+ text = lines.join(' ')
149
+ return { error: 'still contains the placeholder text' } if text == PLACEHOLDER
150
+ return { error: "should not start with a bullet, it's added when assembling" } if text.match?(/\A[*-] /)
151
+ return { error: 'should not start with BREAKING:/Security:, the type adds the prefix' } if text.match?(/\A(BREAKING|Security):/i)
152
+
153
+ { text: text }
154
+ end
155
+
156
+ def read_changes
157
+ File.exist?(changes_path) ? read_utf8(changes_path).gsub("\r\n", "\n") : ''
158
+ end
159
+
160
+ # Explicit so a non-UTF-8 locale (e.g. LANG=C) doesn't break on non-ASCII text.
161
+ def read_utf8(path)
162
+ File.read(path, mode: 'r:bom|utf-8')
163
+ end
164
+
165
+ # A final release (a heading without a pre-release suffix) always gets a section, so every published version has a heading.
166
+ def assemble(heading, fragments, parts)
167
+ entries = grouped_entries(fragments, parts[:unreleased])
168
+ if entries.empty?
169
+ return nil unless heading.match?(/\A\d+\.\d+\.\d+\z/)
170
+
171
+ previous = parts[:rest][/\A=== (.+)$/, 1]
172
+ entries = [" * #{previous ? "No changes since #{previous}." : 'No changes.'}\n"]
173
+ end
174
+ "=== #{heading}\n\n#{entries.join}"
175
+ end
176
+
177
+ # Splits CHANGES.txt into the text before the first heading, the entries of a leading
178
+ # `=== Unreleased` section (as lists of raw lines) and everything from the first released heading on.
179
+ def split_changes(content)
180
+ lines = content.lines
181
+ first = lines.index { |l| l.start_with?('=== ') } || lines.size
182
+ preamble = lines[0...first].join
183
+ return { preamble: preamble, unreleased: [], rest: lines[first..].join } unless lines[first]&.chomp == UNRELEASED
184
+
185
+ body_end = lines.index.with_index { |l, i| i > first && l.start_with?('=== ') } || lines.size
186
+ { preamble: preamble, unreleased: unreleased_entries(lines[(first + 1)...body_end]), rest: lines[body_end..].join }
187
+ end
188
+
189
+ def unreleased_entries(lines)
190
+ lines.each_with_object([]) do |line, entries|
191
+ next if line.strip.empty?
192
+
193
+ if line.match?(/\A\s*\* /)
194
+ entries << [line]
195
+ elsif entries.empty?
196
+ raise Error, "Cannot parse the Unreleased section of CHANGES.txt near: #{line.strip}"
197
+ else
198
+ entries.last << line
199
+ end
200
+ end
201
+ end
202
+
203
+ # Fragments come before the hand-written Unreleased entries of the same group.
204
+ def grouped_entries(fragments, unreleased)
205
+ TYPES.keys.flat_map do |type|
206
+ from_fragments = fragments.select { |f| f.type == type && type != 'none' }.map { |f| " * #{f.entry}\n" }
207
+ from_unreleased = unreleased.select { |lines| unreleased_type(lines.first) == type }.map do |lines|
208
+ lines.join.end_with?("\n") ? lines.join : "#{lines.join}\n"
209
+ end
210
+ from_fragments + from_unreleased
211
+ end
212
+ end
213
+
214
+ def unreleased_type(line)
215
+ text = line.sub(/\A\s*\* /, '')
216
+ TYPES.find { |_type, prefix| prefix && !prefix.empty? && text.start_with?(prefix) }&.first || 'change'
217
+ end
218
+
219
+ # `git rm` so the deletions are staged with the version bump; plain delete outside a git checkout.
220
+ def remove(paths)
221
+ return if paths.empty?
222
+
223
+ relative = paths.map { |p| p.delete_prefix("#{@root}/") }
224
+ _out, status = Open3.capture2e('git', '-C', @root, 'rm', '-q', '--', *relative)
225
+ FileUtils.rm_f(paths) unless status.success?
226
+ rescue SystemCallError
227
+ FileUtils.rm_f(paths)
228
+ end
229
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,94 +1,95 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.0
4
+ version: 8.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
8
8
  - Delano Mandelbaum
9
9
  - Miklós Fazekas
10
- autorequire:
10
+ autorequire:
11
11
  bindir: exe
12
12
  cert_chain:
13
13
  - |
14
14
  -----BEGIN CERTIFICATE-----
15
- MIIDQDCCAiigAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpuZXRz
16
- c2gvREM9c29sdXRpb3VzL0RDPWNvbTAeFw0yMzAxMjQwMzE3NTVaFw0yNDAxMjQw
17
- MzE3NTVaMCUxIzAhBgNVBAMMGm5ldHNzaC9EQz1zb2x1dGlvdXMvREM9Y29tMIIB
18
- IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxieE22fR/qmdPKUHyYTyUx2g
19
- wskLwrCkxay+Tvc97ZZUOwf85LDDDPqhQaTWLvRwnIOMgQE2nBPzwalVclK6a+pW
20
- x/18KDeZY15vm3Qn5p42b0wi9hUxOqPm3J2hdCLCcgtENgdX21nVzejn39WVqFJO
21
- lntgSDNW5+kCS8QaRsmIbzj17GKKkrsw39kiQw7FhWfJFeTjddzoZiWwc59KA/Bx
22
- fBbmDnsMLAtAtauMOxORrbx3EOY7sHku/kSrMg3FXFay7jc6BkbbUij+MjJ/k82l
23
- 4o8o0YO4BAnya90xgEmgOG0LCCxRhuXQFnMDuDjK2XnUe0h4/6NCn94C+z9GsQID
24
- AQABo3sweTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUBfKiwO2e
25
- M4NEiRrVG793qEPLYyMwHwYDVR0RBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20w
26
- HwYDVR0SBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20wDQYJKoZIhvcNAQELBQAD
27
- ggEBAHyOSaOUji+EJFWZ46g+2EZ/kG7EFloFtIQUz8jDJIWGE+3NV5po1M0Z6EqH
28
- XmG3BtMLfgOV9NwMQRqIdKnZDfKsqM/FOu+9IqrP+OieAde5OrXR2pzQls60Xft7
29
- 3qNVaQS99woQRqiUiDQQ7WagOYrZjuVANqTDNt4myzGSjS5sHcKlz3PRn0LJRMe5
30
- ouuLwQ7BCXityv5RRXex2ibCOyY7pB5ris6xDnPe1WdlyCfUf1Fb+Yqxpy6a8QmH
31
- v84waVXQ2i5M7pJaHVBF7DxxeW/q8W3VCnsq8vmmvULSThD18QqYGaFDJeN8sTR4
32
- 6tfjgZ6OvGSScvbCMHkCE9XjonE=
15
+ MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQ8wDQYDVQQDDAZuZXRz
16
+ c2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
17
+ b20wHhcNMjYwMjE1MTAxNzUyWhcNMjcwMjE1MTAxNzUyWjBBMQ8wDQYDVQQDDAZu
18
+ ZXRzc2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
19
+ FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGJ4TbZ9H+qZ08
20
+ pQfJhPJTHaDCyQvCsKTFrL5O9z3tllQ7B/zksMMM+qFBpNYu9HCcg4yBATacE/PB
21
+ qVVyUrpr6lbH/XwoN5ljXm+bdCfmnjZvTCL2FTE6o+bcnaF0IsJyC0Q2B1fbWdXN
22
+ 6Off1ZWoUk6We2BIM1bn6QJLxBpGyYhvOPXsYoqSuzDf2SJDDsWFZ8kV5ON13Ohm
23
+ JbBzn0oD8HF8FuYOewwsC0C1q4w7E5GtvHcQ5juweS7+RKsyDcVcVrLuNzoGRttS
24
+ KP4yMn+TzaXijyjRg7gECfJr3TGASaA4bQsILFGG5dAWcwO4OMrZedR7SHj/o0Kf
25
+ 3gL7P0axAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
26
+ BBQF8qLA7Z4zg0SJGtUbv3eoQ8tjIzAfBgNVHREEGDAWgRRuZXRzc2hAc29sdXRp
27
+ b3VzLmNvbTAfBgNVHRIEGDAWgRRuZXRzc2hAc29sdXRpb3VzLmNvbTANBgkqhkiG
28
+ 9w0BAQsFAAOCAQEASsiVybehJLRPztFeFV8+SKa2BwbBSNJoAkhARVJKhpJxCfeY
29
+ gO7Kqb7JCykzb0anb1s6xTrzD03cWRNGE2YaoBLqnzeUqW1LPqVwmcySmnSIGH9F
30
+ DlFYlHaAn3oSqglyDxQx9bLngKatetx+tSfB3bLAb7Tr9PO8/lhBENbjlD4+UUwD
31
+ gApoZuD9pknWDH3KsITgzphswETBdo0hd9aLnRNR3EifD0lUIEit/0Yx6euSxWtI
32
+ ufHf4AX2UIkJbh7zCPkiNCqIr7MSWLNFG/9lOlHYsEJM8XujT1ofPobYx6YSFx/C
33
+ 7HBrI7UX7awt6UvBZebhcHzyMHxg/B5PVQllPA==
33
34
  -----END CERTIFICATE-----
34
- date: 2023-07-30 00:00:00.000000000 Z
35
+ date: 2026-10-21 00:00:00.000000000 Z
35
36
  dependencies:
36
37
  - !ruby/object:Gem::Dependency
37
- name: bcrypt_pbkdf
38
+ name: logger
38
39
  requirement: !ruby/object:Gem::Requirement
39
40
  requirements:
40
- - - "~>"
41
+ - - ">="
41
42
  - !ruby/object:Gem::Version
42
- version: '1.0'
43
- type: :development
43
+ version: '0'
44
+ type: :runtime
44
45
  prerelease: false
45
46
  version_requirements: !ruby/object:Gem::Requirement
46
47
  requirements:
47
- - - "~>"
48
+ - - ">="
48
49
  - !ruby/object:Gem::Version
49
- version: '1.0'
50
+ version: '0'
50
51
  - !ruby/object:Gem::Dependency
51
- name: ed25519
52
+ name: openssl
52
53
  requirement: !ruby/object:Gem::Requirement
53
54
  requirements:
54
- - - "~>"
55
+ - - ">="
55
56
  - !ruby/object:Gem::Version
56
- version: '1.2'
57
- type: :development
57
+ version: 3.2.0
58
+ type: :runtime
58
59
  prerelease: false
59
60
  version_requirements: !ruby/object:Gem::Requirement
60
61
  requirements:
61
- - - "~>"
62
+ - - ">="
62
63
  - !ruby/object:Gem::Version
63
- version: '1.2'
64
+ version: 3.2.0
64
65
  - !ruby/object:Gem::Dependency
65
- name: x25519
66
+ name: bcrypt_pbkdf
66
67
  requirement: !ruby/object:Gem::Requirement
67
68
  requirements:
68
- - - ">="
69
+ - - "~>"
69
70
  - !ruby/object:Gem::Version
70
- version: '0'
71
+ version: '1.0'
71
72
  type: :development
72
73
  prerelease: false
73
74
  version_requirements: !ruby/object:Gem::Requirement
74
75
  requirements:
75
- - - ">="
76
+ - - "~>"
76
77
  - !ruby/object:Gem::Version
77
- version: '0'
78
+ version: '1.0'
78
79
  - !ruby/object:Gem::Dependency
79
- name: rbnacl
80
+ name: base64
80
81
  requirement: !ruby/object:Gem::Requirement
81
82
  requirements:
82
- - - "~>"
83
+ - - ">="
83
84
  - !ruby/object:Gem::Version
84
- version: '7.1'
85
+ version: '0'
85
86
  type: :development
86
87
  prerelease: false
87
88
  version_requirements: !ruby/object:Gem::Requirement
88
89
  requirements:
89
- - - "~>"
90
+ - - ">="
90
91
  - !ruby/object:Gem::Version
91
- version: '7.1'
92
+ version: '0'
92
93
  - !ruby/object:Gem::Dependency
93
94
  name: bundler
94
95
  requirement: !ruby/object:Gem::Requirement
@@ -121,16 +122,36 @@ dependencies:
121
122
  name: mocha
122
123
  requirement: !ruby/object:Gem::Requirement
123
124
  requirements:
124
- - - "~>"
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '2.1'
128
+ - - "<"
125
129
  - !ruby/object:Gem::Version
126
- version: 2.1.0
130
+ version: '4'
127
131
  type: :development
128
132
  prerelease: false
129
133
  version_requirements: !ruby/object:Gem::Requirement
130
134
  requirements:
131
- - - "~>"
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '2.1'
138
+ - - "<"
139
+ - !ruby/object:Gem::Version
140
+ version: '4'
141
+ - !ruby/object:Gem::Dependency
142
+ name: ostruct
143
+ requirement: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: '0'
148
+ type: :development
149
+ prerelease: false
150
+ version_requirements: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
132
153
  - !ruby/object:Gem::Version
133
- version: 2.1.0
154
+ version: '0'
134
155
  - !ruby/object:Gem::Dependency
135
156
  name: rake
136
157
  requirement: !ruby/object:Gem::Requirement
@@ -173,6 +194,8 @@ files:
173
194
  - ".dockerignore"
174
195
  - ".github/FUNDING.yml"
175
196
  - ".github/config/rubocop_linter_action.yml"
197
+ - ".github/pull_request_template.md"
198
+ - ".github/workflows/changelog.yml"
176
199
  - ".github/workflows/ci-with-docker.yml"
177
200
  - ".github/workflows/ci.yml"
178
201
  - ".github/workflows/rubocop.yml"
@@ -180,12 +203,12 @@ files:
180
203
  - ".rubocop.yml"
181
204
  - ".rubocop_todo.yml"
182
205
  - CHANGES.txt
206
+ - CONTRIBUTING.md
183
207
  - DEVELOPMENT.md
184
208
  - Dockerfile
185
209
  - Dockerfile.openssl3
210
+ - Dockerfile.zlib_ng
186
211
  - Gemfile
187
- - Gemfile.noed25519
188
- - Gemfile.norbnacl
189
212
  - ISSUE_TEMPLATE.md
190
213
  - LICENSE.txt
191
214
  - Manifest
@@ -194,6 +217,7 @@ files:
194
217
  - SECURITY.md
195
218
  - THANKS.txt
196
219
  - appveyor.yml
220
+ - changelog.d/README.md
197
221
  - docker-compose.yml
198
222
  - lib/net/ssh.rb
199
223
  - lib/net/ssh/authentication/agent.rb
@@ -210,6 +234,7 @@ files:
210
234
  - lib/net/ssh/authentication/methods/publickey.rb
211
235
  - lib/net/ssh/authentication/pageant.rb
212
236
  - lib/net/ssh/authentication/pub_key_fingerprint.rb
237
+ - lib/net/ssh/authentication/security_key.rb
213
238
  - lib/net/ssh/authentication/session.rb
214
239
  - lib/net/ssh/buffer.rb
215
240
  - lib/net/ssh/buffered_io.rb
@@ -224,6 +249,10 @@ files:
224
249
  - lib/net/ssh/key_factory.rb
225
250
  - lib/net/ssh/known_hosts.rb
226
251
  - lib/net/ssh/loggable.rb
252
+ - lib/net/ssh/multiplex.rb
253
+ - lib/net/ssh/multiplex/client.rb
254
+ - lib/net/ssh/multiplex/control_path.rb
255
+ - lib/net/ssh/multiplex/proxy_transport.rb
227
256
  - lib/net/ssh/packet.rb
228
257
  - lib/net/ssh/prompt.rb
229
258
  - lib/net/ssh/proxy/command.rb
@@ -243,12 +272,15 @@ files:
243
272
  - lib/net/ssh/test/remote_packet.rb
244
273
  - lib/net/ssh/test/script.rb
245
274
  - lib/net/ssh/test/socket.rb
275
+ - lib/net/ssh/transport/aes128_gcm.rb
276
+ - lib/net/ssh/transport/aes256_gcm.rb
246
277
  - lib/net/ssh/transport/algorithms.rb
247
278
  - lib/net/ssh/transport/chacha20_poly1305_cipher.rb
248
279
  - lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb
249
280
  - lib/net/ssh/transport/cipher_factory.rb
250
281
  - lib/net/ssh/transport/constants.rb
251
282
  - lib/net/ssh/transport/ctr.rb
283
+ - lib/net/ssh/transport/gcm_cipher.rb
252
284
  - lib/net/ssh/transport/hmac.rb
253
285
  - lib/net/ssh/transport/hmac/abstract.rb
254
286
  - lib/net/ssh/transport/hmac/md5.rb
@@ -257,6 +289,7 @@ files:
257
289
  - lib/net/ssh/transport/hmac/ripemd160.rb
258
290
  - lib/net/ssh/transport/hmac/sha1.rb
259
291
  - lib/net/ssh/transport/hmac/sha1_96.rb
292
+ - lib/net/ssh/transport/hmac/sha1_etm.rb
260
293
  - lib/net/ssh/transport/hmac/sha2_256.rb
261
294
  - lib/net/ssh/transport/hmac/sha2_256_96.rb
262
295
  - lib/net/ssh/transport/hmac/sha2_256_etm.rb
@@ -289,16 +322,16 @@ files:
289
322
  - lib/net/ssh/verifiers/always.rb
290
323
  - lib/net/ssh/verifiers/never.rb
291
324
  - lib/net/ssh/version.rb
292
- - lib/net/ssh/version.rb.old
293
325
  - net-ssh-public_cert.pem
294
326
  - net-ssh.gemspec
327
+ - rakelib/changelog.rb
295
328
  - support/ssh_tunnel_bug.rb
296
329
  homepage: https://github.com/net-ssh/net-ssh
297
330
  licenses:
298
331
  - MIT
299
332
  metadata:
300
333
  changelog_uri: https://github.com/net-ssh/net-ssh/blob/master/CHANGES.txt
301
- post_install_message:
334
+ post_install_message:
302
335
  rdoc_options: []
303
336
  require_paths:
304
337
  - lib
@@ -306,7 +339,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
306
339
  requirements:
307
340
  - - ">="
308
341
  - !ruby/object:Gem::Version
309
- version: '2.6'
342
+ version: '2.7'
310
343
  required_rubygems_version: !ruby/object:Gem::Requirement
311
344
  requirements:
312
345
  - - ">="
@@ -314,7 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
314
347
  version: '0'
315
348
  requirements: []
316
349
  rubygems_version: 3.3.3
317
- signing_key:
350
+ signing_key:
318
351
  specification_version: 4
319
352
  summary: 'Net::SSH: a pure-Ruby implementation of the SSH2 client protocol.'
320
353
  test_files: []
metadata.gz.sig CHANGED
@@ -1 +1 @@
1
- �G����<�C�9ˆv�'�E���Ds(�{
1
+ .t��d�l�&%+ j��H�,�+���*S�x6�$|x��j\���Qg�7I^%�G�n�%��m@Ƈh�M#�.2�y �S�ȇfG�>��N���}b�q8y\�� 6$g��M� �;HP����w;�y�B��#��e���M��ƗZ�����S�yC0>w ��ɬ�B�6�_\h�@�'F���<��� _�� Z}^>�5�K^L�7O:�Uy�ZOA�l��������
data/Gemfile.noed25519 DELETED
@@ -1,12 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- ENV['NET_SSH_NO_ED25519'] = 'true'
4
- # Specify your gem's dependencies in mygem.gemspec
5
- gemspec
6
-
7
- if ENV["CI"] && !Gem.win_platform?
8
- gem 'simplecov', require: false, group: :test
9
- gem 'codecov', require: false, group: :test
10
- end
11
-
12
- gem 'webrick', group: %i[development test] if RUBY_VERSION.split(".")[0].to_i >= 3
data/Gemfile.norbnacl DELETED
@@ -1,12 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- ENV['NET_SSH_NO_RBNACL'] = 'true'
4
- # Specify your gem's dependencies in mygem.gemspec
5
- gemspec
6
-
7
- if ENV["CI"] && !Gem.win_platform?
8
- gem 'simplecov', require: false, group: :test
9
- gem 'codecov', require: false, group: :test
10
- end
11
-
12
- gem 'webrick', group: %i[development test] if RUBY_VERSION.split(".")[0].to_i >= 3