: # BE SURE THIS IS STILL THE FIRST LINE IF YOU PASTE INTO THE UW-SETUP FILE
#
# UW Gibraltar customization by Corey Satten, corey@cac, 04/16/01
#    $Revision: 1.76 $ created $Date: 2008/12/10 02:58:27 $ (UTC)
#
# 1) fastboot an "unconfigured" gibraltar cdrom with no floppy in the drive
# 2) login root password gibraltar
# 3) type loadkeys us (the y and z key are interchanged at this point)
# 4) type mount /dev/fd0 /mnt
# 5) type /mnt/uw-setup and answer the questions
# 6) insert a blank floppy and type save-config (or type halt or reboot)
#
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11 #
#
###########################################################
#  Try to work in spite of DOS CRLF line terminators      #
NL=
case "$NL" in '');; *)                                    #
    T=/usr/local/bin/uw-setup; export T                   #
    echo $0 HAS DOS NEWLINES, doing workaround            #
    /bin/sed "s/$NL\$//" <$0 >$T; chmod +x $T; exec $T $* #
    exit 1 ;;                                             #
esac                                                      #
###########################################################

B='[1m'; N='[0m'	# Bold/Normal

Revision=Revision
echo ${B}uw-setup script $Revision: 1.76 ${N}

GVERS=`cat /etc/gibraltar_version`

case "$T" in '');; *) T=DOS;; esac

