summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt20
-rw-r--r--README.md6
-rw-r--r--Rakefile31
-rw-r--r--SECURITY.md4
-rw-r--r--lib/net/ssh/authentication/ed25519.rb1
-rw-r--r--lib/net/ssh/buffer.rb42
-rw-r--r--lib/net/ssh/connection/session.rb2
-rw-r--r--lib/net/ssh/version.rb6
-rw-r--r--net-ssh-public_cert.pem16
-rw-r--r--test/authentication/test_ed25519.rb26
-rw-r--r--test/integration/test_handshake_timeout.rb32
11 files changed, 152 insertions, 34 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 86c5bd1..24540ec 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,23 @@
+
+=== 7.1.0 beta1
+
+ * Don't use the deprecated set_XXX methods on RSA keys. [#875]
+ * Raise error when BCryptPbkdf fails [#876]
+
+=== 7.0.1
+
+ * Drop leftover debug statement [#866]
+
+=== 7.0.0
+
+ * BREAKING: Drop support for Ruby 2.5
+ * Fix decoding of ecdsa-sha2-nistp256 private keys [#657, #854]
+ * Fix missing require [#855]
+ * Support `~` in the path to the SSH agent's unix socket [#850]
+ * Add support for RSA client authentication with SHA-2 [a45f54]
+ * openssl: DSA: don't hardcode expected signature size, see ruby/openssl#483 [23a15c]
+ * Internal housekeeping (rubocop, codecov, remove travis, adding/improving tests)
+
=== 6.3.0 beta1
* Support cert based host key auth, fix asterisk in known_hosts [#833]
diff --git a/README.md b/README.md
index 7b2a451..19e53be 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
[![Backers on Open Collective](https://opencollective.com/net-ssh/backers/badge.svg)](#backers])
[![Sponsors on Open Collective](https://opencollective.com/net-ssh/sponsors/badge.svg)](#sponsors)
-# Net::SSH 6.x
+# Net::SSH 7.x
* Docs: http://net-ssh.github.io/net-ssh
* Issues: https://github.com/net-ssh/net-ssh/issues
@@ -247,6 +247,10 @@ mv gem-public_cert.pem net-ssh-public_cert.pem
gem cert --add net-ssh-public_cert.pem
```
+## Security contact information
+
+See [SECURITY.md](SECURITY.md)
+
## CREDITS
### Contributors
diff --git a/Rakefile b/Rakefile
index 18eeca9..103a295 100644
--- a/Rakefile
+++ b/Rakefile
@@ -55,6 +55,37 @@ namespace :cert do
end
end
+namespace :vbump do
+ desc "Increment prerelease"
+ task :pre do
+ version_file = 'lib/net/ssh/version.rb'
+ require_relative version_file
+ pre = Net::SSH::Version::PRE
+ if pre =~ /^([a-z]+)(\d+)/
+ new_pre = "#{$1}#{$2.to_i+1}"
+ found = false
+
+ File.open("#{version_file}.new", "w") do |f|
+ File.readlines(version_file).each do |line|
+ if line =~ /^(\s+PRE\s+=\s+")#{pre}("\s*)$/
+ new_line = "#{$1}#{new_pre}#{$2}"
+ puts "Changing:\n - #{line} + #{new_line}"
+ line = new_line
+ found = true
+ end
+ f.write(line)
+ end
+ raise ArugmentError, 'Cound not find line: PRE = \"#{pre}\" in #{version_file}"' unless found
+ end
+
+ FileUtils.mv version_file, "#{version_file}.old"
+ FileUtils.mv "#{version_file}.new", version_file
+ else
+ raise ArgumentError, "Unepexeted pre string: #{pre}"
+ end
+ end
+end
+
namespace :rdoc do
desc "Update gh-pages branch"
task :publish do
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 0000000..45d0b8e
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,4 @@
+## Security contact information
+
+To report a security vulnerability, please use the
+[GitHub private vulnerability reporting feature](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing/privately-reporting-a-security-vulnerability).
diff --git a/lib/net/ssh/authentication/ed25519.rb b/lib/net/ssh/authentication/ed25519.rb
index dccc64f..892000a 100644
--- a/lib/net/ssh/authentication/ed25519.rb
+++ b/lib/net/ssh/authentication/ed25519.rb
@@ -77,6 +77,7 @@ module Net
raise "BCryptPbkdf is not implemented for jruby" if RUBY_PLATFORM == "java"
key = BCryptPbkdf::key(password, salt, keylen + ivlen, rounds)
+ raise DecryptError.new("BCyryptPbkdf failed", encrypted_key: true) unless key
else
key = '\x00' * (keylen + ivlen)
end
diff --git a/lib/net/ssh/buffer.rb b/lib/net/ssh/buffer.rb
index e5d12eb..0544b96 100644
--- a/lib/net/ssh/buffer.rb
+++ b/lib/net/ssh/buffer.rb
@@ -251,7 +251,6 @@ module Net
def read_private_keyblob(type)
case type
when /^ssh-rsa$/
- key = OpenSSL::PKey::RSA.new
n = read_bignum
e = read_bignum
d = read_bignum
@@ -262,27 +261,28 @@ module Net
_unkown2 = read_bignum
dmp1 = d % (p - 1)
dmq1 = d % (q - 1)
- if key.respond_to?(:set_key)
- key.set_key(n, e, d)
- else
- key.e = e
- key.n = n
- key.d = d
- end
- if key.respond_to?(:set_factors)
- key.set_factors(p, q)
- else
- key.p = p
- key.q = q
+ # Public key
+ data_sequence = OpenSSL::ASN1::Sequence([
+ OpenSSL::ASN1::Integer(n),
+ OpenSSL::ASN1::Integer(e)
+ ])
+
+ if d && p && q && dmp1 && dmq1 && iqmp
+ data_sequence = OpenSSL::ASN1::Sequence([
+ OpenSSL::ASN1::Integer(0),
+ OpenSSL::ASN1::Integer(n),
+ OpenSSL::ASN1::Integer(e),
+ OpenSSL::ASN1::Integer(d),
+ OpenSSL::ASN1::Integer(p),
+ OpenSSL::ASN1::Integer(q),
+ OpenSSL::ASN1::Integer(dmp1),
+ OpenSSL::ASN1::Integer(dmq1),
+ OpenSSL::ASN1::Integer(iqmp)
+ ])
end
- if key.respond_to?(:set_crt_params)
- key.set_crt_params(dmp1, dmq1, iqmp)
- else
- key.dmp1 = dmp1
- key.dmq1 = dmq1
- key.iqmp = iqmp
- end
- key
+
+ asn1 = OpenSSL::ASN1::Sequence(data_sequence)
+ OpenSSL::PKey::RSA.new(asn1.to_der)
when /^ecdsa\-sha2\-(\w*)$/
OpenSSL::PKey::EC.read_keyblob($1, self)
else
diff --git a/lib/net/ssh/connection/session.rb b/lib/net/ssh/connection/session.rb
index fbfc017..218173d 100644
--- a/lib/net/ssh/connection/session.rb
+++ b/lib/net/ssh/connection/session.rb
@@ -416,7 +416,7 @@ module Net
#
# matches = ssh.exec!("grep something /some/files")
#
- # the returned string has an exitstatus method to query it's exit satus
+ # the returned string has an exitstatus method to query its exit status
def exec!(command, status: nil, &block)
block_or_concat = block || Proc.new do |ch, type, data|
ch[:result] ||= String.new
diff --git a/lib/net/ssh/version.rb b/lib/net/ssh/version.rb
index bd909ed..3755ca7 100644
--- a/lib/net/ssh/version.rb
+++ b/lib/net/ssh/version.rb
@@ -49,14 +49,14 @@ module Net
MAJOR = 7
# The minor component of this version of the Net::SSH library
- MINOR = 0
+ MINOR = 1
# The tiny component of this version of the Net::SSH library
- TINY = 1
+ TINY = 0
# The prerelease component of this version of the Net::SSH library
# nil allowed
- PRE = nil
+ PRE = "beta2"
# The current version of the Net::SSH library as a Version instance
CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
diff --git a/net-ssh-public_cert.pem b/net-ssh-public_cert.pem
index f51a7a0..9ecfdd6 100644
--- a/net-ssh-public_cert.pem
+++ b/net-ssh-public_cert.pem
@@ -1,7 +1,7 @@
-----BEGIN CERTIFICATE-----
MIIDQDCCAiigAwIBAgIBATANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpuZXRz
-c2gvREM9c29sdXRpb3VzL0RDPWNvbTAeFw0yMTA4MTAwODMyMzBaFw0yMjA4MTAw
-ODMyMzBaMCUxIzAhBgNVBAMMGm5ldHNzaC9EQz1zb2x1dGlvdXMvREM9Y29tMIIB
+c2gvREM9c29sdXRpb3VzL0RDPWNvbTAeFw0yMzAxMjQwMzE3NTVaFw0yNDAxMjQw
+MzE3NTVaMCUxIzAhBgNVBAMMGm5ldHNzaC9EQz1zb2x1dGlvdXMvREM9Y29tMIIB
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxieE22fR/qmdPKUHyYTyUx2g
wskLwrCkxay+Tvc97ZZUOwf85LDDDPqhQaTWLvRwnIOMgQE2nBPzwalVclK6a+pW
x/18KDeZY15vm3Qn5p42b0wi9hUxOqPm3J2hdCLCcgtENgdX21nVzejn39WVqFJO
@@ -11,10 +11,10 @@ fBbmDnsMLAtAtauMOxORrbx3EOY7sHku/kSrMg3FXFay7jc6BkbbUij+MjJ/k82l
AQABo3sweTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUBfKiwO2e
M4NEiRrVG793qEPLYyMwHwYDVR0RBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20w
HwYDVR0SBBgwFoEUbmV0c3NoQHNvbHV0aW91cy5jb20wDQYJKoZIhvcNAQELBQAD
-ggEBABRChgo0Jo+iXSnTpODNongzZoU0sWqwx3/FQVo8nyAyr1qFuiqpSPb4bDbU
-DsVnUn3t0X/gGA8qJhutlmfTpEQCjUeyj2x9rWpD3lvttlGWV6btQ0qN4Dfc2gsw
-rCp9Jpful0HGWhiwfjWfsarqAdtLzIG0UC47IN7LGeCMRJIijOsXQhiZ915eNBEw
-g9+WSSGHkMFt/7vi2pFkvXSC0+RF8ovvRWf4Zw2aYXtJ1GElgi4ZS/s6ZU0gmv20
-i4SfC5m5UXIVZvOBYiMuZ/1B2m6R9xU41027zfOVwRFNtlVDiNfQRq6sDmz44At/
-dv8pkxXDgySe41vzlRXFsgIgz5A=
+ggEBAHyOSaOUji+EJFWZ46g+2EZ/kG7EFloFtIQUz8jDJIWGE+3NV5po1M0Z6EqH
+XmG3BtMLfgOV9NwMQRqIdKnZDfKsqM/FOu+9IqrP+OieAde5OrXR2pzQls60Xft7
+3qNVaQS99woQRqiUiDQQ7WagOYrZjuVANqTDNt4myzGSjS5sHcKlz3PRn0LJRMe5
+ouuLwQ7BCXityv5RRXex2ibCOyY7pB5ris6xDnPe1WdlyCfUf1Fb+Yqxpy6a8QmH
+v84waVXQ2i5M7pJaHVBF7DxxeW/q8W3VCnsq8vmmvULSThD18QqYGaFDJeN8sTR4
+6tfjgZ6OvGSScvbCMHkCE9XjonE=
-----END CERTIFICATE-----
diff --git a/test/authentication/test_ed25519.rb b/test/authentication/test_ed25519.rb
index d0d0e9e..e4f347a 100644
--- a/test/authentication/test_ed25519.rb
+++ b/test/authentication/test_ed25519.rb
@@ -92,6 +92,18 @@ unless ENV['NET_SSH_NO_ED25519']
self.assert_equal(pub_key.fingerprint('sha256'), key_fingerprint_sha256_pwd)
end
+ def test_pwd_key_blank
+ self.assert_raises(Net::SSH::Authentication::ED25519::OpenSSHPrivateKeyLoader::DecryptError) do
+ Net::SSH::Authentication::ED25519::PrivKey.read(private_key_no_rounds, '')
+ end
+ end
+
+ def test_priv_key_no_rounds_should_raise
+ self.assert_raises(Net::SSH::Authentication::ED25519::OpenSSHPrivateKeyLoader::DecryptError) do
+ Net::SSH::Authentication::ED25519::PrivKey.read(private_key_no_rounds, 'pwd')
+ end
+ end
+
def private_key_pwd
@pwd_key = <<~EOF
-----BEGIN OPENSSH PRIVATE KEY-----
@@ -105,6 +117,20 @@ unless ENV['NET_SSH_NO_ED25519']
EOF
end
+ def private_key_no_rounds
+ @private_key_no_rounds = <<~EOF
+ -----BEGIN OPENSSH PRIVATE KEY-----
+ b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jYmMAAAAGYmNyeXB0AAAAGAAA
+ ABBxwCvr3V/8pWhC/xvTnGJhAAAAAAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5
+ AAAAICaHkFaGXqYhUVFcaZ10TPUbkIvmaFXwYRoOS5qE8MciAAAAsNUAhbNQ
+ KwNcOr0eNq3nhtjoyeVyH8hRrpWsiY46vPiECi6R6OdYGSd7W3fdzUDeyOYC
+ Y9ZVIjAzENG+9FsygYzMi6XCuw00OuDFLUp4fL4Ki/coUIVqouB4TPQAmsCV
+ XiIRVTWQtRG0kWfFaV3qRt/bc22ZCvCT6ZZ1UmtulqqfUhSlKMoPcTikV1iW
+ H5Xc+GxRFRRGTN/6HvBf0AKDB1kMXlDhGnBnHGeNH1pk44xG
+ -----END OPENSSH PRIVATE KEY-----
+ EOF
+ end
+
def public_key_pwd
'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICaHkFaGXqYhUVFcaZ10TPUbkIvmaFXwYRoOS5qE8Mci vagrant@vagrant-ubuntu-trusty-64'
end
diff --git a/test/integration/test_handshake_timeout.rb b/test/integration/test_handshake_timeout.rb
new file mode 100644
index 0000000..c297377
--- /dev/null
+++ b/test/integration/test_handshake_timeout.rb
@@ -0,0 +1,32 @@
+require_relative 'common'
+require 'net/ssh'
+
+class TestHandshakeTimeout < NetSSHTest
+ include IntegrationTestHelpers
+
+ def with_non_responding_server(&block)
+ port = "4444"
+ pipe = IO.popen("/bin/nc -l -k -p #{port}")
+ begin
+ yield(port)
+ ensure
+ Process.kill("TERM", pipe.pid)
+ end
+ end
+
+ def nc_port_open?(port)
+ Socket.tcp("localhost", port, connect_timeout: 1) { true } rescue false # rubocop:disable Style/RescueModifier
+ end
+
+ def test_error_exitstatus
+ with_non_responding_server do |port|
+ sleep(0.1) until nc_port_open?(port.to_i)
+
+ assert_raises(Net::SSH::ConnectionTimeout, 'timeout during server version negotiating') do
+ Net::SSH.start("localhost", "net_ssh_1", password: 'foopwd', port: port, timeout: 1) do |ssh|
+ ssh.exec! "exit 42"
+ end
+ end
+ end
+ end
+end