From 6727dad965452380716b36739811c2233cbf7af4 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 27 Jul 2016 13:58:45 +0200 Subject: [PATCH] Fix KnownHostsKeys#keys_for to match on the entire hostlist See https://github.com/capistrano/sshkit/issues/362#issuecomment-234742497 --- CHANGELOG.md | 2 ++ lib/sshkit/backends/netssh/known_hosts.rb | 8 +++++--- test/known_hosts/github_ip | 1 + test/unit/backends/test_netssh.rb | 15 ++++++++++----- 4 files changed, 18 insertions(+), 8 deletions(-) create mode 100644 test/known_hosts/github_ip 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