net-ssh 4.2.0 → 5.0.0.beta1
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +20 -19
- data/CHANGES.txt +9 -1
- data/Gemfile +0 -4
- data/{Gemfile.norbnacl → Gemfile.noed25519} +1 -1
- data/{Gemfile.norbnacl.lock → Gemfile.noed25519.lock} +14 -14
- data/README.rdoc +1 -1
- data/Rakefile +14 -0
- data/appveyor.yml +5 -5
- data/lib/net/ssh.rb +1 -1
- data/lib/net/ssh/authentication/agent.rb +2 -2
- data/lib/net/ssh/authentication/ed25519.rb +8 -19
- data/lib/net/ssh/authentication/ed25519_loader.rb +2 -3
- data/lib/net/ssh/buffered_io.rb +1 -1
- data/lib/net/ssh/config.rb +36 -19
- data/lib/net/ssh/connection/event_loop.rb +2 -2
- data/lib/net/ssh/proxy/command.rb +20 -6
- data/lib/net/ssh/ruby_compat.rb +0 -12
- data/lib/net/ssh/transport/cipher_factory.rb +22 -5
- data/lib/net/ssh/transport/ctr.rb +31 -3
- data/lib/net/ssh/transport/openssl.rb +2 -2
- data/lib/net/ssh/transport/packet_stream.rb +2 -2
- data/lib/net/ssh/version.rb +3 -3
- data/net-ssh-public_cert.pem +8 -8
- data/net-ssh.gemspec +3 -4
- metadata +19 -39
- metadata.gz.sig +1 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: bb60ae0c4c1ea03a94da3dcb5b35842280c1b0ab5454cebb8d456ff7a3160fde
|
|
4
|
+
data.tar.gz: 2bd1168668f3e93b472560d3b8fae9482ce91a10f1a7dd4b7235f6b7db67e6b6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cdc3a433ce7ba44494eb5e52f9231359004afc9be010fdf60a62e9e846aa23230a556f38c549cc4d58f7b1ba98c72e53eb526b8a0f52313661cdf571d1c17a53
|
|
7
|
+
data.tar.gz: 0fc94c9dbc7f9e3ea106d53de363faf8cf2b3473857857c387512040b427dbf336ff4cf73d4eb696864ceac61a365571a756ef6b449552d7417b5db34fe19e95
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data.tar.gz.sig
CHANGED
|
Binary file
|
data/.travis.yml
CHANGED
|
@@ -7,45 +7,46 @@ addon:
|
|
|
7
7
|
gateway.netssh
|
|
8
8
|
|
|
9
9
|
rvm:
|
|
10
|
-
- 2.0
|
|
11
|
-
- 2.1
|
|
12
10
|
- 2.2
|
|
13
|
-
- 2.3.
|
|
14
|
-
- 2.4.
|
|
15
|
-
-
|
|
16
|
-
-
|
|
11
|
+
- 2.3.5
|
|
12
|
+
- 2.4.3
|
|
13
|
+
- 2.5.0
|
|
14
|
+
- jruby-9.1.13.0
|
|
15
|
+
- rbx-3.84
|
|
17
16
|
- ruby-head
|
|
18
17
|
env:
|
|
19
18
|
NET_SSH_RUN_INTEGRATION_TESTS=1
|
|
20
19
|
|
|
21
20
|
matrix:
|
|
22
21
|
exclude:
|
|
23
|
-
- rvm: rbx-3.
|
|
24
|
-
- rvm: jruby-9.1.
|
|
22
|
+
- rvm: rbx-3.84
|
|
23
|
+
- rvm: jruby-9.1.13.0
|
|
25
24
|
include:
|
|
26
|
-
- rvm: rbx-3.
|
|
25
|
+
- rvm: rbx-3.84
|
|
27
26
|
env: NET_SSH_RUN_INTEGRATION_TESTS=
|
|
28
|
-
- rvm: jruby-9.1.
|
|
27
|
+
- rvm: jruby-9.1.13.0
|
|
29
28
|
env: JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false' NET_SSH_RUN_INTEGRATION_TESTS=
|
|
30
29
|
fast_finish: true
|
|
31
30
|
allow_failures:
|
|
32
|
-
- rvm: rbx-3.
|
|
33
|
-
- rvm: jruby-9.1.
|
|
31
|
+
- rvm: rbx-3.84
|
|
32
|
+
- rvm: jruby-9.1.13.0
|
|
34
33
|
- rvm: ruby-head
|
|
35
34
|
|
|
36
35
|
install:
|
|
37
36
|
- export JRUBY_OPTS='--client -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1 -Xcext.enabled=false -J-Xss2m -Xcompile.invokedynamic=false'
|
|
38
37
|
- sudo pip install ansible
|
|
39
|
-
- gem install bundler -v "= 1.
|
|
40
|
-
-
|
|
41
|
-
-
|
|
38
|
+
- gem install bundler -v "= 1.16"
|
|
39
|
+
- gem list bundler
|
|
40
|
+
- bundle _1.16_ install
|
|
41
|
+
- bundle _1.16_ -v
|
|
42
|
+
- BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.16_ install
|
|
42
43
|
- sudo ansible-galaxy install rvm_io.ruby
|
|
43
44
|
- sudo chown -R travis:travis /home/travis/.ansible
|
|
44
45
|
- 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'
|
|
45
46
|
|
|
46
47
|
script:
|
|
47
48
|
- ssh -V
|
|
48
|
-
- bundle _1.
|
|
49
|
-
- BUNDLE_GEMFILE=./Gemfile.
|
|
50
|
-
- bundle _1.
|
|
51
|
-
- bundle _1.
|
|
49
|
+
- bundle _1.16_ exec rake test
|
|
50
|
+
- BUNDLE_GEMFILE=./Gemfile.noed25519 bundle _1.16_ exec rake test
|
|
51
|
+
- bundle _1.16_ exec rake test_test
|
|
52
|
+
- bundle _1.16_ exec rubocop
|
data/CHANGES.txt
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
=== 5.0.0.beta1
|
|
2
|
+
|
|
3
|
+
* Don't leave proxy command as zombie on timeout [DimitriosLisenko, #560]
|
|
4
|
+
* Use OpenSSL for aes*-ctr for up to 5x throughput improvement [Miklós Fazekas, Harald Sitter, #570]
|
|
5
|
+
* Optimize slice! usage in CTR for up to 2x throughput improvement [Harald Sitter, #569]
|
|
6
|
+
* Replace RbNaCl dependency with ed25519 gem [Tony Arcieri ,#563]
|
|
7
|
+
* Add initial Match support [Kasumi Hanazuki, #553]
|
|
8
|
+
|
|
1
9
|
=== 4.2.0.rc2
|
|
2
10
|
|
|
3
11
|
* Fix double close bug on auth failure (or ruby 2.2 or earlier) [#538]
|
|
@@ -183,7 +191,7 @@
|
|
|
183
191
|
=== 2.9.2-beta
|
|
184
192
|
|
|
185
193
|
* Remove advertised algorithms that were not working (ssh-rsa-cert-* *ed25519 acm*-gcm@openssh.com) [mfazekas]
|
|
186
|
-
*
|
|
194
|
+
* Unknown algorithms now ignored instead of failed [mfazekas]
|
|
187
195
|
* Configuration change: Asks for password with password auth (up to number_of_password_prompts) [mfazekas]
|
|
188
196
|
* Removed warnings [amatsuda]
|
|
189
197
|
|
data/Gemfile
CHANGED
|
@@ -7,10 +7,6 @@ if !Gem.win_platform? && RUBY_ENGINE == "ruby"
|
|
|
7
7
|
gem 'byebug', group: [:development, :test]
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
if (Gem::Version.new(RUBY_VERSION) <=> Gem::Version.new("2.2.6")) < 0
|
|
11
|
-
gem 'rbnacl', '< 4.0'
|
|
12
|
-
end
|
|
13
|
-
|
|
14
10
|
if ENV["CI"]
|
|
15
11
|
gem 'codecov', require: false, group: :test
|
|
16
12
|
gem 'simplecov', require: false, group: :test
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
net-ssh (4.
|
|
4
|
+
net-ssh (4.2.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
9
|
ast (2.3.0)
|
|
10
10
|
metaclass (0.0.4)
|
|
11
|
-
minitest (5.10.
|
|
12
|
-
mocha (1.
|
|
11
|
+
minitest (5.10.3)
|
|
12
|
+
mocha (1.3.0)
|
|
13
13
|
metaclass (~> 0.0.1)
|
|
14
|
-
parser (2.
|
|
15
|
-
ast (~> 2.
|
|
14
|
+
parser (2.4.0.2)
|
|
15
|
+
ast (~> 2.3)
|
|
16
16
|
powerpack (0.1.1)
|
|
17
|
-
rainbow (2.
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
rainbow (2.2.2)
|
|
18
|
+
rake
|
|
19
|
+
rake (12.3.0)
|
|
20
|
+
rubocop (0.47.1)
|
|
21
|
+
parser (>= 2.3.3.1, < 3.0)
|
|
21
22
|
powerpack (~> 0.1)
|
|
22
23
|
rainbow (>= 1.99.1, < 3.0)
|
|
23
24
|
ruby-progressbar (~> 1.7)
|
|
24
25
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
|
25
|
-
ruby-progressbar (1.
|
|
26
|
-
unicode-display_width (1.
|
|
26
|
+
ruby-progressbar (1.9.0)
|
|
27
|
+
unicode-display_width (1.3.0)
|
|
27
28
|
|
|
28
29
|
PLATFORMS
|
|
29
30
|
ruby
|
|
30
|
-
x86-mingw32
|
|
31
31
|
|
|
32
32
|
DEPENDENCIES
|
|
33
33
|
bundler (~> 1.11)
|
|
@@ -35,7 +35,7 @@ DEPENDENCIES
|
|
|
35
35
|
mocha (>= 1.2.1)
|
|
36
36
|
net-ssh!
|
|
37
37
|
rake (~> 12.0)
|
|
38
|
-
rubocop (~> 0.
|
|
38
|
+
rubocop (~> 0.47.0)
|
|
39
39
|
|
|
40
40
|
BUNDLED WITH
|
|
41
|
-
1.
|
|
41
|
+
1.14.6
|
data/README.rdoc
CHANGED
|
@@ -106,7 +106,7 @@ Then, when install the gem, do so with high security:
|
|
|
106
106
|
|
|
107
107
|
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.
|
|
108
108
|
|
|
109
|
-
For ed25519 public key auth support your bundle file should contain ```
|
|
109
|
+
For ed25519 public key auth support your bundle file should contain ```ed25519```, ```bcrypt_pbkdf``` dependencies.
|
|
110
110
|
|
|
111
111
|
== RUBY SUPPORT
|
|
112
112
|
|
data/Rakefile
CHANGED
|
@@ -43,6 +43,20 @@ RDoc::Task.new do |rdoc|
|
|
|
43
43
|
}
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
namespace :cert do
|
|
47
|
+
desc "Update public cert from private - only run if public is expired"
|
|
48
|
+
task :update_public_when_expired do
|
|
49
|
+
require 'openssl'
|
|
50
|
+
require 'time'
|
|
51
|
+
raw = File.read "net-ssh-public_cert.pem"
|
|
52
|
+
certificate = OpenSSL::X509::Certificate.new raw
|
|
53
|
+
raise Exception, "Not yet expired: #{certificate.not_after}" unless certificate.not_after < Time.now
|
|
54
|
+
sh "gem cert --build netssh@solutious.com --days 365*5 --private-key /mnt/gem/net-ssh-private_key.pem"
|
|
55
|
+
sh "mv gem-public_cert.pem net-ssh-public_cert.pem"
|
|
56
|
+
sh "gem cert --add net-ssh-public_cert.pem"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
46
60
|
namespace :rdoc do
|
|
47
61
|
desc "Update gh-pages branch"
|
|
48
62
|
task :publish do
|
data/appveyor.yml
CHANGED
|
@@ -29,9 +29,9 @@ install:
|
|
|
29
29
|
- if "%ruby_version%" == "jruby-9.1.2.0" ( cinst jruby --version 9.1.2.0 -i --allow-empty-checksums )
|
|
30
30
|
- if "%ruby_version%" == "jruby-9.1.2.0" ( SET "PATH=C:\jruby-9.1.2.0\bin\;%PATH%" )
|
|
31
31
|
- ruby --version
|
|
32
|
-
- gem install bundler --no-document -v 1.
|
|
33
|
-
- SET BUNDLE_GEMFILE=Gemfile.
|
|
34
|
-
- bundle
|
|
32
|
+
- gem install bundler --no-document --user-install -v 1.16
|
|
33
|
+
- SET BUNDLE_GEMFILE=Gemfile.noed25519
|
|
34
|
+
- bundle install --retry=3
|
|
35
35
|
- cinst freesshd
|
|
36
36
|
- cinst putty --allow-empty-checksums
|
|
37
37
|
- ps: |
|
|
@@ -49,8 +49,8 @@ install:
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
test_script:
|
|
52
|
-
- SET BUNDLE_GEMFILE=Gemfile.
|
|
52
|
+
- SET BUNDLE_GEMFILE=Gemfile.noed25519
|
|
53
53
|
- SET NET_SSH_RUN_WIN_INTEGRATION_TESTS=YES
|
|
54
|
-
- bundle
|
|
54
|
+
- bundle exec rake test
|
|
55
55
|
|
|
56
56
|
build: off
|
data/lib/net/ssh.rb
CHANGED
|
@@ -192,7 +192,7 @@ module Net
|
|
|
192
192
|
# * :password_prompt => a custom prompt object with ask method. See Net::SSH::Prompt
|
|
193
193
|
#
|
|
194
194
|
# * :agent_socket_factory => enables the user to pass a lambda/block that will serve as the socket factory
|
|
195
|
-
# Net::SSH
|
|
195
|
+
# Net::SSH.start(host,user,agent_socket_factory: ->{ UNIXSocket.open('/foo/bar') })
|
|
196
196
|
# example: ->{ UNIXSocket.open('/foo/bar')}
|
|
197
197
|
# * :verify_host_key => either false, true, :very, or :secure specifying how
|
|
198
198
|
# strict host-key verification should be (in increasing order here).
|
|
@@ -238,12 +238,12 @@ module Net; module SSH; module Authentication
|
|
|
238
238
|
Net::SSH::Buffer.from(:string, priv_key.to_blob, :bignum, priv_key.key.private_key).to_s
|
|
239
239
|
when /^ssh-ed25519$/
|
|
240
240
|
Net::SSH::Buffer.from(:string, priv_key.public_key.verify_key.to_bytes,
|
|
241
|
-
:string, priv_key.sign_key.
|
|
241
|
+
:string, priv_key.sign_key.keypair).to_s
|
|
242
242
|
when /^ssh-ed25519-cert-v01@openssh\.com$/
|
|
243
243
|
# Unlike the other certificate types, the public key is included after the certifiate.
|
|
244
244
|
Net::SSH::Buffer.from(:string, priv_key.to_blob,
|
|
245
245
|
:string, priv_key.key.public_key.verify_key.to_bytes,
|
|
246
|
-
:string, priv_key.key.sign_key.
|
|
246
|
+
:string, priv_key.key.sign_key.keypair).to_s
|
|
247
247
|
when /^ssh-rsa$/
|
|
248
248
|
# `n` and `e` are reversed compared to the ordering in `OpenSSL::PKey::RSA#to_blob`.
|
|
249
249
|
Net::SSH::Buffer.from(:bignum, priv_key.n, :bignum, priv_key.e, :bignum, priv_key.d,
|
|
@@ -1,16 +1,7 @@
|
|
|
1
|
-
gem '
|
|
1
|
+
gem 'ed25519', '~> 1.2'
|
|
2
2
|
gem 'bcrypt_pbkdf', '~> 1.0' unless RUBY_PLATFORM == "java"
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
require 'rbnacl/libsodium'
|
|
6
|
-
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
require 'rbnacl'
|
|
10
|
-
require 'rbnacl/signatures/ed25519/verify_key'
|
|
11
|
-
require 'rbnacl/signatures/ed25519/signing_key'
|
|
12
|
-
|
|
13
|
-
require 'rbnacl/hash'
|
|
4
|
+
require 'ed25519'
|
|
14
5
|
|
|
15
6
|
require 'base64'
|
|
16
7
|
|
|
@@ -19,10 +10,12 @@ require 'bcrypt_pbkdf' unless RUBY_PLATFORM == "java"
|
|
|
19
10
|
|
|
20
11
|
module Net; module SSH; module Authentication
|
|
21
12
|
module ED25519
|
|
22
|
-
class SigningKeyFromFile <
|
|
13
|
+
class SigningKeyFromFile < SimpleDelegator
|
|
23
14
|
def initialize(pk,sk)
|
|
24
|
-
|
|
25
|
-
|
|
15
|
+
key = ::Ed25519::SigningKey.from_keypair(sk)
|
|
16
|
+
raise ArgumentError, "pk does not match sk" unless pk == key.verify_key.to_bytes
|
|
17
|
+
|
|
18
|
+
super(key)
|
|
26
19
|
end
|
|
27
20
|
end
|
|
28
21
|
|
|
@@ -30,7 +23,7 @@ module ED25519
|
|
|
30
23
|
attr_reader :verify_key
|
|
31
24
|
|
|
32
25
|
def initialize(data)
|
|
33
|
-
@verify_key =
|
|
26
|
+
@verify_key = ::Ed25519::VerifyKey.new(data)
|
|
34
27
|
end
|
|
35
28
|
|
|
36
29
|
def self.read_keyblob(buffer)
|
|
@@ -151,10 +144,6 @@ module ED25519
|
|
|
151
144
|
def self.read(data,password)
|
|
152
145
|
self.new(data,password)
|
|
153
146
|
end
|
|
154
|
-
|
|
155
|
-
def self.read_keyblob(buffer)
|
|
156
|
-
ED25519::PubKey.read_keyblob(buffer)
|
|
157
|
-
end
|
|
158
147
|
end
|
|
159
148
|
end
|
|
160
149
|
end; end; end
|
|
@@ -21,10 +21,9 @@ end
|
|
|
21
21
|
|
|
22
22
|
def self.dependenciesRequiredForED25519
|
|
23
23
|
result = "net-ssh requires the following gems for ed25519 support:\n"
|
|
24
|
-
result << " *
|
|
25
|
-
result << " * rbnacl-libsodium, if your system doesn't have libsodium installed.\n"
|
|
24
|
+
result << " * ed25519 (>= 1.2, < 2.0)\n"
|
|
26
25
|
result << " * bcrypt_pbkdf (>= 1.0, < 2.0)\n" unless RUBY_PLATFORM == "java"
|
|
27
|
-
result << "See https://github.com/net-ssh/net-ssh/issues/
|
|
26
|
+
result << "See https://github.com/net-ssh/net-ssh/issues/565 for more information\n"
|
|
28
27
|
end
|
|
29
28
|
|
|
30
29
|
end
|
data/lib/net/ssh/buffered_io.rb
CHANGED
|
@@ -113,7 +113,7 @@ module Net; module SSH
|
|
|
113
113
|
def wait_for_pending_sends
|
|
114
114
|
send_pending
|
|
115
115
|
while output.length > 0
|
|
116
|
-
result =
|
|
116
|
+
result = IO.select(nil, [self]) or next
|
|
117
117
|
next unless result[1].any?
|
|
118
118
|
send_pending
|
|
119
119
|
end
|
data/lib/net/ssh/config.rb
CHANGED
|
@@ -49,11 +49,11 @@ module Net; module SSH
|
|
|
49
49
|
# Returns an array of locations of OpenSSH configuration files
|
|
50
50
|
# to parse by default.
|
|
51
51
|
def default_files
|
|
52
|
-
@@default_files
|
|
52
|
+
@@default_files.clone
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def default_auth_methods
|
|
56
|
-
@@default_auth_methods
|
|
56
|
+
@@default_auth_methods.clone
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
# Loads the configuration data for the given +host+ from all of the
|
|
@@ -78,8 +78,8 @@ module Net; module SSH
|
|
|
78
78
|
return settings unless File.readable?(file)
|
|
79
79
|
|
|
80
80
|
globals = {}
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
block_matched = false
|
|
82
|
+
block_seen = false
|
|
83
83
|
IO.foreach(file) do |line|
|
|
84
84
|
next if line =~ /^\s*(?:#.*)?$/
|
|
85
85
|
|
|
@@ -112,14 +112,17 @@ module Net; module SSH
|
|
|
112
112
|
negative_matched = negative_hosts.any? { |h| host =~ pattern2regex(h[1..-1]) }
|
|
113
113
|
|
|
114
114
|
if negative_matched
|
|
115
|
-
|
|
115
|
+
block_matched = false
|
|
116
116
|
else
|
|
117
|
-
|
|
117
|
+
block_matched = positive_hosts.any? { |h| host =~ pattern2regex(h) }
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
block_seen = true
|
|
121
121
|
settings[key] = host
|
|
122
|
-
elsif
|
|
122
|
+
elsif key == 'match'
|
|
123
|
+
block_matched = eval_match_condition(value, host, settings)
|
|
124
|
+
block_seen = true
|
|
125
|
+
elsif !block_seen
|
|
123
126
|
case key
|
|
124
127
|
when 'identityfile'
|
|
125
128
|
(globals[key] ||= []) << value
|
|
@@ -130,7 +133,7 @@ module Net; module SSH
|
|
|
130
133
|
else
|
|
131
134
|
globals[key] = value unless settings.key?(key)
|
|
132
135
|
end
|
|
133
|
-
elsif
|
|
136
|
+
elsif block_matched
|
|
134
137
|
case key
|
|
135
138
|
when 'identityfile'
|
|
136
139
|
(settings[key] ||= []) << value
|
|
@@ -144,18 +147,14 @@ module Net; module SSH
|
|
|
144
147
|
end
|
|
145
148
|
end
|
|
146
149
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
newval
|
|
154
|
-
end
|
|
150
|
+
globals.merge(settings) do |key, oldval, newval|
|
|
151
|
+
case key
|
|
152
|
+
when 'identityfile'
|
|
153
|
+
oldval + newval
|
|
154
|
+
else
|
|
155
|
+
newval
|
|
155
156
|
end
|
|
156
157
|
end
|
|
157
|
-
|
|
158
|
-
return settings
|
|
159
158
|
end
|
|
160
159
|
|
|
161
160
|
# Given a hash of OpenSSH configuration options, converts them into
|
|
@@ -323,6 +322,24 @@ module Net; module SSH
|
|
|
323
322
|
def tokenize_config_value(str)
|
|
324
323
|
str.scan(/([^"\s]+)?(?:"([^"]+)")?\s*/).map(&:join)
|
|
325
324
|
end
|
|
325
|
+
|
|
326
|
+
def eval_match_condition(condition, host, settings)
|
|
327
|
+
if condition.start_with?('!')
|
|
328
|
+
negated = true
|
|
329
|
+
condition = condition[1..-1]
|
|
330
|
+
else
|
|
331
|
+
negated = false
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
condition_met =
|
|
335
|
+
case condition
|
|
336
|
+
when 'all'
|
|
337
|
+
true
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# return false for unsupported conditions
|
|
341
|
+
condition_met.nil? ? false : (negated ^ condition_met)
|
|
342
|
+
end
|
|
326
343
|
end
|
|
327
344
|
end
|
|
328
345
|
|
|
@@ -64,7 +64,7 @@ module Net; module SSH; module Connection
|
|
|
64
64
|
sw.each { |wi| owners[wi] = session }
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
readers, writers, =
|
|
67
|
+
readers, writers, = IO.select(r, w, nil, minwait)
|
|
68
68
|
|
|
69
69
|
fired_sessions = {}
|
|
70
70
|
|
|
@@ -105,7 +105,7 @@ module Net; module SSH; module Connection
|
|
|
105
105
|
raise "Only one session expected" unless @sessions.count == 1
|
|
106
106
|
session = @sessions.first
|
|
107
107
|
sr,sw,actwait = session.ev_do_calculate_rw_wait(wait)
|
|
108
|
-
readers, writers, =
|
|
108
|
+
readers, writers, = IO.select(sr, sw, nil, actwait)
|
|
109
109
|
|
|
110
110
|
session.ev_do_handle_events(readers,writers)
|
|
111
111
|
session.ev_do_postprocess(!((readers.nil? || readers.empty?) && (writers.nil? || writers.empty?)))
|
|
@@ -23,6 +23,9 @@ module Net; module SSH; module Proxy
|
|
|
23
23
|
# The command line for the session
|
|
24
24
|
attr_reader :command_line
|
|
25
25
|
|
|
26
|
+
# Timeout in seconds in open, defaults to 60
|
|
27
|
+
attr_accessor :timeout
|
|
28
|
+
|
|
26
29
|
# Create a new socket factory that tunnels via a command executed
|
|
27
30
|
# with the user's shell, which is composed from the given command
|
|
28
31
|
# template. In the command template, `%h' will be substituted by
|
|
@@ -30,6 +33,7 @@ module Net; module SSH; module Proxy
|
|
|
30
33
|
def initialize(command_line_template)
|
|
31
34
|
@command_line_template = command_line_template
|
|
32
35
|
@command_line = nil
|
|
36
|
+
@timeout = 60
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
# Return a new socket connected to the given host and port via the
|
|
@@ -56,13 +60,17 @@ module Net; module SSH; module Proxy
|
|
|
56
60
|
}
|
|
57
61
|
begin
|
|
58
62
|
io = IO.popen(command_line, "r+")
|
|
59
|
-
|
|
60
|
-
if result.
|
|
61
|
-
io.
|
|
62
|
-
|
|
63
|
+
begin
|
|
64
|
+
if result = IO.select([io], nil, [io], @timeout)
|
|
65
|
+
if result.last.any? || io.eof?
|
|
66
|
+
raise "command failed"
|
|
67
|
+
end
|
|
68
|
+
else
|
|
69
|
+
raise "command timed out"
|
|
63
70
|
end
|
|
64
|
-
|
|
65
|
-
|
|
71
|
+
rescue
|
|
72
|
+
close_on_error(io)
|
|
73
|
+
raise
|
|
66
74
|
end
|
|
67
75
|
rescue => e
|
|
68
76
|
raise ConnectError, "#{e}: #{command_line}"
|
|
@@ -104,6 +112,12 @@ module Net; module SSH; module Proxy
|
|
|
104
112
|
end
|
|
105
113
|
io
|
|
106
114
|
end
|
|
115
|
+
|
|
116
|
+
def close_on_error(io)
|
|
117
|
+
Process.kill('TERM', io.pid)
|
|
118
|
+
Thread.new { io.close }
|
|
119
|
+
end
|
|
120
|
+
|
|
107
121
|
end
|
|
108
122
|
|
|
109
123
|
end; end; end
|
data/lib/net/ssh/ruby_compat.rb
CHANGED
|
@@ -10,15 +10,3 @@ class String
|
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
|
-
|
|
14
|
-
module Net; module SSH
|
|
15
|
-
|
|
16
|
-
# This class contains miscellaneous patches and workarounds
|
|
17
|
-
# for different ruby implementations.
|
|
18
|
-
class Compat
|
|
19
|
-
def self.io_select(*params)
|
|
20
|
-
IO.select(*params)
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
end; end
|
|
@@ -24,9 +24,10 @@ module Net; module SSH; module Transport
|
|
|
24
24
|
|
|
25
25
|
"3des-ctr" => "des-ede3",
|
|
26
26
|
"blowfish-ctr" => "bf-ecb",
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
27
|
+
|
|
28
|
+
"aes256-ctr" => "aes-256-ctr",
|
|
29
|
+
"aes192-ctr" => "aes-192-ctr",
|
|
30
|
+
"aes128-ctr" => "aes-128-ctr",
|
|
30
31
|
"cast128-ctr" => "cast5-ecb",
|
|
31
32
|
|
|
32
33
|
"none" => "none",
|
|
@@ -63,7 +64,13 @@ module Net; module SSH; module Transport
|
|
|
63
64
|
|
|
64
65
|
cipher.padding = 0
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
if name =~ /-ctr(@openssh.org)?$/
|
|
68
|
+
if ossl_name !~ /-ctr/
|
|
69
|
+
cipher.extend(Net::SSH::Transport::CTR)
|
|
70
|
+
else
|
|
71
|
+
cipher = Net::SSH::Transport::OpenSSLAESCTR.new(cipher)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
67
74
|
cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
|
|
68
75
|
|
|
69
76
|
key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
|
|
@@ -89,7 +96,17 @@ module Net; module SSH; module Transport
|
|
|
89
96
|
key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
|
|
90
97
|
cipher.key_len = key_len
|
|
91
98
|
|
|
92
|
-
|
|
99
|
+
block_size =
|
|
100
|
+
case ossl_name
|
|
101
|
+
when "rc4"
|
|
102
|
+
8
|
|
103
|
+
when /\-ctr/
|
|
104
|
+
Net::SSH::Transport::OpenSSLAESCTR.block_size
|
|
105
|
+
else
|
|
106
|
+
cipher.block_size
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
result = [key_len, block_size]
|
|
93
110
|
result << cipher.iv_len if options[:iv_len]
|
|
94
111
|
end
|
|
95
112
|
result
|
|
@@ -1,7 +1,32 @@
|
|
|
1
1
|
require 'openssl'
|
|
2
|
+
require 'delegate'
|
|
2
3
|
|
|
3
4
|
module Net::SSH::Transport
|
|
5
|
+
#:nodoc:
|
|
6
|
+
class OpenSSLAESCTR < SimpleDelegator
|
|
7
|
+
def initialize(original)
|
|
8
|
+
super
|
|
9
|
+
@was_reset = false
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def block_size
|
|
13
|
+
16
|
|
14
|
+
end
|
|
4
15
|
|
|
16
|
+
def self.block_size
|
|
17
|
+
16
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reset
|
|
21
|
+
@was_reset = true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def iv=(iv_s)
|
|
25
|
+
super unless @was_reset
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#:nodoc:
|
|
5
30
|
# Pure-Ruby implementation of Stateful Decryption Counter(SDCTR) Mode
|
|
6
31
|
# for Block Ciphers. See RFC4344 for detail.
|
|
7
32
|
module CTR
|
|
@@ -12,7 +37,7 @@ module Net::SSH::Transport
|
|
|
12
37
|
@counter_len = orig.block_size
|
|
13
38
|
orig.encrypt
|
|
14
39
|
orig.padding = 0
|
|
15
|
-
|
|
40
|
+
|
|
16
41
|
singleton_class.send(:alias_method, :_update, :update)
|
|
17
42
|
singleton_class.send(:private, :_update)
|
|
18
43
|
singleton_class.send(:undef_method, :update)
|
|
@@ -50,11 +75,14 @@ module Net::SSH::Transport
|
|
|
50
75
|
|
|
51
76
|
encrypted = ""
|
|
52
77
|
|
|
53
|
-
|
|
54
|
-
|
|
78
|
+
offset = 0
|
|
79
|
+
while (@remaining.bytesize - offset) >= block_size
|
|
80
|
+
encrypted += xor!(@remaining.slice(offset, block_size),
|
|
55
81
|
_update(@counter))
|
|
56
82
|
increment_counter!
|
|
83
|
+
offset += block_size
|
|
57
84
|
end
|
|
85
|
+
@remaining = @remaining.slice(offset..-1)
|
|
58
86
|
|
|
59
87
|
encrypted
|
|
60
88
|
end
|
|
@@ -109,12 +109,12 @@ module OpenSSL
|
|
|
109
109
|
OpenSSL::ASN1::Integer(sig_r),
|
|
110
110
|
OpenSSL::ASN1::Integer(sig_s)
|
|
111
111
|
])
|
|
112
|
-
return verify(OpenSSL::Digest::
|
|
112
|
+
return verify(OpenSSL::Digest::SHA1.new, a1sig.to_der, data)
|
|
113
113
|
end
|
|
114
114
|
|
|
115
115
|
# Signs the given data.
|
|
116
116
|
def ssh_do_sign(data)
|
|
117
|
-
sig = sign( OpenSSL::Digest::
|
|
117
|
+
sig = sign( OpenSSL::Digest::SHA1.new, data)
|
|
118
118
|
a1sig = OpenSSL::ASN1.decode( sig )
|
|
119
119
|
|
|
120
120
|
sig_r = a1sig.value[0].value.to_s(2)
|
|
@@ -72,7 +72,7 @@ module Net; module SSH; module Transport
|
|
|
72
72
|
|
|
73
73
|
# Returns true if the IO is available for reading, and false otherwise.
|
|
74
74
|
def available_for_read?
|
|
75
|
-
result =
|
|
75
|
+
result = IO.select([self], nil, nil, 0)
|
|
76
76
|
result && result.first.any?
|
|
77
77
|
end
|
|
78
78
|
|
|
@@ -105,7 +105,7 @@ module Net; module SSH; module Transport
|
|
|
105
105
|
return packet if packet
|
|
106
106
|
|
|
107
107
|
loop do
|
|
108
|
-
result =
|
|
108
|
+
result = IO.select([self]) or next
|
|
109
109
|
break if result.first.any?
|
|
110
110
|
end
|
|
111
111
|
|
data/lib/net/ssh/version.rb
CHANGED
|
@@ -45,17 +45,17 @@ module Net; module SSH
|
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
# The major component of this version of the Net::SSH library
|
|
48
|
-
MAJOR =
|
|
48
|
+
MAJOR = 5
|
|
49
49
|
|
|
50
50
|
# The minor component of this version of the Net::SSH library
|
|
51
|
-
MINOR =
|
|
51
|
+
MINOR = 0
|
|
52
52
|
|
|
53
53
|
# The tiny component of this version of the Net::SSH library
|
|
54
54
|
TINY = 0
|
|
55
55
|
|
|
56
56
|
# The prerelease component of this version of the Net::SSH library
|
|
57
57
|
# nil allowed
|
|
58
|
-
PRE =
|
|
58
|
+
PRE = "beta1"
|
|
59
59
|
|
|
60
60
|
# The current version of the Net::SSH library as a Version instance
|
|
61
61
|
CURRENT = new(*[MAJOR, MINOR, TINY, PRE].compact)
|
data/net-ssh-public_cert.pem
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
|
2
|
-
|
|
2
|
+
MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQ8wDQYDVQQDDAZuZXRz
|
|
3
3
|
c2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
|
|
4
|
-
|
|
4
|
+
b20wHhcNMTgwMzExMDU0MzU1WhcNMTkwMzExMDU0MzU1WjBBMQ8wDQYDVQQDDAZu
|
|
5
5
|
ZXRzc2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
|
|
6
6
|
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGJ4TbZ9H+qZ08
|
|
7
7
|
pQfJhPJTHaDCyQvCsKTFrL5O9z3tllQ7B/zksMMM+qFBpNYu9HCcg4yBATacE/PB
|
|
@@ -12,10 +12,10 @@ KP4yMn+TzaXijyjRg7gECfJr3TGASaA4bQsILFGG5dAWcwO4OMrZedR7SHj/o0Kf
|
|
|
12
12
|
3gL7P0axAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
|
13
13
|
BBQF8qLA7Z4zg0SJGtUbv3eoQ8tjIzAfBgNVHREEGDAWgRRuZXRzc2hAc29sdXRp
|
|
14
14
|
b3VzLmNvbTAfBgNVHRIEGDAWgRRuZXRzc2hAc29sdXRpb3VzLmNvbTANBgkqhkiG
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
15
|
+
9w0BAQsFAAOCAQEAnINf4yDsUx62QPKC2E+5Dj0hN2yUjcYzTGwxyz8x+nCiC0X3
|
|
16
|
+
cyjftyEViuKvAKtZ0Uo4OG0x2SZ5O7I45OkUo1bAOFcuYRFYiD1JRlyvl8aB+2Vl
|
|
17
|
+
pFyi/4ClnmjNxnplXL+mmScv/4VacBD1/LNBUVNluhLue2yIakAXFy0KthqLzIG8
|
|
18
|
+
BYIiexqQMKfkw+auIcyXe1luZnCt6JFksW0BVoZGTj5Sj7sC2+cS4y9XYog1dSks
|
|
19
|
+
ZFwoIuXKeDmTTpryd/vI7sdLXDuV6MbWOLGh6gXn9RDDXG1EqEXW0bjovATBMpdH
|
|
20
|
+
9OGohJvAFzcvhDTWPwT6w3PG5B80pqb9j1hEAg==
|
|
21
21
|
-----END CERTIFICATE-----
|
data/net-ssh.gemspec
CHANGED
|
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
|
|
|
16
16
|
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.}
|
|
17
17
|
spec.homepage = "https://github.com/net-ssh/net-ssh"
|
|
18
18
|
spec.license = "MIT"
|
|
19
|
-
spec.required_ruby_version = Gem::Requirement.new(">= 2.
|
|
19
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.2.6")
|
|
20
20
|
|
|
21
21
|
spec.extra_rdoc_files = [
|
|
22
22
|
"LICENSE.txt",
|
|
@@ -28,9 +28,8 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
29
29
|
spec.require_paths = ["lib"]
|
|
30
30
|
|
|
31
|
-
unless ENV['
|
|
32
|
-
spec.add_development_dependency("
|
|
33
|
-
spec.add_development_dependency("rbnacl", ['>= 3.2.0','< 5.0'])
|
|
31
|
+
unless ENV['NET_SSH_NO_ED25519']
|
|
32
|
+
spec.add_development_dependency("ed25519", "~> 1.2")
|
|
34
33
|
spec.add_development_dependency("bcrypt_pbkdf", "~> 1.0") unless RUBY_PLATFORM == "java"
|
|
35
34
|
end
|
|
36
35
|
|
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:
|
|
4
|
+
version: 5.0.0.beta1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jamis Buck
|
|
@@ -12,9 +12,9 @@ bindir: exe
|
|
|
12
12
|
cert_chain:
|
|
13
13
|
- |
|
|
14
14
|
-----BEGIN CERTIFICATE-----
|
|
15
|
-
|
|
15
|
+
MIIDeDCCAmCgAwIBAgIBATANBgkqhkiG9w0BAQsFADBBMQ8wDQYDVQQDDAZuZXRz
|
|
16
16
|
c2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZFgNj
|
|
17
|
-
|
|
17
|
+
b20wHhcNMTgwMzExMDU0MzU1WhcNMTkwMzExMDU0MzU1WjBBMQ8wDQYDVQQDDAZu
|
|
18
18
|
ZXRzc2gxGTAXBgoJkiaJk/IsZAEZFglzb2x1dGlvdXMxEzARBgoJkiaJk/IsZAEZ
|
|
19
19
|
FgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGJ4TbZ9H+qZ08
|
|
20
20
|
pQfJhPJTHaDCyQvCsKTFrL5O9z3tllQ7B/zksMMM+qFBpNYu9HCcg4yBATacE/PB
|
|
@@ -25,49 +25,29 @@ cert_chain:
|
|
|
25
25
|
3gL7P0axAgMBAAGjezB5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW
|
|
26
26
|
BBQF8qLA7Z4zg0SJGtUbv3eoQ8tjIzAfBgNVHREEGDAWgRRuZXRzc2hAc29sdXRp
|
|
27
27
|
b3VzLmNvbTAfBgNVHRIEGDAWgRRuZXRzc2hAc29sdXRpb3VzLmNvbTANBgkqhkiG
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
9w0BAQsFAAOCAQEAnINf4yDsUx62QPKC2E+5Dj0hN2yUjcYzTGwxyz8x+nCiC0X3
|
|
29
|
+
cyjftyEViuKvAKtZ0Uo4OG0x2SZ5O7I45OkUo1bAOFcuYRFYiD1JRlyvl8aB+2Vl
|
|
30
|
+
pFyi/4ClnmjNxnplXL+mmScv/4VacBD1/LNBUVNluhLue2yIakAXFy0KthqLzIG8
|
|
31
|
+
BYIiexqQMKfkw+auIcyXe1luZnCt6JFksW0BVoZGTj5Sj7sC2+cS4y9XYog1dSks
|
|
32
|
+
ZFwoIuXKeDmTTpryd/vI7sdLXDuV6MbWOLGh6gXn9RDDXG1EqEXW0bjovATBMpdH
|
|
33
|
+
9OGohJvAFzcvhDTWPwT6w3PG5B80pqb9j1hEAg==
|
|
34
34
|
-----END CERTIFICATE-----
|
|
35
|
-
date:
|
|
35
|
+
date: 2018-03-11 00:00:00.000000000 Z
|
|
36
36
|
dependencies:
|
|
37
37
|
- !ruby/object:Gem::Dependency
|
|
38
|
-
name:
|
|
38
|
+
name: ed25519
|
|
39
39
|
requirement: !ruby/object:Gem::Requirement
|
|
40
40
|
requirements:
|
|
41
41
|
- - "~>"
|
|
42
42
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: 1.
|
|
43
|
+
version: '1.2'
|
|
44
44
|
type: :development
|
|
45
45
|
prerelease: false
|
|
46
46
|
version_requirements: !ruby/object:Gem::Requirement
|
|
47
47
|
requirements:
|
|
48
48
|
- - "~>"
|
|
49
49
|
- !ruby/object:Gem::Version
|
|
50
|
-
version: 1.
|
|
51
|
-
- !ruby/object:Gem::Dependency
|
|
52
|
-
name: rbnacl
|
|
53
|
-
requirement: !ruby/object:Gem::Requirement
|
|
54
|
-
requirements:
|
|
55
|
-
- - ">="
|
|
56
|
-
- !ruby/object:Gem::Version
|
|
57
|
-
version: 3.2.0
|
|
58
|
-
- - "<"
|
|
59
|
-
- !ruby/object:Gem::Version
|
|
60
|
-
version: '5.0'
|
|
61
|
-
type: :development
|
|
62
|
-
prerelease: false
|
|
63
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
-
requirements:
|
|
65
|
-
- - ">="
|
|
66
|
-
- !ruby/object:Gem::Version
|
|
67
|
-
version: 3.2.0
|
|
68
|
-
- - "<"
|
|
69
|
-
- !ruby/object:Gem::Version
|
|
70
|
-
version: '5.0'
|
|
50
|
+
version: '1.2'
|
|
71
51
|
- !ruby/object:Gem::Dependency
|
|
72
52
|
name: bcrypt_pbkdf
|
|
73
53
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -169,8 +149,8 @@ files:
|
|
|
169
149
|
- ".travis.yml"
|
|
170
150
|
- CHANGES.txt
|
|
171
151
|
- Gemfile
|
|
172
|
-
- Gemfile.
|
|
173
|
-
- Gemfile.
|
|
152
|
+
- Gemfile.noed25519
|
|
153
|
+
- Gemfile.noed25519.lock
|
|
174
154
|
- ISSUE_TEMPLATE.md
|
|
175
155
|
- LICENSE.txt
|
|
176
156
|
- Manifest
|
|
@@ -278,15 +258,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
278
258
|
requirements:
|
|
279
259
|
- - ">="
|
|
280
260
|
- !ruby/object:Gem::Version
|
|
281
|
-
version:
|
|
261
|
+
version: 2.2.6
|
|
282
262
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
283
263
|
requirements:
|
|
284
|
-
- - "
|
|
264
|
+
- - ">"
|
|
285
265
|
- !ruby/object:Gem::Version
|
|
286
|
-
version:
|
|
266
|
+
version: 1.3.1
|
|
287
267
|
requirements: []
|
|
288
268
|
rubyforge_project:
|
|
289
|
-
rubygems_version: 2.6
|
|
269
|
+
rubygems_version: 2.7.6
|
|
290
270
|
signing_key:
|
|
291
271
|
specification_version: 4
|
|
292
272
|
summary: 'Net::SSH: a pure-Ruby implementation of the SSH2 client protocol.'
|
metadata.gz.sig
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
8����l��Wؚ����po{C�m>V@;������?����y��(�=��긱#RW.�`*[]d��KhS�7�-�D�iO��N)�JԒW&h���0�N��tu���zKd�
|
|
1
|
+
������������Z�p�t����3M3��s���G�`��O�d!�t����\1a4��{���Q����J*&;E��<��Dx�=�^��(�9D��\�v�Π&{���>���S�������ڸ���('�W�r�2#(�X�Z�B��`����⽾w!ZZ�A���Y�����e�D��r�� �{�1I�c���D��)�X��l���R}���NOB���j�p���K�
|