net-ssh 2.5.2 → 2.6.0

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.
@@ -1,4 +1,13 @@
1
1
 
2
+ === 2.6.0 / 19 Sep 2012
3
+
4
+ * Use OpenSSL::PKey.read to read arbitrary private key. [nagachika]
5
+ * Check availability of UNIXSocket and UNIXServer for Windows [Nobuhiro IMAI]
6
+ * Bump version to 2.5.3 and depend on newer jruby-pageant version for Java 1.5 compat. [arturaz]
7
+ * Implementation of the "none"-authentication method [dubspeed]
8
+ * Add class for stricter host key verification [Andy Brody]
9
+
10
+
2
11
  === 2.5.2 / 25 May 2012
3
12
 
4
13
  * Fix for Net::SSH::KnownHosts::SUPPORTED_TYPE [Marco Sandrini]
data/Manifest CHANGED
@@ -77,6 +77,7 @@ lib/net/ssh/transport/session.rb
77
77
  lib/net/ssh/transport/state.rb
78
78
  lib/net/ssh/verifiers/lenient.rb
79
79
  lib/net/ssh/verifiers/null.rb
80
+ lib/net/ssh/verifiers/secure.rb
80
81
  lib/net/ssh/verifiers/strict.rb
81
82
  lib/net/ssh/version.rb
82
83
  net-ssh.gemspec
@@ -1,7 +1,7 @@
1
1
  = Net::SSH
2
2
 
3
3
  * Docs: http://net-ssh.github.com/net-ssh
4
- * Issues: http://net-ssh.lighthouseapp.com/
4
+ * Issues: https://github.com/net-ssh/net-ssh/issues
5
5
  * Codes: http://github.com/net-ssh/net-ssh
6
6
  * Email: net-ssh@solutious.com
7
7
 
data/Rakefile CHANGED
@@ -1,14 +1,10 @@
1
1
  require 'rubygems'
2
+ require 'rubygems/package_task'
2
3
  require 'rake/clean'
3
- require 'rake/gempackagetask'
4
4
  require 'fileutils'
5
5
  include FileUtils
6
6
 
7
- begin
8
- require 'hanna/rdoctask'
9
- rescue LoadError
10
- require 'rdoc/task'
11
- end
7
+ require 'rdoc/task'
12
8
 
13
9
 
14
10
  task :default => :package
@@ -39,7 +35,7 @@ version = @spec.version
39
35
 
40
36
  # INSTALL =============================================================
41
37
 
42
- Rake::GemPackageTask.new(@spec) do |p|
38
+ Gem::PackageTask.new(@spec) do |p|
43
39
  p.need_tar = true if RUBY_PLATFORM !~ /mswin/
44
40
  end
45
41
 
@@ -74,15 +70,15 @@ end
74
70
 
75
71
  # RUBY DOCS TASK ==================================
76
72
 
77
- Rake::RDocTask.new do |t|
73
+ RDoc::Task.new do |t|
74
+ # this only works with RDoc 3.1 or greater
75
+ t.generator = 'hanna' # gem install hanna-nouveau
78
76
  t.rdoc_dir = 'doc'
79
77
  t.title = @spec.summary
80
- t.options << '--line-numbers' << '-A cattr_accessor=object'
81
- t.options << '--charset' << 'utf-8'
78
+ t.main = README
82
79
  t.rdoc_files.include(README)
83
80
  t.rdoc_files.include(CHANGES)
84
81
  t.rdoc_files.include(THANKS)
85
82
  t.rdoc_files.include(LICENSE)
86
83
  t.rdoc_files.include('lib/**/*.rb')
87
84
  end
88
-
@@ -133,8 +133,8 @@ module Net
133
133
  # option is intended for situations where ssh-agent offers many different
134
134
  # identites.
135
135
  # * :logger => the logger instance to use when logging
136
- # * :paranoid => either true, false, or :very, specifying how strict
137
- # host-key verification should be
136
+ # * :paranoid => either false, true, :very, or :secure specifying how
137
+ # strict host-key verification should be (in increasing order here)
138
138
  # * :passphrase => the passphrase to use when loading a private key (default
139
139
  # is +nil+, for no passphrase)
140
140
  # * :password => the password to use to login
@@ -41,7 +41,7 @@ module Net; module SSH; module Authentication
41
41
  self.logger = transport.logger
