net-ssh 1.1.1 → 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +545 -0
- data/LICENSE +7 -0
- data/NEWS +146 -0
- data/README +14 -0
- data/THANKS +19 -0
- data/bin/rb-keygen +1 -1
- data/doc/manual-html/chapter-1.html +2 -2
- data/doc/manual-html/chapter-2.html +2 -2
- data/doc/manual-html/chapter-3.html +2 -2
- data/doc/manual-html/chapter-4.html +2 -2
- data/doc/manual-html/chapter-5.html +2 -2
- data/doc/manual-html/chapter-6.html +2 -2
- data/doc/manual-html/chapter-7.html +2 -2
- data/doc/manual-html/index.html +2 -2
- data/lib/net/ssh/connection/channel.rb +4 -4
- data/lib/net/ssh/connection/driver.rb +1 -1
- data/lib/net/ssh/host-key-verifier.rb +17 -73
- data/lib/net/ssh/known-hosts.rb +96 -0
- data/lib/net/ssh/proxy/socks5.rb +1 -1
- data/lib/net/ssh/service/agentforward/driver.rb +1 -1
- data/lib/net/ssh/service/process/open.rb +6 -6
- data/lib/net/ssh/service/process/popen3.rb +2 -2
- data/lib/net/ssh/service/shell/shell.rb +9 -0
- data/lib/net/ssh/session.rb +1 -1
- data/lib/net/ssh/transport/algorithm-negotiator.rb +10 -2
- data/lib/net/ssh/transport/packet-stream.rb +1 -1
- data/lib/net/ssh/transport/session.rb +6 -0
- data/lib/net/ssh/userauth/methods/keyboard-interactive.rb +1 -1
- data/lib/net/ssh/userauth/services.rb +1 -1
- data/lib/net/ssh/version.rb +1 -1
- data/test/proxy/tc_socks5.rb +2 -2
- data/test/service/forward/tc_driver.rb +1 -1
- data/test/transport/tc_algorithm_negotiator.rb +1 -0
- data/test/transport/tc_session.rb +1 -1
- data/test/userauth/tc_driver.rb +1 -1
- metadata +9 -3
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Net::SSH is copyrighted free software by Jamis Buck <jamis@37signals.com>.
|
2
|
+
The reader is hereby granted permission to redistribute and/or modify it
|
3
|
+
under the terms of the BSD license, the Ruby license, or (by association
|
4
|
+
with the Ruby license) the GPL, at the reader's option.
|
5
|
+
|
6
|
+
Look in the "doc" subdirectory, and see the LICENSE-BSD, LICENSE-RUBY and
|
7
|
+
LICENSE-GPL files for the text of these licenses.
|
data/NEWS
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
Net:SSH
|
2
|
+
http://rubyforge.org/projects/net-ssh
|
3
|
+
|
4
|
+
[1.1.2] 18 June 2007
|
5
|
+
* Fixed bug #6156 (ruby -w warnings)
|
6
|
+
|
7
|
+
* Fixed bug #11532 (Hang after MSG_CHANNEL_OPEN_FAILURE)
|
8
|
+
|
9
|
+
* Fixed bug #10818 (Exception in split_data_for_packet)
|
10
|
+
|
11
|
+
* Fixed bug #6667 (wrong SOCKS 5 auth version)
|
12
|
+
|
13
|
+
* Fixed bug #11270 (error when server uses some aes ciphers)
|
14
|
+
|
15
|
+
* Fixed bug #11355 (typo in session.rb)
|
16
|
+
|
17
|
+
* Fixed bug #11250 (host key verification problems when an RSA key appears
|
18
|
+
in the known hosts file, but the server has both DSS and RSA keys)
|
19
|
+
|
20
|
+
[1.1.1] 9 May 2007
|
21
|
+
* Fixed broken mkdir in host key verification.
|
22
|
+
|
23
|
+
* Fixed problems with Windows users getting "address family for hostname
|
24
|
+
not supported" errors.
|
25
|
+
|
26
|
+
[1.1.0] 1 May 2007
|
27
|
+
* Added the missing rb-keygen utility
|
28
|
+
|
29
|
+
* Server key verification (enabled by default, disable with :paranoid => false)
|
30
|
+
|
31
|
+
* Add support for SSH agent forwwarding
|
32
|
+
|
33
|
+
[1.0.10] 9 Sep 2006
|
34
|
+
* Experiment with using read instead of sysread, to try and alleviate problems
|
35
|
+
on Windows.
|
36
|
+
|
37
|
+
* Use printf instead of echo -n in the shell service, for compatibility with
|
38
|
+
more unices.
|
39
|
+
|
40
|
+
* Give a sane error message when the user name is nil and cannot be derived
|
41
|
+
from the environment.
|
42
|
+
|
43
|
+
* Add a #connection accessor to the session.
|
44
|
+
|
45
|
+
* Add initial support for server-originated global requests.
|
46
|
+
|
47
|
+
[1.0.9] 14 Apr 2006
|
48
|
+
* Fix a bug when used in tandem with edge Rails, due to monkeypatching in Rails.
|
49
|
+
|
50
|
+
[1.0.8] 18 Feb 2006
|
51
|
+
* Move connect for forwarded connections outside of thread so errors can be
|
52
|
+
caught
|
53
|
+
|
54
|
+
[1.0.7] 27 Jan 2006
|
55
|
+
* Fix intermittent "corrupt mac" bug (finally!)
|
56
|
+
|
57
|
+
[1.0.6] 19 Jan 2006
|
58
|
+
* Send NEWKEYS message first, for compatibility with wodSSHServer (which
|
59
|
+
won't send NEWKEYS until recieving it)
|
60
|
+
|
61
|
+
* Do not print the banner message by default on authorization (rarely useful
|
62
|
+
for automated processes anyway)
|
63
|
+
|
64
|
+
[1.0.5] 2 Jan 2006
|
65
|
+
* Added connection.ping! and session.ping! for testing the connection
|
66
|
+
|
67
|
+
[1.0.4] 24 Dec 2005
|
68
|
+
* Fixed tests broken by changes in Ruby 1.8.4.
|
69
|
+
|
70
|
+
* Fixed references to obsolete contact email address.
|
71
|
+
|
72
|
+
[1.0.3] 9 Nov 2005
|
73
|
+
* Fixed for windows so that connections succeed even if pageant process is
|
74
|
+
not running.
|
75
|
+
|
76
|
+
[1.0.2] 26 Jul 2005
|
77
|
+
* Fixed channel on_request callback signature.
|
78
|
+
|
79
|
+
* Better thread-safety in the connection driver (fixes some "Bad packet size"
|
80
|
+
errors in multi-threaded apps)
|
81
|
+
|
82
|
+
* Corrected various minor bugs.
|
83
|
+
|
84
|
+
[1.0.1] 17 Jun 2005
|
85
|
+
* Added a :timeout option on the transport session
|
86
|
+
|
87
|
+
* Net::SSH works with the Putty Agent now
|
88
|
+
|
89
|
+
[1.0.0] 6 Feb 2005
|
90
|
+
* Password can be programmatically specified for the 'keyboard-authentication'
|
91
|
+
method.
|
92
|
+
|
93
|
+
* All unit tests pass on Windows now.
|
94
|
+
|
95
|
+
* Channels now respect their own local window and maximum packet sizes, and
|
96
|
+
report reasonable values to the server. This fixes a bug that caused
|
97
|
+
problems when large quantities of data were requested of the server and
|
98
|
+
certain server maximums were being exceeded.
|
99
|
+
|
100
|
+
* Client name is determined in a more robust manner.
|
101
|
+
|
102
|
+
* Fixed hostbased bug.
|
103
|
+
|
104
|
+
* Authentication process is now aware of the authentication methods reported
|
105
|
+
by the server as having a chance of succeeded, and no longer attempts
|
106
|
+
those methods that cannot possibly succeed.
|
107
|
+
|
108
|
+
[0.9.0] 11 Jan 2005
|
109
|
+
* Added 'shell' and 'sync' services for interacting with users' shells,
|
110
|
+
including a demo script that uses these to implement a simple SSH terminal
|
111
|
+
client.
|
112
|
+
|
113
|
+
* The 'keyboard-interactive' authentication method is implemented correctly
|
114
|
+
now, which means users will receive a prompt to enter a password if one is
|
115
|
+
not given, and is required.
|
116
|
+
|
117
|
+
* The bug that caused the agent to always be used--even if it was
|
118
|
+
unavailable--has been fixed.
|
119
|
+
|
120
|
+
* The user manual now includes links to previous/next chapters, and uses
|
121
|
+
syntax highlighting for the code blocks. Various other style tweaks in the
|
122
|
+
manual.
|
123
|
+
|
124
|
+
* Window sizes and maximum packet sizes are now honored, which should take
|
125
|
+
care of various bugs and make Net::SSH play nicer with older SSH servers.
|
126
|
+
|
127
|
+
* Non-blocking reads are now supported via the
|
128
|
+
Transport::Session#reader_ready? method. The Connection::Driver#process
|
129
|
+
method has been modified to make better use of this.
|
130
|
+
|
131
|
+
* Moved to subversion, from CVS. Repository is now at
|
132
|
+
http://www.jamisbuck.org/svn/net-ssh
|
133
|
+
|
134
|
+
[0.6.0] 2 Dec 2004
|
135
|
+
* Added pageant support (thanks to Guillaume Mar�ais)
|
136
|
+
|
137
|
+
* Added support for external services (like SFTP).
|
138
|
+
|
139
|
+
* Use USERNAME environment variable if USER is not set (like on Windows)
|
140
|
+
|
141
|
+
[0.5.0] 23 Nov 2004
|
142
|
+
* Refactored to use Needle.
|
143
|
+
|
144
|
+
* Moved SFTP support into its own library.
|
145
|
+
|
146
|
+
* Moved command-line utilities into their own library.
|
data/README
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
= Net::SSH
|
2
|
+
|
3
|
+
<b><em>A pure Ruby module that emulates an SSH client.</em></b>
|
4
|
+
|
5
|
+
<em>Author: Jamis Buck (jamis@37signals.com)</em>
|
6
|
+
|
7
|
+
Net::SSH absolutely WILL NOT work with the version of Ruby's OpenSSL module currently shipped with Ruby versions < 1.8.2 final. If you insist on trying it with a pre-1.8.2 final version, you must get a patched version of the OpenSSL module and install it (and remove the old module) before using Net::SSH.
|
8
|
+
|
9
|
+
The current release of Net::SSH supports:
|
10
|
+
|
11
|
+
* the execution of processes on the remote host (interactively, or non-interactively)
|
12
|
+
* interacting with a user's shell
|
13
|
+
* port forwarding, both from a local port to a remote port, and vice versa
|
14
|
+
* HTTP and SOCKS proxy support (and support for creation of additional proxy types)
|
data/THANKS
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Net::SSH was originally written by Jamis Buck <jamis@37signals.com>. In
|
2
|
+
addition, the following individuals are gratefully acknowledged for their
|
3
|
+
contributions:
|
4
|
+
|
5
|
+
GOTOU Yuuzou <gotoyuzo@notwork.org>
|
6
|
+
* help and code related to OpenSSL
|
7
|
+
|
8
|
+
Guillaume Mar�ais <guillaume.marcais@free.fr>
|
9
|
+
* support for communicating with the the PuTTY "pageant" process
|
10
|
+
|
11
|
+
Daniel Berger <djberg96@yahoo.com>
|
12
|
+
* help getting unit tests to pass in Windows
|
13
|
+
|
14
|
+
Chris Andrews <chris@nodnol.org> and Lee Jensen <lee@outerim.com>
|
15
|
+
* support for ssh agent forwarding
|
16
|
+
|
17
|
+
If you have contributed to Net::SSH and are not on the above list, please do
|
18
|
+
not take offense! Jamis is notoriously forgetful. Instead, just let him know
|
19
|
+
what your contribution was, and he'll be only too happy to add you.
|
data/bin/rb-keygen
CHANGED
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Net::SSH Version: <strong>1.1.
|
18
|
-
Manual Last Updated: <strong>2007-
|
17
|
+
Net::SSH Version: <strong>1.1.2</strong><br />
|
18
|
+
Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Net::SSH Version: <strong>1.1.
|
18
|
-
Manual Last Updated: <strong>2007-
|
17
|
+
Net::SSH Version: <strong>1.1.2</strong><br />
|
18
|
+
Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Net::SSH Version: <strong>1.1.
|
18
|
-
Manual Last Updated: <strong>2007-
|
17
|
+
Net::SSH Version: <strong>1.1.2</strong><br />
|
18
|
+
Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Net::SSH Version: <strong>1.1.
|
18
|
-
Manual Last Updated: <strong>2007-
|
17
|
+
Net::SSH Version: <strong>1.1.2</strong><br />
|
18
|
+
Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Net::SSH Version: <strong>1.1.
|
18
|
-
Manual Last Updated: <strong>2007-
|
17
|
+
Net::SSH Version: <strong>1.1.2</strong><br />
|
18
|
+
Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Net::SSH Version: <strong>1.1.
|
18
|
-
Manual Last Updated: <strong>2007-
|
17
|
+
Net::SSH Version: <strong>1.1.2</strong><br />
|
18
|
+
Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Net::SSH Version: <strong>1.1.
|
18
|
-
Manual Last Updated: <strong>2007-
|
17
|
+
Net::SSH Version: <strong>1.1.2</strong><br />
|
18
|
+
Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
data/doc/manual-html/index.html
CHANGED
@@ -14,8 +14,8 @@
|
|
14
14
|
</div>
|
15
15
|
</td><td valign='middle' align='right'>
|
16
16
|
<div class="info">
|
17
|
-
Net::SSH Version: <strong>1.1.
|
18
|
-
Manual Last Updated: <strong>2007-
|
17
|
+
Net::SSH Version: <strong>1.1.2</strong><br />
|
18
|
+
Manual Last Updated: <strong>2007-06-18 18:12 UTC</strong>
|
19
19
|
</div>
|
20
20
|
</td></tr>
|
21
21
|
</table>
|
@@ -303,10 +303,10 @@ module Net
|
|
303
303
|
data = data[0,window_size]
|
304
304
|
end
|
305
305
|
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
data = data[0,
|
306
|
+
max_size_less_overhead = maximum_packet_size - overhead
|
307
|
+
if data.length > max_size_less_overhead
|
308
|
+
data_to_return = data[max_size_less_overhead..-1] + ( data_to_return || "" )
|
309
|
+
data = data[0,max_size_less_overhead]
|
310
310
|
end
|
311
311
|
|
312
312
|
[ data, data_to_return ]
|
@@ -71,7 +71,7 @@ module Net
|
|
71
71
|
# the confirmation, the +on_confirm+ callback will be invoked.
|
72
72
|
def open_channel( type, extra_data=nil, &on_confirm )
|
73
73
|
channel = @factories[:open].call( type, extra_data )
|
74
|
-
channel.on_confirm_open
|
74
|
+
channel.on_confirm_open(&on_confirm)
|
75
75
|
@channel_map[ channel.local_id ] = channel
|
76
76
|
end
|
77
77
|
|
@@ -1,20 +1,13 @@
|
|
1
1
|
require 'net/ssh/errors'
|
2
|
+
require 'net/ssh/known-hosts'
|
2
3
|
|
3
4
|
module Net
|
4
5
|
module SSH
|
5
6
|
|
6
7
|
class HostKeyVerifier
|
7
8
|
def verify(arguments)
|
8
|
-
|
9
|
-
matches =
|
10
|
-
host = item[:host] || arguments[:peer][:host]
|
11
|
-
ip = item[:ip] || arguments[:peer][:ip]
|
12
|
-
port = item[:port] || arguments[:peer][:port]
|
13
|
-
|
14
|
-
host == arguments[:peer][:host] &&
|
15
|
-
ip == arguments[:peer][:ip] &&
|
16
|
-
port == arguments[:peer][:port]
|
17
|
-
end
|
9
|
+
host = canonize(arguments[:peer])
|
10
|
+
matches = Net::SSH::KnownHosts.search_for(host)
|
18
11
|
|
19
12
|
# we've never seen this host before, so just automatically add the key.
|
20
13
|
# not the most secure option (since the first hit might be the one that
|
@@ -22,85 +15,36 @@ module Net
|
|
22
15
|
# fingerprint, this is a reasonable compromise between usability and
|
23
16
|
# security.
|
24
17
|
if matches.empty?
|
25
|
-
|
18
|
+
Net::SSH::KnownHosts.add(host, arguments[:key])
|
26
19
|
return true
|
27
20
|
end
|
28
21
|
|
29
22
|
# If we found any matches, check to see that the key type and
|
30
23
|
# blob also match.
|
31
|
-
found = matches.any? do |
|
32
|
-
|
33
|
-
|
34
|
-
|
24
|
+
found = matches.any? do |key|
|
25
|
+
key.ssh_type == arguments[:key].ssh_type &&
|
26
|
+
key.to_blob == arguments[:key].to_blob
|
27
|
+
end
|
35
28
|
|
36
29
|
# If a match was found, return true. Otherwise, raise an exception
|
37
30
|
# indicating that the key was not recognized.
|
38
|
-
found || process_cache_miss(arguments)
|
31
|
+
found || process_cache_miss(host, arguments)
|
39
32
|
end
|
40
33
|
|
41
34
|
private
|
42
35
|
|
43
|
-
def process_cache_miss(args)
|
44
|
-
exception = HostKeyMismatch.new("fingerprint #{args[:fingerprint]} does not match for #{
|
36
|
+
def process_cache_miss(host, args)
|
37
|
+
exception = HostKeyMismatch.new("fingerprint #{args[:fingerprint]} does not match for #{host.join(',')}")
|
45
38
|
exception.data = args
|
46
|
-
exception.callback = Proc.new {
|
39
|
+
exception.callback = Proc.new { Net::SSH::KnownHosts.add(host, args[:key]) }
|
47
40
|
raise exception
|
48
41
|
end
|
49
42
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
def user_key_file
|
57
|
-
@user_key_file ||= "#{home_directory}/.ssh/known_hosts"
|
58
|
-
end
|
59
|
-
|
60
|
-
def add_key(args)
|
61
|
-
keys << { :host => args[:peer][:host], :port => args[:peer][:port], :ip => args[:peer][:ip], :type => args[:key].ssh_type, :key => args[:key_blob] }
|
62
|
-
|
63
|
-
key_directory = File.dirname(user_key_file)
|
64
|
-
Dir.mkdir(key_directory, 0700) if !File.exists?(key_directory)
|
65
|
-
|
66
|
-
File.open(user_key_file, "a") do |f|
|
67
|
-
host = args[:peer][:host]
|
68
|
-
host = "[#{host}]:#{args[:peer][:port]}" if host && args[:peer][:port] != 22
|
69
|
-
|
70
|
-
ip = args[:peer][:ip]
|
71
|
-
ip = nil if ip == "127.0.0.1" || ip == "::1"
|
72
|
-
|
73
|
-
host = [host, ip].compact.join(",")
|
74
|
-
f.puts "%s %s %s" % [host, args[:key].ssh_type, [args[:key_blob]].pack("m*").gsub(/\s/, "")]
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def keys
|
79
|
-
@keys ||= begin
|
80
|
-
list = []
|
81
|
-
list.concat(load_keys_from(user_key_file)) if File.exist?(user_key_file)
|
82
|
-
list
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
def load_keys_from(path)
|
87
|
-
File.readlines(path).map do |line|
|
88
|
-
host, type, key = line.chomp.split
|
89
|
-
host, address = host.split(/,/)
|
90
|
-
|
91
|
-
if address.nil? && host =~ /^\d+\.\d+\.\d+\.\d+$/
|
92
|
-
host, address = address, host
|
93
|
-
end
|
94
|
-
|
95
|
-
if host
|
96
|
-
host, port = host.split(/:/, 2)
|
97
|
-
host = host.gsub(/[\[\]]/, "")
|
98
|
-
end
|
99
|
-
|
100
|
-
key = key.unpack("m*").first
|
101
|
-
|
102
|
-
{ :host => host, :ip => address, :port => port, :type => type, :key => key }
|
103
|
-
end
|
43
|
+
def canonize(peer)
|
44
|
+
hosts = []
|
45
|
+
hosts << Net::SSH::KnownHosts.canonize(peer[:host], peer[:port])
|
46
|
+
hosts << Net::SSH::KnownHosts.canonize(peer[:ip], peer[:port])
|
47
|
+
hosts.compact
|
104
48
|
end
|
105
49
|
end
|
106
50
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
require 'net/ssh/transport/ossl/buffer'
|
3
|
+
require 'net/ssh/util/openssl'
|
4
|
+
|
5
|
+
module Net; module SSH
|
6
|
+
class KnownHosts
|
7
|
+
class <<self
|
8
|
+
def canonize(location, port)
|
9
|
+
value = location
|
10
|
+
value = "[#{value}]:#{port}" if port && port != 22
|
11
|
+
value
|
12
|
+
end
|
13
|
+
|
14
|
+
def search_for(host)
|
15
|
+
search_in(hostfile_locations, host)
|
16
|
+
end
|
17
|
+
|
18
|
+
def add(host, key)
|
19
|
+
hostfile_locations.each do |file|
|
20
|
+
begin
|
21
|
+
KnownHosts.new(file).add(host, key)
|
22
|
+
return
|
23
|
+
rescue SystemCallError
|
24
|
+
# try the next hostfile
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def search_in(files, host)
|
30
|
+
files.map { |file| KnownHosts.new(file).keys_for(host) }.flatten
|
31
|
+
end
|
32
|
+
|
33
|
+
def hostfile_locations
|
34
|
+
@hostfile_locations ||= [
|
35
|
+
"#{home_directory}/.ssh/known_hosts",
|
36
|
+
"#{home_directory}/.ssh/known_hosts2",
|
37
|
+
"/etc/ssh/ssh_known_hosts",
|
38
|
+
"/etc/ssh/ssh_known_hosts2"
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
def home_directory
|
43
|
+
ENV['HOME'] ||
|
44
|
+
(ENV['HOMEPATH'] && "#{ENV['HOMEDRIVE']}#{ENV['HOMEPATH']}") ||
|
45
|
+
"/"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
attr_reader :source
|
51
|
+
|
52
|
+
def initialize(source)
|
53
|
+
@source = source
|
54
|
+
end
|
55
|
+
|
56
|
+
def keys_for(host)
|
57
|
+
keys = []
|
58
|
+
hosts = Array(host)
|
59
|
+
|
60
|
+
File.open(source) do |file|
|
61
|
+
scanner = StringScanner.new("")
|
62
|
+
file.each_line do |line|
|
63
|
+
scanner.string = line
|
64
|
+
|
65
|
+
scanner.skip(/\s*/)
|
66
|
+
next if scanner.match?(/$|#/)
|
67
|
+
|
68
|
+
hostlist = scanner.scan(/\S+/)
|
69
|
+
next if (hostlist.split(/,/) & hosts).empty?
|
70
|
+
|
71
|
+
scanner.skip(/\s*/)
|
72
|
+
type = scanner.scan(/\S+/)
|
73
|
+
scanner.skip(/\s*/)
|
74
|
+
blob = scanner.rest.unpack("m*").first
|
75
|
+
keys << Net::SSH::Transport::OSSL::Buffer.new(blob).read_key
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
keys
|
80
|
+
rescue SystemCallError
|
81
|
+
return []
|
82
|
+
end
|
83
|
+
|
84
|
+
def add(host, key)
|
85
|
+
dir = File.dirname(source)
|
86
|
+
Dir.mkdir(dir, 0700) if !File.exists?(dir)
|
87
|
+
|
88
|
+
File.open(source, "a") do |file|
|
89
|
+
buffer = Net::SSH::Transport::OSSL::Buffer.new
|
90
|
+
buffer.write_key(key)
|
91
|
+
blob = [buffer.to_s].pack("m*").gsub(/\s/, "")
|
92
|
+
file.puts "#{Array(host).join(',')} #{key.ssh_type} #{blob}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end; end
|