Skip to content

Commit

Permalink
Merge pull request #88 from yast/SLE-15-SP2-selinux-AY-update
Browse files Browse the repository at this point in the history
AutoYaST for SELinux
  • Loading branch information
dgdavid committed Feb 15, 2021
2 parents e61f582 + d099383 commit 0ad18aa
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 17 deletions.
7 changes: 7 additions & 0 deletions package/yast2-security.changes
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Sun Feb 14 21:13:17 UTC 2021 - David Diaz <dgonzalez@suse.com>

- AutoYaST: add support for SELinux configuration (jsc#SMO-20,
jsc#SLE-17342).
- 4.2.18

-------------------------------------------------------------------
Fri Feb 12 09:12:11 UTC 2021 - David Diaz <dgonzalez@suse.com>

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-security.spec
Expand Up @@ -17,7 +17,7 @@


Name: yast2-security
Version: 4.2.17
Version: 4.2.18
Release: 0
Group: System/YaST
License: GPL-2.0-only
Expand Down
2 changes: 2 additions & 0 deletions src/autoyast-rnc/security.rnc
Expand Up @@ -7,6 +7,7 @@ cwd_in_user_path = element cwd_in_user_path { text }
disable_restart_on_update = element disable_restart_on_update { text }
disable_stop_on_removal = element disable_stop_on_removal { text }
extra_services = element extra_services { text }
selinux_mode = element selinux_mode { text }
displaymanager_remote_access = element displaymanager_remote_access { text }
displaymanager_root_login_remote = element displaymanager_root_login_remote { text }
displaymanager_shutdown = element displaymanager_shutdown { text }
Expand Down Expand Up @@ -69,6 +70,7 @@ y2_security =
| disable_restart_on_update
| disable_stop_on_removal
| extra_services
| selinux_mode
| displaymanager_remote_access
| displaymanager_root_login_remote
| displaymanager_xserver_tcp_port_6000_open
Expand Down
20 changes: 20 additions & 0 deletions src/clients/security_auto.rb
Expand Up @@ -30,6 +30,8 @@
# goes through the configuration and return the setting.
# Does not do any changes to the configuration.

require "y2security/selinux"

# @param function to execute
# @param map/list of security settings
# @return [Hash] edited settings, Summary or boolean on success depending on called function
Expand All @@ -47,6 +49,7 @@ def main

Yast.import "Map"
Yast.import "Security"
Yast.import "AutoInstall"

Yast.include self, "security/routines.rb"
Yast.include self, "security/wizards.rb"
Expand Down Expand Up @@ -80,6 +83,23 @@ def main
@ret = SecurityAutoSequence()
# Import Data
elsif @func == "Import"

#Checking value semantic
if @param.has_key?("selinux_mode")
selinux_values = Y2Security::Selinux.new.modes.map {|m| m.id.to_s}
if !selinux_values.include?(@param["selinux_mode"])
Yast::AutoInstall.issues_list.add(
:invalid_value,
"security",
"selinux_mode",
@param["selinux_mode"],
_("Wrong SELinux mode. Possible values: ") +
selinux_values.join(", "),
:warn
)
end
end

# Compat
if Builtins.haskey(@param, "encryption")
Ops.set(
Expand Down
74 changes: 60 additions & 14 deletions src/modules/Security.rb
Expand Up @@ -32,6 +32,7 @@
require "yaml"
require "security/ctrl_alt_del_config"
require "security/display_manager"
require "y2security/selinux"

module Yast
class SecurityClass < Module
Expand Down Expand Up @@ -68,7 +69,6 @@ class SecurityClass < Module
"USERDEL_POSTCMD"
].freeze


attr_reader :display_manager

def main
Expand All @@ -83,10 +83,13 @@ def import_modules
Yast.import "UI"
Yast.import "FileUtils"
Yast.import "Package"
Yast.import "Pkg"
Yast.import "Pam"
Yast.import "Progress"
Yast.import "Service"
Yast.import "Directory"
Yast.import "Report"
Yast.import "PackagesProposal"
Yast.include self, "security/levels.rb"
end

Expand Down Expand Up @@ -155,7 +158,8 @@ def init_settings
"DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN" => "no",
"SMTPD_LISTEN_REMOTE" => "no",
"MANDATORY_SERVICES" => "yes",
"EXTRA_SERVICES" => "no"
"EXTRA_SERVICES" => "no",
"SELINUX_MODE" => ""
}

