net-ssh 2.10.0.beta1 → 2.10.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: 99ac97b623723117ba47a0785cf3dc7d2e1ae594
4
- data.tar.gz: 705651920fb196430521248ef4d457a955814ac6
3
+ metadata.gz: 9f03cb3368a2d774044b5b2ea19a283825e638d5
4
+ data.tar.gz: 68da3613cd8dc0764ce823f3b493ff2003a17801
5
5
  SHA512:
6
- metadata.gz: e6a3403271ad3a629769a30b99a9e4802f918444d0c3b97ef8f2df955ae9b2aeac2eaf0c64454227c4d74ac375d3ccf0e60ee7e19518cf1e63f424dd22d3dceb
7
- data.tar.gz: f84cae92e328113fa58bfd19e0e828412fe1bdce7bc0fa2cdca254b7c25562c0efcd1a9de5987de3be6180f5c64583baee4f560b748f65d37eabd0760529eadf
6
+ metadata.gz: bb71608ade7fc1ae4ec0d037d318da80322f2867c4e6debd94f183d6834f728acc6984ba357b22d1b5e1dbd2110214c0872b04da4a11c0be53c7fd0b30efff72
7
+ data.tar.gz: 22f414e1afe8ebaf4ec71db0354fa7b7da70bcd90de1e93e07d4579d2fa8d1f4992c0610fbae4dd9b6ae62e081a8f05595433182edb1f33b14f4ac040302aae4
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -1,4 +1,11 @@
1
- === 2.10.0-?
1
+ === 2.10.0-beta2
2
+
3
+ * Fix :passphrase option with :non_interactive [Jeremy Stanley]
4
+ * Use Socket.tcp with connect_timeout instead of Timeout::timeout [Carl Hörberg]
5
+ * Support for hostname hashes [Jef Mathiot]
6
+ * Ruby 1.9.3 is no longer supported but should moslty work expect for stuff like connect_timeout
7
+
8
+ === 2.10.0-beta1
2
9
 
3
10
  * Fix could not parse PKey error. [Andrey Voronkov]
4
11
  * Workaround for threading issue in MRI + singleton method declaration [Matt Brictson]
@@ -110,46 +110,11 @@ Then, when install the gem, do so with high security:
110
110
 
111
111
  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.
112
112
 
113
- == RUBY 1.8 SUPPORT
113
+ == RUBY 1.x SUPPORT
114
114
 
