#!/usr/bin/tclsh
# --------------------------------------------
#
# This script gets the newest virus IDEs from
# Sophos and installs them in the dirs set in
# the config vars below.
#
# Last Change: 12.Sep.2002 Michael Schlenker
# 24.Feb 2003 M.S
#
# --------------------------------------------
# used for changing uid/gid
package require Tclx
# configuration data
set config(avupdateuser) avupdate
set config(avgroup) antivir
# drop rights instantly
id group $config(avgroup)
id user $config(avupdateuser)
# needed for http file transfer
package require http
# url of the ide file list
set config(url) http://www.sophos.com/downloads/ide/web_list.txt
# base url to download ides from
set config(base_url) http://www.sophos.com/downloads/ide/
# local sav dir for locally running icheckd (intercheck daemon)
set config(sav) /usr/local/sav
# install dir for W2k clients
set config(client) /home/sophos/NTInst/i386
# install dir for Win95 clients
lappend config(client) /home/sophos/W95Inst
# get the weblist and check what has to be done
proc Init {} {
global config
set geturls ""
# get weblist from sophos.com
set token [http::geturl $config(url)]
set data [http::data $token]
http::cleanup $token
# split list into single lines
set lines [split $data "\n" ]
set status ""
if {[llength $lines] > 0} {
set lines [lrange $lines 0 end-1]
}
# see if we have the ide files already
set files [glob -nocomplain -directory $config(sav) *.ide]
foreach file $files {
set fn [file tail $file]
lappend status $config(base_url)$fn
}
foreach line $lines {
if {[lsearch -exact $status [string trim $line]]== -1} {
puts stdout "New IDE: [string map [list $config(base_url) {}] $line]"
lappend geturls $line
} else {
set file [string map "$config(base_url) {}" $line]
set ffile [file join $config(sav) $file]
set mtime [file mtime $ffile]
set tok [http::geturl $line -validate 1]
upvar #0 $tok state
foreach {tag value} $state(meta) {
if {[string equal $tag "Last-Modified"]} {
set wmtime [clock scan $value]
}
}
http::cleanup $tok
# is the web server version newer?
if {$wmtime > $mtime} {
puts stdout "Updated IDE: $file"
lappend geturls $line
}
}
}
if {[llength $geturls]==0} {
puts stdout "No New IDEs found"
}
return $geturls
}
# get the ide files from sophos
proc geturls urllist {
global config
foreach url $urllist {
puts stdout "Getting $url"
set token [http::geturl $url]
set data [http::data $token]
set fn [string map [list $config(base_url) {}] $url]
set filename [file join $config(sav) $fn]
set fid [open $filename w+]
puts $fid $data
close $fid
http::cleanup $token
}
}
# copy the ide files to all target locations
proc copyides {} {
global config
set files [glob -directory $config(sav) *.ide]
# being lazy, copying all ide files to install dir
foreach file $files {
foreach dir $config(client) {
file copy -force $file $dir
file attributes [file join $dir [file tail $file]] -permissions a+r
puts stdout "Copying $file to client dir"
}
}
}
set urls [Init]
if {[llength $urls] > 0} {
geturls $urls
puts stdout "Downloaded [llength $urls] files"
copyides
} else {
puts stdout "Nothing to be done."
}
exit 0---SGET.EXE style script. Sophos SGET.EXE basically does authenticated HTTP, so not really a problem to get things done: #!/usr/bin/tclsh
# SGET.EXE in tcl
#
# (c) 2002,2003 Michael Schlenker
#
# last changes: 24.02.2003
#
# Sophos Update Program
#
#
# needed packages
package require Tclx
package require base64
package require http
# configuration data
#
# base_url is the url sophos provides the packages
set config(base_url) http://www.sophos.com/sophos/products/full/
# list of products to download
# -- angz.zip --> W2k Client
# -- linux.inter... -> linux server icheckd
# -- a95z.zip --> Win95 Client
#
set config(products) [list angz.zip linux.intel.libc6.tar.Z a95z.zip]
# list of temp dirs for products
# This lists the temp directories the packages are downloaded to for all the
# above products.
set config(localpath) [list /home/sophos/tmp /home/sophos/tmp /home/sophos/tmp]
# list of target unzip/uncompress/untar dirs for products
set config(targetpath) [list /home/sophos/tmp/win2000 /home/sophos /home/sophos/tmp/win95]
# passwort info
# the sophos password and user info needed
set config(user) ""
set config(passwd) ""
# user info
# the local group and user the files should belong to
set config(sophos_user) sophos
set config(sophos_group) antivir
if {[id userid] == 0 || \
[id effektive userid] == 0} {
puts stdout "Should not be run by root. Switching to sophos user."
id group $config(sophos_group)
id user $config(sophos_user)
}
# authenticated geturl
proc geturl_auth {url username password} {
puts stdout "Getting URL: $url"
set auth "Basic [base64::encode $username:$password]"
set headerl [list Authorization $auth]
set tok [http::geturl $url -headers $headerl -progress progress]
puts stdout "\nData received: [http::size $tok] bytes total"
set res [http::data $tok]
http::cleanup $tok
return $res
}
proc progress {token total count} {
puts -nonewline stdout "."
flush stdout
}
proc update_files {} {
global config
puts stdout "Updating products"
foreach prod $config(products) path $config(localpath) {
puts stdout "Getting $prod"
set data [geturl_auth $config(base_url)$prod $config(user) $config(passwd)]
set fid [open [file join $path $prod] w+]
fconfigure $fid -translation binary -encoding binary
puts -nonewline $fid $data
close $fid
puts stdout "Done getting $prod"
}
}
update_filesA script to scan a Starkit Archive with Sophos sweep: #!/usr/bin/env tclsh
package require vfs::mk4
if {[llength $argv] != 1} {
puts stderr "Usage: starscan.tcl <starkit>"
exit 1
}
# path to av scanner (sophos sweep in this case)
set avscanner /usr/local/bin/sweep
set tmpdir /var/tmp/starkitav
puts "Creating tempdir for decompression in $tmpdir"
if {![file exists $tmpdir]} {
file mkdir $tmpdir
}
file mkdir [file join $tmpdir avarea]
puts "Mounting virtual filesystem"
set vfs [vfs::mk4::Mount $starkit [file join $tmpdir starkit]]
puts "Copying vfs to local filesystem."
file copy [file join $tmpdir starkit] [file join $tmpdir avarea]
# executing av program
if {[set code [catch {exec $avscanner [file join $tmpdir $avarea]} msg]]} {
puts "Problem Found in $starkit: $code\n$msg"
}
# cleanup
vfs::mk4::Umount $vfs [file join $tmpdir starkit]
file delete -force [file join $tmpdir avarea]
exit $code
# end of scriptBut with the source available here, that means that someone might have infected the above code ...
Sure, but its short enough to really do code review ;-)

