net-ssh 7.1.0 → 7.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 69f379018d9756042dedb6948dda7f92b8d866a0fd3beb7745a11ab1da739001
4
- data.tar.gz: 8e5b659e405ea5403ce34fec03e05c1abe1d3dcf6b8962610d7b6c62c6df7794
3
+ metadata.gz: 524dafc8f2460b2e19662e19cb1916dc6b7f57b78b9cdc6ceadf486bc4fc1945
4
+ data.tar.gz: 1f400ebf2e8622ab81b348c6db7d45d88dfd3c3bd04e61bc60ea8678482f5f11
5
5
  SHA512:
6
- metadata.gz: 065e5076a1d6ed2af0ca3b51f6dc885cf05d09b93ba8a9f5ad003031b5ab3b652e1289b4c5ff9b2e9865db3c12f58874b1ec504044ee17fe1551396e4081daa9
7
- data.tar.gz: c27bb7b11148313012628ada70d22e5e425ef4b36c7645e40bd422ad86a2b9495de1b71fa70ad8ae2b9584d4cbbe8fef3030883f29df0c7551f8e3d8eddc4339
6
+ metadata.gz: 00c33f37023f2cb493b231ee924db6be810fb8d3505d085160c6d790bcd928856081321b5743c2829e773ba506fee8aa3e5a5e9c94ec705199fa77458ad8c17f
7
+ data.tar.gz: 195425e6e604b3dbe56cfabd2567b292cd40caa8affbd3f624901a2ddbcb024bacc052093722407a62070bfd3bacdce4c60aee6693a29ac20ad140ba2683fcc3
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1 @@
1
+ github: [mfazekas]
@@ -4,10 +4,10 @@ on:
4
4
  push: { branches: master }
5
5
  jobs:
6
6
  test:
7
- runs-on: ubuntu-18.04
7
+ runs-on: ubuntu-22.04
8
8
  strategy:
9
9
  matrix:
10
- ruby-version: [2.6.6, 2.7.2, 3.0.1, 3.1.1]
10
+ ruby-version: [2.6.10, 2.7.7, 3.0.6, 3.1.3, 3.2.1, 3.3.0]
11
11
  steps:
12
12
  - uses: actions/checkout@v3
13
13
 
@@ -39,13 +39,14 @@ jobs:
39
39
  ${{ runner.os }}-pip-v1
40
40
  - name: Bundle install
41
41
  run: |
42
- gem install bundler
42
+ gem install bundler ${{ (startsWith(matrix.ruby-version, '2.6.') || startsWith(matrix.ruby-version, '2.7.')) && '-v 2.4.22' || '' }}
43
43
  bundle config set path 'vendor/bundle'
44
44
  bundle config set --local path 'vendor/bundle'
45
45
  bundle install --jobs 4 --retry 3 --path vendor/bundle
46
46
  BUNDLE_GEMFILE=./Gemfile.noed25519 bundle install --jobs 4 --retry 3 --path vendor/bundle
47
47
  env:
48
48
  BUNDLE_PATH: vendor/bundle
49
+
49
50
 
50
51
  - name: Add to etc/hosts
51
52
  run: |
@@ -77,6 +78,12 @@ jobs:
77
78
  env:
78
79
  NET_SSH_RUN_INTEGRATION_TESTS: 1
79
80
  CI: 1
81
+ - name: Run tests (without rbnacl)
82
+ run: bundle exec rake test
83
+ env:
84
+ BUNDLE_GEMFILE: ./Gemfile.norbnacl
85
+ NET_SSH_RUN_INTEGRATION_TESTS: 1
86
+ CI: 1
80
87
  - name: Run Tests (without ed25519)
81
88
  run: bundle exec rake test
82
89
  env:
data/.gitignore CHANGED
@@ -8,6 +8,8 @@ pkg
8
8
  test/integration/.vagrant
9
9
  test/integration/playbook.retry
10
10
 
11
+ lib/net/ssh/version.rb.old
12
+
11
13
  .byebug_history
12
14
 
13
15
  tryout
data/.rubocop_todo.yml CHANGED
@@ -251,7 +251,7 @@ Metrics/BlockNesting:
251
251
  # Offense count: 33
252
252
  # Configuration parameters: CountComments, CountAsOne.
253
253
  Metrics/ClassLength:
254
- Max: 488
254
+ Max: 350
255
255
 
256
256
  # Offense count: 38
257
257
  # Configuration parameters: IgnoredMethods.