115
- net-ssh supports Ruby 1.8.x up until the 2.5.1 release. Current version requires ruby 1.9 or later.
116
-
117
- == JRUBY 1.6
118
-
119
- There is an issue with jruby-openssl that produces the following error in jruby 1.6:
120
-
121
- <ArgumentError> wrong number of arguments (2 for 1)
122
- /home/offers/tracking/shared/bundle/jruby/1.8/gems/net-ssh-2.6.0/lib/net/ssh/key_factory.rb:77:in `load_data_private_key'
123
-
124
- You can downgrade jruby-openssl to version 0.7.4 (before they added the PKey.read method) to resolve it or upgrade jruby to 1.7. See issue #61 for more info: https://github.com/net-ssh/net-ssh/issues/61.
125
-
126
-
127
- == ARCFOUR SUPPORT:
128
-
129
- from Karl Varga:
130
-
131
- Ruby's OpenSSL bindings always return a key length of 16 for RC4 ciphers, which means that when we try to use ARCFOUR256 or higher, Net::SSH generates keys which are consistently too short - 16 bytes as opposed to 32 bytes - resulting in the following error:
132
-
133
- OpenSSL::CipherError: key length too short
134
-
135
- My patch simply instructs Net::SSH to build keys of the the proper length, regardless of the required key length reported by OpenSSL.
136
-
137
- You should also be aware that your OpenSSL C libraries may also contain this bug. I've updated to 0.9.8k, but according to this thread[https://bugzilla.mindrot.org/show_bug.cgi?id=1291], the bug existed as recently as 0.9.8e! I've manually taken a look at my header files and they look ok, which is what makes me think it's a bug in the Ruby implementation.
138
-
139
- To see your OpenSSL version:
140
-
141
- $ openssl version
142
- OpenSSL 0.9.8k 25 Mar 2009
143
-
144
- After installing this gem, verify that Net::SSH is generating keys of the correct length by running the script <tt>support/arcfour_check.rb</tt>:
145
-
146
- $ ruby arcfour_support.rb
147
-
148
- which should produce the following:
149
-
150
- arcfour128: [16, 8] OpenSSL::Cipher::Cipher
151
- arcfour256: [32, 8] OpenSSL::Cipher::Cipher
152
- arcfour512: [64, 8] OpenSSL::Cipher::Cipher
115
+ net-ssh supports Ruby 1.8.x up until the 2.5.1 release.
116
+ net-ssh supports Ruby 1.9.x up until the 2.9.x release.
117
+ Current version requires ruby 2.0 or later.
153
118
 
154
119
 
155
120
  == RUNNING TESTS
@@ -162,14 +127,7 @@ Run a single test file like this:
162
127
 
163
128
  ruby -Ilib -Itest -rrubygems test/transport/test_server_version.rb
164
129
 
165
-
166
- === EXPECTED RESULTS
167
-
168
- * Ruby 1.8: all tests pass
169
-
170
- * Ruby 1.9: all tests pass
171
-
172
- * JRuby 1.5: 99% tests pass (448 tests, 1846 assertions, 1 failures)
130
+ To run integration tests see test/integration/README.txt
173
131
 
174
132
  === BUILDING GEM
175
133
 
@@ -204,7 +204,6 @@ module Net
204
204
 
205
205
  if options[:non_interactive]
206
206
  options[:number_of_password_prompts] = 0
207
- options[:passphrase] = false
208
207
  end
209
208
 
210
209
  if options[:verbose]
@@ -98,7 +98,7 @@ module Net
98
98
  def each_identity
99
99
  prepared_identities = prepare_identities_from_files + prepare_identities_from_data
100
100
 
101
- user_identities = load_identities(prepared_identities, false)
101
+ user_identities = load_identities(prepared_identities, false, true)
102
102
 
103
103
  if agent
104
104
  agent.identities.each do |key|
@@ -114,7 +114,7 @@ module Net
114
114
  end
115
115
  end
116
116
 
117
- user_identities = load_identities(user_identities, true)
117
+ user_identities = load_identities(user_identities, !options[:non_interactive], false)
118
118
 
119
119
  user_identities.each do |identity|
120
120
  key = identity.delete(:public_key)
@@ -139,7 +139,7 @@ module Net
139
139
 
140
140
  if info[:key].nil? && info[:from] == :file
141
141
  begin
142
- info[:key] = KeyFactory.load_private_key(info[:file], options[:passphrase], true)
142
+ info[:key] = KeyFactory.load_private_key(info[:file], options[:passphrase], !options[:non_interactive])
143
143
  rescue Exception, OpenSSL::OpenSSLError => e
144
144
  raise KeyManagerError, "the given identity is known, but the private key could not be loaded: #{e.class} (#{e.message})"
145
145
  end
@@ -212,8 +212,8 @@ module Net
212
212
  end
213
213
  end
214
214
 
215
- # Load prepared identities. Private key decryption errors ignored if passphrase was not prompted.
216
- def load_identities(identities, ask_passphrase)
215
+ # Load prepared identities. Private key decryption errors ignored if ignore_decryption_errors
216
+ def load_identities(identities, ask_passphrase, ignore_decryption_errors)
217
217
  identities.map do |identity|
218
218
  begin
219
219
  case identity[:load_from]
@@ -233,11 +233,11 @@ module Net
233
233
  end
234
234
 
235
235
  rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError => e
236
- if ask_passphrase
236
+ if ignore_decryption_errors
237
+ identity
238
+ else
237
239
  process_identity_loading_error(identity, e)
238
240
  nil
239
- else
240
- identity
241
241
  end
242
242
  rescue ArgumentError => e
243
243
  process_identity_loading_error(identity, e)
@@ -1,4 +1,6 @@
1
1
  require 'strscan'
2
+ require 'openssl'
3
+ require 'base64'
2
4
  require 'net/ssh/buffer'
3
5
 
4
6
  module Net; module SSH
@@ -111,7 +113,9 @@ module Net; module SSH
111
113
  next if scanner.match?(/$|#/)
112
114
 
113
115
  hostlist = scanner.scan(/\S+/).split(/,/)
114
- next unless entries.all? { |entry| hostlist.include?(entry) }
116
+ found = entries.all? { |entry| hostlist.include?(entry) } ||
117
+ known_host_hash?(hostlist, entries, scanner)
118
+ next unless found
115
119
 
116
120
  scanner.skip(/\s*/)
117
121
  type = scanner.scan(/\S+/)
@@ -127,6 +131,21 @@ module Net; module SSH
127
131
  keys
128
132
  end
129
133
 
134
+ # Indicates whether one of the entries matches an hostname that has been
135
+ # stored as a HMAC-SHA1 hash in the known hosts.
136
+ def known_host_hash?(hostlist, entries, scanner)
137
+ if hostlist.size == 1 && hostlist.first =~ /\A\|1(\|.+){2}\z/
138
+ chunks = hostlist.first.split(/\|/)
139
+ salt = Base64.decode64(chunks[2])
140
+ digest = OpenSSL::Digest.new('sha1')
141
+ entries.each do |entry|
142
+ hmac = OpenSSL::HMAC.digest(digest, salt, entry)
143
+ return true if Base64.encode64(hmac).chomp == chunks[3]
144
+ end
145
+ end
146
+ false
147
+ end
148
+
130
149
  # Tries to append an entry to the current source file for the given host
131
150
  # and key. If it is unable to (because the file is not writable, for
132
151
  # instance), an exception will be raised.
@@ -48,8 +48,9 @@ module Net; module SSH; module Proxy
48
48
 
49
49
  # Return a new socket connected to the given host and port via the
50
50
  # proxy that was requested when the socket factory was instantiated.
51
- def open(host, port, connection_options = nil)
52
- socket = TCPSocket.new(proxy_host, proxy_port)
51
+ def open(host, port, connection_options)
52
+ socket = Socket.tcp(proxy_host, proxy_port, nil, nil,
53
+ connect_timeout: connection_options[:timeout])
53
54
  socket.write "CONNECT #{host}:#{port} HTTP/1.0\r\n"
54
55
 
55
56
  if options[:user]
@@ -48,7 +48,8 @@ module Net
48
48
  # Return a new socket connected to the given host and port via the
49
49
  # proxy that was requested when the socket factory was instantiated.
50
50
  def open(host, port, connection_options)
51
- socket = TCPSocket.new(proxy_host, proxy_port)
51
+ socket = Socket.tcp(proxy_host, proxy_port, nil, nil,
52
+ connect_timeout: connection_options[:timeout])
52
53
  ip_addr = IPAddr.new(Resolv.getaddress(host))
53
54
 
54
55
  packet = [VERSION, CONNECT, port.to_i, ip_addr.to_i, options[:user]].pack("CCnNZ*")
@@ -62,8 +62,9 @@ module Net
62
62
 
63
63
  # Return a new socket connected to the given host and port via the
64
64
  # proxy that was requested when the socket factory was instantiated.
65
- def open(host, port, connection_options = nil)
66
- socket = TCPSocket.new(proxy_host, proxy_port)
65
+ def open(host, port, connection_options)
66
+ socket = Socket.tcp(proxy_host, proxy_port, nil, nil,
67
+ connect_timeout: connection_options[:timeout])
67
68
 
68
69
  methods = [METHOD_NO_AUTH]
69
70
  methods << METHOD_PASSWD if options[:user]
@@ -25,11 +25,11 @@ module Net; module SSH; module Transport
25
25
 
26
26
  # Instantiates a new ServerVersion and immediately (and synchronously)
27
27
  # negotiates the SSH protocol in effect, using the given socket.
28
- def initialize(socket, logger)
28
+ def initialize(socket, logger, timeout = nil)
29
29
  @header = ""
30
30
  @version = nil
31
31
  @logger = logger
32
- negotiate!(socket)
32
+ negotiate!(socket, timeout)
33
33
  end
34
34
 
35
35
  private
@@ -37,9 +37,12 @@ module Net; module SSH; module Transport
37
37
  # Negotiates the SSH protocol to use, via the given socket. If the server
38
38
  # reports an incompatible SSH version (e.g., SSH1), this will raise an
39
39
  # exception.
40
- def negotiate!(socket)
40
+ def negotiate!(socket, timeout)
41
41
  info { "negotiating protocol version" }
42
42
 
43
+ if timeout && !IO.select([socket], nil, nil, timeout)
44
+ raise Net::SSH::ConnectionTimeout, "timeout during server version negotiating"
45
+ end
43
46
  loop do
44
47
  @version = ""
45
48
  loop do
@@ -63,6 +66,9 @@ module Net; module SSH; module Transport
63
66
  raise Net::SSH::Exception, "incompatible SSH version `#{@version}'"
