net-ssh 2.5.2 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-