42
42
  @transport = transport
43
43
 
44
- @auth_methods = options[:auth_methods] || %w(publickey hostbased password keyboard-interactive)
44
+ @auth_methods = options[:auth_methods] || %w(none publickey hostbased password keyboard-interactive)
45
45
  @options = options
46
46
 
47
47
  @allowed_auth_methods = @auth_methods
@@ -318,7 +318,7 @@ module Net; module SSH
318
318
  def write_string(*text)
319
319
  text.each do |string|
320
320
  s = string.to_s
321
- write_long(s.length)
321
+ write_long(s.bytesize)
322
322
  write(s)
323
323
  end
324
324
  self
@@ -35,12 +35,10 @@ module Net; module SSH
35
35
  end
36
36
  end
37
37
 
38
- # Raised when the cached key for a particular host does not match the
39
- # key given by the host, which can be indicative of a man-in-the-middle
40
- # attack. When rescuing this exception, you can inspect the key fingerprint
41
- # and, if you want to proceed anyway, simply call the remember_host!
42
- # method on the exception, and then retry.
43
- class HostKeyMismatch < Exception
38
+ # Base class for host key exceptions. When rescuing this exception, you can
39
+ # inspect the key fingerprint and, if you want to proceed anyway, simply call
40
+ # the remember_host! method on the exception, and then retry.
41
+ class HostKeyError < Exception
44
42
  # the callback to use when #remember_host! is called
45
43
  attr_writer :callback #:nodoc:
46
44
 
@@ -85,4 +83,18 @@ module Net; module SSH
85
83
  @callback.call
86
84
  end
87
85
  end
88
- end; end
86
+
87
+ # Raised when the cached key for a particular host does not match the
88
+ # key given by the host, which can be indicative of a man-in-the-middle
89
+ # attack. When rescuing this exception, you can inspect the key fingerprint
90
+ # and, if you want to proceed anyway, simply call the remember_host!
91
+ # method on the exception, and then retry.
92
+ class HostKeyMismatch < HostKeyError; end
93
+
94
+ # Raised when there is no cached key for a particular host, which probably
95
+ # means that the host has simply not been seen before.
96
+ # When rescuing this exception, you can inspect the key fingerprint and, if
97
+ # you want to proceed anyway, simply call the remember_host! method on the
98
+ # exception, and then retry.
99
+ class HostKeyUnknown < HostKeyError; end
100
+ end; end
@@ -48,24 +48,37 @@ module Net; module SSH
48
48
  # encrypted (requiring a passphrase to use), the user will be
49
49
  # prompted to enter their password unless passphrase works.
50
50
  def load_data_private_key(data, passphrase=nil, ask_passphrase=true, filename="")
51
- if data.match(/-----BEGIN DSA PRIVATE KEY-----/)
52
- key_type = OpenSSL::PKey::DSA
53
- elsif data.match(/-----BEGIN RSA PRIVATE KEY-----/)
54
- key_type = OpenSSL::PKey::RSA
55
- elsif data.match(/-----BEGIN EC PRIVATE KEY-----/) && defined?(OpenSSL::PKey::EC)
56
- key_type = OpenSSL::PKey::EC
57
- elsif data.match(/-----BEGIN (.*) PRIVATE KEY-----/)
58
- raise OpenSSL::PKey::PKeyError, "not a supported key type '#{$1}'"
51
+ if OpenSSL::PKey.respond_to?(:read)
52
+ pkey_read = true
53
+ error_class = ArgumentError
59
54
  else
60
- raise OpenSSL::PKey::PKeyError, "not a private key (#{filename})"
55
+ pkey_read = false
56
+ if data.match(/-----BEGIN DSA PRIVATE KEY-----/)
57
+ key_type = OpenSSL::PKey::DSA
58
+ error_class = OpenSSL::PKey::DSAError
59
+ elsif data.match(/-----BEGIN RSA PRIVATE KEY-----/)
60
+ key_type = OpenSSL::PKey::RSA
61
+ error_class = OpenSSL::PKey::RSAError
62
+ elsif data.match(/-----BEGIN EC PRIVATE KEY-----/) && defined?(OpenSSL::PKey::EC)
63
+ key_type = OpenSSL::PKey::EC
64
+ error_class = OpenSSL::PKey::RCError
65
+ elsif data.match(/-----BEGIN (.+) PRIVATE KEY-----/)
66
+ raise OpenSSL::PKey::PKeyError, "not a supported key type '#{$1}'"
67
+ else
68
+ raise OpenSSL::PKey::PKeyError, "not a private key (#{filename})"
69
+ end
61
70
  end
