net-ssh 2.1.0 → 2.1.3

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,9 +1,21 @@
1
1
 
2
2
 
3
+ === 2.1.3 / 2 Mar 2011
4
+
5
+ * Call to transport.closed should be transport.close [Woon Jung]
6
+
7
+
8
+ === 2.1.2 / 1 Mar 2011
9
+
10
+ * Fix for Net::SSH Continues to attempt authentication when notified it is not allowed [Eric Hodel]
11
+ (see: http://net-ssh.lighthouseapp.com/projects/36253-net-ssh/tickets/26)
12
+ * Fix for transport won't be closed if authentication fails [Patrick Marchi]
13
+
14
+
3
15
  === 2.1 / 19 Jan 2011
4
16
 
5
- * Support "IdentitiesOnly" directive [Edmund Haselwanter]
6
- * Speeding up the Loggable module [robbebob]
17
+ * Support "IdentitiesOnly" directive (LH-24) [Musy Bite, Edmund Haselwanter]
18
+ * Speeding up the Loggable module (LH-23) [robbebob]
7
19
 
8
20
 
9
21
  === 2.0.24 / 14 Jan 2011
@@ -117,6 +117,47 @@ which should produce the following:
117
117
  arcfour512: [64, 8] OpenSSL::Cipher::Cipher
118
118
 
119
119
 
120
+ == RUNNING TESTS
121
+
122
+ Run the test suite from the net-ssh directory with the following command:
123
+
124
+ ruby -Ilib -Itest -rrubygems test/test_all.rb
125
+
126
+ Run a single test file like this:
127
+
128
+ ruby -Ilib -Itest -rrubygems test/transport/test_server_version.rb
129
+
130
+
131
+ === EXPECTED RESULTS
132
+
133
+ * Ruby 1.8: all tests pass
134
+
135
+ * Ruby 1.9: all tests pass
136
+
137
+ * JRuby 1.5: 99% tests pass (448 tests, 1846 assertions, 1 failures)
138
+
139
+
140
+ === PORT FORWARDING TESTS
141
+
142
+ ruby -Ilib -Itest -rrubygems test/manual/test_forward.rb
143
+
144
+ test_forward.rb must be run separately from the test suite because
145
+ it requires authorizing your public SSH keys on you localhost.
146
+
147
+ If you already have keys you can do this:
148
+
149
+ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
150
+
151
+ If you don't have keys see:
152
+
153
+ http://kimmo.suominen.com/docs/ssh/#ssh-keygen
154
+
155
+ You should now be able to login to your localhost with out
156
+ bring prompted for a password:
157
+
158
+ ssh localhost
159
+
160
+
120
161
  == LICENSE:
121
162
 
122
163
  (The MIT License)
data/Rakefile CHANGED
@@ -57,7 +57,7 @@ end
57
57
  if @spec.rubyforge_project
58
58
  desc 'Publish website to rubyforge'
59
59
  task 'publish:rdoc' => 'doc/index.html' do
60
- sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/ssh/v2/api/"
60
+ sh "scp -r doc/* rubyforge.org:/var/www/gforge-projects/#{name}/ssh/v2/api/"
61
61
  end
62
62
 
63
63
  desc 'Public release to rubyforge'
@@ -193,6 +193,7 @@ module Net
193
193
  return connection
194
194
  end
195
195
  else
196
+ transport.close
196
197
  raise AuthenticationFailed, user
197
198
  end
198
199
  end
@@ -135,7 +135,7 @@ module Net
135
135
  if info[:key].nil? && info[:from] == :file
136
136
  begin
137
137
  info[:key] = KeyFactory.load_private_key(info[:file], options[:passphrase])
138
- rescue Exception => e
138
+ rescue Exception, OpenSSL::OpenSSLError => e
139
139
  raise KeyManagerError, "the given identity is known, but the private key could not be loaded: #{e.class} (#{e.message})"
140
140
  end
141
141
  end
@@ -51,6 +51,10 @@ module Net
51
51
  return true
52
52
  when USERAUTH_FAILURE
53
53
  info { "hostbased failed (#{identity.fingerprint})" }
54
+
55
+ raise Net::SSH::Authentication::DisallowedMethod unless
56
+ message[:authentications].split(/,/).include? 'hostbased'
57
+
54
58
  return false
55
59
  else
56
60
  raise Net::SSH::Exception, "unexpected server response to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
@@ -27,6 +27,10 @@ module Net
27
27
  return true
28
28
  when USERAUTH_FAILURE
29
29
  debug { "keyboard-interactive failed" }
30
+
31
+ raise Net::SSH::Authentication::DisallowedMethod unless
32
+ message[:authentications].split(/,/).include? 'keyboard-interactive'
33
+
30
34
  return false
31
35
  when USERAUTH_INFO_REQUEST
32
36
  name = message.read_string
@@ -23,6 +23,10 @@ module Net
23
23
  return true
24
24
  when USERAUTH_FAILURE
25
25
  debug { "password failed" }
26
+
27
+ raise Net::SSH::Authentication::DisallowedMethod unless
28
+ message[:authentications].split(/,/).include? 'password'
29
+
26
30
  return false
27
31
  when USERAUTH_PASSWD_CHANGEREQ
28
32
  debug { "password change request received, failing" }
@@ -70,6 +70,10 @@ module Net
70
70
  return true
71
71
  when USERAUTH_FAILURE
72
72
  debug { "publickey failed (#{identity.fingerprint})" }
73
+
74
+ raise Net::SSH::Authentication::DisallowedMethod unless
75
+ message[:authentications].split(/,/).include? 'publickey'
76
+
73
77
  return false
74
78
  else
75
79
  raise Net::SSH::Exception,
@@ -9,6 +9,10 @@ require 'net/ssh/authentication/methods/keyboard_interactive'
9
9
 
10
10
  module Net; module SSH; module Authentication
11
11
 
12
+ # Raised if the current authentication method is not allowed
13
+ class DisallowedMethod < Net::SSH::Exception
14
+ end
15
+
12
16
  # Represents an authentication session. It manages the authentication of
13
17
  # a user over an established connection (the "transport" object, see
14
18
  # Net::SSH::Transport::Session).
@@ -59,13 +63,16 @@ module Net; module SSH; module Authentication
59
63
  attempted = []
60
64
 
61
65
  @auth_methods.each do |name|
62
- next unless @allowed_auth_methods.include?(name)
63
- attempted << name
66
+ begin
67
+ next unless @allowed_auth_methods.include?(name)
68
+ attempted << name
64
69
 
65
- debug { "trying #{name}" }
66
- method = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join).new(self, :key_manager => key_manager)
70
+ debug { "trying #{name}" }
71
+ method = Methods.const_get(name.split(/\W+/).map { |p| p.capitalize }.join).new(self, :key_manager => key_manager)
67
72
 
