From cbe7e8c03f33c4d7983cdf7803a8c274d30767cc Mon Sep 17 00:00:00 2001 From: Vasu1105 Date: Fri, 9 Apr 2021 14:35:06 +0530 Subject: [PATCH] Add selinux resource with basic features support Signed-off-by: Vasu1105 --- .../content/inspec/resources/selinux.md | 40 ++++++++++++++ lib/inspec/resources.rb | 1 + lib/inspec/resources/selinux.rb | 55 +++++++++++++++++++ test/fixtures/cmd/sestatus | 9 +++ test/helpers/mock_loader.rb | 1 + test/unit/resources/selinux_test.rb | 25 +++++++++ 6 files changed, 131 insertions(+) create mode 100644 docs-chef-io/content/inspec/resources/selinux.md create mode 100644 lib/inspec/resources/selinux.rb create mode 100644 test/fixtures/cmd/sestatus create mode 100644 test/unit/resources/selinux_test.rb diff --git a/docs-chef-io/content/inspec/resources/selinux.md b/docs-chef-io/content/inspec/resources/selinux.md new file mode 100644 index 000000000..ab12e560c --- /dev/null +++ b/docs-chef-io/content/inspec/resources/selinux.md @@ -0,0 +1,40 @@ ++++ +title = "selinux resource" +draft = false +gh_repo = "inspec" +platform = "linux" + +[menu] + [menu.inspec] + title = "selinux" + identifier = "inspec/resources/os/selinux.md selinux resource" + parent = "inspec/resources/os" ++++ + +Use the `selinux` Chef InSpec audit resource to test the state/mode of SELinux policy. + +SELinux resource extracts and exposes data reported by the command 'sestatus' + +## Availability + +### Installation + +This resource is distributed along with Chef InSpec itself. You can use it automatically. + +### Version + +## Syntax + +An `selinux` Chef InSpec audit resource block extracts configuration settings that should be tested: + + describe selinux do + it { should be_installed } + it { should be_enabled } + it { should be_enforcing } + it { should be_permissive } + end + +## Properties + +## Property Examples + diff --git a/lib/inspec/resources.rb b/lib/inspec/resources.rb index ff89a2cb6..6f153e94d 100644 --- a/lib/inspec/resources.rb +++ b/lib/inspec/resources.rb @@ -103,6 +103,7 @@ require "inspec/resources/rabbitmq_config" require "inspec/resources/registry_key" require "inspec/resources/security_identifier" require "inspec/resources/security_policy" +require "inspec/resources/selinux" require "inspec/resources/service" require "inspec/resources/shadow" require "inspec/resources/ssh_config" diff --git a/lib/inspec/resources/selinux.rb b/lib/inspec/resources/selinux.rb new file mode 100644 index 000000000..12dc87a8f --- /dev/null +++ b/lib/inspec/resources/selinux.rb @@ -0,0 +1,55 @@ +require "inspec/resources/command" + +module Inspec::Resources + class Selinux < Inspec.resource(1) + name "selinux" + + supports platform: "unix" + + desc "Use selinux Inspec resource to test state/mode of the selinux policy." + + example <<~EXAMPLE + describe selinux do + it { should be_installed } + it { should be_disabled } + it { should be_permissive } + it { should be_enforcing } + end + EXAMPLE + + def initialize(selinux_path = "/etc/selinux/config") + @path = selinux_path + cmd = inspec.command("sestatus") + if cmd.exit_status != 0 + return skip_resource "#{cmd.stdout}" + end + result = cmd.stdout.delete(" ").gsub(/\n/, ",").gsub(/\r/,"").downcase + @data = Hash[result.scan /([^:]+):([^,]+)[,$]/] + + return if inspec.os.linux? + + @data = [] + skip_resource "The 'selinux' resource is not supported non linux OS." + end + + def installed? + inspec.file(@path).exist? + end + + def disabled? + @data["selinuxstatus"] == 'disabled' unless @data.empty? + end + + def enforcing? + @data["currentmode"] == 'enforcing' unless @data.empty? + end + + def permissive? + @data["currentmode"] == 'permissive' unless @data.empty? + end + + def to_s + "SELinux" + end + end +end \ No newline at end of file diff --git a/test/fixtures/cmd/sestatus b/test/fixtures/cmd/sestatus new file mode 100644 index 000000000..36b375463 --- /dev/null +++ b/test/fixtures/cmd/sestatus @@ -0,0 +1,9 @@ +SELinux status: enabled +SELinuxfs mount: /sys/fs/selinux +SELinux root directory: /etc/selinux +Loaded policy name: targeted +Current mode: enforcing +Mode from config file: enforcing +Policy MLS status: enabled +Policy deny_unknown status: allowed +Max kernel policy version: 31 \ No newline at end of file diff --git a/test/helpers/mock_loader.rb b/test/helpers/mock_loader.rb index 6fc3424c7..0a2353ca0 100644 --- a/test/helpers/mock_loader.rb +++ b/test/helpers/mock_loader.rb @@ -556,6 +556,7 @@ class MockLoader # filesystem command "2e7e0d4546342cee799748ec7e2b1c87ca00afbe590fa422a7c27371eefa88f0" => cmd.call("get-wmiobject-filesystem"), + 'sestatus' => cmd.call("sestatus") } # ports on linux diff --git a/test/unit/resources/selinux_test.rb b/test/unit/resources/selinux_test.rb new file mode 100644 index 000000000..478058f72 --- /dev/null +++ b/test/unit/resources/selinux_test.rb @@ -0,0 +1,25 @@ +require "helper" +require "inspec/resource" +require "inspec/resources/selinux" + +describe "Inspec::Resources::Selinux" do + it "verify selinux state - enforcing" do + resource = load_resource("selinux") + _(resource.enforcing?).must_equal true + end + + it "verify selinux state - permissive" do + resource = load_resource("selinux") + _(resource.permissive?).must_equal false + end + + it "verify selinux disabled " do + resource = load_resource("selinux") + _(resource.disabled?).must_equal false + end + + it "verify selinux on windows" do + resource = MockLoader.new("windows").load_resource("selinux") + _(resource.enforcing?).must_equal nil + end +end