62
71
 
63
72
  encrypted_key = data.match(/ENCRYPTED/)
64
73
  tries = 0
65
74
 
66
75
  begin
67
- return key_type.new(data, passphrase || 'invalid')
68
- rescue OpenSSL::PKey::RSAError, OpenSSL::PKey::DSAError, OpenSSL::PKey::ECError => e
76
+ if pkey_read
77
+ return OpenSSL::PKey.read(data, passphrase || 'invalid')
78
+ else
79
+ return key_type.new(data, passphrase || 'invalid')
80
+ end
81
+ rescue error_class
69
82
  if encrypted_key && ask_passphrase
70
83
  tries += 1
71
84
  if tries <= 3
@@ -57,7 +57,7 @@ module Net; module SSH; module Service
57
57
  local_port_type = :long
58
58
 
59
59
  socket = begin
60
- if args.first.class == UNIXServer
60
+ if defined?(UNIXServer) and args.first.class == UNIXServer
61
61
  local_port_type = :string
62
62
  args.shift
63
63
  else
@@ -120,18 +120,18 @@ module Net; module SSH; module Transport
120
120
  payload = client.compress(payload)
121
121
 
122
122
  # the length of the packet, minus the padding
123
- actual_length = 4 + payload.length + 1
123
+ actual_length = 4 + payload.bytesize + 1
124
124
 
125
125
  # compute the padding length
126
126
  padding_length = client.block_size - (actual_length % client.block_size)
127
127
  padding_length += client.block_size if padding_length < 4
128
128
 
129
129
  # compute the packet length (sans the length field itself)
130
- packet_length = payload.length + padding_length + 1
130
+ packet_length = payload.bytesize + padding_length + 1
131
131
 
132
132
  if packet_length < 16
133
133
  padding_length += client.block_size
134
- packet_length = payload.length + padding_length + 1
134
+ packet_length = payload.bytesize + padding_length + 1
135
135
  end
136
136
 
137
137
  padding = Array.new(padding_length) { rand(256) }.pack("C*")
@@ -9,6 +9,7 @@ require 'net/ssh/transport/constants'
9
9
  require 'net/ssh/transport/packet_stream'
10
10
  require 'net/ssh/transport/server_version'
11
11
  require 'net/ssh/verifiers/null'
12
+ require 'net/ssh/verifiers/secure'
12
13
  require 'net/ssh/verifiers/strict'
13
14
  require 'net/ssh/verifiers/lenient'
14
15
 
@@ -255,8 +256,9 @@ module Net; module SSH; module Transport
255
256
  # Instantiates a new host-key verification class, based on the value of
256
257
  # the parameter. When true or nil, the default Lenient verifier is
257
258
  # returned. If it is false, the Null verifier is returned, and if it is
258
- # :very, the Strict verifier is returned. If the argument happens to
259
- # respond to :verify, it is returned directly. Otherwise, an exception
259
+ # :very, the Strict verifier is returned. If it is :secure, the even more
260
+ # strict Secure verifier is returned. If the argument happens to respond
261
+ # to :verify, it is returned directly. Otherwise, an exception
260
262
  # is raised.
261
263
  def select_host_key_verifier(paranoid)
262
264
  case paranoid
@@ -266,6 +268,8 @@ module Net; module SSH; module Transport
266
268
  Net::SSH::Verifiers::Null.new
267
269
  when :very then
268
270
  Net::SSH::Verifiers::Strict.new
271
+ when :secure then
272
+ Net::SSH::Verifiers::Secure.new
269
273
  else
270
274
  if paranoid.respond_to?(:verify)
271
275
  paranoid