68
- return true if method.authenticate(next_service, username, password)
73
+ return true if method.authenticate(next_service, username, password)
74
+ rescue Net::SSH::Authentication::DisallowedMethod
75
+ end
69
76
  end
70
77
 
71
78
  error { "all authorization methods failed (tried #{attempted.join(', ')})" }
@@ -131,4 +138,4 @@ module Net; module SSH; module Authentication
131
138
  Array(options[:key_data])
132
139
  end
133
140
  end
134
- end; end; end
141
+ end; end; end
@@ -51,7 +51,7 @@ module Net; module SSH
51
51
  MINOR = 1
52
52
 
53
53
  # The tiny component of this version of the Net::SSH library
54
- TINY = 0
54
+ TINY = 3
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.1.0"
4
+ s.version = "2.1.3"
5
5
  s.summary = "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."
6
6
  s.description = s.summary
7
7
  s.authors = ["Jamis Buck", "Delano Mandelbaum"]
@@ -1,4 +1,4 @@
1
- 2010-03-16
1
+ 2011-01-19
2
2
 
3
3
  RUNNING TESTS
4
4
 
@@ -17,7 +17,7 @@ EXPECTED RESULTS
17
17
 
18
18
  * Ruby 1.9: all tests pass
19
19
 
20
- * JRuby 1.4: 96% tests pass (242 tests, 554 assertions, 0 failures, 8 errors)
20
+ * JRuby 1.5: 99% tests pass (448 tests, 1846 assertions, 1 failures)
21
21
 
22
22
 
23
23
  PORT FORWARDING TESTS
@@ -10,7 +10,7 @@ module Authentication; module Methods
10
10
  USERAUTH_INFO_REQUEST = 60
11
11
  USERAUTH_INFO_RESPONSE = 61
12
12
 
13
- def test_authenticate_should_be_false_when_server_does_not_support_this_method
13
+ def test_authenticate_should_raise_if_keyboard_interactive_disallowed
14
14
  transport.expect do |t,packet|
15
15
  assert_equal USERAUTH_REQUEST, packet.type
16
16
  assert_equal "jamis", packet.read_string
@@ -22,7 +22,9 @@ module Authentication; module Methods
22
22
  t.return(USERAUTH_FAILURE, :string, "password")
23
23
  end
24
24
 
25
- assert_equal false, subject.authenticate("ssh-connection", "jamis")
25
+ assert_raises Net::SSH::Authentication::DisallowedMethod do
26
+ subject.authenticate("ssh-connection", "jamis")
27
+ end
26
28
  end
