Mailinglist Archive: yast-devel (46 mails)

< Previous Next >
[yast-devel] [PATCH 2/3] Handle profiles
From: Goldwyn Rodrigues <rgoldwyn@xxxxxxxx>

Handles the profiles using JSON output of aa-status. This replaces the earlier
way of handling profiles.

Signed-off-by: Goldwyn Rodrigues <rgoldwyn@xxxxxxxx>
---
src/clients/AA_EditProfile.rb | 129 ----------------------
src/clients/apparmor-settings.rb | 3 +-
src/clients/apparmor.rb | 1 -
src/clients/profiles.rb | 111 +++++++++++++++++++
src/lib/apparmor/profiles.rb | 227 +++++++++++++++++++++++++++++++++++++++
5 files changed, 340 insertions(+), 131 deletions(-)
delete mode 100644 src/clients/AA_EditProfile.rb
create mode 100644 src/clients/profiles.rb
create mode 100644 src/lib/apparmor/profiles.rb

diff --git a/src/clients/AA_EditProfile.rb b/src/clients/AA_EditProfile.rb
deleted file mode 100644
index a616143..0000000
--- a/src/clients/AA_EditProfile.rb
+++ /dev/null
@@ -1,129 +0,0 @@
-# encoding: utf-8
-
-# ***************************************************************************
-#
-# Copyright (c) 2002 - 2012 Novell, Inc.
-# All Rights Reserved.
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of version 2 of the GNU General Public License as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, contact Novell, Inc.
-#
-# To contact Novell about this file by physical or electronic mail,
-# you may find current contact information at www.novell.com
-#
-# ***************************************************************************
-module Yast
- class AAEditProfileClient < Client
- def main
- Yast.import "UI"
- Yast.import "Wizard"
- Yast.import "Popup"
- Yast.import "Label"
- Yast.import "Sequencer"
- Yast.include self, "apparmor/apparmor_packages.rb"
- Yast.include self, "apparmor/apparmor_profile_check.rb"
- Yast.include self, "apparmor/profile_dialogs.rb"
- textdomain "yast2-apparmor"
-
- # Globalz
-
- @profiles = nil
-
-
-
- #
- # YEAH BABY RUN BABY RUN
- #
- @ret = nil
-
- # no command line support #269891
- if Ops.greater_than(Builtins.size(WFM.Args), 0)
- Yast.import "CommandLine"
- CommandLine.Init({}, WFM.Args)
- return deep_copy(@ret)
- end
-
- return deep_copy(@ret) if !installAppArmorPackages
-
- return deep_copy(@ret) if !checkProfileSyntax
-
-
- @ret = MainSequence()
- deep_copy(@ret)
- end
-
- def Reread
- @profiles = Convert.to_map(SCR.Read(path(".apparmor_profiles"), "all"))
- :next
- end
-
-
- def MainSequence
- #
- # Read the profiles from the SCR agent
- Reread()
-
- aliases = {
- "showProfile" => lambda do
- DisplayProfileForm(
- Ops.get_string(@Settings, "CURRENT_PROFILE", ""),
- false
- )
- end,
- "showHat" => lambda do
- DisplayProfileForm(Ops.get_string(@Settings, "CURRENT_HAT", ""),
true)
- end,
- "chooseProfile" => lambda do
- SelectProfileForm(
- @profiles,
- _("Select a listed profile and press Edit to edit it."),
- _("Edit Profile - Choose profile to edit"),
- "apparmor_edit_profile"
- )
- end,
- "reread" => lambda { Reread() }
- }
-
- sequence = {
- "ws_start" => "chooseProfile",
- "chooseProfile" => {
- :abort => :abort,
- :edit => "showProfile",
- :reread => "reread",
- :next => :next
- },
- "showProfile" => {
- :abort => :abort,
- :next => "reread",
- :showhat => "showHat",
- :finish => :next
- },
- "reread" => { :next => "chooseProfile" },
- "showHat" => {
- :abort => :abort,
- :next => "showProfile",
- :finish => :next
- }
- }
-
- Wizard.CreateDialog
- Wizard.SetTitleIcon("apparmor_edit_profile")
- ret = Sequencer.Run(aliases, sequence)
- Wizard.CloseDialog
- @Settings = Builtins.remove(@Settings, "CURRENT_PROFILE")
- @Settings = Builtins.remove(@Settings, "PROFILE_MAP")
- deep_copy(ret)
- end
- end
-end
-
-Yast::AAEditProfileClient.new.main
diff --git a/src/clients/apparmor-settings.rb b/src/clients/apparmor-settings.rb
index 2b2d3f2..d3f6d1a 100644
--- a/src/clients/apparmor-settings.rb
+++ b/src/clients/apparmor-settings.rb
@@ -21,6 +21,7 @@
# ***************************************************************************