@@ -0,0 +1,54 @@
1
+ require 'net/ssh/errors'
2
+ require 'net/ssh/known_hosts'
3
+
4
+ module Net; module SSH; module Verifiers
5
+
6
+ # Does a strict host verification, looking the server up in the known
7
+ # host files to see if a key has already been seen for this server. If this
8
+ # server does not appear in any host file, an exception will be raised
9
+ # (HostKeyUnknown). This is in contrast to the "Strict" class, which will
10
+ # silently add the key to your known_hosts file. If the server does appear at
11
+ # least once, but the key given does not match any known for the server, an
12
+ # exception will be raised (HostKeyMismatch).
13
+ # Otherwise, this returns true.
14
+ class Secure
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)
19
+
20
+ # We've never seen this host before, so raise an exception.
21
+ if matches.empty?
22
+ process_cache_miss(host, arguments, HostKeyUnknown, "is unknown")
23
+ end
24
+
25
+ # If we found any matches, check to see that the key type and
26
+ # blob also match.
27
+ found = matches.any? do |key|
28
+ key.ssh_type == arguments[:key].ssh_type &&
29
+ key.to_blob == arguments[:key].to_blob
30
+ end
31
+
32
+ # If a match was found, return true. Otherwise, raise an exception
33
+ # indicating that the key was not recognized.
34
+ unless found
35
+ process_cache_miss(host, arguments, HostKeyMismatch, "does not match")
36
+ end
37
+
38
+ found
39
+ end
40
+
41
+ private
42
+
43
+ def process_cache_miss(host, args, exc_class, message)
44
+ exception = exc_class.new("fingerprint #{args[:fingerprint]} " +
45
+ "#{message} for #{host.inspect}")
46
+ exception.data = args
47
+ exception.callback = Proc.new do
48
+ Net::SSH::KnownHosts.add(host, args[:key], args[:session].options)
49
+ end
50
+ raise exception
51
+ end
52
+ end
53
+
54
+ end; end; end
@@ -1,5 +1,6 @@
1
1
  require 'net/ssh/errors'
2
2
  require 'net/ssh/known_hosts'
3
+ require 'net/ssh/verifiers/secure'
3
4
 
4
5
  module Net; module SSH; module Verifiers
5
6
 
@@ -9,45 +10,15 @@ module Net; module SSH; module Verifiers
9
10
  # server. If the server does appear at least once, but the key given does
10
11
  # not match any known for the server, an exception will be raised (HostKeyMismatch).
11
12
  # Otherwise, this returns true.
12
- class Strict
13
+ class Strict < Secure
13
14
  def verify(arguments)
14
- options = arguments[:session].options
15
- host = options[:host_key_alias] || arguments[:session].host_as_string
16
- matches = Net::SSH::KnownHosts.search_for(host, arguments[:session].options)
17
-
18
- # we've never seen this host before, so just automatically add the key.
19
- # not the most secure option (since the first hit might be the one that
20
- # is hacked), but since almost nobody actually compares the key
21
- # fingerprint, this is a reasonable compromise between usability and
22
- # security.
23
- if matches.empty?
24
- ip = arguments[:session].peer[:ip]
25
- Net::SSH::KnownHosts.add(host, arguments[:key], arguments[:session].options)
15
+ begin
16
+ super
17
+ rescue HostKeyUnknown => err
18
+ err.remember_host!
26
19
  return true
27
20
  end
28
-
29
- # If we found any matches, check to see that the key type and
30
- # blob also match.
31
- found = matches.any? do |key|
32
- key.ssh_type == arguments[:key].ssh_type &&
33
- key.to_blob == arguments[:key].to_blob
34
- end
35
-
36
- # If a match was found, return true. Otherwise, raise an exception
37
- # indicating that the key was not recognized.
38
- found || process_cache_miss(host, arguments)
39
21
  end
40
-
41
- private
42
-
43
- def process_cache_miss(host, args)
44
- exception = HostKeyMismatch.new("fingerprint #{args[:fingerprint]} does not match for #{host.inspect}")
45
- exception.data = args
46
- exception.callback = Proc.new do
47
- Net::SSH::KnownHosts.add(host, args[:key], args[:session].options)
48
- end
49
- raise exception
50
- end
51
22
  end
52
23
 
53
- end; end; end
24
+ end; end; end
@@ -48,10 +48,10 @@ module Net; module SSH
48
48
  MAJOR = 2
49
49
 
50
50
  # The minor component of this version of the Net::SSH library
51
- MINOR = 5
51
+ MINOR = 6
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 current version of the Net::SSH library as a Version instance
57
57
  CURRENT = new(MAJOR, MINOR, TINY)