27
29
 
28
30
  def test_authenticate_should_be_false_if_given_password_is_not_accepted
@@ -33,7 +35,7 @@ module Authentication; module Methods
33
35
  assert_equal USERAUTH_INFO_RESPONSE, packet2.type
34
36
  assert_equal 1, packet2.read_long
35
37
  assert_equal "the-password", packet2.read_string
36
- t2.return(USERAUTH_FAILURE, :string, "publickey")
38
+ t2.return(USERAUTH_FAILURE, :string, "keyboard-interactive")
37
39
  end
38
40
  end
39
41
 
@@ -95,4 +97,4 @@ module Authentication; module Methods
95
97
  end
96
98
  end
97
99
 
98
- end; end
100
+ end; end
@@ -7,7 +7,7 @@ module Authentication; module Methods
7
7
  class TestPassword < Test::Unit::TestCase
8
8
  include Common
9
9
 
10
- def test_authenticate_when_password_is_unacceptible_should_return_false
10
+ def test_authenticate_should_raise_if_password_disallowed
11
11
  transport.expect do |t,packet|
12
12
  assert_equal USERAUTH_REQUEST, packet.type
13
13
  assert_equal "jamis", packet.read_string
@@ -19,7 +19,9 @@ module Authentication; module Methods
19
19
  t.return(USERAUTH_FAILURE, :string, "publickey")
20
20
  end
21
21
 
22
- assert !subject.authenticate("ssh-connection", "jamis", "the-password")
22
+ assert_raises Net::SSH::Authentication::DisallowedMethod do
23
+ subject.authenticate("ssh-connection", "jamis", "the-password")
24
+ end
23
25
  end
24
26
 
25
27
  def test_authenticate_when_password_is_acceptible_should_return_true
@@ -31,6 +31,27 @@ module Authentication; module Methods
31
31
  assert_equal false, subject.authenticate("ssh-connection", "jamis")
32
32
  end
33
33
 
34
+ def test_authenticate_should_raise_if_publickey_disallowed
35
+ key_manager.expects(:sign).with(&signature_parameters(keys.first)).returns("sig-one")
36
+
37
+ transport.expect do |t, packet|
38
+ assert_equal USERAUTH_REQUEST, packet.type
39
+ assert verify_userauth_request_packet(packet, keys.first, false)
40
+ t.return(USERAUTH_PK_OK, :string, keys.first.ssh_type, :string, Net::SSH::Buffer.from(:key, keys.first))
41
+
42
+ t.expect do |t2,packet2|
43
+ assert_equal USERAUTH_REQUEST, packet2.type
44
+ assert verify_userauth_request_packet(packet2, keys.first, true)
45
+ assert_equal "sig-one", packet2.read_string
46
+ t2.return(USERAUTH_FAILURE, :string, "hostbased,password")
47
+ end
48
+ end
49
+
50
+ assert_raises Net::SSH::Authentication::DisallowedMethod do
51
+ subject.authenticate("ssh-connection", "jamis")
52
+ end
53
+ end
54
+
34
55
  def test_authenticate_should_return_false_if_signature_exchange_fails
35
56
  key_manager.expects(:sign).with(&signature_parameters(keys.first)).returns("sig-one")
36
57
  key_manager.expects(:sign).with(&signature_parameters(keys.last)).returns("sig-two")
@@ -44,7 +65,7 @@ module Authentication; module Methods
44
65
  assert_equal USERAUTH_REQUEST, packet2.type
45
66
  assert verify_userauth_request_packet(packet2, keys.first, true)
46
67
  assert_equal "sig-one", packet2.read_string
47
- t2.return(USERAUTH_FAILURE, :string, "hostbased,password")
68
+ t2.return(USERAUTH_FAILURE, :string, "publickey")
48
69
 
49
70
  t2.expect do |t3, packet3|
50
71
  assert_equal USERAUTH_REQUEST, packet3.type
@@ -55,7 +76,7 @@ module Authentication; module Methods
55
76
  assert_equal USERAUTH_REQUEST, packet4.type
56
77
  assert verify_userauth_request_packet(packet4, keys.last, true)
57
78
  assert_equal "sig-two", packet4.read_string
58
- t4.return(USERAUTH_FAILURE, :string, "hostbased,password")
79
+ t4.return(USERAUTH_FAILURE, :string, "publickey")
59
80
  end
60
81
  end
61
82
  end
@@ -32,7 +32,7 @@ module Authentication
32
32
  manager.stubs(:agent).returns(nil)
33
33
 
34
34
  stub_file_key "/first", rsa
