diff options
author | Miklós Fazekas <mfazekas@szemafor.com> | 2018-02-06 10:45:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-06 10:45:35 +0100 |
commit | ab9bdab03618012a553d435b76b6e0480d4e996f (patch) | |
tree | 22150e70420a80dc7b8a958b07aa6d59041fb6ea | |
parent | 0cb2ead9add545abbfeaa757a27909460808345d (diff) | |
parent | 38d95432f454ea7b3d22804d619147d1d370ec2e (diff) | |
download | net-ssh-ab9bdab03618012a553d435b76b6e0480d4e996f.tar.gz |
Merge branch 'master' into fix-tests
-rw-r--r-- | .travis.yml | 19 | ||||
-rw-r--r-- | CHANGES.txt | 7 | ||||
-rw-r--r-- | Gemfile | 4 | ||||
-rw-r--r-- | Gemfile.noed25519 (renamed from Gemfile.norbnacl) | 2 | ||||
-rw-r--r-- | Gemfile.noed25519.lock (renamed from Gemfile.norbnacl.lock) | 28 | ||||
-rw-r--r-- | README.rdoc | 2 | ||||
-rw-r--r-- | appveyor.yml | 10 | ||||
-rw-r--r-- | lib/net/ssh.rb | 2 | ||||
-rw-r--r-- | lib/net/ssh/authentication/agent.rb | 4 | ||||
-rw-r--r-- | lib/net/ssh/authentication/ed25519.rb | 27 | ||||
-rw-r--r-- | lib/net/ssh/authentication/ed25519_loader.rb | 5 | ||||
-rw-r--r-- | lib/net/ssh/config.rb | 51 | ||||
-rw-r--r-- | lib/net/ssh/transport/cipher_factory.rb | 27 | ||||
-rw-r--r-- | lib/net/ssh/transport/ctr.rb | 33 | ||||
-rw-r--r-- | lib/net/ssh/version.rb | 6 | ||||
-rw-r--r-- | net-ssh.gemspec | 7 | ||||
-rw-r--r-- | test/authentication/test_agent.rb | 4 | ||||
-rw-r--r-- | test/authentication/test_ed25519.rb | 4 | ||||
-rw-r--r-- | test/configs/match | 15 | ||||
-rw-r--r-- | test/integration/test_cert_user_auth.rb | 2 | ||||
-rw-r--r-- | test/integration/test_ed25519_pkeys.rb | 2 | ||||
-rw-r--r-- | test/test_config.rb | 8 | ||||
-rw-r--r-- | test/transport/test_cipher_factory.rb | 64 |
23 files changed, 228 insertions, 105 deletions
diff --git a/.travis.yml b/.travis.yml index eaf1e46..3c7e37e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,8 @@ addon: rvm: - 2.2 - 2.3.5 - - 2.4.2 + - 2.4.3 + - 2.5.0 - jruby-9.1.13.0 - rbx-3.84 - ruby-head @@ -34,16 +35,18 @@ matrix: install: - export JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false' - sudo pip install ansible - - gem install bundler -v "= 1.13.7" - - bundle _1.13.7_ install - - BUNDLE_GEMFILE=./Gemfile.norbnacl bundle _1.13.7_ install + - gem install bundler -v "= 1.16" + - gem list bundler + - bundle _1.16_ install + - bundle _1.16_ -v + - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.16_ install - sudo ansible-galaxy install rvm_io.ruby - sudo chown -R travis:travis /home/travis/.ansible - ansible-playbook ./test/integration/playbook.yml -i "localhost," --become -c local -e 'no_rvm=true' -e 'myuser=travis' -e 'mygroup=travis' -e 'homedir=/home/travis' script: - ssh -V - - bundle _1.13.7_ exec rake test - - BUNDLE_GEMFILE=./Gemfile.norbnacl bundle _1.13.7_ exec rake test - - bundle _1.13.7_ exec rake test_test - - bundle _1.13.7_ exec rubocop + - bundle _1.16_ exec rake test + - BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.16_ exec rake test + - bundle _1.16_ exec rake test_test + - bundle _1.16_ exec rubocop diff --git a/CHANGES.txt b/CHANGES.txt index 7deed90..32c5d41 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,10 @@ +=== 5.0.0.beta1 + + * Use OpenSSL for aes*-ctr for up to 5x throughput improvement [Miklós Fazekas, Harald Sitter, #570] + * Optimize slice! usage in CTR for up to 2x throughput improvement [Harald Sitter, #569] + * Replace RbNaCl dependency with ed25519 gem [Tony Arcieri ,#563] + * Add initial Match support [Kasumi Hanazuki, #553] + === 4.2.0.rc2 * Fix double close bug on auth failure (or ruby 2.2 or earlier) [#538] @@ -7,10 +7,6 @@ if !Gem.win_platform? && RUBY_ENGINE == "ruby" gem 'byebug', group: [:development, :test] end -if (Gem::Version.new(RUBY_VERSION) <=> Gem::Version.new("2.2.6")) < 0 - gem 'rbnacl', '< 4.0' -end - if ENV["CI"] gem 'codecov', require: false, group: :test gem 'simplecov', require: false, group: :test diff --git a/Gemfile.norbnacl b/Gemfile.noed25519 index 999aa32..b6c3576 100644 --- a/Gemfile.norbnacl +++ b/Gemfile.noed25519 @@ -1,6 +1,6 @@ source 'https://rubygems.org' -ENV['NET_SSH_NO_RBNACL'] = 'true' +ENV['NET_SSH_NO_ED25519'] = 'true' # Specify your gem's dependencies in mygem.gemspec gemspec diff --git a/Gemfile.norbnacl.lock b/Gemfile.noed25519.lock index a64c7da..3d15a2f 100644 --- a/Gemfile.norbnacl.lock +++ b/Gemfile.noed25519.lock @@ -1,33 +1,33 @@ PATH remote: . specs: - net-ssh (4.0.0) + net-ssh (4.2.0) GEM remote: https://rubygems.org/ specs: ast (2.3.0) metaclass (0.0.4) - minitest (5.10.1) - mocha (1.2.1) + minitest (5.10.3) + mocha (1.3.0) metaclass (~> 0.0.1) - parser (2.3.3.1) - ast (~> 2.2) + parser (2.4.0.2) + ast (~> 2.3) powerpack (0.1.1) - rainbow (2.1.0) - rake (12.0.0) - rubocop (0.46.0) - parser (>= 2.3.1.1, < 3.0) + rainbow (2.2.2) + rake + rake (12.3.0) + rubocop (0.47.1) + parser (>= 2.3.3.1, < 3.0) powerpack (~> 0.1) rainbow (>= 1.99.1, < 3.0) ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) - ruby-progressbar (1.8.1) - unicode-display_width (1.1.2) + ruby-progressbar (1.9.0) + unicode-display_width (1.3.0) PLATFORMS ruby - x86-mingw32 DEPENDENCIES bundler (~> 1.11) @@ -35,7 +35,7 @@ DEPENDENCIES mocha (>= 1.2.1) net-ssh! rake (~> 12.0) - rubocop (~> 0.46.0) + rubocop (~> 0.47.0) BUNDLED WITH - 1.13.6 + 1.14.6 diff --git a/README.rdoc b/README.rdoc index 1545874..f774538 100644 --- a/README.rdoc +++ b/README.rdoc @@ -106,7 +106,7 @@ Then, when install the gem, do so with high security: If you don't add the public key, you'll see an error like "Couldn't verify data signature". If you're still having trouble let me know and I'll give you a hand. -For ed25519 public key auth support your bundle file should contain ```rbnacl-libsodium```, ```rbnacl```, ```bcrypt_pbkdf``` dependencies. +For ed25519 public key auth support your bundle file should contain ```ed25519```, ```bcrypt_pbkdf``` dependencies. == RUBY SUPPORT diff --git a/appveyor.yml b/appveyor.yml index 4c80d4c..2beadc6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -29,9 +29,9 @@ install: - if "%ruby_version%" == "jruby-9.1.2.0" ( cinst jruby --version 9.1.2.0 -i --allow-empty-checksums ) - if "%ruby_version%" == "jruby-9.1.2.0" ( SET "PATH=C:\jruby-9.1.2.0\bin\;%PATH%" ) - ruby --version - - gem install bundler --no-document -v 1.13.5 - - SET BUNDLE_GEMFILE=Gemfile.norbnacl - - bundle _1.13.5_ install --retry=3 + - gem install bundler --no-document --user-install -v 1.16 + - SET BUNDLE_GEMFILE=Gemfile.noed25519 + - bundle install --retry=3 - cinst freesshd - cinst putty --allow-empty-checksums - ps: | @@ -49,8 +49,8 @@ install: } test_script: - - SET BUNDLE_GEMFILE=Gemfile.norbnacl + - SET BUNDLE_GEMFILE=Gemfile.noed25519 - SET NET_SSH_RUN_WIN_INTEGRATION_TESTS=YES - - bundle _1.13.5_ exec rake test + - bundle exec rake test build: off diff --git a/lib/net/ssh.rb b/lib/net/ssh.rb index f3d88c3..6471eb0 100644 --- a/lib/net/ssh.rb +++ b/lib/net/ssh.rb @@ -192,7 +192,7 @@ module Net # * :password_prompt => a custom prompt object with ask method. See Net::SSH::Prompt # # * :agent_socket_factory => enables the user to pass a lambda/block that will serve as the socket factory - # Net::SSH::start(user,host,agent_socket_factory: ->{ UNIXSocket.open('/foo/bar') }) + # Net::SSH.start(host,user,agent_socket_factory: ->{ UNIXSocket.open('/foo/bar') }) # example: ->{ UNIXSocket.open('/foo/bar')} # * :verify_host_key => either false, true, :very, or :secure specifying how # strict host-key verification should be (in increasing order here). diff --git a/lib/net/ssh/authentication/agent.rb b/lib/net/ssh/authentication/agent.rb index 1085d9c..f019458 100644 --- a/lib/net/ssh/authentication/agent.rb +++ b/lib/net/ssh/authentication/agent.rb @@ -238,12 +238,12 @@ module Net; module SSH; module Authentication Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.private_key).to_s when /^ssh-ed25519$/ Net::SSH::Buffer.from(:string, priv_key.public_key.verify_key.to_bytes, - :string, priv_key.sign_key.keypair_bytes).to_s + :string, priv_key.sign_key.keypair).to_s when /^ssh-ed25519-cert-v01@openssh\.com$/ # Unlike the other certificate types, the public key is included after the certifiate. Net::SSH::Buffer.from(:string, priv_key.to_blob, :string, priv_key.key.public_key.verify_key.to_bytes, - :string, priv_key.key.sign_key.keypair_bytes).to_s + :string, priv_key.key.sign_key.keypair).to_s when /^ssh-rsa$/ # `n` and `e` are reversed compared to the ordering in `OpenSSL::PKey::RSA#to_blob`. Net::SSH::Buffer.from(:bignum, priv_key.n, :bignum, priv_key.e, :bignum, priv_key.d, diff --git a/lib/net/ssh/authentication/ed25519.rb b/lib/net/ssh/authentication/ed25519.rb index a92011a..571a40c 100644 --- a/lib/net/ssh/authentication/ed25519.rb +++ b/lib/net/ssh/authentication/ed25519.rb @@ -1,16 +1,7 @@ -gem 'rbnacl', '>= 3.2.0', '< 5.0' +gem 'ed25519', '~> 1.2' gem 'bcrypt_pbkdf', '~> 1.0' unless RUBY_PLATFORM == "java" -begin - require 'rbnacl/libsodium' -rescue LoadError # rubocop:disable Lint/HandleExceptions -end - -require 'rbnacl' -require 'rbnacl/signatures/ed25519/verify_key' -require 'rbnacl/signatures/ed25519/signing_key' - -require 'rbnacl/hash' +require 'ed25519' require 'base64' @@ -19,10 +10,12 @@ require 'bcrypt_pbkdf' unless RUBY_PLATFORM == "java" module Net; module SSH; module Authentication module ED25519 - class SigningKeyFromFile < RbNaCl::Signatures::Ed25519::SigningKey + class SigningKeyFromFile < SimpleDelegator def initialize(pk,sk) - @signing_key = sk - @verify_key = RbNaCl::Signatures::Ed25519::VerifyKey.new(pk) + key = ::Ed25519::SigningKey.from_keypair(sk) + raise ArgumentError, "pk does not match sk" unless pk == key.verify_key.to_bytes + + super(key) end end @@ -30,7 +23,7 @@ module ED25519 attr_reader :verify_key def initialize(data) - @verify_key = RbNaCl::Signatures::Ed25519::VerifyKey.new(data) + @verify_key = ::Ed25519::VerifyKey.new(data) end def self.read_keyblob(buffer) @@ -151,10 +144,6 @@ module ED25519 def self.read(data,password) self.new(data,password) end - - def self.read_keyblob(buffer) - ED25519::PubKey.read_keyblob(buffer) - end end end end; end; end diff --git a/lib/net/ssh/authentication/ed25519_loader.rb b/lib/net/ssh/authentication/ed25519_loader.rb index 5c3d43f..c609b9c 100644 --- a/lib/net/ssh/authentication/ed25519_loader.rb +++ b/lib/net/ssh/authentication/ed25519_loader.rb @@ -21,10 +21,9 @@ end def self.dependenciesRequiredForED25519 result = "net-ssh requires the following gems for ed25519 support:\n" - result << " * rbnacl (>= 3.2, < 5.0)\n" - result << " * rbnacl-libsodium, if your system doesn't have libsodium installed.\n" + result << " * ed25519 (>= 1.2, < 2.0)\n" result << " * bcrypt_pbkdf (>= 1.0, < 2.0)\n" unless RUBY_PLATFORM == "java" - result << "See https://github.com/net-ssh/net-ssh/issues/478 for more information\n" + result << "See https://github.com/net-ssh/net-ssh/issues/565 for more information\n" end end diff --git a/lib/net/ssh/config.rb b/lib/net/ssh/config.rb index 46d8373..2c98b5b 100644 --- a/lib/net/ssh/config.rb +++ b/lib/net/ssh/config.rb @@ -78,8 +78,8 @@ module Net; module SSH return settings unless File.readable?(file) globals = {} - host_matched = false - seen_host = false + block_matched = false + block_seen = false IO.foreach(file) do |line| next if line =~ /^\s*(?:#.*)?$/ @@ -112,14 +112,17 @@ module Net; module SSH negative_matched = negative_hosts.any? { |h| host =~ pattern2regex(h[1..-1]) } if negative_matched - host_matched = false + block_matched = false else - host_matched = positive_hosts.any? { |h| host =~ pattern2regex(h) } + block_matched = positive_hosts.any? { |h| host =~ pattern2regex(h) } end - seen_host = true + block_seen = true settings[key] = host - elsif !seen_host + elsif key == 'match' + block_matched = eval_match_condition(value, host, settings) + block_seen = true + elsif !block_seen case key when 'identityfile' (globals[key] ||= []) << value @@ -130,7 +133,7 @@ module Net; module SSH else globals[key] = value unless settings.key?(key) end - elsif host_matched + elsif block_matched case key when 'identityfile' (settings[key] ||= []) << value @@ -144,18 +147,14 @@ module Net; module SSH end end - if globals - settings = globals.merge(settings) do |key, oldval, newval| - case key - when 'identityfile' - oldval + newval - else - newval - end + globals.merge(settings) do |key, oldval, newval| + case key + when 'identityfile' + oldval + newval + else + newval end end - - return settings end # Given a hash of OpenSSH configuration options, converts them into @@ -323,6 +322,24 @@ module Net; module SSH def tokenize_config_value(str) str.scan(/([^"\s]+)?(?:"([^"]+)")?\s*/).map(&:join) end + + def eval_match_condition(condition, host, settings) + if condition.start_with?('!') + negated = true + condition = condition[1..-1] + else + negated = false + end + + condition_met = + case condition + when 'all' + true + end + + # return false for unsupported conditions + condition_met.nil? ? false : (negated ^ condition_met) + end end end diff --git a/lib/net/ssh/transport/cipher_factory.rb b/lib/net/ssh/transport/cipher_factory.rb index e7e39d1..d3b3991 100644 --- a/lib/net/ssh/transport/cipher_factory.rb +++ b/lib/net/ssh/transport/cipher_factory.rb @@ -24,9 +24,10 @@ module Net; module SSH; module Transport "3des-ctr" => "des-ede3", "blowfish-ctr" => "bf-ecb", - "aes256-ctr" => "aes-256-ecb", - "aes192-ctr" => "aes-192-ecb", - "aes128-ctr" => "aes-128-ecb", + + "aes256-ctr" => "aes-256-ctr", + "aes192-ctr" => "aes-192-ctr", + "aes128-ctr" => "aes-128-ctr", "cast128-ctr" => "cast5-ecb", "none" => "none", @@ -63,7 +64,13 @@ module Net; module SSH; module Transport cipher.padding = 0 - cipher.extend(Net::SSH::Transport::CTR) if (name =~ /-ctr(@openssh.org)?$/) + if name =~ /-ctr(@openssh.org)?$/ + if ossl_name !~ /-ctr/ + cipher.extend(Net::SSH::Transport::CTR) + else + cipher = Net::SSH::Transport::OpenSSLAESCTR.new(cipher) + end + end cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4" key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len @@ -89,7 +96,17 @@ module Net; module SSH; module Transport key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len cipher.key_len = key_len - result = [key_len, ossl_name=="rc4" ? 8 : cipher.block_size] + block_size = + case ossl_name + when "rc4" + 8 + when /\-ctr/ + Net::SSH::Transport::OpenSSLAESCTR.block_size + else + cipher.block_size + end + + result = [key_len, block_size] result << cipher.iv_len if options[:iv_len] end result diff --git a/lib/net/ssh/transport/ctr.rb b/lib/net/ssh/transport/ctr.rb index 8b446b5..6c7c86c 100644 --- a/lib/net/ssh/transport/ctr.rb +++ b/lib/net/ssh/transport/ctr.rb @@ -1,7 +1,31 @@ require 'openssl' module Net::SSH::Transport + #:nodoc: + class OpenSSLAESCTR < SimpleDelegator + def initialize(original) + super + @was_reset = false + end + + def block_size + 16 + end + def self.block_size + 16 + end + + def reset + @was_reset = true + end + + def iv=(iv_s) + super unless @was_reset + end + end + + #:nodoc: # Pure-Ruby implementation of Stateful Decryption Counter(SDCTR) Mode # for Block Ciphers. See RFC4344 for detail. module CTR @@ -12,7 +36,7 @@ module Net::SSH::Transport @counter_len = orig.block_size orig.encrypt orig.padding = 0 - + singleton_class.send(:alias_method, :_update, :update) singleton_class.send(:private, :_update) singleton_class.send(:undef_method, :update) @@ -50,11 +74,14 @@ module Net::SSH::Transport encrypted = "" - while @remaining.bytesize >= block_size - encrypted += xor!(@remaining.slice!(0, block_size), + offset = 0 + while (@remaining.bytesize - offset) >= block_size + encrypted += xor!(@remaining.slice(offset, block_size), _update(@counter)) increment_counter! + offset += block_size end + @remaining = @remaining.slice(offset..-1) encrypted end diff --git a/lib/net/ssh/version.rb b/lib/net/ssh/version.rb index e380c60..aa4d992 100644 --- a/lib/net/ssh/version.rb +++ b/lib/net/ssh/version.rb @@ -45,17 +45,17 @@ module Net; module SSH end # The major component of this version of the Net::SSH library - MAJOR = 4 + MAJOR = 5 # The minor component of this version of the Net::SSH library - MINOR = 2 + MINOR = 0 # The tiny component of this version of the Net::SSH library TINY = 0 # The prerelease component of this version of the Net::SSH library # nil allowed - PRE = nil + PRE = "beta1" # The current version of the Net::SSH library as a Version instance CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact) diff --git a/net-ssh.gemspec b/net-ssh.gemspec index 91ab190..dabc785 100644 --- a/net-ssh.gemspec +++ b/net-ssh.gemspec @@ -16,7 +16,7 @@ Gem::Specification.new do |spec| 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.} spec.homepage = "https://github.com/net-ssh/net-ssh" spec.license = "MIT" - spec.required_ruby_version = Gem::Requirement.new(">= 2.0") + spec.required_ruby_version = Gem::Requirement.new(">= 2.2.6") spec.extra_rdoc_files = [ "LICENSE.txt", @@ -28,9 +28,8 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - unless ENV['NET_SSH_NO_RBNACL'] - spec.add_development_dependency("rbnacl-libsodium", "~> 1.0.11") - spec.add_development_dependency("rbnacl", ['>= 3.2.0','< 5.0']) + unless ENV['NET_SSH_NO_ED25519'] + spec.add_development_dependency("ed25519", "~> 1.2") spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0") unless RUBY_PLATFORM == "java" end diff --git a/test/authentication/test_agent.rb b/test/authentication/test_agent.rb index 78659c2..92fb862 100644 --- a/test/authentication/test_agent.rb +++ b/test/authentication/test_agent.rb @@ -312,7 +312,7 @@ EOF assert_equal SSH2_AGENT_ADD_IDENTITY, type assert_equal buffer.read_string, "ssh-ed25519" assert_equal buffer.read_string, ed25519.public_key.verify_key.to_bytes - assert_equal buffer.read_string, ed25519.sign_key.keypair_bytes + assert_equal buffer.read_string, ed25519.sign_key.keypair assert_equal 'foobar', buffer.read_string assert buffer.eof? @@ -330,7 +330,7 @@ EOF assert_equal buffer.read_string, "ssh-ed25519-cert-v01@openssh.com" assert_equal buffer.read_string, cert.to_blob assert_equal buffer.read_string, cert.key.public_key.verify_key.to_bytes - assert_equal buffer.read_string, cert.key.sign_key.keypair_bytes + assert_equal buffer.read_string, cert.key.sign_key.keypair assert_equal 'foobar', buffer.read_string assert buffer.eof? diff --git a/test/authentication/test_ed25519.rb b/test/authentication/test_ed25519.rb index f4a1931..e9e10fd 100644 --- a/test/authentication/test_ed25519.rb +++ b/test/authentication/test_ed25519.rb @@ -1,4 +1,4 @@ -unless ENV['NET_SSH_NO_RBNACL'] +unless ENV['NET_SSH_NO_ED25519'] require 'common' require 'net/ssh/authentication/ed25519_loader' @@ -8,7 +8,7 @@ module Authentication class TestED25519 < NetSSHTest def setup - raise "No ED25519 set NET_SSH_NO_RBNACL to ignore this test" unless Net::SSH::Authentication::ED25519Loader::LOADED + raise "No ED25519 set NET_SSH_NO_ED25519 to ignore this test" unless Net::SSH::Authentication::ED25519Loader::LOADED end def test_no_pwd_key diff --git a/test/configs/match b/test/configs/match new file mode 100644 index 0000000..c610e8c --- /dev/null +++ b/test/configs/match @@ -0,0 +1,15 @@ +Host test.host + ForwardAgent yes + +Match all + Compression yes + +Match !all + Port 1234 + +Match unsupported + Port 2345 + +Host * + Port 22 + Compression no diff --git a/test/integration/test_cert_user_auth.rb b/test/integration/test_cert_user_auth.rb index 4045943..382d88f 100644 --- a/test/integration/test_cert_user_auth.rb +++ b/test/integration/test_cert_user_auth.rb @@ -5,7 +5,7 @@ require 'net/ssh' # 1. cert files: /etc/ssh/users_ca and /etc/ssh/users_ca.pub and # 2. /etc/ssh/sshd_config: TrustedUserCAKeys /etc/ssh/users_ca.pub -unless ENV['NET_SSH_NO_RBNACL'] +unless ENV['NET_SSH_NO_ED25519'] class TestCertUserAuth < NetSSHTest include IntegrationTestHelpers diff --git a/test/integration/test_ed25519_pkeys.rb b/test/integration/test_ed25519_pkeys.rb index 56efcee..4e17e0c 100644 --- a/test/integration/test_ed25519_pkeys.rb +++ b/test/integration/test_ed25519_pkeys.rb @@ -4,7 +4,7 @@ require 'tmpdir' require 'net/ssh' -unless ENV['NET_SSH_NO_RBNACL'] +unless ENV['NET_SSH_NO_ED25519'] # see Vagrantfile,playbook for env. # we're running as net_ssh_1 user password foo # and usually connecting to net_ssh_2 user password foo2pwd diff --git a/test/test_config.rb b/test/test_config.rb index 6c34f7a..662a01d 100644 --- a/test/test_config.rb +++ b/test/test_config.rb @@ -286,6 +286,14 @@ class TestConfig < NetSSHTest assert_equal %w(~/.ssh/id.pem ~/.ssh/id2.pem ~/.ssh/id3.pem), net_ssh[:keys] end + def test_load_with_match_block + config = Net::SSH::Config.load(config(:match), "test.host") + net_ssh = Net::SSH::Config.translate(config) + assert_equal true, net_ssh[:forward_agent] + assert_equal true, net_ssh[:compression] + assert_equal 22, net_ssh[:port] + end + private def with_home_env(value,&block) diff --git a/test/transport/test_cipher_factory.rb b/test/transport/test_cipher_factory.rb index bbc6525..5b9ba7d 100644 --- a/test/transport/test_cipher_factory.rb +++ b/test/transport/test_cipher_factory.rb @@ -56,11 +56,11 @@ module Transport def test_lengths_for_arcfour128 assert_equal [16,8], factory.get_lengths("arcfour128") end - + def test_lengths_for_arcfour256 assert_equal [32,8], factory.get_lengths("arcfour256") end - + def test_lengths_for_arcfour512 assert_equal [64,8], factory.get_lengths("arcfour512") end @@ -180,33 +180,33 @@ module Transport def test_arcfour_for_decryption assert_equal TEXT, decrypt("arcfour", ARCFOUR) end - + ARCFOUR128 = "\n\x90\xED*\xD4\xBE\xCBg5\xA5\a\xEC]\x97\xB7L\x06)6\x12FL\x90@\xF4Sqxqh\r\x11\x1Aq \xC8\xE6v\xC6\x12\xD9<A\xDAZ\xFE\x7F\x88\x19f.\x06\xA7\xFE:\xFF\x93\x9B\x8D\xA0\\\x9E\xCA\x03\x15\xE1\xE2\f\xC0\b\xA2C\xE1\xBD\xB6\x13D\xD1\xB4'g\x89\xDC\xEB\f\x19Z)U" def test_arcfour128_for_encryption assert_equal ARCFOUR128, encrypt("arcfour128") end - + def test_arcfour128_for_decryption assert_equal TEXT, decrypt("arcfour128", ARCFOUR128) end - + ARCFOUR256 = "|g\xCCw\xF5\xC1y\xEB\xF0\v\xF7\x83\x14\x03\xC8\xAB\xE8\xC2\xFCY\xDC,\xB8\xD4dVa\x8B\x18%\xA4S\x00\xE0at\x86\xE8\xA6W\xAB\xD2\x9D\xA8\xDE[g\aZy.\xFB\xFC\x82c\x04h\f\xBFYq\xB7U\x80\x0EG\x91\x88\xDF\xA3\xA2\xFA(\xEC\xDB\xA4\xE7\xFE)\x12u\xAF\x0EZ\xA0\xBA\x97\n\xFC" def test_arcfour256_for_encryption assert_equal ARCFOUR256, encrypt("arcfour256") end - + def test_arcfour256_for_decryption assert_equal TEXT, decrypt("arcfour256", ARCFOUR256) end - + ARCFOUR512 = "|8\"v\xE7\xE3\b\xA8\x19\x9Aa\xB6Vv\x00\x11\x8A$C\xB6xE\xEF\xF1j\x90\xA8\xFA\x10\xE4\xA1b8\xF6\x04\xF2+\xC0\xD1(8\xEBT]\xB0\xF3/\xD9\xE0@\x83\a\x93\x9D\xCA\x04RXS\xB7A\x0Fj\x94\bE\xEB\x84j\xB4\xDF\nU\xF7\x83o\n\xE8\xF9\x01{jH\xEE\xCDQym\x9E" def test_arcfour512_for_encryption assert_equal ARCFOUR512, encrypt("arcfour512") end - + def test_arcfour512_for_decryption assert_equal TEXT, decrypt("arcfour512", ARCFOUR512) end @@ -252,11 +252,20 @@ module Transport end AES128_CTR = "\x9D\xC7]R\x89\x01\xC4\x14\x00\xE7\xCEc`\x80\v\xC7\xF7\xBD\xD5#d\f\xC9\xB0\xDE\xA6\x8Aq\x10p\x8F\xBC\xFF\x8B\xB4\xC5\xB3\xF7,\xF7eO\x06Q]\x0F\x05\x86\xEC\xA6\xC8\x12\xE9\xC4\x9D0\xD3\x9AL\x192\xAA\xDFu\x0E\xECz\x7F~g\xCA\xEA\xBA\x80,\x83V\x10\xF6/\x04\xD2\x8A\x94\x94\xA9T>~\xD2\r\xE6\x0E\xA0q\xEF" + AES128_CTR2 = "\xA5\xAA\xE3\xEC\xA7\xCCc\xFA~\x01\r\xD87\xE6\"\n6\x05\xD1\x9B\xC8_o\xD1i\xF6t\xD7[\xE5\x8B%>]\xD6\xC4<\x1DBd\xA9\x02\x9C\xEB\x89#\x955\xD6\x0F\xD0\x03\xF9\xC6\xD7\xB0@\e\\\xAB\xC0\xA9\xFB\x91\#{w\xADL\xF6'(\xCC\x14\xA2A\x16\xC1\x9C'\xD1\xBA'i\x88\x80\xF1\xA7E\x82\xA8\xC7@\xBA\a\xEA" def test_aes128_ctr_for_encryption assert_equal AES128_CTR, encrypt("aes128-ctr") end + def test_aes128_ctr_for_encryption2 + assert_equal [AES128_CTR, AES128_CTR2], encrypt2("aes128-ctr") + end + + def test_aes128_ctr_for_decryption2 + assert_equal [TEXT, TEXT2], decrypt2("aes128-ctr", [AES128_CTR, AES128_CTR2]) + end + def test_aes128_ctr_for_decryption assert_equal TEXT, decrypt("aes128-ctr", AES128_CTR) end @@ -272,11 +281,16 @@ module Transport end AES256_CTR = "2\xB8\xE6\xC9\x95\xB4\x05\xD2\xC7+\x7F\x88\xEB\xD4\xA0\b\"\xBF\x9E\x85t\x19,\e\x90\x11\x04b\xC7\xEE$\xDE\xE6\xC5@G\xFEm\xE1u\x9B\au\xAF\xB5\xB8\x857\x87\x139u\xAC\x1A\xAB\fh\x8FiW~\xB8:\xA4\xA0#~\xC4\x89\xBA5#:\xFC\xC8\xE3\x9B\xF0A2\x87\x980\xD1\xE3\xBC'\xBE\x1E\n\x1A*B\x06\xF3\xCC" + AES256_CTR2 = "\x13\xBF}\x93\xC3\xFCkw[\\\x8A\xDA\x9F\x85e3AH!\x19\xD9S(+x]B\x1A\x85):\x1Ce\xB1\xD1\x9F^\x8D\\\xFA\xFE\xC6\x9FDkm=?>.\x93\xA6O\x80\xB5o\xBE\xB5\\82\xEEWi\xFC<\xA7\xB6g\xBD\xF1\xA6\xAA\xE7\xD3_&N\xC9[K8\xE61L\xD1\xC0\xC8\x02\b\xE7\xF1!\xA5\x04\xCA" def test_aes256_ctr_for_encryption assert_equal AES256_CTR, encrypt("aes256-ctr") end + def test_aes256_ctr_for_encryption2 + assert_equal [AES256_CTR,AES256_CTR2], encrypt2("aes256-ctr") + end + def test_aes256_ctr_for_decryption assert_equal TEXT, decrypt("aes256-ctr", AES256_CTR) end @@ -289,10 +303,11 @@ module Transport def test_none_for_decryption assert_equal TEXT, decrypt("none", TEXT) end - + private TEXT = "But soft! What light through yonder window breaks? It is the east, and Juliet is the sun!" + TEXT2 = "2But soft! What light through yonder window breaks? It is the east, and Juliet is the sun!" OPTIONS = { iv: "ABC", key: "abc", @@ -312,12 +327,43 @@ module Transport result << cipher.final end + def encrypt2(type) + cipher = factory.get(type, OPTIONS.merge(encrypt: true)) + padding = TEXT.length % cipher.block_size + result = cipher.update(TEXT.dup) + result << cipher.update(" " * (cipher.block_size - padding)) if padding > 0 + result << cipher.final + + cipher.reset + + cipher.iv = "0123456789123456" + padding = TEXT2.length % cipher.block_size + result2 = cipher.update(TEXT2.dup) + result2 << cipher.update(" " * (cipher.block_size - padding)) if padding > 0 + result2 << cipher.final + [result, result2] + end + def decrypt(type, data) cipher = factory.get(type, OPTIONS.merge(decrypt: true)) result = cipher.update(data.dup) result << cipher.final result.strip end + + def decrypt2(type, datas) + cipher = factory.get(type, OPTIONS.merge(decrypt: true)) + result = cipher.update(datas[0].dup) + result << cipher.final + first = result.strip + + cipher.reset + + result = cipher.update(datas[1].dup) + result << cipher.final + second = result.strip + [first, second] + end end end |