@@ -1,7 +1,7 @@
1
1
  @spec = Gem::Specification.new do |s|
2
2
  s.name = "net-ssh"
3
3
  s.rubyforge_project = 'net-ssh'
4
- s.version = "2.5.2"
4
+ s.version = "2.6.0"
5
5
  s.summary = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
6
6
  s.description = s.summary + " It allows you to write programs that invoke and interact with processes on remote servers, via SSH2."
7
7
  s.authors = ["Jamis Buck", "Delano Mandelbaum"]
@@ -14,12 +14,10 @@
14
14
  s.require_paths = %w[lib]
15
15
  s.rubygems_version = '1.3.2'
16
16
 
17
- if RUBY_PLATFORM == "java"
18
- # This has two flavours with java one actually doing something and other
19
- # one just raising error. This is a workaround for no ability to specify
20
- # platform specific dependencies in gemspecs.
21
- s.add_dependency 'jruby-pageant', ">=1.0.2"
22
- end
17
+ # This has two flavours with java one actually doing something and other
18
+ # one just raising error. This is a workaround for no ability to specify
19
+ # platform specific dependencies in gemspecs.
20
+ s.add_dependency 'jruby-pageant', ">=1.1.1"
23
21
 
24
22
  s.executables = %w[]
25
23
 
@@ -107,6 +105,7 @@
107
105
  lib/net/ssh/transport/state.rb
108
106
  lib/net/ssh/verifiers/lenient.rb
109
107
  lib/net/ssh/verifiers/null.rb
108
+ lib/net/ssh/verifiers/secure.rb
110
109
  lib/net/ssh/verifiers/strict.rb
111
110
  lib/net/ssh/version.rb
112
111
  net-ssh.gemspec
@@ -8,7 +8,7 @@ module Authentication
8
8
  include Net::SSH::Authentication::Constants
9
9
 
10
10
  def test_constructor_should_set_defaults
11
- assert_equal %w(publickey hostbased password keyboard-interactive), session.auth_methods
11
+ assert_equal %w(none publickey hostbased password keyboard-interactive), session.auth_methods
12
12
  assert_equal session.auth_methods, session.allowed_auth_methods
13
13
  end
14
14
 
@@ -21,6 +21,7 @@ module Authentication
21
21
 
22
22
  Net::SSH::Authentication::Methods::Publickey.any_instance.expects(:authenticate).with("next service", "username", "password").raises(Net::SSH::Authentication::DisallowedMethod)
23
23
  Net::SSH::Authentication::Methods::Hostbased.any_instance.expects(:authenticate).with("next service", "username", "password").returns(true)
24
+ Net::SSH::Authentication::Methods::None.any_instance.expects(:authenticate).with("next service", "username", "password").returns(false)
24
25
 
25
26
  assert session.authenticate("next service", "username", "password")
26
27
  end
@@ -46,7 +47,8 @@ module Authentication
46
47
  Net::SSH::Authentication::Methods::Hostbased.any_instance.expects(:authenticate).with("next service", "username", "password").returns(false)
47
48
  Net::SSH::Authentication::Methods::Password.any_instance.expects(:authenticate).with("next service", "username", "password").returns(false)
48
49
  Net::SSH::Authentication::Methods::KeyboardInteractive.any_instance.expects(:authenticate).with("next service", "username", "password").returns(false)
49
-
50
+ Net::SSH::Authentication::Methods::None.any_instance.expects(:authenticate).with("next service", "username", "password").returns(false)
51
+
50
52
  assert_equal false, session.authenticate("next service", "username", "password")
51
53
  end
52
54
 
@@ -128,7 +128,7 @@ class TestForward < Test::Unit::TestCase
128
128
  tempfile.delete
129
129
  yield UNIXServer.open(path)
130
130
  File.delete(path)
131
- end
131
+ end if defined?(UNIXServer)
132
132
 
133
133
  def test_forward_local_unix_socket_to_remote_port
134
134
  session = Net::SSH.start(*ssh_start_params)
@@ -157,7 +157,7 @@ class TestForward < Test::Unit::TestCase
157
157
 
158
158
  assert_not_nil(client_data, "client should have received data")
159
159
  assert(client_data.match(/item\d/), 'client should have received the string item')
160
- end
160
+ end if defined?(UNIXSocket)
161
161
 