@Settings.merge!(@display_manager.default_settings) if @display_manager
Expand Down Expand Up @@ -444,6 +448,15 @@ def read_polkit_settings
"#{@Settings['HIBERNATE_SYSTEM']}"
end

# Sets the SELINUX_MODE setting
#
# @see Y2Security::Selinux
def read_selinux_settings
@Settings["SELINUX_MODE"] = selinux_config.mode.id.to_s

log.debug "SELINUX_MODE (after #{__callee__}): #{@Settings['SELINUX_MODE']}"
end

# Read all security settings
# @return true on success
def Read
Expand All @@ -470,6 +483,8 @@ def Read

read_kernel_settings

read_selinux_settings

# remember the read values
@Settings_bak = deep_copy(@Settings)

Expand Down Expand Up @@ -547,6 +562,15 @@ def write_shadow_config
shadow_config.save
end

# Set SELinux settings
#
# @return true on success
def write_selinux
selinux_config.mode = @Settings["SELINUX_MODE"]
selinux_config.save
end


# Write settings related to PAM behavior
def write_pam_settings
# use cracklib?
Expand Down Expand Up @@ -670,25 +694,29 @@ def Write
" ",
steps,
[
# Progress stage 1/4
# Progress stage 1/5
_("Write security settings"),
# Progress stage 2/4
# Progress stage 2/5
_("Write inittab settings"),
# Progress stage 3/4
# Progress stage 3/5
_("Write PAM settings"),
# Progress stage 4/4
_("Update system settings")
# Progress stage 4/5
_("Update system settings"),
# Progress stage 5/5
_("Write SELinux settings")
],
[
# Progress step 1/5
# Progress step 1/6
_("Writing security settings..."),
# Progress step 2/5
# Progress step 2/6
_("Writing inittab settings..."),
# Progress step 3/5
# Progress step 3/6
_("Writing PAM settings..."),
# Progress step 4/5
# Progress step 4/6
_("Updating system settings..."),
# Progress step 5/5
# Progress step 5/6
_("Writing settings..."),
# Progress step 6/6
_("Finished")
],
""
Expand Down Expand Up @@ -726,6 +754,10 @@ def Write
Progress.NextStage
activate_changes

return false if Abort()
Progress.NextStage
write_selinux

return false if Abort()
@modified = false
true
Expand Down Expand Up @@ -758,7 +790,6 @@ def Import(settings)
end

return true if settings == {}

@modified = true
tmpSettings = {}
@Settings.each do |k, v|
Expand All @@ -779,8 +810,9 @@ def Import(settings)
end
end
end
@Settings = tmpSettings

@Settings = tmpSettings
set_selinux_patterns # Checking needed packages
true
end

Expand Down Expand Up @@ -867,6 +899,13 @@ def default_encrypt_method

protected

# Ensures needed patterns for SELinux, if any, will be installed
def set_selinux_patterns
selinux_config.mode = @Settings["SELINUX_MODE"] unless @Settings["SELINUX_MODE"].to_s.empty?

PackagesProposal.SetResolvables("selinux_patterns", :pattern, selinux_config.needed_patterns)
end

# Sets @missing_mandatory_services honoring the systemd aliases
def read_missing_mandatory_services
log.info("Checking mandatory services")
Expand Down Expand Up @@ -936,6 +975,13 @@ def shadow_config
end
end

# Returns a SELinux configuration handler
#
# @return [Y2Security::Selinux] the SELinux config handler
def selinux_config
@selinux_config ||= Y2Security::Selinux.new
end

