Skip to content

Commit

Permalink
Merge 4c1d0ef into cfa680b
Browse files Browse the repository at this point in the history
  • Loading branch information
jreidinger committed Feb 12, 2021
2 parents cfa680b + 4c1d0ef commit f78babf
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 20 deletions.
1 change: 1 addition & 0 deletions Dockerfile
@@ -1,3 +1,4 @@
FROM registry.opensuse.org/yast/sle-15/sp2/containers/yast-ruby
RUN zypper --non-interactive in --no-recommends yast2-security
COPY . /usr/src/app

9 changes: 8 additions & 1 deletion package/yast2-firewall.changes
@@ -1,8 +1,15 @@
-------------------------------------------------------------------
Thu Feb 4 09:14:13 UTC 2021 - Josef Reidinger <jreidinger@suse.com>

- Add to firewall/security proposal option to setup selinux if
given product require it. (jsc#SLE-17427)
- 4.2.6

-------------------------------------------------------------------
Fri Oct 16 15:15:49 UTC 2020 - Josef Reidinger <jreidinger@suse.com>

- Do not enable firewall during first stage of AutoYaST
(bsc#1177778)
(bsc#1177778)
- 4.2.5

-------------------------------------------------------------------
Expand Down
6 changes: 4 additions & 2 deletions package/yast2-firewall.spec
Expand Up @@ -17,7 +17,7 @@


Name: yast2-firewall
Version: 4.2.5
Version: 4.2.6
Release: 0
Summary: YaST2 - Firewall Configuration
Group: System/YaST
Expand All @@ -26,8 +26,10 @@ Url: https://github.com/yast/yast-firewall

Source0: %{name}-%{version}.tar.bz2

BuildRequires: perl-XML-Writer update-desktop-files yast2-testsuite
BuildRequires: update-desktop-files
BuildRequires: yast2-devtools >= 4.2.2
# for proposing selinux
BuildRequires: yast2-security >= 4.2.17
# Removed zone name from common attributes definition
BuildRequires: yast2 >= 4.1.67
BuildRequires: rubygem(%rb_default_ruby_abi:yast-rake)
Expand Down
1 change: 1 addition & 0 deletions src/lib/y2firewall/clients/installation_finish.rb
Expand Up @@ -57,6 +57,7 @@ def modes
def write
Service.Enable("sshd") if @settings.enable_sshd
configure_firewall if @firewalld.installed?
@settings.selinux_config.save
true
end

Expand Down
17 changes: 16 additions & 1 deletion src/lib/y2firewall/clients/proposal.rb
Expand Up @@ -122,7 +122,7 @@ def call_proposal_action_for(link)
def proposals
# Filter proposals with content
[cpu_mitigations_proposal, firewall_proposal, sshd_proposal,
ssh_port_proposal, vnc_fw_proposal].compact
ssh_port_proposal, vnc_fw_proposal, selinux_proposal].compact
end

# Returns the cpu mitigation part of the bootloader proposal description
Expand Down Expand Up @@ -218,6 +218,21 @@ def sshd_proposal
) % LINK_ENABLE_SSHD
end
end

# Returns the Selinux config description
# @return [String, nil] proposal html text or nil if not configurable
def selinux_proposal
return nil unless @settings.selinux_config.configurable?

# add required patterns
Yast.import "PackagesProposal"
Yast::PackagesProposal.SetResolvables("SELinux", :pattern,
@settings.selinux_config.needed_patterns)

_(
"Selinux Default Mode is %s"
) % @settings.selinux_config.mode.to_human_string
end
end
end
end
56 changes: 43 additions & 13 deletions src/lib/y2firewall/dialogs/proposal.rb
Expand Up @@ -41,19 +41,17 @@ def title
end

def contents
VBox(
Frame(
_("Firewall and SSH service"),
HSquash(
MarginBox(
0.5,
0.5,
VBox(
Widgets::FirewallSSHProposal.new(@settings)
)
)
)
)
content = [Left(firewall_ssh_content)]
content << Left(selinux_content) if selinux_configurable?

HBox(
HStretch(),
VBox(
VStretch(),
*content,
VStretch()
),
HStretch()
)
end

Expand All @@ -76,6 +74,38 @@ def disable_buttons

protected

def selinux_configurable?
@settings.selinux_config.configurable?
end

def firewall_ssh_content
Frame(
_("Firewall and SSH service"),
HSquash(
MarginBox(
0.5,
0.5,
VBox(
Widgets::FirewallSSHProposal.new(@settings)
)
)
)
)
end

def selinux_content
Frame(
_("SELinux"),
MarginBox(
0.5,
0.5,
VBox(
Widgets::SelinuxMode.new(@settings)
)
)
)
end

# Hostname of the current system.
#
# Getting the hostname is sometimes a little bit slow, so the value is
Expand Down
11 changes: 11 additions & 0 deletions src/lib/y2firewall/proposal_settings.rb
Expand Up @@ -22,6 +22,7 @@
require "yast"

Yast.import "UsersSimple"
require "y2security/selinux"

module Y2Firewall
# Class that stores the proposal settings for firewalld during installation.
Expand Down Expand Up @@ -122,6 +123,16 @@ def close_vnc!
self.open_vnc = false
end

# Returns a SELinux configuration handler
#
# @note this is here only for SLE-15-SP2 and derivated products. Newer code
# streams will have it in the yast2-installation -> security settings
#
# @return [Y2Security::Selinux] the SELinux config handler
def selinux_config
@selinux_config ||= Y2Security::Selinux.new
end

private

def load_feature(feature, to, source: global_section)
Expand Down
38 changes: 38 additions & 0 deletions src/lib/y2firewall/widgets/proposal.rb
Expand Up @@ -200,5 +200,43 @@ def help
)
end
end

# Widget to set SELinux mode
class SelinuxMode < CWM::ComboBox
def initialize(settings)
textdomain "firewall"

@settings = settings
end

def label
# TRANSLATORS: SELinu Mode just SELinux is already content of frame.
_("Mode")
end

def items
@settings.selinux_config.modes.map { |m| [m.id, m.to_human_string] }
end

def init
self.value = @settings.selinux_config.mode.id
end

def store
@settings.selinux_config.mode = value
end

def help
_(
"<p>Sets default SELinux mode. Modes are: <ul>" \
"<li><b>Enforcing</b> the state that enforces SELinux security policy. "\
"Access is denied to users and programs unless permitted by " \
"SELinux security policy rules. All denial messages are logged.</li> "\
"<b>Permissive</b> is a diagnostic state. The security policy rules are " \
"not enforced, but SELinux sends denial messages to a log file.</li>" \
"<b>Disabled</b> SELinux does not enforce a security policy.</li></ul></p>"
)
end
end
end
end
7 changes: 7 additions & 0 deletions test/lib/y2firewall/clients/installation_finish_test.rb
Expand Up @@ -33,6 +33,7 @@
allow(proposal_settings).to receive(:enable_sshd).and_return(enable_sshd)
allow(firewalld).to receive(:installed?).and_return(installed)
allow(proposal_settings).to receive(:open_ssh).and_return(false)
allow(proposal_settings.selinux_config).to receive(:save).and_return(true)
end

it "enables the sshd service if enabled in the proposal" do
Expand All @@ -42,6 +43,12 @@
subject.write
end

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

subject.write
end

context "when firewalld is not installed" do
let(:installed) { false }

Expand Down
1 change: 1 addition & 0 deletions test/lib/y2firewall/clients/proposal_test.rb
Expand Up @@ -30,6 +30,7 @@
before do
# skip bootloader proposal to avoid build dependency on it
allow(subject).to receive(:cpu_mitigations_proposal)
allow(subject).to receive(:selinux_proposal)
end

describe "#initialize" do
Expand Down
29 changes: 28 additions & 1 deletion test/lib/y2firewall/dialogs/proposal_test.rb
Expand Up @@ -25,9 +25,36 @@
require "y2firewall/dialogs/proposal"

describe Y2Firewall::Dialogs::Proposal do
subject { described_class.new(settings) }

let(:settings) { instance_double("Y2Firewall::ProposalSettings") }
let(:selinux_configurable) { false }

subject { described_class.new(settings) }
before do
allow(subject).to receive(:selinux_configurable?)
.and_return(selinux_configurable)
end

include_examples "CWM::Dialog"

describe "#contents" do
let(:widgets) { Yast::CWM.widgets_in_contents([subject.contents]) }
let(:selinux_mode_widget) { widgets.find { |w| w.is_a?(Y2Firewall::Widgets::SelinuxMode) } }

context "when SELinux is set to be configurable" do
let(:selinux_configurable) { true }

it "contains the Y2Firewall::Widgets::SelinuxMode content" do
expect(selinux_mode_widget).to_not be_nil
end
end

context "when SELinux is set to not be configurable" do
let(:selinux_configurable) { false }

it "does not contain the Y2Firewall::Widgets::SelinuxMode content" do
expect(selinux_mode_widget).to be_nil
end
end
end
end
6 changes: 6 additions & 0 deletions test/lib/y2firewall/proposal_settings_test.rb
Expand Up @@ -106,6 +106,12 @@
end
end

describe "#selinux_config" do
it "returns a Y2Security::Selinux instance" do
expect(subject.selinux_config).to be_a(Y2Security::Selinux)
end
end

describe "#enable_firewall!" do
it "sets firewalld service to be enabled" do
allow(Yast::PackagesProposal).to receive("AddResolvables")
Expand Down
10 changes: 9 additions & 1 deletion test/lib/y2firewall/widgets/proposal_test.rb
Expand Up @@ -30,10 +30,12 @@
end

describe Y2Firewall::Widgets do
let(:selinux_config) { instance_double(Y2Security::Selinux, modes: []) }

let(:proposal_settings) do
instance_double(
Y2Firewall::ProposalSettings, enable_firewall: true, enable_sshd: true,
open_ssh: true, open_vnc: true
open_ssh: true, open_vnc: true, selinux_config: selinux_config
)
end

Expand Down Expand Up @@ -330,4 +332,10 @@
end
end
end

describe Y2Firewall::Widgets::SelinuxMode do
subject { described_class.new(proposal_settings) }

include_examples "CWM::ComboBox"
end
end
15 changes: 14 additions & 1 deletion test/test_helper.rb
Expand Up @@ -35,15 +35,28 @@ def stub_module(name, fake_class = nil)
end

# stub classes from other modules to speed up a build
stub_module("AutoInstall")
# rubocop:disable Style/SingleLineMethods
# rubocop:disable Style/MethodName
stub_module("AutoInstall", Class.new { def issues_list; []; end })
stub_module("UsersSimple", Class.new { def self.GetRootPassword; "secret"; end })
# rubocop:enable Style/SingleLineMethods
# rubocop:enable Style/MethodName

# some tests have translatable messages
ENV["LANG"] = "en_US.UTF-8"
ENV["LC_ALL"] = "en_US.UTF-8"

RSpec.configure do |config|
config.mock_with :rspec do |mocks|
# If you misremember a method name both in code and in tests,
# will save you.
# https://relishapp.com/rspec/rspec-mocks/v/3-0/docs/verifying-doubles/partial-doubles
#
# With graceful degradation for RSpec 2
mocks.verify_partial_doubles = true if mocks.respond_to?(:verify_partial_doubles=)
end
end

if ENV["COVERAGE"]
require "simplecov"
SimpleCov.start do
Expand Down

0 comments on commit f78babf

Please sign in to comment.