diff options
Diffstat (limited to 'apol/terules_tab.tcl')
-rw-r--r-- | apol/terules_tab.tcl | 1034 |
1 files changed, 1034 insertions, 0 deletions
diff --git a/apol/terules_tab.tcl b/apol/terules_tab.tcl new file mode 100644 index 0000000..c5a490f --- /dev/null +++ b/apol/terules_tab.tcl @@ -0,0 +1,1034 @@ +# Copyright (C) 2001-2007 Tresys Technology, LLC +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# 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, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +namespace eval Apol_TE { + variable vals + variable widgets + variable tabs + variable enabled +} + +proc Apol_TE::create {tab_name nb} { + variable vals + variable widgets + + _initializeVars + + set frame [$nb insert end $tab_name -text "TE Rules"] + set pw [PanedWindow $frame.pw -side left -weights extra] + set topf [$pw add -weight 0] + set bottomf [$pw add -weight 1] + pack $pw -expand 1 -fill both + + # Major SubFrames: + # rsbox - rule selection + # oobox - other search options + # obox - holds search options widgets + # rbox - holds display window widgets + # abox - action buttons + set top_leftf [frame $topf.tl] + set widgets(search_opts) [NoteBook $topf.nb] + set abox [frame $topf.abox] + pack $top_leftf -side left -expand 0 -fill y + pack $widgets(search_opts) -side left -expand 1 -fill both -padx 10 + pack $abox -side right -fill y -padx 5 + set rsbox [TitleFrame $top_leftf.rsbox -text "Rule Selection"] + set oobox [TitleFrame $top_leftf.oobox -text "Search Options"] + set rbox [TitleFrame $bottomf.rbox -text "Type Enforcement Rules Display"] + pack $rsbox -side top -expand 0 -fill both + pack $oobox -side top -expand 1 -fill both -pady 2 + pack $rbox -expand yes -fill both -padx 2 + + # Rule selection subframe + set fm_rules [$rsbox getframe] + set allow [checkbutton $fm_rules.allow -text "allow" \ + -onvalue $::QPOL_RULE_ALLOW -offvalue 0 \ + -variable Apol_TE::vals(rs:avrule_allow)] + set neverallow [checkbutton $fm_rules.neverallow -text "neverallow" \ + -onvalue $::QPOL_RULE_NEVERALLOW -offvalue 0 \ + -variable Apol_TE::vals(rs:avrule_neverallow)] + set auditallow [checkbutton $fm_rules.auditallow -text "auditallow" \ + -onvalue $::QPOL_RULE_AUDITALLOW -offvalue 0 \ + -variable Apol_TE::vals(rs:avrule_auditallow)] + set dontaudit [checkbutton $fm_rules.dontaudit -text "dontaudit" \ + -onvalue $::QPOL_RULE_DONTAUDIT -offvalue 0 \ + -variable Apol_TE::vals(rs:avrule_dontaudit)] + set type_transition [checkbutton $fm_rules.type_transition -text "type_trans" \ + -onvalue $::QPOL_RULE_TYPE_TRANS -offvalue 0 \ + -variable Apol_TE::vals(rs:type_transition)] + set type_member [checkbutton $fm_rules.type_member -text "type_member" \ + -onvalue $::QPOL_RULE_TYPE_MEMBER -offvalue 0 \ + -variable Apol_TE::vals(rs:type_member)] + set type_change [checkbutton $fm_rules.type_change -text "type_change" \ + -onvalue $::QPOL_RULE_TYPE_CHANGE -offvalue 0 \ + -variable Apol_TE::vals(rs:type_change)] + grid $allow $type_transition -sticky w -padx 2 + grid $auditallow $type_member -sticky w -padx 2 + grid $dontaudit $type_change -sticky w -padx 2 + grid $neverallow x -sticky w -padx 2 + foreach x {allow neverallow auditallow dontaudit type_transition type_member type_change} { + trace add variable Apol_TE::vals(rs:$x) write \ + [list Apol_TE::_toggle_rule_selection] + } + + # Other search options subframe + set fm_options [$oobox getframe] + set enabled [checkbutton $fm_options.enabled -text "Search only enabled rules" \ + -variable Apol_TE::vals(oo:enabled)] + set regexp [checkbutton $fm_options.regex -text "Search using regular expression" \ + -variable Apol_TE::vals(oo:regexp)] + pack $enabled $regexp -expand 0 -fill none -anchor w + + _createTypesAttribsTab + _createClassesPermsTab + + # Action buttons + set widgets(new) [button $abox.new -text "New Search" -width 12 \ + -command [list Apol_TE::_search_terules new]] + set widgets(update) [button $abox.update -text "Update Search" -width 12 -state disabled \ + -command [list Apol_TE::_search_terules update]] + set widgets(reset) [button $abox.reset -text "Reset Criteria" -width 12 \ + -command Apol_TE::_reset] + pack $widgets(new) $widgets(update) $widgets(reset) \ + -side top -pady 5 -padx 5 -anchor ne + + $widgets(search_opts) compute_size + + # Popup menu widget + set popupTab_Menu [menu .popup_terules -tearoff 0] + set tab_menu_callbacks \ + [list {"Close Tab" Apol_TE::_delete_results} \ + {"Rename Tab" Apol_TE::_display_rename_tab_dialog}] + + # Notebook creation for results + set widgets(results) [NoteBook [$rbox getframe].results] + $widgets(results) bindtabs <Button-1> Apol_TE::_switch_to_tab + $widgets(results) bindtabs <Button-3> \ + [list ApolTop::popup \ + %W %x %y $popupTab_Menu $tab_menu_callbacks] + set close [button [$rbox getframe].close -text "Close Tab" \ + -command Apol_TE::_delete_current_results] + pack $widgets(results) -expand 1 -fill both -padx 4 + pack $close -expand 0 -fill x -padx 4 -pady 2 + + _initializeVars + + return $frame +} + +proc Apol_TE::open {ppath} { + _initializeVars + _initializeWidgets + _initializeTabs + + variable vals + variable enabled + set vals(cp:classes) [Apol_Class_Perms::getClasses] + set enabled(cp:classes) 1 + set enabled(cp:perms) 1 +} + +proc Apol_TE::close {} { + _initializeTabs + _initializeWidgets + _initializeVars + set enabled(cp:perms) 1 +} + +proc Apol_TE::getTextWidget {} { + variable widgets + variable tabs + if {[$widgets(results) pages] != {}} { + set raisedPage [$widgets(results) raise] + if {$raisedPage != {}} { + return $tabs($raisedPage).tb + } + } + return {} +} + +proc Apol_TE::save_query_options {file_channel query_file} { + variable vals + foreach {key value} [array get vals] { + if {$key != "cp:classes" && $key != "cp:perms"} { + puts $file_channel "$key $value" + } + } +} + +proc Apol_TE::load_query_options {file_channel} { + variable vals + variable widgets + variable enabled + _initializeVars + + # load as many values as possible + set classes_selected {} + set perms_selected {} + while {[gets $file_channel line] >= 0} { + set line [string trim $line] + # Skip empty lines and comments + if {$line == {} || [string index $line 0] == "#"} { + continue + } + regexp -line -- {^(\S+)( (.+))?} $line -> key --> value + if {$key == "cp:classes_selected"} { + set classes_selected $value + } elseif {$key == "cp:perms_selected"} { + set perms_selected $value + } else { + set vals($key) $value + } + } + + # update the display + _initializeWidgets + set vals(cp:classes) [Apol_Class_Perms::getClasses] + set enabled(cp:classes) 1 + set enabled(cp:perms) 1 + _toggle_perms_toshow -> -> reset + + # then verify that selected object classes and permissions exist + # for this policy + + set unknowns {} + set vals(cp:classes_selected) {} + foreach class $classes_selected { + if {[set i [lsearch $vals(cp:classes) $class]] >= 0} { + $widgets(cp:classes) selection set $i + lappend vals(cp:classes_selected) $class + } else { + lappend unknowns $class + } + } + if {[llength $unknowns] > 0} { + tk_messageBox -icon warning -type ok -title "Open Apol Query" \ + -message "The following object classes do not exist in the currently loaded policy and were ignored:\n\n[join $unknowns ", "]" \ + -parent . + } + + _toggle_perms_toshow {} {} {} + set unknowns {} + set vals(cp:perms_selected) {} + foreach perm $perms_selected { + if {[set i [lsearch $vals(cp:perms) $perm]] >= 0} { + $widgets(cp:perms) selection set $i + lappend vals(cp:perms_selected) $perm + } else { + lappend unknowns $perm + } + } + if {[llength $unknowns] > 0} { + tk_messageBox -icon warning -type ok -title "Open Apol Query" \ + -message "The following permissions do not exist in the currently loaded policy and were ignored:\n\n[join $unknowns ", "]" \ + -parent $parentDlg + } +} + +#### private functions below #### + +proc Apol_TE::_initializeVars {} { + variable vals + array set vals [list \ + rs:avrule_allow $::QPOL_RULE_ALLOW \ + rs:avrule_neverallow 0 \ + rs:avrule_auditallow $::QPOL_RULE_AUDITALLOW \ + rs:avrule_dontaudit $::QPOL_RULE_DONTAUDIT \ + rs:type_transition $::QPOL_RULE_TYPE_TRANS \ + rs:type_member $::QPOL_RULE_TYPE_MEMBER \ + rs:type_change $::QPOL_RULE_TYPE_CHANGE \ + ta:source_sym,types $::APOL_QUERY_SYMBOL_IS_TYPE \ + ta:target_sym,types $::APOL_QUERY_SYMBOL_IS_TYPE \ + ta:default_sym,types $::APOL_QUERY_SYMBOL_IS_TYPE \ + ] + + array set vals { + oo:enabled 0 + oo:regexp 0 + + ta:use_source 0 + ta:source_indirect 1 + ta:source_which source + ta:source_sym,attribs 0 + ta:source_sym {} + + ta:use_target 0 + ta:target_indirect 1 + ta:target_sym,attribs 0 + ta:target_sym {} + + ta:use_default 0 + ta:default_sym,attribs 0 + ta:default_sym {} + + cp:classes {} + cp:classes_selected {} + cp:perms {} + cp:perms_selected {} + cp:perms_toshow all + cp:perms_matchall 0 + } + + variable enabled + array set enabled { + ta:use_source 1 + ta:use_target 1 + ta:use_default 1 + + cp:classes 0 + cp:perms 0 + } +} + +proc Apol_TE::_initializeTabs {} { + variable widgets + variable tabs + array set tabs { + next_result_id 1 + } + foreach p [$widgets(results) pages 0 end] { + _delete_results $p + } +} + +proc Apol_TE::_initializeWidgets {} { + variable widgets + $widgets(search_opts) raise typeattrib + + $widgets(cp:classes) selection clear 0 end + $widgets(cp:perms) selection clear 0 end +} + +proc Apol_TE::_createTypesAttribsTab {} { + variable vals + variable widgets + variable enabled + + set ta_tab [$widgets(search_opts) insert end typeattrib -text "Types/Attributes"] + set fm_source [frame $ta_tab.source] + set fm_target [frame $ta_tab.target] + set fm_default [frame $ta_tab.default] + grid $fm_source $fm_target $fm_default -padx 4 -sticky ewns + foreach i {0 1 2} { + grid columnconfigure $ta_tab $i -weight 1 -uniform 1 + } + grid rowconfigure $ta_tab 0 -weight 1 + + _create_ta_box source $fm_source "Source type/attribute" 1 1 1 + _create_ta_box target $fm_target "Target type/attribute" 1 0 1 + _create_ta_box default $fm_default "Default type" 0 0 0 + + $widgets(search_opts) raise typeattrib +} + +proc Apol_TE::_create_ta_box {prefix f title has_indirect has_which has_attribs} { + variable vals + variable widgets + + set widgets(ta:use_${prefix}) [checkbutton $f.use -text $title \ + -variable Apol_TE::vals(ta:use_${prefix})] + pack $widgets(ta:use_${prefix}) -side top -anchor w + trace add variable Apol_TE::vals(ta:use_${prefix}) write \ + [list Apol_TE::_toggle_ta_box $prefix] + + set w {} + + if {$has_attribs} { + set helptext "Type or select a type or attribute" + } else { + set helptext "Type or select a type" + } + set widgets(ta:${prefix}_sym) [ComboBox $f.sym \ + -state disabled -entrybg $ApolTop::default_bg_color \ + -textvariable Apol_TE::vals(ta:${prefix}_sym) \ + -helptext $helptext -autopost 1] + pack $widgets(ta:${prefix}_sym) -expand 0 -fill x -padx 8 + lappend w $widgets(ta:${prefix}_sym) + + if {$has_attribs} { + set ta_frame [frame $f.ta] + pack $ta_frame -expand 0 -anchor center -pady 2 + set types [checkbutton $ta_frame.types -text "Types" -state disabled \ + -onvalue $::APOL_QUERY_SYMBOL_IS_TYPE -offvalue 0 \ + -variable Apol_TE::vals(ta:${prefix}_sym,types)] + set attribs [checkbutton $ta_frame.attribs -text "Attribs" -state disabled \ + -onvalue $::APOL_QUERY_SYMBOL_IS_ATTRIBUTE -offvalue 0 \ + -variable Apol_TE::vals(ta:${prefix}_sym,attribs)] + $types configure -command [list Apol_TE::_toggle_ta_pushed $prefix $types] + $attribs configure -command [list Apol_TE::_toggle_ta_pushed $prefix $attribs] + trace add variable Apol_TE::vals(ta:${prefix}_sym,attribs) write \ + [list Apol_TE::_toggle_ta_sym $prefix] + pack $types $attribs -side left -padx 2 + lappend w $types $attribs + } + + if {$has_indirect} { + set indirect [checkbutton $f.indirect -text "Only direct matches" \ + -state disabled -variable Apol_TE::vals(ta:${prefix}_indirect) \ + -onvalue 0 -offvalue 1] + pack $indirect -anchor w -padx 8 + lappend w $indirect + } + + if {$has_which} { + set which_fm [frame $f.which] + set which_source [radiobutton $which_fm.source \ + -text "As source" -state disabled \ + -variable Apol_TE::vals(ta:${prefix}_which) \ + -value source] + set which_any [radiobutton $which_fm.any \ + -text "Any" -state disabled \ + -variable Apol_TE::vals(ta:${prefix}_which) \ + -value either] + trace add variable Apol_TE::vals(ta:${prefix}_which) write \ + [list Apol_TE::_toggle_which] + pack $which_source $which_any -side left -padx 2 + pack $which_fm -anchor w -padx 6 + lappend w $which_source $which_any + } + + # update contents of the combobox whenever the 'Types' checkbutton + # is enabled; for default type, this is invoked by a call to + # reinitialize_default_search_options + trace add variable Apol_TE::vals(ta:${prefix}_sym,types) write \ + [list Apol_TE::_toggle_ta_sym $prefix] + + set widgets(ta:${prefix}_widgets) $w + trace add variable Apol_TE::enabled(ta:use_${prefix}) write \ + [list Apol_TE::_toggle_enable_ta ${prefix}] +} + +proc Apol_TE::_toggle_rule_selection {name1 name2 op} { + _maybe_enable_default_type + _maybe_enable_perms +} + + +## lots of obscure callbacks here to determine when to enable a ta box ## + + +# called when there is a change in state to the top checkbutton within +# a ta box +proc Apol_TE::_toggle_ta_box {col name1 name2 op} { + variable vals + variable enabled + if {$col == "source"} { + _maybe_enable_target_type + _maybe_enable_default_type + } + + # force a refresh of this box's state; this invokes + # _toggle_enable_ta callback + set enabled(ta:use_${col}) $enabled(ta:use_${col}) +} + +# disable target type/attrib and default type if source box is marked as "any" +proc Apol_TE::_toggle_which {name1 name2 op} { + _maybe_enable_target_type + _maybe_enable_default_type +} + +proc Apol_TE::_maybe_enable_target_type {} { + variable vals + variable enabled + + set any_set 0 + if {$enabled(ta:use_source) && $vals(ta:use_source) && $vals(ta:source_which) == "either"} { + set any_set 1 + } + if {!$any_set} { + set enabled(ta:use_target) 1 + } else { + set enabled(ta:use_target) 0 + } +} + +proc Apol_TE::_maybe_enable_default_type {} { + variable vals + variable enabled + + set typerule_set 0 + set any_set 0 + foreach x {type_transition type_member type_change} { + if {$vals(rs:$x)} { + set typerule_set 1 + break + } + } + if {$enabled(ta:use_source) && $vals(ta:use_source) && $vals(ta:source_which) == "either"} { + set any_set 1 + } + if {$typerule_set && !$any_set} { + set enabled(ta:use_default) 1 + } else { + set enabled(ta:use_default) 0 + } +} + +# called whenever a ta box is enabled or disabled +proc Apol_TE::_toggle_enable_ta {col name1 name2 op} { + variable vals + variable widgets + variable enabled + if {$enabled(ta:use_${col})} { + $widgets(ta:use_${col}) configure -state normal + } else { + $widgets(ta:use_${col}) configure -state disabled + } + if {$enabled(ta:use_${col}) && $vals(ta:use_${col})} { + foreach w $widgets(ta:${col}_widgets) { + $w configure -state normal + } + $widgets(ta:${col}_sym) configure -entrybg white + } else { + foreach w $widgets(ta:${col}_widgets) { + $w configure -state disabled + } + $widgets(ta:${col}_sym) configure -entrybg $ApolTop::default_bg_color + } + + # update this tab's name if one of the columns is enabled and used + if {($enabled(ta:use_source) && $vals(ta:use_source)) || \ + ($enabled(ta:use_target) && $vals(ta:use_target)) || \ + ($enabled(ta:use_default) && $vals(ta:use_default))} { + $widgets(search_opts) itemconfigure typeattrib -text "Types/Attributes *" + } else { + $widgets(search_opts) itemconfigure typeattrib -text "Types/Attributes" + } +} + +proc Apol_TE::_toggle_ta_sym {col name1 name2 op} { + variable vals + variable widgets + + if {!$vals(ta:${col}_sym,types) && !$vals(ta:${col}_sym,attribs)} { + # don't change combobox if both types and attribs are deselected + return + } + if {$vals(ta:${col}_sym,types) && $vals(ta:${col}_sym,attribs)} { + set items [lsort [concat [Apol_Types::getTypes] [Apol_Types::getAttributes]]] + } elseif {$vals(ta:${col}_sym,types)} { + set items [Apol_Types::getTypes] + } else { + set items [Apol_Types::getAttributes] + } + $widgets(ta:${col}_sym) configure -values $items +} + +# disallow both types and attribs to be deselected within a ta box +proc Apol_TE::_toggle_ta_pushed {col cb} { + variable vals + if {!$vals(ta:${col}_sym,types) && !$vals(ta:${col}_sym,attribs)} { + $cb select + } +} + +# code to create and handle the classe/permissions subtab + +proc Apol_TE::_createClassesPermsTab {} { + variable vals + variable widgets + variable enabled + + set objects_tab [$widgets(search_opts) insert end classperms -text "Classes/Permissions"] + set fm_objs [TitleFrame $objects_tab.objs -text "Object Classes"] + set fm_perms [TitleFrame $objects_tab.perms -text "AV Rule Permissions"] + pack $fm_objs -side left -expand 0 -fill both -padx 2 -pady 2 + pack $fm_perms -side left -expand 1 -fill both -padx 2 -pady 2 + + # object classes subframe + set sw [ScrolledWindow [$fm_objs getframe].sw -auto both] + set widgets(cp:classes) [listbox [$sw getframe].lb -height 5 -width 24 \ + -highlightthickness 0 -selectmode multiple \ + -exportselection 0 -state disabled \ + -bg $ApolTop::default_bg_color \ + -listvar Apol_TE::vals(cp:classes)] + $sw setwidget $widgets(cp:classes) + update + grid propagate $sw 0 + bind $widgets(cp:classes) <<ListboxSelect>> \ + [list Apol_TE::_toggle_cp_select classes] + pack $sw -expand 1 -fill both + set clear [button [$fm_objs getframe].b -text "Clear" -width 6 -state disabled \ + -command [list Apol_TE::_clear_cp_listbox $widgets(cp:classes) classes]] + pack $clear -expand 0 -pady 2 + set widgets(cp:classes_widgets) [list $widgets(cp:classes) $clear] + + # permissions subframe + set f [$fm_perms getframe] + set sw [ScrolledWindow $f.sw -auto both] + set widgets(cp:perms) [listbox [$sw getframe].lb -height 5 -width 24 \ + -highlightthickness 0 -selectmode multiple \ + -exportselection 0 -bg white \ + -listvar Apol_TE::vals(cp:perms)] + $sw setwidget $widgets(cp:perms) + update + grid propagate $sw 0 + bind $widgets(cp:perms) <<ListboxSelect>> \ + [list Apol_TE::_toggle_cp_select perms] + set clear [button $f.clear -text "Clear" \ + -command [list Apol_TE::_clear_cp_listbox $widgets(cp:perms) perms]] + set reverse [button $f.reverse -text "Reverse" \ + -command [list Apol_TE::_reverse_cp_listbox $widgets(cp:perms)]] + set perm_opts_f [frame $f.perms] + set perm_rb_f [frame $perm_opts_f.rb] + set l [label $perm_rb_f.l -text "Permissions to show:" -state disabled] + set all [radiobutton $perm_rb_f.all -text "All" \ + -variable Apol_TE::vals(cp:perms_toshow) -value all] + set union [radiobutton $perm_rb_f.union -text "All for selected classes" \ + -variable Apol_TE::vals(cp:perms_toshow) -value union] + set intersect [radiobutton $perm_rb_f.inter -text "Common to selected classes" \ + -variable Apol_TE::vals(cp:perms_toshow) -value intersect] + trace add variable Apol_TE::vals(cp:perms_toshow) write \ + Apol_TE::_toggle_perms_toshow + pack $l $all $union $intersect -anchor w + set all_perms [checkbutton $perm_opts_f.all -text "AV rule must have all selected permissions" \ + -variable Apol_TE::vals(cp:perms_matchall)] + pack $perm_rb_f $all_perms -anchor w -pady 4 -padx 4 + grid $sw - $perm_opts_f -sticky nsw + grid $clear $reverse ^ -pady 2 -sticky ew + grid columnconfigure $f 0 -weight 0 -uniform 1 -pad 2 + grid columnconfigure $f 1 -weight 0 -uniform 1 -pad 2 + grid columnconfigure $f 2 -weight 1 + grid rowconfigure $f 0 -weight 1 + set widgets(cp:perms_widgets) \ + [list $widgets(cp:perms) $clear $reverse $l $all $union $intersect $all_perms] + + trace add variable Apol_TE::vals(cp:classes_selected) write \ + [list Apol_TE::_update_cp_tabname] + trace add variable Apol_TE::vals(cp:perms_selected) write \ + [list Apol_TE::_update_cp_tabname] + trace add variable Apol_TE::enabled(cp:classes) write \ + [list Apol_TE::_toggle_enable_cp classes] + trace add variable Apol_TE::enabled(cp:perms) write \ + [list Apol_TE::_toggle_enable_cp perms] +} + +proc Apol_TE::_toggle_enable_cp {prefix name1 name2 op} { + variable vals + variable widgets + variable enabled + if {$enabled(cp:${prefix})} { + foreach w $widgets(cp:${prefix}_widgets) { + $w configure -state normal + } + $widgets(cp:${prefix}) configure -bg white + } else { + foreach w $widgets(cp:${prefix}_widgets) { + $w configure -state disabled + } + $widgets(cp:${prefix}) configure -bg $ApolTop::default_bg_color + } + # force a refresh of this tab's name + set vals(cp:${prefix}_selected) $vals(cp:${prefix}_selected) +} + +proc Apol_TE::_maybe_enable_perms {} { + variable vals + variable enabled + + set avrule_set 0 + foreach x {avrule_allow avrule_neverallow avrule_auditallow avrule_dontaudit} { + if {$vals(rs:$x)} { + set avrule_set 1 + break + } + } + if {$avrule_set} { + set enabled(cp:perms) 1 + } else { + set enabled(cp:perms) 0 + } +} + +proc Apol_TE::_toggle_perms_toshow {name1 name2 op} { + variable vals + variable widgets + if {$vals(cp:perms_toshow) == "all"} { + # don't change the list of permissions if there was a new + # object class selection and the current radiobutton is all + if {$op != "update"} { + set vals(cp:perms) $Apol_Class_Perms::perms_list + set vals(cp:perms_selected) {} + } + } elseif {$vals(cp:perms_toshow) == "union"} { + set vals(cp:perms) {} + set vals(cp:perms_selected) {} + foreach class $vals(cp:classes_selected) { + set vals(cp:perms) [lsort -unique -dictionary [concat $vals(cp:perms) [Apol_Class_Perms::getPermsForClass $class]]] + } + } else { ;# intersection + set vals(cp:perms) {} + set vals(cp:perms_selected) {} + set classes {} + foreach i [$widgets(cp:classes) curselection] { + lappend classes [$widgets(cp:classes) get $i] + } + if {$classes == {}} { + return + } + set vals(cp:perms) [Apol_Class_Perms::getPermsForClass [lindex $classes 0]] + foreach class [lrange $classes 1 end] { + set this_perms [Apol_Class_Perms::getPermsForClass $class] + set new_perms {} + foreach p $vals(cp:perms) { + if {[lsearch -exact $this_perms $p] >= 0} { + lappend new_perms $p + } + } + set vals(cp:perms) $new_perms + } + } +} + +# called whenever an item with a class/perm listbox is +# selected/deselected +proc Apol_TE::_toggle_cp_select {col} { + variable vals + variable widgets + set items {} + foreach i [$widgets(cp:${col}) curselection] { + lappend items [$widgets(cp:${col}) get $i] + } + set vals(cp:${col}_selected) $items + if {$col == "classes"} { + _toggle_perms_toshow {} {} update + } +} + +proc Apol_TE::_clear_cp_listbox {lb prefix} { + variable vals + $lb selection clear 0 end + set vals(cp:${prefix}_selected) {} + if {$prefix == "classes"} { + _toggle_perms_toshow {} {} update + } +} + +proc Apol_TE::_reverse_cp_listbox {lb} { + variable vals + set old_selection [$lb curselection] + set items {} + for {set i 0} {$i < [$lb index end]} {incr i} { + if {[lsearch $old_selection $i] >= 0} { + $lb selection clear $i + } else { + $lb selection set $i + lappend items [$lb get $i] + } + } + set vals(cp:perms_selected) $items +} + +proc Apol_TE::_update_cp_tabname {name1 name2 op} { + variable vals + variable widgets + variable enabled + if {($enabled(cp:classes) && $vals(cp:classes_selected) > 0) || \ + ($enabled(cp:perms) && $vals(cp:perms_selected) > 0)} { + $widgets(search_opts) itemconfigure classperms -text "Classes/Permissions *" + } else { + $widgets(search_opts) itemconfigure classperms -text "Classes/Permissions" + } +} + +proc Apol_TE::_delete_results {pageID} { + variable widgets + variable tabs + + # Remove tab and its widgets + set curpos [$widgets(results) index $pageID] + $widgets(results) delete $pageID + array unset tabs $pageID:* + array unset tabs $pageID + + # try to raise the next tab + if {[set next_id [$widgets(results) pages $curpos]] != {}} { + _switch_to_tab $next_id + } elseif {$curpos > 0} { + # raise the previous page instead + _switch_to_tab [$widgets(results) pages [expr {$curpos - 1}]] + } else { + # no tabs remaining + $widgets(update) configure -state disabled + } +} + +proc Apol_TE::_display_rename_tab_dialog {pageID} { + variable widgets + variable tabs + set d [Dialog .apol_te_tab_rename -homogeneous 1 -spacing 2 -cancel 1 \ + -default 0 -modal local -parent . -place center -separator 1 \ + -side bottom -title "Rename Results Tab"] + $d add -text "OK" -command [list $d enddialog "ok"] + $d add -text "Cancel" -command [list $d enddialog "cancel"] + set f [$d getframe] + set l [label $f.l -text "Tab name:"] + set tabs(tab:new_name) [$widgets(results) itemcget $pageID -text] + set e [entry $f.e -textvariable Apol_TE::tabs(tab:new_name) -width 16 -bg white] + pack $l $e -side left -padx 2 + set retval [$d draw] + destroy $d + if {$retval == "ok"} { + $widgets(results) itemconfigure $pageID -text $tabs(tab:new_name) + } +} + +proc Apol_TE::_delete_current_results {} { + variable widgets + if {[set curid [$widgets(results) raise]] != {}} { + _delete_results $curid + } +} + +proc Apol_TE::_create_new_results_tab {} { + variable vals + variable widgets + variable tabs + + set i $tabs(next_result_id) + incr tabs(next_result_id) + set id "results$i" + set frame [$widgets(results) insert end "$id" -text "Results $i"] + $widgets(results) raise $id + set tabs($id) [Apol_Widget::makeSearchResults $frame.results] + pack $tabs($id) -expand 1 -fill both + + set tabs($id:vals) [array get vals] + return $tabs($id) +} + +proc Apol_TE::_switch_to_tab {pageID} { + variable vals + variable widgets + variable tabs + + # check if switching to already visible tab + if {[$Apol_TE::widgets(results) raise] == $pageID} { + return + } + $widgets(results) raise $pageID + set cur_search_opts [$widgets(search_opts) raise] + + # restore the tab's search criteria + array set tmp_vals $tabs($pageID:vals) + set classes_selected $tmp_vals(cp:classes_selected) + set perms_selected $tmp_vals(cp:perms_selected) + array set vals $tabs($pageID:vals) + _initializeWidgets + set vals(cp:classes_selected) $classes_selected + set vals(cp:perms_selected) $perms_selected + foreach c $classes_selected { + $widgets(cp:classes) selection set [lsearch $vals(cp:classes) $c] + } + foreach p $perms_selected { + $widgets(cp:perms) selection set [lsearch $vals(cp:perms) $p] + } + $widgets(search_opts) raise $cur_search_opts +} + +######################################################################## + +proc Apol_TE::_reset {} { + variable enabled + set old_classes_enabled $enabled(cp:classes) + _initializeVars + _initializeWidgets + if {[set enabled(cp:classes) $old_classes_enabled]} { + variable vals + set vals(cp:classes) [Apol_Class_Perms::getClasses] + set enabled(cp:classes) 1 + set enabled(cp:perms) 1 + } +} + +proc Apol_TE::_search_terules {whichButton} { + variable vals + variable widgets + variable enabled + variable tabs + + if {![ApolTop::is_policy_open]} { + tk_messageBox -icon error -type ok -title "TE Rule Search" -message "No current policy file is opened." + return + } + + # check search options + if {$enabled(ta:use_source) && $vals(ta:use_source) && $vals(ta:source_sym) == {}} { + tk_messageBox -icon error -type ok -title "TE Rule Search" -message "No source type/attribute was selected." + return + } + if {$enabled(ta:use_target) && $vals(ta:use_target) && $vals(ta:target_sym) == {}} { + tk_messageBox -icon error -type ok -title "TE Rule Search" -message "No target type/attribute was selected." + return + } + if {$enabled(ta:use_default) && $vals(ta:use_default) && $vals(ta:default_sym) == {}} { + + tk_messageBox -icon error -type ok -title "TE Rule Search" -message "No default type selected." + return + } + + set avrule_selection 0 + foreach {key value} [array get vals rs:avrule_*] { + set avrule_selection [expr {$avrule_selection | $value}] + } + set terule_selection 0 + foreach {key value} [array get vals rs:type_*] { + set terule_selection [expr {$terule_selection | $value}] + } + if {$avrule_selection == 0 && $terule_selection == 0} { + tk_messageBox -icon error -type ok -title "TE Rule Search" -message "At least one rule must be selected." + return + } + + # start building queries + set avq [new_apol_avrule_query_t] + set teq [new_apol_terule_query_t] + + if {$enabled(ta:use_source) && $vals(ta:use_source)} { + if {$vals(ta:source_which) == "either"} { + $avq set_source_any $::ApolTop::policy 1 + } + $avq set_source $::ApolTop::policy $vals(ta:source_sym) $vals(ta:source_indirect) + $avq set_source_component $::ApolTop::policy [expr {$vals(ta:source_sym,types) | $vals(ta:source_sym,attribs)}] + $teq set_source $::ApolTop::policy $vals(ta:source_sym) $vals(ta:source_indirect) + $teq set_source_component $::ApolTop::policy [expr {$vals(ta:source_sym,types) | $vals(ta:source_sym,attribs)}] + } + if {$enabled(ta:use_target) && $vals(ta:use_target)} { + $avq set_target $::ApolTop::policy $vals(ta:target_sym) $vals(ta:target_indirect) + $avq set_target_component $::ApolTop::policy [expr {$vals(ta:target_sym,types) | $vals(ta:target_sym,attribs)}] + $teq set_target $::ApolTop::policy $vals(ta:target_sym) $vals(ta:target_indirect) + $teq set_target_component $::ApolTop::policy [expr {$vals(ta:target_sym,types) | $vals(ta:target_sym,attribs)}] + } + if {$enabled(ta:use_default) && $vals(ta:use_default)} { + $teq set_default $::ApolTop::policy $vals(ta:default_sym) + } + + if {$enabled(cp:classes)} { + foreach c $vals(cp:classes_selected) { + $avq append_class $::ApolTop::policy $c + $teq append_class $::ApolTop::policy $c + } + } + if {$enabled(cp:perms)} { + foreach p $vals(cp:perms_selected) { + $avq append_perm $::ApolTop::policy $p + } + $avq set_all_perms $::ApolTop::policy $vals(cp:perms_matchall) + } + + $avq set_rules $::ApolTop::policy $avrule_selection + $teq set_rules $::ApolTop::policy $terule_selection + $avq set_enabled $::ApolTop::policy $vals(oo:enabled) + $teq set_enabled $::ApolTop::policy $vals(oo:enabled) + $avq set_regex $::ApolTop::policy $vals(oo:regexp) + $teq set_regex $::ApolTop::policy $vals(oo:regexp) + + foreach x {new update reset} { + $widgets($x) configure -state disabled + } + + if {$vals(rs:avrule_neverallow)} { + ApolTop::loadNeverAllows + } + if {![ApolTop::is_capable "neverallow"]} { + set avrule_selection [expr {$avrule_selection & (~$::QPOL_RULE_NEVERALLOW)}] + $avq set_rules $::ApolTop::policy $avrule_selection + } + + Apol_Progress_Dialog::wait "TE Rules" "Searching rules" \ + { + set numTEs {0 0 0} + set numAVs {0 0 0} + set avresults NULL + set teresults NULL + set num_avresults 0 + set num_teresults 0 + if {![ApolTop::is_capable "syntactic rules"]} { + if {$avrule_selection != 0} { + set avresults [$avq run $::ApolTop::policy] + } + if {$terule_selection != 0} { + set teresults [$teq run $::ApolTop::policy] + } + } else { + $::ApolTop::qpolicy build_syn_rule_table + if {$avrule_selection != 0} { + set avresults [$avq run_syn $::ApolTop::policy] + } + if {$terule_selection != 0} { + set teresults [$teq run_syn $::ApolTop::policy] + } + } + + $avq -acquire + $avq -delete + $teq -acquire + $teq -delete + if {$avresults != "NULL"} { + set num_avresults [$avresults get_size] + } + if {$teresults != "NULL"} { + set num_teresults [$teresults get_size] + } + + if {$whichButton == "new"} { + set sr [_create_new_results_tab] + } else { + set id [$widgets(results) raise] + set tabs($id:vals) [array get vals] + set sr $tabs($id) + Apol_Widget::clearSearchResults $sr + } + + if {![ApolTop::is_capable "syntactic rules"]} { + apol_tcl_set_info_string $::ApolTop::policy "Rendering $num_avresults AV rule results" + apol_tcl_terule_sort $::ApolTop::policy $teresults + if {$num_avresults > 0} { + set numAVs [Apol_Widget::appendSearchResultRules $sr 0 $avresults qpol_avrule_from_void] + } + apol_tcl_set_info_string $::ApolTop::policy "Rendering $num_teresults TE rule results" + apol_tcl_avrule_sort $::ApolTop::policy $avresults + if {$num_teresults > 0} { + set numTEs [Apol_Widget::appendSearchResultRules $sr 0 $teresults qpol_terule_from_void] + } + } else { + apol_tcl_set_info_string $::ApolTop::policy "Rendering $num_avresults AV rule results" + if {$num_avresults > 0} { + set numAVs [Apol_Widget::appendSearchResultSynRules $sr 0 $avresults qpol_syn_avrule_from_void] + } + apol_tcl_set_info_string $::ApolTop::policy "Rendering $num_teresults TE rule results" + if {$num_teresults > 0} { + set numTEs [Apol_Widget::appendSearchResultSynRules $sr 0 $teresults qpol_syn_terule_from_void] + } + } + set num_rules [expr {[lindex $numAVs 0] + [lindex $numTEs 0]}] + set num_enabled [expr {[lindex $numAVs 1] + [lindex $numTEs 1]}] + set num_disabled [expr {[lindex $numAVs 2] + [lindex $numTEs 2]}] + set header "$num_rules rule" + if {$num_rules != 1} { + append header s + } + append header " match the search criteria.\n" + append header "Number of enabled conditional rules: $num_enabled\n" + append header "Number of disabled conditional rules: $num_disabled\n" + Apol_Widget::appendSearchResultHeader $sr $header + } + $widgets(new) configure -state normal + $widgets(reset) configure -state normal + if {[$widgets(results) pages] != {} || $retval == 0} { + $widgets(update) configure -state normal + } +} |