net-ssh 7.1.0 → 7.2.3

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: 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