From ba46c304bdffdce0b6019a47f6759ce6abbeef90 Mon Sep 17 00:00:00 2001 From: Stefan Ritter Date: Tue, 16 Aug 2011 10:51:41 +0200 Subject: Initial commit --- weed | 593 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 593 insertions(+) create mode 100755 weed (limited to 'weed') diff --git a/weed b/weed new file mode 100755 index 0000000..2740712 --- /dev/null +++ b/weed @@ -0,0 +1,593 @@ +#! /bin/sh +# This trick is borrowed from Tothwolf's Wolfpack \ +# Check for working 'grep -E' before using 'egrep' \ +if echo a | (grep -E '(a|b)') >/dev/null 2>&1; \ +then \ + egrep="grep -E"; \ +else \ + egrep=egrep; \ +fi; \ +# Search for tclsh[0-9].[0-9] in each valid dir in PATH \ +for dir in $(echo $PATH | sed 's/:/ /g'); \ +do \ + if test -d $dir; \ + then \ + files=$(/bin/ls $dir | $egrep '^tclsh[0-9]\.[0-9]$'); \ + if test "$files" != ""; \ + then \ + versions="${versions:+$versions }$(echo $files | sed 's/tclsh//g')"; \ + fi; \ + fi; \ +done; \ +for ver in $versions; \ +do \ + tmpver=$(echo $ver | sed 's/\.//g'); \ + if test "$lasttmpver" != ""; \ + then \ + if test "$tmpver" -gt "$lasttmpver"; \ + then \ + lastver=$ver; \ + lasttmpver=$tmpver; \ + fi; \ + else \ + lastver=$ver; \ + lasttmpver=$tmpver; \ + fi; \ +done; \ +exec tclsh$lastver "$0" ${1+"$@"} +# +# $Id: weed,v 1.9 2008/06/18 10:12:22 tothwolf Exp $ +# +# weed out certain undesirables from an eggdrop userlist +# try just typing 'tclsh weed' to find out the options +# Robey Pointer, November 1994 +# +# : +# I did a few bug fixes to the original weed script, things changed... +# +# when specifying other weed options they would unset the User() field and +# a maxlast weed would try and weed again and cause the script to stop due +# to User() being already unset (array nonexistant) +# +# when loadUserFile encountered an xtra field it would try and use the $info +# variable, which was supposed to be $xtra (something overlooked when the +# line was cut and pasted -- I hate it when that happens) +# +# changed the formatting of the saved weed file to match more closely to +# eggdrop 0.9tp (so this may cause incompatibilities), but when a hostmask +# field exactly matched 40 characters it would save it with no spaces after +# it and eggdrop would reject the user record. I know I could have easily +# changed one character, but I couldn't help myself. +# 5 march 1996 +# +# : +# upgrade for v2 userfiles +# : +# fixed xtra field from getting truncated +# : +# stopped it from mangling channel ban lists +# : +# upgrade for v3 userfiles +# : +# added an option to remove users from unwanted channels +# : +# upgrade for v4 userfiles, with v3 converter +# : +# fixed bug "list element in braces followed by X instead of space" +# (the use of "lrange" where you aren't sure if it's a list is bad) +# fixed --CONSOLE item not being included, creating "user" --CONSOLE +# : +# two more improper occurrences of "lrange" removed +# : +# removed ancient way of determining the current time. +# : +# [clock] isn't in all versions of Tcl... +# : +# borrowed code from Tothwolf's Wolfpack to find tclsh better +# + +set exempt {*ban *ignore} +set exemptops 0 ; set exemptmasters 0 ; set exemptfriends 0 +set exemptparty 0 ; set exemptfile 0 ; set exemptchanm 0 +set exemptbotm 0 ; set exemptchann 0 ; set exemptchanf 0 +set exemptchano 0 +set maxlast 0 ; set maxban 0 ; set maxignore 0 +set weedops 0 ; set weedmasters 0 ; set weednopw 0 +set stripops 0 ; set stripmasters 0 ; set weedlurkers 0 +set chanrem {} +set convert 0 + +if {![string compare "" [info commands clock]]} then { + set fd [open "/tmp/egg.timer." w] + close $fd + set CURRENT [file atime "/tmp/egg.timer."] + exec rm -f /tmp/egg.timer. +} else { + set CURRENT [clock seconds] +} + +if {$argc < 1} { + puts stdout "\nUsage: weed \[options\]" + puts stdout " (weeds out users from an eggdrop userlist)" + puts stdout "Output goes to .weed" + puts stdout "Possible options:" + puts stdout " - exempt this user from weeding" + puts stdout " ^o ^m ^f exempt ops or masters or friends" + puts stdout " ^co ^cm ^cf exempt chanops or chanmasters or chanfriends" + puts stdout " ^cn exempt chanowner" + puts stdout " ^p ^x exempt party-line or file-area users" + puts stdout " ^b exempt botnet master" + puts stdout " + weed: haven't been seen in N days" + puts stdout " :n weed: haven't EVER been seen" + puts stdout " :o :m weed: ops or masters with no password set" + puts stdout " :a weed: anyone with no password set" + puts stdout " o m unop/unmaster: ops or masters with no pass." + puts stdout " b weed: bans not used in N days" + puts stdout " i weed: ignores created over N days ago" + puts stdout " = weed: channels no longer supported" + puts stdout " c convert v3 eggdrop userfile" + puts stdout "" + exit +} +puts stdout "\nWEED 18jun97, robey\n" + +set filename [lindex $argv 0] +for {set i 1} {$i < $argc} {incr i} { + set carg [lindex $argv $i] + if {$carg == ":n"} { + set weedlurkers 1 + } elseif {$carg == ":o"} { + set weedops 1 ; set stripops 0 ; set weednopw 0 + } elseif {$carg == ":m"} { + set weedmasters 1 ; set stripmasters 0 ; set weednopw 0 + } elseif {$carg == ":a"} { + set weednopw 1 ; set weedops 0 ; set weedmasters 0 + set stripops 0 ; set stripmasters 0 + } elseif {$carg == "o"} { + set stripops 1 ; set weedops 0 ; set weednopw 0 + } elseif {$carg == "m"} { + set stripmasters 1 ; set weedmasters 0 ; set weednopw 0 + } elseif {$carg == "^m"} { + set exemptmasters 1 + } elseif {$carg == "^o"} { + set exemptops 1 + } elseif {$carg == "^f"} { + set exemptfriends 1 + } elseif {$carg == "^p"} { + set exemptparty 1 + } elseif {$carg == "^x"} { + set exemptfile 1 + } elseif {$carg == "^cf"} { + set exemptchanf 1 + } elseif {$carg == "^cm"} { + set exemptchanm 1 + } elseif {$carg == "^cn"} { + set exemptchann 1 + } elseif {$carg == "^b"} { + set exemptbotm 1 + } elseif {$carg == "^co"} { + set exemptchano 1 + } elseif {$carg == "c"} { + set convert 1 + } elseif {[string index $carg 0] == "-"} { + lappend exempt [string range $carg 1 end] + } elseif {[string index $carg 0] == "+"} { + set maxlast [expr 60*60*24* [string range $carg 1 end]] + } elseif {[string index $carg 0] == "b"} { + set maxban [expr 60*60*24* [string range $carg 1 end]] + } elseif {[string index $carg 0] == "i"} { + set maxignore [expr 60*60*24* [string range $carg 1 end]] + } elseif {[string index $carg 0] == "="} { + lappend chanrem [string tolower [string range $carg 1 end]] + } else { + puts stderr "UNKNOWN OPTION: '$carg'\n" + exit + } +} + +if {(!$weedlurkers) && (!$weedops) && (!$weedmasters) && (!$weednopw) && + (!$stripops) && (!$stripmasters) && ($maxlast == 0) && ($convert == 0) && + ($maxban == 0) && ($maxignore == 0) && ($chanrem == {})} { + puts stderr "PROBLEM: You didn't specify anything to weed out.\n" + exit +} + +set weeding { } ; set strip { } ; set exempting { } +if {$weedlurkers} { lappend weeding "lurkers" } +if {$weedops} { lappend weeding "pwdless-ops" } +if {$weedmasters} { lappend weeding "pwdless-masters" } +if {$weednopw} { lappend weeding "pwdless-users" } +if {$chanrem != {}} { lappend weeding "unwanted-channel" } +if {$maxlast > 0} { lappend weeding ">[expr $maxlast /(60*60*24)]-days" } +if {$maxban > 0} { lappend weeding "bans>[expr $maxban /(60*60*24)]-days" } +if {$maxignore > 0} { lappend weeding "ign>[expr $maxignore /(60*60*24)]-days" } +if {$weeding != { }} { puts stdout "Weeding:$weeding" } + +if {$stripops} { lappend strip "pwdless-ops" } +if {$stripmasters} { lappend strip "pwdless-masters" } +if {$strip != { }} { puts stdout "Stripping:$strip" } + +if {$exemptops} { lappend exempting "(ops)" } +if {$exemptmasters} { lappend exempting "(masters)" } +if {$exemptfriends} { lappend exempting "(friends)" } +if {$exemptparty} { lappend exempting "(party-line)" } +if {$exemptfile} { lappend exempting "(file-area)" } +if {$exemptchann} { lappend exempting "(channel-owners)" } +if {$exemptchanm} { lappend exempting "(channel-masters)" } +if {$exemptchano} { lappend exempting "(channel-ops)" } +if {$exemptchanf} { lappend exempting "(channel-friends)" } +if {$exemptbotm} { lappend exempting "(botnet masters)" } +if {[llength $exempt]>2} { lappend exempting "[lrange $exempt 2 end]" } +if {$exempting != { }} { puts stdout "Exempt:$exempting" } + +puts stdout "\nReading $filename ..." + +proc convertUserFile {fname} { + global User Hostmask Channel Botflag LastOn BotAddr Xtra convert + puts stdout "\nRunning Converter on $fname" + set oldhandle {} + if {[catch {set fd [open $fname r]}] != 0} { return 0 } + set line [string trim [gets $fd]] + if {[string range $line 1 2] == "3v"} { + set convert 1 + } elseif {[string range $line 1 2] == "4v"} { + return 0 + } + while {![eof $fd]} { + set line [string trim [gets $fd]] + if {([string index $line 0] != "#") && ([string length $line] > 0)} { + scan $line "%s" handle + if {$handle == "-"} { + # hostmask + set hmList [split [string range $line 2 end] ,] + for {set i 0} {$i < [llength $hmList]} {incr i} { + lappend Hostmask($oldhandle) [string trim [lindex $hmList $i]] + } + } elseif {$handle == "!"} { + # channel + set chList [string trim [string range $line 1 end]] + lappend Channel($oldhandle) "[lrange $chList 0 1] [string trim [lindex $chList end] 0123456789]" + } elseif {$handle == "*"} { + # dccdir + set dccdir [string trim [string range $line 2 end]] + set User($oldhandle) [lreplace $User($oldhandle) 2 2 $dccdir] + } elseif {$handle == "+"} { + # email + set email [string trim [string range $line 2 end]] + set User($oldhandle) [lreplace $User($oldhandle) 3 3 $email] + } elseif {$handle == "="} { + # comment + set comment [string trim [string range $line 2 end]] + set User($oldhandle) [lreplace $User($oldhandle) 4 4 $comment] + } elseif {$handle == ":"} { + # user info line / bot addresses + if {[lsearch [split [lindex $User($oldhandle) 0] ""] b] == -1} { + set info [string trim [string range $line 1 end]] + set User($oldhandle) [lreplace $User($oldhandle) 5 5 $info] + } else { + set BotAddr($oldhandle) [string trim [string range $line 1 end]] + } + } elseif {$handle == "."} { + # xtra field start + if {![info exists xtraList($oldhandle)]} { + set xtraList($oldhandle) [string trim [string range $line 1 end]] + } { + set xtraList($oldhandle) "$xtraList($oldhandle) [string trim [string range $line 1 end]]" + } + } elseif {$handle == "!!"} { + # laston + set LastOn($oldhandle) [lindex $line 1] + } else { + # finish up xtra field first + if {[info exists xtraList($oldhandle)]} { + for {set i 0} {$i < [llength $xtraList($oldhandle)]} {incr i} { + lappend Xtra($oldhandle) [string trim [lindex $xtraList($oldhandle) $i] \{] + } + } + # begin of new user + scan $line "%s %s %s %s" handle pass attr ts + if {$convert == 1 && $attr != ""} { + regsub -all {B} $attr {t} attr + set botflags "s h a l r" ; set Botflag($handle) "" + set nattr [split [string trim $attr 0123456789] ""] ; set attr "" + foreach flag $botflags { + if {[lsearch -exact $nattr $flag] != -1} {append Botflag($handle) $flag} + } + foreach flag $nattr { + if {[lsearch -exact $botflags $flag] == -1} {append attr $flag} + } + } + set User($handle) [list $attr $pass {} {} {} {}] + set Hostmask($handle) {} + set Channel($handle) {} + set oldhandle $handle + } + } + } + return 1 +} + +proc loadUserFile {fname} { + global User Hostmask Channel Botflag LastOn BotAddr Xtra + set oldhandle {} + if {[catch {set fd [open $fname r]}] != 0} { return 0 } + set line [string trim [gets $fd]] + if {[string range $line 1 2] != "4v"} { + if {[string range $line 1 2] == "3v"} { + convertUserFile $fname + return 1 + } else { + puts stderr "Unknown userfile version! (not v4)\n" + exit + } + } + while {![eof $fd]} { + set line [string trim [gets $fd]] + if {([string index $line 0] != "#") && ([string length $line] > 0)} { + scan $line "%s" handle + if {$handle == "--HOSTS"} { + # hostmask + set hmList [lindex $line 1] + lappend Hostmask($oldhandle) [string trim $hmList] + } elseif {$handle == "-"} { + # hostmask + set hmList [join [lrange $line 1 end]] + lappend Hostmask($oldhandle) [string trim $hmList] + } elseif {$handle == "!"} { + # channel + set chList [string trim [string range $line 1 end]] + lappend Channel($oldhandle) $chList + } elseif {$handle == "--BOTADDR"} { + # botaddr + set BotAddr($oldhandle) [lindex $line 1] + } elseif {$handle == "--PASS"} { + # pass + set pass [string trim [string range $line [expr [string first " " $line] + 1] end]] + set User($oldhandle) [lreplace $User($oldhandle) 1 1 $pass] + } elseif {$handle == "--DCCDIR"} { + # dccdir + set first [string first " " $line] + if {$first != -1} { + set dccdir [string trim [string range $line [expr $first + 1] end]] + } { + set dccdir "" + } + set User($oldhandle) [lreplace $User($oldhandle) 2 2 $dccdir] + } elseif {$handle == "--COMMENT"} { + # comment + set first [string first " " $line] + if {$first != -1} { + set comment [string trim [string range $line [expr $first + 1] end]] + } { + set comment "" + } + set User($oldhandle) [lreplace $User($oldhandle) 4 4 $comment] + } elseif {$handle == "--INFO"} { + # user info line + set first [string first " " $line] + if {$first != -1} { + set info [string trim [string range $line [expr $first + 1] end]] + } { + set info "" + } + set User($oldhandle) [lreplace $User($oldhandle) 5 5 $info] + } elseif {$handle == "--CONSOLE"} { + # console + set first [string first " " $line] + if {$first != -1} { + set console [string trim [string range $line [expr $first + 1] end]] + } { + set console "" + } + set User($oldhandle) [lreplace $User($oldhandle) 6 6 $console] + } elseif {$handle == "--XTRA"} { + # xtra field + set first [string first " " $line] + if {$first != -1} { + set xtraList [string trim [string range $line [expr $first + 1] end]] + } { + set xtraList "" + } + lappend Xtra($oldhandle) $xtraList + } elseif {$handle == "--LASTON"} { + # laston + set LastOn($oldhandle) [lindex $line 1] + } elseif {$handle == "--BOTFL"} { + # botflags + set Botflag($oldhandle) [string trim [string range $line 1 end]] + } else { + # begin of new user + scan $line "%s %s %s" handle dash attr + set User($handle) [list $attr {} {} {} {} {} {}] + set Hostmask($handle) {} + set Channel($handle) {} + set oldhandle $handle + } + } + } + return 1 +} + +proc saveUserFile fname { + global User Hostmask Channel Botflag LastOn BotAddr Xtra + if {[catch {set fd [open $fname w]}] != 0} { return 0 } + puts $fd "#4v: weed! now go away." + foreach i [array names User] { + set hmask "none" + set hmloop 0 ; set chloop 0 ; set loloop 0 ; set xloop 0 ; set aloop 0 + if {[lindex $User($i) 1] == "bans"} {set plug "bans"} {set plug "-"} + set attr [lindex $User($i) 0] + set ts [lindex $User($i) 2] + puts $fd [format "%-9s %-20s %-24s" $i $plug $attr] + for {} {$hmloop < [llength $Hostmask($i)]} {incr hmloop} { + if {[string index $i 0] == "*" || [string range $i 0 1] == "::"} { + set hmask [lindex $Hostmask($i) $hmloop] + regsub -all {~} $hmask { } hmask + puts $fd "- $hmask" + } else { + puts $fd "--HOSTS [lindex $Hostmask($i) $hmloop]" + } + } + if {[info exists BotAddr($i)]} { + puts $fd "--BOTADDR [lindex $BotAddr($i) 0]" + } + if {[info exists Xtra($i)]} { + for {} {$xloop < [llength $Xtra($i)]} {incr xloop} { + puts $fd "--XTRA [lindex $Xtra($i) $xloop]" + } + } + if {[info exists Channel($i)]} { + for {} {$chloop < [llength $Channel($i)]} {incr chloop} { + puts $fd "! [lindex $Channel($i) $chloop]" + } + } + if {[info exists Botflag($i)]} { + if {$Botflag($i) != ""} { puts $fd "--BOTFL [lindex $Botflag($i) 0]" } + } + if {[string index $i 0] == "*" || [string range $i 0 1] == "::"} { + set User($i) [lreplace $User($i) 1 1 {}] + } + if {[lindex $User($i) 1] != {}} { puts $fd "--PASS [lindex $User($i) 1]" } + if {[lindex $User($i) 2] != {}} { puts $fd "--DCCDIR [lindex $User($i) 2]" } + if {[lindex $User($i) 3] != {}} { puts $fd "--XTRA EMAIL [lindex $User($i) 3]" } + if {[lindex $User($i) 4] != {}} { puts $fd "--COMMENT [lindex $User($i) 4]" } + if {[lindex $User($i) 5] != {}} { puts $fd "--INFO [lindex $User($i) 5]" } + if {[lindex $User($i) 6] != {}} { puts $fd "--CONSOLE [lindex $User($i) 6]" } + if {[info exists LastOn($i)]} { + puts $fd "--LASTON [lindex $LastOn($i) 0]" + } + } + close $fd + return 1 +} + +if {![loadUserFile $filename]} { + puts stdout "* Couldn't load userfile!\n" + exit +} + +if {$convert == 0} { + puts stdout "Loaded. Weeding..." + puts stdout "(pwd = no pass, -o/-m = removed op/master, lrk = never seen, exp = expired)" + puts stdout "(uwc = unwanted channel)\n" +} else { + puts stdout "Loaded. Converting..." +} + +set total 0 +set weeded 0 +foreach i [array names User] { + incr total + set attr [lindex $User($i) 0] + set chanattr [lindex [lindex $Channel($i) 0] 2] + if {([lsearch -exact $exempt $i] == -1) && + ([string range $i 0 1] != "::") && + ([string range $i 0 1] != "--") && + (([string first o $attr] == -1) || (!$exemptops)) && + (([string first m $attr] == -1) || (!$exemptmasters)) && + (([string first f $attr] == -1) || (!$exemptfriends)) && + (([string first p $attr] == -1) || (!$exemptparty)) && + (([string first x $attr] == -1) || (!$exemptfile)) && + (([string first t $attr] == -1) || (!$exemptbotm)) && + (([string first f $chanattr] == -1) || (!$exemptchanf)) && + (([string first m $chanattr] == -1) || (!$exemptchanm)) && + (([string first n $chanattr] == -1) || (!$exemptchann)) && + (([string first o $chanattr] == -1) || (!$exemptchano))} { + set pass [lindex $User($i) 1] + if {[info exists LastOn($i)]} { set ts [lindex $LastOn($i) 0] } { set ts 0 } + if {([string compare $pass "-"] == 0) && ([string first b $attr] == -1)} { + if {$weednopw == 1} { + unset User($i) ; incr weeded + puts -nonewline stdout "[format "pwd: %-10s " $i]" + } elseif {([string first o $attr] != -1) && ($weedops == 1)} { + unset User($i) ; incr weeded + puts -nonewline stdout "[format "pwd: %-10s " $i]" + } elseif {([string first m $attr] != -1) && ($weedmasters == 1)} { + unset User($i) ; incr weeded + puts -nonewline stdout "[format "pwd: %-10s " $i]" + } + if {([string first o $attr] != -1) && ($stripops == 1)} { + set nattr {} + for {set x 0} {$x < [string length $attr]} {incr x} { + if {[string index $attr $x] != "o"} { + set nattr [format "%s%s" $nattr [string index $attr $x]] + } + } + if {$nattr == {}} { set nattr "-" } + set User($i) [lreplace $User($i) 0 0 $nattr] + puts -nonewline stdout "[format " -o: %-10s " $i]" + } + if {([string first m $attr] != -1) && ($stripmasters == 1)} { + set nattr {} + for {set x 0} {$x < [string length $attr]} {incr x} { + if {[string index $attr $x] != "m"} { + set nattr [format "%s%s" $nattr [string index $attr $x]] + } + } + if {$nattr == {}} { set nattr "-" } + set User($i) [lreplace $User($i) 0 0 $nattr] + puts -nonewline stdout "[format " -m: %-10s " $i]" + } + } + if {($ts==0) && ($weedlurkers==1) && ([string first b $attr] == -1) && [info exists User($i)]} { + unset User($i) ; incr weeded + puts -nonewline stdout "[format "lrk: %-10s " $i]" + } + if {($ts > 0) && ($maxlast > 0) && ($CURRENT-$ts > $maxlast && [info exists User($i)])} { + unset User($i) ; incr weeded + puts -nonewline stdout "[format "exp: %-10s " $i]" + } + if {$chanrem != {} && [info exists Channel($i)]} { + foreach unchan $chanrem { + set id [lsearch [string tolower $Channel($i)] *$unchan*] + if {$id != -1} { + set Channel($i) [lreplace $Channel($i) $id $id] ; incr weeded + puts -nonewline stdout "[format "uwc: %-10s " $i]" + } + } + } + } + flush stdout +} +if {$weeded == 0 && $convert == 0} { puts -nonewline stdout "uNF... Nothing to weed!" } +puts stdout "\n" + +foreach i [array names User] { + if {([string range $i 0 1] == "::") || ($i == "*ban")} { + for {set j 0} {$j < [llength $Hostmask($i)]} {incr j} { + set ban [split [lindex $Hostmask($i) $j] :] + if {[string range [lindex $ban 2] 0 0] == "+"} { + set lastused [lindex $ban 3] + if {($maxban > 0) && ($CURRENT-$lastused > $maxban)} { + if {$i == "*ban"} { + puts stdout "Expired ban: [lindex $ban 0]" + } { + puts stdout "Expired ban on [string range $i 2 end]: [lindex $ban 0]" + } + set Hostmask($i) [lreplace $Hostmask($i) $j $j] + incr j -1 + } + } + } + } + if {$i == "*ignore"} { + for {set j 0} {$j < [llength $Hostmask($i)]} {incr j} { + set ign [split [lindex $Hostmask($i) $j] :] + set lastused [lindex $ign 3] + if {($maxignore > 0) && ($CURRENT-$lastused > $maxignore)} { + puts stdout "Expired ignore: [lindex $ign 0]" + set Hostmask($i) [lreplace $Hostmask($i) $j $j] + incr j -1 + } + } + } +} + +puts stdout "\nFinished scan." +puts stdout "Original total ($total), new total ([expr $total-$weeded]), zapped ($weeded)" + +if {![saveUserFile $filename.weed]} { + puts stdout "* uNF... Couldn't save new userfile!\n" + exit +} +puts stdout "Wrote $filename.weed" -- cgit v1.2.3