net-ssh 2.0.24 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +7 -0
- data/lib/net/ssh.rb +5 -1
- data/lib/net/ssh/authentication/key_manager.rb +53 -27
- data/lib/net/ssh/config.rb +3 -0
- data/lib/net/ssh/loggable.rb +5 -5
- data/lib/net/ssh/version.rb +2 -2
- data/net-ssh.gemspec +1 -1
- data/test/authentication/test_key_manager.rb +16 -2
- metadata +4 -4
data/CHANGELOG.rdoc
CHANGED
@@ -1,4 +1,11 @@
|
|
1
1
|
|
2
|
+
|
3
|
+
=== 2.1 / 19 Jan 2011
|
4
|
+
|
5
|
+
* Support "IdentitiesOnly" directive [Edmund Haselwanter]
|
6
|
+
* Speeding up the Loggable module [robbebob]
|
7
|
+
|
8
|
+
|
2
9
|
=== 2.0.24 / 14 Jan 2011
|
3
10
|
|
4
11
|
* Fix for process code to correctly wait until remote_id is set before sending any output, including eof. [Daniel Pittman, Markus Roberts]
|
data/lib/net/ssh.rb
CHANGED
@@ -66,7 +66,7 @@ module Net
|
|
66
66
|
:logger, :paranoid, :password, :port, :proxy, :rekey_blocks_limit,
|
67
67
|
:rekey_limit, :rekey_packet_limit, :timeout, :verbose,
|
68
68
|
:global_known_hosts_file, :user_known_hosts_file, :host_key_alias,
|
69
|
-
:host_name, :user, :properties, :passphrase
|
69
|
+
:host_name, :user, :properties, :passphrase, :keys_only
|
70
70
|
]
|
71
71
|
|
72
72
|
# The standard means of starting a new SSH connection. When used with a
|
@@ -125,6 +125,10 @@ module Net
|
|
125
125
|
# and hostbased authentication
|
126
126
|
# * :key_data => an array of strings, with each element of the array being
|
127
127
|
# a raw private key in PEM format.
|
128
|
+
# * :keys_only => set to +true+ to use only private keys from +keys+ and
|
129
|
+
# +key_data+ parameters, even if ssh-agent offers more identities. This
|
130
|
+
# option is intended for situations where ssh-agent offers many different
|
131
|
+
# identites.
|
128
132
|
# * :logger => the logger instance to use when logging
|
129
133
|
# * :paranoid => either true, false, or :very, specifying how strict
|
130
134
|
# host-key verification should be
|
@@ -90,40 +90,30 @@ module Net
|
|
90
90
|
# The origin of the identities may be from files on disk or from an
|
91
91
|
# ssh-agent. Note that identities from an ssh-agent are always listed
|
92
92
|
# first in the array, with other identities coming after.
|
93
|
+
#
|
94
|
+
# If key manager was created with :keys_only option, any identity
|
95
|
+
# from ssh-agent will be ignored unless it present in key_files or
|
96
|
+
# key_data.
|
93
97
|
def each_identity
|
98
|
+
user_identities = load_identities_from_files + load_identities_from_data
|
99
|
+
|
94
100
|
if agent
|
95
101
|
agent.identities.each do |key|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
if File.readable?(public_key_file)
|
104
|
-
begin
|
105
|
-
key = KeyFactory.load_public_key(public_key_file)
|
106
|
-
known_identities[key] = { :from => :file, :file => file }
|
107
|
-
yield key
|
108
|
-
rescue Exception => e
|
109
|
-
error { "could not load public key file `#{public_key_file}': #{e.class} (#{e.message})" }
|
110
|
-
end
|
111
|
-
elsif File.readable?(file)
|
112
|
-
begin
|
113
|
-
private_key = KeyFactory.load_private_key(file, options[:passphrase])
|
114
|
-
key = private_key.send(:public_key)
|
115
|
-
known_identities[key] = { :from => :file, :file => file, :key => private_key }
|
102
|
+
corresponding_user_identity = user_identities.detect { |identity|
|
103
|
+
identity[:public_key].to_pem == key.to_pem
|
104
|
+
}
|
105
|
+
user_identities.delete(corresponding_user_identity) if corresponding_user_identity
|
106
|
+
|
107
|
+
if !options[:keys_only] || corresponding_user_identity
|
108
|
+
known_identities[key] = { :from => :agent }
|
116
109
|
yield key
|
117
|
-
rescue Exception => e
|
118
|
-
error { "could not load private key file `#{file}': #{e.class} (#{e.message})" }
|
119
110
|
end
|
120
111
|
end
|
121
112
|
end
|
122
113
|
|
123
|
-
|
124
|
-
|
125
|
-
key =
|
126
|
-
known_identities[key] = { :from => :key_data, :data => data, :key => private_key }
|
114
|
+
user_identities.each do |identity|
|
115
|
+
key = identity.delete(:public_key)
|
116
|
+
known_identities[key] = identity
|
127
117
|
yield key
|
128
118
|
end
|
129
119
|
|
@@ -186,8 +176,44 @@ module Net
|
|
186
176
|
@use_agent = false
|
187
177
|
nil
|
188
178
|
end
|
189
|
-
end
|
190
179
|
|
180
|
+
private
|
181
|
+
|
182
|
+
# Extracts identities from user key_files, preserving their order and sources.
|
183
|
+
def load_identities_from_files
|
184
|
+
key_files.map do |file|
|
185
|
+
public_key_file = file + ".pub"
|
186
|
+
if File.readable?(public_key_file)
|
187
|
+
begin
|
188
|
+
key = KeyFactory.load_public_key(public_key_file)
|
189
|
+
{ :public_key => key, :from => :file, :file => file }
|
190
|
+
rescue Exception => e
|
191
|
+
error { "could not load public key file `#{public_key_file}': #{e.class} (#{e.message})" }
|
192
|
+
nil
|
193
|
+
end
|
194
|
+
elsif File.readable?(file)
|
195
|
+
begin
|
196
|
+
private_key = KeyFactory.load_private_key(file, options[:passphrase])
|
197
|
+
key = private_key.send(:public_key)
|
198
|
+
{ :public_key => key, :from => :file, :file => file, :key => private_key }
|
199
|
+
rescue Exception => e
|
200
|
+
error { "could not load private key file `#{file}': #{e.class} (#{e.message})" }
|
201
|
+
nil
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end.compact
|
205
|
+
end
|
206
|
+
|
207
|
+
# Extraccts identities from user key_data, preserving their order and sources.
|
208
|
+
def load_identities_from_data
|
209
|
+
key_data.map do |data|
|
210
|
+
private_key = KeyFactory.load_data_private_key(data)
|
211
|
+
key = private_key.send(:public_key)
|
212
|
+
{ :public_key => key, :from => :key_data, :data => data, :key => private_key }
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
191
217
|
end
|
192
218
|
end
|
193
219
|
end
|
data/lib/net/ssh/config.rb
CHANGED
@@ -19,6 +19,7 @@ module Net; module SSH
|
|
19
19
|
# * HostKeyAlias => :host_key_alias
|
20
20
|
# * HostName => :host_name
|
21
21
|
# * IdentityFile => maps to the :keys option
|
22
|
+
# * IdentitiesOnly => :keys_only
|
22
23
|
# * Macs => maps to the :hmac option
|
23
24
|
# * PasswordAuthentication => maps to the :auth_methods option
|
24
25
|
# * Port => :port
|
@@ -128,6 +129,8 @@ module Net; module SSH
|
|
128
129
|
hash[:timeout] = value
|
129
130
|
when 'forwardagent' then
|
130
131
|
hash[:forward_agent] = value
|
132
|
+
when 'identitiesonly' then
|
133
|
+
hash[:keys_only] = value
|
131
134
|
when 'globalknownhostsfile'
|
132
135
|
hash[:global_known_hosts_file] = value
|
133
136
|
when 'hostbasedauthentication' then
|
data/lib/net/ssh/loggable.rb
CHANGED
@@ -22,31 +22,31 @@ module Net; module SSH
|
|
22
22
|
# Displays the result of yielding if the log level is Logger::DEBUG or
|
23
23
|
# greater.
|
24
24
|
def debug
|
25
|
-
logger.add(Logger::DEBUG, nil, facility) { yield } if logger
|
25
|
+
logger.add(Logger::DEBUG, nil, facility) { yield } if logger && logger.debug?
|
26
26
|
end
|
27
27
|
|
28
28
|
# Displays the result of yielding if the log level is Logger::INFO or
|
29
29
|
# greater.
|
30
30
|
def info
|
31
|
-
logger.add(Logger::INFO, nil, facility) { yield } if logger
|
31
|
+
logger.add(Logger::INFO, nil, facility) { yield } if logger && logger.info?
|
32
32
|
end
|
33
33
|
|
34
34
|
# Displays the result of yielding if the log level is Logger::WARN or
|
35
35
|
# greater. (Called lwarn to avoid shadowing with Kernel#warn.)
|
36
36
|
def lwarn
|
37
|
-
logger.add(Logger::WARN, nil, facility) { yield } if logger
|
37
|
+
logger.add(Logger::WARN, nil, facility) { yield } if logger && logger.warn?
|
38
38
|
end
|
39
39
|
|
40
40
|
# Displays the result of yielding if the log level is Logger:ERROR or
|
41
41
|
# greater.
|
42
42
|
def error
|
43
|
-
logger.add(Logger::ERROR, nil, facility) { yield } if logger
|
43
|
+
logger.add(Logger::ERROR, nil, facility) { yield } if logger && logger.error?
|
44
44
|
end
|
45
45
|
|
46
46
|
# Displays the result of yielding if the log level is Logger::FATAL or
|
47
47
|
# greater.
|
48
48
|
def fatal
|
49
|
-
logger.add(Logger::FATAL, nil, facility) { yield } if logger
|
49
|
+
logger.add(Logger::FATAL, nil, facility) { yield } if logger && logger.fatal?
|
50
50
|
end
|
51
51
|
|
52
52
|
private
|
data/lib/net/ssh/version.rb
CHANGED
@@ -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 =
|
51
|
+
MINOR = 1
|
52
52
|
|
53
53
|
# The tiny component of this version of the Net::SSH library
|
54
|
-
TINY =
|
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)
|
data/net-ssh.gemspec
CHANGED
@@ -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.0
|
4
|
+
s.version = "2.1.0"
|
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"]
|
@@ -59,6 +59,20 @@ module Authentication
|
|
59
59
|
assert_equal({:from => :agent}, manager.known_identities[dsa])
|
60
60
|
end
|
61
61
|
|
62
|
+
def test_only_identities_with_key_files_should_load_from_agent_of_keys_only_set
|
63
|
+
manager(:keys_only => true).stubs(:agent).returns(agent)
|
64
|
+
|
65
|
+
stub_file_key "/first", rsa
|
66
|
+
|
67
|
+
identities = []
|
68
|
+
manager.each_identity { |identity| identities << identity }
|
69
|
+
|
70
|
+
assert_equal 1, identities.length
|
71
|
+
assert_equal rsa.to_blob, identities.first.to_blob
|
72
|
+
|
73
|
+
assert_equal({:from => :agent}, manager.known_identities[rsa])
|
74
|
+
end
|
75
|
+
|
62
76
|
def test_sign_with_agent_originated_key_should_request_signature_from_agent
|
63
77
|
manager.stubs(:agent).returns(agent)
|
64
78
|
manager.each_identity { |identity| } # preload the known_identities
|
@@ -96,8 +110,8 @@ module Authentication
|
|
96
110
|
@agent ||= stub("agent", :identities => [rsa, dsa])
|
97
111
|
end
|
98
112
|
|
99
|
-
def manager
|
100
|
-
@manager ||= Net::SSH::Authentication::KeyManager.new(nil)
|
113
|
+
def manager(options = {})
|
114
|
+
@manager ||= Net::SSH::Authentication::KeyManager.new(nil, options)
|
101
115
|
end
|
102
116
|
|
103
117
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 11
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 2
|
8
|
+
- 1
|
8
9
|
- 0
|
9
|
-
|
10
|
-
version: 2.0.24
|
10
|
+
version: 2.1.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jamis Buck
|
@@ -16,7 +16,7 @@ autorequire:
|
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
18
|
|
19
|
-
date: 2011-01-
|
19
|
+
date: 2011-01-20 00:00:00 -05:00
|
20
20
|
default_executable:
|
21
21
|
dependencies: []
|
22
22
|
|