162
162
  def test_loop_should_not_abort_when_server_side_of_forward_is_closed
163
163
  session = Net::SSH.start(*ssh_start_params)
@@ -29,6 +29,11 @@ class TestBuffer < Test::Unit::TestCase
29
29
  assert_equal "\1\2\3\4\5", buffer.to_s
30
30
  end
31
31
 
32
+ def test_from_should_measure_bytesize_of_utf_8_string_correctly
33
+ buffer = Net::SSH::Buffer.from(:string, "\u2603") # Snowman is 3 bytes
34
+ assert_equal "\0\0\0\3\u2603", buffer.to_s
35
+ end
36
+
32
37
  def test_read_without_argument_should_read_to_end
33
38
  buffer = new("hello world")
34
39
  assert_equal "hello world", buffer.read
@@ -41,13 +41,23 @@ class TestKeyFactory < Test::Unit::TestCase
41
41
  def test_load_encrypted_private_key_should_give_three_tries_for_the_password_and_then_raise_exception
42
42
  File.expects(:read).with(@key_file).returns(encrypted(rsa_key, "password"))
43
43
  Net::SSH::KeyFactory.expects(:prompt).times(3).with("Enter passphrase for #{@key_file}:", false).returns("passwod","passphrase","passwd")
44
- assert_raises(OpenSSL::PKey::RSAError) { Net::SSH::KeyFactory.load_private_key(@key_file) }
44
+ if OpenSSL::PKey.respond_to?(:read)
45
+ error_class = ArgumentError
46
+ else
47
+ error_class = OpenSSL::PKey::RSAError
48
+ end
49
+ assert_raises(error_class) { Net::SSH::KeyFactory.load_private_key(@key_file) }
45
50
  end
46
51
 
47
52
  def test_load_encrypted_private_key_should_raise_exception_without_asking_passphrase
48
53
  File.expects(:read).with(@key_file).returns(encrypted(rsa_key, "password"))
49
54
  Net::SSH::KeyFactory.expects(:prompt).never
50
- assert_raises(OpenSSL::PKey::RSAError) { Net::SSH::KeyFactory.load_private_key(@key_file, nil, false) }
55
+ if OpenSSL::PKey.respond_to?(:read)
56
+ error_class = ArgumentError
57
+ else
58
+ error_class = OpenSSL::PKey::RSAError
59
+ end
60
+ assert_raises(error_class) { Net::SSH::KeyFactory.load_private_key(@key_file, nil, false) }
51
61
  end
52
62
 
53
63
  def test_load_public_rsa_key_should_return_key
@@ -83,6 +93,15 @@ class TestKeyFactory < Test::Unit::TestCase
83
93
  end
84
94
  end
85
95
 
96
+ def test_load_anonymous_private_key_should_return_key_or_raise_exception
97
+ File.expects(:read).with(@key_file).returns(anonymous_private_key)
98
+ if OpenSSL::PKey.respond_to?(:read)
99
+ assert_equal OpenSSL::PKey::RSA.new(anonymous_private_key).to_der, Net::SSH::KeyFactory.load_private_key(@key_file).to_der
100
+ else
101
+ assert_raises(OpenSSL::PKey::PKeyError) { Net::SSH::KeyFactory.load_private_key(@key_file) }
102
+ end
103
+ end
104
+
86
105
  private
87
106
 
88
107
  def rsa_key
@@ -109,6 +128,39 @@ class TestKeyFactory < Test::Unit::TestCase
109
128
  end
110
129
  end
111
130
 