35
- stub_file_key "/second", dsa
35
+ stub_file_key "/second", dsa
36
36
 
37
37
  identities = []
38
38
  manager.each_identity { |identity| identities << identity }
@@ -40,7 +40,7 @@ module Authentication
40
40
  assert_equal 2, identities.length
41
41
  assert_equal rsa.to_blob, identities.first.to_blob
42
42
  assert_equal dsa.to_blob, identities.last.to_blob
43
-
43
+
44
44
  assert_equal({:from => :file, :file => "/first", :key => rsa}, manager.known_identities[rsa])
45
45
  assert_equal({:from => :file, :file => "/second", :key => dsa}, manager.known_identities[dsa])
46
46
  end
@@ -82,15 +82,25 @@ module Authentication
82
82
 
83
83
  def test_sign_with_file_originated_key_should_load_private_key_and_sign_with_it
84
84
  manager.stubs(:agent).returns(nil)
85
- stub_file_key "/first", rsa(512), true
85
+ stub_file_key "/first", rsa(512)
86
86
  rsa.expects(:ssh_do_sign).with("hello, world").returns("abcxyz123")
87
87
  manager.each_identity { |identity| } # preload the known_identities
88
88
  assert_equal "\0\0\0\assh-rsa\0\0\0\011abcxyz123", manager.sign(rsa, "hello, world")
89
89
  end
90
90
 
91
+ def test_sign_with_file_originated_key_should_raise_key_manager_error_if_unloadable
92
+ manager.known_identities[rsa] = { :from => :file, :file => "/first" }
93
+
94
+ Net::SSH::KeyFactory.expects(:load_private_key).raises(OpenSSL::PKey::RSAError)
95
+
96
+ assert_raises Net::SSH::Authentication::KeyManagerError do
97
+ manager.sign(rsa, "hello, world")
98
+ end
99
+ end
100
+
91
101
  private
92
102
 
93
- def stub_file_key(name, key, also_private=false)
103
+ def stub_file_key(name, key)
94
104
  manager.add(name)
95
105
  File.expects(:readable?).with(name).returns(true)
96
106
  File.expects(:readable?).with(name + ".pub").returns(false)
@@ -12,6 +12,19 @@ module Authentication
12
12
  assert_equal session.auth_methods, session.allowed_auth_methods
13
13
  end
14
14
 
15
+ def test_authenticate_should_continue_if_method_disallowed
16
+ transport.expect do |t, packet|
17
+ assert_equal SERVICE_REQUEST, packet.type
18
+ assert_equal "ssh-userauth", packet.read_string
19
+ t.return(SERVICE_ACCEPT)
20
+ end
21
+
22
+ Net::SSH::Authentication::Methods::Publickey.any_instance.expects(:authenticate).with("next service", "username", "password").raises(Net::SSH::Authentication::DisallowedMethod)
23
+ Net::SSH::Authentication::Methods::Hostbased.any_instance.expects(:authenticate).with("next service", "username", "password").returns(true)
24
+
25
+ assert session.authenticate("next service", "username", "password")
26
+ end
27
+
15
28
  def test_authenticate_should_raise_error_if_service_request_fails
16
29
  transport.expect do |t, packet|
17
30
  assert_equal SERVICE_REQUEST, packet.type
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-ssh
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
5
- prerelease: false
6
- segments:
7
- - 2
8
- - 1
9
- - 0
10
- version: 2.1.0
4
+ prerelease:
5
+ version: 2.1.3
11
6
  platform: ruby
12
7
  authors:
13
8
  - Jamis Buck
@@ -16,7 +11,7 @@ autorequire:
16
11
  bindir: bin
17
12
  cert_chain: []
18
13
 
19
- date: 2011-01-20 00:00:00 -05:00
14
+ date: 2011-03-02 00:00:00 -05:00
20
15
  default_executable:
21
16
  dependencies: []
22
17
 
@@ -164,23 +159,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
164
159
  requirements:
165
160
  - - ">="
166
161
  - !ruby/object:Gem::Version
167
- hash: 3
168
- segments:
169
- - 0
170
162
  version: "0"
171
163
  required_rubygems_version: !ruby/object:Gem::Requirement
172
164
  none: false
173
165
  requirements:
174
166
  - - ">="
175
167
  - !ruby/object:Gem::Version
176
- hash: 3
177
- segments:
178
- - 0
179
168
  version: "0"
180
169
  requirements: []
181
170
 
182
171
  rubyforge_project: net-ssh
183
- rubygems_version: 1.3.7
172
+ rubygems_version: 1.5.2
184
173
  signing_key:
185
174
  specification_version: 3
186
175
  summary: "Net::SSH: a pure-Ruby implementation of the SSH2 client protocol."