#!/usr/bin/wish -f # where to find the TIS report executables for things like netacl-summ.sh set TISBIN "/home/ark/bin" set scrollJump 0 set pscrollJump 0 set escrollJump 0 set alertJump 1 set defconRaise 1 set defconDeicon 1 set textViewCutoff 5000 set tailCutoff 100 array set filters { "Show only su" " su: " "Show only AUTH" "AUTH" "Securityalerts" "securityalert" "Filter out squid-gw" "^(?!.*squid-gw)" } array set cfilters { "Administrative actions" ".*su: |.*login: |.*sshd.*LOGIN|.*sshd.*login|.*cron.*system.* RELOAD" "Authenitcation management" ".*authsrv" "Security alerts" ".*securityalert" "Security warnings" ".*securitywarning" "Rejected connections" ".*deny" "Interactive sessions" ".*x-gw|.*tn-gw|.*rlogin-gw" "Remote execution" ".*rexec-gw|.*rsh-gw" "Line printer" ".*lp-gw" "FTP transfers" ".*ftp-gw" "HTTP transfers" ".*squid" "Realaudio" ".*ra-gw" "News" ".*nntp-gw" "Email" ".*smap|.*smapd|.*ssmtp|.*pop3-gw|.*imap-gw" "Database" ".*ms-sql-gw|.*sybase-gw|.*mysql-gw" "Messaging (irc,icq,aol)" ".*ms-sql-gw|.*sybase-gw|.*mysql-gw" "Netacl" ".*netacl" "IP filtering and NAT" ".*ipmon" } array set msglevel { "critical" "fwtksyserr|fwtkcfgerr|file system full|signal 11" "security" "alert:" "failure" "LOCKED|FAILURE|error.*:|squid.*Detected DEAD Parent" "rejected" "deny|relay denied|spam ignored|BADAUTH|sshd.*fatal:|su:.*D SU" "admin" "su: |login: |sshd.*LOGIN|sshd.*login|cron.*system.* RELOAD" "warning" "unable|icmpinfo: |securitywarning|hqdaemon.*warning" "auth" "AUTHENTICATE|authentication for.*accepted" "notice" "squid-gw.*unknown tag|squid-gw.*header field|ipmon.*NAT:MAP|squid.*Detected REVIVED Parent|pop3-gw.*insecure mode|bad request|Bad request" } array set msgcolor { "critical" "Red" "security" "Yellow" "failure" "Orange" "rejected" "HotPink" "admin" "LightBlue" "warning" "cyan" "auth" "Green" "notice" "MistyRose2" } set priority_colorize { "critical" "security" "failure" "rejected" "admin" "auth" } array set msgalert { "critical" 1 "security" 3 "failure" 5 "rejected" 2 "admin" 4 "warning" 5 "auth" 4 "notice" 5 } ############################################################################### # this is a graphical tool to view logs from the TIS firewall toolkit (or # # for that matter, any syslog file). It was written by Kevin McCurley, by # # modifying code obtained from other sources: # # Searchbox (copyright below) # # fileselect (in separate files, but included for convenience) # # for convenience, I have distributed the Searchbox and fileselect source # # along with this rather than require you to find them from another source. # ############################################################################### if [llength $argv]==0 {set thefile "/var/log/messages"} \ {set thefile [lfirst $argv]} puts "using logfile $thefile" set delay 2 # where to find the fileselect.tcl, searchbox.tcl, and taputils.tcl files set sbx(lib) /home/ark/lib/tcl set sbx(version) 1.0.1 source $sbx(lib)/taputils.tcl source $sbx(lib)/newsb.tcl source $sbx(lib)/fileselect.tcl set sb(scrollbarside) right set sb(fontList) { "-dec-terminal-medium-r-normal--14-140-75-75-c-80-iso8859-1" "-adobe-new century schoolbook-medium-r-normal--*-100-*" "-adobe-new century schoolbook-medium-r-normal--*-120-*" "-adobe-new century schoolbook-medium-r-normal--*-140-*" "-adobe-courier-medium-r-normal--*-80-*" "-adobe-courier-medium-r-normal--*-100-*" "-adobe-courier-medium-r-normal--*-120-*" "fixed" "default" "6x13" "9x15" } set sb(wrapList) {none char word} set sb(printList) {lpr enscript} set sb(text,font) "fixed" set sb(geom) 1015x500 set sb(text,wrap) none set sb(text,fontcolor) black set sb(text,margin) 5 set sb(regexp,case) 1 set sb(incr,case) 0 set sb(filter) "" set sbx(uid) 0 if [file exists ~/.fwtk_watch] {source ~/.fwtk_watch} set defcon 4 set apos 0 # this part of the code is modified from "Searchbox". Searchbox was # Copyright (c) 1993 T.A. Phelps # # Permission to use, copy, modify, and distribute this software and its # documentation for educational, research and non-profit purposes, # without fee, and without a written agreement is hereby granted, # provided that the above copyright notice and the following three # paragraphs appear in all copies. # # Permission to incorporate this software into commercial products may # be obtained from the Office of Technology Licensing, 2150 Shattuck # Avenue, Suite 510, Berkeley, CA 94704. # # IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY # FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES # ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF # THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # # THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE # PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF # CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, # ENHANCEMENTS, OR MODIFICATIONS. proc sbGUI {{w .fwtk_watch}} { global sb sbx filters msgcolor msglevel scrollJump pscrollJump pstatic \ static defcon defconDeicon defconRaise alertJump escrollJump \ cfilters rwinid rsource set rwinid 1 if {![winfo exists $w]} {toplevel $w} wm minsize $w 100 100 wm geometry $w $sb(geom) wm title $w "Firewall Monitoring Tool" wm iconname $w "fw watch" if {![winfo exists .elog]} {toplevel .elog} wm withdraw .elog frame $w.mb label $w.mb.status -text bozo button $w.help -text "Help" menubutton $w.mb.print -text "Print" -menu $w.mb.print.m menu $w.mb.print.m foreach i $sb(printList) { $w.mb.print.m add command -label $i -command "sbPrint $w $i" } menubutton $w.mb.mail -text "Mail" -menu $w.mb.mail.m menu $w.mb.mail.m $w.mb.mail.m add command -label "Mail text" -command "mailit $w" $w.mb.mail.m add command -label "Mail selection" -command "mailsel" checkbutton $w.mb.static -text "Static" -variable static -command "tail" -relief raised checkbutton $w.mb.freeze -text "Fix pane" -variable scrollJump -relief raised button $w.mb.clear -text "Clear" -command "$w.text delete 1.0 end" -pady 0 button $w.mb.refresh -text "Refresh" -command "refreshfile" -pady 0 menubutton $w.mb.options -text "Options" -menu $w.mb.options.m menu $w.mb.options.m menu $w.mb.options.m.font foreach i $sb(fontList) { $w.mb.options.m.font add radiobutton -label $i -variable sb(text,font) \ -command "$w.text configure -font [list $i]" } $w.mb.options.m add cascade -label "Font.." -menu $w.mb.options.m.font menu $w.mb.options.m.wrap foreach i {none char word} { $w.mb.options.m.wrap add radiobutton -label $i -variable sb(text,wrap) \ -command "$w.text configure -wrap $i" } $w.mb.options.m add cascade -label "Wrap.." -menu $w.mb.options.m.wrap $w.mb.options.m add separator $w.mb.options.m add checkbutton -label "Incremental Search Case Sensitive" \ -variable sb(incr,case) $w.mb.options.m add checkbutton -label "Regexp Search Case Sensitive" \ -variable sb(regexp,case) $w.mb.options.m add separator $w.mb.options.m add checkbutton -label "Deiconify on alert" \ -variable defconDeicon $w.mb.options.m add checkbutton -label "Raise on alert" \ -variable defconRaise $w.mb.options.m add checkbutton -label "Auto-scroll to alert log" \ -variable alertJump menubutton $w.mb.filter -text "Filter" -menu $w.mb.filter.m menu $w.mb.filter.m $w.mb.filter.m add command -label "Reload file" \ -command "refreshfile" $w.mb.filter.m add separator menu $w.mb.filter.m.cfilters set ef "" foreach i [array names cfilters] { if {$ef != ""} { set ef "$ef|\($cfilters($i)\)" } else { set ef "\($cfilters($i)\)" } } set "cfilters(Unsorted - everything else)" "^\(?!$ef\)" foreach i [lsort [array names cfilters]] { set active_filter($i) 0 $w.mb.filter.m.cfilters add checkbutton -label "$i" \ -variable active_filter($i) -command gen_cfilter } $w.mb.filter.m.cfilters add command -label "Select all" \ -command "set_cfilters 1; gen_cfilter" $w.mb.filter.m.cfilters add command -label "Apply filters to frame" \ -command {global win,sb \ gen_cfilter; \ matchlines $win $sb(filter); \ gen_cfilter} $w.mb.filter.m add cascade -menu $w.mb.filter.m.cfilters \ -label "Additive filters.." -command gen_cfilter menu $w.mb.filter.m.filters foreach i [lsort [array names filters]] { $w.mb.filter.m.filters add radiobutton -label $i \ -command "set_cfilters 0; matchlines $w $filters($i)" } $w.mb.filter.m add cascade -menu $w.mb.filter.m.filters \ -label "Exclusive filters.." $w.mb.filter.m add separator $w.mb.filter.m add command -label "Clear filter" \ -command "set sb(filter) {}; set_cfilters 0; reload_status" $w.mb.filter.m add command -label "Customize filter" \ -command "custom_filter $w" menubutton $w.mb.reports -text "Reports" -menu $w.mb.reports.m menu $w.mb.reports.m menu $w.mb.reports.m.source $w.mb.reports.m.source add radiobutton -label "Current frame" \ -variable rsource -value "frame" $w.mb.reports.m.source add radiobutton -label "Current logfile" \ -variable rsource -value "log" $w.mb.reports.m.source add radiobutton -label "Select from filesystem" \ -variable rsource -value "select" $w.mb.reports.m add cascade -label "Source.." -menu $w.mb.reports.m.source $w.mb.reports.m add command -label "Filters.." $w.mb.reports.m add separator $w.mb.reports.m add command -label "Network hourly load (total)" \ -command "show_report $w chart.pl" $w.mb.reports.m add command -label "Summary on current logfile" \ -command "show_report $w summ_complete.pl" $w.mb.reports.m add separator $w.mb.reports.m add command -label "Customize summary report" menubutton $w.mb.events -text "Events" -menu $w.mb.events.m menu $w.mb.events.m $w.mb.events.m add command -label "Show event history" -command "event_log" $w.mb.events.m add command -label "Clear" -command "elog_clear" menubutton $w.mb.file -text "File" -menu $w.mb.file.m menu $w.mb.file.m $w.mb.file.m add command -label "Select file..." \ -command changefile $w.mb.file.m add command -label "Toggle monitoring file" \ -command tail pack $w.mb.file $w.mb.options $w.mb.print $w.mb.mail \ $w.mb.filter $w.mb.events $w.mb.reports -side left pack $w.mb.refresh -side right pack $w.mb.clear -side right pack $w.mb.freeze -side right pack $w.mb.static -side right pack $w.mb.status -in $w.mb -side left -fill x -expand yes tk_menuBar $w.mb $w.mb.font $w.mb.wrap $w.mb.print $w.mb.options frame $w.t text $w.text -font $sb(text,font) -foreground $sb(text,fontcolor) \ -relief sunken -borderwidth 2 -padx $sb(text,margin) -pady $sb(text,margin) \ -yscrollcommand "$w.v set" -exportselection yes -wrap $sb(text,wrap) \ -state disabled bind $w.text sbQuit $w.text tag configure search \ -foreground [lindex [$w.text configure -background] 4] \ -background [lindex [$w.text configure -foreground] 4] bind $w.text " searchboxKeyNav \[key_state2mnemon %s\] %K \$sb(incr,case) $w.text $w.mb.status 0 " bind $w.t {} scrollbar $w.v -orient vertical -command "$w.text yview" pack $w.v -in $w.text -side $sb(scrollbarside) -fill y pack $w.text -in $w.t -side top -fill both -expand yes $w.text mark set viewpoint end frame $w.tt label $w.tt.status -text "Priority messages" button $w.tt.defcon -text "Condition: green (DEFCON 4)" -bg grey85 \ -command "cclean" -pady 0 -state disabled -relief flat \ -disabledforeground black checkbutton $w.tt.freeze -text "Fix pane" -variable pscrollJump -relief raised checkbutton $w.tt.static -text "Static" -variable pstatic -relief raised button $w.tt.clear -text "Clear" -command "$w.text1 delete 1.0 end" -pady 0 button $w.tt.refresh -text "Refresh" -command "prefresh $w" -pady 0 pack $w.tt.status -in $w.tt -side left -fill x pack $w.tt.defcon -in $w.tt -side left -fill x -expand yes pack $w.tt.refresh -side right pack $w.tt.clear -side right pack $w.tt.freeze -side right pack $w.tt.static -side right frame $w.t1 text $w.text1 -font $sb(text,font) -foreground $sb(text,fontcolor) \ -relief sunken -borderwidth 2 -padx $sb(text,margin) -pady $sb(text,margin) \ -yscrollcommand "$w.v1 set" -wrap $sb(text,wrap) \ -height 6 bind $w.text1 sbQuit bind $w.text1 " searchboxKeyNav \[key_state2mnemon %s\] %K \$sb(incr,case) $w.text1 $w.mb.status 0 " bind $w.text1 { set scrollJump 1 $win.text yview -pickplace 1.0 puts stderr "[$win.text1 get {@%x,%y linestart} {@%x,%y lineend}]" searchboxSearch [$win.text1 get {@%x,%y linestart} {@%x,%y lineend}] \ 0 1 search $win.text $win.mb.status $win.cnt searchboxNext search $win.text $win.mb.status } scrollbar $w.v1 -orient vertical -command "$w.text1 yview" pack $w.v1 -in $w.t1 -side right -fill y pack $w.text1 -in $w.t1 -side bottom -fill both -expand yes $w.text1 mark set viewpoint end frame $w.s button $w.search -text "Search" -command " if !\[catch {selection get}\] {set sbx(search,string$w) \[selection get\]} searchboxSearch \$sbx(search,string$w) 1 \$sb(regexp,case) search $w.text $w.mb.status $w.cnt " button $w.next -text "Next" -command "searchboxNext search $w.text $w.mb.status" entry $w.searchpat -font fixed -relief sunken -textvariable sbx(search,string$w) emacsbind $w.searchpat bind $w.searchpat sbQuit set sbx(search,oldstring$w) "" bind $w.searchpat " selection clear $w.text if {\$sbx(search,oldstring$w)!=\$sbx(search,string$w)} { set sbx(search,oldstring$w) \$sbx(search,string$w) $w.search invoke } else {$w.next invoke}" label $w.cnt button $w.quit -text "Quit" -command sbQuit; # write out new params? pack $w.search -in $w.s -side left pack $w.next -in $w.s -side left -padx 6 pack $w.searchpat -in $w.s -side left -fill x -expand yes -ipadx 10 -anchor w pack $w.cnt -in $w.s -side left pack $w.quit -in $w.search -side left -padx 3 bind all "$w.quit invoke" pack $w.quit -in $w.s -side left pack $w.mb -fill x -pady 4 pack $w.t -fill both -expand yes pack $w.tt -fill both pack $w.t1 -fill both pack $w.s -fill x -pady 6 foreach i {t text v} {bind $w.$i "focus $w.text"} bind $w.s "focus $w.searchpat" foreach k {KeyPress-Tab Shift-KeyPress-Tab} { bind $w.searchpat <$k> "focus $w.text" bind $w.text <$k> "focus $w.searchpat" } foreach i [array names msgcolor] { $w.text tag configure $i -borderwidth 2 -relief raised \ -background $msgcolor($i) $w.text1 tag configure $i -borderwidth 2 -relief raised \ -background $msgcolor($i) } bind $w.text {destroy .} bind $w.text {destroy .} frame .elog.tt label .elog.tt.status -text " Date/Time Type Message" -font $sb(text,font) checkbutton .elog.tt.freeze -text "Fix pane" -variable escrollJump -relief raised button .elog.tt.clear -text "Clear" -command "elog_clear" -pady 0 pack .elog.tt.status -in .elog.tt -side left -fill x pack .elog.tt.clear -side right pack .elog.tt.freeze -side right frame .elog.t text .elog.text -font $sb(text,font) -foreground $sb(text,fontcolor) \ -relief sunken -borderwidth 2 -padx $sb(text,margin) -pady $sb(text,margin) \ -yscrollcommand ".elog.v set" -wrap $sb(text,wrap) \ -height 15 -xscrollcommand ".elog.h set" .elog.text tag configure 1 -borderwidth 2 -relief raised \ -background red .elog.text tag configure 2 -borderwidth 2 -relief raised \ -background orange .elog.text tag configure 3 -borderwidth 2 -relief raised \ -background yellow .elog.text tag configure auth -borderwidth 2 -relief raised \ -background green .elog.text tag configure admin -borderwidth 2 -relief raised \ -background lightblue .elog.text tag configure clear -borderwidth 2 -relief raised \ -background blue .elog.text tag configure lost -borderwidth 2 -relief raised \ -background cyan bind .elog.text { set scrollJump 1 set pscrollJump 1 $win.text yview -pickplace 1.0 $win.text1 yview -pickplace 1.0 searchboxSearch [.elog.text get {@%x,%y linestart} {@%x,%y linestart +15 chars}] \ 0 1 search $win.text $win.mb.status $win.cnt searchboxNext search $win.text $win.mb.status searchboxSearch [.elog.text get {@%x,%y linestart} {@%x,%y linestart +15 chars}] \ 0 1 search $win.text1 $win.mb.status $win.cnt searchboxNext search $win.text1 $win.mb.status } scrollbar .elog.v -orient vertical -command ".elog.text yview" pack .elog.v -in .elog.t -side right -fill y scrollbar .elog.h -orient horizontal -command ".elog.text xview" pack .elog.text -in .elog.t -side bottom -fill both -expand yes .elog.text mark set viewpoint end pack .elog.tt -fill both pack .elog.t -fill both -expand yes pack .elog.h -fill x button .elog.c -text "Close" -command "wm withdraw .elog" pack .elog.c -fill x focus $w return $w } proc set_cfilters {x} { global cfilters active_filter foreach i [array names cfilters] { set active_filter($i) $x } } proc gen_cfilter {} { global sb cfilters active_filter win thefile set sb(filter) "" foreach i [array names cfilters] { if {$active_filter($i)} { if {$sb(filter) != ""} { set sb(filter) "$sb(filter)|\($cfilters($i)\)" } else { set sb(filter) "\($cfilters($i)\)" } } } if {$sb(filter) != ""} { $win.mb.status configure -text "filtered $thefile by additive filter set" } else { reload_status } } proc sbReadFile {filename} { global sb sbx win thefile msglevel $win.text configure -state normal $win.text delete 1.0 end $win.text1 delete 1.0 end if {[catch {set lf [glob $filename]}]} { okdialog Error "$filename doesn't exist" } set filename [lfirst $lf] if {![file readable $filename]} { okdialog {Error} "file $filename is not readable" } $win.mb.status configure -text "reading $filename ..." update idletasks if {$filename=="stdin"} {set fid "stdin"} { if {[catch {set fid [open $filename]}]} { okdialog {Error} "file $filename cannot be opened" } } set cnt 0 while {![eof $fid]} { gets $fid line processTextLine $line $win incr cnt update idletasks } close $fid switch $cnt { 0 {set cnttxt "empty"} 1 {set cnttxt "1 line"} default {set cnttxt "$cnt lines"} } $win.cnt configure -text $cnttxt $win.mb.status configure -text "static $filename" update idletasks set thefile $filename } proc sbPrint {w cmd} { set fid [open "|$cmd" w] scan [$w.text index end] "%d" end for {set i 1} {$i<$end} {incr i} { puts $fid [$w.text get $i.0 "$i.0 lineend"] } close $fid } proc printSel {cmd} { set fid [open "|$cmd" w] if [catch {selection get}] { okdialog Error "Mail not sent - no text selected" } else { puts $fid [selection get] close $fid } } proc sbQuit {} { global inputstream if {$inputstream != "NONE"} { # catch {exec /bin/kill $inputpid} catch {close $inputstream} } destroy . } # this stuff is modified from the book by Ousterhout: Tcl and the Tk Toolkit proc okdialog {title text} { global button toplevel .dlg -class Dialog wm title .dlg $title set buttonvar 0 frame .dlg.top -relief raised -bd 1 pack .dlg.top -side top -fill both frame .dlg.bot -relief raised -bd 1 pack .dlg.bot -side bottom -fill both message .dlg.top.msg -width 3i -text $text pack .dlg.top.msg -side right -expand 1 -fill both -padx 3m -pady 3m button .dlg.bot.butt -text "OK" -command "set buttonvar 1" pack .dlg.bot.butt -side left -expand 1 -padx 3m -pady 3m -ipadx 2m -ipady 1m set oldFocus [focus] grab set .dlg focus .dlg tkwait variable buttonvar focus $oldFocus destroy .dlg } # most of the stuff below here is added by KSM ############################### proc changefile {} { global inputstream if {$inputstream != "NONE"} { tail } fileselect sbReadFile {Select Log File} } proc loadfile {} { global thefile inputstream if {$inputstream != "NONE"} { tail return } sbReadFile $thefile } proc refreshfile {} { global thefile inputstream if {$inputstream != "NONE"} { catch {close $inputstream} set inputstream "NONE" tail return } sbReadFile $thefile } # # this is a toggle of whether to input from a "tail -f thefile" # proc reload_status {} { global thefile win inputstream if {$inputstream == "NONE"} { $win.mb.status configure -text "static $thefile" } else { $win.mb.status configure -text "monitoring $thefile" } } proc tail {} { global delay win thefile inputstream tailCutoff if {$inputstream == "NONE"} { $win.text configure -state normal $win.text delete 1.0 end $win.mb.status configure -text "reading $thefile" set cnt 0 set static 0 set inputstream [open "|tail -$tailCutoff $thefile" r] while {![eof $inputstream]} { gets $inputstream line processTextLine $line $win incr cnt update idletasks } close $inputstream set inputstream [open $thefile r] fconfigure $inputstream -buffering none $win.mb.status configure -text "monitoring $thefile" catch {seek $inputstream 0 end} while {![eof $inputstream]} { gets $inputstream line processTextLine $line $win update idletasks } update idletasks after $delay [list tailread] } else { catch {close $inputstream} $win.mb.status configure -text "static $thefile" set inputstream "NONE" set static 1 } } proc tailread {} { global delay maxlines win thefile inputstream if {$inputstream == "NONE"} { return } gets $inputstream data if [string length $data] { processTextLine $data $win } after $delay [list tailread] } proc cclean {} { global win defcon apos apos1 scrollJump pscrollJump alertJump \ escrollJump $win.tt.defcon configure -text "Condition: green (DEFCON 4)" \ -background grey85 -state disabled \ -relief flat .elog.text insert end [exec date "+%b %e %H:%M:%S"] .elog.text insert end " CLEARED Defence condition cleared by operator" .elog.text tag add clear "end -1 line +16 chars" "end -1 line +24 chars" .elog.text insert end "\n" if {!$escrollJump } { .elog.text mark set viewpoint end .elog.text yview -pickplace end } if {$alertJump} { set scrollJump 1 set pscrollJump 1 $win.text yview -pickplace $apos.0 $win.text1 yview -pickplace $apos1.0 } set defcon 4 set apos 0 } proc elog_clear {} { .elog.text delete 1.0 end .elog.text insert end [exec date "+%b %e %H:%M:%S"] .elog.text insert end " CLEARED Event history removed by operator" .elog.text tag add clear "end -1 line +16 chars" "end -1 line +24 chars" .elog.text insert end "\n" } proc do_defcon {} { global win defcon defconRaise defconDeicon if {$defconRaise} {raise $win} if {![winfo ismapped $win] & $defconDeicon} { wm deiconify $win } switch $defcon { 1 { $win.tt.defcon configure -text "Condition: RED (DEFCON 1)" \ -bg red -activebackground red -state normal \ -relief raised } 2 { $win.tt.defcon configure -text "Condition: ORANGE (DEFCON 2)" \ -bg orange -activebackground orange -state normal \ -relief raised } 3 { $win.tt.defcon configure -text "Condition: YELLOW (DEFCON 3)" \ -bg yellow -activebackground yellow -state normal \ -relief raised } default {} } } proc tag_line {line cnt} { global win msglevel msgcolor defcon msgalert apos escrollJump foreach i [array names msglevel] { if [regexp $msglevel($i) $line] { $win.text tag add $i $cnt.0 "$cnt.0 lineend" if {$msgalert($i) <5} { .elog.text insert end [string range $line 0 15] if {$msgalert($i) == 4} { if {$i == "admin"} { .elog.text insert end "ADMIN " .elog.text tag add admin "end -1 line +16 chars" "end -1 line +24 chars" } elseif {$i == "auth"} { .elog.text insert end "AUTH " .elog.text tag add auth "end -1 line +16 chars" "end -1 line +24 chars" } } else { .elog.text insert end "DEFCON $msgalert($i) " .elog.text tag add $msgalert($i) "end -1 line +16 chars" "end -1 line +24 chars" } .elog.text insert end [string range $line 16 end] .elog.text insert end "\n" if {!$escrollJump } { .elog.text mark set viewpoint end .elog.text yview -pickplace end } } if {$msgalert($i) < $defcon} { set apos $cnt set defcon $msgalert($i) do_defcon } break } } } proc tag_pline {line cnt} { global win msglevel msgcolor priority_colorize apos1 defcon msgalert foreach i $priority_colorize { if [regexp $msglevel($i) $line] { if {$msgalert($i) == $defcon} { set apos1 $cnt } $win.text1 tag add $i $cnt.0 "$cnt.0 lineend" incr cnt -1 break } } } proc mailit {w} { set fid [open "|whoami" r] gets $fid me close $fid sbPrint $w "mail $me" } proc mailsel {} { set fid [open "|whoami" r] gets $fid me close $fid printSel "mail $me" } proc show_report {w script} { global TISBIN thefile inputstream rwinid sb set crwin_id .report_[incr rwinid] toplevel $crwin_id frame $crwin_id.t label $crwin_id.status -text "Generating report.." text $crwin_id.text -font $sb(text,font) \ -foreground $sb(text,fontcolor) -relief sunken \ -borderwidth 2 -padx $sb(text,margin) \ -pady $sb(text,margin) \ -yscrollcommand "$crwin_id.v set" \ -wrap $sb(text,wrap) -height 50 # -xscrollcommand "$crwin_id.h set" scrollbar $crwin_id.v -orient vertical -command "$crwin_id.text yview" pack $crwin_id.v -in $crwin_id.t -side right -fill y # scrollbar $crwin_id.h -orient horizontal -command "$crwin_id.text xview" button $crwin_id.c -text "Close" -command "destroy $crwin_id" pack $crwin_id.status -side top pack $crwin_id.text -in $crwin_id.t -side bottom -fill both -expand yes pack $crwin_id.t -fill both -expand yes # pack $crwin_id.h -fill x pack $crwin_id.c -fill x $crwin_id.status configure -text "processing $thefile..." update idletasks set input [open "|$TISBIN/$script $thefile" r+] # $w.text configure -state normal # $w.text delete 1.0 end while {![eof $input]} { $crwin_id.text insert end [read $input 1000] } close $input # $w.text configure -state disabled $crwin_id.status configure -text "finished $script report" # scan [$w.text index end] %d numlines # $w.cnt configure -text "$numlines lines" } proc prefresh {w} { global sb msglevel $w.text1 delete 1.0 end scan [$w.text index end] %d numlines for {set i 1} {$i<=$numlines} {incr i} { foreach j [array names msglevel] { set line [$w.text get $i.0 "$i.0 lineend"] if [regexp $msglevel($j) $line] { $w.text1 insert end $line $w.text1 insert end "\n" scan [$w.text1 index end] %d pnumlines incr pnumlines -2 tag_pline $line $pnumlines break } } } } proc matchlines {w patt} { global thefile global sb $w.mb.status configure -text "filtering $thefile for string $patt..." update idletasks set sb(filter) $patt $w.text configure -state normal scan [$w.text index end] %d numlines for {set i $numlines} {$i>0} {incr i -1} { if ![regexp $patt [$w.text get $i.0 "$i.0 lineend"]] { $w.text delete $i.0 "$i.0 lineend + 1 chars" incr numlines -1 } } switch $numlines { 0 {set cnttxt "empty"} 1 {set cnttxt "1 line"} default {set cnttxt "$numlines lines"} } $w.cnt configure -text $cnttxt if {$patt!=""} { $w.mb.status configure -text "filtered $thefile by string $patt" } else { reload_status } update idletasks } proc custom_filter {w} { global sb toplevel .dlg wm title .dlg "Custom filter" set good "" label .dlg.label -text "Custom filter (regexp)" entry .dlg.str -relief sunken -borderwidth 4 -textvariable sb(filter) \ -font fixed bind .dlg.str ".dlg.ok invoke" button .dlg.ok -text OK -command "matchlines $w \$sb(filter) ; destroy .dlg" button .dlg.clear -text Clear -command "set sb(filter) {}; set_cfilters 0" pack .dlg.str -fill x -expand yes -padx 2m -pady 2m pack .dlg.label .dlg.clear .dlg.ok -side left -padx 1m -pady 2m } proc event_log {} { wm title .elog "Event history" wm deiconify .elog wm protocol .elog WM_DELETE_WINDOW {wm withdraw .elog} } # code provided by Stuart Clayman (sclayman@cs.ucl.ac.uk) proc readline {pipe} { global win if { [gets $pipe line] == -1} { return } processTextLine $line $win update idletasks } proc processTextLine {line w} { global textViewCutoff sb msglevel scrollJump pscrollJump \ pstatic apos escrollJump # move to end if looking at end otherwise stay where we are if { [expr {[$w.text index end] > $textViewCutoff}] } { set atime [$w.text get 1.0 1.15] $w.text delete 1.0 2.0 if {$apos} { incr apos -1 if {!$apos} { .elog.text insert end [exec date "+%b %e %H:%M:%S"] .elog.text insert end " WARNING Alert position for $atime lost in scrollback" .elog.text tag add lost "end -1 line +16 chars" "end -1 line +24 chars" .elog.text insert end "\n" if {!$escrollJump } { .elog.text mark set viewpoint end .elog.text yview -pickplace end } } } } if [regexp $sb(filter) $line] { if { $line != "" } {$w.text insert end "\n"} $w.text insert end "$line" scan [$w.text index end] %d numlines incr numlines -1 tag_line $line $numlines } if {!$scrollJump } { $w.text mark set viewpoint end if { [$w.text compare viewpoint == end] } { $w.text yview -pickplace end } } if {!$pscrollJump} { $w.text1 mark set viewpoint end if { [$w.text1 compare viewpoint == end] } { $w.text1 yview -pickplace end } } if (!$pstatic) { foreach i [array names msglevel] { if [regexp $msglevel($i) $line] { if { $line != "" } {$w.text1 insert end "\n"} $w.text1 insert end "$line" scan [$w.text1 index end] %d numlines incr numlines -1 tag_pline $line $numlines break } } } } wm withdraw . if {$tk_version<8.0} {puts stderr "Tcl/Tk 8.0 required"; exit 1} bind Text {textb1motion %W @%x,%y} bind Text { global test; set text(txnd) 0 } bind Text {} bind Text {} bind Text {} bind Text {} bind Text {} set win [sbGUI] $win.mb.status configure -text "unloaded $thefile" set inputstream "NONE" set inputpid "NONE" tail