case "$T$0" in DOS*|/mnt/*)
    echo "Copying uw-setup to /usr/local/bin for future use" 
    sleep 1
    echo "Resuming execution from the copy in /usr/local/bin..."
    sleep 1
esac

case "$0" in /mnt*)
    T=/usr/local/bin/uw-setup
    /bin/sed "s/$NL\$//" <$0 >$T; chmod +x $T; exec $T $*
esac

if mount | grep 'on /mnt ' >/dev/null ;then
    echo "Unmounting your floppy disk"
    umount /mnt
    sleep 1
    fi

case "$1" in -n)
    NO_NET_CONF=1; shift
    echo
    echo "${B}Skipping network and interfaces config due to -n flag${N}"
    sleep 1
esac

echo ${B}
echo "This program will customize a default Gibraltar (cdrom-linux) system for"
echo "use at the University of Washington."
echo ${N}

########################################
SRC=/usr/share/keymaps/i386/qwerty/us.kmap.gz 
if [ -d /etc/console ] ;then
  DST=/etc/console/boottime.kmap.gz
else
  DST=/etc/console-tools/default.kmap.gz
fi
cp $SRC $DST
echo 'Switching to US keyboard mapping...'
echo
echo -n "Would you like to swap the left CTRL key with CAPS LOCK? [n]/y > "
read ANS
case "$ANS" in y*)
    zcat $SRC | sed '
	/^keycode *29 = Control/s/Control/Caps_Lock/
	/^keycode *58 = Caps_Lock/s/Caps_Lock/Control/
	' | gzip -9 > $DST;;
esac
loadkeys -q $DST

########################################
echo
OTZ=`date|awk '{print $5}'`
tzconfig
NTZ=`date|awk '{print $5}'`
########################################
echo
echo 'Configuring DNS...'
echo -n "What ${B}DEPT${N} goes here:  host.${B}DEPT${N}.washington.edu? > "
read DEPT

cat <<EOF >/etc/resolv.conf
search ${DEPT:+$DEPT.washington.edu} washington.edu
nameserver 128.95.112.1
nameserver 128.95.120.1
EOF

DEVS=/usr/local/sbin/moredevs
cat <<'EOF' >$DEVS
# let's flesh out the standard ide drivers a bit (opening hda creates hda* )
if [ ! -e /dev/hda ] ;then mknod /dev/hda b 3   0; echo -n </dev/hda; fi 2>&-
if [ ! -e /dev/hdb ] ;then mknod /dev/hdb b 3  64; echo -n </dev/hdb; fi 2>&-
if [ ! -e /dev/hdc ] ;then mknod /dev/hdc b 22  0; echo -n </dev/hdc; fi 2>&-
if [ ! -e /dev/hdd ] ;then mknod /dev/hdd b 22 64; echo -n </dev/hdd; fi 2>&-

# this doesn't belong here but it doesn't really warrant its own file either...
LASTLOG=/var/log/lastlog
if [ ! -e $LASTLOG ] ;then
  mkdir $LASTLOG
  fi

# logcheck in 0.99.4 needs /var/tmp/logcheck/
LCD=`sed -n 's/^TMPDIR=\([!-~]*\)$/\1/p' /usr/sbin/logcheck*`
if [ ! -d $LCD ] ;then
  mkdir -p $LCD
  fi
EOF
chmod 755 $DEVS
$DEVS

########################################
# fix "ipsec setup start" bug in 0.99.2
IPSEC=/etc/init.d/ipsec		# normal place
IPSEC2=/usr/local/sbin/ipsec	# bugfix copy
OIPS=/usr/lib/ipsec		# normal place
NIPS=$IPSEC2.d			# bugfix copy
case "$GVERS" in
 0.99.[23])			# {
    IPSEC=$IPSEC2
    rm -rf $NIPS
    mkdir $NIPS
    ln -s $OIPS/* $NIPS/
    F=$NIPS/ipsec
    sed "s;$OIPS;$NIPS;" < $F > $F.new && mv $F.new $F; chmod +x $F
    rm -f $IPSEC2
    ln -s $NIPS/ipsec $IPSEC2
    F=$NIPS/_startklips
    sed 's/&& modprobe/; modprobe/' < $F > $F.new && mv $F.new $F; chmod +x $F
    ;;				# }
 *) rm -rf $NIPS $IPSEC2;;
esac

########################################
case "$GVERS" in 2.1*)rev<<EOF|sh
yek.esnecil/ratlarbig/cte/ > MASQLOJII3ZDKFRTRQ5KQX4Z4IUNHORNMUUG64WNPQPTZLH2TJVGHBW3O5PK7BNCQ6Y4VL7C2SYLOP4E3QP3VMQGCGJ3QUQNBP66K6MJKCFBTXJI3ELPT62ULNECVEIOYSYXA3RYE3AVIGNDONSVYN2OPTUVR274Q26P33WJM5OIOJ3IL5QUVDFQAUIEAMHZF7KVRVRFT2426HOMYXRNNZM7YVQCYQO6NXP2KRJXRXVXPC6PHGQSRDDXHI3VMI2ELIQB5YI4ZCZGNQUW5MTS7OBKYCZLGUPNVDMIG3NOXSIWHTTENRKLPIG63FSSMJATDZB5TLT3VUBFFU6L3DYFMDR5KZ4SXVOJSBEFP2MNIIUF56T3QSIYE2EBM4GHTBAZ7A5FZZEHIQK3LKIAVUSDMS32GJAYMZRMGW3UGZJZIGSFHTZYEDRBGWBOCTY4GFLOMW44GYRZED3YMQBAGH3VMELZEXXVNPR3SGRNOPB3CWR5NM3LEXZVOPBAAAAAAAAZAAAAAEDAAACAABAAAAAAAAAACDXIGAAAAAAEI7MBXAAUOELZ4CX5NU3Z4WUBNTLYOHXMMB3YAU4VMS33GGA4KGCTASLVKAIA6FIOA ohce
EOF
;; esac
case "$GVERS" in 2.2*)rev<<EOF|sh
yek.esnecil/ratlarbig/cte/ > W3ZUSSL4VEIBSJRZCLAHZV7XWCFBFXEAIAI6H6LTDIAQYJUPZFU5MWGEEZ32N7APC7O2L2Q2RD7L2R74NZVHTTGDUD3TPYG5U7PGZIXHEFYQ5UBANMZOIYARK5ARKTFKYUAXIW3HLB3PPP63XCDVSOGAXQT2XAG5PZU5GNWAYLDNMUZP4GCZYDG3BDXNA4WSU4F53DHU4VZVOPHRZFAGCRFTFV6QA4C2Y6BOZ32E2TWBUBENISWFSHANFM57PAMKGH2EZLLI76VPIVM5YOIIKLEAQJB4TIBYAMFFZW7D7HDJNGWM4S25GPQCBDQF5QNDM4LJYUASYO3V4LKWWZCGUCO63MGDRWBYI2BY2SKVYBSET2EMMF6JSAVKNRY2ZUO646OIX7ERY2PJ4FKRSOXYQ2KGFFAYMZRMGW3UGZJZIGSFHTZYEDRBGWBOCTY4GFLOMW44GYRZED3YMQBAGH3VMELZEXXVNPR3SGRNOPB3CWR5NM3LEXZVOPBAAAAAAAAZAAAAAEDAAACAABAAAAAAAAAAEDXIGAAAAAAEI7MBXAAUOELZ4CX5NU3Z4WUBNTLYOHXMMB3YAU4VMS33GGA4KGCTASLVKAIA6FIOA ohce
EOF
;; esac
case "$GVERS" in 2.3*)rev<<EOF|sh
yek.esnecil/ratlarbig/cte/ > SVTRFQIC2FDSNKDNEMQVGZBBVSOR4XTZA3VFKRGZTLGQOFNNGBCUCBY7KJ3QYCT3MMOLQWFYBFRMNPC4CAGZOTQGW6A5ES3RQZICDT6PFBGNAL3CGJBUJUT67IOFEERX2KZQLUKE6AG6QA75OBCXYYW4IQPLZEHHKV2FO2K343J3Q6MWT3YNZLCPLLGD6Z27ONFYSI6NODOE6OQ3JPQGYWF4VBKIL4VAF6OYSRZEDODQYOUVLZB3JTV2FN5CQ6QMYSK7AOXINDKAYH6X5OVAJP733GCA6WHQKOXDCCWTKMO4MEXFQOPQCP7MNR3Y6B4IQ6WDWCAKEU7WP4UPEMVN3BULYGSN4UVIIL7QN4KEKIM5HBVM2L5JXFYRXH6OM3ZBGT6BQFJQDL4DSDVMJ6XMADRRIDAYMZRMGW3UGZJZIGSFHTZYEDRBGWBOCTY4GFLOMW44GYRZED3YMQBAGH3VMELZEXXVNPR3SGRNOPB3CWR5NM3LEXZVOPBAAAAAAAAZAAAAAEDAAACAABAAAAAAAAAAGDXIGAAAAAAEI7MBXAAUOELZ4CX5NU3Z4WUBNTLYOHXMMB3YAU4VMS33GGA4KGCTASLVKAIA6FIOA ohce
EOF
;; esac
case "$GVERS" in 2.4*)rev<<EOF|sh
yek.esnecil/ratlarbig/cte/ > YOZVQIAUEJA7KLUQU74CTTIUS4T6UGD6J2LAXD5FEWVYQ3BOL7LF46KQWFWIY3BKSE3LDFZ5RI72MB6J2Z54KH557QKRLSROAONALOYGCESO36FRWTSJGVUKXADCD6XPUGQBOOFFEJPO5YEAKCL5PGW3V3XJJACALTSLA32P4GYIFXAH6ND5XT6UJFIYUIFMLQGOVZI2AH4GM5XADTKPAWS47UUNH4XBQPG4OHGGJHAYSVAYI7CLSTV7J5X2ISKBRRQCBRSFQF33BK33LVAX6SI5EE6EUZVIG32FRZQXWLUIO6MGQ4X2DFH2HSWBMYIQXEPTZCQEGDZ3RSGUC6EPOIBVYIXOYT6U25TNJUYHKFDF4WR4GJZHEN2GAXW7LC4AZW3CAL7MAJCNR4NOUOI7O5H2MFAYMZRMGW3UGZJZIGSFHTZYEDRBGWBOCTY4GFLOMW44GYRZED3YMQBAGH3VMELZEXXVNPR3SGRNOPB3CWR5NM3LEXZVOPBAAAAAAAAZAAAAAEDAAACAABAAAAAAAAAAIDXIGAAAAAAEI7MBXAAUOELZ4CX5NU3Z4WUBNTLYOHXMMB3YAU4VMS33GGA4KGCTASLVKAIA6FIOA ohce
EOF
;; esac
case "$GVERS" in 2.5*)rev<<EOF|sh
yek.esnecil/ratlarbig/cte/ > IQWC6WD5RNJROXESKGICUKMKS7QYB77IBG3J4EFXU4XTPRJXJ43XMLXF6YIEZVFYSL6IOXLF7EWNDMKXU56ITCH3FBMIJQUM3J4ALYEP2BPGJUBGUNRQX3MRGMBNS4ZKI5J2GQQUHAESX5M2AMMVPVK6YRS7E327JYF2NQ4LSDVHQ73AIDFFDMQOBPUGKJK7RDKPXISESNCYMYRLUWQZZBKZ3IZBWJNC6RXYNGDZWCG5LFGIHC3GNIGSOYOEOWN3PQZ44M7ZDQSQLR45CARWLEAGDKG3UB7IIIOYVWQKOOYFUML4HXOFAP4IG2LDQOEKYLETMF6LFHSUMAHLK7Y4OLHGKHETUR5EIUGTBJPDDZRZ6EZMAQAKV5QNE7PDEL4DQQHJNPDSI45WPLCQ5TDZEMO63CAYMZRMGW3UGZJZIGSFHTZYEDRBGWBOCTY4GFLOMW44GYRZED3YMQBAGH3VMELZEXXVNPR3SGRNOPB3CWR5NM3LEXZVOPBAAAAAAAAZAAAAAEDAAACAABAAAAAAAAAAKDXIGAAAAAAYIDDVACAUOELZ4CX5NU3Z4WUBNTLYOHXMMB3YAU4VMS33GGA4KGCTASLVKAIA6FIOA ohce
EOF
;; esac
case "$GVERS" in 2.6*)rev<<EOF|sh
yek.esnecil/ratlarbig/cte/ > MZKTDGARGBW6WLZISZOTRISOH2FRHUUJRBBUFKQJW674QJJGYEHSNGKIXXOFYLMIN3TKGZK6ZYJDNOHRR5A6TFGRLFI6ALKHNXJZS7R6V2G3H7SLY2RKWBQCYI7S23CZ5J24ESYP5J6GLBMSOVM4DZBRTZUT5Q3GCWHFMWLQY5Q4YJKW4BTIFPDN7LUIEKFHP6WYARIUFCW36VFMD6YNRMFJ5UASOLHWKN5K4WV44SUWAHCR45F645ZP56VZK5J2RAT2XV6YAUOOODLB3DVJORTPEPQOJWCXQH47SZYCRCW2BXBEUCTHLA4PGAWDLVUOETJ3KS4NRM73BLMFNREQAMIJJ2IGS52UTAOWMHNSX4ZA6COCCNPGSBRWLPZVCBGQ563FEGPMQS2HRUQVOKEJLE5DIJAYMZRMGW3UGZJZIGSFHTZYEDRBGWBOCTY4GFLOMW44GYRZED3YMQBAGH3VMELZEXXVNPR3SGRNOPB3CWR5NM3LEXZVOPBAAAAAAAAZAAAAAEDAAACAABAAAAAAAAAAMDXIGAAAAAAYIDDVACAUOELZ4CX5NU3Z4WUBNTLYOHXMMB3YAU4VMS33GGA4KGCTASLVKAIA6FIOA ohce
EOF
;; esac

########################################
# turn off unneeded services and install initial firewall
TB=/usr/local/sbin/tables
RL=runlevel.conf
cp /etc/$RL /tmp/RL$$ &&
gawk '
BEGIN			{dir = "/usr/local/sbin"; rl = "2,3,4,5"}
BEGIN			{GVERS = "'$GVERS'"}
/^[0-9].*\/bld-submit/	{print "#" $0; next}
/^[0-9].*\/dnscache/	{print "#" $0; next}
/^[0-9].*\/daemontools/	{print "#" $0; next}
/^[0-9].*\/portsentry/	{print "#" $0; next}
/^[0-9].*\/ntpdate/	{print "#" $0; next}
/^[0-9].*\/ntp$/	{print "#" $0; next}
/^[0-9].*\/psad$/	{print "#" $0; next}
/^[0-9].*\/jetty$/	{print "#" $0; next}
/^[0-9].*\/spamassassin/{print "#" $0; next}
/^#[0-9].*\/postfix/	{print substr($0,2); next}
/^[0-9].*\/networking/	{sub(/0,6[^,]/,"0,2,3,4,5,6"); print; next}
/^[0-9].*\/arplog/	{next}
/^[0-9].*\/clocksync/	{next}
/^[0-9].*\/tables$/	{next}
/^[0-9].*\/moredevs$/	{next}
/^[0-9].*\/mount-tmp$/	{next}
/^[0-9].*\/ipsec$/	{sub(/[!-~]*ipsec/,"'"$IPSEC"'"); print; next}
$1 > 22 && !d1++	{print "22\t-\t" rl "\t\t" dir "/mount-tmp"}
$1 > 98 && !d2++	{print "98\t-\t" rl "\t\t'"$TB"'"}
$1 > 98 && !d3++	{print "98\t-\t" rl "\t\t" dir "/clocksync"}
$1 > 98 && !d4++	{print "98\t-\t" rl "\t\t'"$DEVS"'"}
$1 > 98 && !d5++	{print "98\t-\t" rl "\t\t" dir "/arplog"}
			{print}
' </tmp/RL$$ >/etc/$RL && rm /tmp/RL$$

BLDS=/etc/init.d/bld-submitter
if [ -f $BLDS ] ;then $BLDS stop ;fi

DNSC=/etc/init.d/dnscache
if [ -f $DNSC ] ;then $DNSC stop ;fi

DTLS=/etc/init.d/daemontools	# in 0.99.3 this runs dnscache
if [ -f $DTLS ] ;then $DTLS stop 2>&- ;fi

PSEN=/etc/init.d/portsentry
if [ -f $PSEN ] ;then $PSEN stop ;fi

NTPD=/etc/init.d/ntp
if [ -f $NTPD ] ;then $NTPD stop ;fi

PSAD=/etc/init.d/psad
if [ -f $PSAD ] ;then $PSAD stop ;fi

JSRV=/etc/init.d/jetty
if [ -f $JSRV ] ;then echo Stoping java; $JSRV stop >/dev/null 2>&1 & fi

SPAS=/etc/init.d/spamassassin
if [ -f $SPAS ] ;then $SPAS stop ;fi

if [ ! -s $TB ] ;then	# create initial firewall to block all tcp except ssh
cat <<'EOF' >$TB
#!/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/bin/X11

if lsmod|grep '^ip_tables' >/dev/null ;then :; else
  modprobe ip_tables
  fi

echo 0 > /proc/sys/net/ipv4/conf/all/proxy_arp
echo 0 > /proc/sys/net/ipv4/ip_forward

####################################
# these protect the firewall box   #
####################################

# protect box until rules are installed
iptables -P INPUT DROP
iptables -P OUTPUT ACCEPT
iptables -F		# flush all tables
iptables -X		# delete all user-defined tables

####################################
# these protect the firewall box   #
####################################
iptables -A INPUT -p tcp -s localhost				    -j ACCEPT
iptables -A INPUT -p tcp --tcp-flags ALL ALL			    -j DROP
iptables -A INPUT -p tcp --tcp-flags ALL NONE			    -j DROP
iptables -A INPUT -m state --state ESTABLISHED			    -j ACCEPT
iptables -A INPUT -p tcp			  --dport 22	    -j ACCEPT
iptables -A INPUT -p tcp					    -j REJECT
iptables -A INPUT -p udp					    -j REJECT
iptables -A INPUT						    -j ACCEPT
EOF

chmod +x $TB
$TB
fi

########################################
echo
HOSTNAME=
case "$NO_NET_CONF" in '')
    echo 'To configure the primary ethernet interface, enter a hostname below.'
    echo 'To leave firewall rules unchanged and skip network configuration,'
    echo '...supply no hostname below (just press enter).'
echo -n "What DNS ${B}hostname${N} would you like to give this system? > "
read HOSTNAME
esac

case "$NO_NET_CONF@$HOSTNAME" in
     @) echo; echo 'No hostname given, skipping network configuration';;
    1@) echo 'uw-setup -n, so skipping network configuration';;
     *)
echo $HOSTNAME | sed 's/\..*//' > /etc/hostname; hostname $HOSTNAME

