Skip to content

Commit

Permalink
Merge pull request #10 from ancorgs/speedup_read_service_settings
Browse files Browse the repository at this point in the history
Speedup Security.ReadServiceSettings (bnc#890349)
  • Loading branch information
ancorgs committed Aug 6, 2014
2 parents 7eae684 + 64e1b23 commit 6055df6
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 80 deletions.
7 changes: 7 additions & 0 deletions package/yast2-security.changes
@@ -1,3 +1,10 @@
-------------------------------------------------------------------
Tue Aug 5 12:58:39 UTC 2014 - ancor@suse.com

- Speedup Security.ReadServiceSettings (bnc#890349)
- Drop obsolete runlevel parameter from some methods
- 3.1.4

-------------------------------------------------------------------
Fri Mar 28 10:09:46 UTC 2014 - vmoravec@suse.com

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


Name: yast2-security
Version: 3.1.3
Version: 3.1.4
Release: 0

BuildRoot: %{_tmppath}/%{name}-%{version}-build
Expand Down
6 changes: 4 additions & 2 deletions src/include/security/dialogs.rb
Expand Up @@ -389,9 +389,10 @@ def DisplayHelpPopup(help_id)
# add extra help to service related options
if help_id == "RUNLEVEL3_MANDATORY_SERVICES" ||
help_id == "RUNLEVEL5_MANDATORY_SERVICES"
# TODO: runlevel is not longer needed, but we are in 'text freeze phase'
runlevel = help_id == "RUNLEVEL3_MANDATORY_SERVICES" ? 3 : 5

missing = Security.MissingMandatoryServices(runlevel)
missing = Security.MissingMandatoryServices

if missing != nil && missing != []
srvs = ""
Expand Down Expand Up @@ -420,8 +421,9 @@ def DisplayHelpPopup(help_id)
end
elsif help_id == "RUNLEVEL3_EXTRA_SERVICES" ||
help_id == "RUNLEVEL5_EXTRA_SERVICES"
# TODO: runlevel is not longer needed (read above)
runlevel = help_id == "RUNLEVEL3_EXTRA_SERVICES" ? 3 : 5
extra = Security.ExtraServices(runlevel)
extra = Security.ExtraServices

if extra != nil && extra != []
srvs = Builtins.mergestring(extra, "<BR>")
Expand Down
122 changes: 45 additions & 77 deletions src/modules/Security.rb
Expand Up @@ -29,6 +29,9 @@

module Yast
class SecurityClass < Module

include Yast::Logger

def main
Yast.import "UI"
textdomain "security"
Expand All @@ -37,7 +40,7 @@ def main
Yast.import "Package"
Yast.import "Pam"
Yast.import "Progress"
Yast.import "Service"
Yast.import "SystemdService"

Yast.include self, "security/levels.rb"

Expand Down Expand Up @@ -269,71 +272,49 @@ def main
}
end

# return list of missing mandatory services in a runlevel
def MissingMandatoryServices(runlevel)
Builtins.y2milestone(
"Checking mandatory services in runlevel %1",
runlevel
)

ret = []
enabled_services = Service.EnabledServices(runlevel)

Builtins.y2milestone("enabled_services: %1", enabled_services)

return nil if enabled_services == nil

Builtins.foreach(@mandatory_services) do |services|
enabled = false
Builtins.foreach(services) do |service|
enabled = enabled || Builtins.contains(enabled_services, service)
end
Builtins.y2milestone(
"Mandatory services %1 are enabled: %2",
services,
enabled
)
ret = Builtins.add(ret, services) if !enabled
# List of missing mandatory services
#
# @param [Array<String>] enabled_services optional list with names of the
# currently enabled services. If not provided, it will be obtained
# from SystemdService.
def MissingMandatoryServices(enabled_services = nil)
log.info("Checking mandatory services")

enabled_services ||= SystemdService.all.select(&:enabled?).map(&:name)
log.info("enabled_services: #{enabled_services}")
return nil if enabled_services.nil?

ret = @mandatory_services.select do |services|
enabled = services.any? { |service| enabled_services.include?(service) }
log.info("Mandatory services #{services} are enabled: #{enabled}")
!enabled
end


Builtins.y2milestone(
"Missing mandatory services in runlevel %1: %2",
runlevel,
ret
)

log.info("Missing mandatory services: #{ret}")
deep_copy(ret)
end

def ExtraServices(runlevel)
Builtins.y2milestone(
"Searching for extra services in runlevel %1",
runlevel
)

extra_services = []
enabled_services = Service.EnabledServices(runlevel)
# List of enabled services that are neither mandatory nor optional
#
# @param [Array<String>] enabled_services optional list with names of the
# currently enabled services. If not provided, it will be obtained
# from SystemdService.
def ExtraServices(enabled_services = nil)
log.info("Searching for extra services")

enabled_services ||= SystemdService.all.select(&:enabled?).map(&:name)
return nil if enabled_services == nil

Builtins.foreach(enabled_services) do |service|
mandatory = @mandatory_services.flatten
ret = enabled_services.select do |service|
# the extra service is not mandatory and it's not optional
extra = !Builtins.contains(
Builtins.flatten(@mandatory_services),
service
) &&
!Builtins.contains(@optional_services, service)
if extra
Builtins.y2milestone("Found extra service: %1", service)
extra_services = Builtins.add(extra_services, service)
end
extra = !mandatory.include?(service) && !@optional_services.include?(service)
log.info("Found extra service: #{service}") if extra
extra
end
log.info("All extra services: #{ret}")


Builtins.y2milestone("All extra services: %1", extra_services)

deep_copy(extra_services)
deep_copy(ret)
end

# Check for pending Abort press
Expand Down Expand Up @@ -374,26 +355,13 @@ def Modified
end

def ReadServiceSettings
Ops.set(
@Settings,
"RUNLEVEL3_MANDATORY_SERVICES",
MissingMandatoryServices(3) == [] ? "secure" : "insecure"
)
Ops.set(
@Settings,
"RUNLEVEL5_MANDATORY_SERVICES",
MissingMandatoryServices(5) == [] ? "secure" : "insecure"
)
Ops.set(
@Settings,
"RUNLEVEL3_EXTRA_SERVICES",
ExtraServices(3) == [] ? "secure" : "insecure"
)
Ops.set(
@Settings,
"RUNLEVEL5_EXTRA_SERVICES",
ExtraServices(5) == [] ? "secure" : "insecure"
)
services = SystemdService.all.select(&:enabled?).map(&:name)
setting = MissingMandatoryServices(services) == [] ? "secure" : "insecure"
# Runlevels are not longer used, but @Settings is populated this way for
# compatibility with the current interface
@Settings["RUNLEVEL3_MANDATORY_SERVICES"] = @Settings["RUNLEVEL5_MANDATORY_SERVICES"] = setting
setting = ExtraServices(services) == [] ? "secure" : "insecure"
@Settings["RUNLEVEL3_EXTRA_SERVICES"] = @Settings["RUNLEVEL5_EXTRA_SERVICES"] = setting

nil
end
Expand Down Expand Up @@ -918,8 +886,8 @@ def Overview

publish :variable => :mandatory_services, :type => "const list <list <string>>"
publish :variable => :optional_services, :type => "const list <string>"
publish :function => :MissingMandatoryServices, :type => "list <list <string>> (integer)"
publish :function => :ExtraServices, :type => "list <string> (integer)"
publish :function => :MissingMandatoryServices, :type => "list <list <string>> ()"
publish :function => :ExtraServices, :type => "list <string> ()"
publish :variable => :Settings, :type => "map <string, string>"
publish :variable => :do_not_test, :type => "list <string>"
publish :variable => :PasswordMaxLengths, :type => "map"
Expand Down
78 changes: 78 additions & 0 deletions test/security_test.rb
@@ -0,0 +1,78 @@
#!/usr/bin/env rspec

require 'rspec'
ENV["Y2DIR"] = File.expand_path("../../src", __FILE__)
require "yast"

def services_for(names)
names.map {|n| Yast::DummySystemdUnit.new(n) }
end

module Yast
# SystemdUnit is 'too smart' for our testing purposes
class DummySystemdUnit
attr_accessor :name

def initialize(name)
self.name = name
end

def enabled?; true; end
end

import "Security"

describe Security do
describe "#ReadServiceSettings" do

before(:each) do
allow(SystemdService).to receive(:all).and_return services_for(service_names)
Security.ReadServiceSettings
end

context "only with mandatory services" do
let(:service_names) { %w(ntp syslog auditd random kbd cron postfix sendmail) }

it "sets settings for all runlevels to 'secure'" do
expect(Security.Settings["RUNLEVEL3_MANDATORY_SERVICES"]).to eq("secure")
expect(Security.Settings["RUNLEVEL5_MANDATORY_SERVICES"]).to eq("secure")
expect(Security.Settings["RUNLEVEL3_EXTRA_SERVICES"]).to eq("secure")
expect(Security.Settings["RUNLEVEL5_EXTRA_SERVICES"]).to eq("secure")
end
end

context "with mandatory and extra services" do
let(:service_names) { %w(ntp syslog auditd random kbd extra1 cron postfix sendmail) }

it "sets settings for extra services as 'insecure'" do
expect(Security.Settings["RUNLEVEL3_MANDATORY_SERVICES"]).to eq("secure")
expect(Security.Settings["RUNLEVEL5_MANDATORY_SERVICES"]).to eq("secure")
expect(Security.Settings["RUNLEVEL3_EXTRA_SERVICES"]).to eq("insecure")
expect(Security.Settings["RUNLEVEL5_EXTRA_SERVICES"]).to eq("insecure")
end
end

context "without all mandatory services and extra ones" do
let(:service_names) { %w(ntp syslog auditd extra1 cron postfix sendmail) }

it "sets settings for all runlevels to 'insecure'" do
expect(Security.Settings["RUNLEVEL3_MANDATORY_SERVICES"]).to eq("insecure")
expect(Security.Settings["RUNLEVEL5_MANDATORY_SERVICES"]).to eq("insecure")
expect(Security.Settings["RUNLEVEL3_EXTRA_SERVICES"]).to eq("insecure")
expect(Security.Settings["RUNLEVEL5_EXTRA_SERVICES"]).to eq("insecure")
end
end

context "with no services" do
let(:service_names) { [] }

it "sets settings for mandatory to 'insecure'" do
expect(Security.Settings["RUNLEVEL3_MANDATORY_SERVICES"]).to eq("insecure")
expect(Security.Settings["RUNLEVEL5_MANDATORY_SERVICES"]).to eq("insecure")
expect(Security.Settings["RUNLEVEL3_EXTRA_SERVICES"]).to eq("secure")
expect(Security.Settings["RUNLEVEL5_EXTRA_SERVICES"]).to eq("secure")
end
end
end
end
end

0 comments on commit 6055df6

Please sign in to comment.