64
67
  end
65
68
 
69
+ if timeout && !IO.select(nil, [socket], nil, timeout)
70
+ raise Net::SSH::ConnectionTimeout, "timeout during client version negotiating"
71
+ end
66
72
  debug { "local is `#{PROTO_VERSION}'" }
67
73
  socket.write "#{PROTO_VERSION}\r\n"
68
74
  socket.flush
@@ -1,5 +1,4 @@
1
1
  require 'socket'
2
- require 'timeout'
3
2
 
4
3
  require 'net/ssh/errors'
5
4
  require 'net/ssh/loggable'
@@ -64,13 +63,13 @@ module Net; module SSH; module Transport
64
63
 
65
64
  debug { "establishing connection to #{@host}:#{@port}" }
66
65
 
67
- @socket = timeout(options[:timeout] || 0) do
66
+ @socket =
68
67
  if (factory = options[:proxy])
69
68
  factory.open(@host, @port, options)
70
69
  else
71
- TCPSocket.open(@host, @port, @bind_address)
70
+ Socket.tcp(@host, @port, @bind_address, nil,
71
+ connect_timeout: options[:timeout])
72
72
  end
73
- end
74
73
 
75
74
  @socket.extend(PacketStream)
76
75
  @socket.logger = @logger
@@ -82,7 +81,7 @@ module Net; module SSH; module Transport
82
81
  @host_key_verifier = select_host_key_verifier(options[:paranoid])
