require 'spec_helper' require 'puppet/network/authconfig' require 'puppet/network/auth_config_parser' RSpec::Matchers.define :allow do |params| match do |auth| begin auth.check_authorization(*params) true rescue Puppet::Network::AuthorizationError false end end failure_message do |instance| "expected #{params[2][:node]}/#{params[2][:ip]} to be allowed" end failure_message_when_negated do |instance| "expected #{params[2][:node]}/#{params[2][:ip]} to be forbidden" end end describe Puppet::Network::AuthConfig do include PuppetSpec::Files def add_rule(rule) parser = Puppet::Network::AuthConfigParser.new( "path /test\n#{rule}\n" ) @auth = parser.parse end def add_regex_rule(regex, rule) parser = Puppet::Network::AuthConfigParser.new( "path ~ #{regex}\n#{rule}\n" ) @auth = parser.parse end def add_raw_stanza(stanza) parser = Puppet::Network::AuthConfigParser.new( stanza ) @auth = parser.parse end def request(args = {}) args = { :key => 'key', :node => 'host.domain.com', :ip => '10.1.1.1', :authenticated => true }.merge(args) [:find, "/test/#{args[:key]}", args] end describe "allow" do it "should not match IP addresses" do add_rule("allow 10.1.1.1") expect(@auth).not_to allow(request) end it "should not accept CIDR IPv4 address" do expect { add_rule("allow 10.0.0.0/8") }.to raise_error Puppet::ConfigurationError, /Invalid pattern 10\.0\.0\.0\/8/ end it "should not match wildcard IPv4 address" do expect { add_rule("allow 10.1.1.*") }.to raise_error Puppet::ConfigurationError, /Invalid pattern 10\.1\.1\.*/ end it "should not match IPv6 address" do expect { add_rule("allow 2001:DB8::8:800:200C:417A") }.to raise_error Puppet::ConfigurationError, /Invalid pattern 2001/ end it "should support hostname" do add_rule("allow host.domain.com") expect(@auth).to allow(request) end it "should support wildcard host" do add_rule("allow *.domain.com") expect(@auth).to allow(request) end it 'should warn about missing path before allow_ip in stanza' do expect { add_raw_stanza("allow_ip 10.0.0.1\n") }.to raise_error Puppet::ConfigurationError, /Missing or invalid 'path' before right directive at line.*/ end it 'should warn about missing path before allow in stanza' do expect { add_raw_stanza("allow host.domain.com\n") }.to raise_error Puppet::ConfigurationError, /Missing or invalid 'path' before right directive at line.*/ end it "should support hostname backreferences" do add_regex_rule('^/test/([^/]+)$', "allow $1.domain.com") expect(@auth).to allow(request(:key => 'host')) end it "should support opaque strings" do add_rule("allow this-is-opaque@or-not") expect(@auth).to allow(request(:node => 'this-is-opaque@or-not')) end it "should support opaque strings and backreferences" do add_regex_rule('^/test/([^/]+)$', "allow $1") expect(@auth).to allow(request(:key => 'this-is-opaque@or-not', :node => 'this-is-opaque@or-not')) end it "should support hostname ending with '.'" do pending('bug #7589') add_rule("allow host.domain.com.") expect(@auth).to allow(request(:node => 'host.domain.com.')) end it "should support hostname ending with '.' and backreferences" do pending('bug #7589') add_regex_rule('^/test/([^/]+)$',"allow $1") expect(@auth).to allow(request(:node => 'host.domain.com.')) end it "should support trailing whitespace" do add_rule('allow host.domain.com ') expect(@auth).to allow(request) end it "should support inlined comments" do add_rule('allow host.domain.com # will it work?') expect(@auth).to allow(request) end it "should deny non-matching host" do add_rule("allow inexistent") expect(@auth).not_to allow(request) end end describe "allow_ip" do it "should not warn when matches against IP addresses fail" do add_rule("allow_ip 10.1.1.2") expect(@auth).not_to allow(request) expect(@logs).not_to be_any {|log| log.level == :warning and log.message =~ /Authentication based on IP address is deprecated/} end it "should support IPv4 address" do add_rule("allow_ip 10.1.1.1") expect(@auth).to allow(request) end it "should support CIDR IPv4 address" do add_rule("allow_ip 10.0.0.0/8") expect(@auth).to allow(request) end it "should support wildcard IPv4 address" do add_rule("allow_ip 10.1.1.*") expect(@auth).to allow(request) end it "should support IPv6 address" do add_rule("allow_ip 2001:DB8::8:800:200C:417A") expect(@auth).to allow(request(:ip => '2001:DB8::8:800:200C:417A')) end it "should support hostname" do expect { add_rule("allow_ip host.domain.com") }.to raise_error Puppet::ConfigurationError, /Invalid IP pattern host.domain.com/ end end describe "deny" do it "should deny denied hosts" do add_rule <<-EOALLOWRULE deny host.domain.com allow *.domain.com EOALLOWRULE expect(@auth).not_to allow(request) end it "denies denied hosts after allowing them" do add_rule <<-EOALLOWRULE allow *.domain.com deny host.domain.com EOALLOWRULE expect(@auth).not_to allow(request) end it "should not deny based on IP" do add_rule <<-EOALLOWRULE deny 10.1.1.1 allow host.domain.com EOALLOWRULE expect(@auth).to allow(request) end it "should not deny based on IP (ordering #2)" do add_rule <<-EOALLOWRULE allow host.domain.com deny 10.1.1.1 EOALLOWRULE expect(@auth).to allow(request) end end describe "deny_ip" do it "should deny based on IP" do add_rule <<-EOALLOWRULE deny_ip 10.1.1.1 allow host.domain.com EOALLOWRULE expect(@auth).not_to allow(request) end it "should deny based on IP (ordering #2)" do add_rule <<-EOALLOWRULE allow host.domain.com deny_ip 10.1.1.1 EOALLOWRULE expect(@auth).not_to allow(request) end end end