echo
echo -n "What ${B}IP address${N} should $HOSTNAME correspond to? > "
read IP

echo
echo -n "What is the ${B}netmask${N} for $IP (defaults to 255.255.255.0) > "
read MASK
case "$MASK" in '') MASK=255.255.255.0;; esac


and() { # bitwise and of four dotted decimal octets
    perl -e '@a = split(/\./, shift); @b = split(/\./, shift);
	for $i ( 0 .. $#a) { $out .= (($a[$i]+0) & ($b[$i]+0)) . " "; }
	print "$out\n";' $*
    }
nor() { # bitwise or of four dotted decimal octets but with first arg negated
    perl -e '@a = split(/\./, shift); @b = split(/\./, shift);
	for $i ( 0 .. $#a) { $out .= ((($a[$i]+0)^255) | ($b[$i]+0)) . " "; }
	print "$out\n";' $*
    }

set x `and $IP $MASK`
NET=$2.$3.$4.$5
case "$NET" in *.*.*.0) GW=$2.$3.$4.100;; esac

set x `nor $MASK $IP`
BCAST=$2.$3.$4.$5

echo
echo -n "What is the ${B}gateway${N} for $IP (defaults to $GW) > "
read GWAY
case "$GWAY" in '') GWAY=$GW;; esac

IFACE=/etc/network/interfaces

if [ ! -f $IFACE.bak ] ;then
    mv $IFACE $IFACE.bak
    fi

cat <<EOF > /etc/network/interfaces
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)

# The loopback interface
# automatically added when upgrading
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
	address $IP
	netmask $MASK
	network $NET
	broadcast $BCAST
	gateway $GWAY
EOF

echo
echo "Please choose a ${B}good${N} password for the root (superuser) account"
for i in 1 2 3 4 5 6 7 8 9 10; do
  passwd && break
done

# gibraltar 0.98c misconfigures the 3c905 NIC to use the missing 3c90x module
# change it to use the existing 3c59x module
EMOD=/etc/modules
if listpci | grep -q '^NETWORK 3c90x ' ;then
  if modprobe 3c90x 2>&- ;then : ;else
     echo enabling 3c90x card with 3c59x driver
     cp $EMOD $EMOD.orig &&
       sed '/^3c90x$/d; /^3c59x$/d' < $EMOD.orig > $EMOD &&
       echo 3c59x >> $EMOD &&
       rm -f $EMOD.orig
     modprobe 3c59x
   fi
fi 2>&-

/etc/init.d/networking stop
/etc/init.d/networking start
;;
esac

########################################
# gibraltar 0.98c doesn't load ip_conntrack_ftp and ip_nat_ftp by default
EMOD=/etc/modules
cp $EMOD $EMOD.orig &&
  sed '/^#ip_.*_ftp/s/#//' < $EMOD.orig > $EMOD &&
  rm -f $EMOD.orig
modprobe `grep '^ip_.*_ftp' $EMOD` 2>&-

########################################
# workaround for broken man command
MAN=/usr/local/bin/man
echo '#!/bin/sh
/usr/bin/man ${1+"$@"} | $PAGER -r -M' > $MAN
chmod 755 $MAN

########################################
CS=/usr/local/sbin/clocksync
cat <<'EOF' > $CS
#! /bin/sh

test -f /usr/sbin/ntpdate || exit 0

FILE=/etc/cron.d/clocksync

. /etc/default/rcS
case "$UTC" in
  no|"") ZONE=--localtime;;
      *) ZONE=--utc;;
esac

case "$1" in
''|start|restart|force-reload)
  NS=`sed -n 'h; s/^nameserver *//p; g; /^nameserver/q' /etc/resolv.conf`
  ping -w 10 -c 1 localhost >/dev/null 2>&1
  case "$?" in 0|1) WFLAG='-w 10';; esac
  if ping $WFLAG -c 1 $NS >/dev/null ;then
    echo "Running ntpdate to set the date and time"
    /usr/sbin/ntpdate -b -s seiko.cac rolex.cac
  fi
  echo "Setting the hardware clock to $ZONE"
  /sbin/hwclock --systohc $ZONE
  echo "Arranging to keep the time correct"
  MIN=`/bin/date +%M`
  echo "$MIN * * * * root /usr/sbin/ntpdate -s seiko.cac rolex.cac" > $FILE
  ;;
stop)
  rm -f $FILE
  ;;
*)
  echo "Usage: $0 {start|stop|restart|force-reload}"
  exit 1
esac

exit 0
EOF
chmod 755 $CS
echo
$CS start
(crontab -l 2>/dev/null | grep -v -w ntpdate) | crontab -

########################################
# ifstate bug workaround
SPOOF=/etc/network/spoof-protect
if grep workaround $SPOOF >/dev/null ;then :; else
cat <<'EOF' >> $SPOOF

# workaround in case ifupdown isn't run at runlevel S - Corey 0.98
case "`runlevel`/$1" in unknown/start) rm -f /etc/network/ifstate;; esac
EOF
fi

########################################
# ifup ifdown bug workaround
IFUP=/usr/local/sbin/ifup
IFDOWN=/usr/local/sbin/ifdown
cat <<'EOF' > $IFUP
#!/bin/sh
#
# workaround for bug in ifup/ifdown where several eth0:# entries dump core.
# fix does stanzas individually so blank lines are now significant!  - Corey 

