# Copyright (C) 2001-2008 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_Types { variable typelist {} variable attriblist {} variable opts variable widgets } proc Apol_Types::create {tab_name nb} { variable opts variable widgets _initializeVars set frame [$nb insert end $tab_name -text "Types"] set pw1 [PanedWindow $frame.pw -side top] set left_pane [$pw1 add -weight 0] set center_pane [$pw1 add -weight 1] set tpane [frame $left_pane.t] set apane [frame $left_pane.a] set tbox [TitleFrame $tpane.tbox -text "Types"] set abox [TitleFrame $apane.abox -text "Attributes"] set obox [TitleFrame $center_pane.obox -text "Search Options"] set rbox [TitleFrame $center_pane.rbox -text "Search Results"] pack $obox -side top -expand 0 -fill both -padx 2 pack $rbox -expand yes -fill both -padx 2 pack $tbox -fill both -expand yes pack $abox -fill both -expand yes pack $pw1 -fill both -expand yes pack $tpane -fill both -expand 1 pack $apane -fill both -expand 1 set tlistbox [Apol_Widget::makeScrolledListbox [$tbox getframe].types \ -height 10 -width 20 -listvar Apol_Types::typelist] Apol_Widget::setListboxCallbacks $tlistbox \ {{"Show Type Info" {Apol_Types::_popupTypeInfo type}}} pack $tlistbox -expand 1 -fill both set alistbox [Apol_Widget::makeScrolledListbox [$abox getframe].attribs \ -height 5 -width 20 -listvar Apol_Types::attriblist] Apol_Widget::setListboxCallbacks $alistbox {{"Show Attribute Info" {Apol_Types::_popupTypeInfo attrib}}} pack $alistbox -expand 1 -fill both set ofm [$obox getframe] set fm_types_select [frame $ofm.to] set fm_attribs_select [frame $ofm.ao] pack $fm_types_select $fm_attribs_select -side left -padx 4 -pady 2 -anchor nw set types_select [checkbutton $fm_types_select.type -text "Show types" -variable Apol_Types::opts(types)] set typeattribs [checkbutton $fm_types_select.typeattribs -text "Include attributes" \ -variable Apol_Types::opts(types:show_attribs)] pack $types_select -anchor w pack $typeattribs -anchor w -padx 8 trace add variable Apol_Types::opts(types) write \ [list Apol_Types::_toggleCheckbuttons $typeattribs] set attribs_select [checkbutton $fm_attribs_select.type -text "Show attributes" \ -variable Apol_Types::opts(attribs)] set a_types [checkbutton $fm_attribs_select.types -text "Include types" \ -variable Apol_Types::opts(attribs:show_types) -state disabled] set a_typeattribs [checkbutton $fm_attribs_select.typeattribs -text "Include types' attributes" \ -variable Apol_Types::opts(attribs:show_attribs) -state disabled] pack $attribs_select -anchor w pack $a_types $a_typeattribs -anchor w -padx 8 trace add variable Apol_Types::opts(attribs) write \ [list Apol_Types::_toggleCheckbuttons [list $a_typeattribs $a_types]] set widgets(regexp) [Apol_Widget::makeRegexpEntry $ofm.regexpf] Apol_Widget::setRegexpEntryState $widgets(regexp) 1 pack $widgets(regexp) -side left -padx 4 -pady 2 -anchor nw set ok [button $ofm.ok -text OK -width 6 -command Apol_Types::_searchTypes] pack $ok -side right -padx 5 -pady 5 -anchor ne set widgets(results) [Apol_Widget::makeSearchResults [$rbox getframe].results] pack $widgets(results) -expand yes -fill both return $frame } proc Apol_Types::open {ppath} { set q [new_apol_type_query_t] set v [$q run $::ApolTop::policy] $q -acquire $q -delete variable typelist [lsort [type_vector_to_list $v]] $v -acquire $v -delete set q [new_apol_attr_query_t] set v [$q run $::ApolTop::policy] $q -acquire $q -delete variable attriblist [lsort [attr_vector_to_list $v]] $v -acquire $v -delete } proc Apol_Types::close {} { variable widgets _initializeVars set Apol_Types::typelist {} set Apol_Types::attriblist {} Apol_Widget::clearSearchResults $widgets(results) } proc Apol_Types::getTextWidget {} { variable widgets return $widgets(results).tb } # Given a type or alias name, return non-zero if that type/alias is # within the policy. If no policy has been loaded then return zero. proc Apol_Types::isTypeInPolicy {type} { if {![ApolTop::is_policy_open]} { return 0 } set q [new_apol_type_query_t] $q set_type $::ApolTop::policy $type set v [$q run $::ApolTop::policy] $q -acquire $q -delete if {$v == "NULL" || [$v get_size] == 0} { set retval 0 } else { set retval 1 } $v -acquire $v -delete set retval } # Given an attribute name, return non-zero if that attribute is within # the loaded policy. If no policy has been loaded then return zero. proc Apol_Types::isAttributeInPolicy {attrib} { variable attriblist if {[ApolTop::is_policy_open] && [lsearch $attriblist $attrib] >= 0} { return 1 } return 0 } # Return a sorted list of all type names (not attributes nor aliases) # within the current policy. If no policy is open then return an # empty list. proc Apol_Types::getTypes {} { variable typelist set typelist } # Return a list of all attribute names within the current policy. If # no policy is open then return an empty list. proc Apol_Types::getAttributes {} { variable attriblist set attriblist } #### private functions below #### proc Apol_Types::_initializeVars {} { variable opts array set opts { types 1 types:show_attribs 1 types:show_aliases 1 attribs 0 attribs:show_types 1 attribs:show_attribs 1 } } proc Apol_Types::_toggleCheckbuttons {w name1 name2 op} { variable opts variable widgets if {$opts($name2)} { foreach x $w { $x configure -state normal } } else { foreach x $w { $x configure -state disabled } } if {!$opts(types) && !$opts(attribs)} { Apol_Widget::setRegexpEntryState $widgets(regexp) 0 } else { Apol_Widget::setRegexpEntryState $widgets(regexp) 1 } } proc Apol_Types::_popupTypeInfo {which ta} { if {[Apol_File_Contexts::is_db_loaded]} { set entry_vector [Apol_File_Contexts::get_fc_files_for_ta $which $ta] set index_file_loaded 1 } else { set entry_vector {} set index_file_loaded 0 } if {$which == "type"} { set info_ta [_renderType $ta 1 1] } else { set info_ta [_renderAttrib $ta 1 0] } set w .ta_infobox destroy $w set w [Dialog .ta_infobox -cancel 0 -default 0 -modal none -parent . -separator 1 -title $ta] $w add -text "Close" -command [list destroy $w] set notebook [NoteBook [$w getframe].nb] pack $notebook -expand 1 -fill both set ta_info_tab [$notebook insert end ta_info_tab] set fc_info_tab [$notebook insert end fc_info_tab -text "Files"] if {$which == "type"} { $notebook itemconfigure ta_info_tab -text "Attributes" } else { $notebook itemconfigure ta_info_tab -text "Types" } set sw [ScrolledWindow [$notebook getframe ta_info_tab].sw -scrollbar both -auto both] set text [text [$sw getframe].text -wrap none -font {helvetica 10} -bg white] $sw setwidget $text pack $sw -expand 1 -fill both $text insert 0.0 $info_ta $text configure -state disabled if {$which != "type"} { set l [label [$notebook getframe fc_info_tab].l \ -text "Files labeled with types that are members of this attribute:" \ -justify left] pack $l -anchor nw } set sw [ScrolledWindow [$notebook getframe fc_info_tab].sw -scrollbar both -auto both] set fc_text [text [$sw getframe].text -wrap none -font {helvetica 10} -bg white] $sw setwidget $fc_text pack $sw -expand 1 -fill both $notebook raise [$notebook page 0] if {$index_file_loaded} { if {$entry_vector != {}} { set num [$entry_vector get_size] $fc_text insert 1.0 "Number of files: $num\n\n" for {set i 0} {$i < $num} {incr i} { set entry [sefs_entry_from_void [$entry_vector get_element $i]] $fc_text insert end "[$entry toString]\n" } $entry_vector -delete } else { $fc_text insert end "No files found." } } else { $fc_text insert 0.0 "No index file is loaded. Load an index file through the File Contexts tab." } $fc_text configure -state disabled $w draw {} 0 400x400 } proc Apol_Types::_searchTypes {} { variable widgets variable opts Apol_Widget::clearSearchResults $widgets(results) if {![ApolTop::is_policy_open]} { tk_messageBox -icon error -type ok -title "Error" -message "No current policy file is opened." return } if {$opts(types) == 0 && $opts(attribs) == 0} { tk_messageBox -icon error -type ok -title "Error" -message "No search options provided." return } set use_regexp [Apol_Widget::getRegexpEntryState $widgets(regexp)] set regexp [Apol_Widget::getRegexpEntryValue $widgets(regexp)] if {$use_regexp} { if {$regexp == {}} { tk_messageBox -icon error -type ok -title "Error" -message "No regular expression provided." return } } else { set regexp {} } set results {} if {$opts(types)} { set q [new_apol_type_query_t] $q set_type $::ApolTop::policy $regexp $q set_regex $::ApolTop::policy $use_regexp set v [$q run $::ApolTop::policy] $q -acquire $q -delete set types_data [type_vector_to_list $v] $v -acquire $v -delete append results "TYPES ([llength $types_data]):\n\n" foreach t [lsort $types_data] { append results "[_renderType $t $opts(types:show_attribs) $opts(types:show_aliases)]\n" } } if {$opts(attribs)} { set q [new_apol_attr_query_t] $q set_attr $::ApolTop::policy $regexp $q set_regex $::ApolTop::policy $use_regexp set v [$q run $::ApolTop::policy] $q -acquire $q -delete set attribs_data [attr_vector_to_list $v] $v -acquire $v -delete if {$opts(types)} { append results "\n\n" } append results "ATTRIBUTES ([llength $attribs_data]):\n\n" foreach a [lsort $attribs_data] { append results "[_renderAttrib $a $opts(attribs:show_types) $opts(attribs:show_attribs)]\n" } } Apol_Widget::appendSearchResultText $widgets(results) $results } proc Apol_Types::_renderType {type_name show_attribs show_aliases} { set qpol_type_datum [new_qpol_type_t $::ApolTop::qpolicy $type_name] set aliases {} set attribs {} set i [$qpol_type_datum get_alias_iter $::ApolTop::qpolicy] set aliases [iter_to_str_list $i] $i -acquire $i -delete set i [$qpol_type_datum get_attr_iter $::ApolTop::qpolicy] foreach a [iter_to_list $i] { set a [qpol_type_from_void $a] lappend attribs [$a get_name $::ApolTop::qpolicy] } $i -acquire $i -delete set text "$type_name" if {$show_aliases && [llength $aliases] > 0} { append text " alias [list $aliases]" } if {$show_attribs} { append text " ([llength $attribs] attribute" if {[llength $attribs] != 1} { append text s } append text ")\n" foreach a [lsort $attribs] { append text " $a\n" } } return $text } proc Apol_Types::_renderAttrib {attrib_name show_types show_attribs} { set qpol_type_datum [new_qpol_type_t $::ApolTop::qpolicy $attrib_name] set text "$attrib_name" if {$show_types} { set types {} set i [$qpol_type_datum get_type_iter $::ApolTop::qpolicy] foreach t [iter_to_list $i] { set t [qpol_type_from_void $t] lappend types [$t get_name $::ApolTop::qpolicy] } $i -acquire $i -delete append text " ([llength $types] type" if {[llength $types] != 1} { append text s } append text ")\n" foreach type_name [lsort $types] { append text " $type_name" if {$show_attribs} { set t [new_qpol_type_t $::ApolTop::qpolicy $type_name] set this_attribs {} set i [$t get_attr_iter $::ApolTop::qpolicy] foreach a [iter_to_list $i] { set a [qpol_type_from_void $a] lappend this_attribs [$a get_name $::ApolTop::qpolicy] } $i -acquire $i -delete set this_attribs [lsort $this_attribs] # remove the entry that we know should be there set idx [lsearch -sorted -exact $attrib_name $this_attribs] append text " { [lreplace $this_attribs $idx $idx] }" } append text "\n" } } return $text }