From 58c4cbca9369b8d341b2fe2ad9ded2490ddf3d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikl=C3=B3s=20Fazekas?= Date: Fri, 6 Aug 2021 11:47:03 +0200 Subject: Allow single asterisk in known hosts and asterisk should match mutliple dots --- lib/net/ssh/known_hosts.rb | 6 +++--- test/test_known_hosts.rb | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/lib/net/ssh/known_hosts.rb b/lib/net/ssh/known_hosts.rb index b52bc6a..eb7d7a7 100644 --- a/lib/net/ssh/known_hosts.rb +++ b/lib/net/ssh/known_hosts.rb @@ -223,11 +223,11 @@ module Net def match(host, pattern) if pattern.include?('*') || pattern.include?('?') # see man 8 sshd for pattern details - pattern_regexp = pattern.split('*').map do |x| - x.split('?').map do |y| + pattern_regexp = pattern.split('*', -1).map do |x| + x.split('?', -1).map do |y| Regexp.escape(y) end.join('.') - end.join('[^.]*') + end.join('.*') host =~ Regexp.new("\\A#{pattern_regexp}\\z") else diff --git a/test/test_known_hosts.rb b/test/test_known_hosts.rb index fcd64fa..5bd7668 100644 --- a/test/test_known_hosts.rb +++ b/test/test_known_hosts.rb @@ -1,4 +1,4 @@ -require 'common' +require_relative './common' class TestKnownHosts < NetSSHTest def perform_test(source) @@ -109,7 +109,29 @@ class TestKnownHosts < NetSSHTest def test_search_for_with_hostname_not_matching_pattern_3 options = { user_known_hosts_file: path("known_hosts/misc") } keys = Net::SSH::KnownHosts.search_for('subsubdomain.subdomain.gitfoo.com',options) - assert_equal(0, keys.count) + assert_equal(1, keys.count) + end + + def test_asterisk_matches_multiple_dots + with_config_file(lines: ["*.git???.com #{sample_key}"]) do |path| + options = { user_known_hosts_file: path } + keys = Net::SSH::KnownHosts.search_for('subsubdomain.subdomain.gitfoo.com',options) + assert_equal(1, keys.count) + + keys = Net::SSH::KnownHosts.search_for('subsubdomain.subdomain.gitfoo2.com',options) + assert_equal(0, keys.count) + end + end + + def test_asterisk_matches_everything + with_config_file(lines: ["* #{sample_key}"]) do |path| + options = { user_known_hosts_file: path } + keys = Net::SSH::KnownHosts.search_for('subsubdomain.subdomain.gitfoo.com',options) + assert_equal(1, keys.count) + + keys = Net::SSH::KnownHosts.search_for('subsubdomain.subdomain.gitfoo2.com',options) + assert_equal(1, keys.count) + end end def test_search_for_then_add @@ -131,6 +153,18 @@ class TestKnownHosts < NetSSHTest File.join(File.dirname(__FILE__), relative_path) end + def sample_key + "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" + end + + def with_config_file(lines: [], &block) + Tempfile.open('known_hosts') do |f| + f.write(lines.join("\n")) + f.close + yield(f.path) + end + end + def rsa_key key = OpenSSL::PKey::RSA.new if key.respond_to?(:set_key) -- cgit v1.2.1