PROG=/sbin/`basename $0`
TMP=/tmp/ifup$$

trap "rm -f $TMP; exit 0" 0 1 2 13 15
case "$PROG" in *ifdown) exec 2>&-;; esac

for i in $*; do
  case "$1" in
    -h|--help)		exec $PROG "$@";;
    -V|--version)	exec $PROG "$@";;
    -a|--all)		FLAGS="$FLAGS $1"; shift;;
    -i|--interfaces)	IFILE="$2"; shift; shift;;
    -n|--no-act)	FLAGS="$FLAGS $1"; shift;;
    -v|--verbose)	FLAGS="$FLAGS $1"; shift;;
    --nomappings)	FLAGS="$FLAGS $1"; shift;;
    --force)		FLAGS="$FLAGS $1"; shift;;
  esac
done

IFILE=${IFILE-/etc/network/interfaces}
TFILE="/tmp/`basename $IFILE`".up

case $PROG in
  *ifup) cp $IFILE $TFILE; exec < $IFILE;;
  *down) if [ ! -f $TFILE ] ;then cp $IFILE $TFILE; fi; exec < $TFILE;;
esac

while read -r a b c; do
  if [ ! -z "$a" ] ;then
    echo "$a $b $c" >>$TMP
    case "$a$PROG" in
      iface*ifdown) echo "$b=$b" >/etc/network/ifstate;;
      iface*ifup)   echo -n      >/etc/network/ifstate;;
    esac
  else
    if [ -s $TMP ] ;then $PROG $FLAGS -i $TMP; rm $TMP ;fi
  fi
done
if [ -s $TMP ] ;then $PROG $FLAGS -i $TMP; rm $TMP ;fi
EOF
rm -f $IFDOWN; ln $IFUP $IFDOWN; chmod +x $IFUP

########################################
# email-related fixes

TMP=/tmp/ema$$
MASTER=/etc/postfix/master.cf
NL='
'
sed "
  s/tlsmgrrewrite/tlsmgr\\${NL}rewrite/
  s/^#local/local/
  " $MASTER > $TMP && cp $TMP $MASTER && rm $TMP

MAIN=/etc/postfix/main.cf
HOSTNAME=`cat /etc/hostname`${DEPT:+.$DEPT}.washington.edu
sed "
  s/^myhostname.*/myhostname = $HOSTNAME/
  s/^myorigin/#&/
  s/^destinations/#&/
  s/^mynetworks/#&/
  " $MAIN > $TMP && cp $TMP $MAIN && rm $TMP

ALIASES=/etc/aliases
if grep '^root:' $ALIASES >/dev/null ;then :; else
  echo "root:		/dev/null" >> /etc/aliases
  newaliases
  fi

/etc/init.d/postfix restart

########################################
# add space to /var and isolate /tmp

case "$GVERS" in	# {
0.98*)			# start of case 0.98 {

VARDISKSIZE=/etc/vardisk-size
cat <<'EOF' >$VARDISKSIZE
RDS=`sed -n 's/.*ramdisk_size=\([0-9]*\).*/\1/p' /proc/cmdline`
VARDISK_SIZE=${RDS:-2048}

# normally this would return to /sbin/make-var-disk but I need to override it
# to expand /var onto 3 ramdisks to get more space and inodes without
# changing the CDROM - Corey

ramdev2=$ramdevnumber
ramdev3=`expr $ramdevnumber + 1`
ramdev4=`expr $ramdevnumber + 2`

echo -n "Creating ramdisks for unpacking the $mountpoint image ($VARDISK_SIZE kb)... "

dd if=/dev/zero "of=${ramdisks}${ramdev2}" bs=1024 count=$VARDISK_SIZE >&- 2>&-
dd if=/dev/zero "of=${ramdisks}${ramdev3}" bs=1024 count=$VARDISK_SIZE >&- 2>&-
dd if=/dev/zero "of=${ramdisks}${ramdev4}" bs=1024 count=$VARDISK_SIZE >&- 2>&-

mke2fs -b 1024 -i 4096 -q "${ramdisks}${ramdev2}" > /dev/null 2> /dev/null
mke2fs -b 1024 -i 4096 -q "${ramdisks}${ramdev3}" > /dev/null 2> /dev/null
mke2fs -b 1024 -i 4096 -q "${ramdisks}${ramdev4}" > /dev/null 2> /dev/null

mount -t ext2 "${ramdisks}${ramdev2}" $mountpoint
mkdir $mountpoint/tmp $mountpoint/log
mount -t ext2 "${ramdisks}${ramdev3}" $mountpoint/tmp
mount -t ext2 "${ramdisks}${ramdev4}" $mountpoint/log
chmod 777 $mountpoint/tmp

echo "done"

echo -n "Unpacking default $mountpoint tree ... "
pushd $mountpoint > /dev/null
tar xz --preserve --same-owner -f $image
popd > /dev/null
echo "done"

exit 0
EOF

if mount | grep '/var/tmp' > /dev/null ;then :; else
 echo
 echo "${B}Your next reboot will add ramdisk needed for long-term operation${N}"
 echo
 sleep 1
fi

;;			# end of case 0.98 }
*)			# start of new case {

GCONF=/etc/gibraltar_config
if [ -f $GCONF -a ! -f $GCONF.bak ] ;then
  if grep -q 'Attached: Yes' /proc/scsi/usb-storage*/* 2>&- &&
   ! grep -q '^/dev/f[ld]' /etc/gibraltar/config_source 2>&-
  then EDC=16m	# suitable for config on USB
  else EDC=10m	# suitable for config on floppy
  fi 
  VARS=16m; TMPS=8m	# default sizes
  # because intensive port scanning can generate large logs, if system has
  # enough RAM, enlarge ramdisk so logcheck can email at least 5MB at once
  MEMS=`awk '/^Mem:/ {printf("%d\n", $2/1000000)}' /proc/meminfo`
  if [ "$MEMS" -ge 80 ] ;then VARS=32m; TMPS=32m; fi
  sed '
    /^SAVE_AUTOFORMAT=/s/=.*/=YES/
    /^VARDISK_SIZE=/s/=.*/='"$VARS"'/
    /^ETCDISK_SIZE=/s/=.*/='"$EDC"'/
    /^AUTOMATIC_VAR_CLEANUP_REBOOT=/s/=.*/=no/
    /^SAVE_FILESYSTEM=/s/=.*/=vfat/
    $a\
TMPDISK_SIZE='"$TMPS"'
    /^TMPDISK_SIZE=/d
    ' < $GCONF > $GCONF.new &&
  cp -p $GCONF{,.bak} && cp $GCONF{.new,} && rm $GCONF.new
fi

MT=/usr/local/sbin/mount-tmp
cat <<EOF >$MT
#!/bin/sh

CDEF=/usr/lib/gibraltar-bootsupport/common-definitions.sh
if [ -f \$CDEF ] ;then
  . \$CDEF
else 
  . /etc/default/common-definitions.sh
fi
. $GCONF

remount_tmpfs \$VARDISK_SIZE /var
remount_tmpfs \$ETCDISK_SIZE /etc

if mount | grep '/var/tmp' > /dev/null ;then
  remount_tmpfs \$TMPDISK_SIZE /var/tmp
else
  mount_tmpfs \$TMPDISK_SIZE /var/tmp
fi
EOF
chmod 755 $MT
$MT

;;			# end of new case }
esac			# }


########################################
# state viewing tools
STATE=/usr/local/bin/state
IP2NAME=/usr/local/bin/ip2name
cat <<'EOF' >$STATE
#!/bin/sh
# show firewall state in easier to read format - Corey Satten 5/3/01

# first octet of public net
OCT1=`ifconfig eth0|sed -n '2s/^.*inet addr:\([0-9][0-9]*\).*/\1/p'`

case "$1" in
	-n) cat -n;;
	*) cat -n | ip2name -I -g;;
esac < /proc/net/ip_conntrack |

sed '
: top
# change src=foo dst=bar sport=N dport=M to ((foo:N->bar:M))
s/\(.*\)src=\([!-~]*\) *dst=\([!-~]*\) *sport=\([0-9]*\) *dport=\([0-9]*\)/\1((\2:\4->\3:\5))/
t top

# replace 10. addresses with their public addresses
s/\([^0-9]\)10\.\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*:\)/\1'${OCT1:-10}'.\2/g

# collapse ((foo:N->bar:M))->((bar:M->foo:N)) to <<foo:N<->bar:M>>
s/((\(.*\)->\(.*\))) *((\(\2\)->\(\1\)))/<<\1<->\2>>/