require "yast"
+require "apparmor/profiles"

Yast.import "UI"
Yast.import "Label"
@@ -77,7 +78,7 @@ module AppArmor
loop do
case Yast::UI.UserInput
when :modeconf
- break
+ AppArmor::ProfilesDialog.new.run
when :quit
break
end
diff --git a/src/clients/apparmor.rb b/src/clients/apparmor.rb
index 63e8874..1e6d7e3 100644
--- a/src/clients/apparmor.rb
+++ b/src/clients/apparmor.rb
@@ -70,7 +70,6 @@ module Yast
[
# Selection box items
Item(Id("apparmor-settings"), _("Settings"), true),
- Item(Id("AA_EditProfile"), _("Manage Existing Profiles")),
Item(Id("AA_AddProfile"), _("Manually Add Profile"))
]
),
diff --git a/src/clients/profiles.rb b/src/clients/profiles.rb
new file mode 100644
index 0000000..06c6e8a
--- /dev/null
+++ b/src/clients/profiles.rb
@@ -0,0 +1,111 @@
+
+require "apparmor/profiles"
+Yast.import "UI"
+Yast.import "Label"
+Yast.import "Popup"
+
+class ProfilesDialog
+ include Yast::UIShortcuts
+ include Yast::I18n
+ include Yast::Logger
+
+ def initialize
+ @profiles = Apparmor::Profiles.new
+ @active = true
+ end
+
+ def run
+ return unless create_dialog
+
+ begin
+ return event_loop
+ ensure
+ close_dialog
+ end
+ end
+
+private
+ def create_dialog
+ Yast::UI.OpenDialog(
+ Opt(:decorated, :defaultsize),
+ VBox(
+ #Header
+ Heading(_("Profile List")),
+ # Active profiles
+ Left(
+ CheckBox(Id(:active_only), Opt(:notify), _("Show Active only"),
@active)
+ ),
+ VSpacing(0.4),
+ # Profile List
+ table,
+ VSpacing(0.3),
+ # Footer buttons
+ HBox(
+ HWeight(1, PushButton(Id(:toggle), _("Toggle mode"))),
+ HStretch(),
+ HWeight(1, PushButton(Id(:add), Yast::Label.AddButton)),
+ HStretch(),
+ HWeight(1, PushButton(Id(:edit), Yast::Label.EditButton)),
+ HStretch(),
+ HWeight(1, PushButton(Id(:finish), Yast::Label.FinishButton))
+ )
+ )
+ )
+ end
+
+ def table
+ headers = Array[_("Name"), _("Mode"), _("PID")]
+ Table(
+ Id(:entries_table),
+ Opt(:keepSorting),
+ Header(*headers),
+ table_items
+ )
+ end
+
+ def table_items
+ if @active
+ profs = @profiles.active
+ else
+ profs = @profiles.all
+ end
+ arr = Array.new
+ profs.each do | n, pr |
+ arr.push(pr.to_array)
+ end
+ arr.map { |i| Item(*i) }
+ end
+
+ def redraw_table
+ Yast::UI.ChangeWidget(Id(:entries_table), :Items, table_items)
+ end
+
+ def event_loop
+ loop do
+ case Yast::UI.UserInput
+ when :active_only
+ @active = Yast::UI.QueryWidget(Id(:active_only), :Value)
+ redraw_table
+ when :cancel
+ break
+ when :toggle
+ selectedItem = Yast::UI.QueryWidget(Id(:entries_table), :CurrentItem)
+ log.info "Toggling #{selectedItem}"
+ @profiles.toggle(selectedItem)
+ redraw_table
+ when :edit
+ break
+ when :finish
+ break
+ end
+ end
+ end
+
+ def close_dialog
+ Yast::UI.CloseDialog
+ end
+end
+
+ProfilesDialog.new.run
+
+
diff --git a/src/lib/apparmor/profiles.rb b/src/lib/apparmor/profiles.rb
new file mode 100644
index 0000000..f3129f6
--- /dev/null
+++ b/src/lib/apparmor/profiles.rb
@@ -0,0 +1,227 @@
+# Get the status of profiles loaded
+# - enforced
+# - complain
+# Uses aa-status --json
+
+require "json"
+require "open3"
+Yast.import "UI"
+Yast.import "Label"
+Yast.import "Popup"
+
+module AppArmor
+
+ class Profile
+ attr_reader :name, :status, :pid
+
+ def initialize(name, status)
+ @name=name
+ @status=status
+ @pid = Array.new
+ end
+
+ #Return/Set the name of the profile
+ def name(n="")
+ if n.length > 0
+ @name = n
+ end
+ return @name
+ end
+
+ #return the current status
+ def status(s="")
+ if s != ""
+ @status = s
+ end
+ return @status
+ end
+
+ # Set to complain mode
+ def complain()
+ system("/usr/sbin/aa-complain #{@name}")
+ return self.status("complain")
+ end
+
+ # Set to enforce mode
+ def enforce()
+ system("/usr/sbin/aa-enforce #{@name}")
+ return self.status("enforce")
+ end
+
+ def addPid(p)
+ @pid.push(p)
+ end
+
+ def pid
+ return @pid
+ end
+
+ def toggle
+ if @status == "complain"
+ self.enforce
+ else
+ self.complain
+ end
+ end
+
+ def to_s
+ @name + ", " + @status + ", " + @pid
+ end
+
+ def to_array
+ a = Array.new
+ a.push(@name)
+ a.push(@status)
+ pstr = " "
+ # Convert PID array to a pretty string with commas
+ @pid.each do | p |
+ pstr = pstr + p.to_str + ", "
+ end
+ a.push(pstr)
+ return a
+ end
+ end
+
+ class ProfileMap
+ def self.all(text)
+ jtext = JSON.parse(text)
+ h = jtext["profiles"]
+ entries = Hash.new
+ h.each do |name, status|
+ entries[name] = Profile.new(name, status)
+ end
+ h = jtext["processes"]
+ h.each do |name, pidmap|
+ pidmap.each do |p|
+ entries[name].addPid(p["pid"])
+ end
+ end
+ return entries
+ end
+ end
+
+ class Profiles
+ STATUS_CMD = "sudo /usr/sbin/aa-status --json"
+ attr_reader :raw, :prof
+ def initialize()
+ cmd = "#{STATUS_CMD}"
+ stdin, stdout, stderr, wait_thr = Open3.popen3(cmd)
+ @prof = ProfileMap.all(stdout.read)
+ end
+
+ def remove(name)
+ e = @prof.delete(name)
+ # execute file deletion?
+ end
+
+ def active()
+ # Select the ones which have pids
+ @prof.select { | name, pr | pr.pid.length > 0 }
+ end
+
+ def all()
+ return @prof
+ end
+
+ def toggle(name)
+ @prof[name].toggle
+ end
+ end
+
+ class ProfilesDialog
+ include Yast::UIShortcuts
+ include Yast::I18n
+ include Yast::Logger
+
+ def initialize
+ @profiles = Profiles.new
+ @active = true
+ end
+
+ def run
+ return unless create_dialog
+
+ begin
+ return event_loop
+ ensure
+ close_dialog
+ end
+ end
+
+ private
+ def create_dialog
+ Yast::UI.OpenDialog(
+ Opt(:decorated, :defaultsize),
+ VBox(
+ #Header
+ Heading(_("Profile List")),
+ # Active profiles
+ Left(
+ CheckBox(Id(:active_only), Opt(:notify), _("Show Active only"),
@active)
+ ),
+ VSpacing(0.4),
+ # Profile List
+ table,
+ VSpacing(0.3),
+ # Footer buttons
+ HBox(
+ HWeight(1, PushButton(Id(:changeMode), _("Change mode"))),
+ HStretch(),
+ HWeight(1, PushButton(Id(:finish), Yast::Label.FinishButton))
+ )
+ )
+ )
+ end
+
+ def table
+ headers = Array[_("Name"), _("Mode"), _("PID")]
+ Table(
+ Id(:entries_table),
+ Opt(:keepSorting),
+ Header(*headers),
+ table_items
+ )
+ end
+
+ def table_items
+ if @active
+ profs = @profiles.active
+ else
+ profs = @profiles.all
+ end
+ arr = Array.new
+ profs.each do | n, pr |
+ arr.push(pr.to_array)
+ end
+ arr.map { |i| Item(*i) }
+ end
+
+ def redraw_table
+ Yast::UI.ChangeWidget(Id(:entries_table), :Items, table_items)
+ end
+
+ def event_loop
+ loop do
+ case Yast::UI.UserInput
+ when :active_only
+ @active = Yast::UI.QueryWidget(Id(:active_only), :Value)
+ redraw_table
+ when :cancel
+ break
+ when :changeMode
+ selectedItem = Yast::UI.QueryWidget(Id(:entries_table), :CurrentItem)
+ log.info "Toggling #{selectedItem}"
+ @profiles.toggle(selectedItem)
+ redraw_table
+ when :finish
+ break
+ end
+ end
+ end
+
+ def close_dialog
+ Yast::UI.CloseDialog
+ end
+ end
+end
+
--
2.12.3

--
To unsubscribe, e-mail: yast-devel+unsubscribe@xxxxxxxxxxxx
To contact the owner, e-mail: yast-devel+owner@xxxxxxxxxxxx

< Previous Next >
Follow Ups
References