83
82
 
84
83
 
85
- @server_version = timeout(options[:timeout] || 0) { ServerVersion.new(socket, logger) }
84
+ @server_version = ServerVersion.new(socket, logger, options[:timeout])
86
85
 
87
86
  @algorithms = Algorithms.new(self, options)
88
87
  wait { algorithms.initialized? }
@@ -55,7 +55,7 @@ module Net; module SSH
55
55
 
56
56
  # The prerelease component of this version of the Net::SSH library
57
57
  # nil allowed
58
- PRE = 'beta1'
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 2.10.0.beta1 ruby lib
5
+ # stub: net-ssh 2.10.0.beta2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "net-ssh"
9
- s.version = "2.10.0.beta1"
9
+ s.version = "2.10.0.beta2"
10
10
 
11
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-05-21"
15
+ s.date = "2015-07-01"
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 = [
@@ -145,6 +145,7 @@ Gem::Specification.new do |s|
145
145
  "test/integration/playbook.yml",
146
146
  "test/integration/test_id_rsa_keys.rb",
147
147
  "test/known_hosts/github",
148
+ "test/known_hosts/github_hash",
148
149
  "test/manual/test_forward.rb",
149
150
  "test/manual/test_pageant.rb",
150
151
  "test/start/test_connection.rb",
@@ -56,6 +56,15 @@ module Authentication
56
56
  assert_equal({:from => :file, :file => second, :key => dsa}, manager.known_identities[dsa])
57
57
  end
58
58
 
59
+ def test_each_identity_should_not_prompt_for_passphrase_in_non_interactive_mode
60
+ manager(:non_interactive => true).stubs(:agent).returns(nil)
61
+ first = File.expand_path("/first")
62
+ stub_file_private_key first, rsa, :passphrase => :should_not_be_asked
63
+ identities = []
64
+ manager.each_identity { |identity| identities << identity }
65
+ assert_equal(identities, [])
66
+ end
67
+
59
68
  def test_identities_should_load_from_agent
60
69
  manager.stubs(:agent).returns(agent)
61
70
 
@@ -10,8 +10,14 @@ require 'net/ssh'
10
10
  class TestIDRSAPKeys < Test::Unit::TestCase
11
11
  include IntegrationTestHelpers
12
12
 
13
+ def tmpdir(&block)
14
+ Dir.mktmpdir do |dir|
15
+ yield(dir)
16
+ end
17
+ end
18
+
13
19
  def test_in_file_no_password
14
- Dir.mktmpdir do |dir| dir = "/tmp/test"
20
+ tmpdir do |dir|
15
21
  sh "rm -rf #{dir}/id_rsa #{dir}/id_rsa.pub"
16
22
  sh "ssh-keygen -f #{dir}/id_rsa -t rsa -N ''"
17
23
  set_authorized_key('net_ssh_1',"#{dir}/id_rsa.pub")
@@ -28,7 +34,7 @@ class TestIDRSAPKeys < Test::Unit::TestCase
28
34
 
29
35
 
30
36
  def test_ssh_agent
31
- Dir.mktmpdir do |dir| dir = "/tmp/test"
37
+ tmpdir do |dir|
32
38
  with_agent do
33
39
  sh "rm -rf #{dir}/id_rsa #{dir}/id_rsa.pub"
34
40
  sh "ssh-keygen -f #{dir}/id_rsa -t rsa -N 'pwd123'"
@@ -44,7 +50,7 @@ class TestIDRSAPKeys < Test::Unit::TestCase
44
50
  end
45
51
 
46
52
  def test_ssh_agent_ignores_if_already_in_agent
47
- Dir.mktmpdir do |dir| dir = "/tmp/test"
53
+ tmpdir do |dir|
48
54
  with_agent do
49
55
  sh "rm -rf #{dir}/id_rsa #{dir}/id_rsa.pub"
50
56
  sh "ssh-keygen -f #{dir}/id_rsa -t rsa -N 'pwd123'"
@@ -60,7 +66,7 @@ class TestIDRSAPKeys < Test::Unit::TestCase
60
66
  end
61
67
 
62
68
  def test_in_file_with_password
63
- Dir.mktmpdir do |dir| dir = "/tmp/test"
69
+ tmpdir do |dir|
64
70
  sh "rm -rf #{dir}/id_rsa #{dir}/id_rsa.pub"
65
71
  sh "ssh-keygen -f #{dir}/id_rsa -t rsa -N 'pwd12'"
66
72
  set_authorized_key('net_ssh_1',"#{dir}/id_rsa.pub")
@@ -0,0 +1 @@
1
+ |1|eKp+6E0rZ3lONgsIziurXEnaIik=|rcQB/rlJMUquUyFta64KugPjX4o= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
@@ -2,12 +2,20 @@ require 'common'
2
2
 
3
3
  class TestKnownHosts < Test::Unit::TestCase
4
4
 
5
- def test_key_for_when_all_hosts_are_recognized
6
- source = File.join(File.dirname(__FILE__),"known_hosts/github")
5
+ def perform_test(hostfile)
6
+ source = File.join(File.dirname(__FILE__), hostfile)
7
7
  kh = Net::SSH::KnownHosts.new(source)
8
8
  keys = kh.keys_for("github.com")
9
9
  assert_equal(1, keys.count)
10
10
  assert_equal("ssh-rsa", keys[0].ssh_type)
11
11
  end
12
12
 
13
- end
13
+ def test_key_for_when_all_hosts_are_recognized
14
+ perform_test("known_hosts/github")
15
+ end
16
+
17
+ def test_key_for_when_an_host_hash_is_recognized
18
+ perform_test("known_hosts/github_hash")
19
+ end
20
+
21
+ end
@@ -1,6 +1,7 @@
1
1
  # encoding: ASCII-8BIT
2
2
 
3
3
  require 'common'
4
+ require 'timeout'
4
5
  require 'net/ssh/transport/packet_stream'
5
6
 
6
7
  module Transport
@@ -315,7 +315,7 @@ module Transport
315
315
  def session(options={})
316
316
  @session ||= begin
317
317
  host = options.delete(:host) || "net.ssh.test"
318
- TCPSocket.stubs(:open).with(host, options[:port] || 22, nil).returns(socket)
318
+ Socket.stubs(:tcp).with(host, options[:port] || 22, nil, nil, { connect_timeout: options[:timeout] }).returns(socket)
319
319
  Net::SSH::Transport::ServerVersion.stubs(:new).returns(server_version)
320
320
  Net::SSH::Transport::Algorithms.stubs(:new).returns(algorithms)
321
321
 
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: 2.10.0.beta1
4
+ version: 2.10.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamis Buck
@@ -31,7 +31,7 @@ cert_chain:
31
31
  MbvRpzgROzyfw1qYi4dnIyMwTtXFFcZ0a2jpxHPkcTYFK6TzvFgDLAP0Y/u9jqUQ
32
32
  eZ7/3CdSi/isZHEw
33
33
  -----END CERTIFICATE-----
34
- date: 2015-05-21 00:00:00.000000000 Z
34
+ date: 2015-07-01 00:00:00.000000000 Z
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: test-unit
@@ -196,6 +196,7 @@ files:
196
196
  - test/integration/playbook.yml
197
197
  - test/integration/test_id_rsa_keys.rb
198
198
  - test/known_hosts/github
199
+ - test/known_hosts/github_hash
199
200
  - test/manual/test_forward.rb
200
201
  - test/manual/test_pageant.rb
201
202
  - test/start/test_connection.rb
metadata.gz.sig CHANGED
Binary file