# if line still has ports, better leave it asis
/port=.*port=/b

# else collapse bidirectional portless state to <<foo<->bar>>
s/src=\([!-~]*\) *dst=\([!-~]*\)\(.*\)src=\(\2\) *dst=\(\1\)/<<\1<->\2>>\3/

# improve spacing
s/  */ /g
s/^\([ 0-9]*	\)unknown/\1???/
' |

expand -4
EOF
cat <<'EOF' >$IP2NAME
#! /usr/bin/perl
eval 'exec perl -S $0 ${1+"$@"} ;' unless 1;
#
# find a dotted-decimal IP address somewhere on a line, look up its name
# and append the name to the line.
#
# if -i is given, replace the IP address inplace with as much of the
# name as fits (instead of appending it).
#
# if -I is given, replace the IP address inplace with the whole name
# even if the name doesn't "fit" in the original IP address's space.
#
# if -f is given, don't strip \.washington\.edu from the name
#
# if -g is given, all ip addresses on a line are done (not just the first)
#
# Corey Satten, corey @ cac.washington.edu, 2/13/97, 10/13/99
# Hacked to map private NAT addresses to their public unnatted name 5/1/01

$omit_wash = 1;		# omit .washington.edu unless -f flag given

while ($ARGV[0] =~ /^-./) {
    $_ = shift(@ARGV);
    if (/^-g$/) { $gflag = 1; next; }
    if (/^-i$/) { $inplace = 1; next; }
    if (/^-I$/) { $inplace = 2; next; }
    if (/^-f$/) { $omit_wash = 0; next; }
    die ("unknown flag");
    }

if ($ARGV[0] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
    # argument is IP addr not filename, just convert it and exit.
    $arg = pack("CCCC", $1, $2, $3, $4);
    ($name,$aliases,$addrtype,$length,@addrs) = gethostbyaddr($arg, 2);
    if ($name) {
	print "$name\n";
	exit(0);
	}
    exit(1);
    }

open (nat, "iptables -L -n -t nat|");
while (<nat>) {
    if (/^DNAT.* ((\d+\.){3}\d+)\s+to:((\d+\.){3}\d+)/) {
	$nat{$3} = $1;
	}
    }
close(nat);
	
while (<>) {
    $tmp = $_;		# copy of input line used for ip search & loop control
    $ofs = 0;		# keep track of offset caused by long -I names

    while ($tmp =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)( *)/) {
	if ($nat{"$1.$2.$3.$4"}) {
	    $nat{"$1.$2.$3.$4"} =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/;
	    $arg = pack("CCCC", $1, $2, $3, $4);
	    $fo = $1;
	    }
	else {
	    $arg = pack("CCCC", $1, $2, $3, $4);
	    $fo = $1;
	    }
	if (!$cache{$arg} && $fo != 10) {
	    ($name,$aliases,$addrtype,$length,@addrs) = gethostbyaddr($arg, 2);
	    $cache{$arg} = $name;
	    }
	else { $name = $cache{$arg}; }

	$pos = length($`);		# position IP found in original line
	$len = length("$1.$2.$3.$4$5");	# len of IP and trailing space
	$fmt = $len - 1;		# printf fmt len for name

	$name =~ s/\.washington\.edu$// if ($omit_wash);

	if ($inplace) {
	  if ($name) {
	    if ($inplace == 2) {	# untruncated names can make line grow
		$grow = length($name) > $fmt ? length($name) - $fmt : 0;
		$fmt += $grow;		# line will grow by this much
		}
	    substr($_, $pos+$ofs, $len) = sprintf("%-${fmt}.${fmt}s ", $name);
	    $ofs += $grow;		# keep track of cumulative growth
	    }
	  }
	else { s/$/	$name/; }

	last unless($gflag);

	substr($tmp, $pos, $len) = '-' x $len;	# wipe addr from loop control
	}
    print;
    }
EOF
chmod +x $STATE $IP2NAME

VMS5=/usr/local/bin/vms5
cat <<'EOF' > $VMS5
#!/bin/sh
trap 'kill -9 $BG;  exit 0' 1 2 13 15
while sleep 60; do date; done&
BG=$!
vmstat 5
EOF
chmod +x $VMS5

########################################
# reduce /var/log growth by eliminating
# logging of the same info to multiple files
# also add to logcheck's ignore file

IP=${IP-`ifconfig eth0|sed -n 's/.*inet addr:\([!-~]*\) .*/\1/p'`}
IGN=/etc/logcheck/logcheck.ignore
# these would show up in the "Unusual System Events" section
sed "
  \$a\\
UW-SETUP-ADDITIONS\\
arplog: MAC .* at IP\\
postfix/smtp\\
postfix/qmgr\\
ipsec__plutorun: \\
[Pp]luto\\\\[.*\\\\]: .* network error.*not authenticated\\
[Pp]luto\\\\[.*\\\\]: .* ignoring Vendor ID payload\\
[Pp]luto\\\\[.*\\\\]: .* extended network error info\\
[Pp]luto\\\\[.*\\\\]: .* max number of retransmissions\\
[Pp]luto\\\\[.*\\\\]: .* starting keying attempt\\
[Pp]luto\\\\[.*\\\\]: .* some IKE message we sent\\
[Pp]luto\\\\[.*\\\\]: .* ISAKMP SA\\
[Pp]luto\\\\[.*\\\\]: .* Main Mode\\
[Pp]luto\\\\[.*\\\\]: .* SA established\\
[Pp]luto\\\\[.*\\\\]: .* SA: .* will do$\\
[Pp]luto\\\\[.*\\\\]: .* Quick Mode\\
[Pp]luto\\\\[.*\\\\]: .* superseded by\\
[Pp]luto\\\\[.*\\\\]: .* [Pp]eer ID is ID_IPV4_ADDR:\\
[Pp]luto\\\\[.*\\\\]: .* transition from state\\
[Pp]luto\\\\[.*\\\\]: .* did not send a certificate\\
[Pp]luto\\\\[.*\\\\]: .* ignored informational message\\
[Pp]luto\\\\[.*\\\\]: .* ignoring Delete SA payload\\
ntpdate\\\\[.*\\\\]: .* time server .* offset -*[0-5]\\\\.\\
PAM_unix\\\\[.*\\\\]: \\\\(cron\\\\) session .* for user root\\
kernel: IN=eth.* SRC=140.142.* DST=$IP .* PROTO=TCP .* DPT=113\\\\ \\
kernel: send_arp uses obsolete\\
kernel: ipsec.*: no IPv6 routers present\\
kernel: NAT: [0-9][0-9]* dropping untracked packet
  /^UW-SETUP-ADDITIONS/,\$d
  " < $IGN > $TMP && cp $TMP $IGN && rm $TMP

# these would show up in the "Possible Security Violations" section
IGN2=/etc/logcheck/logcheck.violations.ignore
sed "
  \$a\\
UW-SETUP-ADDITIONS\\
[Pp]luto\\\\[.*\\\\]: .* network error.*not authenticated
  /^UW-SETUP-ADDITIONS/,\$d
  " < $IGN2 > $TMP && cp $TMP $IGN2 && rm $TMP

SYNGCF=/etc/syslog-ng/syslog-ng.conf
SYDCNF=/etc/syslog.conf
LOGCKC="/var/log/syslog /var/log/auth.log"
if [ -f $SYDCNF -a ! -f $SYDCNF.bak -a ! -f $SYNGCF ] ;then
  cp -p $SYDCNF $SYDCNF.bak
  cat <<'EOF' > $SYDCNF
#  /etc/syslog.conf     Configuration file for syslogd.
#                       For more information see syslog.conf manpage.
#
auth,authpriv.*			/var/log/auth.log
*.*;auth,authpriv.none		-/var/log/syslog
EOF
  HUP_SYSLOGD=1
  fi

########################################
# Beginning with 0.99.8a, convert syslog.conf
if [ -f $SYDCNF -a  -f /etc/cron.d/logrotate ]; then
  LOGCKC="/var/log/syslog"
  sed '
    /^auth,authpriv\.\*[^!-~]*\/var\/log\/auth.log[^!-~]*$/ N
    /^.*\n\*\.\*;auth,authpriv.none[^!-~]*-\/var\/log\/syslog[^!-~]*$/ {
             s//*.emerg				*/
             i\
*.notice;mail.*			-/var/log/syslog\
*.=debug;*.=info;mail.none	-/var/log/debug
      } ' < $SYDCNF > $SYDCNF.new
  if cmp -s $SYDCNF{,.new} ;then :; else
     cp $SYDCNF{.new,}
     HUP_SYSLOGD=1
  fi
  rm -f $SYDCNF.new
fi
case "$HUP_SYSLOGD" in 1) killall -1 syslogd;; esac

LOGCKF=/etc/logcheck/logcheck.logfiles
if [ ! -f $LOGCKF.bak ] ;then
  cp -p $LOGCKF $LOGCKF.bak
  (echo "# these files will be checked by logcheck"
   for i in $LOGCKC; do echo $i; done) > $LOGCKF
fi

########################################
# additional scripts

REJFMT=/usr/local/bin/rejfmt
cat <<'EOF' >$REJFMT
#!/usr/bin/perl
#
# make iptables rejected packet messages easier to read - corey@cac 6/01, 6/04

if ($ARGV[0] eq "-s") { shift @ARGV; $src = 1; }

$| = 1;
while (<>) {
  if (/^(.{15}) \S* (kernel: )*IN=.* SRC=(\S*) DST=(\S*) [^[]* PROTO=(\S*) SPT=(\S*) DPT=(\S*) /) {
    printf("%s %15s%s -> %15s:%-5d %3s\n",
      $1, $3, ($src ? sprintf(":%-5d",$6) : ""), $4, $7, $5)
    }
  elsif (/^(.{15}) \S* (kernel: )*IN=.* SRC=(\S*) DST=(\S*) [^[]* PROTO=(\S*) (.*PROTO=(\S*))*/) {
    printf("%s %15s%s -> %15s       %3s\n",
      $1, $3, ($src ? "      " : ""), $4, ($7 ? "$5 re $7" : $5))
    }
  }
EOF
chmod +x $REJFMT

STRINGS=/usr/local/bin/strings
if [ -f /usr/bin/strings ] ;then
rm -f $STRINGS
else
cat <<'EOF' >$STRINGS
#!/bin/sh
#
# output ascii strings of 4 or more chars - corey@cac 7/01
cat $* | tr -d -c '\000 \011\012!-~' | tr '\000' '\012' | sed '/^..../b;d'
EOF
chmod +x $STRINGS
fi

########################################
# arp stuff (used to force gateway to notice when an IP moves to the LFW
# (otherwise must wait for gateway arp cache to timeout which can be a while)

ARPP=/usr/local/bin/arp-push
cat <<'EOF' >$ARPP
#!/bin/sh
#
# Populate the arp cache on the gateway with all firewall IPs
# (until I have a better way to do this...) Corey Satten, corey@cac, 5/28/03

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

case "$1" in -n) NFLAG=echo;; esac

set x `ifconfig |
  sed -n '
    /^eth/ {
	N
	s/^\(eth[0-9]*\).*inet addr:\([!-~][!-~]*\).*Bcast:\([!-~][!-~]*\).*/\2 \3 \1/p
	}'`; shift

for i in $*; do
  case "$1" in
    *.*.*.*) $NFLAG arping -q -I $3 -c 1 -A -s $1 $2; shift; shift; shift;;
          *) break;;
  esac