# Checks if the service is allowed (i.e. not considered 'extra')
#
# @return [Boolean] true whether the service is expected (mandatory or optional)
Expand Down
1 change: 1 addition & 0 deletions test/levels_test.rb
Expand Up @@ -50,6 +50,7 @@ def apply_level2
change_scr_root(File.join(DATA_PATH, "system"))
stub_scr_write
allow(Package).to receive(:Installed).with("systemd").and_return true
allow(Security.selinux_config).to receive(:save)
end

after do
Expand Down
57 changes: 55 additions & 2 deletions test/security_test.rb
Expand Up @@ -111,6 +111,7 @@ def enabled?
it "writes and applies all the settings" do
expect(Security).to receive(:write_to_locations)
expect(Security).to receive(:write_shadow_config)
expect(Security).to receive(:write_selinux)
expect(Security).to receive(:write_console_shutdown)
expect(Security).to receive(:write_pam_settings)
expect(Security).to receive(:write_polkit_settings)
Expand Down Expand Up @@ -239,6 +240,27 @@ def enabled?
end
end

describe "#write_selinux" do
let(:requested_mode) { "enforcing" }

before do
allow(subject.selinux_config).to receive(:save)
subject.Settings["SELINUX_MODE"] = requested_mode
end

it "sets the SELinux mode" do
expect(subject.selinux_config).to receive(:mode=).with(requested_mode)

subject.write_selinux
end

it "saves the selinux config" do
expect(subject.selinux_config).to receive(:save)

subject.write_selinux
end
end

describe "#write_kernel_settings" do
before do
change_scr_root(File.join(DATA_PATH, "system"))
Expand Down Expand Up @@ -723,6 +745,28 @@ def enabled?
end
end

describe "#read_selinux_settings" do
let(:mode) { double("Y2Security::Selinux::Mode", id: :enforcing) }

before do
allow(subject.selinux_config).to receive(:mode).and_return(mode)
end

it "reads the selinux mode" do
expect(subject.selinux_config).to receive(:mode)

subject.read_selinux_settings
end

it "sets the SELINUX_MODE setting" do
expect(Security.Settings["SELINUX_MODE"]).to eq("")

Security.read_selinux_settings

expect(Security.Settings["SELINUX_MODE"]).to eq(mode.id.to_s)
end
end

describe "#Read" do
it "reads settings and returns true" do
expect(Security).to receive(:read_from_locations)
Expand All @@ -731,12 +775,15 @@ def enabled?
expect(Security).to receive(:read_pam_settings)
expect(Security).to receive(:read_permissions)
expect(Security).to receive(:read_polkit_settings)
expect(Security).to receive(:read_selinux_settings)

expect(Security.Read).to eql(true)
end
end

describe "#Import" do
let(:selinux_patterns) { ["example-selinux-patterns"] }

before do
# GENERAL
Security.Settings["FAIL_DELAY"] = "5"
Expand All @@ -750,6 +797,7 @@ def enabled?
Security.Settings["SYS_UID_MIN"] = 200
Security.Settings["SYS_GID_MIN"] = 200

allow(subject.selinux_config).to receive(:needed_patterns).and_return(selinux_patterns)
end

it "doest not touch current Settings if given settings are empty" do
Expand All @@ -758,6 +806,13 @@ def enabled?
expect(Security.Settings).to eql(current)
end

it "sets resolvables for needed SELinux patterns" do
expect(Yast::PackagesProposal).to receive(:SetResolvables)
.with(anything, :pattern, selinux_patterns)

expect(Security.Import({"SELINUX_MODE" => "permissive"}))
end

context "when Settings keys exists in given settings" do
it "imports given settings without modify" do
expect(Security.Import("PASS_MIN_LEN" => "8", "MANDATORY_SERVICES" => "yes")).to eql(true)
Expand Down Expand Up @@ -792,9 +847,7 @@ def enabled?

expect(Security.Settings["FAIL_DELAY"]).to eql("5")
end

end

end
end
end

0 comments on commit 0ad18aa

Please sign in to comment.