net-ssh 1.1.1 → 1.1.2
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.
- 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
|