data/CHANGES.txt CHANGED
@@ -1,3 +1,23 @@
1
+ === 7.2.2
2
+
3
+ * ruby 3.3.0: base64 fix
4
+
5
+ === 7.2.1 rc1
6
+
7
+ * feat: allow load of certkey from string [#926]
8
+ * fix: fix for Socket#recv returning nil on ruby 3.3.0 [#928]
9
+
10
+ === 7.2.0
11
+
12
+ * Add debugging information for algorithm of pubkey in use [#918]
13
+
14
+ === 7.2.0 rc1
15
+
16
+ * Allow IdentityAgent as option to Net::SSH.start [#912]
17
+
18
+ === 7.2.0 beta1
19
+
20
+ * Support `chacha20-poly1305@opnessh.com` cypher if `RbNaCl` gem is installed [#908]
1
21
 
2
22
  === 7.1.0
3
23
 
data/DEVELOPMENT.md ADDED
@@ -0,0 +1,23 @@
1
+ ### Development notes
2
+
3
+ ## Building/running ssh server in debug mode
4
+
5
+ clone the openssh server from `https://github.com/openssh/openssh-portable`
6
+
7
+ ```sh
8
+ brew install openssl
9
+ /usr/local/Cellar/openssl@3/3.1.0/bin/openssl
10
+
11
+ autoreconf
12
+ ./configure --with-ssl-dir=/usr/local/Cellar/openssl@3/3.1.0/ --with-audit=debug --enable-debug CPPFLAGS="-DDEBUG -DPACKET_DEBUG" CFLAGS="-g -O0"
13
+ make
14
+ ```
15
+
16
+ To run server in debug mode:
17
+ ```sh
18
+ echo '#' > /tmp/sshd_config
19
+ ssh-keygen -t rsa -f /tmp/ssh_host_rsa_key
20
+ # /Users/boga/Work/OSS/NetSSH/openssh-portable/sshd -p 2222 -D -d -d -d -e -f /tmp/sshd_config
21
+ /Users/boga/Work/OSS/NetSSH/openssh-portable/sshd -p 2222 -D -d -d -d -e -f /tmp/sshd_config -h /tmp/ssh_host_rsa_key
22
+
23
+ ```
data/Dockerfile CHANGED
@@ -1,7 +1,9 @@
1
1
  ARG RUBY_VERSION=3.1
2
2
  FROM ruby:${RUBY_VERSION}
3
3
 
4
- RUN apt update && apt install -y openssh-server sudo netcat \
4
+ ARG BUNDLERV=
5
+
6
+ RUN apt update && apt install -y openssh-server sudo netcat-openbsd \
5
7
  && useradd --create-home --shell '/bin/bash' --comment 'NetSSH' 'net_ssh_1' \
6
8
  && useradd --create-home --shell '/bin/bash' --comment 'NetSSH' 'net_ssh_2' \
7
9
  && echo net_ssh_1:foopwd | chpasswd \
@@ -20,7 +22,7 @@ COPY Gemfile net-ssh.gemspec $INSTALL_PATH/
20
22
 
21
23
  COPY lib/net/ssh/version.rb $INSTALL_PATH/lib/net/ssh/version.rb
22
24
 
23
- RUN gem install bundler && bundle install
25
+ RUN gem install bundler ${BUNDLERV} && bundle install
24
26
 
25
27
  COPY . $INSTALL_PATH/
26
28
 
data/Gemfile.norbnacl ADDED
@@ -0,0 +1,12 @@
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
data/README.md CHANGED
@@ -33,7 +33,7 @@ We strongly recommend that you install a servers's version that supports the lat
33
33
 
34
34
  It is possible to return to the previous behavior by adding the option : `append_all_supported_algorithms: true`
35
35
 
36
- Unsecure algoritms will definitely be removed in Net::SSH 7.*.
36
+ Unsecure algoritms will definitely be removed in Net::SSH 8.*.
37
37
 
38
38
  ### Host Keys
39
39
 
@@ -44,7 +44,7 @@ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
44
44
  | ecdsa-sha2-nistp521 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
45
45
  | ecdsa-sha2-nistp384 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
46
46
  | ecdsa-sha2-nistp256 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
47
- | ssh-dss | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
47
+ | ssh-dss | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
48
48
 
49
49
  ### Key Exchange
50
50
 
@@ -54,9 +54,9 @@ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
54
54
  | ecdh-sha2-nistp521 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
55
55
  | ecdh-sha2-nistp384 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
56
56
  | ecdh-sha2-nistp256 | OK | [using weak elliptic curves](https://safecurves.cr.yp.to/) |
57
- | diffie-hellman-group1-sha1 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
57
+ | diffie-hellman-group1-sha1 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
58
58
  | diffie-hellman-group14-sha1 | OK | |
59
- | diffie-hellman-group-exchange-sha1 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
59
+ | diffie-hellman-group-exchange-sha1 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
60
60
  | diffie-hellman-group-exchange-sha256 | OK | |
61
61
 
62
62
  ### Encryption algorithms (ciphers)
@@ -64,13 +64,14 @@ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
64
64
  | Name | Support | Details |
65
65
  |--------------------------------------|-----------------------|----------|
66
66
  | aes256-ctr / aes192-ctr / aes128-ctr | OK | |
67
- | aes256-cbc / aes192-cbc / aes128-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
68
- | rijndael-cbc@lysator.liu.se | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
69
- | blowfish-ctr blowfish-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
70
- | cast128-ctr cast128-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
71
- | 3des-ctr 3des-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
72
- | idea-cbc | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
73
- | none | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
67
+ | chacha20-poly1305@openssh.com | OK. | Requires the gem `rbnacl` |
68
+ | aes256-cbc / aes192-cbc / aes128-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
69
+ | rijndael-cbc@lysator.liu.se | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
70
+ | blowfish-ctr blowfish-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
71
+ | cast128-ctr cast128-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
72
+ | 3des-ctr 3des-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
73
+ | idea-cbc | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
74
+ | none | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
74
75
 
75
76
  ### Message Authentication Code algorithms
76
77
 
@@ -80,14 +81,14 @@ Unsecure algoritms will definitely be removed in Net::SSH 7.*.
80
81
  | hmac-sha2-256-etm | OK | |
81
82
  | hmac-sha2-512 | OK | |
82
83
  | hmac-sha2-256 | OK | |
83
- | hmac-sha2-512-96 | Deprecated in 6.0 | removed from the specification, will be removed in 7.0 |
84
- | hmac-sha2-256-96 | Deprecated in 6.0 | removed from the specification, will be removed in 7.0 |
84
+ | hmac-sha2-512-96 | Deprecated in 6.0 | removed from the specification, will be removed in 8.0 |
85
+ | hmac-sha2-256-96 | Deprecated in 6.0 | removed from the specification, will be removed in 8.0 |
85
86
  | hmac-sha1 | OK | for backward compatibility |
86
- | hmac-sha1-96 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
87
- | hmac-ripemd160 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
88
- | hmac-md5 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
89
- | hmac-md5-96 | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
90
- | none | Deprecated in 6.0 | unsecure, will be removed in 7.0 |
87
+ | hmac-sha1-96 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
88
+ | hmac-ripemd160 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
89
+ | hmac-md5 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
90
+ | hmac-md5-96 | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
91
+ | none | Deprecated in 6.0 | unsecure, will be removed in 8.0 |
91
92
 
92
93
  ## SYNOPSIS:
93
94
 
@@ -247,6 +248,8 @@ mv gem-public_cert.pem net-ssh-public_cert.pem
247
248
  gem cert --add net-ssh-public_cert.pem
248
249
  ```
249
250
 
251
+ or `rake cert:update_public_when_expired`
252
+
250
253
  ## Security contact information
251
254
 
252
255
  See [SECURITY.md](SECURITY.md)
data/Rakefile CHANGED
@@ -59,29 +59,48 @@ def change_version(&block)
59
59
  version_file = 'lib/net/ssh/version.rb'
60
60
  require_relative version_file
61
61
  pre = Net::SSH::Version::PRE
62
- result = block[pre: pre]
63
- raise "Version change logic should always return a pre", ArgumentError unless result.key?(:pre)
62
+ tiny = Net::SSH::Version::TINY
63
+ result = block[pre: pre, tiny: Net::SSH::Version::TINY]
64
+ raise ArgumentError, "Version change logic should always return a pre" unless result.key?(:pre)
64
65
 
65
66
  new_pre = result[:pre]
66
- found = false
67
+ new_tiny = result[:tiny] || tiny
68
+ found = { pre: false, tiny: false }
67
69
  File.open("#{version_file}.new", "w") do |f|
68
70
  File.readlines(version_file).each do |line|
69
- match = /^(\s+PRE\s+=\s+")#{pre}("\s*)$/.match(line)
71
+ match =
72
+ if pre.nil?
73
+ /^(\s+PRE\s+=\s+)nil(\s*)$/.match(line)
74
+ else
75
+ /^(\s+PRE\s+=\s+")#{pre}("\s*)$/.match(line)
76
+ end
70
77
  if match
71
78
  prefix = match[1]
72
79
  postfix = match[2]
73
- if new_pre.nil?
74
- prefix.delete_suffix!('"')
75
- postfix.delete_prefix!('"')
76
- end
80
+ prefix.delete_suffix!('"')
81
+ postfix.delete_prefix!('"')
77
82
  new_line = "#{prefix}#{new_pre.inspect}#{postfix}"
78
83
  puts "Changing:\n - #{line} + #{new_line}"
79
84
  line = new_line
80
- found = true
85
+ found[:pre] = true
86
+ end
87
+
88
+ if new_tiny != tiny
89
+ match = /^(\s+TINY\s+=\s+)#{tiny}(\s*)$/.match(line)
90
+ if match
91
+ prefix = match[1]
92
+ postfix = match[2]
93
+ new_line = "#{prefix}#{new_tiny}#{postfix}"
94
+ puts "Changing:\n - #{line} + #{new_line}"
95
+ line = new_line
96
+ found[:tiny] = true
97
+ end
81
98
  end
99
+
82
100
  f.write(line)
83
101
  end
84
- raise ArugmentError, "Cound not find line: PRE = \"#{pre}\" in #{version_file}" unless found
102
+ raise ArgumentError, "Cound not find line: PRE = \"#{pre}\" in #{version_file}" unless found[:pre]
103
+ raise ArgumentError, "Cound not find line: TINY = \"#{tiny}\" in #{version_file}" unless found[:tiny] || new_tiny == tiny
85
104
  end
86
105
 
87
106
  FileUtils.mv version_file, "#{version_file}.old"
@@ -91,20 +110,34 @@ end
91
110
  namespace :vbump do
92
111
  desc "Final release"
93
112
  task :final do
94
- change_version do |pre:|
95
- raise ArgumentError, "Unexpected pre: #{pre}" if pre.nil?
96
-
97
- { pre: nil }
113
+ change_version do |pre:, tiny:|
114
+ _ = tiny
115
+ if pre.nil?
116
+ { tiny: tiny + 1, pre: nil }
117
+ else
118
+ raise ArgumentError, "Unexpected pre: #{pre}" if pre.nil?
119
+
120
+ { pre: nil }
121
+ end
98
122
  end
99
123
  end
100
124
 
101
125
  desc "Increment prerelease"
102
- task :pre do
103
- change_version do |pre:|
126
+ task :pre, [:type] do |_t, args|
127
+ change_version do |pre:, tiny:|
128
+ puts " PRE => #{pre.inspect}"
104
129
  match = /^([a-z]+)(\d+)/.match(pre)
105
- raise ArgumentError, "Unexpected pre: #{pre}" if match.nil?
130
+ raise ArgumentError, "Unexpected pre: #{pre}" if match.nil? && args[:type].nil?
106
131
 
107
- { pre: "#{match[1]}#{match[2].to_i + 1}" }
132
+ if match.nil? || (!args[:type].nil? && args[:type] != match[1])
133
+ if pre.nil?
134
+ { pre: "#{args[:type]}1", tiny: tiny + 1 }
135
+ else
136
+ { pre: "#{args[:type]}1" }
137
+ end
138
+ else
139
+ { pre: "#{match[1]}#{match[2].to_i + 1}" }
140
+ end
108
141
  end
109
142
  end
110
143
  end
data/docker-compose.yml CHANGED
@@ -16,8 +16,10 @@ services:
16
16
  context: .
17
17
  args:
18
18
  RUBY_VERSION: 2.7
19
+ BUNDLERV: "-v 2.2.28"
19
20
  ruby-2.6:
20
21
  build:
21
22
  context: .
22
23
  args:
23
24
  RUBY_VERSION: 2.6
25
+ BUNDLERV: "-v 2.4.22"
@@ -3,8 +3,6 @@ gem 'bcrypt_pbkdf', '~> 1.0' unless RUBY_PLATFORM == "java"
3
3
 
4
4
  require 'ed25519'
5
5
 
6
- require 'base64'
7
-
8
6
  require 'net/ssh/transport/cipher_factory'
9
7
  require 'net/ssh/authentication/pub_key_fingerprint'
10
8
  require 'bcrypt_pbkdf' unless RUBY_PLATFORM == "java"
@@ -46,7 +44,7 @@ module Net
46
44
  raise ArgumentError.new("Expected #{MEND} at end of private key") unless datafull.end_with?(MEND)
47
45
 
48
46
  datab64 = datafull[MBEGIN.size...-MEND.size]
49
- data = Base64.decode64(datab64)
47
+ data = datab64.unpack1("m")
50
48
  raise ArgumentError.new("Expected #{MAGIC} at start of decoded private key") unless data.start_with?(MAGIC)
51
49
 
52
50
  buffer = Net::SSH::Buffer.new(data[MAGIC.size + 1..-1])
@@ -134,7 +132,7 @@ module Net
134
132
 
135
133
  def to_pem
136
134
  # TODO this is not pem
137
- ssh_type + Base64.encode64(@verify_key.to_bytes)
135
+ ssh_type + [@verify_key.to_bytes].pack("m")
138
136
  end
139
137
  end
140
138
 
@@ -32,6 +32,9 @@ module Net
32
32
  # The list of user key certificate files that will be examined
33
33
  attr_reader :keycert_files
34
34
 
35
+ # The list of user key certificate data that will be examined
36
+ attr_reader :keycert_data
37
+
35
38
  # The map of loaded identities
36
39
  attr_reader :known_identities
37
40
 
@@ -46,6 +49,7 @@ module Net
46
49
  @key_files = []
47
50
  @key_data = []
48
51
  @keycert_files = []
52
+ @keycert_data = []
49
53
  @use_agent = options[:use_agent] != false
50
54
  @known_identities = {}
51
55
  @agent = nil
@@ -59,6 +63,7 @@ module Net
59
63
  def clear!
60
64
  key_files.clear
61
65
  key_data.clear
66
+ keycert_data.clear
62
67
  known_identities.clear
63
68
  self
64
69
  end
@@ -75,6 +80,12 @@ module Net
75
80
  self
76
81
  end
77
82
 
83
+ # Add the given keycert_data to the list of keycerts that will be used.
84
+ def add_keycert_data(keycert_data_)
85
+ keycert_data.push(keycert_data_).uniq!
86
+ self
87
+ end
88
+
78
89
  # Add the given key_file to the list of keys that will be used.
79
90
  def add_key_data(key_data_)
80
91
  key_data.push(key_data_).uniq!
@@ -132,8 +143,8 @@ module Net
132
143
  end
133
144
 
134
145
  known_identity_blobs = known_identities.keys.map(&:to_blob)
135
- keycert_files.each do |keycert_file|
136
- keycert = KeyFactory.load_public_key(keycert_file)
146
+
147
+ keycerts.each do |keycert|
137
148
  next if known_identity_blobs.include?(keycert.to_blob)
138
149
 
139
150
  (_, corresponding_identity) = known_identities.detect { |public_key, _|
@@ -227,6 +238,12 @@ module Net
227
238
 
228
239
  private
229
240
 
241
+ # Load keycerts from files and data.
242
+ def keycerts
243
+ keycert_files.map { |keycert_file| KeyFactory.load_public_key(keycert_file) } +
244
+ keycert_data.map { |data| KeyFactory.load_data_public_key(data) }
245
+ end
246
+
230
247
  # Prepares identities from user key_files for loading, preserving their order and sources.
231
248
  def prepare_identities_from_files
232
249
  key_files.map do |file|
@@ -44,7 +44,7 @@ module Net
44
44
  end
45
45
 
46
46
  def authenticate_with_alg(identity, next_service, username, alg, sig_alg = nil)
47
- debug { "trying publickey (#{identity.fingerprint})" }
47
+ debug { "trying publickey (#{identity.fingerprint}) alg #{alg}" }
48
48
  send_request(identity, username, next_service, alg)
49
49
 
50
50
  message = session.next_message
@@ -32,7 +32,7 @@ module Net
32
32
  when 'MD5'
33
33
  OpenSSL::Digest.hexdigest(algorithm, blob).scan(/../).join(":")
34
34
  when 'SHA256'
35
- "SHA256:#{Base64.encode64(OpenSSL::Digest.digest(algorithm, blob)).chomp.gsub(/=+\z/, '')}"
35
+ "SHA256:#{[OpenSSL::Digest.digest(algorithm, blob)].pack('m').chomp.gsub(/=+\z/, '')}"
36
36
  else
37
37
  raise OpenSSL::Digest::DigestError, "unsupported ssh key digest #{algorithm}"
38
38
  end
@@ -63,6 +63,7 @@ module Net
63
63
  key_manager = KeyManager.new(logger, options)
64
64
  keys.each { |key| key_manager.add(key) } unless keys.empty?
65
65
  keycerts.each { |keycert| key_manager.add_keycert(keycert) } unless keycerts.empty?
66
+ keycert_data.each { |data| key_manager.add_keycert_data(data) } unless keycert_data.empty?
66
67
  key_data.each { |key2| key_manager.add_key_data(key2) } unless key_data.empty?
67
68
  default_keys.each { |key| key_manager.add(key) } unless options.key?(:keys) || options.key?(:key_data)
68
69
 
@@ -154,6 +155,12 @@ module Net
154
155
  Array(options[:keycerts])
155
156
  end
156
157
 
158
+ # Returns an array of the keycert data that should be used when
159
+ # attempting any key-based authentication mechanism.
160
+ def keycert_data
161
+ Array(options[:keycert_data])
162
+ end
163
+
157
164
  # Returns an array of the key data that should be used when
158
165
  # attempting any key-based authentication mechanism.
159
166
  def key_data
@@ -61,7 +61,7 @@ module Net
61
61
  # if no data was available to be read.
62
62
  def fill(n = 8192)
63
63
  input.consume!
64
- data = recv(n)
64
+ data = recv(n) || ""
65
65
  debug { "read #{data.length} bytes" }
66
66
  input.append(data)
67
67
  return data.length
@@ -1,6 +1,5 @@
1
1
  require 'strscan'
2
2
  require 'openssl'
3
- require 'base64'
4
3
  require 'delegate'
5
4
  require 'net/ssh/buffer'
6
5
  require 'net/ssh/authentication/ed25519_loader'
@@ -241,11 +240,11 @@ module Net
241
240
  def known_host_hash?(hostlist, entries)
242
241
  if hostlist.size == 1 && hostlist.first =~ /\A\|1(\|.+){2}\z/
243
242
  chunks = hostlist.first.split(/\|/)
244
- salt = Base64.decode64(chunks[2])
243
+ salt = chunks[2].unpack1("m")
245
244
  digest = OpenSSL::Digest.new('sha1')
246
245
  entries.each do |entry|
247
246
  hmac = OpenSSL::HMAC.digest(digest, salt, entry)
248
- return true if Base64.encode64(hmac).chomp == chunks[3]
247
+ return true if [hmac].pack("m").chomp == chunks[3]
249
248
  end
250
249
  end
251
250
  false
@@ -51,6 +51,11 @@ module Net
51
51
  hmac-sha1]
52
52
  }.freeze
53
53
 
54
+ if Net::SSH::Transport::ChaCha20Poly1305CipherLoader::LOADED
55
+ DEFAULT_ALGORITHMS[:encryption].unshift(
56
+ 'chacha20-poly1305@openssh.com'
57
+ )
58
+ end
54
59
  if Net::SSH::Authentication::ED25519Loader::LOADED
55
60
  DEFAULT_ALGORITHMS[:host_key].unshift(
56
61
  'ssh-ed25519-cert-v01@openssh.com',
@@ -437,12 +442,13 @@ module Net
437
442
  def exchange_keys
438
443
  debug { "exchanging keys" }
439
444
 
445
+ need_bytes = kex_byte_requirement
440
446
  algorithm = Kex::MAP[kex].new(self, session,
441
447
  client_version_string: Net::SSH::Transport::ServerVersion::PROTO_VERSION,
442
448
  server_version_string: session.server_version.version,
443
449
  server_algorithm_packet: @server_packet,
444
450
  client_algorithm_packet: @client_packet,
445
- need_bytes: kex_byte_requirement,
451
+ need_bytes: need_bytes,
446
452
  minimum_dh_bits: options[:minimum_dh_bits],
447
453
  logger: logger)
448
454
  result = algorithm.exchange_keys
@@ -464,11 +470,27 @@ module Net
464
470
 
465
471
  parameters = { shared: secret, hash: hash, digester: digester }
466
472
 
467
- cipher_client = CipherFactory.get(encryption_client, parameters.merge(iv: iv_client, key: key_client, encrypt: true))
468
- cipher_server = CipherFactory.get(encryption_server, parameters.merge(iv: iv_server, key: key_server, decrypt: true))
473
+ cipher_client = CipherFactory.get(
474
+ encryption_client,
475
+ parameters.merge(iv: iv_client, key: key_client, encrypt: true)
476
+ )
477
+ cipher_server = CipherFactory.get(
478
+ encryption_server,
479
+ parameters.merge(iv: iv_server, key: key_server, decrypt: true)
480
+ )
469
481
 
470
- mac_client = HMAC.get(hmac_client, mac_key_client, parameters)
471
- mac_server = HMAC.get(hmac_server, mac_key_server, parameters)
482
+ mac_client =
483
+ if cipher_client.implicit_mac?
484
+ cipher_client.implicit_mac
485
+ else
486
+ HMAC.get(hmac_client, mac_key_client, parameters)
487
+ end
488
+ mac_server =
489
+ if cipher_server.implicit_mac?
490
+ cipher_server.implicit_mac
491
+ else
492
+ HMAC.get(hmac_server, mac_key_server, parameters)
493
+ end
472
494
 
473
495
  session.configure_client cipher: cipher_client, hmac: mac_client,
474
496
  compression: normalize_compression_name(compression_client),
@@ -0,0 +1,117 @@
1
+ require 'rbnacl'
2
+ require 'net/ssh/loggable'
3
+
4
+ module Net
5
+ module SSH
6
+ module Transport
7
+ ## Implements the chacha20-poly1305@openssh cipher
8
+ class ChaCha20Poly1305Cipher
9
+ include Net::SSH::Loggable
10
+
11
+ # Implicit HMAC, no need to do anything
12
+ class ImplicitHMac
13
+ def etm
14
+ # TODO: ideally this shouln't be called
15
+ true
16
+ end
17
+
18
+ def key_length
19
+ 64
20
+ end
21
+ end
22
+
23
+ def initialize(encrypt:, key:)
24
+ @chacha_hdr = OpenSSL::Cipher.new("chacha20")
25
+ key_len = @chacha_hdr.key_len
26
+ @chacha_main = OpenSSL::Cipher.new("chacha20")
27
+ @poly = RbNaCl::OneTimeAuths::Poly1305
28
+ if key.size < key_len * 2
29
+ error { "chacha20_poly1305: keylength doesn't match" }
30
+ raise "chacha20_poly1305: keylength doesn't match"
31
+ end
32
+ if encrypt
33
+ @chacha_hdr.encrypt
34
+ @chacha_main.encrypt
35
+ else
36
+ @chacha_hdr.decrypt
37
+ @chacha_main.decrypt
38
+ end
39
+ main_key = key[0...key_len]
40
+ @chacha_main.key = main_key
41
+ hdr_key = key[key_len...(2 * key_len)]
42
+ @chacha_hdr.key = hdr_key
43
+ end
44
+
45
+ def update_cipher_mac(payload, sequence_number)
46
+ iv_data = [0, 0, 0, sequence_number].pack("NNNN")
47
+ @chacha_main.iv = iv_data
48
+ poly_key = @chacha_main.update(([0] * 32).pack('C32'))
49
+
50
+ packet_length = payload.size
51
+ length_data = [packet_length].pack("N")
52
+ @chacha_hdr.iv = iv_data
53
+ packet = @chacha_hdr.update(length_data)
54
+
55
+ iv_data[0] = 1.chr
56
+ @chacha_main.iv = iv_data
57
+ unencrypted_data = payload
58
+ packet += @chacha_main.update(unencrypted_data)
59
+
60
+ packet += @poly.auth(poly_key, packet)
61
+ return packet
62
+ end
63
+
64
+ def read_length(data, sequence_number)
65
+ iv_data = [0, 0, 0, sequence_number].pack("NNNN")
66
+ @chacha_hdr.iv = iv_data
67
+ @chacha_hdr.update(data).unpack1("N")
68
+ end
69
+
70
+ def read_and_mac(data, mac, sequence_number)
71
+ iv_data = [0, 0, 0, sequence_number].pack("NNNN")
72
+ @chacha_main.iv = iv_data
73
+ poly_key = @chacha_main.update(([0] * 32).pack('C32'))
74
+
75
+ iv_data[0] = 1.chr
76
+ @chacha_main.iv = iv_data
77
+ unencrypted_data = @chacha_main.update(data[4..])
78
+ begin
79
+ ok = @poly.verify(poly_key, mac, data[0..])
80
+ raise Net::SSH::Exception, "corrupted hmac detected #{name}" unless ok
81
+ rescue RbNaCl::BadAuthenticatorError
82
+ raise Net::SSH::Exception, "corrupted hmac detected #{name}"
83
+ end
84
+ return unencrypted_data
85
+ end
86
+
87
+ def mac_length
88
+ 16
89
+ end
90
+
91
+ def block_size
92
+ 8
93
+ end
94
+
95
+ def name
96
+ "chacha20-poly1305@openssh.com"
97
+ end
98
+
99
+ def implicit_mac?
100
+ true
101
+ end
102
+
103
+ def implicit_mac
104
+ return ImplicitHMac.new
105
+ end
106
+
107
+ def self.block_size
108
+ 8
109
+ end
110
+
111
+ def self.key_length
112
+ 64
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,17 @@
1
+ module Net
2
+ module SSH
3
+ module Transport
4
+ # Loads chacha20 poly1305 support which requires optinal dependency rbnacl
5
+ module ChaCha20Poly1305CipherLoader
6
+ begin
7
+ require 'net/ssh/transport/chacha20_poly1305_cipher'
8
+ LOADED = true
9
+ ERROR = nil
10
+ rescue LoadError => e
11
+ ERROR = e
12
+ LOADED = false
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -2,6 +2,8 @@ require 'openssl'
2
2
  require 'net/ssh/transport/ctr.rb'
3
3
  require 'net/ssh/transport/key_expander'
4
4
  require 'net/ssh/transport/identity_cipher'
5
+ require 'net/ssh/transport/chacha20_poly1305_cipher_loader'
6
+ require 'net/ssh/transport/openssl_cipher_extensions'
5
7
 
6
8
  module Net
7
9
  module SSH
@@ -29,13 +31,25 @@ module Net
29
31
  'none' => 'none'
30
32
  }
31
33
 
34
+ SSH_TO_CLASS =
35
+ if Net::SSH::Transport::ChaCha20Poly1305CipherLoader::LOADED
36
+ {
37
+ 'chacha20-poly1305@openssh.com' => Net::SSH::Transport::ChaCha20Poly1305Cipher
38
+ }
39
+ else
40
+ {
41
+ }
42
+ end
43
+
32
44
  # Returns true if the underlying OpenSSL library supports the given cipher,
33
45
  # and false otherwise.
34
46
  def self.supported?(name)
47
+ return true if SSH_TO_CLASS.key?(name)
48
+
35
49
  ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
36
50
  return true if ossl_name == "none"
37
51
 
38
- return OpenSSL::Cipher.ciphers.include?(ossl_name)
52
+ return SSH_TO_CLASS.key?(name) || OpenSSL::Cipher.ciphers.include?(ossl_name)
39
53
  end
40
54
 
41
55
  # Retrieves a new instance of the named algorithm. The new instance
@@ -44,6 +58,13 @@ module Net
44
58
  # cipher will be put into encryption or decryption mode, based on the
45
59
  # value of the +encrypt+ parameter.
46
60
  def self.get(name, options = {})
61
+ klass = SSH_TO_CLASS[name]
62
+ unless klass.nil?
63
+ key_len = klass.key_length
64
+ key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
65
+ return klass.new(encrypt: options[:encrypt], key: key)
66
+ end
67
+
47
68
  ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
48
69
  return IdentityCipher if ossl_name == "none"
49
70
 
@@ -53,6 +74,7 @@ module Net
53
74
 
54
75
  cipher.padding = 0
55
76
 
77
+ cipher.extend(Net::SSH::Transport::OpenSSLCipherExtensions)
56
78
  if name =~ /-ctr(@openssh.org)?$/
57
79
  if ossl_name !~ /-ctr/
58
80
  cipher.extend(Net::SSH::Transport::CTR)
@@ -75,6 +97,9 @@ module Net
75
97
  # of the tuple.
76
98
  # if :iv_len option is supplied the third return value will be ivlen
77
99
  def self.get_lengths(name, options = {})
100
+ klass = SSH_TO_CLASS[name]
101
+ return [klass.key_length, klass.block_size] unless klass.nil?
102
+
78
103
  ossl_name = SSH_TO_OSSL[name]
79
104
  if ossl_name.nil? || ossl_name == "none"
80
105
  result = [0, 0]
@@ -11,6 +11,10 @@ module Net
11
11
  8
12
12
  end
13
13
 
14
+ def key_length
15
+ 0
16
+ end
17
+
14
18
  # Returns an arbitrary integer.
15
19
  def iv_len
16
20
  4
@@ -50,6 +54,10 @@ module Net
50
54
  def reset
51
55
  self
52
56
  end
57
+
58
+ def implicit_mac?
59
+ false
60
+ end
53
61
  end
54
62
  end
55
63
  end
@@ -0,0 +1,8 @@
1
+ module Net::SSH::Transport
2
+ # we add those mehtods to OpenSSL::Chipher instances
3
+ module OpenSSLCipherExtensions
4
+ def implicit_mac?
5
+ false
6
+ end
7
+ end
8
+ end
@@ -12,7 +12,7 @@ module Net
12
12
  # module. It adds SSH encryption, compression, and packet validation, as
13
13
  # per the SSH2 protocol. It also adds an abstraction for polling packets,
14
14
  # to allow for both blocking and non-blocking reads.
15
- module PacketStream
15
+ module PacketStream # rubocop:disable Metrics/ModuleLength
16
16
  PROXY_COMMAND_HOST_IP = '<no hostip for proxy command>'.freeze
17
17
 
18
18
  include BufferedIo
@@ -123,7 +123,7 @@ module Net
123
123
  # Enqueues a packet to be sent, but does not immediately send the packet.
124
124
  # The given payload is pre-processed according to the algorithms specified
125
125
  # in the client state (compression, cipher, and hmac).
126
- def enqueue_packet(payload)
126
+ def enqueue_packet(payload) # rubocop:disable Metrics/AbcSize
127
127
  # try to compress the packet
128
128
  payload = client.compress(payload)
129
129
 
@@ -144,7 +144,10 @@ module Net
144
144
 
145
145
  padding = Array.new(padding_length) { rand(256) }.pack("C*")
146
146
 
147
- if client.hmac.etm
147
+ if client.cipher.implicit_mac?
148
+ unencrypted_data = [padding_length, payload, padding].pack("CA*A*")
149
+ message = client.cipher.update_cipher_mac(unencrypted_data, client.sequence_number)
150
+ elsif client.hmac.etm
148
151
  debug { "using encrypt-then-mac" }
149
152
 
150
153
  # Encrypt padding_length, payload, and padding. Take MAC
@@ -225,7 +228,11 @@ module Net
225
228
  data = read_available(minimum + aad_length)
226
229
 
227
230
  # decipher it
228
- if server.hmac.etm
231
+ if server.cipher.implicit_mac?
232
+ @packet_length = server.cipher.read_length(data[0...4], server.sequence_number)
233
+ @packet = Net::SSH::Buffer.new
234
+ @mac_data = data
235
+ elsif server.hmac.etm
229
236
  @packet_length = data.unpack("N").first
230
237
  @mac_data = data
231
238
  @packet = Net::SSH::Buffer.new(server.update_cipher(data[aad_length..-1]))
@@ -238,31 +245,45 @@ module Net
238
245
  need = @packet_length + 4 - aad_length - server.block_size
239
246
  raise Net::SSH::Exception, "padding error, need #{need} block #{server.block_size}" if need % server.block_size != 0
240
247
 
241
- return nil if available < need + server.hmac.mac_length
248
+ if server.cipher.implicit_mac?
249
+ return nil if available < need + server.cipher.mac_length
250
+ else
251
+ return nil if available < need + server.hmac.mac_length # rubocop:disable Style/IfInsideElse
252
+ end
242
253
 
243
254
  if need > 0
244
255
  # read the remainder of the packet and decrypt it.
245
256
  data = read_available(need)
246
- @mac_data += data if server.hmac.etm
247
- @packet.append(server.update_cipher(data))
257
+ @mac_data += data if server.hmac.etm || server.cipher.implicit_mac?
258
+ unless server.cipher.implicit_mac?
259
+ @packet.append(
260
+ server.update_cipher(data)
261
+ )
262
+ end
248
263
  end
249
264
 
250
- # get the hmac from the tail of the packet (if one exists), and
251
- # then validate it.
252
- real_hmac = read_available(server.hmac.mac_length) || ""
253
-
254
- @packet.append(server.final_cipher)
255
- padding_length = @packet.read_byte
265
+ if server.cipher.implicit_mac?
266
+ real_hmac = read_available(server.cipher.mac_length) || ""
267
+ @packet = Net::SSH::Buffer.new(server.cipher.read_and_mac(@mac_data, real_hmac, server.sequence_number))
268
+ padding_length = @packet.read_byte
269
+ payload = @packet.read(@packet_length - padding_length - 1)
270
+ else
271
+ # get the hmac from the tail of the packet (if one exists), and
272
+ # then validate it.
273
+ real_hmac = read_available(server.hmac.mac_length) || ""
256
274
 
257
- payload = @packet.read(@packet_length - padding_length - 1)
275
+ @packet.append(server.final_cipher)
276
+ padding_length = @packet.read_byte
258
277
 
259
- my_computed_hmac = if server.hmac.etm
260
- server.hmac.digest([server.sequence_number, @mac_data].pack("NA*"))
261
- else
262
- server.hmac.digest([server.sequence_number, @packet.content].pack("NA*"))
263
- end
264
- raise Net::SSH::Exception, "corrupted hmac detected #{server.hmac.class}" if real_hmac != my_computed_hmac
278
+ payload = @packet.read(@packet_length - padding_length - 1)
265
279
 
280
+ my_computed_hmac = if server.hmac.etm
281
+ server.hmac.digest([server.sequence_number, @mac_data].pack("NA*"))
282
+ else
283
+ server.hmac.digest([server.sequence_number, @packet.content].pack("NA*"))
284
+ end
285
+ raise Net::SSH::Exception, "corrupted hmac detected #{server.hmac.class}" if real_hmac != my_computed_hmac
286
+ end
266
287
  # try to decompress the payload, in case compression is active
267
288
  payload = server.decompress(payload)
268
289
 
@@ -49,10 +49,10 @@ module Net
49
49
  MAJOR = 7
50
50
 
51
51
  # The minor component of this version of the Net::SSH library
52
- MINOR = 1
52
+ MINOR = 2
53
53
 
54
54
  # The tiny component of this version of the Net::SSH library
55
- TINY = 0
55
+ TINY = 3
56
56
 
57
57
  # The prerelease component of this version of the Net::SSH library
58
58
  # nil allowed
data/lib/net/ssh.rb CHANGED
@@ -64,9 +64,9 @@ module Net
64
64
  # Net::SSH.start for a description of each option.
65
65
  VALID_OPTIONS = %i[
66
66
  auth_methods bind_address compression compression_level config
67
- encryption forward_agent hmac host_key remote_user
67
+ encryption forward_agent hmac host_key identity_agent remote_user
68
68
  keepalive keepalive_interval keepalive_maxcount kex keys key_data
69
- keycerts languages logger paranoid password port proxy
69
+ keycerts keycert_data languages logger paranoid password port proxy
70
70
  rekey_blocks_limit rekey_limit rekey_packet_limit timeout verbose
71
71
  known_hosts global_known_hosts_file user_known_hosts_file host_key_alias
72
72
  host_name user properties passphrase keys_only max_pkt_size
@@ -146,6 +146,8 @@ module Net
146
146
  # and hostbased authentication
147
147
  # * :keycerts => an array of file names of key certificates to use
148
148
  # with publickey authentication
149
+ # * :keycert_data => an array of strings, which each element of the array
150
+ # being a key certificate to use with publickey authentication
149
151
  # * :key_data => an array of strings, with each element of the array being
150
152
  # a raw private key in PEM format.
151
153
  # * :keys_only => set to +true+ to use only private keys from +keys+ and
@@ -192,6 +194,7 @@ module Net
192
194
  # Defaults to %w(~/.ssh/known_hosts ~/.ssh/known_hosts2).
193
195
  # * :use_agent => Set false to disable the use of ssh-agent. Defaults to
194
196
  # true
197
+ # * :identity_agent => the path to the ssh-agent's UNIX socket
195
198
  # * :verbose => how verbose to be (Logger verbosity constants, Logger::DEBUG
196
199
  # is very verbose, Logger::FATAL is all but silent). Logger::FATAL is the
197
200
  # default. The symbols :debug, :info, :warn, :error, and :fatal are also
@@ -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
+ b20wHhcNMjQwNDAxMDk1NjIxWhcNMjUwNDAxMDk1NjIxWjBBMQ8wDQYDVQQDDAZu
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
+ 9w0BAQsFAAOCAQEAfY2WbsBKwRtBep4l+Y2/84H1BKH9UVOsFxqQzYkvM2LFDyup
16
+ UkjYf8nPSjg3mquhaiA5KSoSVUPpNDfQo+UvY3+mlxRs96ttWiUGwz27fy82rx1B
17
+ ZnfKjsWOntemNON6asOD0mtv0xsNBfOB2VNIKW/uqHsiPpa0OaVy5uENhX+5OFan
18
+ 2P1Uy+WcMiv38RlRkn4cdEIZUFupDgKFsguYlaJy473/wsae4exUgc5bvi3Splob
19
+ 1uE/LmB/qWBVSNW8e9KDtJynhDDZBlpESyQHFQCZj6UapzxlnC46LaDncPoAtJPc
20
+ MlWxJ8mKghIcyXc5y4cSyGypNG5BralqnvQUyg==
20
21
  -----END CERTIFICATE-----
data/net-ssh.gemspec CHANGED
@@ -36,9 +36,12 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency('x25519') unless RUBY_PLATFORM == 'java'
37
37
  end
38
38
 
39
+ spec.add_development_dependency('rbnacl', '~> 7.1') unless ENV['NET_SSH_NO_RBNACL']
40
+
41
+ spec.add_development_dependency "base64"
39
42
  spec.add_development_dependency "bundler", ">= 1.17"
40
- spec.add_development_dependency "minitest", "~> 5.10"
41
- spec.add_development_dependency "mocha", "~> 1.11.2"
43
+ spec.add_development_dependency "minitest", "~> 5.19"
44
+ spec.add_development_dependency "mocha", "~> 2.1.0"
42
45
  spec.add_development_dependency "rake", "~> 12.0"
43
46
  spec.add_development_dependency "rubocop", "~> 1.28.0"
44
47
  end
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: 7.1.0
4
+ version: 7.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
@@ -12,26 +12,27 @@ 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
+ b20wHhcNMjQwNDAxMDk1NjIxWhcNMjUwNDAxMDk1NjIxWjBBMQ8wDQYDVQQDDAZu
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
+ 9w0BAQsFAAOCAQEAfY2WbsBKwRtBep4l+Y2/84H1BKH9UVOsFxqQzYkvM2LFDyup
29
+ UkjYf8nPSjg3mquhaiA5KSoSVUPpNDfQo+UvY3+mlxRs96ttWiUGwz27fy82rx1B
30
+ ZnfKjsWOntemNON6asOD0mtv0xsNBfOB2VNIKW/uqHsiPpa0OaVy5uENhX+5OFan
31
+ 2P1Uy+WcMiv38RlRkn4cdEIZUFupDgKFsguYlaJy473/wsae4exUgc5bvi3Splob
32
+ 1uE/LmB/qWBVSNW8e9KDtJynhDDZBlpESyQHFQCZj6UapzxlnC46LaDncPoAtJPc
33
+ MlWxJ8mKghIcyXc5y4cSyGypNG5BralqnvQUyg==
33
34
  -----END CERTIFICATE-----
34
- date: 2023-03-12 00:00:00.000000000 Z
35
+ date: 2024-04-02 00:00:00.000000000 Z
35
36
  dependencies:
36
37
  - !ruby/object:Gem::Dependency
37
38
  name: bcrypt_pbkdf
@@ -75,6 +76,34 @@ dependencies:
75
76
  - - ">="
76
77
  - !ruby/object:Gem::Version
77
78
  version: '0'
79
+ - !ruby/object:Gem::Dependency
80
+ name: rbnacl
81
+ requirement: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '7.1'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: '7.1'
93
+ - !ruby/object:Gem::Dependency
94
+ name: base64
95
+ requirement: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ type: :development
101
+ prerelease: false
102
+ version_requirements: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
78
107
  - !ruby/object:Gem::Dependency
79
108
  name: bundler
80
109
  requirement: !ruby/object:Gem::Requirement
@@ -95,28 +124,28 @@ dependencies:
95
124
  requirements:
96
125
  - - "~>"
97
126
  - !ruby/object:Gem::Version
98
- version: '5.10'
127
+ version: '5.19'
99
128
  type: :development
100
129
  prerelease: false
101
130
  version_requirements: !ruby/object:Gem::Requirement
102
131
  requirements:
103
132
  - - "~>"
104
133
  - !ruby/object:Gem::Version
105
- version: '5.10'
134
+ version: '5.19'
106
135
  - !ruby/object:Gem::Dependency
107
136
  name: mocha
108
137
  requirement: !ruby/object:Gem::Requirement
109
138
  requirements:
110
139
  - - "~>"
111
140
  - !ruby/object:Gem::Version
112
- version: 1.11.2
141
+ version: 2.1.0
113
142
  type: :development
114
143
  prerelease: false
115
144
  version_requirements: !ruby/object:Gem::Requirement
116
145
  requirements:
117
146
  - - "~>"
118
147
  - !ruby/object:Gem::Version
119
- version: 1.11.2
148
+ version: 2.1.0
120
149
  - !ruby/object:Gem::Dependency
121
150
  name: rake
122
151
  requirement: !ruby/object:Gem::Requirement
@@ -157,6 +186,7 @@ extra_rdoc_files:
157
186
  - README.md
158
187
  files:
159
188
  - ".dockerignore"
189
+ - ".github/FUNDING.yml"
160
190
  - ".github/config/rubocop_linter_action.yml"
161
191
  - ".github/workflows/ci-with-docker.yml"
162
192
  - ".github/workflows/ci.yml"
@@ -165,10 +195,12 @@ files:
165
195
  - ".rubocop.yml"
166
196
  - ".rubocop_todo.yml"
167
197
  - CHANGES.txt
198
+ - DEVELOPMENT.md
168
199
  - Dockerfile
169
200
  - Dockerfile.openssl3
170
201
  - Gemfile
171
202
  - Gemfile.noed25519
203
+ - Gemfile.norbnacl
172
204
  - ISSUE_TEMPLATE.md
173
205
  - LICENSE.txt
174
206
  - Manifest
@@ -227,6 +259,8 @@ files:
227
259
  - lib/net/ssh/test/script.rb
228
260
  - lib/net/ssh/test/socket.rb
229
261
  - lib/net/ssh/transport/algorithms.rb
262
+ - lib/net/ssh/transport/chacha20_poly1305_cipher.rb
263
+ - lib/net/ssh/transport/chacha20_poly1305_cipher_loader.rb
230
264
  - lib/net/ssh/transport/cipher_factory.rb
231
265
  - lib/net/ssh/transport/constants.rb
232
266
  - lib/net/ssh/transport/ctr.rb
@@ -260,6 +294,7 @@ files:
260
294
  - lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb
261
295
  - lib/net/ssh/transport/key_expander.rb
262
296
  - lib/net/ssh/transport/openssl.rb
297
+ - lib/net/ssh/transport/openssl_cipher_extensions.rb
263
298
  - lib/net/ssh/transport/packet_stream.rb
264
299
  - lib/net/ssh/transport/server_version.rb
265
300
  - lib/net/ssh/transport/session.rb
metadata.gz.sig CHANGED
Binary file