done
EOF
chmod +x $ARPP

########################################
# send_arp
# from http://www.insecure.org/sploits/arp.games.html by Yuri Volobuev

SNDA=/usr/local/bin/send_arp
cat <<'EOF' >$SNDA
#!/bin/sh
SA=/usr/lib/heartbeat/send_arp
if [ -f $SA-old ] ;then SA=$SA-old; fi	# 0.99.7a
case "$#" in
 4) exec $SA eth0 "$@";;
 *) exec $SA "$@";;
esac
EOF
chmod +x $SNDA

########################################
# gui output processor and manual edit preserver

GUIP=/usr/local/bin/gui-paste
cat <<'EOF' >$GUIP
#!/bin/sh
#
# Process web GUI rule generator output, extract tables and interfaces
# and, if possible, carry forward any manual edits to tables with diff3
# unless the -r (replace) flag is used.
#
# If tables update succeeds, run tables, interfaces, arp-push
#
# Corey Satten, corey@cac, 8/16/01

TABLES=/usr/local/sbin/tables
IFACES=/etc/network/interfaces
P=`basename $0`

case "$1" in
    -r) REPLACE=1; shift;;	# replace (don't merge) tables file
     -) shift;;
    -*) echo "Usage: $0 [-r] [file]" 1>&2; exit 1;;
esac

if [ ! -z "$1" -a ! -f "$1" ] ;then
    echo "$0: can't find input file: $1" 1>&2; exit 1
fi

rm -f $TABLES.new $IFACES.new 2>&-

echo
echo 'Please copy/paste the entire firewall rule-generator output here...'

# IE pastes scroll lists as one huge line which chokes paste in cooked mode
# so now accept the paste in cbreak mode instead.  Handling of control-D
# is somewhat tricky.  It generates a quit signal to terminate the awk
# in cbreak mode (if necessary) but is otherwise ignored.

CODE=0
OLD_MODES=`stty -g </dev/tty`	# save tty modes
trap : 3			# ignore SIGQUIT in script but not children
stty cbreak min 1 time 0 quit ^D </dev/tty
exec 4>&2; exec 2>&-		# save stderr on fd4

# extract the two files we want from the complete webpage
awk '
  BEGIN { tables = "expand >'$TABLES.new'"; ifaces = "expand >'$IFACES.new'" }
	{sub(/[\015]$/,"")}	# convert CRLF to LF
  /^: # BE.*TABLES/,/^# this is the last line of .*tables/ {
	print |tables
	if (/^# this is the last line of .*tables/) close(tables)
	}
  /^# .*configuration .* ifup/,/^# this is the last line of .*interfaces/{
	print |ifaces
	if (/^# this is the last line of .*interfaces/) close(ifaces)
	}
  /^Home Page/ {exit}
  ' $* 
exec 2>&4			# restore stderr
stty $OLD_MODES </dev/tty	# restore tty modes
echo; echo; echo; echo paste accepted
sleep 1

if [ ! -f $TABLES.new -o ! -f $IFACES.new ] ;then
    echo "$P: tables and interfaces data not found in input, aborting." 1>&2
    exit 1
fi

if [ ! -z "$REPLACE" -o ! -e $TABLES.gui -o ! -e $TABLES ] ;then
    if [ -z "$REPLACE" -a -e $TABLES ] ;then
	echo "This looks like the first time you're running $P so"
	echo "$TABLES is being replaced (instead of merged) this time."
	echo "For reference, your old version is in $TABLES.old"
    fi
    mv $TABLES $TABLES.old 2>&-
    cp $TABLES.new $TABLES.gui
    mv $TABLES.new $TABLES
    chmod +x $TABLES
else
    diff3 -m $TABLES $TABLES.gui $TABLES.new > $TABLES.tmp
    if grep '^>>>>>' $TABLES.tmp >/dev/null ;then
	echo "Manual edits to $TABLES conflict with changes made in GUI..."
	echo "See lines flagged between >>>> and <<<< in $TABLES.tmp"
	echo "$TABLES and $IFACES remain unchanged"
	echo "(You can use `basename $0` -r to overwrite your changes)"
	CODE=1
    else
	if cmp -s $TABLES $TABLES.gui ;then :; else
	    echo "Manual edits to $TABLES detected and preserved"
	    echo "The old version is preserved in $TABLES.old"
	    echo "(You can use `basename $0` -r to overwrite your changes)"
	fi
	mv $TABLES $TABLES.old
	mv $TABLES.tmp $TABLES
	mv $TABLES.new $TABLES.gui
	chmod +x $TABLES
    fi
fi

if [ "$CODE" -eq 0 -a -f $IFACES.new ] ;then
    mv $IFACES $IFACES.old 2>&-
    mv $IFACES.new $IFACES
    echo -n "Last chance to interrupt (this is `hostname`)... "
    for i in 5 4 3 2 1; do echo -n "$i "; sleep 1; done
    echo
    echo "installing new iptables rules"
    tables
    sleep 1
    echo "updating interfaces"
    iface-update
    echo "pushing arp table values to the gateway"
    arp-push
fi

exit $CODE
EOF
chmod +x $GUIP

########################################
# disable unnecessary ipac cron entry

for IPAC in /etc/cron.d/ipac* ;do
  if [ -f "$IPAC" ]; then
    TMP=/tmp/ipac$$
    cp $IPAC $TMP && sed '/^[^#].*fetchipac/s/^/#/' < $TMP > $IPAC
    rm -f $TMP
  fi
done

########################################
# incremental interface update (needed for new gui-paste)