131
+ def anonymous_private_key
132
+ @anonymous_key = <<-EOF
133
+ -----BEGIN PRIVATE KEY-----
134
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC3id5gZ6bglJth
135
+ yli8JNaRxhsqKwwPlReEI/mplzz5IP6gWQ92LogXbdBXtHf9ZpA53BeLmtcNBEY0
136
+ Ygd7sPBhlHABS5D5///zltSSX2+L5GCEiC6dpfGsySjqymWF+SZ2PaqfZbkWLmCD
137
+ 9u4ysueaHf7xbF6txGprNp69efttWxdy+vU5tno7HVxemMZQUalpShFrdAYKKXEo
138
+ cV7MtbkQjzubS14gaWGpWCXIl9uNKQeHpLKtre1Qn5Ft/zVpCHmhLQcYDuB1LAj9
139
+ 7eoev4rIiOE2sfdkvKDlmFxvzq3myYH4o27WwAg9OZ5SBusn2zesKkRCBBEZ55rl
140
+ uVknOGHXAgMBAAECggEAZE0U2OxsNxkfXS6+lXswQ5PW7pF90towcsdSPgrniGIu
141
+ pKRnHbfKKbuaewOl+zZcpTIRL/rbgUKPtzrHSiJlC36aQyrvvJ/ZWV5ZJvC+vd19
142
+ nY/qob65NyrrkHwxRSjmiwGiR9/IaUXI+vUsMUqx5Ph1hawqhZ3sZlEAKR4LeDO8
143
+ M+OguG77jLaqj5/SNfi+GwyUDe85de4VfEG4S9HrMQk2Cp66rx0BqDnCLacyFQaI
144
+ R0VczMXTU52q0uETmgUr8G9A1SaRc5ZWKAfZwxJTvqdIImWC9E+CY7wm+mZD4FE6
145
+ iVzVC0ngcdEd596kTDdU2BPVMluWzLkfqIrTt/5CeQKBgQDzgRzCPNxFtai6RAIi
146
+ ekBSHqrDnrbeTaw32GVq5ACk1Zfk2I0svctz1iQ9qJ2SRINpygQhcyJKQ4r/LXi1
147
+ 7Av9H/d6QV4T2AZzS4WcqBkxxRXFUfARtnKChzuCzNt9tNz4EZiv75RyQmztGZjV
148
+ i94+ZvCyqup5be4Svf4MBxin9QKBgQDA9P4nHzFWZakTMei78LGb/4Auc+r0rZp7
149
+ 8xg8Z92tvrDeJjMdesdhiFrPP1qiSYHnQ81MSWpn6BycBsHZqitejQmYnYput/s4
150
+ qG+m7SrkN8WL6rijYsbB+U14VDjMlBlOgcEgjlSNU2oeS+68u+uVI/fgyXcXn4Jq
151
+ 33TSWSgfGwKBgA2tRdE/G9wqfOShZ0FKfoxePpcoNfs8f5zPYbrkPYkEmjh3VU6b
152
+ Bm9mKrjv3JHXmU3608qRLe7f5lG42xvUu0OnZP4P59nTe2FEb6fB5VBfUn63wHUu
153
+ OzZLpDMPkJB59SNV0a6oFT1pr7aNhoEQDxaQL5rJcMwLOaEB3OAOEft1AoGASz7+
154
+ 4Zi7b7rDPVYIMUpCqNfxT6wqovIUPWPmPqAuhXPIm0kAQ+2+VN2MtCc7m+/Ydawu
155
+ IiK7GPweNAY6kDxZH00WweolstmSYVzl9Y2lXUwWgGKvUB/T7I7g1Bzb7YOPftsA
156
+ ykZW2Kn/xwLLfdQ2oXleT82g4Jh2jmDHuMPF7qMCgYEA6QF45PvOgnrJessgmwO/
157
+ dEmkLl07PQYJPGZLaZteuWrvfMrn+AiW5aAdHzhzNaOtNy5B3T7zGUHtgxXegqgd
158
+ /QdCVCJgnZUO/zdAxkr22dDn+WEXkL4wgBVStQvvnQp9C2NJcoOExvex5PLzKWQg
159
+ WEKt5v3QsUEgVrzkM4K9UbI=
160
+ -----END PRIVATE KEY-----
161
+ EOF
162
+ end
163
+
112
164
  def encrypted(key, password)
113
165
  key.export(OpenSSL::Cipher::Cipher.new("des-ede3-cbc"), password)
114
166
  end
@@ -165,6 +165,14 @@ module Transport
165
165
  assert_equal 24, stream.write_buffer.length
166
166
  end
167
167
 
