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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2590e090bc772588e579dbd10b4cdcb1b2915f8f
4
- data.tar.gz: 942b5077890efb1b2c4df16cb78421f982ad5280
3
+ metadata.gz: 8014163f04248cb8c0d06a2b0f9eb99650c4ca1f
4
+ data.tar.gz: 4a3a4ffd2cc73052808781409b6be9bdf7a336a8
5
5
  SHA512:
6
- metadata.gz: 2dcdca345ab73be73cc497f5a329f728c9829c60ed6ff8ef8ac6e44bbd53d114e5e271c166babccebe5ec20a7da2ec493cfaa48e0a05c61bccad44ab3e416296
7
- data.tar.gz: bca132211cc2eebca0f2f760b18ef51d1215b23b8d43f53a248c8aa27b3256eab5c2fa7a5893de2196a9d5a87ac840c732d04f679b745d4cf6971afffb859ea9
6
+ metadata.gz: e70e296ef1844a744fcbb69304203e8e758f5eaf2e5ab89ec3a4352c6fefd12a59395800aecf3efc4ba34b3dfed3ae6f0a729542da1c48173b88c5b0b4d15884
7
+ data.tar.gz: 4c10b1d730425a42f606fc0119080894de291d6d7949854246b71bfe1a62d7056d59edce2e789ca7ef8355e4c6d2ff1c2a0158089f4213d8b8516e08f2dc4c23
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -5,6 +5,7 @@ rvm:
5
5
  - 2.0.0
6
6
  - 2.1.0
7
7
  - 2.2.0
8
+ - 2.3.0
8
9
  - jruby-head
9
10
  - jruby-19mode
10
11
  - rbx-2
@@ -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
 
@@ -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
@@ -12,8 +12,8 @@ else
12
12
 
13
13
  # For now map DL to Fiddler versus updating all the code below
14
14
  module DL
15
- CPtr = Fiddle::Pointer
16
- RUBY_FREE = Fiddle::RUBY_FREE
15
+ CPtr ||= Fiddle::Pointer
16
+ RUBY_FREE ||= Fiddle::RUBY_FREE
17
17
  end
18
18
  end
19
19
 
@@ -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. If the channel is already closing,
295
- # this does nothing, nor does it do anything if the channel has not yet
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
- if remote_id
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
@@ -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 = KnownHosts.search_for(options[:host_key_alias] || session.host_as_string, options)
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
- options = arguments[:session].options
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 matches.empty?
22
- process_cache_miss(host, arguments, HostKeyUnknown, "is unknown")
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 = matches.any? do |key|
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(host, arguments, HostKeyMismatch, "does not match")
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(host, args, exc_class, message)
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
- Net::SSH::KnownHosts.add(host, args[:key], args[:session].options)
46
+ host_keys.add_host_key(args[:key])
49
47
  end
50
48
  raise exception
51
49
  end
@@ -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 = 0
51
+ MINOR = 1
52
52
 
53
53
  # The tiny component of this version of the Net::SSH library
54
- TINY = 2
54
+ TINY = 0
55
55
 
56
56
  # The prerelease component of this version of the Net::SSH library
57
57
  # nil allowed
58
- PRE = nil
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)
@@ -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.2 ruby lib
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.2"
9
+ s.version = "3.1.0.beta2"
10
10
 
11
- s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
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 = "2015-12-30"
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 = [
@@ -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 test_close_before_channel_has_been_confirmed_should_do_nothing
66
+ def test_close_before_channel_has_been_confirmed_should_set_closing
67
67
  assert !channel.closing?
68
68
  channel.close
69
- assert !channel.closing?
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 }
@@ -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.2
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: 2015-12-30 00:00:00.000000000 Z
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: '0'
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