IUPD=/usr/local/bin/iface-update
cat <<'EOF' >$IUPD
#!/bin/sh
#
# Because running /etc/init.d/network restart creates problems
# with ipsec tunnels by bringing down/up interfaces which don't change
# this script brings down/up only what's actually changed
#
# Corey Satten, corey@cac 12/7/01

O=/tmp/interfaces.up
N=/etc/network/interfaces

if [ ! -s $O -o ! -s $N ] ;then exec /etc/init.d/networking restart ;fi

TO=/tmp/old.$$
TN=/tmp/new.$$

U=/tmp/up.$$
D=/tmp/dn.$$

trap "rm -f $TO $TN $D $U; exit 0" 0 1 2 13 15

# concatenate paragraphs of lines delimited by a blank line
# replace the line terminator with $DELIM

pjoin() {
DELIM=${DELIM-%}
sed -n '

$       { H; b done
	}

/[!-~]/	{ H; b
	}

: done
	x
	s/\n/'"$DELIM"'/g
	s/$/'"$DELIM"'/
	s/^'"$DELIM"'//
	p

' $*
}

# deconcatenate pjoined lines by breaking lines at $DELIM

psplit() {
    DELIM=${DELIM-%}
    tr "[$DELIM]" '[\012]' $*
}

pjoin < $N > $TN	# interface paragraphs are single lines in TN, TO
pjoin < $O > $TO

diff $TO $TN | sed -n 's/^< //p' | psplit > $D	# bring these down
diff $TO $TN | sed -n 's/^> //p' | psplit > $U	# bring these up

if [ -s $D ] ;then ifdown -a -i $D; rm -f $D.up; fi

if [ -s $U ] ;then ifup -a -i $U; rm -f $U.up; fi

cp -p $N $O
EOF
chmod +x $IUPD

########################################
# prevent apache log rotation from starting web server
# on Sunday as it otherwise does in 0.99.2
APA=/etc/cron.daily/apache

if grep '^[0-9].*apache$' /etc/$RL >/dev/null ;then : ;else
  if [ -f $APA ] ;then chmod -x $APA ;fi
  fi

########################################
# prevent nuisance mail from snort (0.99.6) if it is not running
SNO=/etc/cron.daily/*snort
if grep '^[0-9].*snort$' /etc/$RL >/dev/null ;then : ;else
  if [ -f $SNO ] ;then chmod -x $SNO ;fi
  fi

########################################
# install uw-restore script
RES=/usr/local/bin/uw-restore

cat <<'EOF' >$RES
#!/bin/sh
#
# This script will extract files from a Gibraltar configuration floppy.
# If no args are given, extract the default set to /etc
# If files are given, extract them to current directory.
# If -n is given, ignore /usr/local/bin/uw-restore.local.
#
# Remember pathnames on floppy are relative to /etc/ and '*' matches work
#
# Corey Satten, 5/23/02, 1/29/03

trap 'umount $UMOUNT; exit 0' 1 2 13 15	# clean up if interrupted

B='[1m'; N='[0m'	# Bold/Normal

UPGRADE_FILES='
    local/sbin/tables*
    aliases
    network/interfaces
    ssh/sshd_config
    ssh/ssh_host*
    ipsec.conf
    ipsec.secrets
    pptpd.conf
    ppp/pptpd-options
    ppp/chap-secrets
    syslog*.conf
    '
UPGRADE_CMDS='
    newaliases;
    echo;
    echo "${B}Remember to run \"uw-setup -n\" after running uw-restore${N}"
    '

case "$1" in
    -n) NX=1; shift;;		# ignore $XTRA even if present
    -*) echo "Usage: $0 [ -n ] [ files ]" 1>&2; exit 1;;
     *) NX=; XTRA="local/bin/uw-restore.local";;
esac

case $# in
    0)  echo -n "Extract/install essential files from ${RESTORE_FROM-floppy}? [y]/n > "
	read ANS
	case "$ANS" in
	  n*) echo OK, aborting.; exit 0;;
	   *) FILES="$UPGRADE_FILES"; DIR=/etc;;
	esac;;
    *)	FILES="$@"; DIR=.; UPGRADE_CMDS=;;
esac

mount ${RESTORE_FROM-/dev/fd0} /mnt && UMOUNT="$UMOUNT /mnt"
if [ -f /mnt/etc.gz ] ;then		# 0.98 case
    S=/tmp/etc
    R=/dev/rd/7
    mkdir -p $S
    zcat /mnt/etc.gz > $R
    mount $R $S && UMOUNT="$UMOUNT $S"
    case "$NX$DIR" in /etc)	# restore and use $XTRA from floppy if present
	(cd $S && tar cf - *) | (set -f; cd $DIR && tar xvfp - $XTRA) 2>&-
	FILES="$FILES `cd $DIR && cat $XTRA 2>&- && echo $XTRA`"
    esac
    (cd $S && tar cf - *) | (set -f; cd $DIR && tar xvfp - $FILES)
    umount $UMOUNT
    rmdir $S
else if [ -f /mnt/etc.tgz ] ;then	# 0.99.x case
    case "$NX$DIR" in /etc)	# restore and use $XTRA from floppy if present
	(set -f; cd $DIR && tar xvzfp /mnt/etc.tgz $XTRA) 2>&-
	FILES="$FILES `cd $DIR && cat $XTRA 2>&- && echo $XTRA`"
    esac
    (set -f; cd $DIR && tar xvzfp /mnt/etc.tgz $FILES)
    fi
    umount $UMOUNT
fi
eval $UPGRADE_CMDS
EOF
chmod +x $RES

########################################
# prevent tmpreaper from deleting /tmp/interfaces.up

TRC=/etc/tmpreaper.conf
if [ -f $TRC ] ;then
  if grep interfaces.up $TRC >/dev/null ;then : ;else
    sed '
      /^TMPREAPER_PROTECT_EXTRA=/s,=\(.\)\(.*\)\1$,=\1\2 /tmp/interfaces.up\1,
      ' < $TRC > $TRC.new &&
    cp $TRC.new $TRC &&
    rm -f $TRC.new
  fi
fi

########################################
# OpenSSH potentially exploitable bug workaround

SSHD=/etc/ssh/sshd_config

case "$GVERS" in 0.99.[1234]*)	# {

    sed '
	$a\
#-       -       -\
#UW-SETUP MODIFICATIONS in response to CERT Advisory CA-2002-18\
ChallengeResponseAuthentication no\
PAMAuthenticationViaKbdInt no\
KbdInteractiveAuthentication no

	/^#-       -       -/d
	/^#UW-SETUP MODIFICATIONS/d
	/^#*ChallengeResponseAuthentication/d
	/^#*PAMAuthenticationViaKbdInt/d
	/^#*KbdInteractiveAuthentication/d

    ' < $SSHD > $SSHD.tmp && cp $SSHD.tmp $SSHD && rm $SSHD.tmp

    /etc/init.d/ssh reload
    ;;

esac			# }

########################################
# arp cache logging

AL=/usr/local/sbin/arplog
if [ -f $AL ] ;then ALSO=`sum <$AL|awk '{print $1}'`; fi
cat >$AL <<'EOF'
#! /usr/bin/perl
eval 'exec perl -S $0 ${1+"$@"} ;' unless 1;

# Cause arp-cache entries to be syslogged at least once/day to aid tracking.
# Poll arp-cache in /proc/net/arp every $interval (default 30 seconds).
# Syslog only new entries except flush cache once/day to relog everything.
#
# Corey Satten, corey@cac 8/26/02, 10/14/03

use Sys::Syslog;
use Socket;

if ($#ARGV >= $[ && $ARGV[0] eq "stop") {
  open(PS, "/bin/ps ax|") || die("can't fork ps");
  while (<PS>) {
    if (/\s*(\d+).*perl.*arplog/ && $1 != $$) {
      printf STDERR ("killing %s", $_);
      kill (15, $1);
      }
    }
  exit 0;
  }

exit_if_already_running();

if ($#ARGV >= $[ && $ARGV[0] eq "start") {	# background self...
  exit if (fork());				# ...parent exits
  close(STDIN);
  close(STDOUT);
  close(STDERR);
  }

$interval = 30;

sub open_log {
  while (($sock_ctime = (stat('/dev/log'))[10]) == 0) {
    sleep 1;
    }
  return if ($opentime >= $sock_ctime);
  Sys::Syslog::closelog() if ($opentime);
  $opentime = $sock_ctime;

  Sys::Syslog::openlog('arplog','cons','local1') ||	# for 0.99.4
  Sys::Syslog::setlogsock('unix') &&			# for 0.98c
  Sys::Syslog::openlog('arplog','cons,ndelay','local1') ||
  Sys::Syslog::setlogsock('inet') &&			# for good measure
  Sys::Syslog::openlog('arplog','cons,ndelay','local1') || die ("cant openlog");
  }

$clear_time = time;

while(1) {
  &open_log;
  open(F, "/proc/net/arp");
  while (<F>) {
    if (/^\d+\./) {
      ($ip,$t,$f,$ha) = split();
      if ($f ne '0x0' && $ha{$ip} ne $ha) {
	delete $ip{$ha{$ip}};	# multiple MACs may alternately use an IP
	$ip{$ha} = $ip;		# IP from MAC lookup
	$ha{$ip} = $ha;		# MAC from IP lookup
        syslog('alert', '%s', "MAC $ha at IP $ip");
	}
      }
    }
  close(F);
  sleep($interval);
  if (($now = time) - $clear_time >= 86400) {	# once every 24 hours
    undef %ha;			# forget everything to force re-logging once/day
    undef %ip;			# forget everything to force re-logging once/day
    $clear_time = $now;
    }
  }

sub exit_if_already_running {
  # while running, exclusively bind to a socket (cleanup is automatic/assured)
  $sockaddr = 'S n a4 x8';	# pack format for sockaddr structure
  $localhost = (gethostbyname('localhost'))[4];
  socket(S, &AF_INET, &SOCK_DGRAM, 0) || die("socket");
  if (!bind(S, pack($sockaddr, &AF_INET, $port=19, $localhost))) {
    print STDERR "arplog: already running, no need to start another\n";
    exit(1);
    }

  # failsafe, also look for running perl arplog process
  $myself = "/proc/$$/cmdline";
  foreach $f (</proc/[0-9]*/cmdline>) {
    if ($f ne $myself && open(C, $f)) {
      while (<C>) {
        if (/\bperl\b.*\barplog\b/) {
          print STDERR "arplog: already running, no need to start another\n";
          exit(1);
          }
        }
      close(C);
      }
    }
  }