168
+ def test_enqueue_utf_8_packet_should_ensure_packet_length_is_in_bytes_and_multiple_of_block_length
169
+ packet = Net::SSH::Buffer.from(:string, "\u2603") # Snowman is 3 bytes
170
+ stream.enqueue_packet(packet)
171
+ # When bytesize is measured wrong using length, the result is off by 2.
172
+ # With length instead of bytesize, you get 26 length buffer.
173
+ assert_equal 0, stream.write_buffer.length % 8
174
+ end
175
+
168
176
  PACKETS = {
169
177
  "3des-cbc" => {
170
178
  "hmac-md5" => {
@@ -28,6 +28,10 @@ module Transport
28
28
  assert_instance_of Net::SSH::Verifiers::Strict, session(:paranoid => :very).host_key_verifier
29
29
  end
30
30
 
31
+ def test_paranoid_secure_uses_secure_verifier
32
+ assert_instance_of Net::SSH::Verifiers::Secure, session(:paranoid => :secure).host_key_verifier
33
+ end
34
+
31
35
  def test_paranoid_false_uses_null_verifier
32
36
  assert_instance_of Net::SSH::Verifiers::Null, session(:paranoid => false).host_key_verifier
33
37
  end
@@ -312,4 +316,4 @@ module Transport
312
316
  alias session! session
313
317
  end
314
318
 
315
- end
319
+ end
metadata CHANGED
@@ -1,31 +1,40 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: net-ssh
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.6.0
4
5
  prerelease:
5
- version: 2.5.2
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Jamis Buck
9
9
  - Delano Mandelbaum
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
-
14
- date: 2012-05-25 00:00:00 Z
15
- dependencies: []
16
-
17
- 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."
18
- email:
13
+ date: 2012-09-19 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: jruby-pageant
17
+ requirement: &70132399474300 !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: 1.1.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: *70132399474300
26
+ description: ! 'Net::SSH: a pure-Ruby implementation of the SSH2 client protocol.
27
+ It allows you to write programs that invoke and interact with processes on remote
28
+ servers, via SSH2.'
29
+ email:
19
30
  - net-ssh@solutious.com
20
31
  executables: []
21
-
22
32
  extensions: []
23
-
24
- extra_rdoc_files:
33
+ extra_rdoc_files:
25
34
  - README.rdoc
26
35
  - THANKS.rdoc
27
36
  - CHANGELOG.rdoc
28
- files:
37
+ files:
29
38
  - CHANGELOG.rdoc
30
39
  - Manifest
31
40
  - README.rdoc
@@ -108,6 +117,7 @@ files:
108
117
  - lib/net/ssh/transport/state.rb
109
118
  - lib/net/ssh/verifiers/lenient.rb
110
119
  - lib/net/ssh/verifiers/null.rb
120
+ - lib/net/ssh/verifiers/secure.rb
111
121
  - lib/net/ssh/verifiers/strict.rb
112
122
  - lib/net/ssh/version.rb
113
123
  - net-ssh.gemspec
@@ -170,34 +180,31 @@ files:
170
180
  - test/transport/test_state.rb
171
181
  homepage: http://github.com/net-ssh/net-ssh
172
182
  licenses: []
173
-
174
183
  post_install_message:
175
- rdoc_options:
184
+ rdoc_options:
176
185
  - --line-numbers
177
186
  - --title
178
- - "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
187
+ - ! 'Net::SSH: a pure-Ruby implementation of the SSH2 client protocol.'
179
188
  - --main
180
189
  - README.rdoc
181
- require_paths:
190
+ require_paths:
182
191
  - lib
183
- required_ruby_version: !ruby/object:Gem::Requirement
192
+ required_ruby_version: !ruby/object:Gem::Requirement
184
193
  none: false
185
- requirements:
186
- - - ">="
187
- - !ruby/object:Gem::Version
188
- version: "0"
189
- required_rubygems_version: !ruby/object:Gem::Requirement
194
+ requirements:
195
+ - - ! '>='
196
+ - !ruby/object:Gem::Version
197
+ version: '0'
198
+ required_rubygems_version: !ruby/object:Gem::Requirement
190
199
  none: false
191
- requirements:
192
- - - ">="
193
- - !ruby/object:Gem::Version
194
- version: "0"
200
+ requirements:
201
+ - - ! '>='
202
+ - !ruby/object:Gem::Version
203
+ version: '0'
195
204
  requirements: []
196
-
197
205
  rubyforge_project: net-ssh
198
206
  rubygems_version: 1.8.10
199
207
  signing_key:
200
208
  specification_version: 3
201
- summary: "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
209
+ summary: ! 'Net::SSH: a pure-Ruby implementation of the SSH2 client protocol.'
202
210
  test_files: []
203
-