diff --git a/CHANGELOG.md b/CHANGELOG.md index e3576042..741128fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ appear at the top. * Add your entries below here, remember to credit yourself however you want to be credited! + * Fix known_hosts caching to match on the entire hostlist + [PR #364](https://github.com/capistrano/sshkit/pull/364) @byroot ## [1.11.0][] (2016-06-14) diff --git a/lib/sshkit/backends/netssh/known_hosts.rb b/lib/sshkit/backends/netssh/known_hosts.rb index ec03fd00..a231d346 100644 --- a/lib/sshkit/backends/netssh/known_hosts.rb +++ b/lib/sshkit/backends/netssh/known_hosts.rb @@ -18,10 +18,12 @@ def keys_for(hostlist) parse_file unless keys && hashes keys, hashes = hosts_keys, hosts_hashes - hostlist.split(',').each do |host| - key_list = keys[host] - return key_list if key_list + host_names = hostlist.split(',') + keys_found = host_names.map { |h| keys[h] || [] }.compact.inject(:&) + return keys_found unless keys_found.empty? + + host_names.each do |host| hashes.each do |(hmac, salt), hash_keys| if OpenSSL::HMAC.digest(sha1, salt, host) == hmac return hash_keys diff --git a/test/known_hosts/github_ip b/test/known_hosts/github_ip new file mode 100644 index 00000000..33afb526 --- /dev/null +++ b/test/known_hosts/github_ip @@ -0,0 +1 @@ +github.com,192.30.252.123 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ== diff --git a/test/unit/backends/test_netssh.rb b/test/unit/backends/test_netssh.rb index 5b2f0993..bacec239 100644 --- a/test/unit/backends/test_netssh.rb +++ b/test/unit/backends/test_netssh.rb @@ -56,23 +56,28 @@ def test_transfer_summarizer if Net::SSH::Version::CURRENT >= Net::SSH::Version[3, 1, 0] def test_known_hosts_for_when_all_hosts_are_recognized - perform_known_hosts_test("github") + perform_known_hosts_test('github', 'github.com') end def test_known_hosts_for_when_an_host_hash_is_recognized - perform_known_hosts_test("github_hash") + perform_known_hosts_test('github_hash', 'github.com') + end + + def test_known_hosts_for_with_multiple_hosts + perform_known_hosts_test('github', '192.30.252.123,github.com', 0) + perform_known_hosts_test('github_ip', '192.30.252.123,github.com', 1) end end private - def perform_known_hosts_test(hostfile) + def perform_known_hosts_test(hostfile, hostlist, keys_count = 1) source = File.join(File.dirname(__FILE__), '../../known_hosts', hostfile) kh = Netssh::KnownHosts.new - keys = kh.search_for('github.com', user_known_hosts_file: source, global_known_hosts_file: Tempfile.new('sshkit-test').path) + keys = kh.search_for(hostlist, user_known_hosts_file: source, global_known_hosts_file: Tempfile.new('sshkit-test').path) assert_instance_of ::Net::SSH::HostKeys, keys - assert_equal(1, keys.count) + assert_equal(keys_count, keys.count) keys.each do |key| assert_equal("ssh-rsa", key.ssh_type) end