EOF
chmod +x $AL
ALSN=`sum <$AL|awk '{print $1}'`
case "$ALSO" in "$ALSN"|"") ;; *)
  echo Arplog updated, restarting it 1>&2
  $AL stop 2>&- ;;
esac
(cd / && $AL start)

# arrange to populate gateway arp cache when pptp client connects
PPPARP=/etc/ppp/ip-up.d/00-arp-push
cat <<'EOF' >$PPPARP
#!/bin/sh
# populate the gateway's arp cache with the new client

GW_DEV=`netstat -rn | awk '$1 == "0.0.0.0" && $4=="UG" {print $NF}'`
ID=`echo $PPP_REMOTE | sed 's/.*\.//'`
ifconfig eth0:t$ID $PPP_REMOTE up && break
arping -q -I $GW_DEV -c 1 -A -s $PPP_REMOTE 255.255.255.255
ifconfig eth0:t$ID down
EOF
chmod +x $PPPARP

# prevent PPTPD from starting various things

NOX="
  /etc/ppp/ip-up.d/portsentry
  /etc/ppp/ip-down.d/portsentry
  /etc/ppp/ip-up.d/snort
  /etc/ppp/ip-down.d/snort
  /etc/ppp/ip-up.d/freenet6
  "
for i in $NOX; do
  if [ -f $i ] ;then chmod -x $i; fi
done

########################################
# if timezone changed, some daemons need restarting

DMNS="
  /etc/init.d/syslog-ng
  /etc/init.d/sysklogd
  /etc/init.d/klogd
  /etc/init.d/cron
  "
case "$OTZ" in "$NTZ");; *)
    echo Restarting syslog and cron daemons in your new timezone... 1>&2
    for DMN in $DMNS; do
	if [ -f $DMN ] && grep "^[0-9].*$DMN[^!-~]*$" /etc/$RL >/dev/null ;then
	  $DMN restart >/dev/null 2>&1
	fi
    done &
    sleep 1
esac

########################################
# if there is no ssh1 key, generate one and enable ssh1 in sshd_config
# for gibraltar 0.99.5 and newer

SSH1K=ssh_host_key
SSHDC=/etc/ssh/sshd_config

if [ ! -f /etc/ssh/$SSH1K ] ;then
    echo
    echo -n 'Enable SSH old protocol 1 (still needed for Teraterm)? [y]/n '
    read SSH1
    case "$SSH1" in ''|y*)
	echo generating an ssh1 host key and enabling ssh protocol 1
	ssh-keygen -t rsa1 -b 1024 -f /etc/ssh/$SSH1K -N "" > /dev/null
	sed "
	s;^\\(Protocol\\)[^!-~].*;\\1 2,1;
	/^HostKey/,/^[^H]/ {
	    /^HostKey \/etc\/ssh\/$SSH1K\$/d
	    /^[^H]/i\\
HostKey /etc/ssh/$SSH1K
	    }
	" $SSHDC > /tmp/ssh$$ && cp /tmp/ssh$$ $SSHDC && rm -f /tmp/ssh$$
	/etc/init.d/ssh restart
    esac
fi

########################################
# 0.99.7 needs default target for save-config.

if [ -d /etc/gibraltar -a ! -f /etc/gibraltar/config_source ] ;then
   echo /dev/floppy/0 > /etc/gibraltar/config_source
fi

########################################
# 0.99.8 uses new pptpd feature names, convert in case user runs uw-restore

case $GVERS in 0.98*|0.99.[1234567]*);; *)
  PPTPO=/etc/ppp/pptpd-options 
  if [ -f $PPTPO ] ;then
    sed '
      s/^\+chapms *$/require-mschap/
      s/^\+chapms-v2 *$/require-mschap-v2/
      s/^mppe-40 *$/require-mppe/
      s/^mppe-128 *$/require-mppe-128/
      s/^mppe-stateless *$/nomppe-stateful/
      ' < $PPTPO > $PPTPO.new
    if cmp -s $PPTPO $PPTPO.new ;then
      rm $PPTPO.new
    else
      echo Converting $PPTPO to new format
      cp -p $PPTPO $PPTPO.old && cp $PPTPO.new $PPTPO && rm -f $PPTPO.new
    fi
  fi
esac

########################################
# 0.99.8 uses new ipsec.conf, convert in case user runs uw-restore

case $GVERS in 0.98*|0.99.[1234567]*);; *)
  IPSC=/etc/ipsec.conf
  if egrep '^[^!-~]*(plutoload|plutostart)' $IPSC >/dev/null ;then
    sed '
      1i\
version 2
      s/^\([^!-~]*\)\(plutoload\)/\1# \2/
      s/^\([^!-~]*\)\(plutostart\)/\1# \2/
      ' < $IPSC > $IPSC.new
    if cmp -s $IPSC $IPSC.new ;then
      rm $IPSC.new
    else
      echo Converting $IPSC to new format
      cp -p $IPSC $IPSC.old && cp $IPSC.new $IPSC && rm -f $IPSC.new
    fi
  fi
esac

########################################
# 1.0 and newer have antivirus crontab entries we don't need; disable them

AV='clamav amavisd-new clamav-freshclam clamav.disable kavupdate bld-apply
    amavis-stats'
for i in $AV; do
  E=/etc/cron.d/$i
  if [ -f $E ] ;then
    sed '/^[^#]/s/^/#/' < $E > $E.new && cp $E{.new,} && rm -f $E.new
  fi
done
AVN='amavisd-new'
for i in $AVN; do
  E=/etc/cron.daily/$i
  if [ -f $E ] ;then chmod -x $E; fi
done

########################################
# increase default log rotation size from 500k to 5M

LRC=/etc/logrotate.conf
if grep -q '^size  *500k' $LRC ;then
  sed '
    /^size  *500k/ {
      s/^/#/p
      s/.*/size 5M/
      }' < $LRC > $LRC.new && cp $LRC{.new,} && rm -f $LRC.new
fi

# to reduce the chance of logs filling ramdisk and stopping
LRF=/etc/cron.d/logrotate
if [ -f $LRF ] ;then
    sed 's;^\*/1*5 ;*/2 ;' < $LRF > $LRF.new && cp $LRF{.new,} && rm -f $LRF.new
fi

########################################
# fix logcheck ignore file in 2.4.1
LCR=/etc/logcheck/ignore.d.paranoid/gibraltar-reboot
if [ -f $LCR ] && grep '^kernel: $' < $LCR >/dev/null ;then
   sed 's/^kernel: $/&\$/' < $LCR > $LCR.new && cp $LCR{.new,} && rm -f $LCR.new
fi
