diff options
author | Miklos Fazekas <mfazekas@szemafor.com> | 2016-05-02 18:23:32 +0200 |
---|---|---|
committer | Miklos Fazekas <mfazekas@szemafor.com> | 2016-05-02 20:03:05 +0200 |
commit | 3fca4204d5eb07479c91c89ee965694206e86046 (patch) | |
tree | 1d2dae1bdcc22f32202febd0fd569fc41b2b7aca | |
parent | 2118da3b5e2b5cb4428b41c0f90704706268540b (diff) | |
download | net-ssh-3fca4204d5eb07479c91c89ee965694206e86046.tar.gz |
Make rbnacl dependency optional
-rw-r--r-- | .rubocop.yml | 4 | ||||
-rw-r--r-- | .travis.yml | 3 | ||||
-rw-r--r-- | Gemfile.norbnacl | 5 | ||||
-rw-r--r-- | Gemfile.norbnacl.lock | 40 | ||||
-rw-r--r-- | lib/net/ssh/authentication/ed25519.rb | 23 | ||||
-rw-r--r-- | lib/net/ssh/key_factory.rb | 63 | ||||
-rw-r--r-- | net-ssh.gemspec | 8 | ||||
-rw-r--r-- | test/authentication/test_ed25519.rb | 6 | ||||
-rw-r--r-- | test/integration/test_ed25519_pkeys.rb | 3 | ||||
-rw-r--r-- | test/transport/test_algorithms.rb | 2 |
10 files changed, 103 insertions, 54 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index cc32da4..a8c00d2 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1 +1,5 @@ inherit_from: .rubocop_todo.yml + +AllCops: + Exclude: + - 'tryout/**/*' diff --git a/.travis.yml b/.travis.yml index 8415326..5b6ac9d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,7 +37,6 @@ install: script: - bundle _1.11.2_ exec rake test + - BUNDLE_GEMFILE=./Gemfile.norbnacl bundle _1.11.2_ exec rake test - bundle _1.11.2_ exec rake test_test - bundle _1.11.2_ exec rubocop - - diff --git a/Gemfile.norbnacl b/Gemfile.norbnacl new file mode 100644 index 0000000..3969fcd --- /dev/null +++ b/Gemfile.norbnacl @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +ENV['NET_SSH_NO_RBNACL'] = 'true' +# Specify your gem's dependencies in mygem.gemspec +gemspec
\ No newline at end of file diff --git a/Gemfile.norbnacl.lock b/Gemfile.norbnacl.lock new file mode 100644 index 0000000..55e2570 --- /dev/null +++ b/Gemfile.norbnacl.lock @@ -0,0 +1,40 @@ +PATH + remote: . + specs: + net-ssh (4.0.0.alpha3) + +GEM + remote: https://rubygems.org/ + specs: + ast (2.2.0) + metaclass (0.0.4) + minitest (5.8.4) + mocha (1.1.0) + metaclass (~> 0.0.1) + parser (2.3.1.0) + ast (~> 2.2) + powerpack (0.1.1) + rainbow (2.1.0) + rake (11.1.2) + rubocop (0.39.0) + parser (>= 2.3.0.7, < 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.0) + unicode-display_width (1.0.5) + +PLATFORMS + ruby + +DEPENDENCIES + bundler (~> 1.11.2) + minitest (~> 5.0) + mocha (>= 1.1.0) + net-ssh! + rake (~> 11.1) + rubocop (~> 0.39.0) + +BUNDLED WITH + 1.11.2 diff --git a/lib/net/ssh/authentication/ed25519.rb b/lib/net/ssh/authentication/ed25519.rb index 50dd229..10fae6e 100644 --- a/lib/net/ssh/authentication/ed25519.rb +++ b/lib/net/ssh/authentication/ed25519.rb @@ -1,5 +1,6 @@ -gem 'rbnacl-libsodium' -gem 'rbnacl' +gem 'rbnacl-libsodium', '~> 1.0.10' +gem 'rbnacl', '~> 3.3.0' +gem 'bcrypt_pbkdf', '~> 1.0.0.alpha1' unless RUBY_PLATFORM == "java" require 'rbnacl/libsodium' require 'rbnacl' @@ -13,20 +14,14 @@ require 'base64' require 'net/ssh/transport/cipher_factory' require 'bcrypt_pbkdf' unless RUBY_PLATFORM == "java" -module RbNaCl - module Signatures - module Ed25519 - class SigningKeyFromFile < SigningKey - def initialize(pk,sk) - @signing_key = sk - @verify_key = VerifyKey.new(pk) - end - end +module ED25519 + class SigningKeyFromFile < RbNaCl::Signatures::Ed25519::SigningKey + def initialize(pk,sk) + @signing_key = sk + @verify_key = RbNaCl::Signatures::Ed25519::VerifyKey.new(pk) end end -end -module ED25519 class PubKey def initialize(data) @verify_key = RbNaCl::Signatures::Ed25519::VerifyKey.new(data) @@ -118,7 +113,7 @@ module ED25519 _comment = decoded.read_string @pk = pk - @sign_key = RbNaCl::Signatures::Ed25519::SigningKeyFromFile.new(pk,sk) + @sign_key = SigningKeyFromFile.new(pk,sk) end def public_key diff --git a/lib/net/ssh/key_factory.rb b/lib/net/ssh/key_factory.rb index 021cc96..84c2b09 100644 --- a/lib/net/ssh/key_factory.rb +++ b/lib/net/ssh/key_factory.rb @@ -1,6 +1,10 @@ require 'net/ssh/transport/openssl' require 'net/ssh/prompt' -require 'net/ssh/authentication/ed25519' + +begin + require 'net/ssh/authentication/ed25519' +rescue Gem::LoadError => e # rubocop:disable Lint/HandleExceptions +end module Net; module SSH @@ -22,7 +26,7 @@ module Net; module SSH } if defined?(OpenSSL::PKey::EC) MAP["ecdsa"] = OpenSSL::PKey::EC - MAP["ed25519"] = ED25519::PrivKey + MAP["ed25519"] = ED25519::PrivKey if defined? ED25519 end class <<self @@ -48,44 +52,15 @@ module Net; module SSH # encrypted (requiring a passphrase to use), the user will be # prompted to enter their password unless passphrase works. def load_data_private_key(data, passphrase=nil, ask_passphrase=true, filename="", prompt=Prompt.default) - if OpenSSL::PKey.respond_to?(:read) - pkey_read = true - error_class = ArgumentError - else - pkey_read = false - if data.match(/-----BEGIN DSA PRIVATE KEY-----/) - key_type = OpenSSL::PKey::DSA - error_class = OpenSSL::PKey::DSAError - elsif data.match(/-----BEGIN RSA PRIVATE KEY-----/) - key_type = OpenSSL::PKey::RSA - error_class = OpenSSL::PKey::RSAError - elsif data.match(/-----BEGIN EC PRIVATE KEY-----/) && defined?(OpenSSL::PKey::EC) - key_type = OpenSSL::PKey::EC - error_class = OpenSSL::PKey::ECError - elsif data.match(/-----BEGIN OPENSSH PRIVATE KEY-----/) - openssh_key = true - key_type = ED25519::PrivKey - elsif data.match(/-----BEGIN (.+) PRIVATE KEY-----/) - raise OpenSSL::PKey::PKeyError, "not a supported key type '#{$1}'" - else - raise OpenSSL::PKey::PKeyError, "not a private key (#{filename})" - end - end + key_read, error_class = classify_key(data, filename) encrypted_key = data.match(/ENCRYPTED/) - openssh_key = data.match(/-----BEGIN OPENSSH PRIVATE KEY-----/) tries = 0 prompter = nil result = begin - if openssh_key - ED25519::PrivKey.read(data, passphrase || 'invalid') - elsif pkey_read - OpenSSL::PKey.read(data, passphrase || 'invalid') - else - key_type.new(data, passphrase || 'invalid') - end + key_read[data, passphrase || 'invalid'] rescue error_class if encrypted_key && ask_passphrase tries += 1 @@ -130,6 +105,28 @@ module Net; module SSH reader = Net::SSH::Buffer.new(blob) reader.read_key or raise OpenSSL::PKey::PKeyError, "not a public key #{filename.inspect}" end + + private + + # Determine whether the file describes an RSA or DSA key, and return how load it + # appropriately. + def classify_key(data, filename) + if data.match(/-----BEGIN OPENSSH PRIVATE KEY-----/) + return ->(key_data, passphrase) { ED25519::PrivKey.read(key_data, passphrase) }, ArgumentError + elsif OpenSSL::PKey.respond_to?(:read) + return ->(key_data, passphrase) { OpenSSL::PKey.read(key_data, passphrase) }, ArgumentError + elsif data.match(/-----BEGIN DSA PRIVATE KEY-----/) + return ->(key_data, passphrase) { OpenSSL::PKey::DSA.new(key_data, passphrase) }, OpenSSL::PKey::DSAError + elsif data.match(/-----BEGIN RSA PRIVATE KEY-----/) + return ->(key_data, passphrase) { OpenSSL::PKey::RSA.new(key_data, passphrase) }, OpenSSL::PKey::RSAError + elsif data.match(/-----BEGIN EC PRIVATE KEY-----/) && defined?(OpenSSL::PKey::EC) + return ->(key_data, passphrase) { OpenSSL::PKey::EC.new(key_data, passphrase) }, OpenSSL::PKey::ECError + elsif data.match(/-----BEGIN (.+) PRIVATE KEY-----/) + raise OpenSSL::PKey::PKeyError, "not a supported key type '#{$1}'" + else + raise OpenSSL::PKey::PKeyError, "not a private key (#{filename})" + end + end end end diff --git a/net-ssh.gemspec b/net-ssh.gemspec index 36e37f0..a6e54b8 100644 --- a/net-ssh.gemspec +++ b/net-ssh.gemspec @@ -28,9 +28,11 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ["lib"] - spec.add_runtime_dependency("rbnacl-libsodium", ">= 1.0.2") - spec.add_runtime_dependency("rbnacl", ">= 3.1.2") - spec.add_runtime_dependency("bcrypt_pbkdf", "= 1.0.0.alpha1") unless RUBY_PLATFORM == "java" + unless ENV['NET_SSH_NO_RBNACL'] + spec.add_development_dependency("rbnacl-libsodium", ">= 1.0.2") + spec.add_development_dependency("rbnacl", ">= 3.1.2") + spec.add_development_dependency("bcrypt_pbkdf", "= 1.0.0.alpha1") unless RUBY_PLATFORM == "java" + end spec.add_development_dependency "bundler", "~> 1.11.2" spec.add_development_dependency "rake", "~> 11.1" diff --git a/test/authentication/test_ed25519.rb b/test/authentication/test_ed25519.rb index 974021a..28d5ebd 100644 --- a/test/authentication/test_ed25519.rb +++ b/test/authentication/test_ed25519.rb @@ -1,3 +1,5 @@ +unless ENV['NET_SSH_NO_RBNACL'] + require 'common' require 'net/ssh/authentication/ed25519' require 'base64' @@ -74,4 +76,6 @@ IDBAU= end end -end
\ No newline at end of file +end + +end diff --git a/test/integration/test_ed25519_pkeys.rb b/test/integration/test_ed25519_pkeys.rb index b780756..99c2068 100644 --- a/test/integration/test_ed25519_pkeys.rb +++ b/test/integration/test_ed25519_pkeys.rb @@ -4,6 +4,7 @@ require 'tmpdir' require 'net/ssh' +unless ENV['NET_SSH_NO_RBNACL'] # 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 @@ -67,4 +68,6 @@ class TestED25519PKeys < NetSSHTest assert_equal "hello from:net_ssh_1\n", ret end end +end + end
\ No newline at end of file diff --git a/test/transport/test_algorithms.rb b/test/transport/test_algorithms.rb index 06de8e6..a0ddd7e 100644 --- a/test/transport/test_algorithms.rb +++ b/test/transport/test_algorithms.rb @@ -1,4 +1,4 @@ -require 'common' +require_relative '../common' require 'net/ssh/transport/algorithms' module Transport |