net-ssh 3.0.2 → 3.1.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/.travis.yml +1 -0
- data/CHANGES.txt +9 -0
- data/lib/net/ssh.rb +4 -1
- data/lib/net/ssh/authentication/pageant.rb +2 -2
- data/lib/net/ssh/config.rb +9 -0
- data/lib/net/ssh/connection/channel.rb +10 -7
- data/lib/net/ssh/known_hosts.rb +26 -1
- data/lib/net/ssh/transport/algorithms.rb +1 -1
- data/lib/net/ssh/transport/server_version.rb +4 -3
- data/lib/net/ssh/transport/session.rb +7 -0
- data/lib/net/ssh/verifiers/secure.rb +8 -10
- data/lib/net/ssh/version.rb +3 -3
- data/net-ssh.gemspec +4 -4
- data/test/common.rb +1 -0
- data/test/connection/test_channel.rb +19 -2
- data/test/test_config.rb +6 -1
- data/test/transport/test_packet_stream.rb +2 -2
- data/test/transport/test_server_version.rb +3 -7
- metadata +4 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8014163f04248cb8c0d06a2b0f9eb99650c4ca1f
|
4
|
+
data.tar.gz: 4a3a4ffd2cc73052808781409b6be9bdf7a336a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e70e296ef1844a744fcbb69304203e8e758f5eaf2e5ab89ec3a4352c6fefd12a59395800aecf3efc4ba34b3dfed3ae6f0a729542da1c48173b88c5b0b4d15884
|
7
|
+
data.tar.gz: 4c10b1d730425a42f606fc0119080894de291d6d7949854246b71bfe1a62d7056d59edce2e789ca7ef8355e4c6d2ff1c2a0158089f4213d8b8516e08f2dc4c23
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/.travis.yml
CHANGED
data/CHANGES.txt
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
=== 3.1.0.beta1
|
2
|
+
|
3
|
+
* trying to execute something on a not yet opend channel throws nicer messag [Miklos Fazekas]
|
4
|
+
* calling close on a not opened channel marks the channel for close [Miklos Fazekas]
|
5
|
+
* read keepalive configuration from ssh config files [Miklos Fazekas]
|
6
|
+
* send client version on hadshake before waiting for server to reduce handshake time [Miklos Fazekas]
|
7
|
+
* allow custom Net::SSH::KnownHosts implementations [Jean Boussier]
|
8
|
+
* memoize known host so we only search it once per session [Jean Boussier, Miklos Fazekas]
|
9
|
+
|
1
10
|
=== 3.0.2
|
2
11
|
=== 3.0.2.rc1
|
3
12
|
|
data/lib/net/ssh.rb
CHANGED
@@ -66,7 +66,7 @@ module Net
|
|
66
66
|
:keepalive, :keepalive_interval, :keepalive_maxcount, :kex, :keys, :key_data,
|
67
67
|
:languages, :logger, :paranoid, :password, :port, :proxy,
|
68
68
|
:rekey_blocks_limit,:rekey_limit, :rekey_packet_limit, :timeout, :verbose,
|
69
|
-
:global_known_hosts_file, :user_known_hosts_file, :host_key_alias,
|
69
|
+
:known_hosts, :global_known_hosts_file, :user_known_hosts_file, :host_key_alias,
|
70
70
|
:host_name, :user, :properties, :passphrase, :keys_only, :max_pkt_size,
|
71
71
|
:max_win_size, :send_env, :use_agent, :number_of_password_prompts,
|
72
72
|
:append_supported_algorithms, :non_interactive
|
@@ -114,6 +114,8 @@ module Net
|
|
114
114
|
# * :encryption => the encryption cipher (or ciphers) to use
|
115
115
|
# * :forward_agent => set to true if you want the SSH agent connection to
|
116
116
|
# be forwarded
|
117
|
+
# * :known_hosts => a custom object holding known hosts records.
|
118
|
+
# It must implement #search_for and add in a similiar manner as KnownHosts.
|
117
119
|
# * :global_known_hosts_file => the location of the global known hosts
|
118
120
|
# file. Set to an array if you want to specify multiple global known
|
119
121
|
# hosts files. Defaults to %w(/etc/ssh/ssh_known_hosts /etc/ssh/ssh_known_hosts2).
|
@@ -132,6 +134,7 @@ module Net
|
|
132
134
|
# * :keepalive_interval => the interval seconds for keepalive.
|
133
135
|
# Defaults to +300+ seconds.
|
134
136
|
# * :keepalive_maxcount => the maximun number of keepalive packet miss allowed.
|
137
|
+
# Defaults to 3
|
135
138
|
# * :kex => the key exchange algorithm (or algorithms) to use
|
136
139
|
# * :keys => an array of file names of private keys to use for publickey
|
137
140
|
# and hostbased authentication
|
data/lib/net/ssh/config.rb
CHANGED
@@ -178,6 +178,15 @@ module Net; module SSH
|
|
178
178
|
hash[:keys] = value
|
179
179
|
when 'macs' then
|
180
180
|
hash[:hmac] = value.split(/,/)
|
181
|
+
when 'serveralivecountmax'
|
182
|
+
hash[:keepalive_maxcount] = value.to_i if value
|
183
|
+
when 'serveraliveinterval'
|
184
|
+
if value && value.to_i > 0
|
185
|
+
hash[:keepalive] = true
|
186
|
+
hash[:keepalive_interval] = value.to_i
|
187
|
+
else
|
188
|
+
hash[:keepalive] = false
|
189
|
+
end
|
181
190
|
when 'passwordauthentication'
|
182
191
|
if value
|
183
192
|
(hash[:auth_methods] << 'password').uniq!
|
@@ -291,15 +291,11 @@ module Net; module SSH; module Connection
|
|
291
291
|
@remote_closed = true
|
292
292
|
end
|
293
293
|
|
294
|
-
# Requests that the channel be closed.
|
295
|
-
#
|
296
|
-
# been confirmed open (see #do_open_confirmation). Otherwise, it sends a
|
297
|
-
# CHANNEL_CLOSE message and marks the channel as closing.
|
294
|
+
# Requests that the channel be closed. It only marks the channel to be closed
|
295
|
+
# the CHANNEL_CLOSE message will be sent from event loop
|
298
296
|
def close
|
299
297
|
return if @closing
|
300
|
-
|
301
|
-
@closing = true
|
302
|
-
end
|
298
|
+
@closing = true
|
303
299
|
end
|
304
300
|
|
305
301
|
# Returns true if the local end of the channel has declared that no more
|
@@ -486,6 +482,7 @@ module Net; module SSH; module Connection
|
|
486
482
|
# convenient helper methods (see #exec and #subsystem).
|
487
483
|
def send_channel_request(request_name, *data, &callback)
|
488
484
|
info { "sending channel request #{request_name.inspect}" }
|
485
|
+
fail "Channel open not yet confirmed, please call send_channel_request(or exec) from block of open_channel" unless remote_id
|
489
486
|
msg = Buffer.from(:byte, CHANNEL_REQUEST,
|
490
487
|
:long, remote_id, :string, request_name,
|
491
488
|
:bool, !callback.nil?, *data)
|
@@ -632,6 +629,12 @@ module Net; module SSH; module Connection
|
|
632
629
|
|
633
630
|
private
|
634
631
|
|
632
|
+
# Runs the SSH event loop until the remote confirmed channel open
|
633
|
+
# experimental api
|
634
|
+
def wait_until_open_confirmed
|
635
|
+
connection.loop { !remote_id }
|
636
|
+
end
|
637
|
+
|
635
638
|
# Updates the local window size by the given amount. If the window
|
636
639
|
# size drops to less than half of the local maximum (an arbitrary
|
637
640
|
# threshold), a CHANNEL_WINDOW_ADJUST message will be sent to the
|
data/lib/net/ssh/known_hosts.rb
CHANGED
@@ -5,6 +5,31 @@ require 'net/ssh/buffer'
|
|
5
5
|
|
6
6
|
module Net; module SSH
|
7
7
|
|
8
|
+
class HostKeys
|
9
|
+
include Enumerable
|
10
|
+
attr_reader :host
|
11
|
+
|
12
|
+
def initialize(host_keys, host, known_hosts, options = {})
|
13
|
+
@host_keys = host_keys
|
14
|
+
@host = host
|
15
|
+
@known_hosts = known_hosts
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def add_host_key(key)
|
20
|
+
@known_hosts.add(@host, key, options)
|
21
|
+
push(key)
|
22
|
+
end
|
23
|
+
|
24
|
+
def each(&block)
|
25
|
+
@host_keys.each(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
def empty?
|
29
|
+
@host_keys.empty?
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
8
33
|
# Searches an OpenSSH-style known-host file for a given host, and returns all
|
9
34
|
# matching keys. This is used to implement host-key verification, as well as
|
10
35
|
# to determine what key a user prefers to use for a given host.
|
@@ -28,7 +53,7 @@ module Net; module SSH
|
|
28
53
|
# Searches all known host files (see KnownHosts.hostfiles) for all keys
|
29
54
|
# of the given host. Returns an array of keys found.
|
30
55
|
def search_for(host, options={})
|
31
|
-
search_in(hostfiles(options), host)
|
56
|
+
HostKeys.new(search_in(hostfiles(options), host), host, self, options)
|
32
57
|
end
|
33
58
|
|
34
59
|
# Search for all known keys for the given host, in every file given in
|
@@ -242,7 +242,7 @@ module Net; module SSH; module Transport
|
|
242
242
|
# make sure the host keys are specified in preference order, where any
|
243
243
|
# existing known key for the host has preference.
|
244
244
|
|
245
|
-
existing_keys =
|
245
|
+
existing_keys = session.host_keys
|
246
246
|
host_keys = existing_keys.map { |key| key.ssh_type }.uniq
|
247
247
|
algorithms[:host_key].each do |name|
|
248
248
|
host_keys << name unless host_keys.include?(name)
|
@@ -40,6 +40,10 @@ module Net; module SSH; module Transport
|
|
40
40
|
def negotiate!(socket, timeout)
|
41
41
|
info { "negotiating protocol version" }
|
42
42
|
|
43
|
+
debug { "local is `#{PROTO_VERSION}'" }
|
44
|
+
socket.write "#{PROTO_VERSION}\r\n"
|
45
|
+
socket.flush
|
46
|
+
|
43
47
|
if timeout && !IO.select([socket], nil, nil, timeout)
|
44
48
|
raise Net::SSH::ConnectionTimeout, "timeout during server version negotiating"
|
45
49
|
end
|
@@ -69,9 +73,6 @@ module Net; module SSH; module Transport
|
|
69
73
|
if timeout && !IO.select(nil, [socket], nil, timeout)
|
70
74
|
raise Net::SSH::ConnectionTimeout, "timeout during client version negotiating"
|
71
75
|
end
|
72
|
-
debug { "local is `#{PROTO_VERSION}'" }
|
73
|
-
socket.write "#{PROTO_VERSION}\r\n"
|
74
|
-
socket.flush
|
75
76
|
end
|
76
77
|
end
|
77
78
|
end; end; end
|
@@ -89,6 +89,13 @@ module Net; module SSH; module Transport
|
|
89
89
|
raise Net::SSH::ConnectionTimeout
|
90
90
|
end
|
91
91
|
|
92
|
+
def host_keys
|
93
|
+
@host_keys ||= begin
|
94
|
+
known_hosts = options.fetch(:known_hosts, KnownHosts)
|
95
|
+
known_hosts.search_for(options[:host_key_alias] || host_as_string, options)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
92
99
|
# Returns the host (and possibly IP address) in a format compatible with
|
93
100
|
# SSH known-host files.
|
94
101
|
def host_as_string
|
@@ -13,18 +13,16 @@ module Net; module SSH; module Verifiers
|
|
13
13
|
# Otherwise, this returns true.
|
14
14
|
class Secure
|
15
15
|
def verify(arguments)
|
16
|
-
|
17
|
-
host = options[:host_key_alias] || arguments[:session].host_as_string
|
18
|
-
matches = Net::SSH::KnownHosts.search_for(host, arguments[:session].options)
|
16
|
+
host_keys = arguments[:session].host_keys
|
19
17
|
|
20
18
|
# We've never seen this host before, so raise an exception.
|
21
|
-
if
|
22
|
-
process_cache_miss(
|
19
|
+
if host_keys.empty?
|
20
|
+
process_cache_miss(host_keys, arguments, HostKeyUnknown, "is unknown")
|
23
21
|
end
|
24
22
|
|
25
23
|
# If we found any matches, check to see that the key type and
|
26
24
|
# blob also match.
|
27
|
-
found =
|
25
|
+
found = host_keys.any? do |key|
|
28
26
|
key.ssh_type == arguments[:key].ssh_type &&
|
29
27
|
key.to_blob == arguments[:key].to_blob
|
30
28
|
end
|
@@ -32,7 +30,7 @@ module Net; module SSH; module Verifiers
|
|
32
30
|
# If a match was found, return true. Otherwise, raise an exception
|
33
31
|
# indicating that the key was not recognized.
|
34
32
|
unless found
|
35
|
-
process_cache_miss(
|
33
|
+
process_cache_miss(host_keys, HostKeyMismatch, "does not match")
|
36
34
|
end
|
37
35
|
|
38
36
|
found
|
@@ -40,12 +38,12 @@ module Net; module SSH; module Verifiers
|
|
40
38
|
|
41
39
|
private
|
42
40
|
|
43
|
-
def process_cache_miss(
|
41
|
+
def process_cache_miss(host_keys, args, exc_class, message)
|
44
42
|
exception = exc_class.new("fingerprint #{args[:fingerprint]} " +
|
45
|
-
"#{message} for #{host.inspect}")
|
43
|
+
"#{message} for #{host_keys.host.inspect}")
|
46
44
|
exception.data = args
|
47
45
|
exception.callback = Proc.new do
|
48
|
-
|
46
|
+
host_keys.add_host_key(args[:key])
|
49
47
|
end
|
50
48
|
raise exception
|
51
49
|
end
|
data/lib/net/ssh/version.rb
CHANGED
@@ -48,14 +48,14 @@ module Net; module SSH
|
|
48
48
|
MAJOR = 3
|
49
49
|
|
50
50
|
# The minor component of this version of the Net::SSH library
|
51
|
-
MINOR =
|
51
|
+
MINOR = 1
|
52
52
|
|
53
53
|
# The tiny component of this version of the Net::SSH library
|
54
|
-
TINY =
|
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 = "beta2"
|
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.gemspec
CHANGED
@@ -2,17 +2,17 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: net-ssh 3.0.
|
5
|
+
# stub: net-ssh 3.1.0.beta2 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "net-ssh"
|
9
|
-
s.version = "3.0.
|
9
|
+
s.version = "3.1.0.beta2"
|
10
10
|
|
11
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
11
|
+
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Jamis Buck", "Delano Mandelbaum", "Mikl\u{f3}s Fazekas"]
|
14
14
|
s.cert_chain = ["net-ssh-public_cert.pem"]
|
15
|
-
s.date = "
|
15
|
+
s.date = "2016-03-05"
|
16
16
|
s.description = "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
|
s.email = "net-ssh@solutious.com"
|
18
18
|
s.extra_rdoc_files = [
|
data/test/common.rb
CHANGED
@@ -41,6 +41,7 @@ class MockTransport < Net::SSH::Transport::Session
|
|
41
41
|
attr_accessor :mock_enqueue
|
42
42
|
|
43
43
|
def initialize(options={})
|
44
|
+
@options = options
|
44
45
|
self.logger = options[:logger]
|
45
46
|
self.host_as_string = "net.ssh.test,127.0.0.1"
|
46
47
|
self.server_version = OpenStruct.new(:version => "SSH-2.0-Ruby/Net::SSH::Test")
|
@@ -63,10 +63,10 @@ module Connection
|
|
63
63
|
assert_equal "helloworld", channel.output.to_s
|
64
64
|
end
|
65
65
|
|
66
|
-
def
|
66
|
+
def test_close_before_channel_has_been_confirmed_should_set_closing
|
67
67
|
assert !channel.closing?
|
68
68
|
channel.close
|
69
|
-
assert
|
69
|
+
assert channel.closing?
|
70
70
|
end
|
71
71
|
|
72
72
|
def test_close_should_set_closing_and_send_message
|
@@ -261,6 +261,18 @@ module Connection
|
|
261
261
|
assert channel.pending_requests.empty?
|
262
262
|
end
|
263
263
|
|
264
|
+
def test_send_channel_request_should_wait_for_remote_id
|
265
|
+
channel.expects(:remote_id).times(1).returns(nil)
|
266
|
+
msg = nil
|
267
|
+
begin
|
268
|
+
channel.send_channel_request("exec", :string, "ls")
|
269
|
+
rescue RuntimeError => e
|
270
|
+
msg = e.message
|
271
|
+
end
|
272
|
+
assert_equal "Channel open not yet confirmed, please call send_channel_request(or exec) from block of open_channel", msg
|
273
|
+
assert channel.pending_requests.empty?
|
274
|
+
end
|
275
|
+
|
264
276
|
def test_send_channel_request_with_callback_should_want_reply
|
265
277
|
channel.do_open_confirmation(0, 100, 100)
|
266
278
|
connection.expect do |t,p|
|
@@ -377,6 +389,11 @@ module Connection
|
|
377
389
|
channel.wait
|
378
390
|
end
|
379
391
|
|
392
|
+
def test_wait_until_open_confirmed_should_block_while_remote_id_nil
|
393
|
+
channel.expects(:remote_id).times(3).returns(nil,nil,3)
|
394
|
+
channel.send(:wait_until_open_confirmed)
|
395
|
+
end
|
396
|
+
|
380
397
|
def test_eof_bang_should_send_eof_to_server
|
381
398
|
channel.do_open_confirmation(0, 1000, 1000)
|
382
399
|
connection.expect { |t,p| assert_equal CHANNEL_EOF, p.type }
|
data/test/test_config.rb
CHANGED
@@ -94,7 +94,9 @@ class TestConfig < Test::Unit::TestCase
|
|
94
94
|
'pubkeyauthentication' => true,
|
95
95
|
'rekeylimit' => 1024,
|
96
96
|
'sendenv' => "LC_*",
|
97
|
-
'numberofpasswordprompts' => '123'
|
97
|
+
'numberofpasswordprompts' => '123',
|
98
|
+
'serveraliveinterval' => '2',
|
99
|
+
'serveralivecountmax' => '4'
|
98
100
|
}
|
99
101
|
|
100
102
|
net_ssh = Net::SSH::Config.translate(open_ssh)
|
@@ -113,6 +115,9 @@ class TestConfig < Test::Unit::TestCase
|
|
113
115
|
assert_equal "127.0.0.1", net_ssh[:bind_address]
|
114
116
|
assert_equal [/^LC_.*$/], net_ssh[:send_env]
|
115
117
|
assert_equal 123, net_ssh[:number_of_password_prompts]
|
118
|
+
assert_equal 4, net_ssh[:keepalive_maxcount]
|
119
|
+
assert_equal 2, net_ssh[:keepalive_interval]
|
120
|
+
assert_equal true, net_ssh[:keepalive]
|
116
121
|
end
|
117
122
|
|
118
123
|
def test_translate_should_turn_off_authentication_methods
|
@@ -109,7 +109,7 @@ module Transport
|
|
109
109
|
def test_next_packet_should_not_block_by_default
|
110
110
|
IO.expects(:select).returns(nil)
|
111
111
|
assert_nothing_raised do
|
112
|
-
timeout(1) { stream.next_packet }
|
112
|
+
Timeout.timeout(1) { stream.next_packet }
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
@@ -1701,7 +1701,7 @@ module Transport
|
|
1701
1701
|
[false, :standard].each do |compress|
|
1702
1702
|
cipher_method_name = cipher_name.gsub(/\W/, "_")
|
1703
1703
|
hmac_method_name = hmac_name.gsub(/\W/, "_")
|
1704
|
-
|
1704
|
+
|
1705
1705
|
define_method("test_next_packet_with_#{cipher_method_name}_and_#{hmac_method_name}_and_#{compress}_compression") do
|
1706
1706
|
opts = { :shared => "123", :hash => "^&*", :digester => OpenSSL::Digest::SHA1 }
|
1707
1707
|
cipher = Net::SSH::Transport::CipherFactory.get(cipher_name, opts.merge(:key => "ABC", :decrypt => true, :iv => "abc"))
|
@@ -47,6 +47,9 @@ module Transport
|
|
47
47
|
def socket(good, version_header, raise_eot=false)
|
48
48
|
socket = mock("socket")
|
49
49
|
|
50
|
+
socket.expects(:write).with("#{Net::SSH::Transport::ServerVersion::PROTO_VERSION}\r\n")
|
51
|
+
socket.expects(:flush)
|
52
|
+
|
50
53
|
data = version_header.split('')
|
51
54
|
recv_times = data.length
|
52
55
|
recv_times += 1 if data[-1] != "\n"
|
@@ -60,13 +63,6 @@ module Transport
|
|
60
63
|
socket.expects(:readpartial).with(1).times(recv_times+1).returns(*data).then.raises(EOFError, "end of file reached")
|
61
64
|
end
|
62
65
|
|
63
|
-
if good
|
64
|
-
socket.expects(:write).with("#{Net::SSH::Transport::ServerVersion::PROTO_VERSION}\r\n")
|
65
|
-
socket.expects(:flush)
|
66
|
-
else
|
67
|
-
socket.expects(:write).never
|
68
|
-
end
|
69
|
-
|
70
66
|
socket
|
71
67
|
end
|
72
68
|
|
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: 3.0.
|
4
|
+
version: 3.1.0.beta2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jamis Buck
|
@@ -31,7 +31,7 @@ cert_chain:
|
|
31
31
|
s/ZUKye79ELwFYKJOhjW5g725OL3hy+llhEleytwKRwgXFQBPTC4f5UkdxZVVWGH
|
32
32
|
e2C9M1m/2odPZo8h
|
33
33
|
-----END CERTIFICATE-----
|
34
|
-
date:
|
34
|
+
date: 2016-03-05 00:00:00.000000000 Z
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: test-unit
|
@@ -251,9 +251,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
251
251
|
version: '2.0'
|
252
252
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
253
253
|
requirements:
|
254
|
-
- - "
|
254
|
+
- - ">"
|
255
255
|
- !ruby/object:Gem::Version
|
256
|
-
version:
|
256
|
+
version: 1.3.1
|
257
257
|
requirements: []
|
258
258
|
rubyforge_project: net-ssh
|
259
259
|
rubygems_version: 2.4.6
|
metadata.gz.sig
CHANGED
Binary file
|